FileDocCategorySizeDatePackage
ActionBarActivityDelegateBase.javaAPI DocAndroid 5.1 API67737Thu Mar 12 22:22:56 GMT 2015android.support.v7.app

ActionBarActivityDelegateBase

public class ActionBarActivityDelegateBase extends ActionBarActivityDelegate implements MenuBuilder.Callback

Fields Summary
private static final String
TAG
private android.support.v7.internal.widget.DecorContentParent
mDecorContentParent
private ActionMenuPresenterCallback
mActionMenuPresenterCallback
private PanelMenuPresenterCallback
mPanelMenuPresenterCallback
android.support.v7.view.ActionMode
mActionMode
android.support.v7.internal.widget.ActionBarContextView
mActionModeView
android.widget.PopupWindow
mActionModePopup
Runnable
mShowActionModePopup
private boolean
mSubDecorInstalled
private android.view.ViewGroup
mWindowDecor
private android.view.ViewGroup
mSubDecor
private android.view.View
mStatusGuard
private CharSequence
mTitleToSet
private boolean
mFeatureProgress
private boolean
mFeatureIndeterminateProgress
private boolean
mClosingActionMenu
private PanelFeatureState[]
mPanels
private PanelFeatureState
mPreparedPanel
private boolean
mInvalidatePanelMenuPosted
private int
mInvalidatePanelMenuFeatures
private final Runnable
mInvalidatePanelMenuRunnable
private boolean
mEnableDefaultActionBarUp
private android.graphics.Rect
mTempRect1
private android.graphics.Rect
mTempRect2
Constructors Summary
ActionBarActivityDelegateBase(ActionBarActivity activity)


      
        super(activity);
    
Methods Summary
public voidaddContentView(android.view.View v, ViewGroup.LayoutParams lp)

        ensureSubDecor();
        ViewGroup contentParent = (ViewGroup) mActivity.findViewById(android.R.id.content);
        contentParent.addView(v, lp);
        mActivity.onSupportContentChanged();
    
private voidapplyFixedSizeWindow()

        TypedArray a = mActivity.obtainStyledAttributes(R.styleable.Theme);

        TypedValue mFixedWidthMajor = null;
        TypedValue mFixedWidthMinor = null;
        TypedValue mFixedHeightMajor = null;
        TypedValue mFixedHeightMinor = null;

        if (a.hasValue(R.styleable.Theme_windowFixedWidthMajor)) {
            if (mFixedWidthMajor == null) mFixedWidthMajor = new TypedValue();
            a.getValue(R.styleable.Theme_windowFixedWidthMajor, mFixedWidthMajor);
        }
        if (a.hasValue(R.styleable.Theme_windowFixedWidthMinor)) {
            if (mFixedWidthMinor == null) mFixedWidthMinor = new TypedValue();
            a.getValue(R.styleable.Theme_windowFixedWidthMinor, mFixedWidthMinor);
        }
        if (a.hasValue(R.styleable.Theme_windowFixedHeightMajor)) {
            if (mFixedHeightMajor == null) mFixedHeightMajor = new TypedValue();
            a.getValue(R.styleable.Theme_windowFixedHeightMajor, mFixedHeightMajor);
        }
        if (a.hasValue(R.styleable.Theme_windowFixedHeightMinor)) {
            if (mFixedHeightMinor == null) mFixedHeightMinor = new TypedValue();
            a.getValue(R.styleable.Theme_windowFixedHeightMinor, mFixedHeightMinor);
        }

        final DisplayMetrics metrics = mActivity.getResources().getDisplayMetrics();
        final boolean isPortrait = metrics.widthPixels < metrics.heightPixels;
        int w = ViewGroup.LayoutParams.MATCH_PARENT;
        int h = ViewGroup.LayoutParams.MATCH_PARENT;

        final TypedValue tvw = isPortrait ? mFixedWidthMinor : mFixedWidthMajor;
        if (tvw != null && tvw.type != TypedValue.TYPE_NULL) {
            if (tvw.type == TypedValue.TYPE_DIMENSION) {
                w = (int) tvw.getDimension(metrics);
            } else if (tvw.type == TypedValue.TYPE_FRACTION) {
                w = (int) tvw.getFraction(metrics.widthPixels, metrics.widthPixels);
            }
        }

        final TypedValue tvh = isPortrait ? mFixedHeightMajor : mFixedHeightMinor;
        if (tvh != null && tvh.type != TypedValue.TYPE_NULL) {
            if (tvh.type == TypedValue.TYPE_DIMENSION) {
                h = (int) tvh.getDimension(metrics);
            } else if (tvh.type == TypedValue.TYPE_FRACTION) {
                h = (int) tvh.getFraction(metrics.heightPixels, metrics.heightPixels);
            }
        }

        if (w != ViewGroup.LayoutParams.MATCH_PARENT || h != ViewGroup.LayoutParams.MATCH_PARENT) {
            mActivity.getWindow().setLayout(w, h);
        }

        a.recycle();
    
private voidcallOnPanelClosed(int featureId, android.support.v7.app.ActionBarActivityDelegateBase$PanelFeatureState panel, android.view.Menu menu)

        // Try to get a menu
        if (menu == null) {
            // Need a panel to grab the menu, so try to get that
            if (panel == null) {
                if ((featureId >= 0) && (featureId < mPanels.length)) {
                    panel = mPanels[featureId];
                }
            }

            if (panel != null) {
                // menu still may be null, which is okay--we tried our best
                menu = panel.menu;
            }
        }

        // If the panel is not open, do not callback
        if ((panel != null) && (!panel.isOpen))
            return;

        getWindowCallback().onPanelClosed(featureId, menu);
    
