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