14143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar/*
24143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * Copyright (C) 2016 The Android Open Source Project
34143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar *
44143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
54143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * you may not use this file except in compliance with the License.
64143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * You may obtain a copy of the License at
74143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar *
84143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
94143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar *
104143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * Unless required by applicable law or agreed to in writing, software
114143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
124143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * See the License for the specific language governing permissions and
144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar * limitations under the License.
154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar */
164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarpackage android.support.v7.widget;
174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport org.hamcrest.BaseMatcher;
194143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport org.hamcrest.Description;
204143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
214143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.content.Context;
224143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.graphics.Color;
234143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.support.v4.util.Pair;
244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.util.AttributeSet;
254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.view.View;
264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport android.view.ViewGroup;
274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport java.util.ArrayList;
294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport java.util.Collections;
304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport java.util.List;
314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport java.util.concurrent.atomic.AtomicLong;
324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport static android.support.v7.widget.LinearLayoutManager.HORIZONTAL;
344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarimport static android.support.v7.widget.LinearLayoutManager.VERTICAL;
354143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
364143554adb9b31b700b6876a251a64419e6111e2Yigit Boyarabstract public class BaseWrapContentWithAspectRatioTest extends BaseRecyclerViewInstrumentationTest {
374143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    final BaseWrapContentTest.WrapContentConfig mWrapContentConfig;
384143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    protected BaseWrapContentWithAspectRatioTest(
404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            BaseWrapContentTest.WrapContentConfig wrapContentConfig) {
414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        mWrapContentConfig = wrapContentConfig;
424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    int getSize(View view, int orientation) {
454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        if (orientation == VERTICAL) {
464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return view.getHeight();
474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        return view.getWidth();
494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    static class LoggingView extends View {
524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
534143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        MeasureBehavior mBehavior;
544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public void setBehavior(MeasureBehavior behavior) {
564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            mBehavior = behavior;
574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public LoggingView(Context context) {
604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            super(context);
614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public LoggingView(Context context, AttributeSet attrs) {
644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            super(context, attrs);
654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public LoggingView(Context context, AttributeSet attrs, int defStyleAttr) {
684143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            super(context, attrs, defStyleAttr);
694143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
704143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
714143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public LoggingView(Context context, AttributeSet attrs, int defStyleAttr,
724143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                int defStyleRes) {
734143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            super(context, attrs, defStyleAttr, defStyleRes);
744143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
754143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
764143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        @Override
774143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
784143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            mBehavior.onMeasure(this, widthMeasureSpec, heightMeasureSpec);
794143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
804143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
814143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        @Override
824143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
834143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            super.onLayout(changed, left, top, right, bottom);
844143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            mBehavior.onLayout(changed, left, top, right, bottom);
854143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
864143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
874143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public void setMeasured(int w, int h) {
884143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            setMeasuredDimension(w, h);
894143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
904143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
914143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public void prepareLayoutParams() {
924143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            mBehavior.setLayoutParams(this);
934143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
944143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
954143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
964143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    static class AspectRatioMeasureBehavior extends MeasureBehavior {
974143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
984143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        Float ratio;
994143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        int control;
1004143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1014143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public AspectRatioMeasureBehavior(int desiredW, int desiredH, int wMode, int hMode) {
1024143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            super(desiredW, desiredH, wMode, hMode);
1034143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
1044143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1054143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public AspectRatioMeasureBehavior aspectRatio(int control, float ratio) {
1064143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            this.control = control;
1074143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            this.ratio = ratio;
1084143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return this;
1094143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
1104143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1114143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        @Override
1124143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public void onMeasure(LoggingView view, int wSpec,
1134143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                int hSpec) {
1144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            super.onMeasure(view, wSpec, hSpec);
1154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (control == VERTICAL) {
1164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                view.setMeasured(getSecondary(view.getMeasuredHeight()),
1174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        view.getMeasuredHeight());
1184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            } else if (control == HORIZONTAL) {
1194143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                view.setMeasured(view.getMeasuredWidth(),
1204143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        getSecondary(view.getMeasuredWidth()));
1214143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
1224143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
1234143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public int getSecondary(int controlSize) {
1254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return (int) (controlSize * ratio);
1264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
1274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
1284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    static class MeasureBehavior {
1304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        private static final AtomicLong idCounter = new AtomicLong(0);
1314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public List<Pair<Integer, Integer>> measureSpecs = new ArrayList<>();
1324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public List<Pair<Integer, Integer>> layouts = new ArrayList<>();
1334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        int desiredW, desiredH;
1344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        final long mId = idCounter.incrementAndGet();
1354143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
136de8a5de43b647f9b61f4859a22a0ce59155f442aYigit Boyar        ViewGroup.MarginLayoutParams layoutParams;
1374143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1384143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public MeasureBehavior(int desiredW, int desiredH, int wMode, int hMode) {
1394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            this.desiredW = desiredW;
1404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            this.desiredH = desiredH;
141de8a5de43b647f9b61f4859a22a0ce59155f442aYigit Boyar            layoutParams = new ViewGroup.MarginLayoutParams(
1424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    wMode, hMode
1434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            );
1444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
1454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
146de8a5de43b647f9b61f4859a22a0ce59155f442aYigit Boyar        public MeasureBehavior withMargins(int left, int top, int right, int bottom) {
147de8a5de43b647f9b61f4859a22a0ce59155f442aYigit Boyar            layoutParams.leftMargin = left;
148de8a5de43b647f9b61f4859a22a0ce59155f442aYigit Boyar            layoutParams.topMargin = top;
149de8a5de43b647f9b61f4859a22a0ce59155f442aYigit Boyar            layoutParams.rightMargin = right;
150de8a5de43b647f9b61f4859a22a0ce59155f442aYigit Boyar            layoutParams.bottomMargin = bottom;
151de8a5de43b647f9b61f4859a22a0ce59155f442aYigit Boyar            return this;
152de8a5de43b647f9b61f4859a22a0ce59155f442aYigit Boyar        }
153de8a5de43b647f9b61f4859a22a0ce59155f442aYigit Boyar
1544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public long getId() {
1554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return mId;
1564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
1574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public void onMeasure(LoggingView view, int wSpec, int hSpec) {
1594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            measureSpecs.add(new Pair<>(wSpec, hSpec));
1604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            view.setMeasured(
1614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    RecyclerView.LayoutManager.chooseSize(wSpec, desiredW, 0),
1624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    RecyclerView.LayoutManager.chooseSize(hSpec, desiredH, 0));
1634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
1644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public int getSpec(int position, int orientation) {
1664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (orientation == VERTICAL) {
1674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                return measureSpecs.get(position).second;
1684143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            } else {
1694143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                return measureSpecs.get(position).first;
1704143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
1714143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
1724143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1734143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public void setLayoutParams(LoggingView view) {
1744143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            view.setLayoutParams(layoutParams);
1754143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
1764143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1774143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public void onLayout(boolean changed, int left, int top, int right, int bottom) {
1784143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (changed) {
1794143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                layouts.add(new Pair<>(right - left, bottom - top));
1804143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
1814143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
1824143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
1834143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1844143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1854143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    static class WrapContentViewHolder extends RecyclerView.ViewHolder {
1864143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1874143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        LoggingView mView;
1884143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1894143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public WrapContentViewHolder(ViewGroup parent) {
1904143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            super(new LoggingView(parent.getContext()));
1914143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            mView = (LoggingView) itemView;
1924143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            mView.setBackgroundColor(Color.GREEN);
1934143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
1944143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
1954143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1964143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    static class WrapContentAdapter extends RecyclerView.Adapter<WrapContentViewHolder> {
1974143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
1984143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        List<MeasureBehavior> behaviors = new ArrayList<>();
1994143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2004143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public WrapContentAdapter(MeasureBehavior... behaviors) {
2014143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            Collections.addAll(this.behaviors, behaviors);
2024143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
2034143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2044143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        @Override
2054143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public WrapContentViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
2064143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return new WrapContentViewHolder(parent);
2074143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
2084143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2094143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        @Override
2104143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public void onBindViewHolder(WrapContentViewHolder holder, int position) {
2114143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            holder.mView.setBehavior(behaviors.get(position));
2124143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            holder.mView.prepareLayoutParams();
2134143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
2144143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2154143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        @Override
2164143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public int getItemCount() {
2174143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return behaviors.size();
2184143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
2194143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
2204143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2214143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    static class MeasureSpecMatcher extends BaseMatcher<Integer> {
2224143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2234143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        private boolean checkSize = false;
2244143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        private boolean checkMode = false;
2254143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        private int mSize;
2264143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        private int mMode;
2274143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2284143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public static MeasureSpecMatcher is(int size, int mode) {
2294143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            MeasureSpecMatcher matcher = new MeasureSpecMatcher(size, mode);
2304143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            matcher.checkSize = true;
2314143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            matcher.checkMode = true;
2324143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return matcher;
2334143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
2344143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2354143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public static MeasureSpecMatcher size(int size) {
2364143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            MeasureSpecMatcher matcher = new MeasureSpecMatcher(size, 0);
2374143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            matcher.checkSize = true;
2384143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            matcher.checkMode = false;
2394143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return matcher;
2404143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
2414143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2424143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public static MeasureSpecMatcher mode(int mode) {
2434143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            MeasureSpecMatcher matcher = new MeasureSpecMatcher(0, mode);
2444143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            matcher.checkSize = false;
2454143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            matcher.checkMode = true;
2464143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return matcher;
2474143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
2484143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2494143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        private MeasureSpecMatcher(int size, int mode) {
2504143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            mSize = size;
2514143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            mMode = mode;
2524143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2534143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
2544143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        @Override
2564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public boolean matches(Object item) {
2574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (item == null) {
2584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                return false;
2594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
2604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            Integer intValue = (Integer) item;
2614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            final int size = View.MeasureSpec.getSize(intValue);
2624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            final int mode = View.MeasureSpec.getMode(intValue);
2634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (checkSize && size != mSize) {
2644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                return false;
2654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
2664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (checkMode && mode != mMode) {
2674143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                return false;
2684143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
2694143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            return true;
2704143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
2714143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2724143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        @Override
2734143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public void describeMismatch(Object item, Description description) {
2744143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            Integer intValue = (Integer) item;
2754143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            final int size = View.MeasureSpec.getSize(intValue);
2764143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            final int mode = View.MeasureSpec.getMode(intValue);
2774143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (checkSize && size != mSize) {
2784143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                description.appendText(" Expected size was ").appendValue(mSize)
2794143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        .appendText(" but received size is ").appendValue(size);
2804143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
2814143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (checkMode && mode != mMode) {
2824143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                description.appendText(" Expected mode was ").appendValue(modeName(mMode))
2834143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                        .appendText(" but received mode is ").appendValue(modeName(mode));
2844143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
2854143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
2864143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2874143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        @Override
2884143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        public void describeTo(Description description) {
2894143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (checkSize) {
2904143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                description.appendText(" Measure spec size:").appendValue(mSize);
2914143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
2924143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            if (checkMode) {
2934143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                description.appendText(" Measure spec mode:").appendValue(modeName(mMode));
2944143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
2954143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
2964143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2974143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        private static String modeName(int mode) {
2984143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            switch (mode) {
2994143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                case View.MeasureSpec.AT_MOST:
3004143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    return "at most";
3014143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                case View.MeasureSpec.EXACTLY:
3024143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    return "exactly";
3034143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                default:
3044143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar                    return "unspecified";
3054143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar            }
3064143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        }
3074143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
3084143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar}
309