private voidcheckCloseActionMenu(android.support.v7.internal.view.menu.MenuBuilder menu)

        if (mClosingActionMenu) {
            return;
        }

        mClosingActionMenu = true;
        mDecorContentParent.dismissPopups();
        WindowCallback cb = getWindowCallback();
        if (cb != null && !isDestroyed()) {
            cb.onPanelClosed(FEATURE_ACTION_BAR, menu);
        }
        mClosingActionMenu = false;
    
private voidclosePanel(int featureId)

        closePanel(getPanelState(featureId, true), true);
    
private voidclosePanel(android.support.v7.app.ActionBarActivityDelegateBase$PanelFeatureState st, boolean doCallback)

        if (doCallback && st.featureId == FEATURE_OPTIONS_PANEL &&
                mDecorContentParent != null && mDecorContentParent.isOverflowMenuShowing()) {
            checkCloseActionMenu(st.menu);
            return;
        }

        final WindowManager wm = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE);
        if ((wm != null) && st.isOpen) {
            if (st.decorView != null) {
                wm.removeView(st.decorView);
            }

            if (doCallback) {
                callOnPanelClosed(st.featureId, st, null);
            }
        }

        st.isPrepared = false;
        st.isHandled = false;
        st.isOpen = false;

        // This view is no longer shown, so null it out
        st.shownPanelView = null;

        // Next time the menu opens, it should not be in expanded mode, so
        // force a refresh of the decor
        st.refreshDecorView = true;

        if (mPreparedPanel == st) {
            mPreparedPanel = null;
        }
    
public ActionBarcreateSupportActionBar()

        ensureSubDecor();
        ActionBar ab = new WindowDecorActionBar(mActivity, mOverlayActionBar);
        ab.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp);
        return ab;
    
android.view.ViewcreateView(java.lang.String name, android.content.Context context, android.util.AttributeSet attrs)

        if (Build.VERSION.SDK_INT < 21) {
            // If we're running pre-L, we need to 'inject' our tint aware Views in place of the
            // standard framework versions
            switch (name) {
                case "EditText":
                    return new TintEditText(context, attrs);
                case "Spinner":
                    return new TintSpinner(context, attrs);
                case "CheckBox":
                    return new TintCheckBox(context, attrs);
                case "RadioButton":
                    return new TintRadioButton(context, attrs);
                case "CheckedTextView":
                    return new TintCheckedTextView(context, attrs);
                case "AutoCompleteTextView":
                    return new TintAutoCompleteTextView(context, attrs);
                case "MultiAutoCompleteTextView":
                    return new TintMultiAutoCompleteTextView(context, attrs);
                case "RatingBar":
                    return new TintRatingBar(context, attrs);
                case "Button":
                    return new TintButton(context, attrs);
            }
        }
        return null;
    
booleandispatchKeyEvent(android.view.KeyEvent event)

        final int keyCode = event.getKeyCode();
        final int action = event.getAction();
        final boolean isDown = action == KeyEvent.ACTION_DOWN;

        return isDown ? onKeyDown(keyCode, event) : onKeyUp(keyCode, event);
    
private voiddoInvalidatePanelMenu(int featureId)

        PanelFeatureState st = getPanelState(featureId, true);
        Bundle savedActionViewStates = null;
        if (st.menu != null) {
            savedActionViewStates = new Bundle();
            st.menu.saveActionViewStates(savedActionViewStates);
            if (savedActionViewStates.size() > 0) {
                st.frozenActionViewState = savedActionViewStates;
            }
            // This will be started again when the panel is prepared.
            st.menu.stopDispatchingItemsChanged();
            st.menu.clear();
        }
        st.refreshMenuContent = true;
        st.refreshDecorView = true;

        // Prepare the options panel if we have an action bar
        if ((featureId == FEATURE_ACTION_BAR || featureId == FEATURE_OPTIONS_PANEL)
                && mDecorContentParent != null) {
            st = getPanelState(Window.FEATURE_OPTIONS_PANEL, false);
            if (st != null) {
                st.isPrepared = false;
                preparePanel(st, null);
            }
        }
    
