AppCompatDelegateImplV7.java revision ea4f700ac38424954c56df5138ff794def50b019
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;
35ea4f700ac38424954c56df5138ff794def50b019Chris 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;
4749c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.widget.ProgressBarCompat;
48415f740df4981ef2f5fb462a50c7cf095cc21128Chris Banesimport android.support.v7.internal.widget.TintCheckBox;
49415f740df4981ef2f5fb462a50c7cf095cc21128Chris Banesimport android.support.v7.internal.widget.TintCheckedTextView;
50469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport android.support.v7.internal.widget.TintEditText;
51415f740df4981ef2f5fb462a50c7cf095cc21128Chris Banesimport android.support.v7.internal.widget.TintRadioButton;
52415f740df4981ef2f5fb462a50c7cf095cc21128Chris Banesimport android.support.v7.internal.widget.TintSpinner;
534bd5cbd6ca4f1e5ed43217b808068a48f937feabChris Banesimport android.support.v7.internal.widget.ViewStubCompat;
54ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banesimport android.support.v7.internal.widget.ViewUtils;
55d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banesimport android.support.v7.view.ActionMode;
5649c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.widget.Toolbar;
57469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport android.util.AttributeSet;
5856fd50144df518461398a9b3397ee4842b346708Chris Banesimport android.util.DisplayMetrics;
5956fd50144df518461398a9b3397ee4842b346708Chris Banesimport android.util.TypedValue;
6061c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banesimport android.view.ContextThemeWrapper;
614c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.view.Gravity;
6200d183885b54de433e43118d3032340f40cac8c0Chris Banesimport android.view.KeyCharacterMap;
63dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banesimport android.view.KeyEvent;
64dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banesimport android.view.LayoutInflater;
6530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.Menu;
6630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.MenuItem;
676386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.view.View;
6849c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.ViewConfiguration;
696386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.view.ViewGroup;
706386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.view.Window;
714c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.view.accessibility.AccessibilityEvent;
7230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.widget.FrameLayout;
734c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.widget.PopupWindow;
746386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
75469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport static android.support.v4.view.WindowCompat.FEATURE_ACTION_BAR;
76469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport static android.support.v4.view.WindowCompat.FEATURE_ACTION_BAR_OVERLAY;
77469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport static android.support.v4.view.WindowCompat.FEATURE_ACTION_MODE_OVERLAY;
7800d183885b54de433e43118d3032340f40cac8c0Chris Banesimport static android.view.Window.FEATURE_OPTIONS_PANEL;
7900d183885b54de433e43118d3032340f40cac8c0Chris Banes
8003fc11b659da1645507062bddda450136e13af35Chris Banesclass ActionBarActivityDelegateBase extends ActionBarActivityDelegate
8103fc11b659da1645507062bddda450136e13af35Chris Banes        implements MenuBuilder.Callback {
8230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    private static final String TAG = "ActionBarActivityDelegateBase";
836386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
8449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    private DecorContentParent mDecorContentParent;
8503fc11b659da1645507062bddda450136e13af35Chris Banes    private ActionMenuPresenterCallback mActionMenuPresenterCallback;
8603fc11b659da1645507062bddda450136e13af35Chris Banes    private PanelMenuPresenterCallback mPanelMenuPresenterCallback;
8703fc11b659da1645507062bddda450136e13af35Chris Banes
884c2a95906254748cb9a843b061288265d6e185a9Chris Banes    ActionMode mActionMode;
894c2a95906254748cb9a843b061288265d6e185a9Chris Banes    ActionBarContextView mActionModeView;
904c2a95906254748cb9a843b061288265d6e185a9Chris Banes    PopupWindow mActionModePopup;
914c2a95906254748cb9a843b061288265d6e185a9Chris Banes    Runnable mShowActionModePopup;
925a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes
935a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes    // true if we have installed a window sub-decor layout.
945a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes    private boolean mSubDecorInstalled;
9503fc11b659da1645507062bddda450136e13af35Chris Banes    private ViewGroup mWindowDecor;
96ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes    private ViewGroup mSubDecor;
97ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes
98ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes    private View mStatusGuard;
99d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
100f53c7bf3146bf9bcba46324f9f06449df475be36Chris Banes    private CharSequence mTitleToSet;
101f53c7bf3146bf9bcba46324f9f06449df475be36Chris Banes
102ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    // Used to keep track of Progress Bar Window features
103ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    private boolean mFeatureProgress, mFeatureIndeterminateProgress;
104ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
1058902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes    // Used for emulating PanelFeatureState
1068902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes    private boolean mClosingActionMenu;
10700d183885b54de433e43118d3032340f40cac8c0Chris Banes    private PanelFeatureState[] mPanels;
10800d183885b54de433e43118d3032340f40cac8c0Chris Banes    private PanelFeatureState mPreparedPanel;
109556ac47ce764a4a9320b5ac914536e9da2524176Chris Banes
11003fc11b659da1645507062bddda450136e13af35Chris Banes    private boolean mInvalidatePanelMenuPosted;
11100d183885b54de433e43118d3032340f40cac8c0Chris Banes    private int mInvalidatePanelMenuFeatures;
11203fc11b659da1645507062bddda450136e13af35Chris Banes    private final Runnable mInvalidatePanelMenuRunnable = new Runnable() {
11303fc11b659da1645507062bddda450136e13af35Chris Banes        @Override
11403fc11b659da1645507062bddda450136e13af35Chris Banes        public void run() {
11500d183885b54de433e43118d3032340f40cac8c0Chris Banes            if ((mInvalidatePanelMenuFeatures & 1 << FEATURE_OPTIONS_PANEL) != 0) {
11600d183885b54de433e43118d3032340f40cac8c0Chris Banes                doInvalidatePanelMenu(FEATURE_OPTIONS_PANEL);
11700d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
11800d183885b54de433e43118d3032340f40cac8c0Chris Banes            if ((mInvalidatePanelMenuFeatures & 1 << FEATURE_ACTION_BAR) != 0) {
11900d183885b54de433e43118d3032340f40cac8c0Chris Banes                doInvalidatePanelMenu(FEATURE_ACTION_BAR);
12000d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
12100d183885b54de433e43118d3032340f40cac8c0Chris Banes            mInvalidatePanelMenuPosted = false;
12200d183885b54de433e43118d3032340f40cac8c0Chris Banes            mInvalidatePanelMenuFeatures = 0;
12303fc11b659da1645507062bddda450136e13af35Chris Banes        }
12403fc11b659da1645507062bddda450136e13af35Chris Banes    };
12503fc11b659da1645507062bddda450136e13af35Chris Banes
12649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    private boolean mEnableDefaultActionBarUp;
12749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
128f2b7cd67036d78fd5b487b0a2dab28aee11d9c88Adam Powell    ActionBarActivityDelegateBase(ActionBarActivity activity) {
1293954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes        super(activity);
1306386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
1316386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
1326386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
13349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    void onCreate(Bundle savedInstanceState) {
13449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        super.onCreate(savedInstanceState);
13549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
13603fc11b659da1645507062bddda450136e13af35Chris Banes        mWindowDecor = (ViewGroup) mActivity.getWindow().getDecorView();
13703fc11b659da1645507062bddda450136e13af35Chris Banes
13849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (NavUtils.getParentActivityName(mActivity) != null) {
13949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            ActionBar ab = getSupportActionBar();
14049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            if (ab == null) {
14149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                mEnableDefaultActionBarUp = true;
14249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            } else {
14349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                ab.setDefaultDisplayHomeAsUpEnabled(true);
14449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            }
14549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
14649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
14749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
14849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
1496386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public ActionBar createSupportActionBar() {
15030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        ensureSubDecor();
15149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        ActionBar ab = new WindowDecorActionBar(mActivity, mOverlayActionBar);
15249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        ab.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp);
15349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        return ab;
15449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
15549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
15649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
15749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    void setSupportActionBar(Toolbar toolbar) {
15849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (getSupportActionBar() instanceof WindowDecorActionBar) {
15949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            throw new IllegalStateException("This Activity already has an action bar supplied " +
16049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    "by the window decor. Do not request Window.FEATURE_ACTION_BAR and set " +
16149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    "windowActionBar to false in your theme to use a Toolbar instead.");
16249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
163a6e86333cb4de18fc9b86746a49643e213db7c18Chris Banes        // Need to make sure we give the action bar the default window callback. Otherwise multiple
164a6e86333cb4de18fc9b86746a49643e213db7c18Chris Banes        // setSupportActionBar() calls lead to memory leaks
1650b216f2263135782c361e122892a12156d5d2ce1Chris Banes        ToolbarActionBar tbab = new ToolbarActionBar(toolbar, mActivity.getTitle(),
166a6e86333cb4de18fc9b86746a49643e213db7c18Chris Banes                mDefaultWindowCallback);
1670b216f2263135782c361e122892a12156d5d2ce1Chris Banes        setSupportActionBar(tbab);
1680b216f2263135782c361e122892a12156d5d2ce1Chris Banes        setWindowCallback(tbab.getWrappedWindowCallback());
1690b216f2263135782c361e122892a12156d5d2ce1Chris Banes        tbab.invalidateOptionsMenu();
1706386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
1716386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
1726386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
1736386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public void onConfigurationChanged(Configuration newConfig) {
1746386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        // If this is called before sub-decor is installed, ActionBar will not
1756386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        // be properly initialized.
1765a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        if (mHasActionBar && mSubDecorInstalled) {
1776386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes            // Note: The action bar will need to access
1786386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes            // view changes from superclass.
17949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            ActionBar ab = getSupportActionBar();
18049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            if (ab != null) {
18149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                ab.onConfigurationChanged(newConfig);
18249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            }
1836386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        }
1846386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
1856386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
1866386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
187a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes    public void onStop() {
18849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        ActionBar ab = getSupportActionBar();
189a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes        if (ab != null) {
190a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes            ab.setShowHideAnimationEnabled(false);
191a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes        }
192a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes    }
193a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes
194a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes    @Override
195a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes    public void onPostResume() {
19649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        ActionBar ab = getSupportActionBar();
197a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes        if (ab != null) {
198a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes            ab.setShowHideAnimationEnabled(true);
199a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes        }
200a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes    }
201a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes
202a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes    @Override
2036386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public void setContentView(View v) {
2046386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        ensureSubDecor();
20556fd50144df518461398a9b3397ee4842b346708Chris Banes        ViewGroup contentParent = (ViewGroup) mActivity.findViewById(android.R.id.content);
20656fd50144df518461398a9b3397ee4842b346708Chris Banes        contentParent.removeAllViews();
20756fd50144df518461398a9b3397ee4842b346708Chris Banes        contentParent.addView(v);
208d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes        mActivity.onSupportContentChanged();
2096386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
2106386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
2116386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
2126386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public void setContentView(int resId) {
2136386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        ensureSubDecor();
21456fd50144df518461398a9b3397ee4842b346708Chris Banes        ViewGroup contentParent = (ViewGroup) mActivity.findViewById(android.R.id.content);
21556fd50144df518461398a9b3397ee4842b346708Chris Banes        contentParent.removeAllViews();
21656fd50144df518461398a9b3397ee4842b346708Chris Banes        mActivity.getLayoutInflater().inflate(resId, contentParent);
217d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes        mActivity.onSupportContentChanged();
2186386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
2196386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
2206386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
2216386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public void setContentView(View v, ViewGroup.LayoutParams lp) {
2226386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        ensureSubDecor();
22356fd50144df518461398a9b3397ee4842b346708Chris Banes        ViewGroup contentParent = (ViewGroup) mActivity.findViewById(android.R.id.content);
22456fd50144df518461398a9b3397ee4842b346708Chris Banes        contentParent.removeAllViews();
22556fd50144df518461398a9b3397ee4842b346708Chris Banes        contentParent.addView(v, lp);
226d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes        mActivity.onSupportContentChanged();
2276386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
2286386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
2296386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
2306386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public void addContentView(View v, ViewGroup.LayoutParams lp) {
2316386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        ensureSubDecor();
23256fd50144df518461398a9b3397ee4842b346708Chris Banes        ViewGroup contentParent = (ViewGroup) mActivity.findViewById(android.R.id.content);
23356fd50144df518461398a9b3397ee4842b346708Chris Banes        contentParent.addView(v, lp);
234d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes        mActivity.onSupportContentChanged();
235d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes    }
236d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes
237d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes    @Override
238d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes    public void onContentChanged() {
239d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes        // Ignore all calls to this method as we call onSupportContentChanged manually above
2406386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
2416386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
2428123e4b3d19031e34a60c0db202f0b3d100eb9d8Chris Banes    final void ensureSubDecor() {
24356fd50144df518461398a9b3397ee4842b346708Chris Banes        if (!mSubDecorInstalled) {
24456fd50144df518461398a9b3397ee4842b346708Chris Banes            if (mHasActionBar) {
2454b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                /**
2464b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                 * This needs some explanation. As we can not use the android:theme attribute
2474b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                 * pre-L, we emulate it by manually creating a LayoutInflater using a
2484b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                 * ContextThemeWrapper pointing to actionBarTheme.
2494b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                 */
2504b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                TypedValue outValue = new TypedValue();
2514b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                mActivity.getTheme().resolveAttribute(R.attr.actionBarTheme, outValue, true);
2524b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes
2534b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                Context themedContext;
2544b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                if (outValue.resourceId != 0) {
2554b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                    themedContext = new ContextThemeWrapper(mActivity, outValue.resourceId);
2564b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                } else {
2574b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                    themedContext = mActivity;
25861c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                }
25961c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes
2604b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                // Now inflate the view using the themed context and set it as the content view
261ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                mSubDecor = (ViewGroup) LayoutInflater.from(themedContext)
2624b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                        .inflate(R.layout.abc_screen_toolbar, null);
2634b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes
264ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                mDecorContentParent = (DecorContentParent) mSubDecor
26503fc11b659da1645507062bddda450136e13af35Chris Banes                        .findViewById(R.id.decor_content_parent);
266a6e86333cb4de18fc9b86746a49643e213db7c18Chris Banes                mDecorContentParent.setWindowCallback(getWindowCallback());
267ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
26856fd50144df518461398a9b3397ee4842b346708Chris Banes                /**
26949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                 * Propagate features to DecorContentParent
27056fd50144df518461398a9b3397ee4842b346708Chris Banes                 */
27149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                if (mOverlayActionBar) {
272469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes                    mDecorContentParent.initFeature(FEATURE_ACTION_BAR_OVERLAY);
27349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                }
27456fd50144df518461398a9b3397ee4842b346708Chris Banes                if (mFeatureProgress) {
27549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    mDecorContentParent.initFeature(Window.FEATURE_PROGRESS);
27656fd50144df518461398a9b3397ee4842b346708Chris Banes                }
27756fd50144df518461398a9b3397ee4842b346708Chris Banes                if (mFeatureIndeterminateProgress) {
27849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    mDecorContentParent.initFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
27956fd50144df518461398a9b3397ee4842b346708Chris Banes                }
28056fd50144df518461398a9b3397ee4842b346708Chris Banes            } else {
281ea4f700ac38424954c56df5138ff794def50b019Chris Banes                if (mOverlayActionMode) {
282ea4f700ac38424954c56df5138ff794def50b019Chris Banes                    mSubDecor = (ViewGroup) LayoutInflater.from(mActivity)
283ea4f700ac38424954c56df5138ff794def50b019Chris Banes                            .inflate(R.layout.abc_screen_simple_overlay_action_mode, null);
284ea4f700ac38424954c56df5138ff794def50b019Chris Banes                } else {
285ea4f700ac38424954c56df5138ff794def50b019Chris Banes                    mSubDecor = (ViewGroup) LayoutInflater.from(mActivity)
286ea4f700ac38424954c56df5138ff794def50b019Chris Banes                            .inflate(R.layout.abc_screen_simple, null);
287ea4f700ac38424954c56df5138ff794def50b019Chris Banes                }
288ea4f700ac38424954c56df5138ff794def50b019Chris Banes
289ea4f700ac38424954c56df5138ff794def50b019Chris Banes                if (Build.VERSION.SDK_INT >= 21) {
290ea4f700ac38424954c56df5138ff794def50b019Chris Banes                    // If we're running on L or above, we can rely on ViewCompat's
291ea4f700ac38424954c56df5138ff794def50b019Chris Banes                    // setOnApplyWindowInsetsListener
292ea4f700ac38424954c56df5138ff794def50b019Chris Banes                    ViewCompat.setOnApplyWindowInsetsListener(mSubDecor,
293ea4f700ac38424954c56df5138ff794def50b019Chris Banes                            new OnApplyWindowInsetsListener() {
294ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                @Override
295ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                public WindowInsetsCompat onApplyWindowInsets(View v,
296ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                        WindowInsetsCompat insets) {
297ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                    final int top = insets.getSystemWindowInsetTop();
298ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                    final int newTop = updateStatusGuard(top);
299ea4f700ac38424954c56df5138ff794def50b019Chris Banes
300ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                    if (top != newTop) {
301ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                        return insets.replaceSystemWindowInsets(
302ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                                insets.getSystemWindowInsetLeft(),
303ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                                newTop,
304ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                                insets.getSystemWindowInsetRight(),
305ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                                insets.getSystemWindowInsetBottom());
306ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                    } else {
307ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                        return insets;
308ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                    }
309ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                }
310ea4f700ac38424954c56df5138ff794def50b019Chris Banes                            });
311ea4f700ac38424954c56df5138ff794def50b019Chris Banes                } else {
312ea4f700ac38424954c56df5138ff794def50b019Chris Banes                    // Else, we need to use our own FitWindowsViewGroup handling
313ea4f700ac38424954c56df5138ff794def50b019Chris Banes                    ((FitWindowsViewGroup) mSubDecor).setOnFitSystemWindowsListener(
314ea4f700ac38424954c56df5138ff794def50b019Chris Banes                            new FitWindowsViewGroup.OnFitSystemWindowsListener() {
315ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                @Override
316ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                public void onFitSystemWindows(Rect insets) {
317ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                    insets.top = updateStatusGuard(insets.top);
318ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                }
319ea4f700ac38424954c56df5138ff794def50b019Chris Banes                            });
320ea4f700ac38424954c56df5138ff794def50b019Chris Banes                }
3213954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes            }
3223954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
3231f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes            // Make the decor optionally fit system windows, like the window's decor
324ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes            ViewUtils.makeOptionalFitsSystemWindows(mSubDecor);
3251f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes
326ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes            // Now set the Activity's content view with the decor
327ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes            mActivity.superSetContentView(mSubDecor);
3281f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes
32992b18eb0263ef2421fda5bf977fea3bf044bf941Chris Banes            // Change our content FrameLayout to use the android.R.id.content id.
33092b18eb0263ef2421fda5bf977fea3bf044bf941Chris Banes            // Useful for fragments.
3314b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes            final View decorContent = mActivity.findViewById(android.R.id.content);
3324b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes            decorContent.setId(View.NO_ID);
33392b18eb0263ef2421fda5bf977fea3bf044bf941Chris Banes            View abcContent = mActivity.findViewById(R.id.action_bar_activity_content);
33492b18eb0263ef2421fda5bf977fea3bf044bf941Chris Banes            abcContent.setId(android.R.id.content);
33592b18eb0263ef2421fda5bf977fea3bf044bf941Chris Banes
3364b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes            // The decorContent may have a foreground drawable set (windowContentOverlay).
3374b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes            // Remove this as we handle it ourselves
3384b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes            if (decorContent instanceof FrameLayout) {
3394b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                ((FrameLayout) decorContent).setForeground(null);
3404b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes            }
3414b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes
342f53c7bf3146bf9bcba46324f9f06449df475be36Chris Banes            // A title was set before we've install the decor so set it now.
34349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            if (mTitleToSet != null && mDecorContentParent != null) {
34449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                mDecorContentParent.setWindowTitle(mTitleToSet);
34556fd50144df518461398a9b3397ee4842b346708Chris Banes                mTitleToSet = null;
346f53c7bf3146bf9bcba46324f9f06449df475be36Chris Banes            }
347556ac47ce764a4a9320b5ac914536e9da2524176Chris Banes
34856fd50144df518461398a9b3397ee4842b346708Chris Banes            applyFixedSizeWindow();
34956fd50144df518461398a9b3397ee4842b346708Chris Banes
35049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            onSubDecorInstalled();
35149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
352f53c7bf3146bf9bcba46324f9f06449df475be36Chris Banes            mSubDecorInstalled = true;
3538902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
35400d183885b54de433e43118d3032340f40cac8c0Chris Banes            // Invalidate if the panel menu hasn't been created before this.
35500d183885b54de433e43118d3032340f40cac8c0Chris Banes            // Panel menu invalidation is deferred avoiding application onCreateOptionsMenu
35600d183885b54de433e43118d3032340f40cac8c0Chris Banes            // being called in the middle of onCreate or similar.
35700d183885b54de433e43118d3032340f40cac8c0Chris Banes            // A pending invalidation will typically be resolved before the posted message
35800d183885b54de433e43118d3032340f40cac8c0Chris Banes            // would run normally in order to satisfy instance state restoration.
35900d183885b54de433e43118d3032340f40cac8c0Chris Banes            PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, false);
3609b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes            if (!isDestroyed() && (st == null || st.menu == null)) {
36100d183885b54de433e43118d3032340f40cac8c0Chris Banes                invalidatePanelMenu(FEATURE_ACTION_BAR);
36200d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
3636386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        }
3646386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
3656386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
36649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    void onSubDecorInstalled() {}
36749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
36856fd50144df518461398a9b3397ee4842b346708Chris Banes    private void applyFixedSizeWindow() {
36949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        TypedArray a = mActivity.obtainStyledAttributes(R.styleable.Theme);
37056fd50144df518461398a9b3397ee4842b346708Chris Banes
37156fd50144df518461398a9b3397ee4842b346708Chris Banes        TypedValue mFixedWidthMajor = null;
37256fd50144df518461398a9b3397ee4842b346708Chris Banes        TypedValue mFixedWidthMinor = null;
37356fd50144df518461398a9b3397ee4842b346708Chris Banes        TypedValue mFixedHeightMajor = null;
37456fd50144df518461398a9b3397ee4842b346708Chris Banes        TypedValue mFixedHeightMinor = null;
37556fd50144df518461398a9b3397ee4842b346708Chris Banes
37649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (a.hasValue(R.styleable.Theme_windowFixedWidthMajor)) {
37756fd50144df518461398a9b3397ee4842b346708Chris Banes            if (mFixedWidthMajor == null) mFixedWidthMajor = new TypedValue();
37849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            a.getValue(R.styleable.Theme_windowFixedWidthMajor, mFixedWidthMajor);
37956fd50144df518461398a9b3397ee4842b346708Chris Banes        }
38049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (a.hasValue(R.styleable.Theme_windowFixedWidthMinor)) {
38156fd50144df518461398a9b3397ee4842b346708Chris Banes            if (mFixedWidthMinor == null) mFixedWidthMinor = new TypedValue();
38249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            a.getValue(R.styleable.Theme_windowFixedWidthMinor, mFixedWidthMinor);
38356fd50144df518461398a9b3397ee4842b346708Chris Banes        }
38449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (a.hasValue(R.styleable.Theme_windowFixedHeightMajor)) {
38556fd50144df518461398a9b3397ee4842b346708Chris Banes            if (mFixedHeightMajor == null) mFixedHeightMajor = new TypedValue();
38649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            a.getValue(R.styleable.Theme_windowFixedHeightMajor, mFixedHeightMajor);
38756fd50144df518461398a9b3397ee4842b346708Chris Banes        }
38849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (a.hasValue(R.styleable.Theme_windowFixedHeightMinor)) {
38956fd50144df518461398a9b3397ee4842b346708Chris Banes            if (mFixedHeightMinor == null) mFixedHeightMinor = new TypedValue();
39049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            a.getValue(R.styleable.Theme_windowFixedHeightMinor, mFixedHeightMinor);
39156fd50144df518461398a9b3397ee4842b346708Chris Banes        }
39256fd50144df518461398a9b3397ee4842b346708Chris Banes
39356fd50144df518461398a9b3397ee4842b346708Chris Banes        final DisplayMetrics metrics = mActivity.getResources().getDisplayMetrics();
39456fd50144df518461398a9b3397ee4842b346708Chris Banes        final boolean isPortrait = metrics.widthPixels < metrics.heightPixels;
39556fd50144df518461398a9b3397ee4842b346708Chris Banes        int w = ViewGroup.LayoutParams.MATCH_PARENT;
39656fd50144df518461398a9b3397ee4842b346708Chris Banes        int h = ViewGroup.LayoutParams.MATCH_PARENT;
39756fd50144df518461398a9b3397ee4842b346708Chris Banes
39856fd50144df518461398a9b3397ee4842b346708Chris Banes        final TypedValue tvw = isPortrait ? mFixedWidthMinor : mFixedWidthMajor;
39956fd50144df518461398a9b3397ee4842b346708Chris Banes        if (tvw != null && tvw.type != TypedValue.TYPE_NULL) {
40056fd50144df518461398a9b3397ee4842b346708Chris Banes            if (tvw.type == TypedValue.TYPE_DIMENSION) {
40156fd50144df518461398a9b3397ee4842b346708Chris Banes                w = (int) tvw.getDimension(metrics);
40256fd50144df518461398a9b3397ee4842b346708Chris Banes            } else if (tvw.type == TypedValue.TYPE_FRACTION) {
40356fd50144df518461398a9b3397ee4842b346708Chris Banes                w = (int) tvw.getFraction(metrics.widthPixels, metrics.widthPixels);
40456fd50144df518461398a9b3397ee4842b346708Chris Banes            }
40556fd50144df518461398a9b3397ee4842b346708Chris Banes        }
40656fd50144df518461398a9b3397ee4842b346708Chris Banes
40756fd50144df518461398a9b3397ee4842b346708Chris Banes        final TypedValue tvh = isPortrait ? mFixedHeightMajor : mFixedHeightMinor;
40856fd50144df518461398a9b3397ee4842b346708Chris Banes        if (tvh != null && tvh.type != TypedValue.TYPE_NULL) {
40956fd50144df518461398a9b3397ee4842b346708Chris Banes            if (tvh.type == TypedValue.TYPE_DIMENSION) {
41056fd50144df518461398a9b3397ee4842b346708Chris Banes                h = (int) tvh.getDimension(metrics);
41156fd50144df518461398a9b3397ee4842b346708Chris Banes            } else if (tvh.type == TypedValue.TYPE_FRACTION) {
41256fd50144df518461398a9b3397ee4842b346708Chris Banes                h = (int) tvh.getFraction(metrics.heightPixels, metrics.heightPixels);
41356fd50144df518461398a9b3397ee4842b346708Chris Banes            }
41456fd50144df518461398a9b3397ee4842b346708Chris Banes        }
41556fd50144df518461398a9b3397ee4842b346708Chris Banes
41656fd50144df518461398a9b3397ee4842b346708Chris Banes        if (w != ViewGroup.LayoutParams.MATCH_PARENT || h != ViewGroup.LayoutParams.MATCH_PARENT) {
41756fd50144df518461398a9b3397ee4842b346708Chris Banes            mActivity.getWindow().setLayout(w, h);
41856fd50144df518461398a9b3397ee4842b346708Chris Banes        }
41956fd50144df518461398a9b3397ee4842b346708Chris Banes
42056fd50144df518461398a9b3397ee4842b346708Chris Banes        a.recycle();
42156fd50144df518461398a9b3397ee4842b346708Chris Banes    }
42256fd50144df518461398a9b3397ee4842b346708Chris Banes
4236386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
424ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    public boolean supportRequestWindowFeature(int featureId) {
4256386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        switch (featureId) {
42600d183885b54de433e43118d3032340f40cac8c0Chris Banes            case FEATURE_ACTION_BAR:
4275a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes                mHasActionBar = true;
4286386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes                return true;
42900d183885b54de433e43118d3032340f40cac8c0Chris Banes            case FEATURE_ACTION_BAR_OVERLAY:
4305a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes                mOverlayActionBar = true;
4316386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes                return true;
43200d183885b54de433e43118d3032340f40cac8c0Chris Banes            case FEATURE_ACTION_MODE_OVERLAY:
433de9f38cc4a30b33ac46b105edf470fbc4a044e99Chris Banes                mOverlayActionMode = true;
434de9f38cc4a30b33ac46b105edf470fbc4a044e99Chris Banes                return true;
435ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            case Window.FEATURE_PROGRESS:
436ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                mFeatureProgress = true;
437ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                return true;
438ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            case Window.FEATURE_INDETERMINATE_PROGRESS:
439ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                mFeatureIndeterminateProgress = true;
440ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                return true;
4416386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes            default:
4426386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes                return mActivity.requestWindowFeature(featureId);
4436386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        }
4446386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
4456386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
4466386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
447904507029cd8ea2d070b6df0911b2dd36b7075a6Chris Banes    public void onTitleChanged(CharSequence title) {
44849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (mDecorContentParent != null) {
44949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            mDecorContentParent.setWindowTitle(title);
45049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        } else if (getSupportActionBar() != null) {
451ca58f2ce7cd9f0e0f2c4a46c3bcc98013209f6b3Chris Banes            getSupportActionBar().setWindowTitle(title);
452f53c7bf3146bf9bcba46324f9f06449df475be36Chris Banes        } else {
453f53c7bf3146bf9bcba46324f9f06449df475be36Chris Banes            mTitleToSet = title;
4546386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        }
4556386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
4566386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
4576386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
4586386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public View onCreatePanelView(int featureId) {
45957c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        View panelView = null;
46057c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes
46157c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        // If there isn't an action mode currently being displayed
46200d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (mActionMode == null) {
46357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            // Let our window callback try first
46457c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            WindowCallback callback = getWindowCallback();
46557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            if (callback != null) {
46657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                panelView = callback.onCreatePanelView(featureId);
46757c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            }
46857c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes
46957c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            if (panelView == null) {
47057c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                // If the callback didn't return a view, check our panels
47157c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                PanelFeatureState st = getPanelState(featureId, true);
47257c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                openPanel(st, null);
47357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                if (st.isOpen) {
47457c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                    panelView = st.shownPanelView;
47557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                }
47657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            }
4776386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        }
47857c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        return panelView;
4796386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
4806386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
4816386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
48230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    public boolean onCreatePanelMenu(int featureId, Menu menu) {
48330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        if (featureId != Window.FEATURE_OPTIONS_PANEL) {
484a6e86333cb4de18fc9b86746a49643e213db7c18Chris Banes            return getWindowCallback().onCreatePanelMenu(featureId, menu);
4856386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        }
4866386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        return false;
4876386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
4886386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
4896386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
49030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    public boolean onPreparePanel(int featureId, View view, Menu menu) {
49130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        if (featureId != Window.FEATURE_OPTIONS_PANEL) {
492a6e86333cb4de18fc9b86746a49643e213db7c18Chris Banes            return getWindowCallback().onPreparePanel(featureId, view, menu);
4936386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        }
4946386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        return false;
4956386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
4966386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
4976386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
49800d183885b54de433e43118d3032340f40cac8c0Chris Banes    public void onPanelClosed(final int featureId, Menu menu) {
49900d183885b54de433e43118d3032340f40cac8c0Chris Banes        PanelFeatureState st = getPanelState(featureId, false);
50000d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st != null) {
50100d183885b54de433e43118d3032340f40cac8c0Chris Banes            // If we know about the feature id, update it's state
50200d183885b54de433e43118d3032340f40cac8c0Chris Banes            closePanel(st, false);
50303fc11b659da1645507062bddda450136e13af35Chris Banes        }
50400d183885b54de433e43118d3032340f40cac8c0Chris Banes
50500d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (featureId == FEATURE_ACTION_BAR) {
50600d183885b54de433e43118d3032340f40cac8c0Chris Banes            ActionBar ab = getSupportActionBar();
50700d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (ab != null) {
50800d183885b54de433e43118d3032340f40cac8c0Chris Banes                ab.dispatchMenuVisibilityChanged(false);
50900d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
5109b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        } else if (!isDestroyed()) {
51100d183885b54de433e43118d3032340f40cac8c0Chris Banes            // Only pass it through to the Activity's super impl if it's not ACTION_BAR. This is
51200d183885b54de433e43118d3032340f40cac8c0Chris Banes            // because ICS+ will try and create a framework action bar due to this call
513c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes            mActivity.superOnPanelClosed(featureId, menu);
514c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes        }
515c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes    }
516c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes
517c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes    @Override
51800d183885b54de433e43118d3032340f40cac8c0Chris Banes    boolean onMenuOpened(final int featureId, Menu menu) {
51900d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (featureId == FEATURE_ACTION_BAR) {
52000d183885b54de433e43118d3032340f40cac8c0Chris Banes            ActionBar ab = getSupportActionBar();
52100d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (ab != null) {
52200d183885b54de433e43118d3032340f40cac8c0Chris Banes                ab.dispatchMenuVisibilityChanged(true);
52300d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
52400d183885b54de433e43118d3032340f40cac8c0Chris Banes            return true;
52500d183885b54de433e43118d3032340f40cac8c0Chris Banes        } else {
526c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes            return mActivity.superOnMenuOpened(featureId, menu);
527c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes        }
52803fc11b659da1645507062bddda450136e13af35Chris Banes    }
52903fc11b659da1645507062bddda450136e13af35Chris Banes
53003fc11b659da1645507062bddda450136e13af35Chris Banes    @Override
5316386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
5329b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        final WindowCallback cb = getWindowCallback();
5339b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        if (cb != null && !isDestroyed()) {
5349b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes            final PanelFeatureState panel = findMenuPanel(menu.getRootMenu());
5359b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes            if (panel != null) {
5369b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                return cb.onMenuItemSelected(panel.featureId, item);
5379b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes            }
5389b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        }
5399b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        return false;
5406386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
5416386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
5426386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
5436386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public void onMenuModeChange(MenuBuilder menu) {
5446386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        reopenMenu(menu, true);
5456386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
5466386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
5476386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
548d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    public ActionMode startSupportActionMode(ActionMode.Callback callback) {
549d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        if (callback == null) {
550d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            throw new IllegalArgumentException("ActionMode callback can not be null.");
551d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
552d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
553d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        if (mActionMode != null) {
554d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            mActionMode.finish();
555d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
556d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
557d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        final ActionMode.Callback wrappedCallback = new ActionModeCallbackWrapper(callback);
558d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
55949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        ActionBar ab = getSupportActionBar();
560d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        if (ab != null) {
5615a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes            mActionMode = ab.startActionMode(wrappedCallback);
5620bf48858279237f95d6aad565a074490745491cdChris Banes            if (mActionMode != null) {
5630bf48858279237f95d6aad565a074490745491cdChris Banes                mActivity.onSupportActionModeStarted(mActionMode);
5640bf48858279237f95d6aad565a074490745491cdChris Banes            }
565d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
566d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
5670bf48858279237f95d6aad565a074490745491cdChris Banes        if (mActionMode == null) {
5680bf48858279237f95d6aad565a074490745491cdChris Banes            // If the action bar didn't provide an action mode, start the emulated window one
5690bf48858279237f95d6aad565a074490745491cdChris Banes            mActionMode = startSupportActionModeFromWindow(wrappedCallback);
570d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
5710bf48858279237f95d6aad565a074490745491cdChris Banes
572d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        return mActionMode;
573d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    }
574d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
575d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    @Override
5766386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public void supportInvalidateOptionsMenu() {
577f2045f06bdfc9e2cc40a734e41e45d11adf2bc23Chris Banes        final ActionBar ab = getSupportActionBar();
578f2045f06bdfc9e2cc40a734e41e45d11adf2bc23Chris Banes        if (ab != null && ab.invalidateOptionsMenu()) return;
579f2045f06bdfc9e2cc40a734e41e45d11adf2bc23Chris Banes
58000d183885b54de433e43118d3032340f40cac8c0Chris Banes        invalidatePanelMenu(FEATURE_OPTIONS_PANEL);
5816386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
5826386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
5834c2a95906254748cb9a843b061288265d6e185a9Chris Banes    @Override
5844c2a95906254748cb9a843b061288265d6e185a9Chris Banes    ActionMode startSupportActionModeFromWindow(ActionMode.Callback callback) {
5854c2a95906254748cb9a843b061288265d6e185a9Chris Banes        if (mActionMode != null) {
5864c2a95906254748cb9a843b061288265d6e185a9Chris Banes            mActionMode.finish();
5874c2a95906254748cb9a843b061288265d6e185a9Chris Banes        }
5884c2a95906254748cb9a843b061288265d6e185a9Chris Banes
5894c2a95906254748cb9a843b061288265d6e185a9Chris Banes        final ActionMode.Callback wrappedCallback = new ActionModeCallbackWrapper(callback);
5904bd5cbd6ca4f1e5ed43217b808068a48f937feabChris Banes        final Context context = getActionBarThemedContext();
5914c2a95906254748cb9a843b061288265d6e185a9Chris Banes
5924c2a95906254748cb9a843b061288265d6e185a9Chris Banes        if (mActionModeView == null) {
5934c2a95906254748cb9a843b061288265d6e185a9Chris Banes            if (mIsFloating) {
5944bd5cbd6ca4f1e5ed43217b808068a48f937feabChris Banes                mActionModeView = new ActionBarContextView(context);
5954bd5cbd6ca4f1e5ed43217b808068a48f937feabChris Banes                mActionModePopup = new PopupWindow(context, null,
5964c2a95906254748cb9a843b061288265d6e185a9Chris Banes                        R.attr.actionModePopupWindowStyle);
5974c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionModePopup.setContentView(mActionModeView);
5984c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionModePopup.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
5994c2a95906254748cb9a843b061288265d6e185a9Chris Banes
6004c2a95906254748cb9a843b061288265d6e185a9Chris Banes                TypedValue heightValue = new TypedValue();
6014c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActivity.getTheme().resolveAttribute(R.attr.actionBarSize, heightValue, true);
6024c2a95906254748cb9a843b061288265d6e185a9Chris Banes                final int height = TypedValue.complexToDimensionPixelSize(heightValue.data,
6034c2a95906254748cb9a843b061288265d6e185a9Chris Banes                        mActivity.getResources().getDisplayMetrics());
6044c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionModeView.setContentHeight(height);
6054c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionModePopup.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
6064c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mShowActionModePopup = new Runnable() {
6074c2a95906254748cb9a843b061288265d6e185a9Chris Banes                    public void run() {
6084c2a95906254748cb9a843b061288265d6e185a9Chris Banes                        mActionModePopup.showAtLocation(
6094c2a95906254748cb9a843b061288265d6e185a9Chris Banes                                mActionModeView,
6104c2a95906254748cb9a843b061288265d6e185a9Chris Banes                                Gravity.TOP | Gravity.FILL_HORIZONTAL, 0, 0);
6114c2a95906254748cb9a843b061288265d6e185a9Chris Banes                    }
6124c2a95906254748cb9a843b061288265d6e185a9Chris Banes                };
6134c2a95906254748cb9a843b061288265d6e185a9Chris Banes            } else {
6144bd5cbd6ca4f1e5ed43217b808068a48f937feabChris Banes                ViewStubCompat stub = (ViewStubCompat) mActivity
6154bd5cbd6ca4f1e5ed43217b808068a48f937feabChris Banes                        .findViewById(R.id.action_mode_bar_stub);
6164c2a95906254748cb9a843b061288265d6e185a9Chris Banes                if (stub != null) {
6174bd5cbd6ca4f1e5ed43217b808068a48f937feabChris Banes                    // Set the layout inflater so that it is inflated with the action bar's context
6184bd5cbd6ca4f1e5ed43217b808068a48f937feabChris Banes                    stub.setLayoutInflater(LayoutInflater.from(context));
6194c2a95906254748cb9a843b061288265d6e185a9Chris Banes                    mActionModeView = (ActionBarContextView) stub.inflate();
6204c2a95906254748cb9a843b061288265d6e185a9Chris Banes                }
6214c2a95906254748cb9a843b061288265d6e185a9Chris Banes            }
6224c2a95906254748cb9a843b061288265d6e185a9Chris Banes        }
6234c2a95906254748cb9a843b061288265d6e185a9Chris Banes
6244c2a95906254748cb9a843b061288265d6e185a9Chris Banes        if (mActionModeView != null) {
6254c2a95906254748cb9a843b061288265d6e185a9Chris Banes            mActionModeView.killMode();
6264bd5cbd6ca4f1e5ed43217b808068a48f937feabChris Banes            ActionMode mode = new StandaloneActionMode(context, mActionModeView, wrappedCallback,
6274c2a95906254748cb9a843b061288265d6e185a9Chris Banes                    mActionModePopup == null);
6284c2a95906254748cb9a843b061288265d6e185a9Chris Banes            if (callback.onCreateActionMode(mode, mode.getMenu())) {
6294c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mode.invalidate();
6304c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionModeView.initForMode(mode);
6314c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionModeView.setVisibility(View.VISIBLE);
6324c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionMode = mode;
6334c2a95906254748cb9a843b061288265d6e185a9Chris Banes                if (mActionModePopup != null) {
6344c2a95906254748cb9a843b061288265d6e185a9Chris Banes                    mActivity.getWindow().getDecorView().post(mShowActionModePopup);
6354c2a95906254748cb9a843b061288265d6e185a9Chris Banes                }
6364c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionModeView.sendAccessibilityEvent(
6374c2a95906254748cb9a843b061288265d6e185a9Chris Banes                        AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
638ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes
639ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                if (mActionModeView.getParent() != null) {
640ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                    ViewCompat.requestApplyInsets((View) mActionModeView.getParent());
641ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                }
6424c2a95906254748cb9a843b061288265d6e185a9Chris Banes            } else {
6434c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionMode = null;
6444c2a95906254748cb9a843b061288265d6e185a9Chris Banes            }
6454c2a95906254748cb9a843b061288265d6e185a9Chris Banes        }
6464c2a95906254748cb9a843b061288265d6e185a9Chris Banes        if (mActionMode != null && mActivity != null) {
6474c2a95906254748cb9a843b061288265d6e185a9Chris Banes            mActivity.onSupportActionModeStarted(mActionMode);
6484c2a95906254748cb9a843b061288265d6e185a9Chris Banes        }
6494c2a95906254748cb9a843b061288265d6e185a9Chris Banes        return mActionMode;
6504c2a95906254748cb9a843b061288265d6e185a9Chris Banes    }
6514c2a95906254748cb9a843b061288265d6e185a9Chris Banes
652d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    @Override
653d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    public boolean onBackPressed() {
654d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        // Back cancels action modes first.
655d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        if (mActionMode != null) {
656d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            mActionMode.finish();
657d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            return true;
658d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
659d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
660d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        // Next collapse any expanded action views.
66149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        ActionBar ab = getSupportActionBar();
66249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (ab != null && ab.collapseActionView()) {
663d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            return true;
664d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
665d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
666d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        return false;
667d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    }
668d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
669d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    @Override
670ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    void setSupportProgressBarVisibility(boolean visible) {
671ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        updateProgressBars(visible ? Window.PROGRESS_VISIBILITY_ON :
672ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                Window.PROGRESS_VISIBILITY_OFF);
673ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    }
674ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
675ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    @Override
676ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    void setSupportProgressBarIndeterminateVisibility(boolean visible) {
677ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        updateProgressBars(visible ? Window.PROGRESS_VISIBILITY_ON :
678ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                Window.PROGRESS_VISIBILITY_OFF);
679ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    }
680ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
681ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    @Override
682ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    void setSupportProgressBarIndeterminate(boolean indeterminate) {
683ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        updateProgressBars(indeterminate ? Window.PROGRESS_INDETERMINATE_ON
684ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                : Window.PROGRESS_INDETERMINATE_OFF);
685ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    }
686ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
687ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    @Override
688ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    void setSupportProgress(int progress) {
689ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        updateProgressBars(Window.PROGRESS_START + progress);
690ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    }
691ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
69245d973fcc4c43f5ea00cddd3d9b947d9e8d8fc4eChris Banes    @Override
693f4a93d160fc696de65e103e7e078106ea8f818faChris Banes    int getHomeAsUpIndicatorAttrId() {
694f4a93d160fc696de65e103e7e078106ea8f818faChris Banes        return R.attr.homeAsUpIndicator;
69545d973fcc4c43f5ea00cddd3d9b947d9e8d8fc4eChris Banes    }
69645d973fcc4c43f5ea00cddd3d9b947d9e8d8fc4eChris Banes
697dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes    @Override
69800d183885b54de433e43118d3032340f40cac8c0Chris Banes    boolean onKeyShortcut(int keyCode, KeyEvent ev) {
699dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        // If the panel is already prepared, then perform the shortcut using it.
70000d183885b54de433e43118d3032340f40cac8c0Chris Banes        boolean handled;
70100d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (mPreparedPanel != null) {
70200d183885b54de433e43118d3032340f40cac8c0Chris Banes            handled = performPanelShortcut(mPreparedPanel, ev.getKeyCode(), ev,
70300d183885b54de433e43118d3032340f40cac8c0Chris Banes                    Menu.FLAG_PERFORM_NO_CLOSE);
70400d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (handled) {
70500d183885b54de433e43118d3032340f40cac8c0Chris Banes                if (mPreparedPanel != null) {
70600d183885b54de433e43118d3032340f40cac8c0Chris Banes                    mPreparedPanel.isHandled = true;
70700d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
70800d183885b54de433e43118d3032340f40cac8c0Chris Banes                return true;
70900d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
71000d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
71100d183885b54de433e43118d3032340f40cac8c0Chris Banes
71200d183885b54de433e43118d3032340f40cac8c0Chris Banes        // If the panel is not prepared, then we may be trying to handle a shortcut key
71300d183885b54de433e43118d3032340f40cac8c0Chris Banes        // combination such as Control+C.  Temporarily prepare the panel then mark it
71400d183885b54de433e43118d3032340f40cac8c0Chris Banes        // unprepared again when finished to ensure that the panel will again be prepared
71500d183885b54de433e43118d3032340f40cac8c0Chris Banes        // the next time it is shown for real.
71600d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (mPreparedPanel == null) {
71700d183885b54de433e43118d3032340f40cac8c0Chris Banes            PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
71800d183885b54de433e43118d3032340f40cac8c0Chris Banes            preparePanel(st, ev);
71900d183885b54de433e43118d3032340f40cac8c0Chris Banes            handled = performPanelShortcut(st, ev.getKeyCode(), ev, Menu.FLAG_PERFORM_NO_CLOSE);
72000d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.isPrepared = false;
72100d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (handled) {
72200d183885b54de433e43118d3032340f40cac8c0Chris Banes                return true;
72300d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
72400d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
72500d183885b54de433e43118d3032340f40cac8c0Chris Banes        return false;
726dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes    }
727dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes
728dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes    @Override
729dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes    boolean onKeyDown(int keyCode, KeyEvent event) {
730dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        // On API v7-10 we need to manually call onKeyShortcut() as this is not called
731dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        // from the Activity
732dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        return onKeyShortcut(keyCode, event);
733dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes    }
734dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes
735469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes    @Override
736469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes    View createView(final String name, @NonNull AttributeSet attrs) {
737469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes        if (Build.VERSION.SDK_INT < 21) {
738469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes            // If we're running pre-L, we need to 'inject' our tint aware Views in place of the
739469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes            // standard framework versions
740469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes            switch (name) {
741469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes                case "EditText":
742469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes                    return new TintEditText(mActivity, attrs);
743415f740df4981ef2f5fb462a50c7cf095cc21128Chris Banes                case "Spinner":
744415f740df4981ef2f5fb462a50c7cf095cc21128Chris Banes                    return new TintSpinner(mActivity, attrs);
745415f740df4981ef2f5fb462a50c7cf095cc21128Chris Banes                case "CheckBox":
746415f740df4981ef2f5fb462a50c7cf095cc21128Chris Banes                    return new TintCheckBox(mActivity, attrs);
747415f740df4981ef2f5fb462a50c7cf095cc21128Chris Banes                case "RadioButton":
748415f740df4981ef2f5fb462a50c7cf095cc21128Chris Banes                    return new TintRadioButton(mActivity, attrs);
749415f740df4981ef2f5fb462a50c7cf095cc21128Chris Banes                case "CheckedTextView":
750415f740df4981ef2f5fb462a50c7cf095cc21128Chris Banes                    return new TintCheckedTextView(mActivity, attrs);
751469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes            }
752469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes        }
753469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes        return null;
754469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes    }
755469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes
756d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    /**
757ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes     * Progress Bar function. Mostly extracted from PhoneWindow.java
758ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes     */
759ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    private void updateProgressBars(int value) {
76049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        ProgressBarCompat circularProgressBar = getCircularProgressBar();
76149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        ProgressBarCompat horizontalProgressBar = getHorizontalProgressBar();
762ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
763ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        if (value == Window.PROGRESS_VISIBILITY_ON) {
764ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            if (mFeatureProgress) {
765ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                int level = horizontalProgressBar.getProgress();
766ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                int visibility = (horizontalProgressBar.isIndeterminate() || level < 10000) ?
767ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                        View.VISIBLE : View.INVISIBLE;
768ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                horizontalProgressBar.setVisibility(visibility);
769ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            }
770ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            if (mFeatureIndeterminateProgress) {
771ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                circularProgressBar.setVisibility(View.VISIBLE);
772ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            }
773ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        } else if (value == Window.PROGRESS_VISIBILITY_OFF) {
774ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            if (mFeatureProgress) {
775ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                horizontalProgressBar.setVisibility(View.GONE);
776ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            }
777ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            if (mFeatureIndeterminateProgress) {
778ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                circularProgressBar.setVisibility(View.GONE);
779ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            }
780ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        } else if (value == Window.PROGRESS_INDETERMINATE_ON) {
781ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            horizontalProgressBar.setIndeterminate(true);
782ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        } else if (value == Window.PROGRESS_INDETERMINATE_OFF) {
783ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            horizontalProgressBar.setIndeterminate(false);
784ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        } else if (Window.PROGRESS_START <= value && value <= Window.PROGRESS_END) {
785ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            // We want to set the progress value before testing for visibility
786ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            // so that when the progress bar becomes visible again, it has the
787ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            // correct level.
788ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            horizontalProgressBar.setProgress(value - Window.PROGRESS_START);
789ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
790ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            if (value < Window.PROGRESS_END) {
791ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                showProgressBars(horizontalProgressBar, circularProgressBar);
792ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            } else {
793ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                hideProgressBars(horizontalProgressBar, circularProgressBar);
794ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            }
795ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        }
796ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    }
797ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
79800d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void openPanel(int featureId, KeyEvent event) {
79900d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (featureId == FEATURE_OPTIONS_PANEL && mDecorContentParent != null &&
80000d183885b54de433e43118d3032340f40cac8c0Chris Banes                mDecorContentParent.canShowOverflowMenu() &&
80100d183885b54de433e43118d3032340f40cac8c0Chris Banes                !ViewConfigurationCompat.hasPermanentMenuKey(ViewConfiguration.get(mActivity))) {
80200d183885b54de433e43118d3032340f40cac8c0Chris Banes            mDecorContentParent.showOverflowMenu();
80300d183885b54de433e43118d3032340f40cac8c0Chris Banes        } else {
80400d183885b54de433e43118d3032340f40cac8c0Chris Banes            openPanel(getPanelState(featureId, true), event);
80500d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
80600d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
80700d183885b54de433e43118d3032340f40cac8c0Chris Banes
80800d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void openPanel(final PanelFeatureState st, KeyEvent event) {
80900d183885b54de433e43118d3032340f40cac8c0Chris Banes        // Already open, return
8109b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        if (st.isOpen || isDestroyed()) {
81100d183885b54de433e43118d3032340f40cac8c0Chris Banes            return;
81200d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
81300d183885b54de433e43118d3032340f40cac8c0Chris Banes
81400d183885b54de433e43118d3032340f40cac8c0Chris Banes        // Don't open an options panel for honeycomb apps on xlarge devices.
81500d183885b54de433e43118d3032340f40cac8c0Chris Banes        // (The app should be using an action bar for menu items.)
81600d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st.featureId == FEATURE_OPTIONS_PANEL) {
81700d183885b54de433e43118d3032340f40cac8c0Chris Banes            Context context = mActivity;
81800d183885b54de433e43118d3032340f40cac8c0Chris Banes            Configuration config = context.getResources().getConfiguration();
81900d183885b54de433e43118d3032340f40cac8c0Chris Banes            boolean isXLarge = (config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) ==
82000d183885b54de433e43118d3032340f40cac8c0Chris Banes                    Configuration.SCREENLAYOUT_SIZE_XLARGE;
82100d183885b54de433e43118d3032340f40cac8c0Chris Banes            boolean isHoneycombApp = context.getApplicationInfo().targetSdkVersion >=
82200d183885b54de433e43118d3032340f40cac8c0Chris Banes                    android.os.Build.VERSION_CODES.HONEYCOMB;
82300d183885b54de433e43118d3032340f40cac8c0Chris Banes
82400d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (isXLarge && isHoneycombApp) {
82500d183885b54de433e43118d3032340f40cac8c0Chris Banes                return;
82600d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
82700d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
82800d183885b54de433e43118d3032340f40cac8c0Chris Banes
82900d183885b54de433e43118d3032340f40cac8c0Chris Banes        WindowCallback cb = getWindowCallback();
83000d183885b54de433e43118d3032340f40cac8c0Chris Banes        if ((cb != null) && (!cb.onMenuOpened(st.featureId, st.menu))) {
83100d183885b54de433e43118d3032340f40cac8c0Chris Banes            // Callback doesn't want the menu to open, reset any state
83200d183885b54de433e43118d3032340f40cac8c0Chris Banes            closePanel(st, true);
83300d183885b54de433e43118d3032340f40cac8c0Chris Banes            return;
83400d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
83500d183885b54de433e43118d3032340f40cac8c0Chris Banes
83600d183885b54de433e43118d3032340f40cac8c0Chris Banes        // Prepare panel (should have been done before, but just in case)
83700d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (!preparePanel(st, event)) {
83800d183885b54de433e43118d3032340f40cac8c0Chris Banes            return;
83900d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
84000d183885b54de433e43118d3032340f40cac8c0Chris Banes
84100d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st.decorView == null || st.refreshDecorView) {
84200d183885b54de433e43118d3032340f40cac8c0Chris Banes            initializePanelDecor(st);
84300d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
84400d183885b54de433e43118d3032340f40cac8c0Chris Banes
84500d183885b54de433e43118d3032340f40cac8c0Chris Banes        // This will populate st.shownPanelView
84600d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (!initializePanelContent(st) || !st.hasPanelItems()) {
84700d183885b54de433e43118d3032340f40cac8c0Chris Banes            return;
84800d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
84900d183885b54de433e43118d3032340f40cac8c0Chris Banes
85000d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.isHandled = false;
85100d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.isOpen = true;
85200d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
85300d183885b54de433e43118d3032340f40cac8c0Chris Banes
85400d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void initializePanelDecor(PanelFeatureState st) {
85500d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.decorView = mWindowDecor;
85657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        st.setStyle(getActionBarThemedContext());
85700d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
85800d183885b54de433e43118d3032340f40cac8c0Chris Banes
85900d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void reopenMenu(MenuBuilder menu, boolean toggleMenuMode) {
86000d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (mDecorContentParent != null && mDecorContentParent.canShowOverflowMenu() &&
86100d183885b54de433e43118d3032340f40cac8c0Chris Banes                (!ViewConfigurationCompat.hasPermanentMenuKey(ViewConfiguration.get(mActivity)) ||
86200d183885b54de433e43118d3032340f40cac8c0Chris Banes                        mDecorContentParent.isOverflowMenuShowPending())) {
8639b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes
8649b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes            WindowCallback cb = getWindowCallback();
8659b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes
86600d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (!mDecorContentParent.isOverflowMenuShowing() || !toggleMenuMode) {
8679b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                if (cb != null && !isDestroyed()) {
8689b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    // If we have a menu invalidation pending, do it now.
8699b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    if (mInvalidatePanelMenuPosted &&
8709b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                            (mInvalidatePanelMenuFeatures & (1 << FEATURE_OPTIONS_PANEL)) != 0) {
8719b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                        mWindowDecor.removeCallbacks(mInvalidatePanelMenuRunnable);
8729b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                        mInvalidatePanelMenuRunnable.run();
8739b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    }
87400d183885b54de433e43118d3032340f40cac8c0Chris Banes
8759b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
87600d183885b54de433e43118d3032340f40cac8c0Chris Banes
8779b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    // If we don't have a menu or we're waiting for a full content refresh,
8789b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    // forget it. This is a lingering event that no longer matters.
8799b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    if (st.menu != null && !st.refreshMenuContent &&
8809b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                            cb.onPreparePanel(FEATURE_OPTIONS_PANEL, null, st.menu)) {
8819b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                        cb.onMenuOpened(FEATURE_ACTION_BAR, st.menu);
8829b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                        mDecorContentParent.showOverflowMenu();
8839b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    }
88400d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
88500d183885b54de433e43118d3032340f40cac8c0Chris Banes            } else {
88600d183885b54de433e43118d3032340f40cac8c0Chris Banes                mDecorContentParent.hideOverflowMenu();
8879b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                if (!isDestroyed()) {
8889b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
8899b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    mActivity.onPanelClosed(FEATURE_ACTION_BAR, st.menu);
8909b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                }
89100d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
89200d183885b54de433e43118d3032340f40cac8c0Chris Banes            return;
89300d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
89400d183885b54de433e43118d3032340f40cac8c0Chris Banes
89500d183885b54de433e43118d3032340f40cac8c0Chris Banes        PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
89600d183885b54de433e43118d3032340f40cac8c0Chris Banes
89700d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.refreshDecorView = true;
89800d183885b54de433e43118d3032340f40cac8c0Chris Banes        closePanel(st, false);
89900d183885b54de433e43118d3032340f40cac8c0Chris Banes
90000d183885b54de433e43118d3032340f40cac8c0Chris Banes        openPanel(st, null);
90100d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
90200d183885b54de433e43118d3032340f40cac8c0Chris Banes
90349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    private void showProgressBars(ProgressBarCompat horizontalProgressBar,
90449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            ProgressBarCompat spinnyProgressBar) {
905ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        if (mFeatureIndeterminateProgress && spinnyProgressBar.getVisibility() == View.INVISIBLE) {
906ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            spinnyProgressBar.setVisibility(View.VISIBLE);
907ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        }
908ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        // Only show the progress bars if the primary progress is not complete
909ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        if (mFeatureProgress && horizontalProgressBar.getProgress() < 10000) {
910ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            horizontalProgressBar.setVisibility(View.VISIBLE);
911ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        }
912ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    }
913ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
91449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    private void hideProgressBars(ProgressBarCompat horizontalProgressBar,
91549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            ProgressBarCompat spinnyProgressBar) {
916ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        if (mFeatureIndeterminateProgress && spinnyProgressBar.getVisibility() == View.VISIBLE) {
917ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            spinnyProgressBar.setVisibility(View.INVISIBLE);
918ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        }
919ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        if (mFeatureProgress && horizontalProgressBar.getVisibility() == View.VISIBLE) {
920ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            horizontalProgressBar.setVisibility(View.INVISIBLE);
921ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        }
922ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    }
923ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
92449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    private ProgressBarCompat getCircularProgressBar() {
92549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        ProgressBarCompat pb = (ProgressBarCompat) mActivity.findViewById(R.id.progress_circular);
926ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        if (pb != null) {
927ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            pb.setVisibility(View.INVISIBLE);
928ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        }
929ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        return pb;
930ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    }
931ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
93249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    private ProgressBarCompat getHorizontalProgressBar() {
93349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        ProgressBarCompat pb = (ProgressBarCompat) mActivity.findViewById(R.id.progress_horizontal);
934ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        if (pb != null) {
935ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            pb.setVisibility(View.INVISIBLE);
936ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        }
937ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes        return pb;
938ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    }
939ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
94000d183885b54de433e43118d3032340f40cac8c0Chris Banes    private boolean initializePanelMenu(final PanelFeatureState st) {
94161c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes        Context context = mActivity;
94261c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes
94300d183885b54de433e43118d3032340f40cac8c0Chris Banes        // If we have an action bar, initialize the menu with the right theme.
94400d183885b54de433e43118d3032340f40cac8c0Chris Banes        if ((st.featureId == FEATURE_OPTIONS_PANEL || st.featureId == FEATURE_ACTION_BAR) &&
94500d183885b54de433e43118d3032340f40cac8c0Chris Banes                mDecorContentParent != null) {
94661c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            final TypedValue outValue = new TypedValue();
94761c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            final Resources.Theme baseTheme = context.getTheme();
94861c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            baseTheme.resolveAttribute(R.attr.actionBarTheme, outValue, true);
94961c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes
95061c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            Resources.Theme widgetTheme = null;
95161c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            if (outValue.resourceId != 0) {
95261c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                widgetTheme = context.getResources().newTheme();
95361c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                widgetTheme.setTo(baseTheme);
95461c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                widgetTheme.applyStyle(outValue.resourceId, true);
95561c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                widgetTheme.resolveAttribute(
95661c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                        R.attr.actionBarWidgetTheme, outValue, true);
95761c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            } else {
95861c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                baseTheme.resolveAttribute(
95961c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                        R.attr.actionBarWidgetTheme, outValue, true);
96061c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            }
96161c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes
96261c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            if (outValue.resourceId != 0) {
96361c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                if (widgetTheme == null) {
96461c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                    widgetTheme = context.getResources().newTheme();
96561c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                    widgetTheme.setTo(baseTheme);
96661c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                }
96761c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                widgetTheme.applyStyle(outValue.resourceId, true);
96861c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            }
96961c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes
97061c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            if (widgetTheme != null) {
97161c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                context = new ContextThemeWrapper(context, 0);
97261c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                context.getTheme().setTo(widgetTheme);
97361c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            }
97461c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes        }
97561c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes
97600d183885b54de433e43118d3032340f40cac8c0Chris Banes        final MenuBuilder menu = new MenuBuilder(context);
97700d183885b54de433e43118d3032340f40cac8c0Chris Banes        menu.setCallback(this);
97800d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.setMenu(menu);
97961c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes
9808902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        return true;
9818902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes    }
9828902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
98300d183885b54de433e43118d3032340f40cac8c0Chris Banes    private boolean initializePanelContent(PanelFeatureState st) {
98400d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st.menu == null) {
98500d183885b54de433e43118d3032340f40cac8c0Chris Banes            return false;
98600d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
98700d183885b54de433e43118d3032340f40cac8c0Chris Banes
98800d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (mPanelMenuPresenterCallback == null) {
98900d183885b54de433e43118d3032340f40cac8c0Chris Banes            mPanelMenuPresenterCallback = new PanelMenuPresenterCallback();
99000d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
99100d183885b54de433e43118d3032340f40cac8c0Chris Banes
99257c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        MenuView menuView = st.getListMenuView(mPanelMenuPresenterCallback);
99300d183885b54de433e43118d3032340f40cac8c0Chris Banes
99400d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.shownPanelView = (View) menuView;
99500d183885b54de433e43118d3032340f40cac8c0Chris Banes
99600d183885b54de433e43118d3032340f40cac8c0Chris Banes        return st.shownPanelView != null;
99700d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
99800d183885b54de433e43118d3032340f40cac8c0Chris Banes
99900d183885b54de433e43118d3032340f40cac8c0Chris Banes    private boolean preparePanel(PanelFeatureState st, KeyEvent event) {
10009b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        if (isDestroyed()) {
10019b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes            return false;
10029b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        }
10039b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes
10048902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        // Already prepared (isPrepared will be reset to false later)
100500d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st.isPrepared) {
10068902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes            return true;
10078902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        }
10088902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
100900d183885b54de433e43118d3032340f40cac8c0Chris Banes        if ((mPreparedPanel != null) && (mPreparedPanel != st)) {
101000d183885b54de433e43118d3032340f40cac8c0Chris Banes            // Another Panel is prepared and possibly open, so close it
101100d183885b54de433e43118d3032340f40cac8c0Chris Banes            closePanel(mPreparedPanel, false);
101200d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
101300d183885b54de433e43118d3032340f40cac8c0Chris Banes
101400d183885b54de433e43118d3032340f40cac8c0Chris Banes        final boolean isActionBarMenu =
101500d183885b54de433e43118d3032340f40cac8c0Chris Banes                (st.featureId == FEATURE_OPTIONS_PANEL || st.featureId == FEATURE_ACTION_BAR);
101600d183885b54de433e43118d3032340f40cac8c0Chris Banes
101700d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (isActionBarMenu && mDecorContentParent != null) {
10188088261dec5dd277ccace13fe00f280ffa80098cChris Banes            // Enforce ordering guarantees around events so that the action bar never
10198088261dec5dd277ccace13fe00f280ffa80098cChris Banes            // dispatches menu-related events before the panel is prepared.
10208088261dec5dd277ccace13fe00f280ffa80098cChris Banes            mDecorContentParent.setMenuPrepared();
10218088261dec5dd277ccace13fe00f280ffa80098cChris Banes        }
10228088261dec5dd277ccace13fe00f280ffa80098cChris Banes
10238902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        // Init the panel state's menu--return false if init failed
102400d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st.menu == null || st.refreshMenuContent) {
102500d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (st.menu == null) {
102600d183885b54de433e43118d3032340f40cac8c0Chris Banes                if (!initializePanelMenu(st) || (st.menu == null)) {
10278902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes                    return false;
10288902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes                }
10298902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes            }
10308902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
103100d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (isActionBarMenu && mDecorContentParent != null) {
103203fc11b659da1645507062bddda450136e13af35Chris Banes                if (mActionMenuPresenterCallback == null) {
103303fc11b659da1645507062bddda450136e13af35Chris Banes                    mActionMenuPresenterCallback = new ActionMenuPresenterCallback();
103403fc11b659da1645507062bddda450136e13af35Chris Banes                }
103500d183885b54de433e43118d3032340f40cac8c0Chris Banes                mDecorContentParent.setMenu(st.menu, mActionMenuPresenterCallback);
10368902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes            }
10378902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
10388902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes            // Creating the panel menu will involve a lot of manipulation;
10398902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes            // don't dispatch change events to presenters until we're done.
104000d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.menu.stopDispatchingItemsChanged();
104100d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (!getWindowCallback().onCreatePanelMenu(st.featureId, st.menu)) {
10428902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes                // Ditch the menu created above
104300d183885b54de433e43118d3032340f40cac8c0Chris Banes                st.setMenu(null);
10448902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
104500d183885b54de433e43118d3032340f40cac8c0Chris Banes                if (isActionBarMenu && mDecorContentParent != null) {
10468902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes                    // Don't show it in the action bar either
104703fc11b659da1645507062bddda450136e13af35Chris Banes                    mDecorContentParent.setMenu(null, mActionMenuPresenterCallback);
10488902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes                }
10498902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
10508902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes                return false;
10518902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes            }
10528902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
105300d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.refreshMenuContent = false;
10548902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        }
10558902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
10568902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        // Preparing the panel menu can involve a lot of manipulation;
10578902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        // don't dispatch change events to presenters until we're done.
105800d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.menu.stopDispatchingItemsChanged();
10598902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
10608902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        // Restore action view state before we prepare. This gives apps
10618902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        // an opportunity to override frozen/restored state in onPrepare.
106200d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st.frozenActionViewState != null) {
106300d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.menu.restoreActionViewStates(st.frozenActionViewState);
106400d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.frozenActionViewState = null;
10658902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        }
10668902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
10678902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        // Callback and return if the callback does not want to show the menu
106800d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (!getWindowCallback().onPreparePanel(FEATURE_OPTIONS_PANEL, null, st.menu)) {
106900d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (isActionBarMenu && mDecorContentParent != null) {
10708902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes                // The app didn't want to show the menu for now but it still exists.
10718902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes                // Clear it out of the action bar.
107203fc11b659da1645507062bddda450136e13af35Chris Banes                mDecorContentParent.setMenu(null, mActionMenuPresenterCallback);
10738902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes            }
107400d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.menu.startDispatchingItemsChanged();
10758902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes            return false;
10768902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        }
10778902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
107800d183885b54de433e43118d3032340f40cac8c0Chris Banes        // Set the proper keymap
107900d183885b54de433e43118d3032340f40cac8c0Chris Banes        KeyCharacterMap kmap = KeyCharacterMap.load(
108000d183885b54de433e43118d3032340f40cac8c0Chris Banes                event != null ? event.getDeviceId() : KeyCharacterMap.VIRTUAL_KEYBOARD);
108100d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.qwertyMode = kmap.getKeyboardType() != KeyCharacterMap.NUMERIC;
108200d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.menu.setQwertyMode(st.qwertyMode);
108300d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.menu.startDispatchingItemsChanged();
10848902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
10858902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        // Set other state
108600d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.isPrepared = true;
108700d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.isHandled = false;
108800d183885b54de433e43118d3032340f40cac8c0Chris Banes        mPreparedPanel = st;
10898902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
10908902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        return true;
10918902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes    }
10928902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
109300d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void checkCloseActionMenu(MenuBuilder menu) {
109403fc11b659da1645507062bddda450136e13af35Chris Banes        if (mClosingActionMenu) {
109503fc11b659da1645507062bddda450136e13af35Chris Banes            return;
109603fc11b659da1645507062bddda450136e13af35Chris Banes        }
109703fc11b659da1645507062bddda450136e13af35Chris Banes
109803fc11b659da1645507062bddda450136e13af35Chris Banes        mClosingActionMenu = true;
109903fc11b659da1645507062bddda450136e13af35Chris Banes        mDecorContentParent.dismissPopups();
110000d183885b54de433e43118d3032340f40cac8c0Chris Banes        WindowCallback cb = getWindowCallback();
11019b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        if (cb != null && !isDestroyed()) {
110200d183885b54de433e43118d3032340f40cac8c0Chris Banes            cb.onPanelClosed(FEATURE_ACTION_BAR, menu);
110300d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
110403fc11b659da1645507062bddda450136e13af35Chris Banes        mClosingActionMenu = false;
110503fc11b659da1645507062bddda450136e13af35Chris Banes    }
110603fc11b659da1645507062bddda450136e13af35Chris Banes
110700d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void closePanel(PanelFeatureState st, boolean doCallback) {
110800d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (doCallback && st.featureId == FEATURE_OPTIONS_PANEL &&
110900d183885b54de433e43118d3032340f40cac8c0Chris Banes                mDecorContentParent != null && mDecorContentParent.isOverflowMenuShowing()) {
111000d183885b54de433e43118d3032340f40cac8c0Chris Banes            checkCloseActionMenu(st.menu);
111100d183885b54de433e43118d3032340f40cac8c0Chris Banes            return;
111200d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
111300d183885b54de433e43118d3032340f40cac8c0Chris Banes
111400d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st.isOpen) {
111500d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (doCallback) {
111600d183885b54de433e43118d3032340f40cac8c0Chris Banes                callOnPanelClosed(st.featureId, st, null);
111700d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
111800d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
111900d183885b54de433e43118d3032340f40cac8c0Chris Banes
112000d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.isPrepared = false;
112100d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.isHandled = false;
112200d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.isOpen = false;
112300d183885b54de433e43118d3032340f40cac8c0Chris Banes
112400d183885b54de433e43118d3032340f40cac8c0Chris Banes        // This view is no longer shown, so null it out
112500d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.shownPanelView = null;
112600d183885b54de433e43118d3032340f40cac8c0Chris Banes
112700d183885b54de433e43118d3032340f40cac8c0Chris Banes        // Next time the menu opens, it should not be in expanded mode, so
112800d183885b54de433e43118d3032340f40cac8c0Chris Banes        // force a refresh of the decor
112900d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.refreshDecorView = true;
113000d183885b54de433e43118d3032340f40cac8c0Chris Banes
113100d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (mPreparedPanel == st) {
113200d183885b54de433e43118d3032340f40cac8c0Chris Banes            mPreparedPanel = null;
113303fc11b659da1645507062bddda450136e13af35Chris Banes        }
113403fc11b659da1645507062bddda450136e13af35Chris Banes    }
113503fc11b659da1645507062bddda450136e13af35Chris Banes
113600d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void callOnPanelClosed(int featureId, PanelFeatureState panel, Menu menu) {
113700d183885b54de433e43118d3032340f40cac8c0Chris Banes        // Try to get a menu
113800d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (menu == null) {
113900d183885b54de433e43118d3032340f40cac8c0Chris Banes            // Need a panel to grab the menu, so try to get that
114000d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (panel == null) {
114100d183885b54de433e43118d3032340f40cac8c0Chris Banes                if ((featureId >= 0) && (featureId < mPanels.length)) {
114200d183885b54de433e43118d3032340f40cac8c0Chris Banes                    panel = mPanels[featureId];
114300d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
114400d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
114500d183885b54de433e43118d3032340f40cac8c0Chris Banes
114600d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (panel != null) {
114700d183885b54de433e43118d3032340f40cac8c0Chris Banes                // menu still may be null, which is okay--we tried our best
114800d183885b54de433e43118d3032340f40cac8c0Chris Banes                menu = panel.menu;
114900d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
115000d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
115100d183885b54de433e43118d3032340f40cac8c0Chris Banes
115200d183885b54de433e43118d3032340f40cac8c0Chris Banes        // If the panel is not open, do not callback
115300d183885b54de433e43118d3032340f40cac8c0Chris Banes        if ((panel != null) && (!panel.isOpen))
115400d183885b54de433e43118d3032340f40cac8c0Chris Banes            return;
115500d183885b54de433e43118d3032340f40cac8c0Chris Banes
115600d183885b54de433e43118d3032340f40cac8c0Chris Banes        getWindowCallback().onPanelClosed(featureId, menu);
115700d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
115800d183885b54de433e43118d3032340f40cac8c0Chris Banes
115900d183885b54de433e43118d3032340f40cac8c0Chris Banes    private PanelFeatureState findMenuPanel(Menu menu) {
116000d183885b54de433e43118d3032340f40cac8c0Chris Banes        final PanelFeatureState[] panels = mPanels;
116100d183885b54de433e43118d3032340f40cac8c0Chris Banes        final int N = panels != null ? panels.length : 0;
116200d183885b54de433e43118d3032340f40cac8c0Chris Banes        for (int i = 0; i < N; i++) {
116300d183885b54de433e43118d3032340f40cac8c0Chris Banes            final PanelFeatureState panel = panels[i];
116400d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (panel != null && panel.menu == menu) {
116500d183885b54de433e43118d3032340f40cac8c0Chris Banes                return panel;
116600d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
116700d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
116800d183885b54de433e43118d3032340f40cac8c0Chris Banes        return null;
116900d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
117000d183885b54de433e43118d3032340f40cac8c0Chris Banes
117100d183885b54de433e43118d3032340f40cac8c0Chris Banes    private PanelFeatureState getPanelState(int featureId, boolean required) {
117200d183885b54de433e43118d3032340f40cac8c0Chris Banes        PanelFeatureState[] ar;
117300d183885b54de433e43118d3032340f40cac8c0Chris Banes        if ((ar = mPanels) == null || ar.length <= featureId) {
117400d183885b54de433e43118d3032340f40cac8c0Chris Banes            PanelFeatureState[] nar = new PanelFeatureState[featureId + 1];
117500d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (ar != null) {
117600d183885b54de433e43118d3032340f40cac8c0Chris Banes                System.arraycopy(ar, 0, nar, 0, ar.length);
117700d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
117800d183885b54de433e43118d3032340f40cac8c0Chris Banes            mPanels = ar = nar;
117903fc11b659da1645507062bddda450136e13af35Chris Banes        }
118000d183885b54de433e43118d3032340f40cac8c0Chris Banes
118100d183885b54de433e43118d3032340f40cac8c0Chris Banes        PanelFeatureState st = ar[featureId];
118200d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st == null) {
118300d183885b54de433e43118d3032340f40cac8c0Chris Banes            ar[featureId] = st = new PanelFeatureState(featureId);
118400d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
118500d183885b54de433e43118d3032340f40cac8c0Chris Banes        return st;
118603fc11b659da1645507062bddda450136e13af35Chris Banes    }
118703fc11b659da1645507062bddda450136e13af35Chris Banes
118800d183885b54de433e43118d3032340f40cac8c0Chris Banes    final boolean performPanelShortcut(PanelFeatureState st, int keyCode, KeyEvent event,
118900d183885b54de433e43118d3032340f40cac8c0Chris Banes            int flags) {
1190dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        if (event.isSystem()) {
1191dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes            return false;
1192dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        }
1193dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes
1194dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        boolean handled = false;
1195dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes
1196dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        // Only try to perform menu shortcuts if preparePanel returned true (possible false
1197dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        // return value from application not wanting to show the menu).
119800d183885b54de433e43118d3032340f40cac8c0Chris Banes        if ((st.isPrepared || preparePanel(st, event)) && st.menu != null) {
1199dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes            // The menu is prepared now, perform the shortcut on it
120000d183885b54de433e43118d3032340f40cac8c0Chris Banes            handled = st.menu.performShortcut(keyCode, event, flags);
1201dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        }
1202dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes
1203dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        if (handled) {
1204dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes            // Only close down the menu if we don't have an action bar keeping it open.
1205dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes            if ((flags & Menu.FLAG_PERFORM_NO_CLOSE) == 0 && mDecorContentParent == null) {
120600d183885b54de433e43118d3032340f40cac8c0Chris Banes                closePanel(st, true);
1207dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes            }
1208dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        }
1209dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes
1210dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        return handled;
1211dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes    }
1212dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes
121300d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void invalidatePanelMenu(int featureId) {
121400d183885b54de433e43118d3032340f40cac8c0Chris Banes        mInvalidatePanelMenuFeatures |= 1 << featureId;
121500d183885b54de433e43118d3032340f40cac8c0Chris Banes
121600d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (!mInvalidatePanelMenuPosted && mWindowDecor != null) {
121700d183885b54de433e43118d3032340f40cac8c0Chris Banes            ViewCompat.postOnAnimation(mWindowDecor, mInvalidatePanelMenuRunnable);
121800d183885b54de433e43118d3032340f40cac8c0Chris Banes            mInvalidatePanelMenuPosted = true;
121900d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
122000d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
122100d183885b54de433e43118d3032340f40cac8c0Chris Banes
122200d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void doInvalidatePanelMenu(int featureId) {
122300d183885b54de433e43118d3032340f40cac8c0Chris Banes        PanelFeatureState st = getPanelState(featureId, true);
122400d183885b54de433e43118d3032340f40cac8c0Chris Banes        Bundle savedActionViewStates = null;
122500d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st.menu != null) {
122600d183885b54de433e43118d3032340f40cac8c0Chris Banes            savedActionViewStates = new Bundle();
122700d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.menu.saveActionViewStates(savedActionViewStates);
122800d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (savedActionViewStates.size() > 0) {
122900d183885b54de433e43118d3032340f40cac8c0Chris Banes                st.frozenActionViewState = savedActionViewStates;
123000d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
123100d183885b54de433e43118d3032340f40cac8c0Chris Banes            // This will be started again when the panel is prepared.
123200d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.menu.stopDispatchingItemsChanged();
123300d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.menu.clear();
123400d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
123500d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.refreshMenuContent = true;
123600d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.refreshDecorView = true;
123700d183885b54de433e43118d3032340f40cac8c0Chris Banes
123800d183885b54de433e43118d3032340f40cac8c0Chris Banes        // Prepare the options panel if we have an action bar
123900d183885b54de433e43118d3032340f40cac8c0Chris Banes        if ((featureId == FEATURE_ACTION_BAR || featureId == FEATURE_OPTIONS_PANEL)
124000d183885b54de433e43118d3032340f40cac8c0Chris Banes                && mDecorContentParent != null) {
124100d183885b54de433e43118d3032340f40cac8c0Chris Banes            st = getPanelState(Window.FEATURE_OPTIONS_PANEL, false);
124200d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (st != null) {
124300d183885b54de433e43118d3032340f40cac8c0Chris Banes                st.isPrepared = false;
124400d183885b54de433e43118d3032340f40cac8c0Chris Banes                preparePanel(st, null);
124500d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
124600d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
124700d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
124800d183885b54de433e43118d3032340f40cac8c0Chris Banes
1249ea4f700ac38424954c56df5138ff794def50b019Chris Banes    /**
1250ea4f700ac38424954c56df5138ff794def50b019Chris Banes     * Updates the status bar guard
1251ea4f700ac38424954c56df5138ff794def50b019Chris Banes     *
1252ea4f700ac38424954c56df5138ff794def50b019Chris Banes     * @param insetTop the current top system window inset
1253ea4f700ac38424954c56df5138ff794def50b019Chris Banes     * @return the new top system window inset
1254ea4f700ac38424954c56df5138ff794def50b019Chris Banes     */
1255ea4f700ac38424954c56df5138ff794def50b019Chris Banes    private int updateStatusGuard(int insetTop) {
1256ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes        boolean showStatusGuard = false;
1257ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes        // Show the status guard when the non-overlay contextual action bar is showing
1258ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes        if (mActionModeView != null) {
1259ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes            if (mActionModeView.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
1260ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams)
1261ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        mActionModeView.getLayoutParams();
1262ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                boolean mlpChanged = false;
1263ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes
1264ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                if (mActionModeView.isShown()) {
1265ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                    if (mOverlayActionMode) {
1266ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        // If we have an overlay action mode, update it's margin so that it is
1267ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        // displayed below the status bar
1268ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        if (mlp.topMargin != insetTop) {
1269ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                            mlpChanged = true;
1270ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                            mlp.topMargin = insetTop;
1271ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        }
1272ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                    } else if (insetTop > 0) {
1273ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        // If we have an inline action mode and we should inset, add a status
1274ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        // guard view which protects the status bar and pushes the action mode down
1275ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        if (mStatusGuard == null) {
1276ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                            mStatusGuard = new View(mActivity);
1277ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                            mStatusGuard.setBackgroundColor(mActivity.getResources()
1278ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                                    .getColor(R.color.abc_input_method_navigation_guard));
1279ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                            mSubDecor.addView(mStatusGuard, 0,
1280ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                                    new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
1281ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                                            insetTop));
1282ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        } else {
1283ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                            ViewGroup.LayoutParams lp = mStatusGuard.getLayoutParams();
1284ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                            if (lp.height != insetTop) {
1285ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                                lp.height = insetTop;
1286ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                                mStatusGuard.setLayoutParams(lp);
1287ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                            }
1288ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        }
1289ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        showStatusGuard = true;
1290ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                    }
1291ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes
1292ea4f700ac38424954c56df5138ff794def50b019Chris Banes                    // Now consume the inset
1293ea4f700ac38424954c56df5138ff794def50b019Chris Banes                    insetTop = 0;
1294ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                } else {
1295ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                    // reset top margin
1296ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                    if (mlp.topMargin != 0) {
1297ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        mlpChanged = true;
1298ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        mlp.topMargin = 0;
1299ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                    }
1300ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                }
1301ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                if (mlpChanged) {
1302ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                    mActionModeView.setLayoutParams(mlp);
1303ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                }
1304ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes            }
1305ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes        }
1306ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes        if (mStatusGuard != null) {
1307ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes            mStatusGuard.setVisibility(showStatusGuard ? View.VISIBLE : View.GONE);
1308ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes        }
1309ea4f700ac38424954c56df5138ff794def50b019Chris Banes
1310ea4f700ac38424954c56df5138ff794def50b019Chris Banes        return insetTop;
1311ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes    }
1312ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes
1313ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    /**
1314d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes     * Clears out internal reference when the action mode is destroyed.
1315d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes     */
1316d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    private class ActionModeCallbackWrapper implements ActionMode.Callback {
1317d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        private ActionMode.Callback mWrapped;
1318d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
1319d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        public ActionModeCallbackWrapper(ActionMode.Callback wrapped) {
1320d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            mWrapped = wrapped;
1321d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
1322d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
1323d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
1324d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            return mWrapped.onCreateActionMode(mode, menu);
1325d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
1326d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
1327d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
13289addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banes            return mWrapped.onPrepareActionMode(mode, menu);
1329d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
1330d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
1331d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
1332d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            return mWrapped.onActionItemClicked(mode, item);
1333d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
1334d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
1335d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        public void onDestroyActionMode(ActionMode mode) {
1336d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            mWrapped.onDestroyActionMode(mode);
13374c2a95906254748cb9a843b061288265d6e185a9Chris Banes            if (mActionModePopup != null) {
13384c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActivity.getWindow().getDecorView().removeCallbacks(mShowActionModePopup);
13394c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionModePopup.dismiss();
13404c2a95906254748cb9a843b061288265d6e185a9Chris Banes            } else if (mActionModeView != null) {
13414c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionModeView.setVisibility(View.GONE);
1342ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                if (mActionModeView.getParent() != null) {
1343ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                    ViewCompat.requestApplyInsets((View) mActionModeView.getParent());
1344ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                }
13454c2a95906254748cb9a843b061288265d6e185a9Chris Banes            }
13464c2a95906254748cb9a843b061288265d6e185a9Chris Banes            if (mActionModeView != null) {
13474c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionModeView.removeAllViews();
13484c2a95906254748cb9a843b061288265d6e185a9Chris Banes            }
13494c2a95906254748cb9a843b061288265d6e185a9Chris Banes            if (mActivity != null) {
13504c2a95906254748cb9a843b061288265d6e185a9Chris Banes                try {
13514c2a95906254748cb9a843b061288265d6e185a9Chris Banes                    mActivity.onSupportActionModeFinished(mActionMode);
13524c2a95906254748cb9a843b061288265d6e185a9Chris Banes                } catch (AbstractMethodError ame) {
13534c2a95906254748cb9a843b061288265d6e185a9Chris Banes                    // Older apps might not implement this callback method.
13544c2a95906254748cb9a843b061288265d6e185a9Chris Banes                }
13554c2a95906254748cb9a843b061288265d6e185a9Chris Banes            }
1356d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            mActionMode = null;
1357d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
1358d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    }
1359d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
136003fc11b659da1645507062bddda450136e13af35Chris Banes    private final class PanelMenuPresenterCallback implements MenuPresenter.Callback {
136103fc11b659da1645507062bddda450136e13af35Chris Banes        @Override
136200d183885b54de433e43118d3032340f40cac8c0Chris Banes        public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
136300d183885b54de433e43118d3032340f40cac8c0Chris Banes            final Menu parentMenu = menu.getRootMenu();
136400d183885b54de433e43118d3032340f40cac8c0Chris Banes            final boolean isSubMenu = parentMenu != menu;
136500d183885b54de433e43118d3032340f40cac8c0Chris Banes            final PanelFeatureState panel = findMenuPanel(isSubMenu ? parentMenu : menu);
136600d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (panel != null) {
136700d183885b54de433e43118d3032340f40cac8c0Chris Banes                if (isSubMenu) {
136800d183885b54de433e43118d3032340f40cac8c0Chris Banes                    callOnPanelClosed(panel.featureId, panel, parentMenu);
136900d183885b54de433e43118d3032340f40cac8c0Chris Banes                    closePanel(panel, true);
137000d183885b54de433e43118d3032340f40cac8c0Chris Banes                } else {
137100d183885b54de433e43118d3032340f40cac8c0Chris Banes                    // Close the panel and only do the callback if the menu is being
137200d183885b54de433e43118d3032340f40cac8c0Chris Banes                    // closed completely, not if opening a sub menu
137328cca4bf59e7f3fd35f9da05caa9418251b5227aChris Banes                    mActivity.closeOptionsMenu();
137400d183885b54de433e43118d3032340f40cac8c0Chris Banes                    closePanel(panel, allMenusAreClosing);
137500d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
137600d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
137703fc11b659da1645507062bddda450136e13af35Chris Banes        }
137803fc11b659da1645507062bddda450136e13af35Chris Banes
137903fc11b659da1645507062bddda450136e13af35Chris Banes        @Override
138000d183885b54de433e43118d3032340f40cac8c0Chris Banes        public boolean onOpenSubMenu(MenuBuilder subMenu) {
138100d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (subMenu == null && mHasActionBar) {
138200d183885b54de433e43118d3032340f40cac8c0Chris Banes                WindowCallback cb = getWindowCallback();
13839b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                if (cb != null && !isDestroyed()) {
138400d183885b54de433e43118d3032340f40cac8c0Chris Banes                    cb.onMenuOpened(FEATURE_ACTION_BAR, subMenu);
138500d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
138600d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
138700d183885b54de433e43118d3032340f40cac8c0Chris Banes            return true;
138803fc11b659da1645507062bddda450136e13af35Chris Banes        }
138903fc11b659da1645507062bddda450136e13af35Chris Banes    }
139003fc11b659da1645507062bddda450136e13af35Chris Banes
139103fc11b659da1645507062bddda450136e13af35Chris Banes    private final class ActionMenuPresenterCallback implements MenuPresenter.Callback {
139203fc11b659da1645507062bddda450136e13af35Chris Banes        @Override
139303fc11b659da1645507062bddda450136e13af35Chris Banes        public boolean onOpenSubMenu(MenuBuilder subMenu) {
139400d183885b54de433e43118d3032340f40cac8c0Chris Banes            WindowCallback cb = getWindowCallback();
139500d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (cb != null) {
139600d183885b54de433e43118d3032340f40cac8c0Chris Banes                cb.onMenuOpened(FEATURE_ACTION_BAR, subMenu);
139700d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
139800d183885b54de433e43118d3032340f40cac8c0Chris Banes            return true;
139903fc11b659da1645507062bddda450136e13af35Chris Banes        }
140003fc11b659da1645507062bddda450136e13af35Chris Banes
140103fc11b659da1645507062bddda450136e13af35Chris Banes        @Override
140203fc11b659da1645507062bddda450136e13af35Chris Banes        public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
140300d183885b54de433e43118d3032340f40cac8c0Chris Banes            checkCloseActionMenu(menu);
140400d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
140500d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
140600d183885b54de433e43118d3032340f40cac8c0Chris Banes
140700d183885b54de433e43118d3032340f40cac8c0Chris Banes    private static final class PanelFeatureState {
14089b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes
140900d183885b54de433e43118d3032340f40cac8c0Chris Banes        /** Feature ID for this panel. */
141000d183885b54de433e43118d3032340f40cac8c0Chris Banes        int featureId;
141100d183885b54de433e43118d3032340f40cac8c0Chris Banes
141200d183885b54de433e43118d3032340f40cac8c0Chris Banes        /** Dynamic state of the panel. */
141300d183885b54de433e43118d3032340f40cac8c0Chris Banes        ViewGroup decorView;
141400d183885b54de433e43118d3032340f40cac8c0Chris Banes
141500d183885b54de433e43118d3032340f40cac8c0Chris Banes        /** The panel that we are actually showing. */
141600d183885b54de433e43118d3032340f40cac8c0Chris Banes        View shownPanelView;
141700d183885b54de433e43118d3032340f40cac8c0Chris Banes
141800d183885b54de433e43118d3032340f40cac8c0Chris Banes        /** Use {@link #setMenu} to set this. */
141900d183885b54de433e43118d3032340f40cac8c0Chris Banes        MenuBuilder menu;
142000d183885b54de433e43118d3032340f40cac8c0Chris Banes
142100d183885b54de433e43118d3032340f40cac8c0Chris Banes        ListMenuPresenter listMenuPresenter;
142200d183885b54de433e43118d3032340f40cac8c0Chris Banes
142357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        Context listPresenterContext;
142400d183885b54de433e43118d3032340f40cac8c0Chris Banes
142500d183885b54de433e43118d3032340f40cac8c0Chris Banes        /**
142600d183885b54de433e43118d3032340f40cac8c0Chris Banes         * Whether the panel has been prepared (see
14279b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes         * {@link #preparePanel}).
142800d183885b54de433e43118d3032340f40cac8c0Chris Banes         */
142900d183885b54de433e43118d3032340f40cac8c0Chris Banes        boolean isPrepared;
143000d183885b54de433e43118d3032340f40cac8c0Chris Banes
143100d183885b54de433e43118d3032340f40cac8c0Chris Banes        /**
143200d183885b54de433e43118d3032340f40cac8c0Chris Banes         * Whether an item's action has been performed. This happens in obvious
143300d183885b54de433e43118d3032340f40cac8c0Chris Banes         * scenarios (user clicks on menu item), but can also happen with
143400d183885b54de433e43118d3032340f40cac8c0Chris Banes         * chording menu+(shortcut key).
143500d183885b54de433e43118d3032340f40cac8c0Chris Banes         */
143600d183885b54de433e43118d3032340f40cac8c0Chris Banes        boolean isHandled;
143700d183885b54de433e43118d3032340f40cac8c0Chris Banes
143800d183885b54de433e43118d3032340f40cac8c0Chris Banes        boolean isOpen;
143900d183885b54de433e43118d3032340f40cac8c0Chris Banes
144000d183885b54de433e43118d3032340f40cac8c0Chris Banes        public boolean qwertyMode;
144100d183885b54de433e43118d3032340f40cac8c0Chris Banes
144200d183885b54de433e43118d3032340f40cac8c0Chris Banes        boolean refreshDecorView;
144300d183885b54de433e43118d3032340f40cac8c0Chris Banes
144400d183885b54de433e43118d3032340f40cac8c0Chris Banes        boolean refreshMenuContent;
144500d183885b54de433e43118d3032340f40cac8c0Chris Banes
144600d183885b54de433e43118d3032340f40cac8c0Chris Banes        boolean wasLastOpen;
144700d183885b54de433e43118d3032340f40cac8c0Chris Banes
144800d183885b54de433e43118d3032340f40cac8c0Chris Banes        /**
144900d183885b54de433e43118d3032340f40cac8c0Chris Banes         * Contains the state of the menu when told to freeze.
145000d183885b54de433e43118d3032340f40cac8c0Chris Banes         */
145100d183885b54de433e43118d3032340f40cac8c0Chris Banes        Bundle frozenMenuState;
145200d183885b54de433e43118d3032340f40cac8c0Chris Banes
145300d183885b54de433e43118d3032340f40cac8c0Chris Banes        /**
145400d183885b54de433e43118d3032340f40cac8c0Chris Banes         * Contains the state of associated action views when told to freeze.
145500d183885b54de433e43118d3032340f40cac8c0Chris Banes         * These are saved across invalidations.
145600d183885b54de433e43118d3032340f40cac8c0Chris Banes         */
145700d183885b54de433e43118d3032340f40cac8c0Chris Banes        Bundle frozenActionViewState;
145800d183885b54de433e43118d3032340f40cac8c0Chris Banes
145900d183885b54de433e43118d3032340f40cac8c0Chris Banes        PanelFeatureState(int featureId) {
146000d183885b54de433e43118d3032340f40cac8c0Chris Banes            this.featureId = featureId;
146100d183885b54de433e43118d3032340f40cac8c0Chris Banes
146200d183885b54de433e43118d3032340f40cac8c0Chris Banes            refreshDecorView = false;
146300d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
146400d183885b54de433e43118d3032340f40cac8c0Chris Banes
146500d183885b54de433e43118d3032340f40cac8c0Chris Banes        public boolean hasPanelItems() {
146600d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (shownPanelView == null) return false;
146700d183885b54de433e43118d3032340f40cac8c0Chris Banes
146800d183885b54de433e43118d3032340f40cac8c0Chris Banes            return listMenuPresenter.getAdapter().getCount() > 0;
146900d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
147000d183885b54de433e43118d3032340f40cac8c0Chris Banes
147100d183885b54de433e43118d3032340f40cac8c0Chris Banes        /**
147200d183885b54de433e43118d3032340f40cac8c0Chris Banes         * Unregister and free attached MenuPresenters. They will be recreated as needed.
147300d183885b54de433e43118d3032340f40cac8c0Chris Banes         */
147400d183885b54de433e43118d3032340f40cac8c0Chris Banes        public void clearMenuPresenters() {
147500d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (menu != null) {
147600d183885b54de433e43118d3032340f40cac8c0Chris Banes                menu.removeMenuPresenter(listMenuPresenter);
147700d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
147800d183885b54de433e43118d3032340f40cac8c0Chris Banes            listMenuPresenter = null;
147900d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
148000d183885b54de433e43118d3032340f40cac8c0Chris Banes
148100d183885b54de433e43118d3032340f40cac8c0Chris Banes        void setStyle(Context context) {
148257c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            final TypedValue outValue = new TypedValue();
148357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            final Resources.Theme widgetTheme = context.getResources().newTheme();
148457c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            widgetTheme.setTo(context.getTheme());
148557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes
148657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            // First apply the actionBarPopupTheme
148757c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            widgetTheme.resolveAttribute(R.attr.actionBarPopupTheme, outValue, true);
148857c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            if (outValue.resourceId != 0) {
148957c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                widgetTheme.applyStyle(outValue.resourceId, true);
149057c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            }
149157c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes
149257c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            // Now apply the panelMenuListTheme
149357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            widgetTheme.resolveAttribute(R.attr.panelMenuListTheme, outValue, true);
149457c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            if (outValue.resourceId != 0) {
149557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                widgetTheme.applyStyle(outValue.resourceId, true);
149657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            } else {
149757c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                widgetTheme.applyStyle(R.style.Theme_AppCompat_CompactMenu, true);
149857c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            }
149957c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes
150057c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            context = new ContextThemeWrapper(context, 0);
150157c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            context.getTheme().setTo(widgetTheme);
150257c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes
150357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            listPresenterContext = context;
150400d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
150500d183885b54de433e43118d3032340f40cac8c0Chris Banes
150600d183885b54de433e43118d3032340f40cac8c0Chris Banes        void setMenu(MenuBuilder menu) {
150700d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (menu == this.menu) return;
150800d183885b54de433e43118d3032340f40cac8c0Chris Banes
150900d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (this.menu != null) {
151000d183885b54de433e43118d3032340f40cac8c0Chris Banes                this.menu.removeMenuPresenter(listMenuPresenter);
151100d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
151200d183885b54de433e43118d3032340f40cac8c0Chris Banes            this.menu = menu;
151300d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (menu != null) {
151400d183885b54de433e43118d3032340f40cac8c0Chris Banes                if (listMenuPresenter != null) menu.addMenuPresenter(listMenuPresenter);
151500d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
151600d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
151700d183885b54de433e43118d3032340f40cac8c0Chris Banes
151857c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        MenuView getListMenuView(MenuPresenter.Callback cb) {
151900d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (menu == null) return null;
152000d183885b54de433e43118d3032340f40cac8c0Chris Banes
152100d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (listMenuPresenter == null) {
152257c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                listMenuPresenter = new ListMenuPresenter(listPresenterContext,
152357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                        R.layout.abc_list_menu_item_layout);
152400d183885b54de433e43118d3032340f40cac8c0Chris Banes                listMenuPresenter.setCallback(cb);
152500d183885b54de433e43118d3032340f40cac8c0Chris Banes                menu.addMenuPresenter(listMenuPresenter);
152600d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
152700d183885b54de433e43118d3032340f40cac8c0Chris Banes
152800d183885b54de433e43118d3032340f40cac8c0Chris Banes            MenuView result = listMenuPresenter.getMenuView(decorView);
152900d183885b54de433e43118d3032340f40cac8c0Chris Banes
153000d183885b54de433e43118d3032340f40cac8c0Chris Banes            return result;
153100d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
153200d183885b54de433e43118d3032340f40cac8c0Chris Banes
153300d183885b54de433e43118d3032340f40cac8c0Chris Banes        Parcelable onSaveInstanceState() {
153400d183885b54de433e43118d3032340f40cac8c0Chris Banes            SavedState savedState = new SavedState();
153500d183885b54de433e43118d3032340f40cac8c0Chris Banes            savedState.featureId = featureId;
153600d183885b54de433e43118d3032340f40cac8c0Chris Banes            savedState.isOpen = isOpen;
153700d183885b54de433e43118d3032340f40cac8c0Chris Banes
153800d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (menu != null) {
153900d183885b54de433e43118d3032340f40cac8c0Chris Banes                savedState.menuState = new Bundle();
154000d183885b54de433e43118d3032340f40cac8c0Chris Banes                menu.savePresenterStates(savedState.menuState);
154100d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
154200d183885b54de433e43118d3032340f40cac8c0Chris Banes
154300d183885b54de433e43118d3032340f40cac8c0Chris Banes            return savedState;
154400d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
154500d183885b54de433e43118d3032340f40cac8c0Chris Banes
154600d183885b54de433e43118d3032340f40cac8c0Chris Banes        void onRestoreInstanceState(Parcelable state) {
154700d183885b54de433e43118d3032340f40cac8c0Chris Banes            SavedState savedState = (SavedState) state;
154800d183885b54de433e43118d3032340f40cac8c0Chris Banes            featureId = savedState.featureId;
154900d183885b54de433e43118d3032340f40cac8c0Chris Banes            wasLastOpen = savedState.isOpen;
155000d183885b54de433e43118d3032340f40cac8c0Chris Banes            frozenMenuState = savedState.menuState;
155100d183885b54de433e43118d3032340f40cac8c0Chris Banes
155200d183885b54de433e43118d3032340f40cac8c0Chris Banes            shownPanelView = null;
155300d183885b54de433e43118d3032340f40cac8c0Chris Banes            decorView = null;
155400d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
155500d183885b54de433e43118d3032340f40cac8c0Chris Banes
155600d183885b54de433e43118d3032340f40cac8c0Chris Banes        void applyFrozenState() {
155700d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (menu != null && frozenMenuState != null) {
155800d183885b54de433e43118d3032340f40cac8c0Chris Banes                menu.restorePresenterStates(frozenMenuState);
155900d183885b54de433e43118d3032340f40cac8c0Chris Banes                frozenMenuState = null;
156000d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
156100d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
156200d183885b54de433e43118d3032340f40cac8c0Chris Banes
156300d183885b54de433e43118d3032340f40cac8c0Chris Banes        private static class SavedState implements Parcelable {
156400d183885b54de433e43118d3032340f40cac8c0Chris Banes            int featureId;
156500d183885b54de433e43118d3032340f40cac8c0Chris Banes            boolean isOpen;
156600d183885b54de433e43118d3032340f40cac8c0Chris Banes            Bundle menuState;
156700d183885b54de433e43118d3032340f40cac8c0Chris Banes
156800d183885b54de433e43118d3032340f40cac8c0Chris Banes            public int describeContents() {
156900d183885b54de433e43118d3032340f40cac8c0Chris Banes                return 0;
157000d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
157100d183885b54de433e43118d3032340f40cac8c0Chris Banes
157200d183885b54de433e43118d3032340f40cac8c0Chris Banes            public void writeToParcel(Parcel dest, int flags) {
157300d183885b54de433e43118d3032340f40cac8c0Chris Banes                dest.writeInt(featureId);
157400d183885b54de433e43118d3032340f40cac8c0Chris Banes                dest.writeInt(isOpen ? 1 : 0);
157500d183885b54de433e43118d3032340f40cac8c0Chris Banes
157600d183885b54de433e43118d3032340f40cac8c0Chris Banes                if (isOpen) {
157700d183885b54de433e43118d3032340f40cac8c0Chris Banes                    dest.writeBundle(menuState);
157800d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
157900d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
158000d183885b54de433e43118d3032340f40cac8c0Chris Banes
158100d183885b54de433e43118d3032340f40cac8c0Chris Banes            private static SavedState readFromParcel(Parcel source) {
158200d183885b54de433e43118d3032340f40cac8c0Chris Banes                SavedState savedState = new SavedState();
158300d183885b54de433e43118d3032340f40cac8c0Chris Banes                savedState.featureId = source.readInt();
158400d183885b54de433e43118d3032340f40cac8c0Chris Banes                savedState.isOpen = source.readInt() == 1;
158500d183885b54de433e43118d3032340f40cac8c0Chris Banes
158600d183885b54de433e43118d3032340f40cac8c0Chris Banes                if (savedState.isOpen) {
158700d183885b54de433e43118d3032340f40cac8c0Chris Banes                    savedState.menuState = source.readBundle();
158800d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
158900d183885b54de433e43118d3032340f40cac8c0Chris Banes
159000d183885b54de433e43118d3032340f40cac8c0Chris Banes                return savedState;
159100d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
159200d183885b54de433e43118d3032340f40cac8c0Chris Banes
159300d183885b54de433e43118d3032340f40cac8c0Chris Banes            public static final Parcelable.Creator<SavedState> CREATOR
159400d183885b54de433e43118d3032340f40cac8c0Chris Banes                    = new Parcelable.Creator<SavedState>() {
159500d183885b54de433e43118d3032340f40cac8c0Chris Banes                public SavedState createFromParcel(Parcel in) {
159600d183885b54de433e43118d3032340f40cac8c0Chris Banes                    return readFromParcel(in);
159700d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
159800d183885b54de433e43118d3032340f40cac8c0Chris Banes
159900d183885b54de433e43118d3032340f40cac8c0Chris Banes                public SavedState[] newArray(int size) {
160000d183885b54de433e43118d3032340f40cac8c0Chris Banes                    return new SavedState[size];
160100d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
160200d183885b54de433e43118d3032340f40cac8c0Chris Banes            };
160303fc11b659da1645507062bddda450136e13af35Chris Banes        }
160403fc11b659da1645507062bddda450136e13af35Chris Banes    }
160503fc11b659da1645507062bddda450136e13af35Chris Banes
16066386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes}
1607