119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller/*
219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller * Copyright (C) 2012 The Android Open Source Project
319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller *
419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller * Licensed under the Apache License, Version 2.0 (the "License");
519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller * you may not use this file except in compliance with the License.
619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller * You may obtain a copy of the License at
719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller *
819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller *      http://www.apache.org/licenses/LICENSE-2.0
919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller *
1019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller * Unless required by applicable law or agreed to in writing, software
1119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller * distributed under the License is distributed on an "AS IS" BASIS,
1219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller * See the License for the specific language governing permissions and
1419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller * limitations under the License.
1519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller */
1619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
1719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Millerpackage com.android.internal.policy.impl.keyguard;
1819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
199d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powellimport com.android.internal.R;
209d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell
21c345146a3a321644f653fce0fb79f288a0221fb0Chris Wrenimport android.animation.Animator;
22c345146a3a321644f653fce0fb79f288a0221fb0Chris Wrenimport android.animation.AnimatorListenerAdapter;
23c345146a3a321644f653fce0fb79f288a0221fb0Chris Wrenimport android.animation.ObjectAnimator;
2419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Millerimport android.content.Context;
259d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powellimport android.content.res.Resources;
2619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Millerimport android.content.res.TypedArray;
2719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Millerimport android.graphics.Rect;
2819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Millerimport android.util.AttributeSet;
299d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powellimport android.util.DisplayMetrics;
3019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Millerimport android.view.Gravity;
3119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Millerimport android.view.View;
3219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Millerimport android.view.ViewGroup;
3319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Millerimport android.widget.LinearLayout;
3419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
3519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Millerpublic class MultiPaneChallengeLayout extends ViewGroup implements ChallengeLayout {
3619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    private static final String TAG = "MultiPaneChallengeLayout";
3719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
3819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    final int mOrientation;
39eee209313d564be37b8fc068f785b3844cd6597eAdam Powell    private boolean mIsBouncing;
4019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
4119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    public static final int HORIZONTAL = LinearLayout.HORIZONTAL;
4219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    public static final int VERTICAL = LinearLayout.VERTICAL;
4370c2f8736437ebb6073c3b6dab2e08e6dd9f39a6Winson Chung    public static final int ANIMATE_BOUNCE_DURATION = 350;
4419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
45c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren    private KeyguardSecurityContainer mChallengeView;
4619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    private View mUserSwitcherView;
47eee209313d564be37b8fc068f785b3844cd6597eAdam Powell    private View mScrimView;
480b1b552268bc6641cc5d01fb80c12258da9c6985Adam Powell    private OnBouncerStateChangedListener mBouncerListener;
4919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
5019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    private final Rect mTempRect = new Rect();
51c065a5d7271c6683b64578490ccc836c72d3ed78Winson Chung    private final Rect mZeroPadding = new Rect();
529d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell
539d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell    private final DisplayMetrics mDisplayMetrics;
5419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
55eee209313d564be37b8fc068f785b3844cd6597eAdam Powell    private final OnClickListener mScrimClickListener = new OnClickListener() {
56eee209313d564be37b8fc068f785b3844cd6597eAdam Powell        @Override
57eee209313d564be37b8fc068f785b3844cd6597eAdam Powell        public void onClick(View v) {
58eee209313d564be37b8fc068f785b3844cd6597eAdam Powell            hideBouncer();
59eee209313d564be37b8fc068f785b3844cd6597eAdam Powell        }
60eee209313d564be37b8fc068f785b3844cd6597eAdam Powell    };
61eee209313d564be37b8fc068f785b3844cd6597eAdam Powell
6219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    public MultiPaneChallengeLayout(Context context) {
6319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        this(context, null);
6419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    }
6519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
6619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    public MultiPaneChallengeLayout(Context context, AttributeSet attrs) {
6719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        this(context, attrs, 0);
6819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    }
6919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
7019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    public MultiPaneChallengeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
7119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        super(context, attrs, defStyleAttr);
7219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
7319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        final TypedArray a = context.obtainStyledAttributes(attrs,
7419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                R.styleable.MultiPaneChallengeLayout, defStyleAttr, 0);
7519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        mOrientation = a.getInt(R.styleable.MultiPaneChallengeLayout_orientation,
7619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                HORIZONTAL);
7719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        a.recycle();
789d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell
799d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell        final Resources res = getResources();
809d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell        mDisplayMetrics = res.getDisplayMetrics();
81eec4fe2cbe20174ac3b60f0ca90b51271ea98751Adam Powell
82eec4fe2cbe20174ac3b60f0ca90b51271ea98751Adam Powell        setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_STABLE);
8319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    }
8419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
8519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    @Override
8619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    public boolean isChallengeShowing() {
8719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        return true;
8819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    }
8919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
9019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    @Override
9119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    public boolean isChallengeOverlapping() {
9219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        return false;
9319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    }
9419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
9519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    @Override
9619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    public void showChallenge(boolean b) {
9719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    }
9819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
9919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    @Override
10070c2f8736437ebb6073c3b6dab2e08e6dd9f39a6Winson Chung    public int getBouncerAnimationDuration() {
10170c2f8736437ebb6073c3b6dab2e08e6dd9f39a6Winson Chung        return ANIMATE_BOUNCE_DURATION;
10270c2f8736437ebb6073c3b6dab2e08e6dd9f39a6Winson Chung    }
10370c2f8736437ebb6073c3b6dab2e08e6dd9f39a6Winson Chung
10470c2f8736437ebb6073c3b6dab2e08e6dd9f39a6Winson Chung    @Override
10519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    public void showBouncer() {
106eee209313d564be37b8fc068f785b3844cd6597eAdam Powell        if (mIsBouncing) return;
107eee209313d564be37b8fc068f785b3844cd6597eAdam Powell        mIsBouncing = true;
108eee209313d564be37b8fc068f785b3844cd6597eAdam Powell        if (mScrimView != null) {
109c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren            if (mChallengeView != null) {
110c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren                mChallengeView.showBouncer(ANIMATE_BOUNCE_DURATION);
111c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren            }
112c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren
113c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren            Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 1f);
114c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren            anim.setDuration(ANIMATE_BOUNCE_DURATION);
115c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren            anim.addListener(new AnimatorListenerAdapter() {
116c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren                @Override
117c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren                public void onAnimationStart(Animator animation) {
118c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren                    mScrimView.setVisibility(VISIBLE);
119c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren                }
120c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren            });
121c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren            anim.start();
122eee209313d564be37b8fc068f785b3844cd6597eAdam Powell        }
1230b1b552268bc6641cc5d01fb80c12258da9c6985Adam Powell        if (mBouncerListener != null) {
1240b1b552268bc6641cc5d01fb80c12258da9c6985Adam Powell            mBouncerListener.onBouncerStateChanged(true);
1250b1b552268bc6641cc5d01fb80c12258da9c6985Adam Powell        }
126eee209313d564be37b8fc068f785b3844cd6597eAdam Powell    }
127eee209313d564be37b8fc068f785b3844cd6597eAdam Powell
128eee209313d564be37b8fc068f785b3844cd6597eAdam Powell    @Override
129eee209313d564be37b8fc068f785b3844cd6597eAdam Powell    public void hideBouncer() {
130eee209313d564be37b8fc068f785b3844cd6597eAdam Powell        if (!mIsBouncing) return;
131eee209313d564be37b8fc068f785b3844cd6597eAdam Powell        mIsBouncing = false;
132eee209313d564be37b8fc068f785b3844cd6597eAdam Powell        if (mScrimView != null) {
133c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren            if (mChallengeView != null) {
134c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren                mChallengeView.hideBouncer(ANIMATE_BOUNCE_DURATION);
135c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren            }
136c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren
137c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren            Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 0f);
138c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren            anim.setDuration(ANIMATE_BOUNCE_DURATION);
139c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren            anim.addListener(new AnimatorListenerAdapter() {
140c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren                @Override
141c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren                public void onAnimationEnd(Animator animation) {
142c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren                    mScrimView.setVisibility(INVISIBLE);
143c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren                }
144c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren            });
145c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren            anim.start();
146eee209313d564be37b8fc068f785b3844cd6597eAdam Powell        }
1470b1b552268bc6641cc5d01fb80c12258da9c6985Adam Powell        if (mBouncerListener != null) {
1480b1b552268bc6641cc5d01fb80c12258da9c6985Adam Powell            mBouncerListener.onBouncerStateChanged(false);
1490b1b552268bc6641cc5d01fb80c12258da9c6985Adam Powell        }
150eee209313d564be37b8fc068f785b3844cd6597eAdam Powell    }
151eee209313d564be37b8fc068f785b3844cd6597eAdam Powell
152eee209313d564be37b8fc068f785b3844cd6597eAdam Powell    @Override
153eee209313d564be37b8fc068f785b3844cd6597eAdam Powell    public boolean isBouncing() {
154eee209313d564be37b8fc068f785b3844cd6597eAdam Powell        return mIsBouncing;
155eee209313d564be37b8fc068f785b3844cd6597eAdam Powell    }
156eee209313d564be37b8fc068f785b3844cd6597eAdam Powell
1570b1b552268bc6641cc5d01fb80c12258da9c6985Adam Powell    @Override
1580b1b552268bc6641cc5d01fb80c12258da9c6985Adam Powell    public void setOnBouncerStateChangedListener(OnBouncerStateChangedListener listener) {
1590b1b552268bc6641cc5d01fb80c12258da9c6985Adam Powell        mBouncerListener = listener;
1600b1b552268bc6641cc5d01fb80c12258da9c6985Adam Powell    }
1610b1b552268bc6641cc5d01fb80c12258da9c6985Adam Powell
1620b1b552268bc6641cc5d01fb80c12258da9c6985Adam Powell    @Override
1630b1b552268bc6641cc5d01fb80c12258da9c6985Adam Powell    public void requestChildFocus(View child, View focused) {
1640b1b552268bc6641cc5d01fb80c12258da9c6985Adam Powell        if (mIsBouncing && child != mChallengeView) {
1650b1b552268bc6641cc5d01fb80c12258da9c6985Adam Powell            // Clear out of the bouncer if the user tries to move focus outside of
1660b1b552268bc6641cc5d01fb80c12258da9c6985Adam Powell            // the security challenge view.
1670b1b552268bc6641cc5d01fb80c12258da9c6985Adam Powell            hideBouncer();
1680b1b552268bc6641cc5d01fb80c12258da9c6985Adam Powell        }
1690b1b552268bc6641cc5d01fb80c12258da9c6985Adam Powell        super.requestChildFocus(child, focused);
1700b1b552268bc6641cc5d01fb80c12258da9c6985Adam Powell    }
1710b1b552268bc6641cc5d01fb80c12258da9c6985Adam Powell
172eee209313d564be37b8fc068f785b3844cd6597eAdam Powell    void setScrimView(View scrim) {
173eee209313d564be37b8fc068f785b3844cd6597eAdam Powell        if (mScrimView != null) {
174eee209313d564be37b8fc068f785b3844cd6597eAdam Powell            mScrimView.setOnClickListener(null);
175eee209313d564be37b8fc068f785b3844cd6597eAdam Powell        }
176eee209313d564be37b8fc068f785b3844cd6597eAdam Powell        mScrimView = scrim;
177c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren        mScrimView.setAlpha(mIsBouncing ? 1.0f : 0.0f);
178c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren        mScrimView.setVisibility(mIsBouncing ? VISIBLE : INVISIBLE);
179eee209313d564be37b8fc068f785b3844cd6597eAdam Powell        mScrimView.setFocusable(true);
180eee209313d564be37b8fc068f785b3844cd6597eAdam Powell        mScrimView.setOnClickListener(mScrimClickListener);
18119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    }
18219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
1839d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell    private int getVirtualHeight(LayoutParams lp, int height, int heightUsed) {
1849d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell        int virtualHeight = height;
1859d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell        final View root = getRootView();
1869d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell        if (root != null) {
1879d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell            // This calculation is super dodgy and relies on several assumptions.
1889d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell            // Specifically that the root of the window will be padded in for insets
1899d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell            // and that the window is LAYOUT_IN_SCREEN.
1909d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell            virtualHeight = mDisplayMetrics.heightPixels - root.getPaddingTop();
1919d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell        }
1929d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell        if (lp.childType == LayoutParams.CHILD_TYPE_WIDGET ||
1939d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                lp.childType == LayoutParams.CHILD_TYPE_USER_SWITCHER) {
1949d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell            // Always measure the widget pager/user switcher as if there were no IME insets
1959d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell            // on the window. We want to avoid resizing widgets when possible as it can
1969d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell            // be ugly/expensive. This lets us simply clip them instead.
1979d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell            return virtualHeight - heightUsed;
198c065a5d7271c6683b64578490ccc836c72d3ed78Winson Chung        } else if (lp.childType == LayoutParams.CHILD_TYPE_PAGE_DELETE_DROP_TARGET) {
199c065a5d7271c6683b64578490ccc836c72d3ed78Winson Chung            return height;
2009d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell        }
2019d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell        return Math.min(virtualHeight - heightUsed, height);
2029d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell    }
2039d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell
20419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    @Override
2059d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell    protected void onMeasure(final int widthSpec, final int heightSpec) {
20619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        if (MeasureSpec.getMode(widthSpec) != MeasureSpec.EXACTLY ||
20719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                MeasureSpec.getMode(heightSpec) != MeasureSpec.EXACTLY) {
20819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            throw new IllegalArgumentException(
20919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                    "MultiPaneChallengeLayout must be measured with an exact size");
21019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        }
21119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
21219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        final int width = MeasureSpec.getSize(widthSpec);
21319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        final int height = MeasureSpec.getSize(heightSpec);
21419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        setMeasuredDimension(width, height);
21519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
21619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        int widthUsed = 0;
21719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        int heightUsed = 0;
21819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
21919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        // First pass. Find the challenge view and measure the user switcher,
22019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        // which consumes space in the layout.
22119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        mChallengeView = null;
22219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        mUserSwitcherView = null;
22319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        final int count = getChildCount();
22419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        for (int i = 0; i < count; i++) {
22519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            final View child = getChildAt(i);
22619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
22719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
22819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            if (lp.childType == LayoutParams.CHILD_TYPE_CHALLENGE) {
22919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                if (mChallengeView != null) {
23019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                    throw new IllegalStateException(
23119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                            "There may only be one child of type challenge");
23219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                }
233c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren                if (!(child instanceof KeyguardSecurityContainer)) {
234c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren                    throw new IllegalArgumentException(
235c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren                            "Challenge must be a KeyguardSecurityContainer");
236c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren                }
237c345146a3a321644f653fce0fb79f288a0221fb0Chris Wren                mChallengeView = (KeyguardSecurityContainer) child;
23819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            } else if (lp.childType == LayoutParams.CHILD_TYPE_USER_SWITCHER) {
23919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                if (mUserSwitcherView != null) {
24019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                    throw new IllegalStateException(
24119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                            "There may only be one child of type userSwitcher");
24219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                }
24319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                mUserSwitcherView = child;
24419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
24519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                if (child.getVisibility() == GONE) continue;
2469d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell
2479d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                int adjustedWidthSpec = widthSpec;
2489d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                int adjustedHeightSpec = heightSpec;
2499d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                if (lp.maxWidth >= 0) {
2509d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                    adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
2519d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                            Math.min(lp.maxWidth, width), MeasureSpec.EXACTLY);
2529d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                }
2539d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                if (lp.maxHeight >= 0) {
2549d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                    adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
2559d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                            Math.min(lp.maxHeight, height), MeasureSpec.EXACTLY);
2569d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                }
2579d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                // measureChildWithMargins will resolve layout direction for the LayoutParams
2589d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                measureChildWithMargins(child, adjustedWidthSpec, 0, adjustedHeightSpec, 0);
2599d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell
2609d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                // Only subtract out space from one dimension. Favor vertical.
2619d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                // Offset by 1.5x to add some balance along the other edge.
2629d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                if (Gravity.isVertical(lp.gravity)) {
2639d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                    heightUsed += child.getMeasuredHeight() * 1.5f;
2649d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                } else if (Gravity.isHorizontal(lp.gravity)) {
2659d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                    widthUsed += child.getMeasuredWidth() * 1.5f;
26619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                }
267eee209313d564be37b8fc068f785b3844cd6597eAdam Powell            } else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
268eee209313d564be37b8fc068f785b3844cd6597eAdam Powell                setScrimView(child);
269eee209313d564be37b8fc068f785b3844cd6597eAdam Powell                child.measure(widthSpec, heightSpec);
27019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            }
27119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        }
27219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
27319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        // Second pass. Measure everything that's left.
27419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        for (int i = 0; i < count; i++) {
27519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            final View child = getChildAt(i);
27619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
27719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
27819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            if (lp.childType == LayoutParams.CHILD_TYPE_USER_SWITCHER ||
279eee209313d564be37b8fc068f785b3844cd6597eAdam Powell                    lp.childType == LayoutParams.CHILD_TYPE_SCRIM ||
28019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                    child.getVisibility() == GONE) {
28119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                // Don't need to measure GONE children, and the user switcher was already measured.
28219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                continue;
28319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            }
28419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
2859d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell            final int virtualHeight = getVirtualHeight(lp, height, heightUsed);
2869d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell
28719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            int adjustedWidthSpec;
28819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            int adjustedHeightSpec;
28919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            if (lp.centerWithinArea > 0) {
29019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                if (mOrientation == HORIZONTAL) {
29119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                    adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
2920a27c4865e5f3afe891680f687ac75c6a659fb84Adam Powell                            (int) ((width - widthUsed) * lp.centerWithinArea + 0.5f),
2930a27c4865e5f3afe891680f687ac75c6a659fb84Adam Powell                            MeasureSpec.EXACTLY);
2940a27c4865e5f3afe891680f687ac75c6a659fb84Adam Powell                    adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
2959d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                            virtualHeight, MeasureSpec.EXACTLY);
29619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                } else {
2970a27c4865e5f3afe891680f687ac75c6a659fb84Adam Powell                    adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
2989d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                            width - widthUsed, MeasureSpec.EXACTLY);
29919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                    adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
3009d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                            (int) (virtualHeight * lp.centerWithinArea + 0.5f),
3010a27c4865e5f3afe891680f687ac75c6a659fb84Adam Powell                            MeasureSpec.EXACTLY);
30219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                }
30319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            } else {
3040a27c4865e5f3afe891680f687ac75c6a659fb84Adam Powell                adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
3059d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                        width - widthUsed, MeasureSpec.EXACTLY);
3060a27c4865e5f3afe891680f687ac75c6a659fb84Adam Powell                adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
3079d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                        virtualHeight, MeasureSpec.EXACTLY);
30819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            }
30919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            if (lp.maxWidth >= 0) {
31019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
3110a27c4865e5f3afe891680f687ac75c6a659fb84Adam Powell                        Math.min(lp.maxWidth, MeasureSpec.getSize(adjustedWidthSpec)),
31219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                        MeasureSpec.EXACTLY);
31319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            }
31419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            if (lp.maxHeight >= 0) {
31519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
3160a27c4865e5f3afe891680f687ac75c6a659fb84Adam Powell                        Math.min(lp.maxHeight, MeasureSpec.getSize(adjustedHeightSpec)),
31719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                        MeasureSpec.EXACTLY);
31819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            }
31919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
3200a27c4865e5f3afe891680f687ac75c6a659fb84Adam Powell            measureChildWithMargins(child, adjustedWidthSpec, 0, adjustedHeightSpec, 0);
32119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        }
32219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    }
32319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
32419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    @Override
32519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    protected void onLayout(boolean changed, int l, int t, int r, int b) {
32619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        final Rect padding = mTempRect;
32719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        padding.left = getPaddingLeft();
32819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        padding.top = getPaddingTop();
32919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        padding.right = getPaddingRight();
33019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        padding.bottom = getPaddingBottom();
33119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        final int width = r - l;
33219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        final int height = b - t;
33319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
33419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        // Reserve extra space in layout for the user switcher by modifying
33519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        // local padding during this layout pass
33619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        if (mUserSwitcherView != null && mUserSwitcherView.getVisibility() != GONE) {
33719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            layoutWithGravity(width, height, mUserSwitcherView, padding, true);
33819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        }
33919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
34019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        final int count = getChildCount();
34119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        for (int i = 0; i < count; i++) {
34219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            final View child = getChildAt(i);
343c065a5d7271c6683b64578490ccc836c72d3ed78Winson Chung            LayoutParams lp = (LayoutParams) child.getLayoutParams();
34419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
34519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            // We did the user switcher above if we have one.
34619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            if (child == mUserSwitcherView || child.getVisibility() == GONE) continue;
34719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
348eee209313d564be37b8fc068f785b3844cd6597eAdam Powell            if (child == mScrimView) {
349eee209313d564be37b8fc068f785b3844cd6597eAdam Powell                child.layout(0, 0, width, height);
350eee209313d564be37b8fc068f785b3844cd6597eAdam Powell                continue;
351c065a5d7271c6683b64578490ccc836c72d3ed78Winson Chung            } else if (lp.childType == LayoutParams.CHILD_TYPE_PAGE_DELETE_DROP_TARGET) {
352c065a5d7271c6683b64578490ccc836c72d3ed78Winson Chung                layoutWithGravity(width, height, child, mZeroPadding, false);
353c065a5d7271c6683b64578490ccc836c72d3ed78Winson Chung                continue;
354eee209313d564be37b8fc068f785b3844cd6597eAdam Powell            }
355eee209313d564be37b8fc068f785b3844cd6597eAdam Powell
35619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            layoutWithGravity(width, height, child, padding, false);
35719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        }
35819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    }
35919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
36019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    private void layoutWithGravity(int width, int height, View child, Rect padding,
36119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            boolean adjustPadding) {
36219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
36319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
3649d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell        final int heightUsed = padding.top + padding.bottom - getPaddingTop() - getPaddingBottom();
3659d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell        height = getVirtualHeight(lp, height, heightUsed);
3669d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell
36719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        final int gravity = Gravity.getAbsoluteGravity(lp.gravity, getLayoutDirection());
36819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
36919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        final boolean fixedLayoutSize = lp.centerWithinArea > 0;
37019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        final boolean fixedLayoutHorizontal = fixedLayoutSize && mOrientation == HORIZONTAL;
37119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        final boolean fixedLayoutVertical = fixedLayoutSize && mOrientation == VERTICAL;
37219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
37319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        final int adjustedWidth;
37419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        final int adjustedHeight;
37519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        if (fixedLayoutHorizontal) {
376c0657fb36ce5ede652e8af084e484d07abfb449dAdam Powell            final int paddedWidth = width - padding.left - padding.right;
377c0657fb36ce5ede652e8af084e484d07abfb449dAdam Powell            adjustedWidth = (int) (paddedWidth * lp.centerWithinArea + 0.5f);
37819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            adjustedHeight = height;
37919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        } else if (fixedLayoutVertical) {
380eeb6255056b5b0b45026db040edf1136662e847cAdam Powell            final int paddedHeight = height - getPaddingTop() - getPaddingBottom();
38119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            adjustedWidth = width;
382c0657fb36ce5ede652e8af084e484d07abfb449dAdam Powell            adjustedHeight = (int) (paddedHeight * lp.centerWithinArea + 0.5f);
38319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        } else {
38419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            adjustedWidth = width;
38519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            adjustedHeight = height;
38619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        }
38719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
38819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        final boolean isVertical = Gravity.isVertical(gravity);
38919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        final boolean isHorizontal = Gravity.isHorizontal(gravity);
39019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        final int childWidth = child.getMeasuredWidth();
39119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        final int childHeight = child.getMeasuredHeight();
39219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
39319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        int left = padding.left;
39419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        int top = padding.top;
39519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        int right = left + childWidth;
39619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        int bottom = top + childHeight;
39719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) {
39819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            case Gravity.TOP:
39919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                top = fixedLayoutVertical ?
40019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                        padding.top + (adjustedHeight - childHeight) / 2 : padding.top;
40119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                bottom = top + childHeight;
402c0657fb36ce5ede652e8af084e484d07abfb449dAdam Powell                if (adjustPadding && isVertical) {
403c0657fb36ce5ede652e8af084e484d07abfb449dAdam Powell                    padding.top = bottom;
404c0657fb36ce5ede652e8af084e484d07abfb449dAdam Powell                    padding.bottom += childHeight / 2;
405c0657fb36ce5ede652e8af084e484d07abfb449dAdam Powell                }
40619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                break;
40719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            case Gravity.BOTTOM:
40819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                bottom = fixedLayoutVertical
4099799714f6c69efe50e21a6073b879140e5e792b7Adam Powell                        ? padding.top + height - (adjustedHeight - childHeight) / 2
4109799714f6c69efe50e21a6073b879140e5e792b7Adam Powell                        : padding.top + height;
41119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                top = bottom - childHeight;
412c0657fb36ce5ede652e8af084e484d07abfb449dAdam Powell                if (adjustPadding && isVertical) {
413c0657fb36ce5ede652e8af084e484d07abfb449dAdam Powell                    padding.bottom = height - top;
414c0657fb36ce5ede652e8af084e484d07abfb449dAdam Powell                    padding.top += childHeight / 2;
415c0657fb36ce5ede652e8af084e484d07abfb449dAdam Powell                }
41619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                break;
41719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            case Gravity.CENTER_VERTICAL:
4189d34f9db81311a931ae4016161e1c927dd2a69d1Adam Powell                top = padding.top + (height - childHeight) / 2;
41919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                bottom = top + childHeight;
42019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                break;
42119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        }
42219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
42319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            case Gravity.LEFT:
42419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                left = fixedLayoutHorizontal ?
42519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                        padding.left + (adjustedWidth - childWidth) / 2 : padding.left;
42619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                right = left + childWidth;
427c0657fb36ce5ede652e8af084e484d07abfb449dAdam Powell                if (adjustPadding && isHorizontal && !isVertical) {
428c0657fb36ce5ede652e8af084e484d07abfb449dAdam Powell                    padding.left = right;
429c0657fb36ce5ede652e8af084e484d07abfb449dAdam Powell                    padding.right += childWidth / 2;
430c0657fb36ce5ede652e8af084e484d07abfb449dAdam Powell                }
43119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                break;
43219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            case Gravity.RIGHT:
43319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                right = fixedLayoutHorizontal
43419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                        ? width - padding.right - (adjustedWidth - childWidth) / 2
43519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                        : width - padding.right;
43619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                left = right - childWidth;
437c0657fb36ce5ede652e8af084e484d07abfb449dAdam Powell                if (adjustPadding && isHorizontal && !isVertical) {
438c0657fb36ce5ede652e8af084e484d07abfb449dAdam Powell                    padding.right = width - left;
439c0657fb36ce5ede652e8af084e484d07abfb449dAdam Powell                    padding.left += childWidth / 2;
440c0657fb36ce5ede652e8af084e484d07abfb449dAdam Powell                }
44119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                break;
44219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            case Gravity.CENTER_HORIZONTAL:
443c0657fb36ce5ede652e8af084e484d07abfb449dAdam Powell                final int paddedWidth = width - padding.left - padding.right;
444c0657fb36ce5ede652e8af084e484d07abfb449dAdam Powell                left = (paddedWidth - childWidth) / 2;
44519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                right = left + childWidth;
44619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                break;
44719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        }
44819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        child.layout(left, top, right, bottom);
44919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    }
45019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
45119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    @Override
45219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
45319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        return new LayoutParams(getContext(), attrs, this);
45419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    }
45519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
45619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    @Override
45719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
45819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        return p instanceof LayoutParams ? new LayoutParams((LayoutParams) p) :
45919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                p instanceof MarginLayoutParams ? new LayoutParams((MarginLayoutParams) p) :
46019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                new LayoutParams(p);
46119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    }
46219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
46319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    @Override
46419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
46519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        return new LayoutParams();
46619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    }
46719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
46819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    @Override
46919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
47019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        return p instanceof LayoutParams;
47119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    }
47219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
47319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    public static class LayoutParams extends MarginLayoutParams {
47419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
47519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        public float centerWithinArea = 0;
47619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
47719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        public int childType = 0;
47819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
47919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        public static final int CHILD_TYPE_NONE = 0;
48019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        public static final int CHILD_TYPE_WIDGET = 1;
48119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        public static final int CHILD_TYPE_CHALLENGE = 2;
48219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        public static final int CHILD_TYPE_USER_SWITCHER = 3;
483eee209313d564be37b8fc068f785b3844cd6597eAdam Powell        public static final int CHILD_TYPE_SCRIM = 4;
484c065a5d7271c6683b64578490ccc836c72d3ed78Winson Chung        public static final int CHILD_TYPE_PAGE_DELETE_DROP_TARGET = 7;
48519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
48619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        public int gravity = Gravity.NO_GRAVITY;
48719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
48819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        public int maxWidth = -1;
48919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        public int maxHeight = -1;
49019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
49119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        public LayoutParams() {
49219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            this(WRAP_CONTENT, WRAP_CONTENT);
49319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        }
49419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
49519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        LayoutParams(Context c, AttributeSet attrs, MultiPaneChallengeLayout parent) {
49619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            super(c, attrs);
49719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
49819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            final TypedArray a = c.obtainStyledAttributes(attrs,
49919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                    R.styleable.MultiPaneChallengeLayout_Layout);
50019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
50119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            centerWithinArea = a.getFloat(
50219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                    R.styleable.MultiPaneChallengeLayout_Layout_layout_centerWithinArea, 0);
50319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            childType = a.getInt(R.styleable.MultiPaneChallengeLayout_Layout_layout_childType,
50419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                    CHILD_TYPE_NONE);
50519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            gravity = a.getInt(R.styleable.MultiPaneChallengeLayout_Layout_layout_gravity,
50619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                    Gravity.NO_GRAVITY);
50719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            maxWidth = a.getDimensionPixelSize(
50819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                    R.styleable.MultiPaneChallengeLayout_Layout_layout_maxWidth, -1);
50919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            maxHeight = a.getDimensionPixelSize(
51019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                    R.styleable.MultiPaneChallengeLayout_Layout_layout_maxHeight, -1);
51119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
51219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            // Default gravity settings based on type and parent orientation
51319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            if (gravity == Gravity.NO_GRAVITY) {
51419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                if (parent.mOrientation == HORIZONTAL) {
51519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                    switch (childType) {
51619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                        case CHILD_TYPE_WIDGET:
51719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                            gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
51819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                            break;
51919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                        case CHILD_TYPE_CHALLENGE:
52019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                            gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL;
52119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                            break;
52219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                        case CHILD_TYPE_USER_SWITCHER:
52319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                            gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
52419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                            break;
52519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                    }
52619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                } else {
52719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                    switch (childType) {
52819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                        case CHILD_TYPE_WIDGET:
52919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                            gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
53019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                            break;
53119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                        case CHILD_TYPE_CHALLENGE:
53219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                            gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
53319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                            break;
53419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                        case CHILD_TYPE_USER_SWITCHER:
53519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                            gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
53619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                            break;
53719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                    }
53819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller                }
53919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            }
54019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
54119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            a.recycle();
54219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        }
54319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
54419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        public LayoutParams(int width, int height) {
54519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            super(width, height);
54619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        }
54719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
54819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        public LayoutParams(ViewGroup.LayoutParams source) {
54919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            super(source);
55019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        }
55119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
55219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        public LayoutParams(MarginLayoutParams source) {
55319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            super(source);
55419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        }
55519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
55619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        public LayoutParams(LayoutParams source) {
55719a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            this((MarginLayoutParams) source);
55819a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller
55919a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            centerWithinArea = source.centerWithinArea;
56019a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            childType = source.childType;
56119a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            gravity = source.gravity;
56219a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            maxWidth = source.maxWidth;
56319a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller            maxHeight = source.maxHeight;
56419a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller        }
56519a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller    }
56619a5267003e7dc70100a4bd4f1f449523b2ff38bJim Miller}
567