final voidensureSubDecor()

        if (!mSubDecorInstalled) {
            if (mHasActionBar) {
                /**
                 * This needs some explanation. As we can not use the android:theme attribute
                 * pre-L, we emulate it by manually creating a LayoutInflater using a
                 * ContextThemeWrapper pointing to actionBarTheme.
                 */
                TypedValue outValue = new TypedValue();
                mActivity.getTheme().resolveAttribute(R.attr.actionBarTheme, outValue, true);

                Context themedContext;
                if (outValue.resourceId != 0) {
                    themedContext = new ContextThemeWrapper(mActivity, outValue.resourceId);
                } else {
                    themedContext = mActivity;
                }

                // Now inflate the view using the themed context and set it as the content view
                mSubDecor = (ViewGroup) LayoutInflater.from(themedContext)
                        .inflate(R.layout.abc_screen_toolbar, null);

                mDecorContentParent = (DecorContentParent) mSubDecor
                        .findViewById(R.id.decor_content_parent);
                mDecorContentParent.setWindowCallback(getWindowCallback());

                /**
                 * Propagate features to DecorContentParent
                 */
                if (mOverlayActionBar) {
                    mDecorContentParent.initFeature(FEATURE_ACTION_BAR_OVERLAY);
                }
                if (mFeatureProgress) {
                    mDecorContentParent.initFeature(Window.FEATURE_PROGRESS);
                }
                if (mFeatureIndeterminateProgress) {
                    mDecorContentParent.initFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
                }
            } else {
                if (mOverlayActionMode) {
                    mSubDecor = (ViewGroup) LayoutInflater.from(mActivity)
                            .inflate(R.layout.abc_screen_simple_overlay_action_mode, null);
                } else {
                    mSubDecor = (ViewGroup) LayoutInflater.from(mActivity)
                            .inflate(R.layout.abc_screen_simple, null);
                }

                if (Build.VERSION.SDK_INT >= 21) {
                    // If we're running on L or above, we can rely on ViewCompat's
                    // setOnApplyWindowInsetsListener
                    ViewCompat.setOnApplyWindowInsetsListener(mSubDecor,
                            new OnApplyWindowInsetsListener() {
                                @Override
                                public WindowInsetsCompat onApplyWindowInsets(View v,
                                        WindowInsetsCompat insets) {
                                    final int top = insets.getSystemWindowInsetTop();
                                    final int newTop = updateStatusGuard(top);

                                    if (top != newTop) {
                                        return insets.replaceSystemWindowInsets(
                                                insets.getSystemWindowInsetLeft(),
                                                newTop,
                                                insets.getSystemWindowInsetRight(),
                                                insets.getSystemWindowInsetBottom());
                                    } else {
                                        return insets;
                                    }
                                }
                            });
                } else {
                    // Else, we need to use our own FitWindowsViewGroup handling
                    ((FitWindowsViewGroup) mSubDecor).setOnFitSystemWindowsListener(
                            new FitWindowsViewGroup.OnFitSystemWindowsListener() {
                                @Override
                                public void onFitSystemWindows(Rect insets) {
                                    insets.top = updateStatusGuard(insets.top);
                                }
                            });
                }
            }

            // Make the decor optionally fit system windows, like the window's decor
            ViewUtils.makeOptionalFitsSystemWindows(mSubDecor);

            final ViewGroup decorContent = (ViewGroup) mActivity.findViewById(android.R.id.content);
            final ViewGroup abcContent = (ViewGroup) mSubDecor.findViewById(
                    R.id.action_bar_activity_content);

            // There might be Views already added to the Window's content view so we need to
            // migrate them to our content view
            while (decorContent.getChildCount() > 0) {
                final View child = decorContent.getChildAt(0);
                decorContent.removeViewAt(0);
                abcContent.addView(child);
            }

            // Now set the Activity's content view with the decor
            mActivity.superSetContentView(mSubDecor);

            // Change our content FrameLayout to use the android.R.id.content id.
            // Useful for fragments.
            decorContent.setId(View.NO_ID);
            abcContent.setId(android.R.id.content);

            // The decorContent may have a foreground drawable set (windowContentOverlay).
            // Remove this as we handle it ourselves
            if (decorContent instanceof FrameLayout) {
                ((FrameLayout) decorContent).setForeground(null);
            }

            // A title was set before we've install the decor so set it now.
            if (mTitleToSet != null && mDecorContentParent != null) {
                mDecorContentParent.setWindowTitle(mTitleToSet);
                mTitleToSet = null;
            }

            applyFixedSizeWindow();

            onSubDecorInstalled();

            mSubDecorInstalled = true;

            // Invalidate if the panel menu hasn't been created before this.
            // Panel menu invalidation is deferred avoiding application onCreateOptionsMenu
            // being called in the middle of onCreate or similar.
            // A pending invalidation will typically be resolved before the posted message
            // would run normally in order to satisfy instance state restoration.
            PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, false);
            if (!isDestroyed() && (st == null || st.menu == null)) {
                invalidatePanelMenu(FEATURE_ACTION_BAR);
            }
        }
    
private android.support.v7.app.ActionBarActivityDelegateBase$PanelFeatureStatefindMenuPanel(android.view.Menu menu)

        final PanelFeatureState[] panels = mPanels;
        final int N = panels != null ? panels.length : 0;
        for (int i = 0; i < N; i++) {
            final PanelFeatureState panel = panels[i];
            if (panel != null && panel.menu == menu) {
                return panel;
            }
        }
        return null;
    
intgetHomeAsUpIndicatorAttrId()

        return R.attr.homeAsUpIndicator;
    
private android.support.v7.app.ActionBarActivityDelegateBase$PanelFeatureStategetPanelState(int featureId, boolean required)

        PanelFeatureState[] ar;
        if ((ar = mPanels) == null || ar.length <= featureId) {
            PanelFeatureState[] nar = new PanelFeatureState[featureId + 1];
            if (ar != null) {
                System.arraycopy(ar, 0, nar, 0, ar.length);
            }
            mPanels = ar = nar;
        }

        PanelFeatureState st = ar[featureId];
        if (st == null) {
            ar[featureId] = st = new PanelFeatureState(featureId);
        }
        return st;
    
private booleaninitializePanelContent(android.support.v7.app.ActionBarActivityDelegateBase$PanelFeatureState st)

        if (st.createdPanelView != null) {
            st.shownPanelView = st.createdPanelView;
            return true;
        }

        if (st.menu == null) {
            return false;
        }

        if (mPanelMenuPresenterCallback == null) {
            mPanelMenuPresenterCallback = new PanelMenuPresenterCallback();
        }

        MenuView menuView = st.getListMenuView(mPanelMenuPresenterCallback);

        st.shownPanelView = (View) menuView;

        return st.shownPanelView != null;
    
private booleaninitializePanelDecor(android.support.v7.app.ActionBarActivityDelegateBase$PanelFeatureState st)

        st.setStyle(getActionBarThemedContext());
        st.decorView = new ListMenuDecorView(st.listPresenterContext);
        st.gravity = Gravity.CENTER | Gravity.BOTTOM;
        return true;
    
