AppCompatDelegateImplV7.java revision 62ab25d71ccfa775a8bd2add7b41277bc4e14bbc
16386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes/* 26386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * Copyright (C) 2013 The Android Open Source Project 36386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * 46386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * Licensed under the Apache License, Version 2.0 (the "License"); 56386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * you may not use this file except in compliance with the License. 66386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * You may obtain a copy of the License at 76386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * 86386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * http://www.apache.org/licenses/LICENSE-2.0 96386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * 106386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * Unless required by applicable law or agreed to in writing, software 116386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * distributed under the License is distributed on an "AS IS" BASIS, 126386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * See the License for the specific language governing permissions and 146386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * limitations under the License. 156386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes */ 166386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 176386aac7ea9be44d23dcea28d9a02110c174e988Chris Banespackage android.support.v7.app; 186386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 19f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.app.Activity; 2016e8d4dd91083260223c007c797e46bc8f631055Chris Banesimport android.app.Dialog; 216386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.content.Context; 226386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.content.res.Configuration; 2361c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banesimport android.content.res.Resources; 246386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.content.res.TypedArray; 2546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport android.graphics.PixelFormat; 26ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banesimport android.graphics.Rect; 2746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport android.media.AudioManager; 28469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport android.os.Build; 298902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banesimport android.os.Bundle; 3000d183885b54de433e43118d3032340f40cac8c0Chris Banesimport android.os.Parcel; 3100d183885b54de433e43118d3032340f40cac8c0Chris Banesimport android.os.Parcelable; 32469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport android.support.annotation.NonNull; 3349c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.app.NavUtils; 3462ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banesimport android.support.v4.os.ParcelableCompat; 3562ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banesimport android.support.v4.os.ParcelableCompatCreatorCallbacks; 36f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.support.v4.view.LayoutInflaterCompat; 37f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.support.v4.view.LayoutInflaterFactory; 38ea4f700ac38424954c56df5138ff794def50b019Chris Banesimport android.support.v4.view.OnApplyWindowInsetsListener; 3903fc11b659da1645507062bddda450136e13af35Chris Banesimport android.support.v4.view.ViewCompat; 4049c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.view.ViewConfigurationCompat; 41c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liuimport android.support.v4.view.ViewPropertyAnimatorCompat; 42c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liuimport android.support.v4.view.ViewPropertyAnimatorListenerAdapter; 43d25af35061a9f20d59b25329d613c62c20184dadChris Banesimport android.support.v4.view.WindowCompat; 44ea4f700ac38424954c56df5138ff794def50b019Chris Banesimport android.support.v4.view.WindowInsetsCompat; 45f5829201b976fc650789accc22f325a2541ed478Chris Banesimport android.support.v4.widget.PopupWindowCompat; 466386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.support.v7.appcompat.R; 472cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banesimport android.support.v7.internal.app.AppCompatViewInflater; 4849c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.app.ToolbarActionBar; 4949c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.app.WindowDecorActionBar; 50878ed08a784cafb112a5d350573b0d1e81c554dbChris Banesimport android.support.v7.internal.view.ContextThemeWrapper; 514c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.support.v7.internal.view.StandaloneActionMode; 526386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.support.v7.internal.view.menu.ListMenuPresenter; 536386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.support.v7.internal.view.menu.MenuBuilder; 546386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.support.v7.internal.view.menu.MenuPresenter; 556386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.support.v7.internal.view.menu.MenuView; 564c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.support.v7.internal.widget.ActionBarContextView; 5719eaf14cb3cca613f984a32be2fab2534427fb29Chris Banesimport android.support.v7.internal.widget.ContentFrameLayout; 5849c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.widget.DecorContentParent; 59ea4f700ac38424954c56df5138ff794def50b019Chris Banesimport android.support.v7.internal.widget.FitWindowsViewGroup; 6046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport android.support.v7.internal.widget.TintManager; 614bd5cbd6ca4f1e5ed43217b808068a48f937feabChris Banesimport android.support.v7.internal.widget.ViewStubCompat; 62ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banesimport android.support.v7.internal.widget.ViewUtils; 63d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banesimport android.support.v7.view.ActionMode; 6449c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.widget.Toolbar; 6516e8d4dd91083260223c007c797e46bc8f631055Chris Banesimport android.text.TextUtils; 66cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banesimport android.util.AndroidRuntimeException; 67469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport android.util.AttributeSet; 6846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport android.util.Log; 6956fd50144df518461398a9b3397ee4842b346708Chris Banesimport android.util.TypedValue; 704c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.view.Gravity; 7100d183885b54de433e43118d3032340f40cac8c0Chris Banesimport android.view.KeyCharacterMap; 72dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banesimport android.view.KeyEvent; 73dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banesimport android.view.LayoutInflater; 7430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.Menu; 7530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.MenuItem; 7646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport android.view.MotionEvent; 776386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.view.View; 7849c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.ViewConfiguration; 796386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.view.ViewGroup; 8046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport android.view.ViewParent; 816386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.view.Window; 8246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport android.view.WindowManager; 834c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.view.accessibility.AccessibilityEvent; 8430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.widget.FrameLayout; 854c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.widget.PopupWindow; 8616e8d4dd91083260223c007c797e46bc8f631055Chris Banesimport android.widget.TextView; 876386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 8846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport static android.view.ViewGroup.LayoutParams.MATCH_PARENT; 8946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; 9000d183885b54de433e43118d3032340f40cac8c0Chris Banesimport static android.view.Window.FEATURE_OPTIONS_PANEL; 9100d183885b54de433e43118d3032340f40cac8c0Chris Banes 92f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesclass AppCompatDelegateImplV7 extends AppCompatDelegateImplBase 93f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes implements MenuBuilder.Callback, LayoutInflaterFactory { 946386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 9549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private DecorContentParent mDecorContentParent; 9603fc11b659da1645507062bddda450136e13af35Chris Banes private ActionMenuPresenterCallback mActionMenuPresenterCallback; 9703fc11b659da1645507062bddda450136e13af35Chris Banes private PanelMenuPresenterCallback mPanelMenuPresenterCallback; 9803fc11b659da1645507062bddda450136e13af35Chris Banes 994c2a95906254748cb9a843b061288265d6e185a9Chris Banes ActionMode mActionMode; 1004c2a95906254748cb9a843b061288265d6e185a9Chris Banes ActionBarContextView mActionModeView; 1014c2a95906254748cb9a843b061288265d6e185a9Chris Banes PopupWindow mActionModePopup; 1024c2a95906254748cb9a843b061288265d6e185a9Chris Banes Runnable mShowActionModePopup; 103c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu ViewPropertyAnimatorCompat mFadeAnim = null; 1045a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes 1055a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes // true if we have installed a window sub-decor layout. 1065a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes private boolean mSubDecorInstalled; 10703fc11b659da1645507062bddda450136e13af35Chris Banes private ViewGroup mWindowDecor; 108ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes private ViewGroup mSubDecor; 109ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes 11016e8d4dd91083260223c007c797e46bc8f631055Chris Banes private TextView mTitleView; 111ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes private View mStatusGuard; 112d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 113ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes // Used to keep track of Progress Bar Window features 114ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes private boolean mFeatureProgress, mFeatureIndeterminateProgress; 115ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes 1168902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes // Used for emulating PanelFeatureState 1178902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes private boolean mClosingActionMenu; 11800d183885b54de433e43118d3032340f40cac8c0Chris Banes private PanelFeatureState[] mPanels; 11900d183885b54de433e43118d3032340f40cac8c0Chris Banes private PanelFeatureState mPreparedPanel; 120556ac47ce764a4a9320b5ac914536e9da2524176Chris Banes 12103fc11b659da1645507062bddda450136e13af35Chris Banes private boolean mInvalidatePanelMenuPosted; 12200d183885b54de433e43118d3032340f40cac8c0Chris Banes private int mInvalidatePanelMenuFeatures; 12303fc11b659da1645507062bddda450136e13af35Chris Banes private final Runnable mInvalidatePanelMenuRunnable = new Runnable() { 12403fc11b659da1645507062bddda450136e13af35Chris Banes @Override 12503fc11b659da1645507062bddda450136e13af35Chris Banes public void run() { 12600d183885b54de433e43118d3032340f40cac8c0Chris Banes if ((mInvalidatePanelMenuFeatures & 1 << FEATURE_OPTIONS_PANEL) != 0) { 12700d183885b54de433e43118d3032340f40cac8c0Chris Banes doInvalidatePanelMenu(FEATURE_OPTIONS_PANEL); 12800d183885b54de433e43118d3032340f40cac8c0Chris Banes } 129d25af35061a9f20d59b25329d613c62c20184dadChris Banes if ((mInvalidatePanelMenuFeatures & 1 << FEATURE_SUPPORT_ACTION_BAR) != 0) { 130d25af35061a9f20d59b25329d613c62c20184dadChris Banes doInvalidatePanelMenu(FEATURE_SUPPORT_ACTION_BAR); 13100d183885b54de433e43118d3032340f40cac8c0Chris Banes } 13200d183885b54de433e43118d3032340f40cac8c0Chris Banes mInvalidatePanelMenuPosted = false; 13300d183885b54de433e43118d3032340f40cac8c0Chris Banes mInvalidatePanelMenuFeatures = 0; 13403fc11b659da1645507062bddda450136e13af35Chris Banes } 13503fc11b659da1645507062bddda450136e13af35Chris Banes }; 13603fc11b659da1645507062bddda450136e13af35Chris Banes 13749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private boolean mEnableDefaultActionBarUp; 13849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 1397efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell private Rect mTempRect1; 1407efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell private Rect mTempRect2; 1417efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell 1422cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes private AppCompatViewInflater mAppCompatViewInflater; 143fd1eb27a3700de31507de34fd1bcc51830fe876cChris Banes 14416e8d4dd91083260223c007c797e46bc8f631055Chris Banes AppCompatDelegateImplV7(Context context, Window window, AppCompatCallback callback) { 14516e8d4dd91083260223c007c797e46bc8f631055Chris Banes super(context, window, callback); 1466386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 1476386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 1486386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes @Override 149f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public void onCreate(Bundle savedInstanceState) { 15016e8d4dd91083260223c007c797e46bc8f631055Chris Banes mWindowDecor = (ViewGroup) mWindow.getDecorView(); 15103fc11b659da1645507062bddda450136e13af35Chris Banes 15216e8d4dd91083260223c007c797e46bc8f631055Chris Banes if (mOriginalWindowCallback instanceof Activity) { 15316e8d4dd91083260223c007c797e46bc8f631055Chris Banes if (NavUtils.getParentActivityName((Activity) mOriginalWindowCallback) != null) { 15416e8d4dd91083260223c007c797e46bc8f631055Chris Banes // Peek at the Action Bar and update it if it already exists 15516e8d4dd91083260223c007c797e46bc8f631055Chris Banes ActionBar ab = peekSupportActionBar(); 15616e8d4dd91083260223c007c797e46bc8f631055Chris Banes if (ab == null) { 15716e8d4dd91083260223c007c797e46bc8f631055Chris Banes mEnableDefaultActionBarUp = true; 15816e8d4dd91083260223c007c797e46bc8f631055Chris Banes } else { 15916e8d4dd91083260223c007c797e46bc8f631055Chris Banes ab.setDefaultDisplayHomeAsUpEnabled(true); 16016e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 16149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 16249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 16349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 16449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 16549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 166f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public void onPostCreate(Bundle savedInstanceState) { 167c826d759805928c84b20e646e442d55483e003c8Chris Banes // Make sure that the sub decor is installed 168c826d759805928c84b20e646e442d55483e003c8Chris Banes ensureSubDecor(); 169c826d759805928c84b20e646e442d55483e003c8Chris Banes } 170c826d759805928c84b20e646e442d55483e003c8Chris Banes 171c826d759805928c84b20e646e442d55483e003c8Chris Banes @Override 1728122ad54f129c2214631fad86cabda82815cc0d8Chris Banes public void initWindowDecorActionBar() { 17330837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell ensureSubDecor(); 17488c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes 1758122ad54f129c2214631fad86cabda82815cc0d8Chris Banes if (!mHasActionBar || mActionBar != null) { 1768122ad54f129c2214631fad86cabda82815cc0d8Chris Banes return; 17788c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes } 17888c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes 17916e8d4dd91083260223c007c797e46bc8f631055Chris Banes if (mOriginalWindowCallback instanceof Activity) { 1808122ad54f129c2214631fad86cabda82815cc0d8Chris Banes mActionBar = new WindowDecorActionBar((Activity) mOriginalWindowCallback, 1818122ad54f129c2214631fad86cabda82815cc0d8Chris Banes mOverlayActionBar); 18216e8d4dd91083260223c007c797e46bc8f631055Chris Banes } else if (mOriginalWindowCallback instanceof Dialog) { 1838122ad54f129c2214631fad86cabda82815cc0d8Chris Banes mActionBar = new WindowDecorActionBar((Dialog) mOriginalWindowCallback); 18416e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 1858122ad54f129c2214631fad86cabda82815cc0d8Chris Banes if (mActionBar != null) { 1868122ad54f129c2214631fad86cabda82815cc0d8Chris Banes mActionBar.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp); 18716e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 18849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 18949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 19049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 191f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public void setSupportActionBar(Toolbar toolbar) { 19216e8d4dd91083260223c007c797e46bc8f631055Chris Banes if (!(mOriginalWindowCallback instanceof Activity)) { 19316e8d4dd91083260223c007c797e46bc8f631055Chris Banes // Only Activities support custom Action Bars 19416e8d4dd91083260223c007c797e46bc8f631055Chris Banes return; 19516e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 19616e8d4dd91083260223c007c797e46bc8f631055Chris Banes 197da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes final ActionBar ab = getSupportActionBar(); 198da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes if (ab instanceof WindowDecorActionBar) { 19949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes throw new IllegalStateException("This Activity already has an action bar supplied " + 200d25af35061a9f20d59b25329d613c62c20184dadChris Banes "by the window decor. Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set " + 20149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes "windowActionBar to false in your theme to use a Toolbar instead."); 20249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 2035ecdb2c5042da49d36d7cda3fa08f1d9151a1fbdChris Banes // Clear out the MenuInflater to make sure that it is valid for the new Action Bar 2045ecdb2c5042da49d36d7cda3fa08f1d9151a1fbdChris Banes mMenuInflater = null; 205da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes 20616e8d4dd91083260223c007c797e46bc8f631055Chris Banes ToolbarActionBar tbab = new ToolbarActionBar(toolbar, ((Activity) mContext).getTitle(), 2078d4765883ff24f0f79bf64fea23d4687d50cec85Chris Banes mAppCompatWindowCallback); 2085ecdb2c5042da49d36d7cda3fa08f1d9151a1fbdChris Banes mActionBar = tbab; 20916e8d4dd91083260223c007c797e46bc8f631055Chris Banes mWindow.setCallback(tbab.getWrappedWindowCallback()); 2100b216f2263135782c361e122892a12156d5d2ce1Chris Banes tbab.invalidateOptionsMenu(); 2116386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 2126386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 2136386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes @Override 2146386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes public void onConfigurationChanged(Configuration newConfig) { 2156386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes // If this is called before sub-decor is installed, ActionBar will not 2166386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes // be properly initialized. 2175a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes if (mHasActionBar && mSubDecorInstalled) { 2186386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes // Note: The action bar will need to access 2196386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes // view changes from superclass. 22049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ActionBar ab = getSupportActionBar(); 22149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (ab != null) { 22249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ab.onConfigurationChanged(newConfig); 22349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 2246386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 2256386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 2266386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 2276386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes @Override 228a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes public void onStop() { 22949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ActionBar ab = getSupportActionBar(); 230a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes if (ab != null) { 231a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes ab.setShowHideAnimationEnabled(false); 232a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes } 233a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes } 234a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes 235a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes @Override 236a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes public void onPostResume() { 23749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ActionBar ab = getSupportActionBar(); 238a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes if (ab != null) { 239a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes ab.setShowHideAnimationEnabled(true); 240a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes } 241a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes } 242a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes 243a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes @Override 2446386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes public void setContentView(View v) { 2456386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes ensureSubDecor(); 24616e8d4dd91083260223c007c797e46bc8f631055Chris Banes ViewGroup contentParent = (ViewGroup) mSubDecor.findViewById(android.R.id.content); 24756fd50144df518461398a9b3397ee4842b346708Chris Banes contentParent.removeAllViews(); 24856fd50144df518461398a9b3397ee4842b346708Chris Banes contentParent.addView(v); 24916e8d4dd91083260223c007c797e46bc8f631055Chris Banes mOriginalWindowCallback.onContentChanged(); 2506386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 2516386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 2526386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes @Override 2536386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes public void setContentView(int resId) { 2546386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes ensureSubDecor(); 25516e8d4dd91083260223c007c797e46bc8f631055Chris Banes ViewGroup contentParent = (ViewGroup) mSubDecor.findViewById(android.R.id.content); 25656fd50144df518461398a9b3397ee4842b346708Chris Banes contentParent.removeAllViews(); 25716e8d4dd91083260223c007c797e46bc8f631055Chris Banes LayoutInflater.from(mContext).inflate(resId, contentParent); 25816e8d4dd91083260223c007c797e46bc8f631055Chris Banes mOriginalWindowCallback.onContentChanged(); 2596386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 2606386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 2616386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes @Override 2626386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes public void setContentView(View v, ViewGroup.LayoutParams lp) { 2636386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes ensureSubDecor(); 26416e8d4dd91083260223c007c797e46bc8f631055Chris Banes ViewGroup contentParent = (ViewGroup) mSubDecor.findViewById(android.R.id.content); 26556fd50144df518461398a9b3397ee4842b346708Chris Banes contentParent.removeAllViews(); 26656fd50144df518461398a9b3397ee4842b346708Chris Banes contentParent.addView(v, lp); 26716e8d4dd91083260223c007c797e46bc8f631055Chris Banes mOriginalWindowCallback.onContentChanged(); 2686386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 2696386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 2706386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes @Override 2716386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes public void addContentView(View v, ViewGroup.LayoutParams lp) { 2726386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes ensureSubDecor(); 27316e8d4dd91083260223c007c797e46bc8f631055Chris Banes ViewGroup contentParent = (ViewGroup) mSubDecor.findViewById(android.R.id.content); 27456fd50144df518461398a9b3397ee4842b346708Chris Banes contentParent.addView(v, lp); 27516e8d4dd91083260223c007c797e46bc8f631055Chris Banes mOriginalWindowCallback.onContentChanged(); 276d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes } 277d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes 278f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes private void ensureSubDecor() { 27956fd50144df518461398a9b3397ee4842b346708Chris Banes if (!mSubDecorInstalled) { 280a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes mSubDecor = createSubDecor(); 28191a95c4599d0d5fa936b81396c71210ae7e68e54Chris Banes 28216e8d4dd91083260223c007c797e46bc8f631055Chris Banes // If a title was set before we installed the decor, propogate it now 28316e8d4dd91083260223c007c797e46bc8f631055Chris Banes CharSequence title = getTitle(); 28416e8d4dd91083260223c007c797e46bc8f631055Chris Banes if (!TextUtils.isEmpty(title)) { 28516e8d4dd91083260223c007c797e46bc8f631055Chris Banes onTitleChanged(title); 286f53c7bf3146bf9bcba46324f9f06449df475be36Chris Banes } 2874b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes 288a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes applyFixedSizeWindow(); 2890f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes 29016e8d4dd91083260223c007c797e46bc8f631055Chris Banes onSubDecorInstalled(mSubDecor); 2910f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes 292f53c7bf3146bf9bcba46324f9f06449df475be36Chris Banes mSubDecorInstalled = true; 2930f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes 29400d183885b54de433e43118d3032340f40cac8c0Chris Banes // Invalidate if the panel menu hasn't been created before this. 29500d183885b54de433e43118d3032340f40cac8c0Chris Banes // Panel menu invalidation is deferred avoiding application onCreateOptionsMenu 29600d183885b54de433e43118d3032340f40cac8c0Chris Banes // being called in the middle of onCreate or similar. 29700d183885b54de433e43118d3032340f40cac8c0Chris Banes // A pending invalidation will typically be resolved before the posted message 29800d183885b54de433e43118d3032340f40cac8c0Chris Banes // would run normally in order to satisfy instance state restoration. 29900d183885b54de433e43118d3032340f40cac8c0Chris Banes PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, false); 3009b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes if (!isDestroyed() && (st == null || st.menu == null)) { 301d25af35061a9f20d59b25329d613c62c20184dadChris Banes invalidatePanelMenu(FEATURE_SUPPORT_ACTION_BAR); 30200d183885b54de433e43118d3032340f40cac8c0Chris Banes } 3036386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 3046386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 305ea4f700ac38424954c56df5138ff794def50b019Chris Banes 306a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes private ViewGroup createSubDecor() { 307a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes TypedArray a = mContext.obtainStyledAttributes(R.styleable.Theme); 308a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes 309a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes if (!a.hasValue(R.styleable.Theme_windowActionBar)) { 310a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes a.recycle(); 311a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes throw new IllegalStateException( 312a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes "You need to use a Theme.AppCompat theme (or descendant) with this activity."); 313a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes } 314a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes 315a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes if (a.getBoolean(R.styleable.Theme_windowNoTitle, false)) { 316a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes requestWindowFeature(Window.FEATURE_NO_TITLE); 317a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes } else if (a.getBoolean(R.styleable.Theme_windowActionBar, false)) { 318a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes // Don't allow an action bar if there is no title. 319a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes requestWindowFeature(FEATURE_SUPPORT_ACTION_BAR); 320a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes } 321a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes if (a.getBoolean(R.styleable.Theme_windowActionBarOverlay, false)) { 322a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes requestWindowFeature(FEATURE_SUPPORT_ACTION_BAR_OVERLAY); 323a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes } 324a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes if (a.getBoolean(R.styleable.Theme_windowActionModeOverlay, false)) { 325a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes requestWindowFeature(FEATURE_ACTION_MODE_OVERLAY); 326a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes } 327a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes mIsFloating = a.getBoolean(R.styleable.Theme_android_windowIsFloating, false); 328a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes a.recycle(); 329a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes 330a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes final LayoutInflater inflater = LayoutInflater.from(mContext); 331a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes ViewGroup subDecor = null; 332a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes 333a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes 334a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes if (!mWindowNoTitle) { 335a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes if (mIsFloating) { 336a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes // If we're floating, inflate the dialog title decor 337a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes subDecor = (ViewGroup) inflater.inflate( 338a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes R.layout.abc_dialog_title_material, null); 339a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes 340a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes // Floating windows can never have an action bar, reset the flags 341a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes mHasActionBar = mOverlayActionBar = false; 342a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes } else if (mHasActionBar) { 343a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes /** 344a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes * This needs some explanation. As we can not use the android:theme attribute 345a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes * pre-L, we emulate it by manually creating a LayoutInflater using a 346a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes * ContextThemeWrapper pointing to actionBarTheme. 347a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes */ 348a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes TypedValue outValue = new TypedValue(); 349a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes mContext.getTheme().resolveAttribute(R.attr.actionBarTheme, outValue, true); 350a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes 351a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes Context themedContext; 352a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes if (outValue.resourceId != 0) { 353a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes themedContext = new ContextThemeWrapper(mContext, outValue.resourceId); 354ea4f700ac38424954c56df5138ff794def50b019Chris Banes } else { 355a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes themedContext = mContext; 356ea4f700ac38424954c56df5138ff794def50b019Chris Banes } 3573954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 358a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes // Now inflate the view using the themed context and set it as the content view 359a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes subDecor = (ViewGroup) LayoutInflater.from(themedContext) 360a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes .inflate(R.layout.abc_screen_toolbar, null); 3610f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes 362a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes mDecorContentParent = (DecorContentParent) subDecor 363a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes .findViewById(R.id.decor_content_parent); 364a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes mDecorContentParent.setWindowCallback(getWindowCallback()); 36516e8d4dd91083260223c007c797e46bc8f631055Chris Banes 366a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes /** 367a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes * Propagate features to DecorContentParent 368a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes */ 369a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes if (mOverlayActionBar) { 370a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes mDecorContentParent.initFeature(FEATURE_SUPPORT_ACTION_BAR_OVERLAY); 371a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes } 372a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes if (mFeatureProgress) { 373a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes mDecorContentParent.initFeature(Window.FEATURE_PROGRESS); 374a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes } 375a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes if (mFeatureIndeterminateProgress) { 376a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes mDecorContentParent.initFeature(Window.FEATURE_INDETERMINATE_PROGRESS); 377a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes } 378a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes } 379a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes } else { 380a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes if (mOverlayActionMode) { 381a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes subDecor = (ViewGroup) inflater.inflate( 382a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes R.layout.abc_screen_simple_overlay_action_mode, null); 383a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes } else { 384a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes subDecor = (ViewGroup) inflater.inflate(R.layout.abc_screen_simple, null); 385a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes } 3861f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes 387a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes if (Build.VERSION.SDK_INT >= 21) { 388a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes // If we're running on L or above, we can rely on ViewCompat's 389a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes // setOnApplyWindowInsetsListener 390a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes ViewCompat.setOnApplyWindowInsetsListener(subDecor, 391a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes new OnApplyWindowInsetsListener() { 392a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes @Override 393a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes public WindowInsetsCompat onApplyWindowInsets(View v, 394a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes WindowInsetsCompat insets) { 395a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes final int top = insets.getSystemWindowInsetTop(); 396a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes final int newTop = updateStatusGuard(top); 397a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes 398a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes if (top != newTop) { 399a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes insets = insets.replaceSystemWindowInsets( 400a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes insets.getSystemWindowInsetLeft(), 401a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes newTop, 402a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes insets.getSystemWindowInsetRight(), 403a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes insets.getSystemWindowInsetBottom()); 404a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes } 405c826d759805928c84b20e646e442d55483e003c8Chris Banes 406a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes // Now apply the insets on our view 407a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes return ViewCompat.onApplyWindowInsets(v, insets); 408a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes } 409a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes }); 410a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes } else { 411a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes // Else, we need to use our own FitWindowsViewGroup handling 412a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes ((FitWindowsViewGroup) subDecor).setOnFitSystemWindowsListener( 413a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes new FitWindowsViewGroup.OnFitSystemWindowsListener() { 414a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes @Override 415a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes public void onFitSystemWindows(Rect insets) { 416a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes insets.top = updateStatusGuard(insets.top); 417a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes } 418a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes }); 419c826d759805928c84b20e646e442d55483e003c8Chris Banes } 420a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes } 421c826d759805928c84b20e646e442d55483e003c8Chris Banes 422a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes if (subDecor == null) { 423a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes throw new IllegalArgumentException( 424a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes "AppCompat does not support the current theme features: { " 425a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes + "windowActionBar: " + mHasActionBar 426a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes + ", windowActionBarOverlay: "+ mOverlayActionBar 427a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes + ", android:windowIsFloating: " + mIsFloating 428a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes + ", windowActionModeOverlay: " + mOverlayActionMode 429a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes + ", windowNoTitle: " + mWindowNoTitle 430a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes + " }"); 431a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes } 4321f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes 433a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes if (mDecorContentParent == null) { 434a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes mTitleView = (TextView) subDecor.findViewById(R.id.title); 435a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes } 43692b18eb0263ef2421fda5bf977fea3bf044bf941Chris Banes 437a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes // Make the decor optionally fit system windows, like the window's decor 438a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes ViewUtils.makeOptionalFitsSystemWindows(subDecor); 4394b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes 440a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes final ViewGroup decorContent = (ViewGroup) mWindow.findViewById(android.R.id.content); 441a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes final ContentFrameLayout abcContent = (ContentFrameLayout) subDecor.findViewById( 442a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes R.id.action_bar_activity_content); 443556ac47ce764a4a9320b5ac914536e9da2524176Chris Banes 444a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes // There might be Views already added to the Window's content view so we need to 445a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes // migrate them to our content view 446a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes while (decorContent.getChildCount() > 0) { 447a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes final View child = decorContent.getChildAt(0); 448a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes decorContent.removeViewAt(0); 449a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes abcContent.addView(child); 450a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes } 45156fd50144df518461398a9b3397ee4842b346708Chris Banes 452a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes // Now set the Window's content view with the decor 453a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes mWindow.setContentView(subDecor); 45449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 455a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes // Change our content FrameLayout to use the android.R.id.content id. 456a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes // Useful for fragments. 457a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes decorContent.setId(View.NO_ID); 458a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes abcContent.setId(android.R.id.content); 4598902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes 460a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes // The decorContent may have a foreground drawable set (windowContentOverlay). 461a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes // Remove this as we handle it ourselves 462a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes if (decorContent instanceof FrameLayout) { 463a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes ((FrameLayout) decorContent).setForeground(null); 4646386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 465a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes 466b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes abcContent.setAttachListener(new ContentFrameLayout.OnAttachListener() { 467b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes @Override 468b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes public void onAttachedFromWindow() {} 469b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes 470b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes @Override 471b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes public void onDetachedFromWindow() { 472b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes dismissPopups(); 473b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes } 474b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes }); 475b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes 476a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes return subDecor; 4776386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 4786386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 47916e8d4dd91083260223c007c797e46bc8f631055Chris Banes void onSubDecorInstalled(ViewGroup subDecor) {} 48049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 481a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes private void applyFixedSizeWindow() { 482a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes ContentFrameLayout cfl = (ContentFrameLayout) mSubDecor.findViewById(android.R.id.content); 483a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes 484d8b7157eae680353a2821dca3c9e52b3aaf737a5Chris Banes // This is a bit weird. In the framework, the window sizing attributes control 485d8b7157eae680353a2821dca3c9e52b3aaf737a5Chris Banes // the decor view's size, meaning that any padding is inset for the min/max widths below. 486d8b7157eae680353a2821dca3c9e52b3aaf737a5Chris Banes // We don't control measurement at that level, so we need to workaround it by making sure 487d8b7157eae680353a2821dca3c9e52b3aaf737a5Chris Banes // that the decor view's padding is taken into account. 488a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes cfl.setDecorPadding(mWindowDecor.getPaddingLeft(), 489d8b7157eae680353a2821dca3c9e52b3aaf737a5Chris Banes mWindowDecor.getPaddingTop(), mWindowDecor.getPaddingRight(), 490d8b7157eae680353a2821dca3c9e52b3aaf737a5Chris Banes mWindowDecor.getPaddingBottom()); 491d8b7157eae680353a2821dca3c9e52b3aaf737a5Chris Banes 49216e8d4dd91083260223c007c797e46bc8f631055Chris Banes TypedArray a = mContext.obtainStyledAttributes(R.styleable.Theme); 493a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes a.getValue(R.styleable.Theme_windowMinWidthMajor, cfl.getMinWidthMajor()); 494a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes a.getValue(R.styleable.Theme_windowMinWidthMinor, cfl.getMinWidthMinor()); 49556fd50144df518461398a9b3397ee4842b346708Chris Banes 49649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (a.hasValue(R.styleable.Theme_windowFixedWidthMajor)) { 497a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes a.getValue(R.styleable.Theme_windowFixedWidthMajor, cfl.getFixedWidthMajor()); 49856fd50144df518461398a9b3397ee4842b346708Chris Banes } 49949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (a.hasValue(R.styleable.Theme_windowFixedWidthMinor)) { 500a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes a.getValue(R.styleable.Theme_windowFixedWidthMinor, cfl.getFixedWidthMinor()); 50156fd50144df518461398a9b3397ee4842b346708Chris Banes } 50249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (a.hasValue(R.styleable.Theme_windowFixedHeightMajor)) { 503a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes a.getValue(R.styleable.Theme_windowFixedHeightMajor, cfl.getFixedHeightMajor()); 50456fd50144df518461398a9b3397ee4842b346708Chris Banes } 50549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (a.hasValue(R.styleable.Theme_windowFixedHeightMinor)) { 506a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes a.getValue(R.styleable.Theme_windowFixedHeightMinor, cfl.getFixedHeightMinor()); 50756fd50144df518461398a9b3397ee4842b346708Chris Banes } 50856fd50144df518461398a9b3397ee4842b346708Chris Banes a.recycle(); 50919eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes 510a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes cfl.requestLayout(); 51156fd50144df518461398a9b3397ee4842b346708Chris Banes } 51256fd50144df518461398a9b3397ee4842b346708Chris Banes 5136386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes @Override 514f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public boolean requestWindowFeature(int featureId) { 5158122ad54f129c2214631fad86cabda82815cc0d8Chris Banes featureId = sanitizeWindowFeatureId(featureId); 5168122ad54f129c2214631fad86cabda82815cc0d8Chris Banes 51788c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes if (mWindowNoTitle && featureId == FEATURE_SUPPORT_ACTION_BAR) { 51888c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes return false; // Ignore. No title dominates. 51988c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes } 52088c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes if (mHasActionBar && featureId == Window.FEATURE_NO_TITLE) { 52188c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes // Remove the action bar feature if we have no title. No title dominates. 52288c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes mHasActionBar = false; 52388c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes } 52488c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes 5256386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes switch (featureId) { 526d25af35061a9f20d59b25329d613c62c20184dadChris Banes case FEATURE_SUPPORT_ACTION_BAR: 527cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes throwFeatureRequestIfSubDecorInstalled(); 5285a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes mHasActionBar = true; 5296386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes return true; 530d25af35061a9f20d59b25329d613c62c20184dadChris Banes case FEATURE_SUPPORT_ACTION_BAR_OVERLAY: 531cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes throwFeatureRequestIfSubDecorInstalled(); 5325a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes mOverlayActionBar = true; 5336386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes return true; 53400d183885b54de433e43118d3032340f40cac8c0Chris Banes case FEATURE_ACTION_MODE_OVERLAY: 535cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes throwFeatureRequestIfSubDecorInstalled(); 536de9f38cc4a30b33ac46b105edf470fbc4a044e99Chris Banes mOverlayActionMode = true; 537de9f38cc4a30b33ac46b105edf470fbc4a044e99Chris Banes return true; 538ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes case Window.FEATURE_PROGRESS: 539cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes throwFeatureRequestIfSubDecorInstalled(); 540ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes mFeatureProgress = true; 541ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes return true; 542ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes case Window.FEATURE_INDETERMINATE_PROGRESS: 543cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes throwFeatureRequestIfSubDecorInstalled(); 544ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes mFeatureIndeterminateProgress = true; 545ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes return true; 54619eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes case Window.FEATURE_NO_TITLE: 54719eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes throwFeatureRequestIfSubDecorInstalled(); 54819eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes mWindowNoTitle = true; 54919eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes return true; 5506386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 551cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes 55216e8d4dd91083260223c007c797e46bc8f631055Chris Banes return mWindow.requestFeature(featureId); 5536386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 5546386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 5556386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes @Override 556eba6361c28fad482737765413aed1290da67f2daChris Banes public boolean hasWindowFeature(int featureId) { 557eba6361c28fad482737765413aed1290da67f2daChris Banes featureId = sanitizeWindowFeatureId(featureId); 558eba6361c28fad482737765413aed1290da67f2daChris Banes switch (featureId) { 559eba6361c28fad482737765413aed1290da67f2daChris Banes case FEATURE_SUPPORT_ACTION_BAR: 560eba6361c28fad482737765413aed1290da67f2daChris Banes return mHasActionBar; 561eba6361c28fad482737765413aed1290da67f2daChris Banes case FEATURE_SUPPORT_ACTION_BAR_OVERLAY: 562eba6361c28fad482737765413aed1290da67f2daChris Banes return mOverlayActionBar; 563eba6361c28fad482737765413aed1290da67f2daChris Banes case FEATURE_ACTION_MODE_OVERLAY: 564eba6361c28fad482737765413aed1290da67f2daChris Banes return mOverlayActionMode; 565eba6361c28fad482737765413aed1290da67f2daChris Banes case Window.FEATURE_PROGRESS: 566eba6361c28fad482737765413aed1290da67f2daChris Banes return mFeatureProgress; 567eba6361c28fad482737765413aed1290da67f2daChris Banes case Window.FEATURE_INDETERMINATE_PROGRESS: 568eba6361c28fad482737765413aed1290da67f2daChris Banes return mFeatureIndeterminateProgress; 569eba6361c28fad482737765413aed1290da67f2daChris Banes case Window.FEATURE_NO_TITLE: 570eba6361c28fad482737765413aed1290da67f2daChris Banes return mWindowNoTitle; 571eba6361c28fad482737765413aed1290da67f2daChris Banes } 572eba6361c28fad482737765413aed1290da67f2daChris Banes return mWindow.hasFeature(featureId); 573eba6361c28fad482737765413aed1290da67f2daChris Banes } 574eba6361c28fad482737765413aed1290da67f2daChris Banes 575eba6361c28fad482737765413aed1290da67f2daChris Banes @Override 57616e8d4dd91083260223c007c797e46bc8f631055Chris Banes void onTitleChanged(CharSequence title) { 57749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mDecorContentParent != null) { 57849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorContentParent.setWindowTitle(title); 579535c5737ba868a622d7783d57f7078ab285717c0Chris Banes } else if (peekSupportActionBar() != null) { 580535c5737ba868a622d7783d57f7078ab285717c0Chris Banes peekSupportActionBar().setWindowTitle(title); 58116e8d4dd91083260223c007c797e46bc8f631055Chris Banes } else if (mTitleView != null) { 58216e8d4dd91083260223c007c797e46bc8f631055Chris Banes mTitleView.setText(title); 5836386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 5846386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 5856386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 5866386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes @Override 587d25af35061a9f20d59b25329d613c62c20184dadChris Banes void onPanelClosed(final int featureId, Menu menu) { 588d25af35061a9f20d59b25329d613c62c20184dadChris Banes if (featureId == FEATURE_SUPPORT_ACTION_BAR) { 58900d183885b54de433e43118d3032340f40cac8c0Chris Banes ActionBar ab = getSupportActionBar(); 59000d183885b54de433e43118d3032340f40cac8c0Chris Banes if (ab != null) { 59100d183885b54de433e43118d3032340f40cac8c0Chris Banes ab.dispatchMenuVisibilityChanged(false); 59200d183885b54de433e43118d3032340f40cac8c0Chris Banes } 593436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes } else if (featureId == FEATURE_OPTIONS_PANEL) { 594436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes // Make sure that the options panel is closed. This is mainly used when we're using a 595436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes // ToolbarActionBar 596436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes PanelFeatureState st = getPanelState(featureId, true); 597436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes if (st.isOpen) { 598436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes closePanel(st, false); 599436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes } 600c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes } 601c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes } 602c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes 603c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes @Override 60400d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean onMenuOpened(final int featureId, Menu menu) { 605d25af35061a9f20d59b25329d613c62c20184dadChris Banes if (featureId == FEATURE_SUPPORT_ACTION_BAR) { 60600d183885b54de433e43118d3032340f40cac8c0Chris Banes ActionBar ab = getSupportActionBar(); 60700d183885b54de433e43118d3032340f40cac8c0Chris Banes if (ab != null) { 60800d183885b54de433e43118d3032340f40cac8c0Chris Banes ab.dispatchMenuVisibilityChanged(true); 60900d183885b54de433e43118d3032340f40cac8c0Chris Banes } 61000d183885b54de433e43118d3032340f40cac8c0Chris Banes return true; 611c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes } 612f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes return false; 61303fc11b659da1645507062bddda450136e13af35Chris Banes } 61403fc11b659da1645507062bddda450136e13af35Chris Banes 61503fc11b659da1645507062bddda450136e13af35Chris Banes @Override 6166386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { 617f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes final Window.Callback cb = getWindowCallback(); 6189b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes if (cb != null && !isDestroyed()) { 6199b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes final PanelFeatureState panel = findMenuPanel(menu.getRootMenu()); 6209b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes if (panel != null) { 6219b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes return cb.onMenuItemSelected(panel.featureId, item); 6229b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes } 6239b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes } 6249b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes return false; 6256386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 6266386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 6276386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes @Override 6286386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes public void onMenuModeChange(MenuBuilder menu) { 6296386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes reopenMenu(menu, true); 6306386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 6316386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 6326386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes @Override 633d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes public ActionMode startSupportActionMode(ActionMode.Callback callback) { 634d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes if (callback == null) { 635d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes throw new IllegalArgumentException("ActionMode callback can not be null."); 636d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 637d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 638d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes if (mActionMode != null) { 639d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes mActionMode.finish(); 640d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 641d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 642547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes final ActionMode.Callback wrappedCallback = new ActionModeCallbackWrapperV7(callback); 643d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 64449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ActionBar ab = getSupportActionBar(); 645d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes if (ab != null) { 6465a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes mActionMode = ab.startActionMode(wrappedCallback); 647f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes if (mActionMode != null && mAppCompatCallback != null) { 648f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes mAppCompatCallback.onSupportActionModeStarted(mActionMode); 6490bf48858279237f95d6aad565a074490745491cdChris Banes } 650d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 651d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 6520bf48858279237f95d6aad565a074490745491cdChris Banes if (mActionMode == null) { 6530bf48858279237f95d6aad565a074490745491cdChris Banes // If the action bar didn't provide an action mode, start the emulated window one 6540bf48858279237f95d6aad565a074490745491cdChris Banes mActionMode = startSupportActionModeFromWindow(wrappedCallback); 655d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 6560bf48858279237f95d6aad565a074490745491cdChris Banes 657d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes return mActionMode; 658d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 659d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 660d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes @Override 661f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public void invalidateOptionsMenu() { 662f2045f06bdfc9e2cc40a734e41e45d11adf2bc23Chris Banes final ActionBar ab = getSupportActionBar(); 663f2045f06bdfc9e2cc40a734e41e45d11adf2bc23Chris Banes if (ab != null && ab.invalidateOptionsMenu()) return; 664f2045f06bdfc9e2cc40a734e41e45d11adf2bc23Chris Banes 66500d183885b54de433e43118d3032340f40cac8c0Chris Banes invalidatePanelMenu(FEATURE_OPTIONS_PANEL); 6666386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 6676386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 6684c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 6694c2a95906254748cb9a843b061288265d6e185a9Chris Banes ActionMode startSupportActionModeFromWindow(ActionMode.Callback callback) { 670c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu endOnGoingFadeAnimation(); 6714c2a95906254748cb9a843b061288265d6e185a9Chris Banes if (mActionMode != null) { 6724c2a95906254748cb9a843b061288265d6e185a9Chris Banes mActionMode.finish(); 6734c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 6744c2a95906254748cb9a843b061288265d6e185a9Chris Banes 675547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes final ActionMode.Callback wrappedCallback = new ActionModeCallbackWrapperV7(callback); 676547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes ActionMode mode = null; 677547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes if (mAppCompatCallback != null && !isDestroyed()) { 678547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes try { 679547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mode = mAppCompatCallback.onWindowStartingSupportActionMode(wrappedCallback); 680547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } catch (AbstractMethodError ame) { 681547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes // Older apps might not implement this callback method. 6824c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 6834c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 6844c2a95906254748cb9a843b061288265d6e185a9Chris Banes 685547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes if (mode != null) { 686547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionMode = mode; 687547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } else { 688547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes if (mActionModeView == null) { 689547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes if (mIsFloating) { 690547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes // Use the action bar theme. 691547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes final TypedValue outValue = new TypedValue(); 692547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes final Resources.Theme baseTheme = mContext.getTheme(); 693547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes baseTheme.resolveAttribute(R.attr.actionBarTheme, outValue, true); 694547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes 695547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes final Context actionBarContext; 696547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes if (outValue.resourceId != 0) { 697547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes final Resources.Theme actionBarTheme = mContext.getResources().newTheme(); 698547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes actionBarTheme.setTo(baseTheme); 699547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes actionBarTheme.applyStyle(outValue.resourceId, true); 700547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes 701547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes actionBarContext = new ContextThemeWrapper(mContext, 0); 702547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes actionBarContext.getTheme().setTo(actionBarTheme); 703547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } else { 704547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes actionBarContext = mContext; 705547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } 706547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes 707547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModeView = new ActionBarContextView(actionBarContext); 708547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModePopup = new PopupWindow(actionBarContext, null, 709547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes R.attr.actionModePopupWindowStyle); 710f5829201b976fc650789accc22f325a2541ed478Chris Banes PopupWindowCompat.setWindowLayoutType(mActionModePopup, 711f5829201b976fc650789accc22f325a2541ed478Chris Banes WindowManager.LayoutParams.TYPE_APPLICATION); 712547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModePopup.setContentView(mActionModeView); 713547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModePopup.setWidth(ViewGroup.LayoutParams.MATCH_PARENT); 714547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes 715547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes actionBarContext.getTheme().resolveAttribute( 716547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes R.attr.actionBarSize, outValue, true); 717547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes final int height = TypedValue.complexToDimensionPixelSize(outValue.data, 718547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes actionBarContext.getResources().getDisplayMetrics()); 719547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModeView.setContentHeight(height); 720547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModePopup.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); 721547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mShowActionModePopup = new Runnable() { 722547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes public void run() { 723547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModePopup.showAtLocation( 724547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModeView, 725547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes Gravity.TOP | Gravity.FILL_HORIZONTAL, 0, 0); 726c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu endOnGoingFadeAnimation(); 727c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu ViewCompat.setAlpha(mActionModeView, 0f); 728c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu mFadeAnim = ViewCompat.animate(mActionModeView).alpha(1f); 729c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu mFadeAnim.setListener(new ViewPropertyAnimatorListenerAdapter() { 730c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu @Override 731c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu public void onAnimationEnd(View view) { 732c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu ViewCompat.setAlpha(mActionModeView, 1f); 733c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu mFadeAnim.setListener(null); 734c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu mFadeAnim = null; 735c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu } 736c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu 737c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu @Override 738c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu public void onAnimationStart(View view) { 739c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu mActionModeView.setVisibility(View.VISIBLE); 740c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu } 741c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu }); 742547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } 743547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes }; 744547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } else { 745547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes ViewStubCompat stub = (ViewStubCompat) mSubDecor 746547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes .findViewById(R.id.action_mode_bar_stub); 747547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes if (stub != null) { 748547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes // Set the layout inflater so that it is inflated with the action bar's context 749547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes stub.setLayoutInflater(LayoutInflater.from(getActionBarThemedContext())); 750547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModeView = (ActionBarContextView) stub.inflate(); 751547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } 7524c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 753547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } 754ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes 755547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes if (mActionModeView != null) { 756c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu endOnGoingFadeAnimation(); 757547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModeView.killMode(); 758547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mode = new StandaloneActionMode(mActionModeView.getContext(), mActionModeView, 759547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes wrappedCallback, mActionModePopup == null); 760547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes if (callback.onCreateActionMode(mode, mode.getMenu())) { 761547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mode.invalidate(); 762547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModeView.initForMode(mode); 763547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionMode = mode; 764c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu ViewCompat.setAlpha(mActionModeView, 0f); 765c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu mFadeAnim = ViewCompat.animate(mActionModeView).alpha(1f); 766c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu mFadeAnim.setListener(new ViewPropertyAnimatorListenerAdapter() { 767c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu @Override 768c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu public void onAnimationEnd(View view) { 769c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu ViewCompat.setAlpha(mActionModeView, 1f); 770c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu mFadeAnim.setListener(null); 771c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu mFadeAnim = null; 772c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu } 773c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu 774c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu @Override 775c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu public void onAnimationStart(View view) { 776c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu mActionModeView.setVisibility(View.VISIBLE); 7778ba0fdde8e91fd59808ce3453eef079e54915ce8Chris Banes mActionModeView.sendAccessibilityEvent( 7788ba0fdde8e91fd59808ce3453eef079e54915ce8Chris Banes AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); 7798ba0fdde8e91fd59808ce3453eef079e54915ce8Chris Banes if (mActionModeView.getParent() != null) { 7808ba0fdde8e91fd59808ce3453eef079e54915ce8Chris Banes ViewCompat.requestApplyInsets((View) mActionModeView.getParent()); 7818ba0fdde8e91fd59808ce3453eef079e54915ce8Chris Banes } 782c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu } 783c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu }); 784547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes if (mActionModePopup != null) { 785547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mWindow.getDecorView().post(mShowActionModePopup); 786547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } 787547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } else { 788547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionMode = null; 789ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 7904c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 7914c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 792f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes if (mActionMode != null && mAppCompatCallback != null) { 793f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes mAppCompatCallback.onSupportActionModeStarted(mActionMode); 7944c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 7954c2a95906254748cb9a843b061288265d6e185a9Chris Banes return mActionMode; 7964c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 7974c2a95906254748cb9a843b061288265d6e185a9Chris Banes 798c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu private void endOnGoingFadeAnimation() { 799c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu if (mFadeAnim != null) { 800c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu mFadeAnim.cancel(); 801c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu } 802c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu } 803c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu 804f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes boolean onBackPressed() { 805d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes // Back cancels action modes first. 806d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes if (mActionMode != null) { 807d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes mActionMode.finish(); 808d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes return true; 809d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 810d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 811d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes // Next collapse any expanded action views. 81249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ActionBar ab = getSupportActionBar(); 81349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (ab != null && ab.collapseActionView()) { 814d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes return true; 815d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 816d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 817f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes // Let the call through... 818d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes return false; 819d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 820d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 821d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes @Override 82200d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean onKeyShortcut(int keyCode, KeyEvent ev) { 823d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes // Let the Action Bar have a chance at handling the shortcut 824d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes ActionBar ab = getSupportActionBar(); 825d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes if (ab != null && ab.onKeyShortcut(keyCode, ev)) { 826d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes return true; 827d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes } 828d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes 829dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes // If the panel is already prepared, then perform the shortcut using it. 83000d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean handled; 83100d183885b54de433e43118d3032340f40cac8c0Chris Banes if (mPreparedPanel != null) { 83200d183885b54de433e43118d3032340f40cac8c0Chris Banes handled = performPanelShortcut(mPreparedPanel, ev.getKeyCode(), ev, 83300d183885b54de433e43118d3032340f40cac8c0Chris Banes Menu.FLAG_PERFORM_NO_CLOSE); 83400d183885b54de433e43118d3032340f40cac8c0Chris Banes if (handled) { 83500d183885b54de433e43118d3032340f40cac8c0Chris Banes if (mPreparedPanel != null) { 83600d183885b54de433e43118d3032340f40cac8c0Chris Banes mPreparedPanel.isHandled = true; 83700d183885b54de433e43118d3032340f40cac8c0Chris Banes } 83800d183885b54de433e43118d3032340f40cac8c0Chris Banes return true; 83900d183885b54de433e43118d3032340f40cac8c0Chris Banes } 84000d183885b54de433e43118d3032340f40cac8c0Chris Banes } 84100d183885b54de433e43118d3032340f40cac8c0Chris Banes 84200d183885b54de433e43118d3032340f40cac8c0Chris Banes // If the panel is not prepared, then we may be trying to handle a shortcut key 84300d183885b54de433e43118d3032340f40cac8c0Chris Banes // combination such as Control+C. Temporarily prepare the panel then mark it 84400d183885b54de433e43118d3032340f40cac8c0Chris Banes // unprepared again when finished to ensure that the panel will again be prepared 84500d183885b54de433e43118d3032340f40cac8c0Chris Banes // the next time it is shown for real. 84600d183885b54de433e43118d3032340f40cac8c0Chris Banes if (mPreparedPanel == null) { 84700d183885b54de433e43118d3032340f40cac8c0Chris Banes PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true); 84800d183885b54de433e43118d3032340f40cac8c0Chris Banes preparePanel(st, ev); 84900d183885b54de433e43118d3032340f40cac8c0Chris Banes handled = performPanelShortcut(st, ev.getKeyCode(), ev, Menu.FLAG_PERFORM_NO_CLOSE); 85000d183885b54de433e43118d3032340f40cac8c0Chris Banes st.isPrepared = false; 85100d183885b54de433e43118d3032340f40cac8c0Chris Banes if (handled) { 85200d183885b54de433e43118d3032340f40cac8c0Chris Banes return true; 85300d183885b54de433e43118d3032340f40cac8c0Chris Banes } 85400d183885b54de433e43118d3032340f40cac8c0Chris Banes } 85500d183885b54de433e43118d3032340f40cac8c0Chris Banes return false; 856dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes } 857dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes 858dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes @Override 85946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes boolean dispatchKeyEvent(KeyEvent event) { 8604d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes if (event.getKeyCode() == KeyEvent.KEYCODE_MENU) { 8614d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes // If this is a MENU event, let the Activity have a go. 8624d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes if (mOriginalWindowCallback.dispatchKeyEvent(event)) { 8634d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes return true; 8644d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes } 8654d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes } 8664d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes 86746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes final int keyCode = event.getKeyCode(); 86846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes final int action = event.getAction(); 86946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes final boolean isDown = action == KeyEvent.ACTION_DOWN; 87046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 87146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return isDown ? onKeyDown(keyCode, event) : onKeyUp(keyCode, event); 87246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 87346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 874f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes boolean onKeyUp(int keyCode, KeyEvent event) { 87546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes switch (keyCode) { 87646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes case KeyEvent.KEYCODE_MENU: 8774d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes onKeyUpPanel(Window.FEATURE_OPTIONS_PANEL, event); 8784d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes return true; 87946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes case KeyEvent.KEYCODE_BACK: 88046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes PanelFeatureState st = getPanelState(Window.FEATURE_OPTIONS_PANEL, false); 88146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (st != null && st.isOpen) { 88246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes closePanel(st, true); 88346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return true; 88446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 885f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes if (onBackPressed()) { 886f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes return true; 887f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 88846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes break; 88946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 89046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return false; 89146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 89246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 893f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes boolean onKeyDown(int keyCode, KeyEvent event) { 894f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes switch (keyCode) { 895f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes case KeyEvent.KEYCODE_MENU: 8964d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes onKeyDownPanel(Window.FEATURE_OPTIONS_PANEL, event); 8972f769dc974bd526d945efe8a644f3f89112e08feChris Banes // We need to return true here and not let it bubble up to the Window. 8982f769dc974bd526d945efe8a644f3f89112e08feChris Banes // For empty menus, PhoneWindow's KEYCODE_BACK handling will steals all events, 8992f769dc974bd526d945efe8a644f3f89112e08feChris Banes // not allowing the Activity to call onBackPressed(). 9002f769dc974bd526d945efe8a644f3f89112e08feChris Banes return true; 90146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 90246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 903dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes // On API v7-10 we need to manually call onKeyShortcut() as this is not called 904dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes // from the Activity 90546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { 906a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes // We do not return true here otherwise dispatchKeyEvent will not reach the Activity 907a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes // (which results in the back button not working) 908c9b517a68ed7070d4edcdd5be818540d81b43db0Chris Banes onKeyShortcut(keyCode, event); 90946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 91046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return false; 911dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes } 912dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes 913469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes @Override 914f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public View createView(View parent, final String name, @NonNull Context context, 915fd1eb27a3700de31507de34fd1bcc51830fe876cChris Banes @NonNull AttributeSet attrs) { 916a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes final boolean isPre21 = Build.VERSION.SDK_INT < 21; 917878ed08a784cafb112a5d350573b0d1e81c554dbChris Banes 9182cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes if (mAppCompatViewInflater == null) { 919e183f2600fb31c69eceacc1c263cd56f12489a65Chris Banes mAppCompatViewInflater = new AppCompatViewInflater(); 920469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes } 921fd1eb27a3700de31507de34fd1bcc51830fe876cChris Banes 922d95c99933cb57a5678afeff01d91269be61e2502Chris Banes // We only want the View to inherit it's context if we're running pre-v21 923d95c99933cb57a5678afeff01d91269be61e2502Chris Banes final boolean inheritContext = isPre21 && mSubDecorInstalled 924d95c99933cb57a5678afeff01d91269be61e2502Chris Banes && shouldInheritContext((ViewParent) parent); 925a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes 926484705a5e6fdc1f6ef746b822716a45f82652ab9Chris Banes return mAppCompatViewInflater.createView(parent, name, context, attrs, inheritContext, 927484705a5e6fdc1f6ef746b822716a45f82652ab9Chris Banes isPre21, /* Only read android:theme pre-L (L+ handles this anyway) */ 928484705a5e6fdc1f6ef746b822716a45f82652ab9Chris Banes true /* Read read app:theme as a fallback at all times for legacy reasons */ 929484705a5e6fdc1f6ef746b822716a45f82652ab9Chris Banes ); 930469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes } 931469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes 932d95c99933cb57a5678afeff01d91269be61e2502Chris Banes private boolean shouldInheritContext(ViewParent parent) { 933d95c99933cb57a5678afeff01d91269be61e2502Chris Banes if (parent == null) { 934d95c99933cb57a5678afeff01d91269be61e2502Chris Banes // The initial parent is null so just return false 935d95c99933cb57a5678afeff01d91269be61e2502Chris Banes return false; 936d95c99933cb57a5678afeff01d91269be61e2502Chris Banes } 937d95c99933cb57a5678afeff01d91269be61e2502Chris Banes while (true) { 938d95c99933cb57a5678afeff01d91269be61e2502Chris Banes if (parent == null) { 939d95c99933cb57a5678afeff01d91269be61e2502Chris Banes // Bingo. We've hit a view which has a null parent before being terminated from 940d95c99933cb57a5678afeff01d91269be61e2502Chris Banes // the loop. This is (most probably) because it's the root view in an inflation 941d95c99933cb57a5678afeff01d91269be61e2502Chris Banes // call, therefore we should inherit. This works as the inflated layout is only 942d95c99933cb57a5678afeff01d91269be61e2502Chris Banes // added to the hierarchy at the end of the inflate() call. 943d95c99933cb57a5678afeff01d91269be61e2502Chris Banes return true; 944d95c99933cb57a5678afeff01d91269be61e2502Chris Banes } else if (parent == mWindowDecor || !(parent instanceof View) 945d95c99933cb57a5678afeff01d91269be61e2502Chris Banes || ViewCompat.isAttachedToWindow((View) parent)) { 946d95c99933cb57a5678afeff01d91269be61e2502Chris Banes // We have either hit the window's decor view, a parent which isn't a View 947d95c99933cb57a5678afeff01d91269be61e2502Chris Banes // (i.e. ViewRootImpl), or an attached view, so we know that the original parent 948d95c99933cb57a5678afeff01d91269be61e2502Chris Banes // is currently added to the view hierarchy. This means that it has not be 949d95c99933cb57a5678afeff01d91269be61e2502Chris Banes // inflated in the current inflate() call and we should not inherit the context. 950d95c99933cb57a5678afeff01d91269be61e2502Chris Banes return false; 951d95c99933cb57a5678afeff01d91269be61e2502Chris Banes } 952d95c99933cb57a5678afeff01d91269be61e2502Chris Banes parent = parent.getParent(); 953d95c99933cb57a5678afeff01d91269be61e2502Chris Banes } 954d95c99933cb57a5678afeff01d91269be61e2502Chris Banes } 955d95c99933cb57a5678afeff01d91269be61e2502Chris Banes 956f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes @Override 957f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public void installViewFactory() { 95816e8d4dd91083260223c007c797e46bc8f631055Chris Banes LayoutInflater layoutInflater = LayoutInflater.from(mContext); 959f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes if (layoutInflater.getFactory() == null) { 960f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes LayoutInflaterCompat.setFactory(layoutInflater, this); 961f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } else { 962f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes Log.i(TAG, "The Activity's LayoutInflater already has a Factory installed" 963f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes + " so we can not install AppCompat's"); 964f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 965f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 966f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 967f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes /** 968f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes * From {@link android.support.v4.view.LayoutInflaterFactory} 969f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes */ 970f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes @Override 971498356fea126122c3e3720a419969055cb889428Chris Banes public final View onCreateView(View parent, String name, 972f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes Context context, AttributeSet attrs) { 973498356fea126122c3e3720a419969055cb889428Chris Banes // First let the Activity's Factory try and inflate the view 974498356fea126122c3e3720a419969055cb889428Chris Banes final View view = callActivityOnCreateView(parent, name, context, attrs); 975498356fea126122c3e3720a419969055cb889428Chris Banes if (view != null) { 976498356fea126122c3e3720a419969055cb889428Chris Banes return view; 977498356fea126122c3e3720a419969055cb889428Chris Banes } 978498356fea126122c3e3720a419969055cb889428Chris Banes 979498356fea126122c3e3720a419969055cb889428Chris Banes // If the Factory didn't handle it, let our createView() method try 980498356fea126122c3e3720a419969055cb889428Chris Banes return createView(parent, name, context, attrs); 981498356fea126122c3e3720a419969055cb889428Chris Banes } 98216e8d4dd91083260223c007c797e46bc8f631055Chris Banes 983498356fea126122c3e3720a419969055cb889428Chris Banes View callActivityOnCreateView(View parent, String name, Context context, AttributeSet attrs) { 984498356fea126122c3e3720a419969055cb889428Chris Banes // Let the Activity's LayoutInflater.Factory try and handle it 98516e8d4dd91083260223c007c797e46bc8f631055Chris Banes if (mOriginalWindowCallback instanceof LayoutInflater.Factory) { 986498356fea126122c3e3720a419969055cb889428Chris Banes final View result = ((LayoutInflater.Factory) mOriginalWindowCallback) 98716e8d4dd91083260223c007c797e46bc8f631055Chris Banes .onCreateView(name, context, attrs); 98816e8d4dd91083260223c007c797e46bc8f631055Chris Banes if (result != null) { 98916e8d4dd91083260223c007c797e46bc8f631055Chris Banes return result; 99016e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 991f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 992498356fea126122c3e3720a419969055cb889428Chris Banes return null; 993f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 994f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 99500d183885b54de433e43118d3032340f40cac8c0Chris Banes private void openPanel(final PanelFeatureState st, KeyEvent event) { 99600d183885b54de433e43118d3032340f40cac8c0Chris Banes // Already open, return 9979b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes if (st.isOpen || isDestroyed()) { 99800d183885b54de433e43118d3032340f40cac8c0Chris Banes return; 99900d183885b54de433e43118d3032340f40cac8c0Chris Banes } 100000d183885b54de433e43118d3032340f40cac8c0Chris Banes 100100d183885b54de433e43118d3032340f40cac8c0Chris Banes // Don't open an options panel for honeycomb apps on xlarge devices. 100200d183885b54de433e43118d3032340f40cac8c0Chris Banes // (The app should be using an action bar for menu items.) 100300d183885b54de433e43118d3032340f40cac8c0Chris Banes if (st.featureId == FEATURE_OPTIONS_PANEL) { 100416e8d4dd91083260223c007c797e46bc8f631055Chris Banes Context context = mContext; 100500d183885b54de433e43118d3032340f40cac8c0Chris Banes Configuration config = context.getResources().getConfiguration(); 100600d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean isXLarge = (config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == 100700d183885b54de433e43118d3032340f40cac8c0Chris Banes Configuration.SCREENLAYOUT_SIZE_XLARGE; 100800d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean isHoneycombApp = context.getApplicationInfo().targetSdkVersion >= 100900d183885b54de433e43118d3032340f40cac8c0Chris Banes android.os.Build.VERSION_CODES.HONEYCOMB; 101000d183885b54de433e43118d3032340f40cac8c0Chris Banes 101100d183885b54de433e43118d3032340f40cac8c0Chris Banes if (isXLarge && isHoneycombApp) { 101200d183885b54de433e43118d3032340f40cac8c0Chris Banes return; 101300d183885b54de433e43118d3032340f40cac8c0Chris Banes } 101400d183885b54de433e43118d3032340f40cac8c0Chris Banes } 101500d183885b54de433e43118d3032340f40cac8c0Chris Banes 1016f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes Window.Callback cb = getWindowCallback(); 101700d183885b54de433e43118d3032340f40cac8c0Chris Banes if ((cb != null) && (!cb.onMenuOpened(st.featureId, st.menu))) { 101800d183885b54de433e43118d3032340f40cac8c0Chris Banes // Callback doesn't want the menu to open, reset any state 101900d183885b54de433e43118d3032340f40cac8c0Chris Banes closePanel(st, true); 102000d183885b54de433e43118d3032340f40cac8c0Chris Banes return; 102100d183885b54de433e43118d3032340f40cac8c0Chris Banes } 102200d183885b54de433e43118d3032340f40cac8c0Chris Banes 102316e8d4dd91083260223c007c797e46bc8f631055Chris Banes final WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); 102446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (wm == null) { 102546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return; 102646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 102746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 102800d183885b54de433e43118d3032340f40cac8c0Chris Banes // Prepare panel (should have been done before, but just in case) 102900d183885b54de433e43118d3032340f40cac8c0Chris Banes if (!preparePanel(st, event)) { 103000d183885b54de433e43118d3032340f40cac8c0Chris Banes return; 103100d183885b54de433e43118d3032340f40cac8c0Chris Banes } 103200d183885b54de433e43118d3032340f40cac8c0Chris Banes 103346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes int width = WRAP_CONTENT; 103400d183885b54de433e43118d3032340f40cac8c0Chris Banes if (st.decorView == null || st.refreshDecorView) { 103546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (st.decorView == null) { 103646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Initialize the panel decor, this will populate st.decorView 103746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (!initializePanelDecor(st) || (st.decorView == null)) 103846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return; 103946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } else if (st.refreshDecorView && (st.decorView.getChildCount() > 0)) { 104046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Decor needs refreshing, so remove its views 104146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.decorView.removeAllViews(); 104246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 104300d183885b54de433e43118d3032340f40cac8c0Chris Banes 104446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // This will populate st.shownPanelView 104546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (!initializePanelContent(st) || !st.hasPanelItems()) { 104646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return; 104746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 104846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 104946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes ViewGroup.LayoutParams lp = st.shownPanelView.getLayoutParams(); 105046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (lp == null) { 105146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes lp = new ViewGroup.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); 105246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 105346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 105446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes int backgroundResId = st.background; 105546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.decorView.setBackgroundResource(backgroundResId); 105646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 105746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes ViewParent shownPanelParent = st.shownPanelView.getParent(); 105846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (shownPanelParent != null && shownPanelParent instanceof ViewGroup) { 105946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes ((ViewGroup) shownPanelParent).removeView(st.shownPanelView); 106046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 106146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.decorView.addView(st.shownPanelView, lp); 106246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 106346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes /* 106446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes * Give focus to the view, if it or one of its children does not 106546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes * already have it. 106646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes */ 106746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (!st.shownPanelView.hasFocus()) { 106846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.shownPanelView.requestFocus(); 106946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 107046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } else if (st.createdPanelView != null) { 107146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // If we already had a panel view, carry width=MATCH_PARENT through 107246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // as we did above when it was created. 107346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes ViewGroup.LayoutParams lp = st.createdPanelView.getLayoutParams(); 107446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (lp != null && lp.width == ViewGroup.LayoutParams.MATCH_PARENT) { 107546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes width = MATCH_PARENT; 107646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 107700d183885b54de433e43118d3032340f40cac8c0Chris Banes } 107800d183885b54de433e43118d3032340f40cac8c0Chris Banes 107900d183885b54de433e43118d3032340f40cac8c0Chris Banes st.isHandled = false; 108046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 108146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes WindowManager.LayoutParams lp = new WindowManager.LayoutParams( 108246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes width, WRAP_CONTENT, 108346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.x, st.y, WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL, 108446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM 108546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, 108646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes PixelFormat.TRANSLUCENT); 108746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 108846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes lp.gravity = st.gravity; 108946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes lp.windowAnimations = st.windowAnimations; 109046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 109146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes wm.addView(st.decorView, lp); 109200d183885b54de433e43118d3032340f40cac8c0Chris Banes st.isOpen = true; 109300d183885b54de433e43118d3032340f40cac8c0Chris Banes } 109400d183885b54de433e43118d3032340f40cac8c0Chris Banes 109546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes private boolean initializePanelDecor(PanelFeatureState st) { 109657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes st.setStyle(getActionBarThemedContext()); 109746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.decorView = new ListMenuDecorView(st.listPresenterContext); 109846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.gravity = Gravity.CENTER | Gravity.BOTTOM; 109946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return true; 110000d183885b54de433e43118d3032340f40cac8c0Chris Banes } 110100d183885b54de433e43118d3032340f40cac8c0Chris Banes 110200d183885b54de433e43118d3032340f40cac8c0Chris Banes private void reopenMenu(MenuBuilder menu, boolean toggleMenuMode) { 110300d183885b54de433e43118d3032340f40cac8c0Chris Banes if (mDecorContentParent != null && mDecorContentParent.canShowOverflowMenu() && 110416e8d4dd91083260223c007c797e46bc8f631055Chris Banes (!ViewConfigurationCompat.hasPermanentMenuKey(ViewConfiguration.get(mContext)) || 110500d183885b54de433e43118d3032340f40cac8c0Chris Banes mDecorContentParent.isOverflowMenuShowPending())) { 11069b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes 1107f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes final Window.Callback cb = getWindowCallback(); 11089b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes 110900d183885b54de433e43118d3032340f40cac8c0Chris Banes if (!mDecorContentParent.isOverflowMenuShowing() || !toggleMenuMode) { 11109b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes if (cb != null && !isDestroyed()) { 11119b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes // If we have a menu invalidation pending, do it now. 11129b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes if (mInvalidatePanelMenuPosted && 11139b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes (mInvalidatePanelMenuFeatures & (1 << FEATURE_OPTIONS_PANEL)) != 0) { 11149b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes mWindowDecor.removeCallbacks(mInvalidatePanelMenuRunnable); 11159b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes mInvalidatePanelMenuRunnable.run(); 11169b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes } 111700d183885b54de433e43118d3032340f40cac8c0Chris Banes 11189b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true); 111900d183885b54de433e43118d3032340f40cac8c0Chris Banes 11209b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes // If we don't have a menu or we're waiting for a full content refresh, 11219b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes // forget it. This is a lingering event that no longer matters. 11229b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes if (st.menu != null && !st.refreshMenuContent && 112346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes cb.onPreparePanel(FEATURE_OPTIONS_PANEL, st.createdPanelView, st.menu)) { 1124d25af35061a9f20d59b25329d613c62c20184dadChris Banes cb.onMenuOpened(FEATURE_SUPPORT_ACTION_BAR, st.menu); 11259b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes mDecorContentParent.showOverflowMenu(); 11269b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes } 112700d183885b54de433e43118d3032340f40cac8c0Chris Banes } 112800d183885b54de433e43118d3032340f40cac8c0Chris Banes } else { 112900d183885b54de433e43118d3032340f40cac8c0Chris Banes mDecorContentParent.hideOverflowMenu(); 11309b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes if (!isDestroyed()) { 11319b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true); 1132d25af35061a9f20d59b25329d613c62c20184dadChris Banes cb.onPanelClosed(FEATURE_SUPPORT_ACTION_BAR, st.menu); 11339b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes } 113400d183885b54de433e43118d3032340f40cac8c0Chris Banes } 113500d183885b54de433e43118d3032340f40cac8c0Chris Banes return; 113600d183885b54de433e43118d3032340f40cac8c0Chris Banes } 113700d183885b54de433e43118d3032340f40cac8c0Chris Banes 113800d183885b54de433e43118d3032340f40cac8c0Chris Banes PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true); 113900d183885b54de433e43118d3032340f40cac8c0Chris Banes 114000d183885b54de433e43118d3032340f40cac8c0Chris Banes st.refreshDecorView = true; 114100d183885b54de433e43118d3032340f40cac8c0Chris Banes closePanel(st, false); 114200d183885b54de433e43118d3032340f40cac8c0Chris Banes 114300d183885b54de433e43118d3032340f40cac8c0Chris Banes openPanel(st, null); 114400d183885b54de433e43118d3032340f40cac8c0Chris Banes } 114500d183885b54de433e43118d3032340f40cac8c0Chris Banes 114600d183885b54de433e43118d3032340f40cac8c0Chris Banes private boolean initializePanelMenu(final PanelFeatureState st) { 114716e8d4dd91083260223c007c797e46bc8f631055Chris Banes Context context = mContext; 114861c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes 114900d183885b54de433e43118d3032340f40cac8c0Chris Banes // If we have an action bar, initialize the menu with the right theme. 1150d25af35061a9f20d59b25329d613c62c20184dadChris Banes if ((st.featureId == FEATURE_OPTIONS_PANEL || st.featureId == FEATURE_SUPPORT_ACTION_BAR) && 115100d183885b54de433e43118d3032340f40cac8c0Chris Banes mDecorContentParent != null) { 115261c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes final TypedValue outValue = new TypedValue(); 115361c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes final Resources.Theme baseTheme = context.getTheme(); 115461c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes baseTheme.resolveAttribute(R.attr.actionBarTheme, outValue, true); 115561c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes 115661c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes Resources.Theme widgetTheme = null; 115761c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes if (outValue.resourceId != 0) { 115861c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes widgetTheme = context.getResources().newTheme(); 115961c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes widgetTheme.setTo(baseTheme); 116061c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes widgetTheme.applyStyle(outValue.resourceId, true); 116161c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes widgetTheme.resolveAttribute( 116261c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes R.attr.actionBarWidgetTheme, outValue, true); 116361c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes } else { 116461c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes baseTheme.resolveAttribute( 116561c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes R.attr.actionBarWidgetTheme, outValue, true); 116661c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes } 116761c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes 116861c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes if (outValue.resourceId != 0) { 116961c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes if (widgetTheme == null) { 117061c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes widgetTheme = context.getResources().newTheme(); 117161c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes widgetTheme.setTo(baseTheme); 117261c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes } 117361c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes widgetTheme.applyStyle(outValue.resourceId, true); 117461c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes } 117561c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes 117661c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes if (widgetTheme != null) { 117761c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes context = new ContextThemeWrapper(context, 0); 117861c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes context.getTheme().setTo(widgetTheme); 117961c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes } 118061c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes } 118161c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes 118200d183885b54de433e43118d3032340f40cac8c0Chris Banes final MenuBuilder menu = new MenuBuilder(context); 118300d183885b54de433e43118d3032340f40cac8c0Chris Banes menu.setCallback(this); 118400d183885b54de433e43118d3032340f40cac8c0Chris Banes st.setMenu(menu); 118561c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes 11868902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes return true; 11878902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes } 11888902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes 118900d183885b54de433e43118d3032340f40cac8c0Chris Banes private boolean initializePanelContent(PanelFeatureState st) { 119046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (st.createdPanelView != null) { 119146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.shownPanelView = st.createdPanelView; 119246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return true; 119346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 119446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 119500d183885b54de433e43118d3032340f40cac8c0Chris Banes if (st.menu == null) { 119600d183885b54de433e43118d3032340f40cac8c0Chris Banes return false; 119700d183885b54de433e43118d3032340f40cac8c0Chris Banes } 119800d183885b54de433e43118d3032340f40cac8c0Chris Banes 119900d183885b54de433e43118d3032340f40cac8c0Chris Banes if (mPanelMenuPresenterCallback == null) { 120000d183885b54de433e43118d3032340f40cac8c0Chris Banes mPanelMenuPresenterCallback = new PanelMenuPresenterCallback(); 120100d183885b54de433e43118d3032340f40cac8c0Chris Banes } 120200d183885b54de433e43118d3032340f40cac8c0Chris Banes 120357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes MenuView menuView = st.getListMenuView(mPanelMenuPresenterCallback); 120400d183885b54de433e43118d3032340f40cac8c0Chris Banes 120500d183885b54de433e43118d3032340f40cac8c0Chris Banes st.shownPanelView = (View) menuView; 120600d183885b54de433e43118d3032340f40cac8c0Chris Banes 120700d183885b54de433e43118d3032340f40cac8c0Chris Banes return st.shownPanelView != null; 120800d183885b54de433e43118d3032340f40cac8c0Chris Banes } 120900d183885b54de433e43118d3032340f40cac8c0Chris Banes 121000d183885b54de433e43118d3032340f40cac8c0Chris Banes private boolean preparePanel(PanelFeatureState st, KeyEvent event) { 12119b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes if (isDestroyed()) { 12129b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes return false; 12139b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes } 12149b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes 12158902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes // Already prepared (isPrepared will be reset to false later) 121600d183885b54de433e43118d3032340f40cac8c0Chris Banes if (st.isPrepared) { 12178902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes return true; 12188902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes } 12198902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes 122000d183885b54de433e43118d3032340f40cac8c0Chris Banes if ((mPreparedPanel != null) && (mPreparedPanel != st)) { 122100d183885b54de433e43118d3032340f40cac8c0Chris Banes // Another Panel is prepared and possibly open, so close it 122200d183885b54de433e43118d3032340f40cac8c0Chris Banes closePanel(mPreparedPanel, false); 122300d183885b54de433e43118d3032340f40cac8c0Chris Banes } 122400d183885b54de433e43118d3032340f40cac8c0Chris Banes 1225f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes final Window.Callback cb = getWindowCallback(); 122646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 122746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (cb != null) { 122846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.createdPanelView = cb.onCreatePanelView(st.featureId); 122946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 123046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 123100d183885b54de433e43118d3032340f40cac8c0Chris Banes final boolean isActionBarMenu = 1232d25af35061a9f20d59b25329d613c62c20184dadChris Banes (st.featureId == FEATURE_OPTIONS_PANEL || st.featureId == FEATURE_SUPPORT_ACTION_BAR); 123300d183885b54de433e43118d3032340f40cac8c0Chris Banes 123400d183885b54de433e43118d3032340f40cac8c0Chris Banes if (isActionBarMenu && mDecorContentParent != null) { 12358088261dec5dd277ccace13fe00f280ffa80098cChris Banes // Enforce ordering guarantees around events so that the action bar never 12368088261dec5dd277ccace13fe00f280ffa80098cChris Banes // dispatches menu-related events before the panel is prepared. 12378088261dec5dd277ccace13fe00f280ffa80098cChris Banes mDecorContentParent.setMenuPrepared(); 12388088261dec5dd277ccace13fe00f280ffa80098cChris Banes } 12398088261dec5dd277ccace13fe00f280ffa80098cChris Banes 12406094d733a9bcc923491937532255f79eb23fab90Chris Banes if (st.createdPanelView == null && 12416094d733a9bcc923491937532255f79eb23fab90Chris Banes (!isActionBarMenu || !(peekSupportActionBar() instanceof ToolbarActionBar))) { 12426094d733a9bcc923491937532255f79eb23fab90Chris Banes // Since ToolbarActionBar handles the list options menu itself, we only want to 12436094d733a9bcc923491937532255f79eb23fab90Chris Banes // init this menu panel if we're not using a TAB. 124446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (st.menu == null || st.refreshMenuContent) { 124546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (st.menu == null) { 124646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (!initializePanelMenu(st) || (st.menu == null)) { 124746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return false; 124846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 12498902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes } 12508902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes 125146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (isActionBarMenu && mDecorContentParent != null) { 125246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (mActionMenuPresenterCallback == null) { 125346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes mActionMenuPresenterCallback = new ActionMenuPresenterCallback(); 125446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 125546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes mDecorContentParent.setMenu(st.menu, mActionMenuPresenterCallback); 125646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 125746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 125846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Creating the panel menu will involve a lot of manipulation; 125946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // don't dispatch change events to presenters until we're done. 126046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.menu.stopDispatchingItemsChanged(); 1261f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes if (!cb.onCreatePanelMenu(st.featureId, st.menu)) { 126246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Ditch the menu created above 126346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.setMenu(null); 126446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 126546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (isActionBarMenu && mDecorContentParent != null) { 126646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Don't show it in the action bar either 126746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes mDecorContentParent.setMenu(null, mActionMenuPresenterCallback); 126846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 126946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 127046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return false; 127103fc11b659da1645507062bddda450136e13af35Chris Banes } 127246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 127346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.refreshMenuContent = false; 12748902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes } 12758902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes 127646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Preparing the panel menu can involve a lot of manipulation; 12778902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes // don't dispatch change events to presenters until we're done. 127800d183885b54de433e43118d3032340f40cac8c0Chris Banes st.menu.stopDispatchingItemsChanged(); 12798902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes 128046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Restore action view state before we prepare. This gives apps 128146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // an opportunity to override frozen/restored state in onPrepare. 128246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (st.frozenActionViewState != null) { 128346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.menu.restoreActionViewStates(st.frozenActionViewState); 128446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.frozenActionViewState = null; 128546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 128646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 128746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Callback and return if the callback does not want to show the menu 128846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (!cb.onPreparePanel(FEATURE_OPTIONS_PANEL, st.createdPanelView, st.menu)) { 128900d183885b54de433e43118d3032340f40cac8c0Chris Banes if (isActionBarMenu && mDecorContentParent != null) { 129046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // The app didn't want to show the menu for now but it still exists. 129146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Clear it out of the action bar. 129203fc11b659da1645507062bddda450136e13af35Chris Banes mDecorContentParent.setMenu(null, mActionMenuPresenterCallback); 12938902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes } 129446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.menu.startDispatchingItemsChanged(); 12958902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes return false; 12968902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes } 12978902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes 129846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Set the proper keymap 129946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes KeyCharacterMap kmap = KeyCharacterMap.load( 130046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes event != null ? event.getDeviceId() : KeyCharacterMap.VIRTUAL_KEYBOARD); 130146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.qwertyMode = kmap.getKeyboardType() != KeyCharacterMap.NUMERIC; 130246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.menu.setQwertyMode(st.qwertyMode); 130300d183885b54de433e43118d3032340f40cac8c0Chris Banes st.menu.startDispatchingItemsChanged(); 13048902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes } 13058902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes 13068902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes // Set other state 130700d183885b54de433e43118d3032340f40cac8c0Chris Banes st.isPrepared = true; 130800d183885b54de433e43118d3032340f40cac8c0Chris Banes st.isHandled = false; 130900d183885b54de433e43118d3032340f40cac8c0Chris Banes mPreparedPanel = st; 13108902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes 13118902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes return true; 13128902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes } 13138902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes 131400d183885b54de433e43118d3032340f40cac8c0Chris Banes private void checkCloseActionMenu(MenuBuilder menu) { 131503fc11b659da1645507062bddda450136e13af35Chris Banes if (mClosingActionMenu) { 131603fc11b659da1645507062bddda450136e13af35Chris Banes return; 131703fc11b659da1645507062bddda450136e13af35Chris Banes } 131803fc11b659da1645507062bddda450136e13af35Chris Banes 131903fc11b659da1645507062bddda450136e13af35Chris Banes mClosingActionMenu = true; 132003fc11b659da1645507062bddda450136e13af35Chris Banes mDecorContentParent.dismissPopups(); 1321f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes Window.Callback cb = getWindowCallback(); 13229b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes if (cb != null && !isDestroyed()) { 1323d25af35061a9f20d59b25329d613c62c20184dadChris Banes cb.onPanelClosed(FEATURE_SUPPORT_ACTION_BAR, menu); 132400d183885b54de433e43118d3032340f40cac8c0Chris Banes } 132503fc11b659da1645507062bddda450136e13af35Chris Banes mClosingActionMenu = false; 132603fc11b659da1645507062bddda450136e13af35Chris Banes } 132703fc11b659da1645507062bddda450136e13af35Chris Banes 132846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes private void closePanel(int featureId) { 132946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes closePanel(getPanelState(featureId, true), true); 133046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 133146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 133200d183885b54de433e43118d3032340f40cac8c0Chris Banes private void closePanel(PanelFeatureState st, boolean doCallback) { 133300d183885b54de433e43118d3032340f40cac8c0Chris Banes if (doCallback && st.featureId == FEATURE_OPTIONS_PANEL && 133400d183885b54de433e43118d3032340f40cac8c0Chris Banes mDecorContentParent != null && mDecorContentParent.isOverflowMenuShowing()) { 133500d183885b54de433e43118d3032340f40cac8c0Chris Banes checkCloseActionMenu(st.menu); 133600d183885b54de433e43118d3032340f40cac8c0Chris Banes return; 133700d183885b54de433e43118d3032340f40cac8c0Chris Banes } 133800d183885b54de433e43118d3032340f40cac8c0Chris Banes 1339436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes final WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); 13404d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes if (wm != null && st.isOpen && st.decorView != null) { 1341436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes wm.removeView(st.decorView); 13424d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes 13434d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes if (doCallback) { 13444d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes callOnPanelClosed(st.featureId, st, null); 13454d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes } 134600d183885b54de433e43118d3032340f40cac8c0Chris Banes } 134700d183885b54de433e43118d3032340f40cac8c0Chris Banes 134800d183885b54de433e43118d3032340f40cac8c0Chris Banes st.isPrepared = false; 134900d183885b54de433e43118d3032340f40cac8c0Chris Banes st.isHandled = false; 135000d183885b54de433e43118d3032340f40cac8c0Chris Banes st.isOpen = false; 135100d183885b54de433e43118d3032340f40cac8c0Chris Banes 135200d183885b54de433e43118d3032340f40cac8c0Chris Banes // This view is no longer shown, so null it out 135300d183885b54de433e43118d3032340f40cac8c0Chris Banes st.shownPanelView = null; 135400d183885b54de433e43118d3032340f40cac8c0Chris Banes 135500d183885b54de433e43118d3032340f40cac8c0Chris Banes // Next time the menu opens, it should not be in expanded mode, so 135600d183885b54de433e43118d3032340f40cac8c0Chris Banes // force a refresh of the decor 135700d183885b54de433e43118d3032340f40cac8c0Chris Banes st.refreshDecorView = true; 135800d183885b54de433e43118d3032340f40cac8c0Chris Banes 135900d183885b54de433e43118d3032340f40cac8c0Chris Banes if (mPreparedPanel == st) { 136000d183885b54de433e43118d3032340f40cac8c0Chris Banes mPreparedPanel = null; 136103fc11b659da1645507062bddda450136e13af35Chris Banes } 136203fc11b659da1645507062bddda450136e13af35Chris Banes } 136303fc11b659da1645507062bddda450136e13af35Chris Banes 136446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes private boolean onKeyDownPanel(int featureId, KeyEvent event) { 136546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (event.getRepeatCount() == 0) { 136646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes PanelFeatureState st = getPanelState(featureId, true); 136746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (!st.isOpen) { 136846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return preparePanel(st, event); 136946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 137046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 137146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 137246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return false; 137346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 137446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 1375559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes private boolean onKeyUpPanel(int featureId, KeyEvent event) { 137646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (mActionMode != null) { 1377559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes return false; 137846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 137946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 1380559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes boolean handled = false; 138146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes final PanelFeatureState st = getPanelState(featureId, true); 138246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (featureId == FEATURE_OPTIONS_PANEL && mDecorContentParent != null && 138346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes mDecorContentParent.canShowOverflowMenu() && 138416e8d4dd91083260223c007c797e46bc8f631055Chris Banes !ViewConfigurationCompat.hasPermanentMenuKey(ViewConfiguration.get(mContext))) { 138546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (!mDecorContentParent.isOverflowMenuShowing()) { 138646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (!isDestroyed() && preparePanel(st, event)) { 1387559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes handled = mDecorContentParent.showOverflowMenu(); 138846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 138946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } else { 1390559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes handled = mDecorContentParent.hideOverflowMenu(); 139146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 139246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } else { 139346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (st.isOpen || st.isHandled) { 139446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Play the sound effect if the user closed an open menu (and not if 139546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // they just released a menu shortcut) 1396559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes handled = st.isOpen; 139746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Close menu 139846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes closePanel(st, true); 139946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } else if (st.isPrepared) { 140046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes boolean show = true; 140146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (st.refreshMenuContent) { 140246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Something may have invalidated the menu since we prepared it. 140346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Re-prepare it to refresh. 140446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.isPrepared = false; 140546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes show = preparePanel(st, event); 140646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 140746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 140846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (show) { 140946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Show menu 141046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes openPanel(st, event); 1411559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes handled = true; 141246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 141346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 141446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 141546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 1416559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes if (handled) { 141716e8d4dd91083260223c007c797e46bc8f631055Chris Banes AudioManager audioManager = (AudioManager) mContext.getSystemService( 141846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes Context.AUDIO_SERVICE); 141946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (audioManager != null) { 142046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes audioManager.playSoundEffect(AudioManager.FX_KEY_CLICK); 142146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } else { 142246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes Log.w(TAG, "Couldn't get audio manager"); 142346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 142446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 1425559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes return handled; 142646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 142746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 142800d183885b54de433e43118d3032340f40cac8c0Chris Banes private void callOnPanelClosed(int featureId, PanelFeatureState panel, Menu menu) { 142900d183885b54de433e43118d3032340f40cac8c0Chris Banes // Try to get a menu 143000d183885b54de433e43118d3032340f40cac8c0Chris Banes if (menu == null) { 143100d183885b54de433e43118d3032340f40cac8c0Chris Banes // Need a panel to grab the menu, so try to get that 143200d183885b54de433e43118d3032340f40cac8c0Chris Banes if (panel == null) { 143300d183885b54de433e43118d3032340f40cac8c0Chris Banes if ((featureId >= 0) && (featureId < mPanels.length)) { 143400d183885b54de433e43118d3032340f40cac8c0Chris Banes panel = mPanels[featureId]; 143500d183885b54de433e43118d3032340f40cac8c0Chris Banes } 143600d183885b54de433e43118d3032340f40cac8c0Chris Banes } 143700d183885b54de433e43118d3032340f40cac8c0Chris Banes 143800d183885b54de433e43118d3032340f40cac8c0Chris Banes if (panel != null) { 143900d183885b54de433e43118d3032340f40cac8c0Chris Banes // menu still may be null, which is okay--we tried our best 144000d183885b54de433e43118d3032340f40cac8c0Chris Banes menu = panel.menu; 144100d183885b54de433e43118d3032340f40cac8c0Chris Banes } 144200d183885b54de433e43118d3032340f40cac8c0Chris Banes } 144300d183885b54de433e43118d3032340f40cac8c0Chris Banes 144400d183885b54de433e43118d3032340f40cac8c0Chris Banes // If the panel is not open, do not callback 144500d183885b54de433e43118d3032340f40cac8c0Chris Banes if ((panel != null) && (!panel.isOpen)) 144600d183885b54de433e43118d3032340f40cac8c0Chris Banes return; 144700d183885b54de433e43118d3032340f40cac8c0Chris Banes 1448d2f8851a0a27ea6a2ddf5a88097f3d10eed38485Chris Banes if (!isDestroyed()) { 1449d2f8851a0a27ea6a2ddf5a88097f3d10eed38485Chris Banes // We need to be careful which callback we dispatch the call to. We can not dispatch 1450d2f8851a0a27ea6a2ddf5a88097f3d10eed38485Chris Banes // this to the Window's callback since that will call back into this method and cause a 1451d2f8851a0a27ea6a2ddf5a88097f3d10eed38485Chris Banes // crash. Instead we need to dispatch down to the original Activity/Dialog/etc. 1452d2f8851a0a27ea6a2ddf5a88097f3d10eed38485Chris Banes mOriginalWindowCallback.onPanelClosed(featureId, menu); 1453f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 145400d183885b54de433e43118d3032340f40cac8c0Chris Banes } 145500d183885b54de433e43118d3032340f40cac8c0Chris Banes 145600d183885b54de433e43118d3032340f40cac8c0Chris Banes private PanelFeatureState findMenuPanel(Menu menu) { 145700d183885b54de433e43118d3032340f40cac8c0Chris Banes final PanelFeatureState[] panels = mPanels; 145800d183885b54de433e43118d3032340f40cac8c0Chris Banes final int N = panels != null ? panels.length : 0; 145900d183885b54de433e43118d3032340f40cac8c0Chris Banes for (int i = 0; i < N; i++) { 146000d183885b54de433e43118d3032340f40cac8c0Chris Banes final PanelFeatureState panel = panels[i]; 146100d183885b54de433e43118d3032340f40cac8c0Chris Banes if (panel != null && panel.menu == menu) { 146200d183885b54de433e43118d3032340f40cac8c0Chris Banes return panel; 146300d183885b54de433e43118d3032340f40cac8c0Chris Banes } 146400d183885b54de433e43118d3032340f40cac8c0Chris Banes } 146500d183885b54de433e43118d3032340f40cac8c0Chris Banes return null; 146600d183885b54de433e43118d3032340f40cac8c0Chris Banes } 146700d183885b54de433e43118d3032340f40cac8c0Chris Banes 146800d183885b54de433e43118d3032340f40cac8c0Chris Banes private PanelFeatureState getPanelState(int featureId, boolean required) { 146900d183885b54de433e43118d3032340f40cac8c0Chris Banes PanelFeatureState[] ar; 147000d183885b54de433e43118d3032340f40cac8c0Chris Banes if ((ar = mPanels) == null || ar.length <= featureId) { 147100d183885b54de433e43118d3032340f40cac8c0Chris Banes PanelFeatureState[] nar = new PanelFeatureState[featureId + 1]; 147200d183885b54de433e43118d3032340f40cac8c0Chris Banes if (ar != null) { 147300d183885b54de433e43118d3032340f40cac8c0Chris Banes System.arraycopy(ar, 0, nar, 0, ar.length); 147400d183885b54de433e43118d3032340f40cac8c0Chris Banes } 147500d183885b54de433e43118d3032340f40cac8c0Chris Banes mPanels = ar = nar; 147603fc11b659da1645507062bddda450136e13af35Chris Banes } 147700d183885b54de433e43118d3032340f40cac8c0Chris Banes 147800d183885b54de433e43118d3032340f40cac8c0Chris Banes PanelFeatureState st = ar[featureId]; 147900d183885b54de433e43118d3032340f40cac8c0Chris Banes if (st == null) { 148000d183885b54de433e43118d3032340f40cac8c0Chris Banes ar[featureId] = st = new PanelFeatureState(featureId); 148100d183885b54de433e43118d3032340f40cac8c0Chris Banes } 148200d183885b54de433e43118d3032340f40cac8c0Chris Banes return st; 148303fc11b659da1645507062bddda450136e13af35Chris Banes } 148403fc11b659da1645507062bddda450136e13af35Chris Banes 1485f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes private boolean performPanelShortcut(PanelFeatureState st, int keyCode, KeyEvent event, 148600d183885b54de433e43118d3032340f40cac8c0Chris Banes int flags) { 1487dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes if (event.isSystem()) { 1488dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes return false; 1489dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes } 1490dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes 1491dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes boolean handled = false; 1492dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes 1493dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes // Only try to perform menu shortcuts if preparePanel returned true (possible false 1494dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes // return value from application not wanting to show the menu). 149500d183885b54de433e43118d3032340f40cac8c0Chris Banes if ((st.isPrepared || preparePanel(st, event)) && st.menu != null) { 1496dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes // The menu is prepared now, perform the shortcut on it 149700d183885b54de433e43118d3032340f40cac8c0Chris Banes handled = st.menu.performShortcut(keyCode, event, flags); 1498dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes } 1499dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes 1500dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes if (handled) { 1501dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes // Only close down the menu if we don't have an action bar keeping it open. 1502dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes if ((flags & Menu.FLAG_PERFORM_NO_CLOSE) == 0 && mDecorContentParent == null) { 150300d183885b54de433e43118d3032340f40cac8c0Chris Banes closePanel(st, true); 1504dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes } 1505dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes } 1506dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes 1507dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes return handled; 1508dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes } 1509dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes 151000d183885b54de433e43118d3032340f40cac8c0Chris Banes private void invalidatePanelMenu(int featureId) { 151100d183885b54de433e43118d3032340f40cac8c0Chris Banes mInvalidatePanelMenuFeatures |= 1 << featureId; 151200d183885b54de433e43118d3032340f40cac8c0Chris Banes 151300d183885b54de433e43118d3032340f40cac8c0Chris Banes if (!mInvalidatePanelMenuPosted && mWindowDecor != null) { 151400d183885b54de433e43118d3032340f40cac8c0Chris Banes ViewCompat.postOnAnimation(mWindowDecor, mInvalidatePanelMenuRunnable); 151500d183885b54de433e43118d3032340f40cac8c0Chris Banes mInvalidatePanelMenuPosted = true; 151600d183885b54de433e43118d3032340f40cac8c0Chris Banes } 151700d183885b54de433e43118d3032340f40cac8c0Chris Banes } 151800d183885b54de433e43118d3032340f40cac8c0Chris Banes 151900d183885b54de433e43118d3032340f40cac8c0Chris Banes private void doInvalidatePanelMenu(int featureId) { 152000d183885b54de433e43118d3032340f40cac8c0Chris Banes PanelFeatureState st = getPanelState(featureId, true); 152100d183885b54de433e43118d3032340f40cac8c0Chris Banes Bundle savedActionViewStates = null; 152200d183885b54de433e43118d3032340f40cac8c0Chris Banes if (st.menu != null) { 152300d183885b54de433e43118d3032340f40cac8c0Chris Banes savedActionViewStates = new Bundle(); 152400d183885b54de433e43118d3032340f40cac8c0Chris Banes st.menu.saveActionViewStates(savedActionViewStates); 152500d183885b54de433e43118d3032340f40cac8c0Chris Banes if (savedActionViewStates.size() > 0) { 152600d183885b54de433e43118d3032340f40cac8c0Chris Banes st.frozenActionViewState = savedActionViewStates; 152700d183885b54de433e43118d3032340f40cac8c0Chris Banes } 152800d183885b54de433e43118d3032340f40cac8c0Chris Banes // This will be started again when the panel is prepared. 152900d183885b54de433e43118d3032340f40cac8c0Chris Banes st.menu.stopDispatchingItemsChanged(); 153000d183885b54de433e43118d3032340f40cac8c0Chris Banes st.menu.clear(); 153100d183885b54de433e43118d3032340f40cac8c0Chris Banes } 153200d183885b54de433e43118d3032340f40cac8c0Chris Banes st.refreshMenuContent = true; 153300d183885b54de433e43118d3032340f40cac8c0Chris Banes st.refreshDecorView = true; 153400d183885b54de433e43118d3032340f40cac8c0Chris Banes 153500d183885b54de433e43118d3032340f40cac8c0Chris Banes // Prepare the options panel if we have an action bar 1536d25af35061a9f20d59b25329d613c62c20184dadChris Banes if ((featureId == FEATURE_SUPPORT_ACTION_BAR || featureId == FEATURE_OPTIONS_PANEL) 153700d183885b54de433e43118d3032340f40cac8c0Chris Banes && mDecorContentParent != null) { 153800d183885b54de433e43118d3032340f40cac8c0Chris Banes st = getPanelState(Window.FEATURE_OPTIONS_PANEL, false); 153900d183885b54de433e43118d3032340f40cac8c0Chris Banes if (st != null) { 154000d183885b54de433e43118d3032340f40cac8c0Chris Banes st.isPrepared = false; 154100d183885b54de433e43118d3032340f40cac8c0Chris Banes preparePanel(st, null); 154200d183885b54de433e43118d3032340f40cac8c0Chris Banes } 154300d183885b54de433e43118d3032340f40cac8c0Chris Banes } 154400d183885b54de433e43118d3032340f40cac8c0Chris Banes } 154500d183885b54de433e43118d3032340f40cac8c0Chris Banes 1546ea4f700ac38424954c56df5138ff794def50b019Chris Banes /** 1547ea4f700ac38424954c56df5138ff794def50b019Chris Banes * Updates the status bar guard 1548ea4f700ac38424954c56df5138ff794def50b019Chris Banes * 1549ea4f700ac38424954c56df5138ff794def50b019Chris Banes * @param insetTop the current top system window inset 1550ea4f700ac38424954c56df5138ff794def50b019Chris Banes * @return the new top system window inset 1551ea4f700ac38424954c56df5138ff794def50b019Chris Banes */ 1552ea4f700ac38424954c56df5138ff794def50b019Chris Banes private int updateStatusGuard(int insetTop) { 1553ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes boolean showStatusGuard = false; 1554ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes // Show the status guard when the non-overlay contextual action bar is showing 1555ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes if (mActionModeView != null) { 1556ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes if (mActionModeView.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) { 1557ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) 1558ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes mActionModeView.getLayoutParams(); 1559ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes boolean mlpChanged = false; 1560ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes 1561ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes if (mActionModeView.isShown()) { 15627efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell if (mTempRect1 == null) { 15637efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell mTempRect1 = new Rect(); 15647efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell mTempRect2 = new Rect(); 15657efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell } 15667efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell final Rect insets = mTempRect1; 15677efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell final Rect localInsets = mTempRect2; 15687efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell insets.set(0, insetTop, 0, 0); 15697efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell 15707efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell ViewUtils.computeFitSystemWindows(mSubDecor, insets, localInsets); 15717efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell final int newMargin = localInsets.top == 0 ? insetTop : 0; 15727efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell if (mlp.topMargin != newMargin) { 15737efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell mlpChanged = true; 15747efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell mlp.topMargin = insetTop; 15757efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell 1576ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes if (mStatusGuard == null) { 157716e8d4dd91083260223c007c797e46bc8f631055Chris Banes mStatusGuard = new View(mContext); 157816e8d4dd91083260223c007c797e46bc8f631055Chris Banes mStatusGuard.setBackgroundColor(mContext.getResources() 1579ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes .getColor(R.color.abc_input_method_navigation_guard)); 15807efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell mSubDecor.addView(mStatusGuard, -1, 1581ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1582ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes insetTop)); 1583ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } else { 1584ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes ViewGroup.LayoutParams lp = mStatusGuard.getLayoutParams(); 1585ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes if (lp.height != insetTop) { 1586ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes lp.height = insetTop; 1587ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes mStatusGuard.setLayoutParams(lp); 1588ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 1589ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 1590ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 1591ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes 1592bbb50c78cc6ee24677c79bd4548fa38fcdc41d92Adam Powell // The action mode's theme may differ from the app, so 1593bbb50c78cc6ee24677c79bd4548fa38fcdc41d92Adam Powell // always show the status guard above it. 1594bbb50c78cc6ee24677c79bd4548fa38fcdc41d92Adam Powell showStatusGuard = mStatusGuard != null; 1595bbb50c78cc6ee24677c79bd4548fa38fcdc41d92Adam Powell 15967efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell // We only need to consume the insets if the action 15977efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell // mode is overlaid on the app content (e.g. it's 15987efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell // sitting in a FrameLayout, see 15997efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell // screen_simple_overlay_action_mode.xml). 1600bbb50c78cc6ee24677c79bd4548fa38fcdc41d92Adam Powell if (!mOverlayActionMode && showStatusGuard) { 16017efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell insetTop = 0; 16027efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell } 1603ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } else { 1604ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes // reset top margin 1605ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes if (mlp.topMargin != 0) { 1606ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes mlpChanged = true; 1607ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes mlp.topMargin = 0; 1608ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 1609ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 1610ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes if (mlpChanged) { 1611ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes mActionModeView.setLayoutParams(mlp); 1612ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 1613ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 1614ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 1615ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes if (mStatusGuard != null) { 1616ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes mStatusGuard.setVisibility(showStatusGuard ? View.VISIBLE : View.GONE); 1617ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 1618ea4f700ac38424954c56df5138ff794def50b019Chris Banes 1619ea4f700ac38424954c56df5138ff794def50b019Chris Banes return insetTop; 1620ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 1621ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes 1622cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes private void throwFeatureRequestIfSubDecorInstalled() { 1623cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes if (mSubDecorInstalled) { 1624cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes throw new AndroidRuntimeException( 1625f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes "Window feature must be requested before adding content"); 1626cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes } 1627cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes } 1628cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes 16298122ad54f129c2214631fad86cabda82815cc0d8Chris Banes private int sanitizeWindowFeatureId(int featureId) { 16308122ad54f129c2214631fad86cabda82815cc0d8Chris Banes if (featureId == WindowCompat.FEATURE_ACTION_BAR) { 16318122ad54f129c2214631fad86cabda82815cc0d8Chris Banes Log.i(TAG, "You should now use the AppCompatDelegate.FEATURE_SUPPORT_ACTION_BAR" 16328122ad54f129c2214631fad86cabda82815cc0d8Chris Banes + " id when requesting this feature."); 16338122ad54f129c2214631fad86cabda82815cc0d8Chris Banes return FEATURE_SUPPORT_ACTION_BAR; 16348122ad54f129c2214631fad86cabda82815cc0d8Chris Banes } else if (featureId == WindowCompat.FEATURE_ACTION_BAR_OVERLAY) { 16358122ad54f129c2214631fad86cabda82815cc0d8Chris Banes Log.i(TAG, "You should now use the AppCompatDelegate.FEATURE_SUPPORT_ACTION_BAR_OVERLAY" 16368122ad54f129c2214631fad86cabda82815cc0d8Chris Banes + " id when requesting this feature."); 16378122ad54f129c2214631fad86cabda82815cc0d8Chris Banes return FEATURE_SUPPORT_ACTION_BAR_OVERLAY; 16388122ad54f129c2214631fad86cabda82815cc0d8Chris Banes } 16398122ad54f129c2214631fad86cabda82815cc0d8Chris Banes // Else we'll just return the original id 16408122ad54f129c2214631fad86cabda82815cc0d8Chris Banes return featureId; 16418122ad54f129c2214631fad86cabda82815cc0d8Chris Banes } 16428122ad54f129c2214631fad86cabda82815cc0d8Chris Banes 164316e8d4dd91083260223c007c797e46bc8f631055Chris Banes ViewGroup getSubDecor() { 164416e8d4dd91083260223c007c797e46bc8f631055Chris Banes return mSubDecor; 164516e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 164616e8d4dd91083260223c007c797e46bc8f631055Chris Banes 1647b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes private void dismissPopups() { 1648b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes if (mDecorContentParent != null) { 1649b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes mDecorContentParent.dismissPopups(); 1650b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes } 1651b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes 1652b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes if (mActionModePopup != null) { 1653b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes mWindowDecor.removeCallbacks(mShowActionModePopup); 1654b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes if (mActionModePopup.isShowing()) { 1655b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes mActionModePopup.dismiss(); 1656b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes } 1657b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes mActionModePopup = null; 1658b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes } 1659b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes endOnGoingFadeAnimation(); 1660b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes 1661b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, false); 1662b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes if (st != null && st.menu != null) { 1663b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes st.menu.close(); 1664b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes } 1665b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes } 1666b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes 1667ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes /** 1668d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes * Clears out internal reference when the action mode is destroyed. 1669d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes */ 1670547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes class ActionModeCallbackWrapperV7 implements ActionMode.Callback { 1671d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes private ActionMode.Callback mWrapped; 1672d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 1673547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes public ActionModeCallbackWrapperV7(ActionMode.Callback wrapped) { 1674d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes mWrapped = wrapped; 1675d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 1676d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 1677d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes public boolean onCreateActionMode(ActionMode mode, Menu menu) { 1678d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes return mWrapped.onCreateActionMode(mode, menu); 1679d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 1680d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 1681d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 16829addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banes return mWrapped.onPrepareActionMode(mode, menu); 1683d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 1684d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 1685d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 1686d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes return mWrapped.onActionItemClicked(mode, item); 1687d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 1688d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 1689d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes public void onDestroyActionMode(ActionMode mode) { 1690d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes mWrapped.onDestroyActionMode(mode); 16914c2a95906254748cb9a843b061288265d6e185a9Chris Banes if (mActionModePopup != null) { 169216e8d4dd91083260223c007c797e46bc8f631055Chris Banes mWindow.getDecorView().removeCallbacks(mShowActionModePopup); 16934c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1694c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu 16954c2a95906254748cb9a843b061288265d6e185a9Chris Banes if (mActionModeView != null) { 1696c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu endOnGoingFadeAnimation(); 1697c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu mFadeAnim = ViewCompat.animate(mActionModeView).alpha(0f); 1698c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu mFadeAnim.setListener(new ViewPropertyAnimatorListenerAdapter() { 1699c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu @Override 1700c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu public void onAnimationEnd(View view) { 1701c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu mActionModeView.setVisibility(View.GONE); 1702c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu if (mActionModePopup != null) { 1703c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu mActionModePopup.dismiss(); 1704c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu } else if (mActionModeView.getParent() instanceof View) { 1705c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu ViewCompat.requestApplyInsets((View) mActionModeView.getParent()); 1706c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu } 1707c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu mActionModeView.removeAllViews(); 1708c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu mFadeAnim.setListener(null); 1709c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu mFadeAnim = null; 1710c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu } 1711c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu }); 17124c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1713f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes if (mAppCompatCallback != null) { 1714f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes mAppCompatCallback.onSupportActionModeFinished(mActionMode); 17154c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1716d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes mActionMode = null; 1717d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 1718d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 1719d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 172003fc11b659da1645507062bddda450136e13af35Chris Banes private final class PanelMenuPresenterCallback implements MenuPresenter.Callback { 172103fc11b659da1645507062bddda450136e13af35Chris Banes @Override 172200d183885b54de433e43118d3032340f40cac8c0Chris Banes public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { 172300d183885b54de433e43118d3032340f40cac8c0Chris Banes final Menu parentMenu = menu.getRootMenu(); 172400d183885b54de433e43118d3032340f40cac8c0Chris Banes final boolean isSubMenu = parentMenu != menu; 172500d183885b54de433e43118d3032340f40cac8c0Chris Banes final PanelFeatureState panel = findMenuPanel(isSubMenu ? parentMenu : menu); 172600d183885b54de433e43118d3032340f40cac8c0Chris Banes if (panel != null) { 172700d183885b54de433e43118d3032340f40cac8c0Chris Banes if (isSubMenu) { 172800d183885b54de433e43118d3032340f40cac8c0Chris Banes callOnPanelClosed(panel.featureId, panel, parentMenu); 172900d183885b54de433e43118d3032340f40cac8c0Chris Banes closePanel(panel, true); 173000d183885b54de433e43118d3032340f40cac8c0Chris Banes } else { 173100d183885b54de433e43118d3032340f40cac8c0Chris Banes // Close the panel and only do the callback if the menu is being 173200d183885b54de433e43118d3032340f40cac8c0Chris Banes // closed completely, not if opening a sub menu 173300d183885b54de433e43118d3032340f40cac8c0Chris Banes closePanel(panel, allMenusAreClosing); 173400d183885b54de433e43118d3032340f40cac8c0Chris Banes } 173500d183885b54de433e43118d3032340f40cac8c0Chris Banes } 173603fc11b659da1645507062bddda450136e13af35Chris Banes } 173703fc11b659da1645507062bddda450136e13af35Chris Banes 173803fc11b659da1645507062bddda450136e13af35Chris Banes @Override 173900d183885b54de433e43118d3032340f40cac8c0Chris Banes public boolean onOpenSubMenu(MenuBuilder subMenu) { 174000d183885b54de433e43118d3032340f40cac8c0Chris Banes if (subMenu == null && mHasActionBar) { 1741f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes Window.Callback cb = getWindowCallback(); 17429b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes if (cb != null && !isDestroyed()) { 1743d25af35061a9f20d59b25329d613c62c20184dadChris Banes cb.onMenuOpened(FEATURE_SUPPORT_ACTION_BAR, subMenu); 174400d183885b54de433e43118d3032340f40cac8c0Chris Banes } 174500d183885b54de433e43118d3032340f40cac8c0Chris Banes } 174600d183885b54de433e43118d3032340f40cac8c0Chris Banes return true; 174703fc11b659da1645507062bddda450136e13af35Chris Banes } 174803fc11b659da1645507062bddda450136e13af35Chris Banes } 174903fc11b659da1645507062bddda450136e13af35Chris Banes 175003fc11b659da1645507062bddda450136e13af35Chris Banes private final class ActionMenuPresenterCallback implements MenuPresenter.Callback { 175103fc11b659da1645507062bddda450136e13af35Chris Banes @Override 175203fc11b659da1645507062bddda450136e13af35Chris Banes public boolean onOpenSubMenu(MenuBuilder subMenu) { 1753f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes Window.Callback cb = getWindowCallback(); 175400d183885b54de433e43118d3032340f40cac8c0Chris Banes if (cb != null) { 1755d25af35061a9f20d59b25329d613c62c20184dadChris Banes cb.onMenuOpened(FEATURE_SUPPORT_ACTION_BAR, subMenu); 175600d183885b54de433e43118d3032340f40cac8c0Chris Banes } 175700d183885b54de433e43118d3032340f40cac8c0Chris Banes return true; 175803fc11b659da1645507062bddda450136e13af35Chris Banes } 175903fc11b659da1645507062bddda450136e13af35Chris Banes 176003fc11b659da1645507062bddda450136e13af35Chris Banes @Override 176103fc11b659da1645507062bddda450136e13af35Chris Banes public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { 176200d183885b54de433e43118d3032340f40cac8c0Chris Banes checkCloseActionMenu(menu); 176300d183885b54de433e43118d3032340f40cac8c0Chris Banes } 176400d183885b54de433e43118d3032340f40cac8c0Chris Banes } 176500d183885b54de433e43118d3032340f40cac8c0Chris Banes 176600d183885b54de433e43118d3032340f40cac8c0Chris Banes private static final class PanelFeatureState { 17679b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes 176800d183885b54de433e43118d3032340f40cac8c0Chris Banes /** Feature ID for this panel. */ 176900d183885b54de433e43118d3032340f40cac8c0Chris Banes int featureId; 177000d183885b54de433e43118d3032340f40cac8c0Chris Banes 177146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes int background; 177246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 177346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes int gravity; 177446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 177546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes int x; 177646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 177746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes int y; 177846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 177946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes int windowAnimations; 178046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 178100d183885b54de433e43118d3032340f40cac8c0Chris Banes /** Dynamic state of the panel. */ 178200d183885b54de433e43118d3032340f40cac8c0Chris Banes ViewGroup decorView; 178300d183885b54de433e43118d3032340f40cac8c0Chris Banes 178400d183885b54de433e43118d3032340f40cac8c0Chris Banes /** The panel that we are actually showing. */ 178500d183885b54de433e43118d3032340f40cac8c0Chris Banes View shownPanelView; 178600d183885b54de433e43118d3032340f40cac8c0Chris Banes 178746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes /** The panel that was returned by onCreatePanelView(). */ 178846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes View createdPanelView; 178946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 179000d183885b54de433e43118d3032340f40cac8c0Chris Banes /** Use {@link #setMenu} to set this. */ 179100d183885b54de433e43118d3032340f40cac8c0Chris Banes MenuBuilder menu; 179200d183885b54de433e43118d3032340f40cac8c0Chris Banes 179300d183885b54de433e43118d3032340f40cac8c0Chris Banes ListMenuPresenter listMenuPresenter; 179400d183885b54de433e43118d3032340f40cac8c0Chris Banes 179557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes Context listPresenterContext; 179600d183885b54de433e43118d3032340f40cac8c0Chris Banes 179700d183885b54de433e43118d3032340f40cac8c0Chris Banes /** 179800d183885b54de433e43118d3032340f40cac8c0Chris Banes * Whether the panel has been prepared (see 17999b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes * {@link #preparePanel}). 180000d183885b54de433e43118d3032340f40cac8c0Chris Banes */ 180100d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean isPrepared; 180200d183885b54de433e43118d3032340f40cac8c0Chris Banes 180300d183885b54de433e43118d3032340f40cac8c0Chris Banes /** 180400d183885b54de433e43118d3032340f40cac8c0Chris Banes * Whether an item's action has been performed. This happens in obvious 180500d183885b54de433e43118d3032340f40cac8c0Chris Banes * scenarios (user clicks on menu item), but can also happen with 180600d183885b54de433e43118d3032340f40cac8c0Chris Banes * chording menu+(shortcut key). 180700d183885b54de433e43118d3032340f40cac8c0Chris Banes */ 180800d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean isHandled; 180900d183885b54de433e43118d3032340f40cac8c0Chris Banes 181000d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean isOpen; 181100d183885b54de433e43118d3032340f40cac8c0Chris Banes 181200d183885b54de433e43118d3032340f40cac8c0Chris Banes public boolean qwertyMode; 181300d183885b54de433e43118d3032340f40cac8c0Chris Banes 181400d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean refreshDecorView; 181500d183885b54de433e43118d3032340f40cac8c0Chris Banes 181600d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean refreshMenuContent; 181700d183885b54de433e43118d3032340f40cac8c0Chris Banes 181800d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean wasLastOpen; 181900d183885b54de433e43118d3032340f40cac8c0Chris Banes 182000d183885b54de433e43118d3032340f40cac8c0Chris Banes /** 182100d183885b54de433e43118d3032340f40cac8c0Chris Banes * Contains the state of the menu when told to freeze. 182200d183885b54de433e43118d3032340f40cac8c0Chris Banes */ 182300d183885b54de433e43118d3032340f40cac8c0Chris Banes Bundle frozenMenuState; 182400d183885b54de433e43118d3032340f40cac8c0Chris Banes 182500d183885b54de433e43118d3032340f40cac8c0Chris Banes /** 182600d183885b54de433e43118d3032340f40cac8c0Chris Banes * Contains the state of associated action views when told to freeze. 182700d183885b54de433e43118d3032340f40cac8c0Chris Banes * These are saved across invalidations. 182800d183885b54de433e43118d3032340f40cac8c0Chris Banes */ 182900d183885b54de433e43118d3032340f40cac8c0Chris Banes Bundle frozenActionViewState; 183000d183885b54de433e43118d3032340f40cac8c0Chris Banes 183100d183885b54de433e43118d3032340f40cac8c0Chris Banes PanelFeatureState(int featureId) { 183200d183885b54de433e43118d3032340f40cac8c0Chris Banes this.featureId = featureId; 183300d183885b54de433e43118d3032340f40cac8c0Chris Banes 183400d183885b54de433e43118d3032340f40cac8c0Chris Banes refreshDecorView = false; 183500d183885b54de433e43118d3032340f40cac8c0Chris Banes } 183600d183885b54de433e43118d3032340f40cac8c0Chris Banes 183700d183885b54de433e43118d3032340f40cac8c0Chris Banes public boolean hasPanelItems() { 183800d183885b54de433e43118d3032340f40cac8c0Chris Banes if (shownPanelView == null) return false; 183946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (createdPanelView != null) return true; 184000d183885b54de433e43118d3032340f40cac8c0Chris Banes 184100d183885b54de433e43118d3032340f40cac8c0Chris Banes return listMenuPresenter.getAdapter().getCount() > 0; 184200d183885b54de433e43118d3032340f40cac8c0Chris Banes } 184300d183885b54de433e43118d3032340f40cac8c0Chris Banes 184400d183885b54de433e43118d3032340f40cac8c0Chris Banes /** 184500d183885b54de433e43118d3032340f40cac8c0Chris Banes * Unregister and free attached MenuPresenters. They will be recreated as needed. 184600d183885b54de433e43118d3032340f40cac8c0Chris Banes */ 184700d183885b54de433e43118d3032340f40cac8c0Chris Banes public void clearMenuPresenters() { 184800d183885b54de433e43118d3032340f40cac8c0Chris Banes if (menu != null) { 184900d183885b54de433e43118d3032340f40cac8c0Chris Banes menu.removeMenuPresenter(listMenuPresenter); 185000d183885b54de433e43118d3032340f40cac8c0Chris Banes } 185100d183885b54de433e43118d3032340f40cac8c0Chris Banes listMenuPresenter = null; 185200d183885b54de433e43118d3032340f40cac8c0Chris Banes } 185300d183885b54de433e43118d3032340f40cac8c0Chris Banes 185400d183885b54de433e43118d3032340f40cac8c0Chris Banes void setStyle(Context context) { 185557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes final TypedValue outValue = new TypedValue(); 185657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes final Resources.Theme widgetTheme = context.getResources().newTheme(); 185757c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes widgetTheme.setTo(context.getTheme()); 185857c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes 185957c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes // First apply the actionBarPopupTheme 186057c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes widgetTheme.resolveAttribute(R.attr.actionBarPopupTheme, outValue, true); 186157c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes if (outValue.resourceId != 0) { 186257c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes widgetTheme.applyStyle(outValue.resourceId, true); 186357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes } 186457c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes 186557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes // Now apply the panelMenuListTheme 186657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes widgetTheme.resolveAttribute(R.attr.panelMenuListTheme, outValue, true); 186757c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes if (outValue.resourceId != 0) { 186857c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes widgetTheme.applyStyle(outValue.resourceId, true); 186957c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes } else { 187057c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes widgetTheme.applyStyle(R.style.Theme_AppCompat_CompactMenu, true); 187157c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes } 187257c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes 187357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes context = new ContextThemeWrapper(context, 0); 187457c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes context.getTheme().setTo(widgetTheme); 187557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes 187657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes listPresenterContext = context; 187746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 187846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes TypedArray a = context.obtainStyledAttributes(R.styleable.Theme); 187946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes background = a.getResourceId( 188046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes R.styleable.Theme_panelBackground, 0); 188146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes windowAnimations = a.getResourceId( 188246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes R.styleable.Theme_android_windowAnimationStyle, 0); 188346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes a.recycle(); 188400d183885b54de433e43118d3032340f40cac8c0Chris Banes } 188500d183885b54de433e43118d3032340f40cac8c0Chris Banes 188600d183885b54de433e43118d3032340f40cac8c0Chris Banes void setMenu(MenuBuilder menu) { 188700d183885b54de433e43118d3032340f40cac8c0Chris Banes if (menu == this.menu) return; 188800d183885b54de433e43118d3032340f40cac8c0Chris Banes 188900d183885b54de433e43118d3032340f40cac8c0Chris Banes if (this.menu != null) { 189000d183885b54de433e43118d3032340f40cac8c0Chris Banes this.menu.removeMenuPresenter(listMenuPresenter); 189100d183885b54de433e43118d3032340f40cac8c0Chris Banes } 189200d183885b54de433e43118d3032340f40cac8c0Chris Banes this.menu = menu; 189300d183885b54de433e43118d3032340f40cac8c0Chris Banes if (menu != null) { 189400d183885b54de433e43118d3032340f40cac8c0Chris Banes if (listMenuPresenter != null) menu.addMenuPresenter(listMenuPresenter); 189500d183885b54de433e43118d3032340f40cac8c0Chris Banes } 189600d183885b54de433e43118d3032340f40cac8c0Chris Banes } 189700d183885b54de433e43118d3032340f40cac8c0Chris Banes 189857c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes MenuView getListMenuView(MenuPresenter.Callback cb) { 189900d183885b54de433e43118d3032340f40cac8c0Chris Banes if (menu == null) return null; 190000d183885b54de433e43118d3032340f40cac8c0Chris Banes 190100d183885b54de433e43118d3032340f40cac8c0Chris Banes if (listMenuPresenter == null) { 190257c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes listMenuPresenter = new ListMenuPresenter(listPresenterContext, 190357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes R.layout.abc_list_menu_item_layout); 190400d183885b54de433e43118d3032340f40cac8c0Chris Banes listMenuPresenter.setCallback(cb); 190500d183885b54de433e43118d3032340f40cac8c0Chris Banes menu.addMenuPresenter(listMenuPresenter); 190600d183885b54de433e43118d3032340f40cac8c0Chris Banes } 190700d183885b54de433e43118d3032340f40cac8c0Chris Banes 190800d183885b54de433e43118d3032340f40cac8c0Chris Banes MenuView result = listMenuPresenter.getMenuView(decorView); 190900d183885b54de433e43118d3032340f40cac8c0Chris Banes 191000d183885b54de433e43118d3032340f40cac8c0Chris Banes return result; 191100d183885b54de433e43118d3032340f40cac8c0Chris Banes } 191200d183885b54de433e43118d3032340f40cac8c0Chris Banes 191300d183885b54de433e43118d3032340f40cac8c0Chris Banes Parcelable onSaveInstanceState() { 191400d183885b54de433e43118d3032340f40cac8c0Chris Banes SavedState savedState = new SavedState(); 191500d183885b54de433e43118d3032340f40cac8c0Chris Banes savedState.featureId = featureId; 191600d183885b54de433e43118d3032340f40cac8c0Chris Banes savedState.isOpen = isOpen; 191700d183885b54de433e43118d3032340f40cac8c0Chris Banes 191800d183885b54de433e43118d3032340f40cac8c0Chris Banes if (menu != null) { 191900d183885b54de433e43118d3032340f40cac8c0Chris Banes savedState.menuState = new Bundle(); 192000d183885b54de433e43118d3032340f40cac8c0Chris Banes menu.savePresenterStates(savedState.menuState); 192100d183885b54de433e43118d3032340f40cac8c0Chris Banes } 192200d183885b54de433e43118d3032340f40cac8c0Chris Banes 192300d183885b54de433e43118d3032340f40cac8c0Chris Banes return savedState; 192400d183885b54de433e43118d3032340f40cac8c0Chris Banes } 192500d183885b54de433e43118d3032340f40cac8c0Chris Banes 192600d183885b54de433e43118d3032340f40cac8c0Chris Banes void onRestoreInstanceState(Parcelable state) { 192700d183885b54de433e43118d3032340f40cac8c0Chris Banes SavedState savedState = (SavedState) state; 192800d183885b54de433e43118d3032340f40cac8c0Chris Banes featureId = savedState.featureId; 192900d183885b54de433e43118d3032340f40cac8c0Chris Banes wasLastOpen = savedState.isOpen; 193000d183885b54de433e43118d3032340f40cac8c0Chris Banes frozenMenuState = savedState.menuState; 193100d183885b54de433e43118d3032340f40cac8c0Chris Banes 193200d183885b54de433e43118d3032340f40cac8c0Chris Banes shownPanelView = null; 193300d183885b54de433e43118d3032340f40cac8c0Chris Banes decorView = null; 193400d183885b54de433e43118d3032340f40cac8c0Chris Banes } 193500d183885b54de433e43118d3032340f40cac8c0Chris Banes 193600d183885b54de433e43118d3032340f40cac8c0Chris Banes void applyFrozenState() { 193700d183885b54de433e43118d3032340f40cac8c0Chris Banes if (menu != null && frozenMenuState != null) { 193800d183885b54de433e43118d3032340f40cac8c0Chris Banes menu.restorePresenterStates(frozenMenuState); 193900d183885b54de433e43118d3032340f40cac8c0Chris Banes frozenMenuState = null; 194000d183885b54de433e43118d3032340f40cac8c0Chris Banes } 194100d183885b54de433e43118d3032340f40cac8c0Chris Banes } 194200d183885b54de433e43118d3032340f40cac8c0Chris Banes 194300d183885b54de433e43118d3032340f40cac8c0Chris Banes private static class SavedState implements Parcelable { 194400d183885b54de433e43118d3032340f40cac8c0Chris Banes int featureId; 194500d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean isOpen; 194600d183885b54de433e43118d3032340f40cac8c0Chris Banes Bundle menuState; 194700d183885b54de433e43118d3032340f40cac8c0Chris Banes 194800d183885b54de433e43118d3032340f40cac8c0Chris Banes public int describeContents() { 194900d183885b54de433e43118d3032340f40cac8c0Chris Banes return 0; 195000d183885b54de433e43118d3032340f40cac8c0Chris Banes } 195100d183885b54de433e43118d3032340f40cac8c0Chris Banes 195200d183885b54de433e43118d3032340f40cac8c0Chris Banes public void writeToParcel(Parcel dest, int flags) { 195300d183885b54de433e43118d3032340f40cac8c0Chris Banes dest.writeInt(featureId); 195400d183885b54de433e43118d3032340f40cac8c0Chris Banes dest.writeInt(isOpen ? 1 : 0); 195500d183885b54de433e43118d3032340f40cac8c0Chris Banes 195600d183885b54de433e43118d3032340f40cac8c0Chris Banes if (isOpen) { 195700d183885b54de433e43118d3032340f40cac8c0Chris Banes dest.writeBundle(menuState); 195800d183885b54de433e43118d3032340f40cac8c0Chris Banes } 195900d183885b54de433e43118d3032340f40cac8c0Chris Banes } 196000d183885b54de433e43118d3032340f40cac8c0Chris Banes 196162ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes private static SavedState readFromParcel(Parcel source, ClassLoader loader) { 196200d183885b54de433e43118d3032340f40cac8c0Chris Banes SavedState savedState = new SavedState(); 196300d183885b54de433e43118d3032340f40cac8c0Chris Banes savedState.featureId = source.readInt(); 196400d183885b54de433e43118d3032340f40cac8c0Chris Banes savedState.isOpen = source.readInt() == 1; 196500d183885b54de433e43118d3032340f40cac8c0Chris Banes 196600d183885b54de433e43118d3032340f40cac8c0Chris Banes if (savedState.isOpen) { 196762ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes savedState.menuState = source.readBundle(loader); 196800d183885b54de433e43118d3032340f40cac8c0Chris Banes } 196900d183885b54de433e43118d3032340f40cac8c0Chris Banes 197000d183885b54de433e43118d3032340f40cac8c0Chris Banes return savedState; 197100d183885b54de433e43118d3032340f40cac8c0Chris Banes } 197200d183885b54de433e43118d3032340f40cac8c0Chris Banes 197300d183885b54de433e43118d3032340f40cac8c0Chris Banes public static final Parcelable.Creator<SavedState> CREATOR 197462ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes = ParcelableCompat.newCreator( 197562ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes new ParcelableCompatCreatorCallbacks<SavedState>() { 197662ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes @Override 197762ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes public SavedState createFromParcel(Parcel in, ClassLoader loader) { 197862ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes return readFromParcel(in, loader); 197962ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes } 198000d183885b54de433e43118d3032340f40cac8c0Chris Banes 198162ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes @Override 198262ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes public SavedState[] newArray(int size) { 198362ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes return new SavedState[size]; 198462ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes } 198562ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes }); 198603fc11b659da1645507062bddda450136e13af35Chris Banes } 198703fc11b659da1645507062bddda450136e13af35Chris Banes } 198803fc11b659da1645507062bddda450136e13af35Chris Banes 1989b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes private class ListMenuDecorView extends ContentFrameLayout { 199046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes public ListMenuDecorView(Context context) { 199146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes super(context); 199246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 199346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 199446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes @Override 199546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes public boolean dispatchKeyEvent(KeyEvent event) { 19961d0e76a0ba8bfc5e280203a56e10be95dd959a51Chris Banes return AppCompatDelegateImplV7.this.dispatchKeyEvent(event) 19971d0e76a0ba8bfc5e280203a56e10be95dd959a51Chris Banes || super.dispatchKeyEvent(event); 199846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 199946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 200046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes @Override 200146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes public boolean onInterceptTouchEvent(MotionEvent event) { 200246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes int action = event.getAction(); 200346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (action == MotionEvent.ACTION_DOWN) { 200446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes int x = (int) event.getX(); 200546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes int y = (int) event.getY(); 200646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (isOutOfBounds(x, y)) { 200746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes closePanel(Window.FEATURE_OPTIONS_PANEL); 200846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return true; 200946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 201046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 201146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return super.onInterceptTouchEvent(event); 201246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 201346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 201446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes @Override 201546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes public void setBackgroundResource(int resid) { 201646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes setBackgroundDrawable(TintManager.getDrawable(getContext(), resid)); 201746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 201846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 201946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes private boolean isOutOfBounds(int x, int y) { 202046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return x < -5 || y < -5 || x > (getWidth() + 5) || y > (getHeight() + 5); 202146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 202246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 20236386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes} 2024