13a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn/*
23a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * Copyright (C) 2012 The Android Open Source Project
33a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn *
43a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
53a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * you may not use this file except in compliance with the License.
63a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * You may obtain a copy of the License at
73a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn *
83a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
93a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn *
103a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * Unless required by applicable law or agreed to in writing, software
113a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
123a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * See the License for the specific language governing permissions and
143a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * limitations under the License.
153a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn */
163a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
173a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackbornpackage com.android.internal.widget;
183a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
191dc5f92716189da02aa62f508adb6099061668b5Dianne Hackbornimport android.view.ViewGroup;
203a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackbornimport com.android.internal.app.ActionBarImpl;
213a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
223a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackbornimport android.content.Context;
233a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackbornimport android.content.res.TypedArray;
243a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackbornimport android.graphics.Rect;
253a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackbornimport android.util.AttributeSet;
263a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackbornimport android.view.View;
273a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
283a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn/**
293a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * Special layout for the containing of an overlay action bar (and its
303a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * content) to correctly handle fitting system windows when the content
313a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * has request that its layout ignore them.
323a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn */
331dc5f92716189da02aa62f508adb6099061668b5Dianne Hackbornpublic class ActionBarOverlayLayout extends ViewGroup {
343a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    private int mActionBarHeight;
353a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    private ActionBarImpl mActionBar;
363a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    private int mWindowVisibility = View.VISIBLE;
371dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
381dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    // The main UI elements that we handle the layout of.
393a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    private View mContent;
403a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    private View mActionBarTop;
411dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    private View mActionBarBottom;
421dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
431dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    // Some interior UI elements.
443a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    private ActionBarContainer mContainerView;
453a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    private ActionBarView mActionView;
461dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
47df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn    private boolean mOverlayMode;
483a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    private int mLastSystemUiVisibility;
491dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    private final Rect mBaseContentInsets = new Rect();
501dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    private final Rect mLastBaseContentInsets = new Rect();
511dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    private final Rect mContentInsets = new Rect();
521dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    private final Rect mBaseInnerInsets = new Rect();
531dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    private final Rect mInnerInsets = new Rect();
541dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    private final Rect mLastInnerInsets = new Rect();
553a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
563a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    static final int[] mActionBarSizeAttr = new int [] {
573a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            com.android.internal.R.attr.actionBarSize
583a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    };
593a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
603a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    public ActionBarOverlayLayout(Context context) {
613a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        super(context);
623a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        init(context);
633a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    }
643a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
653a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    public ActionBarOverlayLayout(Context context, AttributeSet attrs) {
663a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        super(context, attrs);
673a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        init(context);
683a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    }
693a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
703a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    private void init(Context context) {
713a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        TypedArray ta = getContext().getTheme().obtainStyledAttributes(mActionBarSizeAttr);
723a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        mActionBarHeight = ta.getDimensionPixelSize(0, 0);
733a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        ta.recycle();
743a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    }
753a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
76df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn    public void setActionBar(ActionBarImpl impl, boolean overlayMode) {
773a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        mActionBar = impl;
78df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn        mOverlayMode = overlayMode;
793a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        if (getWindowToken() != null) {
803a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            // This is being initialized after being added to a window;
813a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            // make sure to update all state now.
823a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            mActionBar.setWindowVisibility(mWindowVisibility);
833a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            if (mLastSystemUiVisibility != 0) {
843a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn                int newVis = mLastSystemUiVisibility;
853a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn                onWindowSystemUiVisibilityChanged(newVis);
863a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn                requestFitSystemWindows();
873a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            }
883a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
893a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    }
903a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
91139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn    public void setShowingForActionMode(boolean showing) {
92139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn        if (showing) {
93139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            // Here's a fun hack: if the status bar is currently being hidden,
94139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            // and the application has asked for stable content insets, then
95139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            // we will end up with the action mode action bar being shown
96139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            // without the status bar, but moved below where the status bar
97139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            // would be.  Not nice.  Trying to have this be positioned
98139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            // correctly is not easy (basically we need yet *another* content
99139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            // inset from the window manager to know where to put it), so
100139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            // instead we will just temporarily force the status bar to be shown.
101139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            if ((getWindowSystemUiVisibility() & (SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
102139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn                    | SYSTEM_UI_FLAG_LAYOUT_STABLE))
103139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn                    == (SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | SYSTEM_UI_FLAG_LAYOUT_STABLE)) {
104139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn                setDisabledSystemUiVisibility(SYSTEM_UI_FLAG_FULLSCREEN);
105139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            }
106139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn        } else {
107139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            setDisabledSystemUiVisibility(0);
108139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn        }
109139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn    }
110139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn
1113a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    @Override
1123a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    public void onWindowSystemUiVisibilityChanged(int visible) {
1133a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        super.onWindowSystemUiVisibilityChanged(visible);
1143a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        pullChildren();
1153a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        final int diff = mLastSystemUiVisibility ^ visible;
1163a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        mLastSystemUiVisibility = visible;
1173a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        final boolean barVisible = (visible&SYSTEM_UI_FLAG_FULLSCREEN) == 0;
118139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn        final boolean wasVisible = mActionBar != null ? mActionBar.isSystemShowing() : true;
119df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn        final boolean stable = (visible&SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0;
120139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn        if (mActionBar != null) {
121df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn            // We want the bar to be visible if it is not being hidden,
122df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn            // or the app has not turned on a stable UI mode (meaning they
123df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn            // are performing explicit layout around the action bar).
124df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn            mActionBar.enableContentAnimations(!stable);
125df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn            if (barVisible || !stable) mActionBar.showForSystem();
126139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            else mActionBar.hideForSystem();
127139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn        }
128139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn        if ((diff&SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0) {
1293a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            if (mActionBar != null) {
1303a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn                requestFitSystemWindows();
1313a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            }
1323a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
1333a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    }
1343a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
1353a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    @Override
1363a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    protected void onWindowVisibilityChanged(int visibility) {
1373a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        super.onWindowVisibilityChanged(visibility);
1383a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        mWindowVisibility = visibility;
1393a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        if (mActionBar != null) {
1403a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            mActionBar.setWindowVisibility(visibility);
1413a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
1423a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    }
1433a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
1443a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    private boolean applyInsets(View view, Rect insets, boolean left, boolean top,
1453a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            boolean bottom, boolean right) {
1463a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        boolean changed = false;
1471dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        LayoutParams lp = (LayoutParams)view.getLayoutParams();
1483a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        if (left && lp.leftMargin != insets.left) {
1493a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            changed = true;
1503a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            lp.leftMargin = insets.left;
1513a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
1523a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        if (top && lp.topMargin != insets.top) {
1533a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            changed = true;
1543a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            lp.topMargin = insets.top;
1553a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
1563a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        if (right && lp.rightMargin != insets.right) {
1573a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            changed = true;
1583a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            lp.rightMargin = insets.right;
1593a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
1603a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        if (bottom && lp.bottomMargin != insets.bottom) {
1613a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            changed = true;
1623a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            lp.bottomMargin = insets.bottom;
1633a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
1643a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        return changed;
1653a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    }
1663a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
1673a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    @Override
1683a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    protected boolean fitSystemWindows(Rect insets) {
1693a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        pullChildren();
1703a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
1713a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        final int vis = getWindowSystemUiVisibility();
1723a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        final boolean stable = (vis & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0;
1733a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
1743a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        // The top and bottom action bars are always within the content area.
1753a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        boolean changed = applyInsets(mActionBarTop, insets, true, true, false, true);
176474690caf8b3bece133b40914979ac2520036989Dianne Hackborn        if (mActionBarBottom != null) {
177474690caf8b3bece133b40914979ac2520036989Dianne Hackborn            changed |= applyInsets(mActionBarBottom, insets, true, false, true, true);
178474690caf8b3bece133b40914979ac2520036989Dianne Hackborn        }
1791dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
1801dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        mBaseInnerInsets.set(insets);
1811dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        computeFitSystemWindows(mBaseInnerInsets, mBaseContentInsets);
1821dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        if (!mLastBaseContentInsets.equals(mBaseContentInsets)) {
1831dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            changed = true;
1841dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            mLastBaseContentInsets.set(mBaseContentInsets);
185fe2b7ccca4c5fdaa0d77968b897bd789f4c87c30Dianne Hackborn        }
1863a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
1871dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        if (changed) {
1881dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            requestLayout();
1893a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
1901dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
1911dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        // We don't do any more at this point.  To correctly compute the content/inner
1921dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        // insets in all cases, we need to know the measured size of the various action
1931dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        // bar elements.  fitSystemWindows() happens before the measure pass, so we can't
1941dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        // do that here.  Instead we will take this up in onMeasure().
1951dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        return true;
1961dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    }
1971dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
1981dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    @Override
1991dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    protected LayoutParams generateDefaultLayoutParams() {
2001dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
2011dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    }
2021dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
2031dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    @Override
2041dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    public LayoutParams generateLayoutParams(AttributeSet attrs) {
2051dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        return new LayoutParams(getContext(), attrs);
2061dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    }
2071dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
2081dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    @Override
2097cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
2107cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn        return new LayoutParams(p);
2117cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn    }
2127cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn
2137cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn    @Override
2147cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
2157cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn        return p instanceof LayoutParams;
2167cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn    }
2177cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn
2187cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn    @Override
2191dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
220474690caf8b3bece133b40914979ac2520036989Dianne Hackborn        pullChildren();
221474690caf8b3bece133b40914979ac2520036989Dianne Hackborn
2221dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        int maxHeight = 0;
2231dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        int maxWidth = 0;
2241dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        int childState = 0;
2251dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
2261dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        int topInset = 0;
2271dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        int bottomInset = 0;
2281dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
2291dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        measureChildWithMargins(mActionBarTop, widthMeasureSpec, 0, heightMeasureSpec, 0);
2301dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        LayoutParams lp = (LayoutParams) mActionBarTop.getLayoutParams();
2311dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        maxWidth = Math.max(maxWidth,
2321dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                mActionBarTop.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
2331dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        maxHeight = Math.max(maxHeight,
2341dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                mActionBarTop.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
2351dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        childState = combineMeasuredStates(childState, mActionBarTop.getMeasuredState());
2361dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
237474690caf8b3bece133b40914979ac2520036989Dianne Hackborn        // xlarge screen layout doesn't have bottom action bar.
238474690caf8b3bece133b40914979ac2520036989Dianne Hackborn        if (mActionBarBottom != null) {
239474690caf8b3bece133b40914979ac2520036989Dianne Hackborn            measureChildWithMargins(mActionBarBottom, widthMeasureSpec, 0, heightMeasureSpec, 0);
240474690caf8b3bece133b40914979ac2520036989Dianne Hackborn            lp = (LayoutParams) mActionBarBottom.getLayoutParams();
241474690caf8b3bece133b40914979ac2520036989Dianne Hackborn            maxWidth = Math.max(maxWidth,
242474690caf8b3bece133b40914979ac2520036989Dianne Hackborn                    mActionBarBottom.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
243474690caf8b3bece133b40914979ac2520036989Dianne Hackborn            maxHeight = Math.max(maxHeight,
244474690caf8b3bece133b40914979ac2520036989Dianne Hackborn                    mActionBarBottom.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
245474690caf8b3bece133b40914979ac2520036989Dianne Hackborn            childState = combineMeasuredStates(childState, mActionBarBottom.getMeasuredState());
246474690caf8b3bece133b40914979ac2520036989Dianne Hackborn        }
2471dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
2481dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        final int vis = getWindowSystemUiVisibility();
2491dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        final boolean stable = (vis & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0;
2501dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
2511dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        if (stable) {
2521dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            // This is the standard space needed for the action bar.  For stable measurement,
2531dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            // we can't depend on the size currently reported by it -- this must remain constant.
2541dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            topInset = mActionBarHeight;
2551dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            if (mActionBar != null && mActionBar.hasNonEmbeddedTabs()) {
2561dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                View tabs = mContainerView.getTabContainer();
2571dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                if (tabs != null) {
2581dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                    // If tabs are not embedded, increase space on top to account for them.
2591dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                    topInset += mActionBarHeight;
2601dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                }
2613a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            }
2621dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        } else if (mActionBarTop.getVisibility() == VISIBLE) {
2631dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            // This is the space needed on top of the window for all of the action bar
2641dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            // and tabs.
2651dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            topInset = mActionBarTop.getMeasuredHeight();
2663a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
2673a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
2683a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        if (mActionView.isSplitActionBar()) {
2691dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            // If action bar is split, adjust bottom insets for it.
270474690caf8b3bece133b40914979ac2520036989Dianne Hackborn            if (mActionBarBottom != null) {
271474690caf8b3bece133b40914979ac2520036989Dianne Hackborn                if (stable) {
272474690caf8b3bece133b40914979ac2520036989Dianne Hackborn                    bottomInset = mActionBarHeight;
273474690caf8b3bece133b40914979ac2520036989Dianne Hackborn                } else {
274474690caf8b3bece133b40914979ac2520036989Dianne Hackborn                    bottomInset = mActionBarBottom.getMeasuredHeight();
275474690caf8b3bece133b40914979ac2520036989Dianne Hackborn                }
2763a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            }
2773a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
2783a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
279df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn        // If the window has not requested system UI layout flags, we need to
280df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn        // make sure its content is not being covered by system UI...  though it
2811dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        // will still be covered by the action bar if they have requested it to
282df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn        // overlay.
2831dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        mContentInsets.set(mBaseContentInsets);
2841dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        mInnerInsets.set(mBaseInnerInsets);
285df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn        if (!mOverlayMode && !stable) {
2861dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            mContentInsets.top += topInset;
2871dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            mContentInsets.bottom += bottomInset;
288df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn        } else {
2891dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            mInnerInsets.top += topInset;
2901dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            mInnerInsets.bottom += bottomInset;
291df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn        }
2921dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        applyInsets(mContent, mContentInsets, true, true, true, true);
293df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn
2941dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        if (!mLastInnerInsets.equals(mInnerInsets)) {
2951dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            // If the inner insets have changed, we need to dispatch this down to
2961dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            // the app's fitSystemWindows().  We do this before measuring the content
2971dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            // view to keep the same semantics as the normal fitSystemWindows() call.
2981dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            mLastInnerInsets.set(mInnerInsets);
2991dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            super.fitSystemWindows(mInnerInsets);
3003a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
3013a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
3021dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        measureChildWithMargins(mContent, widthMeasureSpec, 0, heightMeasureSpec, 0);
3031dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        lp = (LayoutParams) mContent.getLayoutParams();
3041dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        maxWidth = Math.max(maxWidth,
3051dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                mContent.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
3061dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        maxHeight = Math.max(maxHeight,
3071dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                mContent.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
3081dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        childState = combineMeasuredStates(childState, mContent.getMeasuredState());
3091dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3101dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        // Account for padding too
3111dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        maxWidth += getPaddingLeft() + getPaddingRight();
3121dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        maxHeight += getPaddingTop() + getPaddingBottom();
3131dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3141dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        // Check against our minimum height and width
3151dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
3161dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
3171dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3181dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
3191dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                resolveSizeAndState(maxHeight, heightMeasureSpec,
3201dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                        childState << MEASURED_HEIGHT_STATE_SHIFT));
3211dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    }
3221dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3231dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    @Override
3241dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
3251dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        final int count = getChildCount();
3261dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3271dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        final int parentLeft = getPaddingLeft();
3281dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        final int parentRight = right - left - getPaddingRight();
3291dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3301dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        final int parentTop = getPaddingTop();
3311dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        final int parentBottom = bottom - top - getPaddingBottom();
3321dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3331dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        for (int i = 0; i < count; i++) {
3341dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            final View child = getChildAt(i);
3351dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            if (child.getVisibility() != GONE) {
3361dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
3371dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3381dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                final int width = child.getMeasuredWidth();
3391dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                final int height = child.getMeasuredHeight();
3401dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3411dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                int childLeft = parentLeft + lp.leftMargin;
3421dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                int childTop;
3431dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                if (child == mActionBarBottom) {
3441dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                    childTop = parentBottom - height - lp.bottomMargin;
3451dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                } else {
3461dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                    childTop = parentTop + lp.topMargin;
3471dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                }
3481dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3491dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                child.layout(childLeft, childTop, childLeft + width, childTop + height);
3501dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            }
3511dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        }
3523a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    }
3533a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
3547cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn    @Override
3557cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn    public boolean shouldDelayChildPressedState() {
3567cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn        return false;
3577cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn    }
3587cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn
3593a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    void pullChildren() {
3603a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        if (mContent == null) {
3613a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            mContent = findViewById(com.android.internal.R.id.content);
3623a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            mActionBarTop = findViewById(com.android.internal.R.id.top_action_bar);
3633a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            mContainerView = (ActionBarContainer)findViewById(
3643a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn                    com.android.internal.R.id.action_bar_container);
3653a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            mActionView = (ActionBarView) findViewById(com.android.internal.R.id.action_bar);
3663a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            mActionBarBottom = findViewById(com.android.internal.R.id.split_action_bar);
3673a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
3683a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    }
3691dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3701dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3711dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    public static class LayoutParams extends MarginLayoutParams {
3721dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        public LayoutParams(Context c, AttributeSet attrs) {
3731dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            super(c, attrs);
3741dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        }
3751dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3761dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        public LayoutParams(int width, int height) {
3771dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            super(width, height);
3781dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        }
3791dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3801dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        public LayoutParams(ViewGroup.LayoutParams source) {
3811dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            super(source);
3821dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        }
3831dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3841dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        public LayoutParams(ViewGroup.MarginLayoutParams source) {
3851dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            super(source);
3861dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        }
3871dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    }
3883a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn}
389