private booleaninitializePanelMenu(android.support.v7.app.ActionBarActivityDelegateBase$PanelFeatureState st)

        Context context = mActivity;

        // If we have an action bar, initialize the menu with the right theme.
        if ((st.featureId == FEATURE_OPTIONS_PANEL || st.featureId == FEATURE_ACTION_BAR) &&
                mDecorContentParent != null) {
            final TypedValue outValue = new TypedValue();
            final Resources.Theme baseTheme = context.getTheme();
            baseTheme.resolveAttribute(R.attr.actionBarTheme, outValue, true);

            Resources.Theme widgetTheme = null;
            if (outValue.resourceId != 0) {
                widgetTheme = context.getResources().newTheme();
                widgetTheme.setTo(baseTheme);
                widgetTheme.applyStyle(outValue.resourceId, true);
                widgetTheme.resolveAttribute(
                        R.attr.actionBarWidgetTheme, outValue, true);
            } else {
                baseTheme.resolveAttribute(
                        R.attr.actionBarWidgetTheme, outValue, true);
            }

            if (outValue.resourceId != 0) {
                if (widgetTheme == null) {
                    widgetTheme = context.getResources().newTheme();
                    widgetTheme.setTo(baseTheme);
                }
                widgetTheme.applyStyle(outValue.resourceId, true);
            }

            if (widgetTheme != null) {
                context = new ContextThemeWrapper(context, 0);
                context.getTheme().setTo(widgetTheme);
            }
        }

        final MenuBuilder menu = new MenuBuilder(context);
        menu.setCallback(this);
        st.setMenu(menu);

        return true;
    
private voidinvalidatePanelMenu(int featureId)

        mInvalidatePanelMenuFeatures |= 1 << featureId;

        if (!mInvalidatePanelMenuPosted && mWindowDecor != null) {
            ViewCompat.postOnAnimation(mWindowDecor, mInvalidatePanelMenuRunnable);
            mInvalidatePanelMenuPosted = true;
        }
    
public booleanonBackPressed()

        // Back cancels action modes first.
        if (mActionMode != null) {
            mActionMode.finish();
            return true;
        }

        // Next collapse any expanded action views.
        ActionBar ab = getSupportActionBar();
        if (ab != null && ab.collapseActionView()) {
            return true;
        }

        return false;
    
public voidonConfigurationChanged(android.content.res.Configuration newConfig)

        // If this is called before sub-decor is installed, ActionBar will not
        // be properly initialized.
        if (mHasActionBar && mSubDecorInstalled) {
            // Note: The action bar will need to access
            // view changes from superclass.
            ActionBar ab = getSupportActionBar();
            if (ab != null) {
                ab.onConfigurationChanged(newConfig);
            }
        }
    
public voidonContentChanged()

        // Ignore all calls to this method as we call onSupportContentChanged manually above
    
voidonCreate(android.os.Bundle savedInstanceState)

        super.onCreate(savedInstanceState);

        mWindowDecor = (ViewGroup) mActivity.getWindow().getDecorView();

        if (NavUtils.getParentActivityName(mActivity) != null) {
            // Peek at the Action Bar and update it if it already exists
            ActionBar ab = peekSupportActionBar();
            if (ab == null) {
                mEnableDefaultActionBarUp = true;
            } else {
                ab.setDefaultDisplayHomeAsUpEnabled(true);
            }
        }
    
public booleanonCreatePanelMenu(int featureId, android.view.Menu menu)

        if (featureId != Window.FEATURE_OPTIONS_PANEL) {
            return getWindowCallback().onCreatePanelMenu(featureId, menu);
        }
        return false;
    
protected booleanonKeyDown(int keyCode, android.view.KeyEvent event)

        if (keyCode == KeyEvent.KEYCODE_MENU) {
            onKeyDownPanel(Window.FEATURE_OPTIONS_PANEL, event);
            return true;
        }

        // On API v7-10 we need to manually call onKeyShortcut() as this is not called
        // from the Activity
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            return onKeyShortcut(keyCode, event);
        }
        return false;
    
private booleanonKeyDownPanel(int featureId, android.view.KeyEvent event)

        if (event.getRepeatCount() == 0) {
            PanelFeatureState st = getPanelState(featureId, true);
            if (!st.isOpen) {
                return preparePanel(st, event);
            }
        }

        return false;
    
booleanonKeyShortcut(int keyCode, android.view.KeyEvent ev)

        // Let the Action Bar have a chance at handling the shortcut
        ActionBar ab = getSupportActionBar();
        if (ab != null && ab.onKeyShortcut(keyCode, ev)) {
            return true;
        }

        // If the panel is already prepared, then perform the shortcut using it.
        boolean handled;
        if (mPreparedPanel != null) {
            handled = performPanelShortcut(mPreparedPanel, ev.getKeyCode(), ev,
                    Menu.FLAG_PERFORM_NO_CLOSE);
            if (handled) {
                if (mPreparedPanel != null) {
                    mPreparedPanel.isHandled = true;
                }
                return true;
            }
        }

        // If the panel is not prepared, then we may be trying to handle a shortcut key
        // combination such as Control+C.  Temporarily prepare the panel then mark it
        // unprepared again when finished to ensure that the panel will again be prepared
        // the next time it is shown for real.
        if (mPreparedPanel == null) {
            PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
            preparePanel(st, ev);
            handled = performPanelShortcut(st, ev.getKeyCode(), ev, Menu.FLAG_PERFORM_NO_CLOSE);
            st.isPrepared = false;
            if (handled) {
                return true;
            }
        }
        return false;
    
protected booleanonKeyUp(int keyCode, android.view.KeyEvent event)

        switch (keyCode) {
            case KeyEvent.KEYCODE_MENU:
                onKeyUpPanel(Window.FEATURE_OPTIONS_PANEL, event);
                return true;
            case KeyEvent.KEYCODE_BACK:
                PanelFeatureState st = getPanelState(Window.FEATURE_OPTIONS_PANEL, false);
                if (st != null && st.isOpen) {
                    closePanel(st, true);
                    return true;
                }
                break;
        }
        return false;
    
