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
19b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powellimport android.animation.Animator;
20b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powellimport android.animation.AnimatorListenerAdapter;
213a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackbornimport android.content.Context;
224369e7d0b087d777e5012e2706acc5be9be47de7Adam Powellimport android.content.pm.ActivityInfo;
23720924b6a9770f03355999102a11d98c5954407cAdam Powellimport android.content.res.Configuration;
243a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackbornimport android.content.res.TypedArray;
25b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powellimport android.graphics.Canvas;
263a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackbornimport android.graphics.Rect;
27b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powellimport android.graphics.drawable.Drawable;
28b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powellimport android.os.Build;
294369e7d0b087d777e5012e2706acc5be9be47de7Adam Powellimport android.os.Parcelable;
303a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackbornimport android.util.AttributeSet;
31b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powellimport android.util.IntProperty;
324369e7d0b087d777e5012e2706acc5be9be47de7Adam Powellimport android.util.Log;
33b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powellimport android.util.Property;
344369e7d0b087d777e5012e2706acc5be9be47de7Adam Powellimport android.util.SparseArray;
354369e7d0b087d777e5012e2706acc5be9be47de7Adam Powellimport android.view.KeyEvent;
364369e7d0b087d777e5012e2706acc5be9be47de7Adam Powellimport android.view.Menu;
373a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackbornimport android.view.View;
38b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powellimport android.view.ViewGroup;
39b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powellimport android.view.ViewPropertyAnimator;
404369e7d0b087d777e5012e2706acc5be9be47de7Adam Powellimport android.view.Window;
41b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powellimport android.view.WindowInsets;
42b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powellimport android.widget.OverScroller;
43e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powellimport android.widget.Toolbar;
444369e7d0b087d777e5012e2706acc5be9be47de7Adam Powellimport com.android.internal.view.menu.MenuPresenter;
453a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
463a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn/**
473a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * Special layout for the containing of an overlay action bar (and its
483a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * content) to correctly handle fitting system windows when the content
493a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn * has request that its layout ignore them.
503a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn */
514369e7d0b087d777e5012e2706acc5be9be47de7Adam Powellpublic class ActionBarOverlayLayout extends ViewGroup implements DecorContentParent {
529b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell    private static final String TAG = "ActionBarOverlayLayout";
539b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell
543a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    private int mActionBarHeight;
55b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    //private WindowDecorActionBar mActionBar;
563a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    private int mWindowVisibility = View.VISIBLE;
571dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
581dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    // The main UI elements that we handle the layout of.
593a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    private View mContent;
604369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    private ActionBarContainer mActionBarBottom;
619b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell    private ActionBarContainer mActionBarTop;
621dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
631dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    // Some interior UI elements.
64e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    private DecorToolbar mDecorToolbar;
659b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell
669b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell    // Content overlay drawable - generally the action bar's shadow
679b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell    private Drawable mWindowContentOverlay;
689b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell    private boolean mIgnoreWindowContentOverlay;
691dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
70df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn    private boolean mOverlayMode;
71b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    private boolean mHasNonEmbeddedTabs;
72b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    private boolean mHideOnContentScroll;
73b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    private boolean mAnimatingForFling;
74b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    private int mHideOnContentScrollReference;
753a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    private int mLastSystemUiVisibility;
761dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    private final Rect mBaseContentInsets = new Rect();
771dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    private final Rect mLastBaseContentInsets = new Rect();
781dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    private final Rect mContentInsets = new Rect();
791dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    private final Rect mBaseInnerInsets = new Rect();
801dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    private final Rect mInnerInsets = new Rect();
811dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    private final Rect mLastInnerInsets = new Rect();
823a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
83b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    private ActionBarVisibilityCallback mActionBarVisibilityCallback;
84b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
85b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    private final int ACTION_BAR_ANIMATE_DELAY = 600; // ms
86b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
87b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    private OverScroller mFlingEstimator;
88b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
89b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    private ViewPropertyAnimator mCurrentActionBarTopAnimator;
90b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    private ViewPropertyAnimator mCurrentActionBarBottomAnimator;
91b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
92b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    private final Animator.AnimatorListener mTopAnimatorListener = new AnimatorListenerAdapter() {
93b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        @Override
94b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        public void onAnimationEnd(Animator animation) {
95b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            mCurrentActionBarTopAnimator = null;
96b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            mAnimatingForFling = false;
97b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        }
98b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
99b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        @Override
100b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        public void onAnimationCancel(Animator animation) {
101b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            mCurrentActionBarTopAnimator = null;
102b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            mAnimatingForFling = false;
103b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        }
104b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    };
105b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
106b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    private final Animator.AnimatorListener mBottomAnimatorListener =
107b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            new AnimatorListenerAdapter() {
108b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        @Override
109b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        public void onAnimationEnd(Animator animation) {
110b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            mCurrentActionBarBottomAnimator = null;
111b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            mAnimatingForFling = false;
112b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        }
113b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
114b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        @Override
115b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        public void onAnimationCancel(Animator animation) {
116b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            mCurrentActionBarBottomAnimator = null;
117b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            mAnimatingForFling = false;
118b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        }
119b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    };
120b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
121b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    private final Runnable mRemoveActionBarHideOffset = new Runnable() {
122b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        public void run() {
123b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            haltActionBarHideOffsetAnimations();
124b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            mCurrentActionBarTopAnimator = mActionBarTop.animate().translationY(0)
125b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell                    .setListener(mTopAnimatorListener);
126b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            if (mActionBarBottom != null && mActionBarBottom.getVisibility() != GONE) {
127b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell                mCurrentActionBarBottomAnimator = mActionBarBottom.animate().translationY(0)
128b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell                        .setListener(mBottomAnimatorListener);
129b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            }
130b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        }
131b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    };
132b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
133b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    private final Runnable mAddActionBarHideOffset = new Runnable() {
134b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        public void run() {
135b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            haltActionBarHideOffsetAnimations();
136b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            mCurrentActionBarTopAnimator = mActionBarTop.animate()
137b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell                    .translationY(-mActionBarTop.getHeight())
138b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell                    .setListener(mTopAnimatorListener);
139b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            if (mActionBarBottom != null && mActionBarBottom.getVisibility() != GONE) {
140b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell                mCurrentActionBarBottomAnimator = mActionBarBottom.animate()
141b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell                        .translationY(mActionBarBottom.getHeight())
142b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell                        .setListener(mBottomAnimatorListener);
143b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            }
144b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        }
145b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    };
146b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
147b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    public static final Property<ActionBarOverlayLayout, Integer> ACTION_BAR_HIDE_OFFSET =
148b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            new IntProperty<ActionBarOverlayLayout>("actionBarHideOffset") {
149b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
150b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell                @Override
151b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell                public void setValue(ActionBarOverlayLayout object, int value) {
152b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell                    object.setActionBarHideOffset(value);
153b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell                }
154b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
155b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell                @Override
156b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell                public Integer get(ActionBarOverlayLayout object) {
157b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell                    return object.getActionBarHideOffset();
158b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell                }
159b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            };
160b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
1619b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell    static final int[] ATTRS = new int [] {
1629b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell            com.android.internal.R.attr.actionBarSize,
1639b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell            com.android.internal.R.attr.windowContentOverlay
1643a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    };
1653a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
1663a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    public ActionBarOverlayLayout(Context context) {
1673a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        super(context);
1683a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        init(context);
1693a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    }
1703a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
1713a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    public ActionBarOverlayLayout(Context context, AttributeSet attrs) {
1723a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        super(context, attrs);
1733a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        init(context);
1743a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    }
1753a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
1763a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    private void init(Context context) {
1779b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell        TypedArray ta = getContext().getTheme().obtainStyledAttributes(ATTRS);
1783a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        mActionBarHeight = ta.getDimensionPixelSize(0, 0);
1799b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell        mWindowContentOverlay = ta.getDrawable(1);
1809b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell        setWillNotDraw(mWindowContentOverlay == null);
1813a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        ta.recycle();
1829b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell
1839b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell        mIgnoreWindowContentOverlay = context.getApplicationInfo().targetSdkVersion <
184e8222dddaf2e3da14380101e818d4254899e0c0dChet Haase                Build.VERSION_CODES.KITKAT;
185b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
186b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        mFlingEstimator = new OverScroller(context);
187b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    }
188b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
189b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    @Override
190b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    protected void onDetachedFromWindow() {
191b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        super.onDetachedFromWindow();
192b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        haltActionBarHideOffsetAnimations();
1933a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    }
1943a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
195b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    public void setActionBarVisibilityCallback(ActionBarVisibilityCallback cb) {
196b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        mActionBarVisibilityCallback = cb;
1973a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        if (getWindowToken() != null) {
1983a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            // This is being initialized after being added to a window;
1993a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            // make sure to update all state now.
200b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            mActionBarVisibilityCallback.onWindowVisibilityChanged(mWindowVisibility);
2013a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            if (mLastSystemUiVisibility != 0) {
2023a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn                int newVis = mLastSystemUiVisibility;
2033a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn                onWindowSystemUiVisibilityChanged(newVis);
20446e38fd9abe1af3ccb903a80ff89bc3faef4d3e3Adam Powell                requestApplyInsets();
2053a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            }
2063a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
2073a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    }
2083a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
2099b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell    public void setOverlayMode(boolean overlayMode) {
2109b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell        mOverlayMode = overlayMode;
2119b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell
2129b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell        /*
2139b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell         * Drawing the window content overlay was broken before K so starting to draw it
2149b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell         * again unexpectedly will cause artifacts in some apps. They should fix it.
2159b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell         */
2169b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell        mIgnoreWindowContentOverlay = overlayMode &&
2179b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell                getContext().getApplicationInfo().targetSdkVersion <
218e8222dddaf2e3da14380101e818d4254899e0c0dChet Haase                        Build.VERSION_CODES.KITKAT;
2199b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell    }
2209b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell
221b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    public boolean isInOverlayMode() {
222b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        return mOverlayMode;
223b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    }
224b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
225b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    public void setHasNonEmbeddedTabs(boolean hasNonEmbeddedTabs) {
226b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        mHasNonEmbeddedTabs = hasNonEmbeddedTabs;
227b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    }
228b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
229139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn    public void setShowingForActionMode(boolean showing) {
230139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn        if (showing) {
231139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            // Here's a fun hack: if the status bar is currently being hidden,
232139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            // and the application has asked for stable content insets, then
233139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            // we will end up with the action mode action bar being shown
234139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            // without the status bar, but moved below where the status bar
235139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            // would be.  Not nice.  Trying to have this be positioned
236139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            // correctly is not easy (basically we need yet *another* content
237139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            // inset from the window manager to know where to put it), so
238139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            // instead we will just temporarily force the status bar to be shown.
239139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            if ((getWindowSystemUiVisibility() & (SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
240139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn                    | SYSTEM_UI_FLAG_LAYOUT_STABLE))
241139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn                    == (SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | SYSTEM_UI_FLAG_LAYOUT_STABLE)) {
242139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn                setDisabledSystemUiVisibility(SYSTEM_UI_FLAG_FULLSCREEN);
243139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            }
244139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn        } else {
245139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn            setDisabledSystemUiVisibility(0);
246139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn        }
247139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn    }
248139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn
2493a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    @Override
250720924b6a9770f03355999102a11d98c5954407cAdam Powell    protected void onConfigurationChanged(Configuration newConfig) {
251720924b6a9770f03355999102a11d98c5954407cAdam Powell        super.onConfigurationChanged(newConfig);
252720924b6a9770f03355999102a11d98c5954407cAdam Powell        init(getContext());
253720924b6a9770f03355999102a11d98c5954407cAdam Powell        requestApplyInsets();
254720924b6a9770f03355999102a11d98c5954407cAdam Powell    }
255720924b6a9770f03355999102a11d98c5954407cAdam Powell
256720924b6a9770f03355999102a11d98c5954407cAdam Powell    @Override
2573a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    public void onWindowSystemUiVisibilityChanged(int visible) {
2583a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        super.onWindowSystemUiVisibilityChanged(visible);
2593a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        pullChildren();
2603a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        final int diff = mLastSystemUiVisibility ^ visible;
2613a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        mLastSystemUiVisibility = visible;
262b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        final boolean barVisible = (visible & SYSTEM_UI_FLAG_FULLSCREEN) == 0;
263b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        final boolean stable = (visible & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0;
264b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        if (mActionBarVisibilityCallback != null) {
265df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn            // We want the bar to be visible if it is not being hidden,
266df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn            // or the app has not turned on a stable UI mode (meaning they
267df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn            // are performing explicit layout around the action bar).
268b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            mActionBarVisibilityCallback.enableContentAnimations(!stable);
269b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            if (barVisible || !stable) mActionBarVisibilityCallback.showForSystem();
270b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            else mActionBarVisibilityCallback.hideForSystem();
271139e5aa1da51b27231ab36344cf2d0dafab23f1eDianne Hackborn        }
272b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        if ((diff & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0) {
273b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            if (mActionBarVisibilityCallback != null) {
27446e38fd9abe1af3ccb903a80ff89bc3faef4d3e3Adam Powell                requestApplyInsets();
2753a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            }
2763a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
2773a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    }
2783a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
2793a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    @Override
2803a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    protected void onWindowVisibilityChanged(int visibility) {
2813a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        super.onWindowVisibilityChanged(visibility);
2823a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        mWindowVisibility = visibility;
283b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        if (mActionBarVisibilityCallback != null) {
284b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            mActionBarVisibilityCallback.onWindowVisibilityChanged(visibility);
2853a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
2863a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    }
2873a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
2883a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    private boolean applyInsets(View view, Rect insets, boolean left, boolean top,
2893a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            boolean bottom, boolean right) {
2903a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        boolean changed = false;
2911dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        LayoutParams lp = (LayoutParams)view.getLayoutParams();
2923a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        if (left && lp.leftMargin != insets.left) {
2933a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            changed = true;
2943a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            lp.leftMargin = insets.left;
2953a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
2963a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        if (top && lp.topMargin != insets.top) {
2973a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            changed = true;
2983a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            lp.topMargin = insets.top;
2993a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
3003a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        if (right && lp.rightMargin != insets.right) {
3013a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            changed = true;
3023a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            lp.rightMargin = insets.right;
3033a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
3043a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        if (bottom && lp.bottomMargin != insets.bottom) {
3053a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            changed = true;
3063a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            lp.bottomMargin = insets.bottom;
3073a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
3083a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        return changed;
3093a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    }
3103a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
3113a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    @Override
31246e38fd9abe1af3ccb903a80ff89bc3faef4d3e3Adam Powell    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
3133a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        pullChildren();
3143a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
3153a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        final int vis = getWindowSystemUiVisibility();
3163a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        final boolean stable = (vis & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0;
31746e38fd9abe1af3ccb903a80ff89bc3faef4d3e3Adam Powell        final Rect systemInsets = insets.getSystemWindowInsets();
3183a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
3193a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        // The top and bottom action bars are always within the content area.
32046e38fd9abe1af3ccb903a80ff89bc3faef4d3e3Adam Powell        boolean changed = applyInsets(mActionBarTop, systemInsets, true, true, false, true);
321474690caf8b3bece133b40914979ac2520036989Dianne Hackborn        if (mActionBarBottom != null) {
32246e38fd9abe1af3ccb903a80ff89bc3faef4d3e3Adam Powell            changed |= applyInsets(mActionBarBottom, systemInsets, true, false, true, true);
323474690caf8b3bece133b40914979ac2520036989Dianne Hackborn        }
3241dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
32546e38fd9abe1af3ccb903a80ff89bc3faef4d3e3Adam Powell        mBaseInnerInsets.set(systemInsets);
3261dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        computeFitSystemWindows(mBaseInnerInsets, mBaseContentInsets);
3271dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        if (!mLastBaseContentInsets.equals(mBaseContentInsets)) {
3281dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            changed = true;
3291dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            mLastBaseContentInsets.set(mBaseContentInsets);
330fe2b7ccca4c5fdaa0d77968b897bd789f4c87c30Dianne Hackborn        }
3313a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
3321dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        if (changed) {
3331dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            requestLayout();
3343a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
3351dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3361dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        // We don't do any more at this point.  To correctly compute the content/inner
3371dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        // insets in all cases, we need to know the measured size of the various action
33846e38fd9abe1af3ccb903a80ff89bc3faef4d3e3Adam Powell        // bar elements.  onApplyWindowInsets() happens before the measure pass, so we can't
3391dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        // do that here.  Instead we will take this up in onMeasure().
340720924b6a9770f03355999102a11d98c5954407cAdam Powell        return WindowInsets.CONSUMED;
3411dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    }
3421dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3431dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    @Override
3441dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    protected LayoutParams generateDefaultLayoutParams() {
3451dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
3461dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    }
3471dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3481dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    @Override
3491dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    public LayoutParams generateLayoutParams(AttributeSet attrs) {
3501dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        return new LayoutParams(getContext(), attrs);
3511dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    }
3521dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3531dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    @Override
3547cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
3557cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn        return new LayoutParams(p);
3567cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn    }
3577cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn
3587cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn    @Override
3597cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
3607cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn        return p instanceof LayoutParams;
3617cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn    }
3627cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn
3637cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn    @Override
3641dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
365474690caf8b3bece133b40914979ac2520036989Dianne Hackborn        pullChildren();
366474690caf8b3bece133b40914979ac2520036989Dianne Hackborn
3671dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        int maxHeight = 0;
3681dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        int maxWidth = 0;
3691dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        int childState = 0;
3701dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3711dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        int topInset = 0;
3721dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        int bottomInset = 0;
3731dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3741dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        measureChildWithMargins(mActionBarTop, widthMeasureSpec, 0, heightMeasureSpec, 0);
3751dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        LayoutParams lp = (LayoutParams) mActionBarTop.getLayoutParams();
3761dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        maxWidth = Math.max(maxWidth,
3771dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                mActionBarTop.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
3781dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        maxHeight = Math.max(maxHeight,
3791dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                mActionBarTop.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
3801dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        childState = combineMeasuredStates(childState, mActionBarTop.getMeasuredState());
3811dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
382474690caf8b3bece133b40914979ac2520036989Dianne Hackborn        // xlarge screen layout doesn't have bottom action bar.
383474690caf8b3bece133b40914979ac2520036989Dianne Hackborn        if (mActionBarBottom != null) {
384474690caf8b3bece133b40914979ac2520036989Dianne Hackborn            measureChildWithMargins(mActionBarBottom, widthMeasureSpec, 0, heightMeasureSpec, 0);
385474690caf8b3bece133b40914979ac2520036989Dianne Hackborn            lp = (LayoutParams) mActionBarBottom.getLayoutParams();
386474690caf8b3bece133b40914979ac2520036989Dianne Hackborn            maxWidth = Math.max(maxWidth,
387474690caf8b3bece133b40914979ac2520036989Dianne Hackborn                    mActionBarBottom.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
388474690caf8b3bece133b40914979ac2520036989Dianne Hackborn            maxHeight = Math.max(maxHeight,
389474690caf8b3bece133b40914979ac2520036989Dianne Hackborn                    mActionBarBottom.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
390474690caf8b3bece133b40914979ac2520036989Dianne Hackborn            childState = combineMeasuredStates(childState, mActionBarBottom.getMeasuredState());
391474690caf8b3bece133b40914979ac2520036989Dianne Hackborn        }
3921dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3931dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        final int vis = getWindowSystemUiVisibility();
3941dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        final boolean stable = (vis & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0;
3951dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
3961dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        if (stable) {
3971dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            // This is the standard space needed for the action bar.  For stable measurement,
3981dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            // we can't depend on the size currently reported by it -- this must remain constant.
3991dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            topInset = mActionBarHeight;
400b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            if (mHasNonEmbeddedTabs) {
401b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell                final View tabs = mActionBarTop.getTabContainer();
4021dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                if (tabs != null) {
4031dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                    // If tabs are not embedded, increase space on top to account for them.
4041dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                    topInset += mActionBarHeight;
4051dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                }
4063a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            }
40714a9738330c14410378fe2ba1c25404a444adaf3George Mount        } else if (mActionBarTop.getVisibility() != GONE) {
4081dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            // This is the space needed on top of the window for all of the action bar
4091dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            // and tabs.
4101dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            topInset = mActionBarTop.getMeasuredHeight();
4113a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
4123a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
413e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        if (mDecorToolbar.isSplit()) {
4141dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            // If action bar is split, adjust bottom insets for it.
415474690caf8b3bece133b40914979ac2520036989Dianne Hackborn            if (mActionBarBottom != null) {
416474690caf8b3bece133b40914979ac2520036989Dianne Hackborn                if (stable) {
417474690caf8b3bece133b40914979ac2520036989Dianne Hackborn                    bottomInset = mActionBarHeight;
418474690caf8b3bece133b40914979ac2520036989Dianne Hackborn                } else {
419474690caf8b3bece133b40914979ac2520036989Dianne Hackborn                    bottomInset = mActionBarBottom.getMeasuredHeight();
420474690caf8b3bece133b40914979ac2520036989Dianne Hackborn                }
4213a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            }
4223a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
4233a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
424df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn        // If the window has not requested system UI layout flags, we need to
425df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn        // make sure its content is not being covered by system UI...  though it
4261dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        // will still be covered by the action bar if they have requested it to
427df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn        // overlay.
4281dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        mContentInsets.set(mBaseContentInsets);
4291dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        mInnerInsets.set(mBaseInnerInsets);
430df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn        if (!mOverlayMode && !stable) {
4311dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            mContentInsets.top += topInset;
4321dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            mContentInsets.bottom += bottomInset;
433df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn        } else {
4341dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            mInnerInsets.top += topInset;
4351dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            mInnerInsets.bottom += bottomInset;
436df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn        }
4371dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        applyInsets(mContent, mContentInsets, true, true, true, true);
438df7221ced3b7cd807f14e84c302fc09fd659fd68Dianne Hackborn
4391dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        if (!mLastInnerInsets.equals(mInnerInsets)) {
4401dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            // If the inner insets have changed, we need to dispatch this down to
4411dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            // the app's fitSystemWindows().  We do this before measuring the content
4421dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            // view to keep the same semantics as the normal fitSystemWindows() call.
4431dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            mLastInnerInsets.set(mInnerInsets);
44446e38fd9abe1af3ccb903a80ff89bc3faef4d3e3Adam Powell            mContent.dispatchApplyWindowInsets(new WindowInsets(mInnerInsets));
4453a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
4463a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
4471dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        measureChildWithMargins(mContent, widthMeasureSpec, 0, heightMeasureSpec, 0);
4481dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        lp = (LayoutParams) mContent.getLayoutParams();
4491dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        maxWidth = Math.max(maxWidth,
4501dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                mContent.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
4511dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        maxHeight = Math.max(maxHeight,
4521dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                mContent.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
4531dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        childState = combineMeasuredStates(childState, mContent.getMeasuredState());
4541dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
4551dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        // Account for padding too
4561dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        maxWidth += getPaddingLeft() + getPaddingRight();
4571dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        maxHeight += getPaddingTop() + getPaddingBottom();
4581dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
4591dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        // Check against our minimum height and width
4601dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
4611dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
4621dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
4631dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
4641dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                resolveSizeAndState(maxHeight, heightMeasureSpec,
4651dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                        childState << MEASURED_HEIGHT_STATE_SHIFT));
4661dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    }
4671dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
4681dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    @Override
4691dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
4701dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        final int count = getChildCount();
4711dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
4721dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        final int parentLeft = getPaddingLeft();
4731dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        final int parentRight = right - left - getPaddingRight();
4741dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
4751dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        final int parentTop = getPaddingTop();
4761dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        final int parentBottom = bottom - top - getPaddingBottom();
4771dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
4781dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        for (int i = 0; i < count; i++) {
4791dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            final View child = getChildAt(i);
4801dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            if (child.getVisibility() != GONE) {
4811dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
4821dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
4831dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                final int width = child.getMeasuredWidth();
4841dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                final int height = child.getMeasuredHeight();
4851dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
4861dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                int childLeft = parentLeft + lp.leftMargin;
4871dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                int childTop;
4881dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                if (child == mActionBarBottom) {
4891dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                    childTop = parentBottom - height - lp.bottomMargin;
4901dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                } else {
4911dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                    childTop = parentTop + lp.topMargin;
4921dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                }
4931dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
4941dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn                child.layout(childLeft, childTop, childLeft + width, childTop + height);
4951dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            }
4961dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        }
4973a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    }
4983a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn
4997cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn    @Override
5009b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell    public void draw(Canvas c) {
5019b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell        super.draw(c);
5029b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell        if (mWindowContentOverlay != null && !mIgnoreWindowContentOverlay) {
5039b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell            final int top = mActionBarTop.getVisibility() == VISIBLE ?
5049b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell                    (int) (mActionBarTop.getBottom() + mActionBarTop.getTranslationY() + 0.5f) : 0;
5059b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell            mWindowContentOverlay.setBounds(0, top, getWidth(),
5069b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell                    top + mWindowContentOverlay.getIntrinsicHeight());
5079b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell            mWindowContentOverlay.draw(c);
5089b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell        }
5099b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell    }
5109b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell
5119b0dc2894df1c3d26aa6196ecdef1989967e6ec9Adam Powell    @Override
5127cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn    public boolean shouldDelayChildPressedState() {
5137cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn        return false;
5147cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn    }
5157cf71fbdc3225778d0397b22cdaf40c812c15afbDianne Hackborn
516b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    @Override
517b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    public boolean onStartNestedScroll(View child, View target, int axes) {
518b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        if ((axes & SCROLL_AXIS_VERTICAL) == 0 || mActionBarTop.getVisibility() != VISIBLE) {
519b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            return false;
520b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        }
521b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        return mHideOnContentScroll;
522b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    }
523b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
524b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    @Override
525b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    public void onNestedScrollAccepted(View child, View target, int axes) {
526b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        super.onNestedScrollAccepted(child, target, axes);
527b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        mHideOnContentScrollReference = getActionBarHideOffset();
528b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        haltActionBarHideOffsetAnimations();
529b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        if (mActionBarVisibilityCallback != null) {
530b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            mActionBarVisibilityCallback.onContentScrollStarted();
531b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        }
532b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    }
533b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
534b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    @Override
535b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    public void onNestedScroll(View target, int dxConsumed, int dyConsumed,
536b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            int dxUnconsumed, int dyUnconsumed) {
537b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        mHideOnContentScrollReference += dyConsumed;
538b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        setActionBarHideOffset(mHideOnContentScrollReference);
539b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    }
540b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
541b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    @Override
542b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    public void onStopNestedScroll(View target) {
543b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        super.onStopNestedScroll(target);
544b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        if (mHideOnContentScroll && !mAnimatingForFling) {
545b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            if (mHideOnContentScrollReference <= mActionBarTop.getHeight()) {
546b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell                postRemoveActionBarHideOffset();
547b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            } else {
548b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell                postAddActionBarHideOffset();
549b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            }
550b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        }
551b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        if (mActionBarVisibilityCallback != null) {
552b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            mActionBarVisibilityCallback.onContentScrollStopped();
553b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        }
554b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    }
555b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
556b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    @Override
557b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) {
558b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        if (!mHideOnContentScroll || !consumed) {
559b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            return false;
560b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        }
561b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        if (shouldHideActionBarOnFling(velocityX, velocityY)) {
562b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            addActionBarHideOffset();
563b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        } else {
564b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            removeActionBarHideOffset();
565b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        }
566b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        mAnimatingForFling = true;
567b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        return true;
568b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    }
569b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
5703a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    void pullChildren() {
5713a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        if (mContent == null) {
5723a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn            mContent = findViewById(com.android.internal.R.id.content);
573b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            mActionBarTop = (ActionBarContainer) findViewById(
5743a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn                    com.android.internal.R.id.action_bar_container);
575e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            mDecorToolbar = getDecorToolbar(findViewById(com.android.internal.R.id.action_bar));
5764369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell            mActionBarBottom = (ActionBarContainer) findViewById(
5774369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell                    com.android.internal.R.id.split_action_bar);
5783a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn        }
5793a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn    }
5801dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
581e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    private DecorToolbar getDecorToolbar(View view) {
582e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        if (view instanceof DecorToolbar) {
583e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            return (DecorToolbar) view;
584e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        } else if (view instanceof Toolbar) {
585e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            return ((Toolbar) view).getWrapper();
586e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        } else {
587e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            throw new IllegalStateException("Can't make a decor toolbar out of " +
588e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                    view.getClass().getSimpleName());
589e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        }
590e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell    }
591e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell
592b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    public void setHideOnContentScrollEnabled(boolean hideOnContentScroll) {
593b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        if (hideOnContentScroll != mHideOnContentScroll) {
594b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            mHideOnContentScroll = hideOnContentScroll;
595b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            if (!hideOnContentScroll) {
596b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell                stopNestedScroll();
597b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell                haltActionBarHideOffsetAnimations();
598b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell                setActionBarHideOffset(0);
599b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            }
600b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        }
601b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    }
602b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
603b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    public boolean isHideOnContentScrollEnabled() {
604b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        return mHideOnContentScroll;
605b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    }
606b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
607b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    public int getActionBarHideOffset() {
608c4b416f18d83100a386ab81e934e572cd471c4b3Adam Powell        return mActionBarTop != null ? -((int) mActionBarTop.getTranslationY()) : 0;
609b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    }
610b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
611b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    public void setActionBarHideOffset(int offset) {
612b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        haltActionBarHideOffsetAnimations();
613b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        final int topHeight = mActionBarTop.getHeight();
614b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        offset = Math.max(0, Math.min(offset, topHeight));
615b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        mActionBarTop.setTranslationY(-offset);
616b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        if (mActionBarBottom != null && mActionBarBottom.getVisibility() != GONE) {
617b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            // Match the hide offset proportionally for a split bar
618b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            final float fOffset = (float) offset / topHeight;
619b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            final int bOffset = (int) (mActionBarBottom.getHeight() * fOffset);
620b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            mActionBarBottom.setTranslationY(bOffset);
621b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        }
622b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    }
623b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
624b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    private void haltActionBarHideOffsetAnimations() {
625b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        removeCallbacks(mRemoveActionBarHideOffset);
626b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        removeCallbacks(mAddActionBarHideOffset);
627b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        if (mCurrentActionBarTopAnimator != null) {
628b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            mCurrentActionBarTopAnimator.cancel();
629b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        }
630b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        if (mCurrentActionBarBottomAnimator != null) {
631b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell            mCurrentActionBarBottomAnimator.cancel();
632b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        }
633b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    }
634b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
635b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    private void postRemoveActionBarHideOffset() {
636b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        haltActionBarHideOffsetAnimations();
637b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        postDelayed(mRemoveActionBarHideOffset, ACTION_BAR_ANIMATE_DELAY);
638b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    }
639b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
640b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    private void postAddActionBarHideOffset() {
641b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        haltActionBarHideOffsetAnimations();
642b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        postDelayed(mAddActionBarHideOffset, ACTION_BAR_ANIMATE_DELAY);
643b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    }
644b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
645b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    private void removeActionBarHideOffset() {
646b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        haltActionBarHideOffsetAnimations();
647b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        mRemoveActionBarHideOffset.run();
648b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    }
649b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
650b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    private void addActionBarHideOffset() {
651b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        haltActionBarHideOffsetAnimations();
652b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        mAddActionBarHideOffset.run();
653b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    }
654b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
655b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    private boolean shouldHideActionBarOnFling(float velocityX, float velocityY) {
656b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        mFlingEstimator.fling(0, 0, 0, (int) velocityY, 0, 0, Integer.MIN_VALUE, Integer.MAX_VALUE);
657b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        final int finalY = mFlingEstimator.getFinalY();
658b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        return finalY > mActionBarTop.getHeight();
659b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    }
6601dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
6614369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    @Override
6624369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    public void setWindowCallback(Window.Callback cb) {
6634369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        pullChildren();
664e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        mDecorToolbar.setWindowCallback(cb);
6654369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    }
6664369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell
6674369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    @Override
6684369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    public void setWindowTitle(CharSequence title) {
6694369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        pullChildren();
670e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        mDecorToolbar.setWindowTitle(title);
6714369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    }
6724369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell
6734369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    @Override
6744369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    public CharSequence getTitle() {
6754369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        pullChildren();
676e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        return mDecorToolbar.getTitle();
6774369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    }
6784369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell
6794369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    @Override
6804369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    public void initFeature(int windowFeature) {
6814369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        pullChildren();
6824369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        switch (windowFeature) {
6834369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell            case Window.FEATURE_PROGRESS:
684e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                mDecorToolbar.initProgress();
6854369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell                break;
6864369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell            case Window.FEATURE_INDETERMINATE_PROGRESS:
687e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                mDecorToolbar.initIndeterminateProgress();
6884369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell                break;
6894369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell            case Window.FEATURE_ACTION_BAR_OVERLAY:
6904369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell                setOverlayMode(true);
6914369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell                break;
6924369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        }
6934369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    }
6944369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell
6954369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    @Override
6964369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    public void setUiOptions(int uiOptions) {
6974369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        boolean splitActionBar = false;
6984369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        final boolean splitWhenNarrow =
6994369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell                (uiOptions & ActivityInfo.UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW) != 0;
7004369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        if (splitWhenNarrow) {
7014369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell            splitActionBar = getContext().getResources().getBoolean(
7024369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell                    com.android.internal.R.bool.split_action_bar_is_narrow);
7034369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        }
7044369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        if (splitActionBar) {
7054369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell            pullChildren();
706e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell            if (mActionBarBottom != null && mDecorToolbar.canSplit()) {
707e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                mDecorToolbar.setSplitView(mActionBarBottom);
708e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                mDecorToolbar.setSplitToolbar(splitActionBar);
709e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                mDecorToolbar.setSplitWhenNarrow(splitWhenNarrow);
7104369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell
7114369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell                final ActionBarContextView cab = (ActionBarContextView) findViewById(
7124369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell                        com.android.internal.R.id.action_context_bar);
7134369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell                cab.setSplitView(mActionBarBottom);
714e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell                cab.setSplitToolbar(splitActionBar);
7154369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell                cab.setSplitWhenNarrow(splitWhenNarrow);
7164369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell            } else if (splitActionBar) {
7174369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell                Log.e(TAG, "Requested split action bar with " +
7184369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell                        "incompatible window decor! Ignoring request.");
7194369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell            }
7204369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        }
7214369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    }
7224369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell
7234369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    @Override
7244369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    public boolean hasIcon() {
7254369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        pullChildren();
726e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        return mDecorToolbar.hasIcon();
7274369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    }
7284369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell
7294369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    @Override
7304369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    public boolean hasLogo() {
7314369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        pullChildren();
732e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        return mDecorToolbar.hasLogo();
7334369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    }
7344369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell
7354369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    @Override
7364369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    public void setIcon(int resId) {
7374369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        pullChildren();
738e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        mDecorToolbar.setIcon(resId);
7394369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    }
7404369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell
7414369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    @Override
7424369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    public void setIcon(Drawable d) {
7434369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        pullChildren();
744e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        mDecorToolbar.setIcon(d);
7454369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    }
7464369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell
7474369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    @Override
7484369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    public void setLogo(int resId) {
7494369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        pullChildren();
750e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        mDecorToolbar.setLogo(resId);
7514369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    }
7524369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell
7534369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    @Override
7544369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    public boolean canShowOverflowMenu() {
7554369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        pullChildren();
756e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        return mDecorToolbar.canShowOverflowMenu();
7574369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    }
7584369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell
7594369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    @Override
7604369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    public boolean isOverflowMenuShowing() {
7614369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        pullChildren();
762e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        return mDecorToolbar.isOverflowMenuShowing();
7634369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    }
7644369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell
7654369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    @Override
7664369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    public boolean isOverflowMenuShowPending() {
7674369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        pullChildren();
768e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        return mDecorToolbar.isOverflowMenuShowPending();
7694369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    }
7704369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell
7714369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    @Override
7724369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    public boolean showOverflowMenu() {
7734369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        pullChildren();
774e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        return mDecorToolbar.showOverflowMenu();
7754369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    }
7764369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell
7774369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    @Override
7784369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    public boolean hideOverflowMenu() {
7794369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        pullChildren();
780e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        return mDecorToolbar.hideOverflowMenu();
7814369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    }
7824369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell
7834369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    @Override
7844369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    public void setMenuPrepared() {
7854369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        pullChildren();
786e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        mDecorToolbar.setMenuPrepared();
7874369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    }
7884369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell
7894369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    @Override
7904369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    public void setMenu(Menu menu, MenuPresenter.Callback cb) {
7914369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        pullChildren();
792e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        mDecorToolbar.setMenu(menu, cb);
7934369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    }
7944369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell
7954369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    @Override
7964369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    public void saveToolbarHierarchyState(SparseArray<Parcelable> toolbarStates) {
7974369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        pullChildren();
798e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        mDecorToolbar.saveHierarchyState(toolbarStates);
7994369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    }
8004369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell
8014369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    @Override
8024369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    public void restoreToolbarHierarchyState(SparseArray<Parcelable> toolbarStates) {
8034369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        pullChildren();
804e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        mDecorToolbar.restoreHierarchyState(toolbarStates);
8054369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    }
8064369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell
8074369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    @Override
8084369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    public void dismissPopups() {
8094369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell        pullChildren();
810e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell        mDecorToolbar.dismissPopupMenus();
8114369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell    }
8124369e7d0b087d777e5012e2706acc5be9be47de7Adam Powell
8131dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    public static class LayoutParams extends MarginLayoutParams {
8141dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        public LayoutParams(Context c, AttributeSet attrs) {
8151dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            super(c, attrs);
8161dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        }
8171dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
8181dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        public LayoutParams(int width, int height) {
8191dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            super(width, height);
8201dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        }
8211dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
8221dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        public LayoutParams(ViewGroup.LayoutParams source) {
8231dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            super(source);
8241dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        }
8251dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn
8261dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        public LayoutParams(ViewGroup.MarginLayoutParams source) {
8271dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn            super(source);
8281dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn        }
8291dc5f92716189da02aa62f508adb6099061668b5Dianne Hackborn    }
830b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell
831b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    public interface ActionBarVisibilityCallback {
832b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        void onWindowVisibilityChanged(int visibility);
833b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        void showForSystem();
834b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        void hideForSystem();
835b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        void enableContentAnimations(boolean enable);
836b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        void onContentScrollStarted();
837b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell        void onContentScrollStopped();
838b36e4f944fe28ce68182f9ec91e5341866b49084Adam Powell    }
8393a3a6cfd8ec12208ca75c0d0d871d19d76c34194Dianne Hackborn}
840