GridWidgetTest.java revision db0b1afb71440b79923692d58adee982b5954838
1062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu/*
2062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * Copyright (C) 2015 The Android Open Source Project
3062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu *
4062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * Licensed under the Apache License, Version 2.0 (the "License");
5062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * you may not use this file except in compliance with the License.
6062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * You may obtain a copy of the License at
7062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu *
8062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu *      http://www.apache.org/licenses/LICENSE-2.0
9062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu *
10062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * Unless required by applicable law or agreed to in writing, software
11062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * distributed under the License is distributed on an "AS IS" BASIS,
12062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * See the License for the specific language governing permissions and
14062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * limitations under the License.
15062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu */
16062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gupackage android.support.v17.leanback.widget;
17062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
18247741d74797105ba4f6d2834ec56dab32c14644Dake Guimport android.support.v17.leanback.tests.R;
19062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.test.ActivityInstrumentationTestCase2;
203bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Guimport android.text.Selection;
213bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Guimport android.text.Spannable;
22062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.util.Log;
233bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Guimport android.util.SparseArray;
24062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.view.KeyEvent;
25062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.view.View;
26062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.view.ViewGroup;
27c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Guimport android.widget.TextView;
28062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.app.Instrumentation;
29062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.content.Intent;
303bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Guimport android.os.Parcelable;
31062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
32062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport java.util.ArrayList;
33062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport java.util.Arrays;
34062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport java.util.Comparator;
35062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport java.util.HashMap;
36062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport java.util.Iterator;
37062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
38062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu/**
39062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * @hide from javadoc
40062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu */
41062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gupublic class GridWidgetTest extends ActivityInstrumentationTestCase2<GridActivity> {
42062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
43f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    private static final boolean HUMAN_DELAY = false;
447538845719cd1e588185ce9ae60320377862ef8dDake Gu    private static final long WAIT_FOR_SCROLL_IDLE_TIMEOUT_MS = 60000;
45f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu
46062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    protected GridActivity mActivity;
47062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    protected Instrumentation mInstrumentation;
48062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    protected BaseGridView mGridView;
4985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    protected GridLayoutManager mLayoutManager;
50062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    protected int mOrientation;
51247741d74797105ba4f6d2834ec56dab32c14644Dake Gu    protected int mNumRows;
52062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
53062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    private final Comparator<View> mRowSortComparator = new Comparator<View>() {
54062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        public int compare(View lhs, View rhs) {
55062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            if (mOrientation == BaseGridView.HORIZONTAL) {
56062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu                return lhs.getLeft() - rhs.getLeft();
57062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            } else {
58062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu                return lhs.getTop() - rhs.getTop();
59062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            }
60062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        };
61062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    };
62062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
63062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    /**
64062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu     * Verify margins between items on same row are same.
65062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu     */
66062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    private final Runnable mVerifyLayout = new Runnable() {
67062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        @Override
68062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        public void run() {
69e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            verifyMargin();
70062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        }
71062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    };
72062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
73062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    public GridWidgetTest() {
74062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        super("android.support.v17.leanback.tests", GridActivity.class);
75062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    }
76062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
77f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    private void humanDelay(int delay) throws InterruptedException {
78f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        if (HUMAN_DELAY) Thread.sleep(delay);
79f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    }
80f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    /**
81f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu     * Change size of the Adapter and notifyDataSetChanged.
82f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu     */
83f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    private void changeArraySize(final int size) throws Throwable {
84f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        runTestOnUiThread(new Runnable() {
85f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu            public void run() {
86f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu                mActivity.changeArraySize(size);
87f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu            }
88f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        });
89f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        Thread.sleep(500);
90f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    }
91f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu
92f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    /**
93f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu     * Change selected position.
94f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu     */
95f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    private void setSelectedPosition(final int position, final int scrollExtra) throws Throwable {
96f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        runTestOnUiThread(new Runnable() {
97f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu            public void run() {
98f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu                mGridView.setSelectedPosition(position, scrollExtra);
99f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu            }
100f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        });
101f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        Thread.sleep(500);
102f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    }
103f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu
104062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    /**
105062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu     * Wait for grid view stop scroll and optionally verify state of grid view.
106062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu     */
107062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    protected void waitForScrollIdle(Runnable verify) throws Throwable {
1088c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Thread.sleep(100);
1097538845719cd1e588185ce9ae60320377862ef8dDake Gu        int total = 0;
110062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        while (mGridView.getLayoutManager().isSmoothScrolling() ||
111062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu                mGridView.getScrollState() != BaseGridView.SCROLL_STATE_IDLE) {
1127538845719cd1e588185ce9ae60320377862ef8dDake Gu            if ((total += 100) >= WAIT_FOR_SCROLL_IDLE_TIMEOUT_MS) {
1137538845719cd1e588185ce9ae60320377862ef8dDake Gu                throw new RuntimeException("waitForScrollIdle Timeout");
1147538845719cd1e588185ce9ae60320377862ef8dDake Gu            }
115062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            try {
116062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu                Thread.sleep(100);
117062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            } catch (InterruptedException ex) {
118062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu                break;
119062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            }
120062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            if (verify != null) {
121062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu                runTestOnUiThread(verify);
122062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            }
123062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        }
124062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    }
125062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
126062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    /**
12785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu     * Wait for grid view stop animation and optionally verify state of grid view.
12885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu     */
12985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    protected void waitForTransientStateGone(Runnable verify) throws Throwable {
13085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        do {
13185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            try {
13285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                Thread.sleep(100);
13385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            } catch (InterruptedException ex) {
13485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                break;
13585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            }
13685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            if (verify != null) {
13785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                runTestOnUiThread(verify);
13885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            }
13985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        } while (mGridView.hasTransientState());
14085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    }
14185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
14285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    /**
143062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu     * Wait for grid view stop scroll.
144062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu     */
145062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    protected void waitForScrollIdle() throws Throwable {
146062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        waitForScrollIdle(null);
147062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    }
148062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
149e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    /**
150a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu     * Scrolls using given key.
151a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu     */
152a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu    protected void scroll(int key, Runnable verify) throws Throwable {
153a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        do {
154a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            if (verify != null) {
155a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu                runTestOnUiThread(verify);
156a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            }
157a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            sendRepeatedKeys(10, key);
158a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            try {
1598c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                Thread.sleep(300);
160a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            } catch (InterruptedException ex) {
161a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu                break;
162a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            }
163a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        } while (mGridView.getLayoutManager().isSmoothScrolling() ||
164a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu                mGridView.getScrollState() != BaseGridView.SCROLL_STATE_IDLE);
165a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu    }
166a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu
167a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu    protected void scrollToBegin(Runnable verify) throws Throwable {
168a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        int key;
169a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        if (mOrientation == BaseGridView.HORIZONTAL) {
170a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            if (mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL) {
171a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu                key = KeyEvent.KEYCODE_DPAD_RIGHT;
172a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            } else {
173a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu                key = KeyEvent.KEYCODE_DPAD_LEFT;
174a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            }
175a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        } else {
176a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            key = KeyEvent.KEYCODE_DPAD_UP;
177a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        }
178a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scroll(key, verify);
179a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu    }
180a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu
181a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu    protected void scrollToEnd(Runnable verify) throws Throwable {
182a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        int key;
183a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        if (mOrientation == BaseGridView.HORIZONTAL) {
184a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            if (mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL) {
185a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu                key = KeyEvent.KEYCODE_DPAD_LEFT;
186a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            } else {
187a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu                key = KeyEvent.KEYCODE_DPAD_RIGHT;
188a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            }
189a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        } else {
190a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            key = KeyEvent.KEYCODE_DPAD_DOWN;
191a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        }
192a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scroll(key, verify);
193a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu    }
194a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu
195a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu    /**
196e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu     * Group and sort children by their position on each row (HORIZONTAL) or column(VERTICAL).
197e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu     */
198e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    protected View[][] sortByRows() {
199e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        final HashMap<Integer, ArrayList<View>> rows = new HashMap<Integer, ArrayList<View>>();
200c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        ArrayList<Integer> rowLocations = new ArrayList();
201e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        for (int i = 0; i < mGridView.getChildCount(); i++) {
202e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            View v = mGridView.getChildAt(i);
203e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            int rowLocation;
204e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            if (mOrientation == BaseGridView.HORIZONTAL) {
205e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                rowLocation = v.getTop();
206e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            } else {
207e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                rowLocation = mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL ?
208e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    v.getRight() : v.getLeft();
209e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            }
210e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            ArrayList<View> views = rows.get(rowLocation);
211e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            if (views == null) {
212e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                views = new ArrayList<View>();
213e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                rows.put(rowLocation, views);
214c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                rowLocations.add(rowLocation);
215e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            }
216e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            views.add(v);
217e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        }
218c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        Object[] sortedLocations = rowLocations.toArray();
219c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        Arrays.sort(sortedLocations);
220c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        if (mNumRows != rows.size()) {
221c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            assertEquals("Dump Views by rows "+rows, mNumRows, rows.size());
222c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        }
223e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        View[][] sorted = new View[rows.size()][];
224c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        for (int i = 0; i < rowLocations.size(); i++) {
225c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            Integer rowLocation = rowLocations.get(i);
226c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            ArrayList<View> arr = rows.get(rowLocation);
227e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            View[] views = arr.toArray(new View[arr.size()]);
228e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            Arrays.sort(views, mRowSortComparator);
229c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            sorted[i] = views;
230e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        }
231e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        return sorted;
232e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    }
233e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
234e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    protected void verifyMargin() {
235e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        View[][] sorted = sortByRows();
236e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        for (int row = 0; row < sorted.length; row++) {
237e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            View[] views = sorted[row];
238e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            int margin = -1;
239e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            for (int i = 1; i < views.length; i++) {
240e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                if (mOrientation == BaseGridView.HORIZONTAL) {
241492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                    assertEquals(mGridView.getHorizontalMargin(),
242492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                            views[i].getLeft() - views[i - 1].getRight());
243e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                } else {
244492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                    assertEquals(mGridView.getVerticalMargin(),
245492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                            views[i].getTop() - views[i - 1].getBottom());
246e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                }
247e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            }
248e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        }
249e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    }
250e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
251e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    protected void verifyBeginAligned() {
252e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        View[][] sorted = sortByRows();
253e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        int alignedLocation = 0;
254e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        if (mOrientation == BaseGridView.HORIZONTAL) {
255e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            if (mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL) {
256e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                for (int i = 0; i < sorted.length; i++) {
257e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    if (i == 0) {
258e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                        alignedLocation = sorted[i][sorted[i].length - 1].getRight();
259e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    } else {
260e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                        assertEquals(alignedLocation, sorted[i][sorted[i].length - 1].getRight());
261e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    }
262e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                }
263e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            } else {
264e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                for (int i = 0; i < sorted.length; i++) {
265e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    if (i == 0) {
266e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                        alignedLocation = sorted[i][0].getLeft();
267e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    } else {
268e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                        assertEquals(alignedLocation, sorted[i][0].getLeft());
269e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    }
270e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                }
271e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            }
272e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        } else {
273e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            for (int i = 0; i < sorted.length; i++) {
274e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                if (i == 0) {
275e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    alignedLocation = sorted[i][0].getTop();
276e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                } else {
277e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    assertEquals(alignedLocation, sorted[i][0].getTop());
278e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                }
279e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            }
280e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        }
281e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    }
282e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
283c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu    protected int[] getEndEdges() {
284c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        View[][] sorted = sortByRows();
285c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        int[] edges = new int[sorted.length];
286c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        if (mOrientation == BaseGridView.HORIZONTAL) {
287c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            if (mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL) {
288c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                for (int i = 0; i < sorted.length; i++) {
289c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                    edges[i] = sorted[i][0].getLeft();
290c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                }
291c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            } else {
292c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                for (int i = 0; i < sorted.length; i++) {
293c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                    edges[i] = sorted[i][sorted[i].length - 1].getRight();
294c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                }
295c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            }
296c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        } else {
297c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            for (int i = 0; i < sorted.length; i++) {
298c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                edges[i] = sorted[i][sorted[i].length - 1].getBottom();
299c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            }
300c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        }
301c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        return edges;
302c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu    }
303c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
304c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu    protected void verifyEdgesSame(int[] edges, int[] edges2) {
305c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        assertEquals(edges.length, edges2.length);
306c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        for (int i = 0; i < edges.length; i++) {
307c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            assertEquals(edges[i], edges2[i]);
308c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        }
309c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu    }
310c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
31185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    protected void verifyBoundCount(int count) {
31285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        if (mActivity.getBoundCount() != count) {
31385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            StringBuffer b = new StringBuffer();
31485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            b.append("ItemsLength: ");
31585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            for (int i = 0; i < mActivity.mItemLengths.length; i++) {
31685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                b.append(mActivity.mItemLengths[i]).append(",");
31785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            }
31885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            assertEquals("Bound count does not match, ItemsLengths: "+ b,
31985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                    count, mActivity.getBoundCount());
32085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        }
32185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    }
32285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
3238c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    private static int getCenterY(View v) {
3248c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        return (v.getTop() + v.getBottom())/2;
3258c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    }
326062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
3278c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    private static int getCenterX(View v) {
3288c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        return (v.getLeft() + v.getRight())/2;
3298c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    }
3308c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
3318c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    private void initActivity(Intent intent) {
3328c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        setActivityIntent(intent);
3338c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mActivity = getActivity();
3348c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final String testName = getName();
3358c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        try {
3368c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            runTestOnUiThread(new Runnable() {
3378c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                public void run() {
3388c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                    mActivity.setTitle(testName);
3398c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                }
3408c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            });
3418c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            Thread.sleep(1000);
3428c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        } catch (Throwable t) {
3438c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            t.printStackTrace();
3448c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        }
3458c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mGridView = mActivity.mGridView;
3468c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    }
3478c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
3488c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    public void testThreeRowHorizontalBasic() throws Throwable {
349062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        mInstrumentation = getInstrumentation();
350062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
351247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.horizontal_grid);
352e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 100);
3538c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
354247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
355247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mNumRows = 3;
356062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
357a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
35885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBoundCount(100);
359e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
360a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToBegin(mVerifyLayout);
361062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
362e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        verifyBeginAligned();
363062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    }
364062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
365e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    public void testThreeColumnVerticalBasic() throws Throwable {
366e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
367e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        mInstrumentation = getInstrumentation();
368e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
369247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.vertical_grid);
370e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 200);
3718c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
372247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mOrientation = BaseGridView.VERTICAL;
373247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mNumRows = 3;
374e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
375a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
37685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBoundCount(200);
377e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
378a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToBegin(mVerifyLayout);
37985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
38085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBeginAligned();
38185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    }
38285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
38385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    public void testRedundantAppendRemove() throws Throwable {
38485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mInstrumentation = getInstrumentation();
38585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
386247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
387247741d74797105ba4f6d2834ec56dab32c14644Dake Gu                R.layout.vertical_grid_testredundantappendremove);
38885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, new int[]{
38985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                149,177,128,234,227,187,163,223,146,210,228,148,227,193,182,197,177,142,225,207,
39085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                157,171,209,204,187,184,123,221,197,153,202,179,193,214,226,173,225,143,188,159,
39185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                139,193,233,143,227,203,222,124,228,223,164,131,228,126,211,160,165,152,235,184,
39285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                155,224,149,181,171,229,200,234,177,130,164,172,188,139,132,203,179,220,147,131,
39385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                226,127,230,239,183,203,206,227,123,170,239,234,200,149,237,204,160,133,202,234,
39485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                173,122,139,149,151,153,216,231,121,145,227,153,186,174,223,180,123,215,206,216,
39585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                239,222,219,207,193,218,140,133,171,153,183,132,233,138,159,174,189,171,143,128,
39685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                152,222,141,202,224,190,134,120,181,231,230,136,132,224,136,210,207,150,128,183,
39785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                221,194,179,220,126,221,137,205,223,193,172,132,226,209,133,191,227,127,159,171,
39885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                180,149,237,177,194,207,170,202,161,144,147,199,205,186,164,140,193,203,224,129});
3998c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
400247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mOrientation = BaseGridView.VERTICAL;
401247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mNumRows = 3;
40285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
403a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
40485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
40585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBoundCount(200);
406e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
407a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToBegin(mVerifyLayout);
408e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
409e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        verifyBeginAligned();
410e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    }
41185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
41285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    public void testRedundantAppendRemove2() throws Throwable {
41385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mInstrumentation = getInstrumentation();
41485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
415247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
416247741d74797105ba4f6d2834ec56dab32c14644Dake Gu                R.layout.horizontal_grid_testredundantappendremove2);
41785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, new int[]{
41885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                318,333,199,224,246,273,269,289,340,313,265,306,349,269,185,282,257,354,316,252,
41985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                237,290,283,343,196,313,290,343,191,262,342,228,343,349,251,203,226,305,265,213,
42085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                216,333,295,188,187,281,288,311,244,232,224,332,290,181,267,276,226,261,335,355,
42185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                225,217,219,183,234,285,257,304,182,250,244,223,257,219,342,185,347,205,302,315,
42285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                299,309,292,237,192,309,228,250,347,227,337,298,299,185,185,331,223,284,265,351});
4238c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
424247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
425247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mNumRows = 3;
42685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mLayoutManager = (GridLayoutManager) mGridView.getLayoutManager();
42785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
42885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        // test append without staggered result cache
429a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
43085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
43185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBoundCount(100);
432c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        int[] endEdges = getEndEdges();
43385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
434a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToBegin(mVerifyLayout);
43585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
43685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBeginAligned();
43785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
43885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        // now test append with staggered result cache
439f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(3);
44085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        assertEquals("Staggerd cache should be kept as is when no item size change",
44185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                100, ((StaggeredGrid) mLayoutManager.mGrid).mLocations.size());
44285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
44385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mActivity.resetBoundCount();
444f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(100);
44585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
446a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
44785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBoundCount(100);
448c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
449c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        // we should get same aligned end edges
450c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        int[] endEdges2 = getEndEdges();
451c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        verifyEdgesSame(endEdges, endEdges2);
45285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    }
45385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
454c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu    public void testItemMovedHorizontal() throws Throwable {
45585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
45685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mInstrumentation = getInstrumentation();
45785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
458247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
459247741d74797105ba4f6d2834ec56dab32c14644Dake Gu                R.layout.horizontal_grid);
46085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 200);
4618c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
462247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
463247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mNumRows = 3;
46485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
46585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mGridView.setSelectedPositionSmooth(150);
46685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        waitForScrollIdle(mVerifyLayout);
46785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mActivity.swap(150, 152);
46885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        waitForTransientStateGone(null);
46985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
47085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        runTestOnUiThread(mVerifyLayout);
47185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
472a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToBegin(mVerifyLayout);
47385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
47485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBeginAligned();
47585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    }
47685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
477c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu    public void testItemMovedVertical() throws Throwable {
478c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
479c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        mInstrumentation = getInstrumentation();
480c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
481c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
482c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                R.layout.vertical_grid);
483c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 200);
4848c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
485c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        mOrientation = BaseGridView.VERTICAL;
486c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        mNumRows = 3;
487c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
488c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        mGridView.setSelectedPositionSmooth(150);
489c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        waitForScrollIdle(mVerifyLayout);
490c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        mActivity.swap(150, 152);
491c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        waitForTransientStateGone(null);
492c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
493c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        runTestOnUiThread(mVerifyLayout);
494c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
4957ee22537e201c3d6b5de2908aecc4b0cc59a05c2Dake Gu        scrollToEnd(mVerifyLayout);
496a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToBegin(mVerifyLayout);
497c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
498c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        verifyBeginAligned();
499c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu    }
500c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
501ede7fd3c91008fb042c736240534d0d87234f112Dake Gu    public void testItemAddRemoveHorizontal() throws Throwable {
502ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
503ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        mInstrumentation = getInstrumentation();
504ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
505ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
506ede7fd3c91008fb042c736240534d0d87234f112Dake Gu                R.layout.horizontal_grid);
507ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 200);
5088c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
509ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
510ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        mNumRows = 3;
511ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
512a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
513ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        int[] endEdges = getEndEdges();
514ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
515ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        mGridView.setSelectedPositionSmooth(150);
516ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        waitForScrollIdle(mVerifyLayout);
517ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        int[] removedItems = mActivity.removeItems(151, 4);
518ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        waitForTransientStateGone(null);
519ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
520a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
521ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        mGridView.setSelectedPositionSmooth(150);
522ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        waitForScrollIdle(mVerifyLayout);
523ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
524ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        mActivity.addItems(151, removedItems);
525ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        waitForTransientStateGone(null);
526a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
527ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
528ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        // we should get same aligned end edges
529ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        int[] endEdges2 = getEndEdges();
530ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        verifyEdgesSame(endEdges, endEdges2);
531ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
532a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToBegin(mVerifyLayout);
533ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        verifyBeginAligned();
534ede7fd3c91008fb042c736240534d0d87234f112Dake Gu    }
535ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
5369c56475370d1df940252ff1360b92de50022fff6Dake Gu    public void testFocusToFirstItem() throws Throwable {
5379c56475370d1df940252ff1360b92de50022fff6Dake Gu
5389c56475370d1df940252ff1360b92de50022fff6Dake Gu        mInstrumentation = getInstrumentation();
5399c56475370d1df940252ff1360b92de50022fff6Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
5409c56475370d1df940252ff1360b92de50022fff6Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
5419c56475370d1df940252ff1360b92de50022fff6Dake Gu                R.layout.horizontal_grid);
5429c56475370d1df940252ff1360b92de50022fff6Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 200);
5439c56475370d1df940252ff1360b92de50022fff6Dake Gu        initActivity(intent);
5449c56475370d1df940252ff1360b92de50022fff6Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
5459c56475370d1df940252ff1360b92de50022fff6Dake Gu        mNumRows = 3;
5469c56475370d1df940252ff1360b92de50022fff6Dake Gu
5479c56475370d1df940252ff1360b92de50022fff6Dake Gu        int[] removedItems = mActivity.removeItems(0, 200);
5489c56475370d1df940252ff1360b92de50022fff6Dake Gu
5499c56475370d1df940252ff1360b92de50022fff6Dake Gu        waitForTransientStateGone(null);
550f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
5519c56475370d1df940252ff1360b92de50022fff6Dake Gu        mActivity.addItems(0, removedItems);
5529c56475370d1df940252ff1360b92de50022fff6Dake Gu
5539c56475370d1df940252ff1360b92de50022fff6Dake Gu        waitForTransientStateGone(null);
554f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
5559c56475370d1df940252ff1360b92de50022fff6Dake Gu        assertTrue(mGridView.getLayoutManager().findViewByPosition(0).hasFocus());
5569c56475370d1df940252ff1360b92de50022fff6Dake Gu
557f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(0);
5589c56475370d1df940252ff1360b92de50022fff6Dake Gu
559f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(200);
5609c56475370d1df940252ff1360b92de50022fff6Dake Gu        assertTrue(mGridView.getLayoutManager().findViewByPosition(0).hasFocus());
5619c56475370d1df940252ff1360b92de50022fff6Dake Gu    }
5629c56475370d1df940252ff1360b92de50022fff6Dake Gu
56377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu    public void testNonFocusableHorizontal() throws Throwable {
56477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int numItems = 200;
56577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int startPos = 45;
56677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int skips = 20;
56777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int numColumns = 3;
56877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int endPos = startPos + numColumns * (skips + 1);
56977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
57077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mInstrumentation = getInstrumentation();
57177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
57277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
57377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu                R.layout.horizontal_grid);
57477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, numItems);
57577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
57677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mOrientation = BaseGridView.HORIZONTAL;
57777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mNumRows = numColumns;
57877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        boolean[] focusable = new boolean[numItems];
57977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        for (int i = 0; i < focusable.length; i++) {
58077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            focusable[i] = true;
58177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
58277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        for (int i = startPos + mNumRows, j = 0; j < skips; i += mNumRows, j++) {
58377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            focusable[i] = false;
58477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
58577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS_FOCUSABLE, focusable);
5868c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
58777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
58877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mGridView.setSelectedPositionSmooth(startPos);
58977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
59077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
59177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        if (mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL) {
59277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
59377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        } else {
59477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
59577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
59677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
59777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        assertEquals(endPos, mGridView.getSelectedPosition());
59877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
59977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        if (mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL) {
60077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
60177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        } else {
60277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
60377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
60477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
60577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        assertEquals(startPos, mGridView.getSelectedPosition());
60677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
60777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu    }
60877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
60977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
61077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu    public void testNonFocusableVertical() throws Throwable {
61177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int numItems = 200;
61277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int startPos = 44;
61377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int skips = 20;
61477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int numColumns = 3;
61577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int endPos = startPos + numColumns * (skips + 1);
61677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
61777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mInstrumentation = getInstrumentation();
61877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
61977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
62077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu                R.layout.vertical_grid);
62177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, numItems);
62277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
62377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mOrientation = BaseGridView.VERTICAL;
62477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mNumRows = numColumns;
62577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        boolean[] focusable = new boolean[numItems];
62677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        for (int i = 0; i < focusable.length; i++) {
62777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            focusable[i] = true;
62877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
62977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        for (int i = startPos + mNumRows, j = 0; j < skips; i += mNumRows, j++) {
63077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            focusable[i] = false;
63177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
63277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS_FOCUSABLE, focusable);
6338c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
63477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
63577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mGridView.setSelectedPositionSmooth(startPos);
63677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
63777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
63877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
63977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
64077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        assertEquals(endPos, mGridView.getSelectedPosition());
64177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
64277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
64377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
64477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        assertEquals(startPos, mGridView.getSelectedPosition());
64577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
64677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu    }
6476b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
6486b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu    public void testTransferFocusable() throws Throwable {
6496b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int numItems = 200;
6506b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int numColumns = 3;
6516b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int startPos = 1;
6526b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
6536b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mInstrumentation = getInstrumentation();
6546b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
6556b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
6566b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu                R.layout.horizontal_grid);
6576b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, numItems);
6586b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
6596b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mOrientation = BaseGridView.HORIZONTAL;
6606b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mNumRows = numColumns;
6616b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        boolean[] focusable = new boolean[numItems];
6626b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        for (int i = 0; i < focusable.length; i++) {
6636b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu            focusable[i] = true;
6646b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        }
6656b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        for (int i = 0; i < startPos; i++) {
6666b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu            focusable[i] = false;
6676b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        }
6686b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS_FOCUSABLE, focusable);
6698c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
6706b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
671f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(0);
6726b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        assertTrue(mGridView.isFocused());
6736b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
674f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(numItems);
6756b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        assertTrue(mGridView.getLayoutManager().findViewByPosition(startPos).hasFocus());
6766b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu    }
6776b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
6786b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu    public void testTransferFocusable2() throws Throwable {
6796b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int numItems = 200;
6806b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int numColumns = 3;
6816b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int startPos = 10;
6826b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
6836b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mInstrumentation = getInstrumentation();
6846b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
6856b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
6866b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu                R.layout.horizontal_grid);
6876b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, numItems);
6886b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, true);
6896b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mOrientation = BaseGridView.HORIZONTAL;
6906b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mNumRows = numColumns;
6916b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        boolean[] focusable = new boolean[numItems];
6926b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        for (int i = 0; i < focusable.length; i++) {
6936b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu            focusable[i] = true;
6946b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        }
6956b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        for (int i = 0; i < startPos; i++) {
6966b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu            focusable[i] = false;
6976b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        }
6986b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS_FOCUSABLE, focusable);
6998c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
7006b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
701f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(0);
7026b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        assertTrue(mGridView.isFocused());
7036b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
704f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(numItems);
7056b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        assertTrue(mGridView.getLayoutManager().findViewByPosition(startPos).hasFocus());
7066b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu    }
707fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
7088c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    public void testNonFocusableLoseInFastLayout() throws Throwable {
709fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        mInstrumentation = getInstrumentation();
710fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
711fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
712fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu                R.layout.vertical_linear);
713fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        int[] items = new int[300];
714fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        for (int i = 0; i < items.length; i++) {
715fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu            items[i] = 480;
716fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        }
717fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
718fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
719fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_LAYOUT_ONFOCUS, true);
720fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        mOrientation = BaseGridView.VERTICAL;
721fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        mNumRows = 1;
722fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        int pressDown = 15;
723fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
7248c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
725fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
726fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        mGridView.setSelectedPositionSmooth(0);
727f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        waitForScrollIdle(mVerifyLayout);
728fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
729fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        for (int i = 0; i < pressDown; i++) {
730fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
731fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        }
732fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        waitForScrollIdle(mVerifyLayout);
733fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        assertFalse(mGridView.isFocused());
734fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
735fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu    }
736fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
7378c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    public void testSetSelectionWithDelta() throws Throwable {
7388c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mInstrumentation = getInstrumentation();
7398c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
7408c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
7418c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                R.layout.vertical_linear);
7428c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 300);
7438c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
7448c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mOrientation = BaseGridView.VERTICAL;
7458c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mNumRows = 1;
7468c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
7478c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
7488c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
7498c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
7508c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
7518c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(3);
7528c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
7538c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
7548c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
7558c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top1 = mGridView.getLayoutManager().findViewByPosition(3).getTop();
7568c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
757f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(1000);
7588c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
7598c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to position with delta
760f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(3, 100);
7618c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top2 = mGridView.getLayoutManager().findViewByPosition(3).getTop();
7628c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top2);
7638c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
7648c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to same position without delta, it will be reset
765f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(3, 0);
7668c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top3 = mGridView.getLayoutManager().findViewByPosition(3).getTop();
7678c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top3);
7688c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
7698c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item after last visible item
7708c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int lastVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
7718c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getLastVisibleIndex();
772f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(lastVisiblePos + 1, 100);
7738c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top4 = mGridView.getLayoutManager().findViewByPosition(lastVisiblePos + 1).getTop();
7748c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top4);
7758c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
7768c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item before first visible item
7778c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int firstVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
7788c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getFirstVisibleIndex();
779f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(firstVisiblePos - 1, 100);
7808c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top5 = mGridView.getLayoutManager().findViewByPosition(firstVisiblePos - 1).getTop();
7818c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top5);
7828c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
7838c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
784f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(50, 100);
7858c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top6 = mGridView.getLayoutManager().findViewByPosition(50).getTop();
7868c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top6);
7878c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
7888c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
7898c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
7908c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
7918c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(100);
7928c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
7938c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
7948c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
7958c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top7 = mGridView.getLayoutManager().findViewByPosition(100).getTop();
7968c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top7);
7978c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
7988c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
799f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(10, 50);
8008c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top8 = mGridView.getLayoutManager().findViewByPosition(10).getTop();
8018c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 50, top8);
8028c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    }
8038c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8048c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    public void testSetSelectionWithDeltaInGrid() throws Throwable {
8058c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mInstrumentation = getInstrumentation();
8068c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
8078c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
8088c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                R.layout.vertical_grid);
8098c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 500);
8108c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, true);
8118c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mOrientation = BaseGridView.VERTICAL;
8128c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mNumRows = 3;
8138c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8148c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
8158c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8168c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
8178c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
8188c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(10);
8198c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
8208c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
8218c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
8228c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top1 = getCenterY(mGridView.getLayoutManager().findViewByPosition(10));
8238c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
824f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
8258c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8268c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to position with delta
827f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(20, 100);
8288c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top2 = getCenterY(mGridView.getLayoutManager().findViewByPosition(20));
8298c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top2);
8308c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8318c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to same position without delta, it will be reset
832f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(20, 0);
8338c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top3 = getCenterY(mGridView.getLayoutManager().findViewByPosition(20));
8348c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top3);
8358c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8368c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item after last visible item
8378c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int lastVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
8388c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getLastVisibleIndex();
839f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(lastVisiblePos + 1, 100);
8408c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top4 = getCenterY(mGridView.getLayoutManager().findViewByPosition(lastVisiblePos + 1));
8418c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        verifyMargin();
8428c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top4);
8438c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8448c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item before first visible item
8458c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int firstVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
8468c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getFirstVisibleIndex();
847f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(firstVisiblePos - 1, 100);
8488c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top5 = getCenterY(mGridView.getLayoutManager().findViewByPosition(firstVisiblePos - 1));
8498c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top5);
8508c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8518c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
852f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(100, 100);
8538c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top6 = getCenterY(mGridView.getLayoutManager().findViewByPosition(100));
8548c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top6);
8558c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8568c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
8578c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
8588c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
8598c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(200);
8608c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
8618c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
8628c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
8638c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Thread.sleep(500);
8648c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top7 = getCenterY(mGridView.getLayoutManager().findViewByPosition(200));
8658c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top7);
8668c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8678c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
868f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(10, 50);
8698c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top8 = getCenterY(mGridView.getLayoutManager().findViewByPosition(10));
8708c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 50, top8);
8718c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    }
8728c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8738c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
8748c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    public void testSetSelectionWithDeltaInGrid1() throws Throwable {
8758c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mInstrumentation = getInstrumentation();
8768c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
8778c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
8788c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                R.layout.vertical_grid);
8798c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, new int[]{
8808c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                193,176,153,141,203,184,232,139,177,206,222,136,132,237,172,137,
8818c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                188,172,163,213,158,219,209,147,133,229,170,197,138,215,188,205,
8828c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                223,192,225,170,195,127,229,229,210,195,134,142,160,139,130,222,
8838c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                150,163,180,176,157,137,234,169,159,167,182,150,224,231,202,236,
8848c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                123,140,181,223,120,185,183,221,123,210,134,158,166,208,149,128,
8858c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                192,214,212,198,133,140,158,133,229,173,226,141,180,128,127,218,
8868c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                192,235,183,213,216,150,143,193,125,141,219,210,195,195,192,191,
8878c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                212,236,157,189,160,220,147,158,220,199,233,231,201,180,168,141,
8888c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                156,204,191,183,190,153,123,210,238,151,139,221,223,200,175,191,
8898c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                132,184,197,204,236,157,230,151,195,219,212,143,172,149,219,184,
8908c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                164,211,132,187,172,142,174,146,127,147,206,238,188,129,199,226,
8918c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                132,220,210,159,235,153,208,182,196,123,180,159,131,135,175,226,
8928c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                127,134,237,211,133,225,132,124,160,226,224,200,173,137,217,169,
8938c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                182,183,176,185,122,168,195,159,172,129,126,129,166,136,149,220,
8948c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                178,191,192,238,180,208,234,154,222,206,239,228,129,140,203,125,
8958c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                214,175,125,169,196,132,234,138,192,142,234,190,215,232,239,122,
8968c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                188,158,128,221,159,237,207,157,232,138,132,214,122,199,121,191,
8978c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                199,209,126,164,175,187,173,186,194,224,191,196,146,208,213,210,
8988c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                164,176,202,213,123,157,179,138,217,129,186,166,237,211,157,130,
8998c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                137,132,171,232,216,239,180,151,137,132,190,133,218,155,171,227,
9008c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                193,147,197,164,120,218,193,154,170,196,138,222,161,235,143,154,
9018c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                192,178,228,195,178,133,203,178,173,206,178,212,136,157,169,124,
9028c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                172,121,128,223,238,125,217,187,184,156,169,215,231,124,210,174,
9038c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                146,226,185,134,223,228,183,182,136,133,199,146,180,233,226,225,
9048c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                174,233,145,235,216,170,192,171,132,132,134,223,233,148,154,162,
9058c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                192,179,197,203,139,197,174,187,135,132,180,136,192,195,124,221,
9068c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                120,189,233,233,146,225,234,163,215,143,132,198,156,205,151,190,
9078c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                204,239,221,229,123,138,134,217,219,136,218,215,167,139,195,125,
9088c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                202,225,178,226,145,208,130,194,228,197,157,215,124,147,174,123,
9098c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                237,140,172,181,161,151,229,216,199,199,179,213,146,122,222,162,
9108c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                139,173,165,150,160,217,207,137,165,175,129,158,134,133,178,199,
9118c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                215,213,122,197
9128c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
9138c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, true);
9148c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mOrientation = BaseGridView.VERTICAL;
9158c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mNumRows = 3;
9168c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9178c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
9188c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9198c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
9208c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
9218c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(10);
9228c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
9238c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
9248c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
9258c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top1 = getCenterY(mGridView.getLayoutManager().findViewByPosition(10));
9268c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
927f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
9288c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9298c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to position with delta
930f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(20, 100);
9318c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top2 = getCenterY(mGridView.getLayoutManager().findViewByPosition(20));
9328c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top2);
9338c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9348c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to same position without delta, it will be reset
935f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(20, 0);
9368c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top3 = getCenterY(mGridView.getLayoutManager().findViewByPosition(20));
9378c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top3);
9388c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9398c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item after last visible item
9408c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int lastVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
9418c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getLastVisibleIndex();
942f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(lastVisiblePos + 1, 100);
9438c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top4 = getCenterY(mGridView.getLayoutManager().findViewByPosition(lastVisiblePos + 1));
9448c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        verifyMargin();
9458c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top4);
9468c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9478c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item before first visible item
9488c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int firstVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
9498c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getFirstVisibleIndex();
950f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(firstVisiblePos - 1, 100);
9518c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top5 = getCenterY(mGridView.getLayoutManager().findViewByPosition(firstVisiblePos - 1));
9528c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top5);
9538c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9548c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
955f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(100, 100);
9568c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top6 = getCenterY(mGridView.getLayoutManager().findViewByPosition(100));
9578c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top6);
9588c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9598c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
9608c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
9618c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
9628c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(200);
9638c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
9648c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
9658c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
9668c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Thread.sleep(500);
9678c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top7 = getCenterY(mGridView.getLayoutManager().findViewByPosition(200));
9688c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top7);
9698c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9708c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
971f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(10, 50);
9728c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top8 = getCenterY(mGridView.getLayoutManager().findViewByPosition(10));
9738c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 50, top8);
9748c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    }
975f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
976f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu    public void testSmoothScrollSelectionEvents() throws Throwable {
977f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mInstrumentation = getInstrumentation();
978f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
979f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
980f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                R.layout.vertical_grid);
981f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 500);
982f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
983f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mOrientation = BaseGridView.VERTICAL;
984f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mNumRows = 3;
985f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        initActivity(intent);
986f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
987f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        runTestOnUiThread(new Runnable() {
988f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            public void run() {
989f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                mGridView.setSelectedPositionSmooth(30);
990f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            }
991f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        });
992f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        waitForScrollIdle(mVerifyLayout);
993f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
994f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
995f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        final ArrayList<Integer> selectedPositions = new ArrayList<Integer>();
996f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mGridView.setOnChildSelectedListener(new OnChildSelectedListener() {
997f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            @Override
998f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            public void onChildSelected(ViewGroup parent, View view, int position, long id) {
999f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                selectedPositions.add(position);
1000f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            }
1001f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        });
1002f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1003f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        sendRepeatedKeys(10, KeyEvent.KEYCODE_DPAD_UP);
1004f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
1005f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        waitForScrollIdle(mVerifyLayout);
1006f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        // should only get childselected event for item 0 once
1007f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        assertTrue(selectedPositions.size() > 0);
1008f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        assertEquals(0, selectedPositions.get(selectedPositions.size() - 1).intValue());
1009f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        for (int i = selectedPositions.size() - 2; i >= 0; i--) {
1010f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            assertFalse(0 == selectedPositions.get(i).intValue());
1011f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        }
1012f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1013f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu    }
1014f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1015f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu    public void testSmoothScrollSelectionEventsLinear() throws Throwable {
1016f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mInstrumentation = getInstrumentation();
1017f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1018f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1019f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                R.layout.vertical_linear);
1020f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 500);
1021f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
1022f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mOrientation = BaseGridView.VERTICAL;
1023f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mNumRows = 1;
1024f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        initActivity(intent);
1025f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1026f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        runTestOnUiThread(new Runnable() {
1027f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            public void run() {
1028f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                mGridView.setSelectedPositionSmooth(10);
1029f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            }
1030f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        });
1031f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        waitForScrollIdle(mVerifyLayout);
1032f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
1033f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1034f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        final ArrayList<Integer> selectedPositions = new ArrayList<Integer>();
1035f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mGridView.setOnChildSelectedListener(new OnChildSelectedListener() {
1036f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            @Override
1037f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            public void onChildSelected(ViewGroup parent, View view, int position, long id) {
1038f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                selectedPositions.add(position);
1039f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            }
1040f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        });
1041f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1042f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        sendRepeatedKeys(10, KeyEvent.KEYCODE_DPAD_UP);
1043f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
1044f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        waitForScrollIdle(mVerifyLayout);
1045f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        // should only get childselected event for item 0 once
1046f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        assertTrue(selectedPositions.size() > 0);
1047f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        assertEquals(0, selectedPositions.get(selectedPositions.size() - 1).intValue());
1048f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        for (int i = selectedPositions.size() - 2; i >= 0; i--) {
1049f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            assertFalse(0 == selectedPositions.get(i).intValue());
1050f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        }
1051f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1052f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu    }
10537538845719cd1e588185ce9ae60320377862ef8dDake Gu
10547538845719cd1e588185ce9ae60320377862ef8dDake Gu    public void testScrollToNoneExisting() throws Throwable {
10557538845719cd1e588185ce9ae60320377862ef8dDake Gu        mInstrumentation = getInstrumentation();
10567538845719cd1e588185ce9ae60320377862ef8dDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
10577538845719cd1e588185ce9ae60320377862ef8dDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
10587538845719cd1e588185ce9ae60320377862ef8dDake Gu                R.layout.vertical_grid);
10597538845719cd1e588185ce9ae60320377862ef8dDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 100);
10607538845719cd1e588185ce9ae60320377862ef8dDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
10617538845719cd1e588185ce9ae60320377862ef8dDake Gu        mOrientation = BaseGridView.VERTICAL;
10627538845719cd1e588185ce9ae60320377862ef8dDake Gu        mNumRows = 3;
10637538845719cd1e588185ce9ae60320377862ef8dDake Gu        initActivity(intent);
10647538845719cd1e588185ce9ae60320377862ef8dDake Gu
10657538845719cd1e588185ce9ae60320377862ef8dDake Gu        runTestOnUiThread(new Runnable() {
10667538845719cd1e588185ce9ae60320377862ef8dDake Gu            public void run() {
10677538845719cd1e588185ce9ae60320377862ef8dDake Gu                mGridView.setSelectedPositionSmooth(99);
10687538845719cd1e588185ce9ae60320377862ef8dDake Gu            }
10697538845719cd1e588185ce9ae60320377862ef8dDake Gu        });
10707538845719cd1e588185ce9ae60320377862ef8dDake Gu        waitForScrollIdle(mVerifyLayout);
10717538845719cd1e588185ce9ae60320377862ef8dDake Gu        humanDelay(500);
10727538845719cd1e588185ce9ae60320377862ef8dDake Gu
10737538845719cd1e588185ce9ae60320377862ef8dDake Gu
10747538845719cd1e588185ce9ae60320377862ef8dDake Gu        runTestOnUiThread(new Runnable() {
10757538845719cd1e588185ce9ae60320377862ef8dDake Gu            public void run() {
10767538845719cd1e588185ce9ae60320377862ef8dDake Gu                mGridView.setSelectedPositionSmooth(50);
10777538845719cd1e588185ce9ae60320377862ef8dDake Gu            }
10787538845719cd1e588185ce9ae60320377862ef8dDake Gu        });
10797538845719cd1e588185ce9ae60320377862ef8dDake Gu        Thread.sleep(100);
10807538845719cd1e588185ce9ae60320377862ef8dDake Gu        runTestOnUiThread(new Runnable() {
10817538845719cd1e588185ce9ae60320377862ef8dDake Gu            public void run() {
10827538845719cd1e588185ce9ae60320377862ef8dDake Gu                mGridView.requestLayout();
10837538845719cd1e588185ce9ae60320377862ef8dDake Gu                mGridView.setSelectedPositionSmooth(0);
10847538845719cd1e588185ce9ae60320377862ef8dDake Gu            }
10857538845719cd1e588185ce9ae60320377862ef8dDake Gu        });
10867538845719cd1e588185ce9ae60320377862ef8dDake Gu        waitForScrollIdle(mVerifyLayout);
10877538845719cd1e588185ce9ae60320377862ef8dDake Gu        humanDelay(500);
10887538845719cd1e588185ce9ae60320377862ef8dDake Gu
10897538845719cd1e588185ce9ae60320377862ef8dDake Gu    }
10907538845719cd1e588185ce9ae60320377862ef8dDake Gu
10913a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu    public void testSmoothscrollerInterrupted() throws Throwable {
10923a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        mInstrumentation = getInstrumentation();
10933a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
10943a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
10953a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                R.layout.vertical_linear);
10963a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
10973a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        int[] items = new int[100];
10983a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        for (int i = 0; i < items.length; i++) {
10993a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            items[i] = 680;
11003a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        }
11013a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
11023a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
11033a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        mOrientation = BaseGridView.VERTICAL;
11043a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        mNumRows = 1;
11053a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu
11063a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        initActivity(intent);
11073a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu
11083a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        mGridView.setSelectedPositionSmooth(0);
11093a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        waitForScrollIdle(mVerifyLayout);
11103a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        assertTrue(mGridView.getChildAt(0).hasFocus());
11113a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu
11123a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        // Pressing lots of key to make sure smooth scroller is running
11133a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        for (int i = 0; i < 20; i++) {
11143a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
11153a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        }
11163a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        Thread.sleep(100);
11173a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        int total = 0;
11183a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        while (mGridView.getLayoutManager().isSmoothScrolling() ||
11193a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                mGridView.getScrollState() != BaseGridView.SCROLL_STATE_IDLE) {
11203a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            if ((total += 10) >= WAIT_FOR_SCROLL_IDLE_TIMEOUT_MS) {
11213a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                throw new RuntimeException("waitForScrollIdle Timeout");
11223a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            }
11233a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            try {
11243a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                // Repeatedly pressing to make sure pending keys does not drop to zero.
11253a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                Thread.sleep(10);
11263a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
11273a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            } catch (InterruptedException ex) {
11283a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                break;
11293a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            }
11303a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        }
11313a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu
11323a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        assertTrue("LinearSmoothScroller would not use many RV.smoothScrollBy() calls",
11333a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                ((VerticalGridViewEx) mGridView).mSmoothScrollByCalled < 10);
11343a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu    }
113557f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu
113657f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu    public void testSetNumRowsAndAddItem() throws Throwable {
113757f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        mInstrumentation = getInstrumentation();
113857f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
113957f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
114057f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu                R.layout.vertical_linear);
114157f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
114257f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        int[] items = new int[2];
114357f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        for (int i = 0; i < items.length; i++) {
114457f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu            items[i] = 300;
114557f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        }
114657f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
114757f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
114857f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        mOrientation = BaseGridView.VERTICAL;
114957f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        mNumRows = 1;
115057f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu
115157f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        initActivity(intent);
115257f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu
115357f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        mGridView.setSelectedPositionSmooth(0);
115457f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        waitForScrollIdle(mVerifyLayout);
115557f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu
115657f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        mActivity.addItems(items.length, new int[]{300});
115757f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu
115857f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        runTestOnUiThread(new Runnable() {
115957f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu            public void run() {
116057f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu                ((VerticalGridView) mGridView).setNumColumns(2);
116157f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu            }
116257f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        });
116357f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        Thread.sleep(1000);
116457f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        assertTrue(mGridView.getChildAt(2).getLeft() != mGridView.getChildAt(1).getLeft());
116557f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu    }
1166c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1167c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1168c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu    public void testRequestLayoutBugInLayout() throws Throwable {
1169c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        mInstrumentation = getInstrumentation();
1170c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1171c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1172c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                R.layout.vertical_linear);
1173c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.relative_layout);
1174c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
1175c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        int[] items = new int[100];
1176c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        for (int i = 0; i < items.length; i++) {
1177c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu            items[i] = 300;
1178c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        }
1179c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
1180c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
1181c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        mOrientation = BaseGridView.VERTICAL;
1182c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        mNumRows = 1;
1183c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1184c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        initActivity(intent);
1185c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1186c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        runTestOnUiThread(new Runnable() {
1187c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu            public void run() {
1188c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                mGridView.setSelectedPositionSmooth(1);
1189c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu            }
1190c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        });
1191c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        waitForScrollIdle(mVerifyLayout);
1192c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1193c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
1194c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        waitForScrollIdle(mVerifyLayout);
1195c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1196c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        assertEquals("Line 2", ((TextView) mGridView.findFocus()).getText().toString());
1197c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu    }
1198492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu
1199492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu
1200492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu    public void testChangeLayoutInChild() throws Throwable {
1201492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        mInstrumentation = getInstrumentation();
1202492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1203492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1204492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                R.layout.vertical_linear_wrap_content);
1205492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_LAYOUT_ONFOCUS, true);
1206492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        int[] items = new int[2];
1207492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        for (int i = 0; i < items.length; i++) {
1208492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu            items[i] = 300;
1209492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        }
1210492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
1211492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
1212492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        mOrientation = BaseGridView.VERTICAL;
1213492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        mNumRows = 1;
1214492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu
1215492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        initActivity(intent);
1216492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu
1217492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        runTestOnUiThread(new Runnable() {
1218492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu            public void run() {
1219492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                mGridView.setSelectedPositionSmooth(0);
1220492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu            }
1221492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        });
1222492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        waitForScrollIdle(mVerifyLayout);
1223492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        verifyMargin();
1224492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu
1225492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        runTestOnUiThread(new Runnable() {
1226492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu            public void run() {
1227492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                mGridView.setSelectedPositionSmooth(1);
1228492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu            }
1229492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        });
1230492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        waitForScrollIdle(mVerifyLayout);
1231492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        verifyMargin();
1232492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu    }
12331a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu
12341a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu
12351a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu    public void testZeroFixedSecondarySize() throws Throwable {
12361a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        mInstrumentation = getInstrumentation();
12371a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
12381a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
12391a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu                R.layout.vertical_linear_measured_with_zero);
12401a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        intent.putExtra(GridActivity.EXTRA_SECONDARY_SIZE_ZERO, true);
12411a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        int[] items = new int[2];
12421a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        for (int i = 0; i < items.length; i++) {
12431a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu            items[i] = 0;
12441a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        }
12451a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
12461a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
12471a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        mOrientation = BaseGridView.VERTICAL;
12481a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        mNumRows = 1;
12491a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu
12501a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        initActivity(intent);
12511a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu
12521a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu    }
12533bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
12543bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu    public void testChildStates() throws Throwable {
12553bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        mInstrumentation = getInstrumentation();
12563bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
12573bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.vertical_linear);
12583bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        int[] items = new int[100];
12593bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        for (int i = 0; i < items.length; i++) {
12603bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            items[i] = 200;
12613bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        }
12623bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
12633bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
12643bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_LAYOUT_ONFOCUS, true);
12653bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.selectable_text_view);
12663bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        mOrientation = BaseGridView.VERTICAL;
12673bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        mNumRows = 1;
12683bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
12693bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        initActivity(intent);
12703bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        mGridView.setSaveChildrenPolicy(VerticalGridView.SAVE_ALL_CHILD);
12713bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
127261e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        final SparseArray<Parcelable> container = new SparseArray<Parcelable>();
12733bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
12743bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        // 1 Save view states
12753bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        runTestOnUiThread(new Runnable() {
12763bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            public void run() {
12773bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                Selection.setSelection((Spannable)(((TextView) mGridView.getChildAt(0))
12783bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                        .getText()), 0, 1);
12793bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                Selection.setSelection((Spannable)(((TextView) mGridView.getChildAt(1))
12803bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                        .getText()), 0, 1);
12813bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                mGridView.saveHierarchyState(container);
12823bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            }
12833bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        });
12843bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
12853bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        // 2 Change view states
12863bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        runTestOnUiThread(new Runnable() {
12873bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            public void run() {
12883bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                Selection.setSelection((Spannable)(((TextView) mGridView.getChildAt(0))
12893bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                        .getText()), 1, 2);
12903bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                Selection.setSelection((Spannable)(((TextView) mGridView.getChildAt(1))
12913bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                        .getText()), 1, 2);
12923bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            }
12933bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        });
12943bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
12953bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        // 3 Detached and re-attached,  should still maintain state of (2)
12963bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        runTestOnUiThread(new Runnable() {
12973bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            public void run() {
12983bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                mGridView.setSelectedPositionSmooth(1);
12993bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            }
13003bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        });
13013bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        waitForScrollIdle(mVerifyLayout);
13023bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(0)).getSelectionStart(), 1);
13033bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(0)).getSelectionEnd(), 2);
13043bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(1)).getSelectionStart(), 1);
13053bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(1)).getSelectionEnd(), 2);
13063bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
13073bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        // 4 Recycled and rebound, should load state from (2)
13083bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        runTestOnUiThread(new Runnable() {
13093bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            public void run() {
13103bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                mGridView.setSelectedPositionSmooth(20);
13113bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            }
13123bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        });
13133bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        waitForScrollIdle(mVerifyLayout);
13143bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        runTestOnUiThread(new Runnable() {
13153bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            public void run() {
13163bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                mGridView.setSelectedPositionSmooth(0);
13173bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            }
13183bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        });
13193bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        waitForScrollIdle(mVerifyLayout);
13203bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(0)).getSelectionStart(), 1);
13213bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(0)).getSelectionEnd(), 2);
13223bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(1)).getSelectionStart(), 1);
13233bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(1)).getSelectionEnd(), 2);
13243bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu    }
13253bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
13263bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
132761e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu    public void testNoDispatchSaveChildState() throws Throwable {
132861e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        mInstrumentation = getInstrumentation();
132961e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
133061e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.vertical_linear);
133161e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        int[] items = new int[100];
133261e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        for (int i = 0; i < items.length; i++) {
133361e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            items[i] = 200;
133461e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        }
133561e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
133661e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
133761e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.selectable_text_view);
133861e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        mOrientation = BaseGridView.VERTICAL;
133961e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        mNumRows = 1;
134061e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
134161e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        initActivity(intent);
134261e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        mGridView.setSaveChildrenPolicy(VerticalGridView.SAVE_NO_CHILD);
134361e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
134461e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        final SparseArray<Parcelable> container = new SparseArray<Parcelable>();
134561e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
134661e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        // 1. Set text selection, save view states should do nothing on child
134761e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        runTestOnUiThread(new Runnable() {
134861e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            public void run() {
134961e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                for (int i = 0; i < mGridView.getChildCount(); i++) {
135061e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                    Selection.setSelection((Spannable)(((TextView) mGridView.getChildAt(i))
135161e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                            .getText()), 0, 1);
135261e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                }
135361e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                mGridView.saveHierarchyState(container);
135461e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            }
135561e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        });
135661e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
135761e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        // 2. clear the text selection
135861e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        runTestOnUiThread(new Runnable() {
135961e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            public void run() {
136061e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                for (int i = 0; i < mGridView.getChildCount(); i++) {
136161e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                    Selection.removeSelection((Spannable)(((TextView) mGridView.getChildAt(i))
136261e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                            .getText()));
136361e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                }
136461e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            }
136561e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        });
136661e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
136761e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        // 3. Restore view states should be a no-op for child
136861e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        runTestOnUiThread(new Runnable() {
136961e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            public void run() {
137061e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                mGridView.restoreHierarchyState(container);
137161e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                for (int i = 0; i < mGridView.getChildCount(); i++) {
137261e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                    assertEquals(-1, ((TextView) mGridView.getChildAt(i)).getSelectionStart());
137361e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                    assertEquals(-1, ((TextView) mGridView.getChildAt(i)).getSelectionEnd());
137461e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                }
137561e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            }
137661e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        });
137761e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu    }
137861e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
137908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
138008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static interface ViewTypeProvider {
138108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public int getViewType(int position);
138208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
138308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
138408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static interface ItemAlignmentFacetProvider {
138508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public ItemAlignmentFacet getItemAlignmentFacet(int viewType);
138608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
138708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
138808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static class TwoViewTypesProvider implements ViewTypeProvider {
138908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        static int VIEW_TYPE_FIRST = 1;
139008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        static int VIEW_TYPE_DEFAULT = 0;
139108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        @Override
139208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public int getViewType(int position) {
139308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (position == 0) {
139408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return VIEW_TYPE_FIRST;
139508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            } else {
139608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return VIEW_TYPE_DEFAULT;
139708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
139808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
139908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
140008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
140108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static class PositionItemAlignmentFacetProviderForRelativeLayout1
140208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            implements ItemAlignmentFacetProvider {
140308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        ItemAlignmentFacet mMultipleFacet;
140408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
140508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        PositionItemAlignmentFacetProviderForRelativeLayout1() {
140608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet = new ItemAlignmentFacet();
140708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            ItemAlignmentFacet.ItemAlignmentDef[] defs =
140808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                    new ItemAlignmentFacet.ItemAlignmentDef[2];
140908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0] = new ItemAlignmentFacet.ItemAlignmentDef();
141008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0].setItemAlignmentViewId(R.id.t1);
141108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1] = new ItemAlignmentFacet.ItemAlignmentDef();
141208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentViewId(R.id.t2);
141308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffsetPercent(100);
141408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffset(-10);
141508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet.setAlignmentDefs(defs);
141608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
141708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
141808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        @Override
141908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public ItemAlignmentFacet getItemAlignmentFacet(int position) {
142008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (position == 0) {
142108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return mMultipleFacet;
142208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            } else {
142308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return null;
142408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
142508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
142608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
142708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
142808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    public void testMultipleScrollPosition1() throws Throwable {
142908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mInstrumentation = getInstrumentation();
143008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
143108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
143208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                R.layout.vertical_linear);
143308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.relative_layout);
143408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
143508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int[] items = new int[100];
143608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        for (int i = 0; i < items.length; i++) {
143708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            items[i] = 300;
143808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
143908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
144008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
144108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_VIEWTYPEPROVIDER_CLASS,
144208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                TwoViewTypesProvider.class.getName());
144308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        // Set ItemAlignment for each ViewHolder and view type,  ViewHolder should
144408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        // override the view type settings.
144508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMALIGNMENTPROVIDER_CLASS,
144608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                PositionItemAlignmentFacetProviderForRelativeLayout1.class.getName());
144708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMALIGNMENTPROVIDER_VIEWTYPE_CLASS,
144808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                ViewTypePositionItemAlignmentFacetProviderForRelativeLayout2.class.getName());
144908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mOrientation = BaseGridView.VERTICAL;
145008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mNumRows = 1;
145108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
145208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        initActivity(intent);
145308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
145408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("First view is aligned with padding top",
145508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getPaddingTop(), mGridView.getChildAt(0).getTop());
145608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
145708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
145808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        waitForScrollIdle(mVerifyLayout);
145908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
146008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        final View v = mGridView.getChildAt(0);
146108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t1 = v.findViewById(R.id.t1);
146208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t1align = (t1.getTop() + t1.getBottom()) / 2;
146308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t2 = v.findViewById(R.id.t2);
146408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t2align = t2.getBottom() - 10;
146508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("Expected alignment for 2nd textview",
146608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getPaddingTop() - (t2align - t1align),
146708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                v.getTop());
146808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
146908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
147008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static class PositionItemAlignmentFacetProviderForRelativeLayout2 implements
147108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            ItemAlignmentFacetProvider {
147208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        ItemAlignmentFacet mMultipleFacet;
147308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
147408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        PositionItemAlignmentFacetProviderForRelativeLayout2() {
147508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet = new ItemAlignmentFacet();
147608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            ItemAlignmentFacet.ItemAlignmentDef[] defs = new ItemAlignmentFacet.ItemAlignmentDef[2];
147708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0] = new ItemAlignmentFacet.ItemAlignmentDef();
147808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0].setItemAlignmentViewId(R.id.t1);
147908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0].setItemAlignmentOffsetPercent(0);
148008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1] = new ItemAlignmentFacet.ItemAlignmentDef();
148108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentViewId(R.id.t2);
148208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffsetPercent(ItemAlignmentFacet.ITEM_ALIGN_OFFSET_PERCENT_DISABLED);
148308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffset(-10);
148408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet.setAlignmentDefs(defs);
148508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
148608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
148708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        @Override
148808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public ItemAlignmentFacet getItemAlignmentFacet(int position) {
148908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (position == 0) {
149008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return mMultipleFacet;
149108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            } else {
149208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return null;
149308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
149408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
149508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
149608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
149708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    public void testMultipleScrollPosition2() throws Throwable {
149808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mInstrumentation = getInstrumentation();
149908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
150008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.vertical_linear);
150108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.relative_layout);
150208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
150308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int[] items = new int[100];
150408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        for (int i = 0; i < items.length; i++) {
150508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            items[i] = 300;
150608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
150708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
150808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
150908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_VIEWTYPEPROVIDER_CLASS,
151008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                TwoViewTypesProvider.class.getName());
151108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMALIGNMENTPROVIDER_CLASS,
151208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                PositionItemAlignmentFacetProviderForRelativeLayout2.class.getName());
151308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mOrientation = BaseGridView.VERTICAL;
151408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mNumRows = 1;
151508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
151608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        initActivity(intent);
151708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
151808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("First view is aligned with padding top", mGridView.getPaddingTop(),
151908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getChildAt(0).getTop());
152008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
152108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
152208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        waitForScrollIdle(mVerifyLayout);
152308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
152408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        final View v = mGridView.getChildAt(0);
152508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t1 = v.findViewById(R.id.t1);
152608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t1align = t1.getTop();
152708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t2 = v.findViewById(R.id.t2);
152808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t2align = t2.getTop() - 10;
152908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("Expected alignment for 2nd textview",
153008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getPaddingTop() - (t2align - t1align), v.getTop());
153108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
153208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
153308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static class ViewTypePositionItemAlignmentFacetProviderForRelativeLayout2 implements
153408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            ItemAlignmentFacetProvider {
153508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        ItemAlignmentFacet mMultipleFacet;
153608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
153708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        ViewTypePositionItemAlignmentFacetProviderForRelativeLayout2() {
153808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet = new ItemAlignmentFacet();
153908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            ItemAlignmentFacet.ItemAlignmentDef[] defs = new ItemAlignmentFacet.ItemAlignmentDef[2];
154008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0] = new ItemAlignmentFacet.ItemAlignmentDef();
154108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0].setItemAlignmentViewId(R.id.t1);
154208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0].setItemAlignmentOffsetPercent(0);
154308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1] = new ItemAlignmentFacet.ItemAlignmentDef();
154408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentViewId(R.id.t2);
154508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffsetPercent(100);
154608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffset(-10);
154708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet.setAlignmentDefs(defs);
154808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
154908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
155008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        @Override
155108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public ItemAlignmentFacet getItemAlignmentFacet(int viewType) {
155208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (viewType == TwoViewTypesProvider.VIEW_TYPE_FIRST) {
155308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return mMultipleFacet;
155408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            } else {
155508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return null;
155608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
155708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
155808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
155908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
156008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    public void testMultipleScrollPosition3() throws Throwable {
156108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mInstrumentation = getInstrumentation();
156208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
156308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.vertical_linear);
156408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.relative_layout);
156508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
156608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int[] items = new int[100];
156708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        for (int i = 0; i < items.length; i++) {
156808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            items[i] = 300;
156908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
157008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
157108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
157208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_VIEWTYPEPROVIDER_CLASS,
157308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                TwoViewTypesProvider.class.getName());
157408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMALIGNMENTPROVIDER_VIEWTYPE_CLASS,
157508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                ViewTypePositionItemAlignmentFacetProviderForRelativeLayout2.class.getName());
157608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mOrientation = BaseGridView.VERTICAL;
157708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mNumRows = 1;
157808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
157908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        initActivity(intent);
158008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
158108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("First view is aligned with padding top", mGridView.getPaddingTop(),
158208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getChildAt(0).getTop());
158308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
158408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
158508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        waitForScrollIdle(mVerifyLayout);
158608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
158708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        final View v = mGridView.getChildAt(0);
158808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t1 = v.findViewById(R.id.t1);
158908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t1align = t1.getTop();
159008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t2 = v.findViewById(R.id.t2);
159108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t2align = t2.getBottom() - 10;
159208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("Expected alignment for 2nd textview",
159308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getPaddingTop() - (t2align - t1align), v.getTop());
159408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
159508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
1596db0b1afb71440b79923692d58adee982b5954838Dake Gu    public void testSelectionAndAddItemInOneCycle() throws Throwable {
1597db0b1afb71440b79923692d58adee982b5954838Dake Gu        mInstrumentation = getInstrumentation();
1598db0b1afb71440b79923692d58adee982b5954838Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1599db0b1afb71440b79923692d58adee982b5954838Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1600db0b1afb71440b79923692d58adee982b5954838Dake Gu                R.layout.vertical_linear);
1601db0b1afb71440b79923692d58adee982b5954838Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 0);
1602db0b1afb71440b79923692d58adee982b5954838Dake Gu        initActivity(intent);
1603db0b1afb71440b79923692d58adee982b5954838Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
1604db0b1afb71440b79923692d58adee982b5954838Dake Gu        mNumRows = 1;
1605db0b1afb71440b79923692d58adee982b5954838Dake Gu
1606db0b1afb71440b79923692d58adee982b5954838Dake Gu        runTestOnUiThread(new Runnable() {
1607db0b1afb71440b79923692d58adee982b5954838Dake Gu            public void run() {
1608db0b1afb71440b79923692d58adee982b5954838Dake Gu                mActivity.addItems(0, new int[]{300, 300});
1609db0b1afb71440b79923692d58adee982b5954838Dake Gu                mGridView.setSelectedPosition(0);
1610db0b1afb71440b79923692d58adee982b5954838Dake Gu            }
1611db0b1afb71440b79923692d58adee982b5954838Dake Gu        });
1612db0b1afb71440b79923692d58adee982b5954838Dake Gu        waitForTransientStateGone(null);
1613db0b1afb71440b79923692d58adee982b5954838Dake Gu        assertEquals(0, mGridView.getSelectedPosition());
1614db0b1afb71440b79923692d58adee982b5954838Dake Gu    }
1615db0b1afb71440b79923692d58adee982b5954838Dake Gu
1616db0b1afb71440b79923692d58adee982b5954838Dake Gu    public void testSelectionSmoothAndAddItemInOneCycle() throws Throwable {
1617db0b1afb71440b79923692d58adee982b5954838Dake Gu        mInstrumentation = getInstrumentation();
1618db0b1afb71440b79923692d58adee982b5954838Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1619db0b1afb71440b79923692d58adee982b5954838Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1620db0b1afb71440b79923692d58adee982b5954838Dake Gu                R.layout.vertical_linear);
1621db0b1afb71440b79923692d58adee982b5954838Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 0);
1622db0b1afb71440b79923692d58adee982b5954838Dake Gu        initActivity(intent);
1623db0b1afb71440b79923692d58adee982b5954838Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
1624db0b1afb71440b79923692d58adee982b5954838Dake Gu        mNumRows = 1;
1625db0b1afb71440b79923692d58adee982b5954838Dake Gu
1626db0b1afb71440b79923692d58adee982b5954838Dake Gu        runTestOnUiThread(new Runnable() {
1627db0b1afb71440b79923692d58adee982b5954838Dake Gu            public void run() {
1628db0b1afb71440b79923692d58adee982b5954838Dake Gu                mActivity.addItems(0, new int[]{300, 300});
1629db0b1afb71440b79923692d58adee982b5954838Dake Gu                mGridView.setSelectedPositionSmooth(0);
1630db0b1afb71440b79923692d58adee982b5954838Dake Gu            }
1631db0b1afb71440b79923692d58adee982b5954838Dake Gu        });
1632db0b1afb71440b79923692d58adee982b5954838Dake Gu        waitForTransientStateGone(null);
1633db0b1afb71440b79923692d58adee982b5954838Dake Gu        assertEquals(0, mGridView.getSelectedPosition());
1634db0b1afb71440b79923692d58adee982b5954838Dake Gu    }
1635062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu}
1636