private voidonKeyUpPanel(int featureId, android.view.KeyEvent event)

        if (mActionMode != null) {
            return;
        }

        boolean playSoundEffect = false;
        final PanelFeatureState st = getPanelState(featureId, true);
        if (featureId == FEATURE_OPTIONS_PANEL && mDecorContentParent != null &&
                mDecorContentParent.canShowOverflowMenu() &&
                !ViewConfigurationCompat.hasPermanentMenuKey(ViewConfiguration.get(mActivity))) {
            if (!mDecorContentParent.isOverflowMenuShowing()) {
                if (!isDestroyed() && preparePanel(st, event)) {
                    playSoundEffect = mDecorContentParent.showOverflowMenu();
                }
            } else {
                playSoundEffect = mDecorContentParent.hideOverflowMenu();
            }
        } else {
            if (st.isOpen || st.isHandled) {

                // Play the sound effect if the user closed an open menu (and not if
                // they just released a menu shortcut)
                playSoundEffect = st.isOpen;

                // Close menu
                closePanel(st, true);

            } else if (st.isPrepared) {
                boolean show = true;
                if (st.refreshMenuContent) {
                    // Something may have invalidated the menu since we prepared it.
                    // Re-prepare it to refresh.
                    st.isPrepared = false;
                    show = preparePanel(st, event);
                }

                if (show) {
                    // Show menu
                    openPanel(st, event);

                    playSoundEffect = true;
                }
            }
        }

        if (playSoundEffect) {
            AudioManager audioManager = (AudioManager) mActivity.getSystemService(
                    Context.AUDIO_SERVICE);
            if (audioManager != null) {
                audioManager.playSoundEffect(AudioManager.FX_KEY_CLICK);
            } else {
                Log.w(TAG, "Couldn't get audio manager");
            }
        }
    
public booleanonMenuItemSelected(android.support.v7.internal.view.menu.MenuBuilder menu, android.view.MenuItem item)

        final WindowCallback cb = getWindowCallback();
        if (cb != null && !isDestroyed()) {
            final PanelFeatureState panel = findMenuPanel(menu.getRootMenu());
            if (panel != null) {
                return cb.onMenuItemSelected(panel.featureId, item);
            }
        }
        return false;
    
public voidonMenuModeChange(android.support.v7.internal.view.menu.MenuBuilder menu)

        reopenMenu(menu, true);
    
booleanonMenuOpened(int featureId, android.view.Menu menu)

        if (featureId == FEATURE_ACTION_BAR) {
            ActionBar ab = getSupportActionBar();
            if (ab != null) {
                ab.dispatchMenuVisibilityChanged(true);
            }
            return true;
        } else {
            return mActivity.superOnMenuOpened(featureId, menu);
        }
    
public voidonPanelClosed(int featureId, android.view.Menu menu)

        if (featureId == FEATURE_ACTION_BAR) {
            ActionBar ab = getSupportActionBar();
            if (ab != null) {
                ab.dispatchMenuVisibilityChanged(false);
            }
        } else if (!isDestroyed()) {
            // Only pass it through to the Activity's super impl if it's not ACTION_BAR. This is
            // because ICS+ will try and create a framework action bar due to this call
            mActivity.superOnPanelClosed(featureId, menu);
        }
    
voidonPostCreate(android.os.Bundle savedInstanceState)

        // Make sure that the sub decor is installed
        ensureSubDecor();
    
public voidonPostResume()

        ActionBar ab = getSupportActionBar();
        if (ab != null) {
            ab.setShowHideAnimationEnabled(true);
        }
    
public booleanonPreparePanel(int featureId, android.view.View view, android.view.Menu menu)

        if (featureId != Window.FEATURE_OPTIONS_PANEL) {
            return getWindowCallback().onPreparePanel(featureId, view, menu);
        }
        return false;
    
public voidonStop()

        ActionBar ab = getSupportActionBar();
        if (ab != null) {
            ab.setShowHideAnimationEnabled(false);
        }
    
voidonSubDecorInstalled()

public voidonTitleChanged(java.lang.CharSequence title)

        if (mDecorContentParent != null) {
            mDecorContentParent.setWindowTitle(title);
        } else if (getSupportActionBar() != null) {
            getSupportActionBar().setWindowTitle(title);
        } else {
            mTitleToSet = title;
        }
    
private voidopenPanel(android.support.v7.app.ActionBarActivityDelegateBase$PanelFeatureState st, android.view.KeyEvent event)

        // Already open, return
        if (st.isOpen || isDestroyed()) {
            return;
        }

        // Don't open an options panel for honeycomb apps on xlarge devices.
        // (The app should be using an action bar for menu items.)
        if (st.featureId == FEATURE_OPTIONS_PANEL) {
            Context context = mActivity;
            Configuration config = context.getResources().getConfiguration();
            boolean isXLarge = (config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) ==
                    Configuration.SCREENLAYOUT_SIZE_XLARGE;
            boolean isHoneycombApp = context.getApplicationInfo().targetSdkVersion >=
                    android.os.Build.VERSION_CODES.HONEYCOMB;

            if (isXLarge && isHoneycombApp) {
                return;
            }
        }

        WindowCallback cb = getWindowCallback();
        if ((cb != null) && (!cb.onMenuOpened(st.featureId, st.menu))) {
            // Callback doesn't want the menu to open, reset any state
            closePanel(st, true);
            return;
        }

        final WindowManager wm = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE);
        if (wm == null) {
            return;
        }

        // Prepare panel (should have been done before, but just in case)
        if (!preparePanel(st, event)) {
            return;
        }

        int width = WRAP_CONTENT;
        if (st.decorView == null || st.refreshDecorView) {
            if (st.decorView == null) {
                // Initialize the panel decor, this will populate st.decorView
                if (!initializePanelDecor(st) || (st.decorView == null))
                    return;
            } else if (st.refreshDecorView && (st.decorView.getChildCount() > 0)) {
                // Decor needs refreshing, so remove its views
                st.decorView.removeAllViews();
            }

            // This will populate st.shownPanelView
            if (!initializePanelContent(st) || !st.hasPanelItems()) {
                return;
            }

            ViewGroup.LayoutParams lp = st.shownPanelView.getLayoutParams();
            if (lp == null) {
                lp = new ViewGroup.LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
            }

            int backgroundResId = st.background;
            st.decorView.setBackgroundResource(backgroundResId);

            ViewParent shownPanelParent = st.shownPanelView.getParent();
            if (shownPanelParent != null && shownPanelParent instanceof ViewGroup) {
                ((ViewGroup) shownPanelParent).removeView(st.shownPanelView);
            }
            st.decorView.addView(st.shownPanelView, lp);

            /*
             * Give focus to the view, if it or one of its children does not
             * already have it.
             */
            if (!st.shownPanelView.hasFocus()) {
                st.shownPanelView.requestFocus();
            }
        } else if (st.createdPanelView != null) {
            // If we already had a panel view, carry width=MATCH_PARENT through
            // as we did above when it was created.
            ViewGroup.LayoutParams lp = st.createdPanelView.getLayoutParams();
            if (lp != null && lp.width == ViewGroup.LayoutParams.MATCH_PARENT) {
                width = MATCH_PARENT;
            }
        }

        st.isHandled = false;

        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                width, WRAP_CONTENT,
                st.x, st.y, WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL,
                WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                PixelFormat.TRANSLUCENT);

        lp.gravity = st.gravity;
        lp.windowAnimations = st.windowAnimations;

        wm.addView(st.decorView, lp);
        st.isOpen = true;
    
final booleanperformPanelShortcut(android.support.v7.app.ActionBarActivityDelegateBase$PanelFeatureState st, int keyCode, android.view.KeyEvent event, int flags)

        if (event.isSystem()) {
            return false;
        }

        boolean handled = false;

        // Only try to perform menu shortcuts if preparePanel returned true (possible false
        // return value from application not wanting to show the menu).
        if ((st.isPrepared || preparePanel(st, event)) && st.menu != null) {
            // The menu is prepared now, perform the shortcut on it
            handled = st.menu.performShortcut(keyCode, event, flags);
        }

        if (handled) {
            // Only close down the menu if we don't have an action bar keeping it open.
            if ((flags & Menu.FLAG_PERFORM_NO_CLOSE) == 0 && mDecorContentParent == null) {
                closePanel(st, true);
            }
        }

        return handled;
    
private booleanpreparePanel(android.support.v7.app.ActionBarActivityDelegateBase$PanelFeatureState st, android.view.KeyEvent event)

        if (isDestroyed()) {
            return false;
        }

        // Already prepared (isPrepared will be reset to false later)
        if (st.isPrepared) {
            return true;
        }

        if ((mPreparedPanel != null) && (mPreparedPanel != st)) {
            // Another Panel is prepared and possibly open, so close it
            closePanel(mPreparedPanel, false);
        }

        final WindowCallback cb = getWindowCallback();

        if (cb != null) {
            st.createdPanelView = cb.onCreatePanelView(st.featureId);
        }

        final boolean isActionBarMenu =
                (st.featureId == FEATURE_OPTIONS_PANEL || st.featureId == FEATURE_ACTION_BAR);

        if (isActionBarMenu && mDecorContentParent != null) {
            // Enforce ordering guarantees around events so that the action bar never
            // dispatches menu-related events before the panel is prepared.
            mDecorContentParent.setMenuPrepared();
        }

        if (st.createdPanelView == null) {
            // Init the panel state's menu--return false if init failed
            if (st.menu == null || st.refreshMenuContent) {
                if (st.menu == null) {
                    if (!initializePanelMenu(st) || (st.menu == null)) {
                        return false;
                    }
                }

                if (isActionBarMenu && mDecorContentParent != null) {
                    if (mActionMenuPresenterCallback == null) {
                        mActionMenuPresenterCallback = new ActionMenuPresenterCallback();
                    }
                    mDecorContentParent.setMenu(st.menu, mActionMenuPresenterCallback);
                }

                // Creating the panel menu will involve a lot of manipulation;
                // don't dispatch change events to presenters until we're done.
                st.menu.stopDispatchingItemsChanged();
                if (!getWindowCallback().onCreatePanelMenu(st.featureId, st.menu)) {
                    // Ditch the menu created above
                    st.setMenu(null);

                    if (isActionBarMenu && mDecorContentParent != null) {
                        // Don't show it in the action bar either
                        mDecorContentParent.setMenu(null, mActionMenuPresenterCallback);
                    }

                    return false;
                }

                st.refreshMenuContent = false;
            }

            // Preparing the panel menu can involve a lot of manipulation;
            // don't dispatch change events to presenters until we're done.
            st.menu.stopDispatchingItemsChanged();

            // Restore action view state before we prepare. This gives apps
            // an opportunity to override frozen/restored state in onPrepare.
            if (st.frozenActionViewState != null) {
                st.menu.restoreActionViewStates(st.frozenActionViewState);
                st.frozenActionViewState = null;
            }

            // Callback and return if the callback does not want to show the menu
            if (!cb.onPreparePanel(FEATURE_OPTIONS_PANEL, st.createdPanelView, st.menu)) {
                if (isActionBarMenu && mDecorContentParent != null) {
                    // The app didn't want to show the menu for now but it still exists.
                    // Clear it out of the action bar.
                    mDecorContentParent.setMenu(null, mActionMenuPresenterCallback);
                }
                st.menu.startDispatchingItemsChanged();
                return false;
            }

            // Set the proper keymap
            KeyCharacterMap kmap = KeyCharacterMap.load(
                    event != null ? event.getDeviceId() : KeyCharacterMap.VIRTUAL_KEYBOARD);
            st.qwertyMode = kmap.getKeyboardType() != KeyCharacterMap.NUMERIC;
            st.menu.setQwertyMode(st.qwertyMode);
            st.menu.startDispatchingItemsChanged();
        }

        // Set other state
        st.isPrepared = true;
        st.isHandled = false;
        mPreparedPanel = st;

        return true;
    
private voidreopenMenu(android.support.v7.internal.view.menu.MenuBuilder menu, boolean toggleMenuMode)

        if (mDecorContentParent != null && mDecorContentParent.canShowOverflowMenu() &&
                (!ViewConfigurationCompat.hasPermanentMenuKey(ViewConfiguration.get(mActivity)) ||
                        mDecorContentParent.isOverflowMenuShowPending())) {

            final WindowCallback cb = getWindowCallback();

            if (!mDecorContentParent.isOverflowMenuShowing() || !toggleMenuMode) {
                if (cb != null && !isDestroyed()) {
                    // If we have a menu invalidation pending, do it now.
                    if (mInvalidatePanelMenuPosted &&
                            (mInvalidatePanelMenuFeatures & (1 << FEATURE_OPTIONS_PANEL)) != 0) {
                        mWindowDecor.removeCallbacks(mInvalidatePanelMenuRunnable);
                        mInvalidatePanelMenuRunnable.run();
                    }

                    final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);

                    // If we don't have a menu or we're waiting for a full content refresh,
                    // forget it. This is a lingering event that no longer matters.
                    if (st.menu != null && !st.refreshMenuContent &&
                            cb.onPreparePanel(FEATURE_OPTIONS_PANEL, st.createdPanelView, st.menu)) {
                        cb.onMenuOpened(FEATURE_ACTION_BAR, st.menu);
                        mDecorContentParent.showOverflowMenu();
                    }
                }
            } else {
                mDecorContentParent.hideOverflowMenu();
                if (!isDestroyed()) {
                    final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
                    cb.onPanelClosed(FEATURE_ACTION_BAR, st.menu);
                }
            }
            return;
        }

        PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);

        st.refreshDecorView = true;
        closePanel(st, false);

        openPanel(st, null);
    
public voidsetContentView(int resId)

        ensureSubDecor();
        ViewGroup contentParent = (ViewGroup) mActivity.findViewById(android.R.id.content);
        contentParent.removeAllViews();
        mActivity.getLayoutInflater().inflate(resId, contentParent);
        mActivity.onSupportContentChanged();
    
public voidsetContentView(android.view.View v, ViewGroup.LayoutParams lp)

        ensureSubDecor();
        ViewGroup contentParent = (ViewGroup) mActivity.findViewById(android.R.id.content);
        contentParent.removeAllViews();
        contentParent.addView(v, lp);
        mActivity.onSupportContentChanged();
    
public voidsetContentView(android.view.View v)

        ensureSubDecor();
        ViewGroup contentParent = (ViewGroup) mActivity.findViewById(android.R.id.content);
        contentParent.removeAllViews();
        contentParent.addView(v);
        mActivity.onSupportContentChanged();
    
voidsetSupportActionBar(android.support.v7.widget.Toolbar toolbar)

        final ActionBar ab = getSupportActionBar();
        if (ab instanceof WindowDecorActionBar) {
            throw new IllegalStateException("This Activity already has an action bar supplied " +
                    "by the window decor. Do not request Window.FEATURE_ACTION_BAR and set " +
                    "windowActionBar to false in your theme to use a Toolbar instead.");
        }

        // Need to make sure we give the action bar the default window callback. Otherwise multiple
        // setSupportActionBar() calls lead to memory leaks
        ToolbarActionBar tbab = new ToolbarActionBar(toolbar, mActivity.getTitle(),
                mActivity.getWindow(), mDefaultWindowCallback);
        setSupportActionBar(tbab);
        setWindowCallback(tbab.getWrappedWindowCallback());
        tbab.invalidateOptionsMenu();
    
voidsetSupportProgress(int progress)

        // noop
    
voidsetSupportProgressBarIndeterminate(boolean indeterminate)

        // noop
    
voidsetSupportProgressBarIndeterminateVisibility(boolean visible)

        // noop
    
voidsetSupportProgressBarVisibility(boolean visible)

        // noop
    
public android.support.v7.view.ActionModestartSupportActionMode(ActionMode.Callback callback)

        if (callback == null) {
            throw new IllegalArgumentException("ActionMode callback can not be null.");
        }

        if (mActionMode != null) {
            mActionMode.finish();
        }

        final ActionMode.Callback wrappedCallback = new ActionModeCallbackWrapper(callback);

        ActionBar ab = getSupportActionBar();
        if (ab != null) {
            mActionMode = ab.startActionMode(wrappedCallback);
            if (mActionMode != null) {
                mActivity.onSupportActionModeStarted(mActionMode);
            }
        }

        if (mActionMode == null) {
            // If the action bar didn't provide an action mode, start the emulated window one
            mActionMode = startSupportActionModeFromWindow(wrappedCallback);
        }

        return mActionMode;
    
android.support.v7.view.ActionModestartSupportActionModeFromWindow(ActionMode.Callback callback)

        if (mActionMode != null) {
            mActionMode.finish();
        }

        final ActionMode.Callback wrappedCallback = new ActionModeCallbackWrapper(callback);
        final Context context = getActionBarThemedContext();

        if (mActionModeView == null) {
            if (mIsFloating) {
                mActionModeView = new ActionBarContextView(context);
                mActionModePopup = new PopupWindow(context, null,
                        R.attr.actionModePopupWindowStyle);
                mActionModePopup.setContentView(mActionModeView);
                mActionModePopup.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);

                TypedValue heightValue = new TypedValue();
                mActivity.getTheme().resolveAttribute(R.attr.actionBarSize, heightValue, true);
                final int height = TypedValue.complexToDimensionPixelSize(heightValue.data,
                        mActivity.getResources().getDisplayMetrics());
                mActionModeView.setContentHeight(height);
                mActionModePopup.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
                mShowActionModePopup = new Runnable() {
                    public void run() {
                        mActionModePopup.showAtLocation(
                                mActionModeView,
                                Gravity.TOP | Gravity.FILL_HORIZONTAL, 0, 0);
                    }
                };
            } else {
                ViewStubCompat stub = (ViewStubCompat) mActivity
                        .findViewById(R.id.action_mode_bar_stub);
                if (stub != null) {
                    // Set the layout inflater so that it is inflated with the action bar's context
                    stub.setLayoutInflater(LayoutInflater.from(context));
                    mActionModeView = (ActionBarContextView) stub.inflate();
                }
            }
        }

        if (mActionModeView != null) {
            mActionModeView.killMode();
            ActionMode mode = new StandaloneActionMode(context, mActionModeView, wrappedCallback,
                    mActionModePopup == null);
            if (callback.onCreateActionMode(mode, mode.getMenu())) {
                mode.invalidate();
                mActionModeView.initForMode(mode);
                mActionModeView.setVisibility(View.VISIBLE);
                mActionMode = mode;
                if (mActionModePopup != null) {
                    mActivity.getWindow().getDecorView().post(mShowActionModePopup);
                }
                mActionModeView.sendAccessibilityEvent(
                        AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);

                if (mActionModeView.getParent() != null) {
                    ViewCompat.requestApplyInsets((View) mActionModeView.getParent());
                }
            } else {
                mActionMode = null;
            }
        }
        if (mActionMode != null && mActivity != null) {
            mActivity.onSupportActionModeStarted(mActionMode);
        }
        return mActionMode;
    
public voidsupportInvalidateOptionsMenu()

        final ActionBar ab = getSupportActionBar();
        if (ab != null && ab.invalidateOptionsMenu()) return;

        invalidatePanelMenu(FEATURE_OPTIONS_PANEL);
    
public booleansupportRequestWindowFeature(int featureId)

        switch (featureId) {
            case FEATURE_ACTION_BAR:
                throwFeatureRequestIfSubDecorInstalled();
                mHasActionBar = true;
                return true;
            case FEATURE_ACTION_BAR_OVERLAY:
                throwFeatureRequestIfSubDecorInstalled();
                mOverlayActionBar = true;
                return true;
            case FEATURE_ACTION_MODE_OVERLAY:
                throwFeatureRequestIfSubDecorInstalled();
                mOverlayActionMode = true;
                return true;
            case Window.FEATURE_PROGRESS:
                throwFeatureRequestIfSubDecorInstalled();
                mFeatureProgress = true;
                return true;
            case Window.FEATURE_INDETERMINATE_PROGRESS:
                throwFeatureRequestIfSubDecorInstalled();
                mFeatureIndeterminateProgress = true;
                return true;
        }

        return mActivity.requestWindowFeature(featureId);
    
private voidthrowFeatureRequestIfSubDecorInstalled()

        if (mSubDecorInstalled) {
            throw new AndroidRuntimeException(
                    "supportRequestWindowFeature() must be called before adding content");
        }
    
private intupdateStatusGuard(int insetTop)
Updates the status bar guard

param
insetTop the current top system window inset
return
the new top system window inset

        boolean showStatusGuard = false;
        // Show the status guard when the non-overlay contextual action bar is showing
        if (mActionModeView != null) {
            if (mActionModeView.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
                ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams)
                        mActionModeView.getLayoutParams();
                boolean mlpChanged = false;

                if (mActionModeView.isShown()) {
                    if (mTempRect1 == null) {
                        mTempRect1 = new Rect();
                        mTempRect2 = new Rect();
                    }
                    final Rect insets = mTempRect1;
                    final Rect localInsets = mTempRect2;
                    insets.set(0, insetTop, 0, 0);

                    ViewUtils.computeFitSystemWindows(mSubDecor, insets, localInsets);
                    final int newMargin = localInsets.top == 0 ? insetTop : 0;
                    if (mlp.topMargin != newMargin) {
                        mlpChanged = true;
                        mlp.topMargin = insetTop;

                        if (mStatusGuard == null) {
                            mStatusGuard = new View(mActivity);
                            mStatusGuard.setBackgroundColor(mActivity.getResources()
                                    .getColor(R.color.abc_input_method_navigation_guard));
                            mSubDecor.addView(mStatusGuard, -1,
                                    new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                                            insetTop));
                        } else {
                            ViewGroup.LayoutParams lp = mStatusGuard.getLayoutParams();
                            if (lp.height != insetTop) {
                                lp.height = insetTop;
                                mStatusGuard.setLayoutParams(lp);
                            }
                        }
                    }

                    // The action mode's theme may differ from the app, so
                    // always show the status guard above it.
                    showStatusGuard = mStatusGuard != null;

                    // We only need to consume the insets if the action
                    // mode is overlaid on the app content (e.g. it's
                    // sitting in a FrameLayout, see
                    // screen_simple_overlay_action_mode.xml).
                    if (!mOverlayActionMode && showStatusGuard) {
                        insetTop = 0;
                    }
                } else {
                    // reset top margin
                    if (mlp.topMargin != 0) {
                        mlpChanged = true;
                        mlp.topMargin = 0;
                    }
                }
                if (mlpChanged) {
                    mActionModeView.setLayoutParams(mlp);
                }
            }
        }
        if (mStatusGuard != null) {
            mStatusGuard.setVisibility(showStatusGuard ? View.VISIBLE : View.GONE);
        }

        return insetTop;