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;
28d1cab1b54104d55407335c5d649398635822fffdDake Gu
29d1cab1b54104d55407335c5d649398635822fffdDake Guimport android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
30d1cab1b54104d55407335c5d649398635822fffdDake Guimport android.support.v7.widget.RecyclerViewAccessibilityDelegate;
31d1cab1b54104d55407335c5d649398635822fffdDake Gu
32062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.app.Instrumentation;
33062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport android.content.Intent;
343bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Guimport android.os.Parcelable;
35062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
36062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport java.util.ArrayList;
37062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport java.util.Arrays;
38062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport java.util.Comparator;
39062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport java.util.HashMap;
40062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Guimport java.util.Iterator;
41062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
42062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu/**
43062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu * @hide from javadoc
44062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu */
45062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gupublic class GridWidgetTest extends ActivityInstrumentationTestCase2<GridActivity> {
46062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
47f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    private static final boolean HUMAN_DELAY = false;
487538845719cd1e588185ce9ae60320377862ef8dDake Gu    private static final long WAIT_FOR_SCROLL_IDLE_TIMEOUT_MS = 60000;
49f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu
50062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    protected GridActivity mActivity;
51062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    protected Instrumentation mInstrumentation;
52062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    protected BaseGridView mGridView;
5385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    protected GridLayoutManager mLayoutManager;
54062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    protected int mOrientation;
55247741d74797105ba4f6d2834ec56dab32c14644Dake Gu    protected int mNumRows;
56062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
57062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    private final Comparator<View> mRowSortComparator = new Comparator<View>() {
58062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        public int compare(View lhs, View rhs) {
59062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            if (mOrientation == BaseGridView.HORIZONTAL) {
60062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu                return lhs.getLeft() - rhs.getLeft();
61062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            } else {
62062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu                return lhs.getTop() - rhs.getTop();
63062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            }
64062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        };
65062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    };
66062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
67062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    /**
68062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu     * Verify margins between items on same row are same.
69062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu     */
70062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    private final Runnable mVerifyLayout = new Runnable() {
71062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        @Override
72062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        public void run() {
73e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            verifyMargin();
74062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        }
75062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    };
76062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
77062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    public GridWidgetTest() {
78062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        super("android.support.v17.leanback.tests", GridActivity.class);
79062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    }
80062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
81f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    private void humanDelay(int delay) throws InterruptedException {
82f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        if (HUMAN_DELAY) Thread.sleep(delay);
83f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    }
84f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    /**
85f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu     * Change size of the Adapter and notifyDataSetChanged.
86f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu     */
87f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    private void changeArraySize(final int size) throws Throwable {
88f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        runTestOnUiThread(new Runnable() {
89f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu            public void run() {
90f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu                mActivity.changeArraySize(size);
91f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu            }
92f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        });
93f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        Thread.sleep(500);
94f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    }
95f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu
96f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    /**
97f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu     * Change selected position.
98f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu     */
99f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    private void setSelectedPosition(final int position, final int scrollExtra) throws Throwable {
100f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        runTestOnUiThread(new Runnable() {
101f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu            public void run() {
102f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu                mGridView.setSelectedPosition(position, scrollExtra);
103f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu            }
104f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        });
105f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        Thread.sleep(500);
106f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu    }
107f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu
108062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    /**
109062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu     * Wait for grid view stop scroll and optionally verify state of grid view.
110062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu     */
111062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    protected void waitForScrollIdle(Runnable verify) throws Throwable {
1128c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Thread.sleep(100);
1137538845719cd1e588185ce9ae60320377862ef8dDake Gu        int total = 0;
114062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        while (mGridView.getLayoutManager().isSmoothScrolling() ||
115062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu                mGridView.getScrollState() != BaseGridView.SCROLL_STATE_IDLE) {
1167538845719cd1e588185ce9ae60320377862ef8dDake Gu            if ((total += 100) >= WAIT_FOR_SCROLL_IDLE_TIMEOUT_MS) {
1177538845719cd1e588185ce9ae60320377862ef8dDake Gu                throw new RuntimeException("waitForScrollIdle Timeout");
1187538845719cd1e588185ce9ae60320377862ef8dDake Gu            }
119062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            try {
120062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu                Thread.sleep(100);
121062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            } catch (InterruptedException ex) {
122062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu                break;
123062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            }
124062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            if (verify != null) {
125062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu                runTestOnUiThread(verify);
126062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu            }
127062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        }
128062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    }
129062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
130062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    /**
13185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu     * Wait for grid view stop animation and optionally verify state of grid view.
13285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu     */
13385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    protected void waitForTransientStateGone(Runnable verify) throws Throwable {
13485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        do {
13585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            try {
13685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                Thread.sleep(100);
13785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            } catch (InterruptedException ex) {
13885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                break;
13985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            }
14085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            if (verify != null) {
14185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                runTestOnUiThread(verify);
14285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            }
14385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        } while (mGridView.hasTransientState());
14485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    }
14585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
14685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    /**
147062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu     * Wait for grid view stop scroll.
148062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu     */
149062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    protected void waitForScrollIdle() throws Throwable {
150062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        waitForScrollIdle(null);
151062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    }
152062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
153e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    /**
154a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu     * Scrolls using given key.
155a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu     */
156a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu    protected void scroll(int key, Runnable verify) throws Throwable {
157a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        do {
158a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            if (verify != null) {
159a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu                runTestOnUiThread(verify);
160a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            }
161a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            sendRepeatedKeys(10, key);
162a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            try {
1638c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                Thread.sleep(300);
164a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            } catch (InterruptedException ex) {
165a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu                break;
166a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            }
167a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        } while (mGridView.getLayoutManager().isSmoothScrolling() ||
168a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu                mGridView.getScrollState() != BaseGridView.SCROLL_STATE_IDLE);
169a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu    }
170a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu
171a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu    protected void scrollToBegin(Runnable verify) throws Throwable {
172a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        int key;
173a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        if (mOrientation == BaseGridView.HORIZONTAL) {
174a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            if (mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL) {
175a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu                key = KeyEvent.KEYCODE_DPAD_RIGHT;
176a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            } else {
177a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu                key = KeyEvent.KEYCODE_DPAD_LEFT;
178a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            }
179a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        } else {
180a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            key = KeyEvent.KEYCODE_DPAD_UP;
181a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        }
182a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scroll(key, verify);
183a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu    }
184a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu
185a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu    protected void scrollToEnd(Runnable verify) throws Throwable {
186a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        int key;
187a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        if (mOrientation == BaseGridView.HORIZONTAL) {
188a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            if (mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL) {
189a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu                key = KeyEvent.KEYCODE_DPAD_LEFT;
190a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            } else {
191a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu                key = KeyEvent.KEYCODE_DPAD_RIGHT;
192a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            }
193a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        } else {
194a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu            key = KeyEvent.KEYCODE_DPAD_DOWN;
195a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        }
196a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scroll(key, verify);
197a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu    }
198a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu
199a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu    /**
200e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu     * Group and sort children by their position on each row (HORIZONTAL) or column(VERTICAL).
201e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu     */
202e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    protected View[][] sortByRows() {
203e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        final HashMap<Integer, ArrayList<View>> rows = new HashMap<Integer, ArrayList<View>>();
204c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        ArrayList<Integer> rowLocations = new ArrayList();
205e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        for (int i = 0; i < mGridView.getChildCount(); i++) {
206e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            View v = mGridView.getChildAt(i);
207e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            int rowLocation;
208e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            if (mOrientation == BaseGridView.HORIZONTAL) {
209e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                rowLocation = v.getTop();
210e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            } else {
211e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                rowLocation = mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL ?
212e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    v.getRight() : v.getLeft();
213e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            }
214e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            ArrayList<View> views = rows.get(rowLocation);
215e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            if (views == null) {
216e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                views = new ArrayList<View>();
217e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                rows.put(rowLocation, views);
218c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                rowLocations.add(rowLocation);
219e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            }
220e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            views.add(v);
221e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        }
222c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        Object[] sortedLocations = rowLocations.toArray();
223c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        Arrays.sort(sortedLocations);
224c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        if (mNumRows != rows.size()) {
225c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            assertEquals("Dump Views by rows "+rows, mNumRows, rows.size());
226c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        }
227e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        View[][] sorted = new View[rows.size()][];
228c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        for (int i = 0; i < rowLocations.size(); i++) {
229c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            Integer rowLocation = rowLocations.get(i);
230c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            ArrayList<View> arr = rows.get(rowLocation);
231e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            View[] views = arr.toArray(new View[arr.size()]);
232e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            Arrays.sort(views, mRowSortComparator);
233c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            sorted[i] = views;
234e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        }
235e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        return sorted;
236e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    }
237e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
238e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    protected void verifyMargin() {
239e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        View[][] sorted = sortByRows();
240e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        for (int row = 0; row < sorted.length; row++) {
241e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            View[] views = sorted[row];
242e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            int margin = -1;
243e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            for (int i = 1; i < views.length; i++) {
244e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                if (mOrientation == BaseGridView.HORIZONTAL) {
245492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                    assertEquals(mGridView.getHorizontalMargin(),
246492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                            views[i].getLeft() - views[i - 1].getRight());
247e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                } else {
248492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                    assertEquals(mGridView.getVerticalMargin(),
249492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                            views[i].getTop() - views[i - 1].getBottom());
250e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                }
251e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            }
252e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        }
253e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    }
254e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
255e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    protected void verifyBeginAligned() {
256e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        View[][] sorted = sortByRows();
257e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        int alignedLocation = 0;
258e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        if (mOrientation == BaseGridView.HORIZONTAL) {
259e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            if (mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL) {
260e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                for (int i = 0; i < sorted.length; i++) {
261e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    if (i == 0) {
262e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                        alignedLocation = sorted[i][sorted[i].length - 1].getRight();
263e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    } else {
264e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                        assertEquals(alignedLocation, sorted[i][sorted[i].length - 1].getRight());
265e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    }
266e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                }
267e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            } else {
268e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                for (int i = 0; i < sorted.length; i++) {
269e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    if (i == 0) {
270e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                        alignedLocation = sorted[i][0].getLeft();
271e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    } else {
272e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                        assertEquals(alignedLocation, sorted[i][0].getLeft());
273e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    }
274e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                }
275e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            }
276e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        } else {
277e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            for (int i = 0; i < sorted.length; i++) {
278e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                if (i == 0) {
279e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    alignedLocation = sorted[i][0].getTop();
280e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                } else {
281e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                    assertEquals(alignedLocation, sorted[i][0].getTop());
282e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu                }
283e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu            }
284e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        }
285e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    }
286e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
287c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu    protected int[] getEndEdges() {
288c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        View[][] sorted = sortByRows();
289c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        int[] edges = new int[sorted.length];
290c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        if (mOrientation == BaseGridView.HORIZONTAL) {
291c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            if (mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL) {
292c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                for (int i = 0; i < sorted.length; i++) {
293c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                    edges[i] = sorted[i][0].getLeft();
294c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                }
295c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            } else {
296c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                for (int i = 0; i < sorted.length; i++) {
297c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                    edges[i] = sorted[i][sorted[i].length - 1].getRight();
298c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                }
299c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            }
300c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        } else {
301c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            for (int i = 0; i < sorted.length; i++) {
302c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                edges[i] = sorted[i][sorted[i].length - 1].getBottom();
303c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            }
304c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        }
305c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        return edges;
306c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu    }
307c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
308c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu    protected void verifyEdgesSame(int[] edges, int[] edges2) {
309c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        assertEquals(edges.length, edges2.length);
310c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        for (int i = 0; i < edges.length; i++) {
311c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu            assertEquals(edges[i], edges2[i]);
312c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        }
313c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu    }
314c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
31585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    protected void verifyBoundCount(int count) {
31685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        if (mActivity.getBoundCount() != count) {
31785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            StringBuffer b = new StringBuffer();
31885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            b.append("ItemsLength: ");
31985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            for (int i = 0; i < mActivity.mItemLengths.length; i++) {
32085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                b.append(mActivity.mItemLengths[i]).append(",");
32185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            }
32285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu            assertEquals("Bound count does not match, ItemsLengths: "+ b,
32385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                    count, mActivity.getBoundCount());
32485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        }
32585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    }
32685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
3278c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    private static int getCenterY(View v) {
3288c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        return (v.getTop() + v.getBottom())/2;
3298c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    }
330062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
3318c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    private static int getCenterX(View v) {
3328c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        return (v.getLeft() + v.getRight())/2;
3338c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    }
3348c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
3358c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    private void initActivity(Intent intent) {
3368c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        setActivityIntent(intent);
3378c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mActivity = getActivity();
3388c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final String testName = getName();
3398c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        try {
3408c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            runTestOnUiThread(new Runnable() {
3418c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                public void run() {
3428c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                    mActivity.setTitle(testName);
3438c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                }
3448c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            });
3458c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            Thread.sleep(1000);
3468c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        } catch (Throwable t) {
3478c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            t.printStackTrace();
3488c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        }
3498c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mGridView = mActivity.mGridView;
3508c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    }
3518c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
3528c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    public void testThreeRowHorizontalBasic() throws Throwable {
353062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        mInstrumentation = getInstrumentation();
354062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
355247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.horizontal_grid);
356e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 100);
3578c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
358247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
359247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mNumRows = 3;
360062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
361a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
36285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBoundCount(100);
363e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
364a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToBegin(mVerifyLayout);
365062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
366e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        verifyBeginAligned();
367062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu    }
368062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu
369e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    public void testThreeColumnVerticalBasic() throws Throwable {
370e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
371e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        mInstrumentation = getInstrumentation();
372e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
373247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.vertical_grid);
374e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 200);
3758c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
376247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mOrientation = BaseGridView.VERTICAL;
377247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mNumRows = 3;
378e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
379a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
38085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBoundCount(200);
381e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
382a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToBegin(mVerifyLayout);
38385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
38485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBeginAligned();
38585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    }
38685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
38785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    public void testRedundantAppendRemove() throws Throwable {
38885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mInstrumentation = getInstrumentation();
38985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
390247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
391247741d74797105ba4f6d2834ec56dab32c14644Dake Gu                R.layout.vertical_grid_testredundantappendremove);
39285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, new int[]{
39385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                149,177,128,234,227,187,163,223,146,210,228,148,227,193,182,197,177,142,225,207,
39485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                157,171,209,204,187,184,123,221,197,153,202,179,193,214,226,173,225,143,188,159,
39585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                139,193,233,143,227,203,222,124,228,223,164,131,228,126,211,160,165,152,235,184,
39685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                155,224,149,181,171,229,200,234,177,130,164,172,188,139,132,203,179,220,147,131,
39785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                226,127,230,239,183,203,206,227,123,170,239,234,200,149,237,204,160,133,202,234,
39885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                173,122,139,149,151,153,216,231,121,145,227,153,186,174,223,180,123,215,206,216,
39985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                239,222,219,207,193,218,140,133,171,153,183,132,233,138,159,174,189,171,143,128,
40085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                152,222,141,202,224,190,134,120,181,231,230,136,132,224,136,210,207,150,128,183,
40185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                221,194,179,220,126,221,137,205,223,193,172,132,226,209,133,191,227,127,159,171,
40285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                180,149,237,177,194,207,170,202,161,144,147,199,205,186,164,140,193,203,224,129});
4038c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
404247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mOrientation = BaseGridView.VERTICAL;
405247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mNumRows = 3;
40685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
407a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
40885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
40985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBoundCount(200);
410e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
411a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToBegin(mVerifyLayout);
412e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu
413e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu        verifyBeginAligned();
414e7ead88853562603f76b92189a828ba14d5c4bcbDake Gu    }
41585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
41685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    public void testRedundantAppendRemove2() throws Throwable {
41785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mInstrumentation = getInstrumentation();
41885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
419247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
420247741d74797105ba4f6d2834ec56dab32c14644Dake Gu                R.layout.horizontal_grid_testredundantappendremove2);
42185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, new int[]{
42285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                318,333,199,224,246,273,269,289,340,313,265,306,349,269,185,282,257,354,316,252,
42385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                237,290,283,343,196,313,290,343,191,262,342,228,343,349,251,203,226,305,265,213,
42485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                216,333,295,188,187,281,288,311,244,232,224,332,290,181,267,276,226,261,335,355,
42585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                225,217,219,183,234,285,257,304,182,250,244,223,257,219,342,185,347,205,302,315,
42685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                299,309,292,237,192,309,228,250,347,227,337,298,299,185,185,331,223,284,265,351});
4278c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
428247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
429247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mNumRows = 3;
43085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mLayoutManager = (GridLayoutManager) mGridView.getLayoutManager();
43185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
43285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        // test append without staggered result cache
433a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
43485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
43585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBoundCount(100);
436c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        int[] endEdges = getEndEdges();
43785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
438a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToBegin(mVerifyLayout);
43985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
44085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBeginAligned();
44185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
44285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        // now test append with staggered result cache
443f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(3);
44485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        assertEquals("Staggerd cache should be kept as is when no item size change",
44585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu                100, ((StaggeredGrid) mLayoutManager.mGrid).mLocations.size());
44685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
44785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mActivity.resetBoundCount();
448f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(100);
44985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
450a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
45185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBoundCount(100);
452c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
453c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        // we should get same aligned end edges
454c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        int[] endEdges2 = getEndEdges();
455c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        verifyEdgesSame(endEdges, endEdges2);
45685df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    }
45785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
458c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu    public void testItemMovedHorizontal() throws Throwable {
45985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
46085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mInstrumentation = getInstrumentation();
46185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
462247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
463247741d74797105ba4f6d2834ec56dab32c14644Dake Gu                R.layout.horizontal_grid);
46485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 200);
4658c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
466247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
467247741d74797105ba4f6d2834ec56dab32c14644Dake Gu        mNumRows = 3;
46885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
46985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mGridView.setSelectedPositionSmooth(150);
47085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        waitForScrollIdle(mVerifyLayout);
47185df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        mActivity.swap(150, 152);
47285df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        waitForTransientStateGone(null);
47385df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
47485df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        runTestOnUiThread(mVerifyLayout);
47585df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
476a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToBegin(mVerifyLayout);
47785df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
47885df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu        verifyBeginAligned();
47985df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu    }
48085df3117f0fcd0aa10d7bd45194dab97e22112f2Dake Gu
481c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu    public void testItemMovedVertical() throws Throwable {
482c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
483c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        mInstrumentation = getInstrumentation();
484c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
485c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
486c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu                R.layout.vertical_grid);
487c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 200);
4888c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
489c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        mOrientation = BaseGridView.VERTICAL;
490c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        mNumRows = 3;
491c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
492c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        mGridView.setSelectedPositionSmooth(150);
493c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        waitForScrollIdle(mVerifyLayout);
494c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        mActivity.swap(150, 152);
495c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        waitForTransientStateGone(null);
496c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
497c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        runTestOnUiThread(mVerifyLayout);
498c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
4997ee22537e201c3d6b5de2908aecc4b0cc59a05c2Dake Gu        scrollToEnd(mVerifyLayout);
500a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToBegin(mVerifyLayout);
501c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
502c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu        verifyBeginAligned();
503c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu    }
504c755c85c3596bb00f30f7941bac3860a9dc91d7aDake Gu
505ede7fd3c91008fb042c736240534d0d87234f112Dake Gu    public void testItemAddRemoveHorizontal() throws Throwable {
506ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
507ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        mInstrumentation = getInstrumentation();
508ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
509ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
510ede7fd3c91008fb042c736240534d0d87234f112Dake Gu                R.layout.horizontal_grid);
511ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 200);
5128c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
513ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
514ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        mNumRows = 3;
515ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
516a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
517ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        int[] endEdges = getEndEdges();
518ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
519ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        mGridView.setSelectedPositionSmooth(150);
520ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        waitForScrollIdle(mVerifyLayout);
521ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        int[] removedItems = mActivity.removeItems(151, 4);
522ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        waitForTransientStateGone(null);
523ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
524a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
525ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        mGridView.setSelectedPositionSmooth(150);
526ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        waitForScrollIdle(mVerifyLayout);
527ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
528ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        mActivity.addItems(151, removedItems);
529ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        waitForTransientStateGone(null);
530a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToEnd(mVerifyLayout);
531ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
532ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        // we should get same aligned end edges
533ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        int[] endEdges2 = getEndEdges();
534ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        verifyEdgesSame(endEdges, endEdges2);
535ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
536a3c24a53034f1effc24b2d01328d63d96ad2ac7cDake Gu        scrollToBegin(mVerifyLayout);
537ede7fd3c91008fb042c736240534d0d87234f112Dake Gu        verifyBeginAligned();
538ede7fd3c91008fb042c736240534d0d87234f112Dake Gu    }
539ede7fd3c91008fb042c736240534d0d87234f112Dake Gu
54091feb947412e0521a5f1835553214dcbe03fd362Dake Gu    public void testBug22209986() throws Throwable {
54191feb947412e0521a5f1835553214dcbe03fd362Dake Gu
54291feb947412e0521a5f1835553214dcbe03fd362Dake Gu        mInstrumentation = getInstrumentation();
54391feb947412e0521a5f1835553214dcbe03fd362Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
54491feb947412e0521a5f1835553214dcbe03fd362Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
54591feb947412e0521a5f1835553214dcbe03fd362Dake Gu                R.layout.horizontal_linear);
54691feb947412e0521a5f1835553214dcbe03fd362Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 50);
54791feb947412e0521a5f1835553214dcbe03fd362Dake Gu        initActivity(intent);
54891feb947412e0521a5f1835553214dcbe03fd362Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
54991feb947412e0521a5f1835553214dcbe03fd362Dake Gu        mNumRows = 1;
55091feb947412e0521a5f1835553214dcbe03fd362Dake Gu
55191feb947412e0521a5f1835553214dcbe03fd362Dake Gu        final int focusToIndex = mGridView.getChildCount() - 1;
55291feb947412e0521a5f1835553214dcbe03fd362Dake Gu        runTestOnUiThread(new Runnable() {
55391feb947412e0521a5f1835553214dcbe03fd362Dake Gu            public void run() {
55491feb947412e0521a5f1835553214dcbe03fd362Dake Gu                mGridView.setSelectedPositionSmooth(focusToIndex);
55591feb947412e0521a5f1835553214dcbe03fd362Dake Gu            }
55691feb947412e0521a5f1835553214dcbe03fd362Dake Gu        });
55791feb947412e0521a5f1835553214dcbe03fd362Dake Gu
55891feb947412e0521a5f1835553214dcbe03fd362Dake Gu        waitForTransientStateGone(null);
55991feb947412e0521a5f1835553214dcbe03fd362Dake Gu        waitForScrollIdle();
56091feb947412e0521a5f1835553214dcbe03fd362Dake Gu        runTestOnUiThread(new Runnable() {
56191feb947412e0521a5f1835553214dcbe03fd362Dake Gu            public void run() {
56291feb947412e0521a5f1835553214dcbe03fd362Dake Gu                mGridView.setSelectedPositionSmooth(focusToIndex + 1);
56391feb947412e0521a5f1835553214dcbe03fd362Dake Gu            }
56491feb947412e0521a5f1835553214dcbe03fd362Dake Gu        });
56591feb947412e0521a5f1835553214dcbe03fd362Dake Gu        // let the scroll running for a while and requestLayout during scroll
56691feb947412e0521a5f1835553214dcbe03fd362Dake Gu        Thread.sleep(80);
56791feb947412e0521a5f1835553214dcbe03fd362Dake Gu        runTestOnUiThread(new Runnable() {
56891feb947412e0521a5f1835553214dcbe03fd362Dake Gu            public void run() {
56991feb947412e0521a5f1835553214dcbe03fd362Dake Gu                assertEquals(mGridView.getScrollState(), BaseGridView.SCROLL_STATE_SETTLING);
57091feb947412e0521a5f1835553214dcbe03fd362Dake Gu                mGridView.requestLayout();
57191feb947412e0521a5f1835553214dcbe03fd362Dake Gu            }
57291feb947412e0521a5f1835553214dcbe03fd362Dake Gu        });
57391feb947412e0521a5f1835553214dcbe03fd362Dake Gu        waitForTransientStateGone(null);
57491feb947412e0521a5f1835553214dcbe03fd362Dake Gu        waitForScrollIdle();
57591feb947412e0521a5f1835553214dcbe03fd362Dake Gu
57691feb947412e0521a5f1835553214dcbe03fd362Dake Gu        int leftEdge = mGridView.getLayoutManager().findViewByPosition(focusToIndex).getLeft();
57791feb947412e0521a5f1835553214dcbe03fd362Dake Gu
57891feb947412e0521a5f1835553214dcbe03fd362Dake Gu        runTestOnUiThread(new Runnable() {
57991feb947412e0521a5f1835553214dcbe03fd362Dake Gu            public void run() {
58091feb947412e0521a5f1835553214dcbe03fd362Dake Gu                mGridView.requestLayout();
58191feb947412e0521a5f1835553214dcbe03fd362Dake Gu            }
58291feb947412e0521a5f1835553214dcbe03fd362Dake Gu        });
58391feb947412e0521a5f1835553214dcbe03fd362Dake Gu        waitForTransientStateGone(null);
58491feb947412e0521a5f1835553214dcbe03fd362Dake Gu        waitForScrollIdle();
58591feb947412e0521a5f1835553214dcbe03fd362Dake Gu        assertEquals(leftEdge,
58691feb947412e0521a5f1835553214dcbe03fd362Dake Gu                mGridView.getLayoutManager().findViewByPosition(focusToIndex).getLeft());
58791feb947412e0521a5f1835553214dcbe03fd362Dake Gu    }
58891feb947412e0521a5f1835553214dcbe03fd362Dake Gu
589ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu    public void testScrollAndRemove() throws Throwable {
590ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
591ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mInstrumentation = getInstrumentation();
592ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
593ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
594ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                R.layout.horizontal_linear);
595ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 50);
596ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        initActivity(intent);
597ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mOrientation = BaseGridView.HORIZONTAL;
598ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mNumRows = 1;
599ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
600ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        final int focusToIndex = mGridView.getChildCount() - 1;
601ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        runTestOnUiThread(new Runnable() {
602ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            public void run() {
603ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.setSelectedPositionSmooth(focusToIndex);
604ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            }
605ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        });
606ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
607ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        runTestOnUiThread(new Runnable() {
608ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            public void run() {
609ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mActivity.removeItems(focusToIndex, 1);
610ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            }
611ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        });
612ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
613ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForTransientStateGone(null);
614ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForScrollIdle();
615ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        int leftEdge = mGridView.getLayoutManager().findViewByPosition(focusToIndex).getLeft();
616ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
617ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        runTestOnUiThread(new Runnable() {
618ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            public void run() {
619ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.requestLayout();
620ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            }
621ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        });
622ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForTransientStateGone(null);
623ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForScrollIdle();
624ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        assertEquals(leftEdge,
625ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.getLayoutManager().findViewByPosition(focusToIndex).getLeft());
626ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu    }
627ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
6284927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu    public void testScrollAndInsert() throws Throwable {
6294927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu
6304927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        mInstrumentation = getInstrumentation();
6314927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
6324927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
6334927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu                R.layout.vertical_grid);
6344927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        int[] items = new int[1000];
6354927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        for (int i = 0; i < items.length; i++) {
6364927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu            items[i] = 300 + (int)(Math.random() * 100);
6374927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        }
6384927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
6394927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, true);
6404927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        mOrientation = BaseGridView.VERTICAL;
6414927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        mNumRows = 3;
6424927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu
6434927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        initActivity(intent);
6444927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu
6454927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        runTestOnUiThread(new Runnable() {
6464927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu            public void run() {
6474927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu                mGridView.setSelectedPositionSmooth(150);
6484927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu            }
6494927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        });
6504927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        waitForScrollIdle(mVerifyLayout);
6514927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu
6524927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        View view =  mGridView.getChildAt(mGridView.getChildCount() - 1);
6534927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        final int focusToIndex = mGridView.getChildAdapterPosition(view);
6544927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        runTestOnUiThread(new Runnable() {
6554927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu            public void run() {
6564927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu                mGridView.setSelectedPositionSmooth(focusToIndex);
6574927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu            }
6584927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        });
6594927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu
6604927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        runTestOnUiThread(new Runnable() {
6614927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu            public void run() {
6624927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu                int[] newItems = new int[]{300, 300, 300};
6634927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu                mActivity.addItems(0, newItems);
6644927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu            }
6654927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        });
6664927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu
6674927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        waitForTransientStateGone(null);
6684927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        waitForScrollIdle();
6694927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu    }
6704927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu
6714927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu    public void testScrollAndInsertBeforeVisibleItem() throws Throwable {
6724927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu
6734927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        mInstrumentation = getInstrumentation();
6744927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
6754927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
6764927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu                R.layout.vertical_grid);
6774927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        int[] items = new int[1000];
6784927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        for (int i = 0; i < items.length; i++) {
6794927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu            items[i] = 300 + (int)(Math.random() * 100);
6804927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        }
6814927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
6824927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, true);
6834927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        mOrientation = BaseGridView.VERTICAL;
6844927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        mNumRows = 3;
6854927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu
6864927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        initActivity(intent);
6874927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu
6884927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        runTestOnUiThread(new Runnable() {
6894927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu            public void run() {
6904927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu                mGridView.setSelectedPositionSmooth(150);
6914927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu            }
6924927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        });
6934927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        waitForScrollIdle(mVerifyLayout);
6944927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu
6954927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        View view =  mGridView.getChildAt(mGridView.getChildCount() - 1);
6964927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        final int focusToIndex = mGridView.getChildAdapterPosition(view);
6974927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        runTestOnUiThread(new Runnable() {
6984927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu            public void run() {
6994927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu                mGridView.setSelectedPositionSmooth(focusToIndex);
7004927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu            }
7014927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        });
7024927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu
7034927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        runTestOnUiThread(new Runnable() {
7044927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu            public void run() {
7054927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu                int[] newItems = new int[]{300, 300, 300};
7064927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu                mActivity.addItems(focusToIndex, newItems);
7074927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu            }
7084927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        });
7094927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu
7104927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        waitForTransientStateGone(null);
7114927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu        waitForScrollIdle();
7124927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu    }
7134927a3bbd1921aed5da5d276a5d15240b2960faeDake Gu
714ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu    public void testSmoothScrollAndRemove() throws Throwable {
715ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
716ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mInstrumentation = getInstrumentation();
717ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
718ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
719ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                R.layout.horizontal_linear);
720ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 50);
721ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        initActivity(intent);
722ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mOrientation = BaseGridView.HORIZONTAL;
723ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mNumRows = 1;
724ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
725ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        final int focusToIndex = 40;
726ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        runTestOnUiThread(new Runnable() {
727ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            public void run() {
728ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.setSelectedPositionSmooth(focusToIndex);
729ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            }
730ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        });
731ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
732ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        runTestOnUiThread(new Runnable() {
733ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            public void run() {
734ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mActivity.removeItems(focusToIndex, 1);
735ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            }
736ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        });
737ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
738ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        Thread.sleep(20); // wait for layout
739ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        assertTrue("removing the index of not attached child should not affect smooth scroller",
740ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.getLayoutManager().isSmoothScrolling());
741ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForTransientStateGone(null);
742ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForScrollIdle();
743ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        int leftEdge = mGridView.getLayoutManager().findViewByPosition(focusToIndex).getLeft();
744ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
745ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        runTestOnUiThread(new Runnable() {
746ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            public void run() {
747ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.requestLayout();
748ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            }
749ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        });
750ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForTransientStateGone(null);
751ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForScrollIdle();
752ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        assertEquals(leftEdge,
753ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.getLayoutManager().findViewByPosition(focusToIndex).getLeft());
754ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu    }
755ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
756ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu    public void testSmoothScrollAndRemove2() throws Throwable {
757ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
758ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mInstrumentation = getInstrumentation();
759ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
760ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
761ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                R.layout.horizontal_linear);
762ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 50);
763ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        initActivity(intent);
764ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mOrientation = BaseGridView.HORIZONTAL;
765ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mNumRows = 1;
766ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
767ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        final int focusToIndex = 40;
768ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        runTestOnUiThread(new Runnable() {
769ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            public void run() {
770ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.setSelectedPositionSmooth(focusToIndex);
771ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            }
772ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        });
773ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
774ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        final int removeIndex = mGridView.getChildCount() - 1;
775ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        runTestOnUiThread(new Runnable() {
776ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            public void run() {
777ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mActivity.removeItems(removeIndex, 1);
778ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            }
779ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        });
780ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
781ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        Thread.sleep(20); // wait for layout
782ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        assertFalse("removing the index of attached child should kill smooth scroller",
783ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.getLayoutManager().isSmoothScrolling());
784ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForTransientStateGone(null);
785ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForScrollIdle();
786ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        int leftEdge = mGridView.getLayoutManager().findViewByPosition(focusToIndex).getLeft();
787ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
788ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        runTestOnUiThread(new Runnable() {
789ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            public void run() {
790ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.requestLayout();
791ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            }
792ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        });
793ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForTransientStateGone(null);
794ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForScrollIdle();
795ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        assertEquals(leftEdge,
796ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.getLayoutManager().findViewByPosition(focusToIndex).getLeft());
797ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu    }
798ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
799ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu    public void testPendingSmoothScrollAndRemove() throws Throwable {
800ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mInstrumentation = getInstrumentation();
801ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
802ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
803ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                R.layout.vertical_linear);
804ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
805ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        int[] items = new int[100];
806ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        for (int i = 0; i < items.length; i++) {
807ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            items[i] = 630 + (int)(Math.random() * 100);
808ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        }
809ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
810ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, true);
811ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mOrientation = BaseGridView.VERTICAL;
812ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mNumRows = 1;
813ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
814ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        initActivity(intent);
815ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
816ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mGridView.setSelectedPositionSmooth(0);
817ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForScrollIdle(mVerifyLayout);
818ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        assertTrue(mGridView.getChildAt(0).hasFocus());
819ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
820ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        // Pressing lots of key to make sure smooth scroller is running
821ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        for (int i = 0; i < 20; i++) {
822ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
823ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        }
824ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        Thread.sleep(100);
825ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
826ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        assertTrue(mGridView.getLayoutManager().isSmoothScrolling());
827ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        final int removeIndex = mGridView.getChildCount() - 1;
828ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        runTestOnUiThread(new Runnable() {
829ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            public void run() {
830ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mActivity.removeItems(removeIndex, 1);
831ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            }
832ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        });
833ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
834ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        Thread.sleep(20); // wait for layout
835ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        assertFalse("removing the index of attached child should kill smooth scroller",
836ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.getLayoutManager().isSmoothScrolling());
837ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
838ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForTransientStateGone(null);
839ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForScrollIdle();
840ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        int focusIndex = mGridView.getSelectedPosition();
841ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        int leftEdge = mGridView.getLayoutManager().findViewByPosition(focusIndex).getLeft();
842ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
843ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        runTestOnUiThread(new Runnable() {
844ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            public void run() {
845ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.requestLayout();
846ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            }
847ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        });
848ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForTransientStateGone(null);
849ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForScrollIdle();
850ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        assertEquals(leftEdge,
851ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.getLayoutManager().findViewByPosition(focusIndex).getLeft());
852ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu    }
853ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
8549c56475370d1df940252ff1360b92de50022fff6Dake Gu    public void testFocusToFirstItem() throws Throwable {
8559c56475370d1df940252ff1360b92de50022fff6Dake Gu
8569c56475370d1df940252ff1360b92de50022fff6Dake Gu        mInstrumentation = getInstrumentation();
8579c56475370d1df940252ff1360b92de50022fff6Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
8589c56475370d1df940252ff1360b92de50022fff6Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
8599c56475370d1df940252ff1360b92de50022fff6Dake Gu                R.layout.horizontal_grid);
8609c56475370d1df940252ff1360b92de50022fff6Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 200);
8619c56475370d1df940252ff1360b92de50022fff6Dake Gu        initActivity(intent);
8629c56475370d1df940252ff1360b92de50022fff6Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
8639c56475370d1df940252ff1360b92de50022fff6Dake Gu        mNumRows = 3;
8649c56475370d1df940252ff1360b92de50022fff6Dake Gu
8659c56475370d1df940252ff1360b92de50022fff6Dake Gu        int[] removedItems = mActivity.removeItems(0, 200);
8669c56475370d1df940252ff1360b92de50022fff6Dake Gu
8679c56475370d1df940252ff1360b92de50022fff6Dake Gu        waitForTransientStateGone(null);
868f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
8699c56475370d1df940252ff1360b92de50022fff6Dake Gu        mActivity.addItems(0, removedItems);
8709c56475370d1df940252ff1360b92de50022fff6Dake Gu
8719c56475370d1df940252ff1360b92de50022fff6Dake Gu        waitForTransientStateGone(null);
872f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
8739c56475370d1df940252ff1360b92de50022fff6Dake Gu        assertTrue(mGridView.getLayoutManager().findViewByPosition(0).hasFocus());
8749c56475370d1df940252ff1360b92de50022fff6Dake Gu
875f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(0);
8769c56475370d1df940252ff1360b92de50022fff6Dake Gu
877f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(200);
8789c56475370d1df940252ff1360b92de50022fff6Dake Gu        assertTrue(mGridView.getLayoutManager().findViewByPosition(0).hasFocus());
8799c56475370d1df940252ff1360b92de50022fff6Dake Gu    }
8809c56475370d1df940252ff1360b92de50022fff6Dake Gu
88177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu    public void testNonFocusableHorizontal() throws Throwable {
88277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int numItems = 200;
88377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int startPos = 45;
88477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int skips = 20;
88577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int numColumns = 3;
88677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int endPos = startPos + numColumns * (skips + 1);
88777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
88877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mInstrumentation = getInstrumentation();
88977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
89077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
89177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu                R.layout.horizontal_grid);
89277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, numItems);
89377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
89477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mOrientation = BaseGridView.HORIZONTAL;
89577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mNumRows = numColumns;
89677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        boolean[] focusable = new boolean[numItems];
89777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        for (int i = 0; i < focusable.length; i++) {
89877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            focusable[i] = true;
89977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
90077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        for (int i = startPos + mNumRows, j = 0; j < skips; i += mNumRows, j++) {
90177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            focusable[i] = false;
90277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
90377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS_FOCUSABLE, focusable);
9048c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
90577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
90677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mGridView.setSelectedPositionSmooth(startPos);
90777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
90877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
90977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        if (mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL) {
91077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
91177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        } else {
91277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
91377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
91477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
91577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        assertEquals(endPos, mGridView.getSelectedPosition());
91677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
91777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        if (mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL) {
91877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
91977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        } else {
92077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
92177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
92277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
92377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        assertEquals(startPos, mGridView.getSelectedPosition());
92477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
92577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu    }
92677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
92789b4aed6fcd80f940531e265936ab908a8037f87Dake Gu    public void testNoInitialFocusable() throws Throwable {
92889b4aed6fcd80f940531e265936ab908a8037f87Dake Gu
92989b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        mInstrumentation = getInstrumentation();
93089b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
93189b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
93289b4aed6fcd80f940531e265936ab908a8037f87Dake Gu                R.layout.horizontal_linear);
93389b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        final int numItems = 100;
93489b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, numItems);
93589b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
93689b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
93789b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        mNumRows = 1;
93889b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        boolean[] focusable = new boolean[numItems];
93989b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        final int firstFocusableIndex = 10;
94089b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        for (int i = 0; i < firstFocusableIndex; i++) {
94189b4aed6fcd80f940531e265936ab908a8037f87Dake Gu            focusable[i] = false;
94289b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        }
94389b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        for (int i = firstFocusableIndex; i < focusable.length; i++) {
94489b4aed6fcd80f940531e265936ab908a8037f87Dake Gu            focusable[i] = true;
94589b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        }
94689b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS_FOCUSABLE, focusable);
94789b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        initActivity(intent);
94889b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        assertTrue(mGridView.isFocused());
94989b4aed6fcd80f940531e265936ab908a8037f87Dake Gu
95089b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        if (mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL) {
95189b4aed6fcd80f940531e265936ab908a8037f87Dake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
95289b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        } else {
95389b4aed6fcd80f940531e265936ab908a8037f87Dake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
95489b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        }
95589b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        waitForScrollIdle(mVerifyLayout);
95689b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        assertEquals(firstFocusableIndex, mGridView.getSelectedPosition());
95789b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        assertTrue(mGridView.getLayoutManager().findViewByPosition(firstFocusableIndex).hasFocus());
95889b4aed6fcd80f940531e265936ab908a8037f87Dake Gu    }
95989b4aed6fcd80f940531e265936ab908a8037f87Dake Gu
96006388129e48b308b25bfd85e6f136db8528d4c62Dake Gu    public void testFocusOutOfEmptyListView() throws Throwable {
96106388129e48b308b25bfd85e6f136db8528d4c62Dake Gu
96206388129e48b308b25bfd85e6f136db8528d4c62Dake Gu        mInstrumentation = getInstrumentation();
96306388129e48b308b25bfd85e6f136db8528d4c62Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
96406388129e48b308b25bfd85e6f136db8528d4c62Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
96506388129e48b308b25bfd85e6f136db8528d4c62Dake Gu                R.layout.horizontal_linear);
96606388129e48b308b25bfd85e6f136db8528d4c62Dake Gu        final int numItems = 100;
96706388129e48b308b25bfd85e6f136db8528d4c62Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, numItems);
96806388129e48b308b25bfd85e6f136db8528d4c62Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
96906388129e48b308b25bfd85e6f136db8528d4c62Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
97006388129e48b308b25bfd85e6f136db8528d4c62Dake Gu        mNumRows = 1;
97106388129e48b308b25bfd85e6f136db8528d4c62Dake Gu        initActivity(intent);
97206388129e48b308b25bfd85e6f136db8528d4c62Dake Gu
97306388129e48b308b25bfd85e6f136db8528d4c62Dake Gu        final View horizontalGridView = new HorizontalGridViewEx(mGridView.getContext());
97406388129e48b308b25bfd85e6f136db8528d4c62Dake Gu        runTestOnUiThread(new Runnable() {
97506388129e48b308b25bfd85e6f136db8528d4c62Dake Gu            @Override
97606388129e48b308b25bfd85e6f136db8528d4c62Dake Gu            public void run() {
97706388129e48b308b25bfd85e6f136db8528d4c62Dake Gu                horizontalGridView.setFocusable(true);
97806388129e48b308b25bfd85e6f136db8528d4c62Dake Gu                horizontalGridView.setFocusableInTouchMode(true);
97906388129e48b308b25bfd85e6f136db8528d4c62Dake Gu                horizontalGridView.setLayoutParams(new ViewGroup.LayoutParams(100, 100));
98006388129e48b308b25bfd85e6f136db8528d4c62Dake Gu                ((ViewGroup) mGridView.getParent()).addView(horizontalGridView, 0);
98106388129e48b308b25bfd85e6f136db8528d4c62Dake Gu                horizontalGridView.requestFocus();
98206388129e48b308b25bfd85e6f136db8528d4c62Dake Gu            }
98306388129e48b308b25bfd85e6f136db8528d4c62Dake Gu        });
98406388129e48b308b25bfd85e6f136db8528d4c62Dake Gu
98506388129e48b308b25bfd85e6f136db8528d4c62Dake Gu        assertTrue(horizontalGridView.isFocused());
98606388129e48b308b25bfd85e6f136db8528d4c62Dake Gu
98706388129e48b308b25bfd85e6f136db8528d4c62Dake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
98806388129e48b308b25bfd85e6f136db8528d4c62Dake Gu
98906388129e48b308b25bfd85e6f136db8528d4c62Dake Gu        assertTrue(mGridView.hasFocus());
99006388129e48b308b25bfd85e6f136db8528d4c62Dake Gu    }
99106388129e48b308b25bfd85e6f136db8528d4c62Dake Gu
99289b4aed6fcd80f940531e265936ab908a8037f87Dake Gu    public void testTransferFocusToChildWhenGainFocus() throws Throwable {
99389b4aed6fcd80f940531e265936ab908a8037f87Dake Gu
99489b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        mInstrumentation = getInstrumentation();
99589b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
99689b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
99789b4aed6fcd80f940531e265936ab908a8037f87Dake Gu                R.layout.horizontal_linear);
99889b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        final int numItems = 100;
99989b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, numItems);
100089b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
100189b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
100289b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        mNumRows = 1;
100389b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        boolean[] focusable = new boolean[numItems];
100489b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        final int firstFocusableIndex = 1;
100589b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        for (int i = 0; i < firstFocusableIndex; i++) {
100689b4aed6fcd80f940531e265936ab908a8037f87Dake Gu            focusable[i] = false;
100789b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        }
100889b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        for (int i = firstFocusableIndex; i < focusable.length; i++) {
100989b4aed6fcd80f940531e265936ab908a8037f87Dake Gu            focusable[i] = true;
101089b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        }
101189b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS_FOCUSABLE, focusable);
101289b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        initActivity(intent);
101389b4aed6fcd80f940531e265936ab908a8037f87Dake Gu
101489b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        assertEquals(firstFocusableIndex, mGridView.getSelectedPosition());
101589b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        assertTrue(mGridView.getLayoutManager().findViewByPosition(firstFocusableIndex).hasFocus());
101689b4aed6fcd80f940531e265936ab908a8037f87Dake Gu    }
101789b4aed6fcd80f940531e265936ab908a8037f87Dake Gu
101889b4aed6fcd80f940531e265936ab908a8037f87Dake Gu    public void testFocusFromSecondChild() throws Throwable {
101989b4aed6fcd80f940531e265936ab908a8037f87Dake Gu
102089b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        mInstrumentation = getInstrumentation();
102189b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
102289b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
102389b4aed6fcd80f940531e265936ab908a8037f87Dake Gu                R.layout.horizontal_linear);
102489b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        final int numItems = 100;
102589b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, numItems);
102689b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
102789b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
102889b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        mNumRows = 1;
102989b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        boolean[] focusable = new boolean[numItems];
103089b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        for (int i = 0; i < focusable.length; i++) {
103189b4aed6fcd80f940531e265936ab908a8037f87Dake Gu            focusable[i] = false;
103289b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        }
103389b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS_FOCUSABLE, focusable);
103489b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        initActivity(intent);
103589b4aed6fcd80f940531e265936ab908a8037f87Dake Gu
103689b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        // switching Adapter to cause a full rebind,  test if it will focus to second item.
103789b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        runTestOnUiThread(new Runnable() {
103889b4aed6fcd80f940531e265936ab908a8037f87Dake Gu            @Override
103989b4aed6fcd80f940531e265936ab908a8037f87Dake Gu            public void run() {
104089b4aed6fcd80f940531e265936ab908a8037f87Dake Gu                mActivity.mNumItems = numItems;
104189b4aed6fcd80f940531e265936ab908a8037f87Dake Gu                mActivity.mItemFocusables[1] = true;
104289b4aed6fcd80f940531e265936ab908a8037f87Dake Gu                mActivity.rebindToNewAdapter();
104389b4aed6fcd80f940531e265936ab908a8037f87Dake Gu            }
104489b4aed6fcd80f940531e265936ab908a8037f87Dake Gu        });
104589b4aed6fcd80f940531e265936ab908a8037f87Dake Gu    }
104677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
104777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu    public void testNonFocusableVertical() throws Throwable {
104877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int numItems = 200;
104977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int startPos = 44;
105077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int skips = 20;
105177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int numColumns = 3;
105277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int endPos = startPos + numColumns * (skips + 1);
105377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
105477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mInstrumentation = getInstrumentation();
105577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
105677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
105777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu                R.layout.vertical_grid);
105877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, numItems);
105977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
106077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mOrientation = BaseGridView.VERTICAL;
106177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mNumRows = numColumns;
106277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        boolean[] focusable = new boolean[numItems];
106377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        for (int i = 0; i < focusable.length; i++) {
106477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            focusable[i] = true;
106577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
106677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        for (int i = startPos + mNumRows, j = 0; j < skips; i += mNumRows, j++) {
106777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            focusable[i] = false;
106877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
106977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS_FOCUSABLE, focusable);
10708c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
107177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
107277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mGridView.setSelectedPositionSmooth(startPos);
107377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
107477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
107577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
107677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
107777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        assertEquals(endPos, mGridView.getSelectedPosition());
107877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
107977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
108077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
108177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        assertEquals(startPos, mGridView.getSelectedPosition());
108277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
108377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu    }
10846b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
10856b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu    public void testTransferFocusable() throws Throwable {
10866b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int numItems = 200;
10876b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int numColumns = 3;
10886b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int startPos = 1;
10896b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
10906b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mInstrumentation = getInstrumentation();
10916b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
10926b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
10936b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu                R.layout.horizontal_grid);
10946b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, numItems);
10956b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
10966b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mOrientation = BaseGridView.HORIZONTAL;
10976b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mNumRows = numColumns;
10986b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        boolean[] focusable = new boolean[numItems];
10996b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        for (int i = 0; i < focusable.length; i++) {
11006b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu            focusable[i] = true;
11016b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        }
11026b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        for (int i = 0; i < startPos; i++) {
11036b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu            focusable[i] = false;
11046b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        }
11056b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS_FOCUSABLE, focusable);
11068c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
11076b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
1108f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(0);
11096b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        assertTrue(mGridView.isFocused());
11106b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
1111f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(numItems);
11126b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        assertTrue(mGridView.getLayoutManager().findViewByPosition(startPos).hasFocus());
11136b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu    }
11146b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
11156b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu    public void testTransferFocusable2() throws Throwable {
11166b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int numItems = 200;
11176b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int numColumns = 3;
11186b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int startPos = 10;
11196b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
11206b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mInstrumentation = getInstrumentation();
11216b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
11226b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
11236b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu                R.layout.horizontal_grid);
11246b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, numItems);
11256b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, true);
11266b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mOrientation = BaseGridView.HORIZONTAL;
11276b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mNumRows = numColumns;
11286b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        boolean[] focusable = new boolean[numItems];
11296b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        for (int i = 0; i < focusable.length; i++) {
11306b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu            focusable[i] = true;
11316b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        }
11326b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        for (int i = 0; i < startPos; i++) {
11336b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu            focusable[i] = false;
11346b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        }
11356b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS_FOCUSABLE, focusable);
11368c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
11376b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
1138f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(0);
11396b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        assertTrue(mGridView.isFocused());
11406b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
1141f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(numItems);
11426b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        assertTrue(mGridView.getLayoutManager().findViewByPosition(startPos).hasFocus());
11436b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu    }
1144fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
11458c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    public void testNonFocusableLoseInFastLayout() throws Throwable {
1146fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        mInstrumentation = getInstrumentation();
1147fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1148fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1149fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu                R.layout.vertical_linear);
1150fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        int[] items = new int[300];
1151fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        for (int i = 0; i < items.length; i++) {
1152fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu            items[i] = 480;
1153fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        }
1154fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
1155fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
1156fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_LAYOUT_ONFOCUS, true);
1157fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        mOrientation = BaseGridView.VERTICAL;
1158fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        mNumRows = 1;
1159fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        int pressDown = 15;
1160fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
11618c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
1162fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
1163fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        mGridView.setSelectedPositionSmooth(0);
1164f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        waitForScrollIdle(mVerifyLayout);
1165fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
1166fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        for (int i = 0; i < pressDown; i++) {
1167fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
1168fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        }
1169fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        waitForScrollIdle(mVerifyLayout);
1170fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        assertFalse(mGridView.isFocused());
1171fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
1172fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu    }
1173fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
11748c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    public void testSetSelectionWithDelta() throws Throwable {
11758c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mInstrumentation = getInstrumentation();
11768c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
11778c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
11788c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                R.layout.vertical_linear);
11798c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 300);
11808c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
11818c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mOrientation = BaseGridView.VERTICAL;
11828c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mNumRows = 1;
11838c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
11848c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
11858c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
11868c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
11878c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
11888c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(3);
11898c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
11908c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
11918c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
11928c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top1 = mGridView.getLayoutManager().findViewByPosition(3).getTop();
11938c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
1194f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(1000);
11958c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
11968c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to position with delta
1197f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(3, 100);
11988c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top2 = mGridView.getLayoutManager().findViewByPosition(3).getTop();
11998c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top2);
12008c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
12018c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to same position without delta, it will be reset
1202f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(3, 0);
12038c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top3 = mGridView.getLayoutManager().findViewByPosition(3).getTop();
12048c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top3);
12058c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
12068c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item after last visible item
12078c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int lastVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
12088c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getLastVisibleIndex();
1209f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(lastVisiblePos + 1, 100);
12108c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top4 = mGridView.getLayoutManager().findViewByPosition(lastVisiblePos + 1).getTop();
12118c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top4);
12128c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
12138c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item before first visible item
12148c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int firstVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
12158c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getFirstVisibleIndex();
1216f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(firstVisiblePos - 1, 100);
12178c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top5 = mGridView.getLayoutManager().findViewByPosition(firstVisiblePos - 1).getTop();
12188c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top5);
12198c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
12208c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
1221f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(50, 100);
12228c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top6 = mGridView.getLayoutManager().findViewByPosition(50).getTop();
12238c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top6);
12248c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
12258c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
12268c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
12278c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
12288c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(100);
12298c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
12308c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
12318c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
12328c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top7 = mGridView.getLayoutManager().findViewByPosition(100).getTop();
12338c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top7);
12348c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
12358c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
1236f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(10, 50);
12378c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top8 = mGridView.getLayoutManager().findViewByPosition(10).getTop();
12388c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 50, top8);
12398c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    }
12408c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
12418c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    public void testSetSelectionWithDeltaInGrid() throws Throwable {
12428c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mInstrumentation = getInstrumentation();
12438c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
12448c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
12458c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                R.layout.vertical_grid);
12468c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 500);
12478c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, true);
12488c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mOrientation = BaseGridView.VERTICAL;
12498c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mNumRows = 3;
12508c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
12518c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
12528c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
12538c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
12548c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
12558c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(10);
12568c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
12578c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
12588c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
12598c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top1 = getCenterY(mGridView.getLayoutManager().findViewByPosition(10));
12608c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
1261f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
12628c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
12638c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to position with delta
1264f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(20, 100);
12658c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top2 = getCenterY(mGridView.getLayoutManager().findViewByPosition(20));
12668c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top2);
12678c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
12688c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to same position without delta, it will be reset
1269f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(20, 0);
12708c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top3 = getCenterY(mGridView.getLayoutManager().findViewByPosition(20));
12718c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top3);
12728c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
12738c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item after last visible item
12748c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int lastVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
12758c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getLastVisibleIndex();
1276f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(lastVisiblePos + 1, 100);
12778c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top4 = getCenterY(mGridView.getLayoutManager().findViewByPosition(lastVisiblePos + 1));
12788c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        verifyMargin();
12798c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top4);
12808c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
12818c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item before first visible item
12828c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int firstVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
12838c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getFirstVisibleIndex();
1284f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(firstVisiblePos - 1, 100);
12858c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top5 = getCenterY(mGridView.getLayoutManager().findViewByPosition(firstVisiblePos - 1));
12868c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top5);
12878c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
12888c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
1289f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(100, 100);
12908c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top6 = getCenterY(mGridView.getLayoutManager().findViewByPosition(100));
12918c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top6);
12928c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
12938c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
12948c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
12958c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
12968c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(200);
12978c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
12988c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
12998c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
13008c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Thread.sleep(500);
13018c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top7 = getCenterY(mGridView.getLayoutManager().findViewByPosition(200));
13028c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top7);
13038c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
13048c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
1305f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(10, 50);
13068c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top8 = getCenterY(mGridView.getLayoutManager().findViewByPosition(10));
13078c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 50, top8);
13088c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    }
13098c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
13108c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
13118c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    public void testSetSelectionWithDeltaInGrid1() throws Throwable {
13128c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mInstrumentation = getInstrumentation();
13138c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
13148c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
13158c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                R.layout.vertical_grid);
13168c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, new int[]{
13178c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                193,176,153,141,203,184,232,139,177,206,222,136,132,237,172,137,
13188c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                188,172,163,213,158,219,209,147,133,229,170,197,138,215,188,205,
13198c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                223,192,225,170,195,127,229,229,210,195,134,142,160,139,130,222,
13208c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                150,163,180,176,157,137,234,169,159,167,182,150,224,231,202,236,
13218c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                123,140,181,223,120,185,183,221,123,210,134,158,166,208,149,128,
13228c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                192,214,212,198,133,140,158,133,229,173,226,141,180,128,127,218,
13238c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                192,235,183,213,216,150,143,193,125,141,219,210,195,195,192,191,
13248c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                212,236,157,189,160,220,147,158,220,199,233,231,201,180,168,141,
13258c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                156,204,191,183,190,153,123,210,238,151,139,221,223,200,175,191,
13268c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                132,184,197,204,236,157,230,151,195,219,212,143,172,149,219,184,
13278c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                164,211,132,187,172,142,174,146,127,147,206,238,188,129,199,226,
13288c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                132,220,210,159,235,153,208,182,196,123,180,159,131,135,175,226,
13298c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                127,134,237,211,133,225,132,124,160,226,224,200,173,137,217,169,
13308c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                182,183,176,185,122,168,195,159,172,129,126,129,166,136,149,220,
13318c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                178,191,192,238,180,208,234,154,222,206,239,228,129,140,203,125,
13328c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                214,175,125,169,196,132,234,138,192,142,234,190,215,232,239,122,
13338c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                188,158,128,221,159,237,207,157,232,138,132,214,122,199,121,191,
13348c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                199,209,126,164,175,187,173,186,194,224,191,196,146,208,213,210,
13358c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                164,176,202,213,123,157,179,138,217,129,186,166,237,211,157,130,
13368c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                137,132,171,232,216,239,180,151,137,132,190,133,218,155,171,227,
13378c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                193,147,197,164,120,218,193,154,170,196,138,222,161,235,143,154,
13388c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                192,178,228,195,178,133,203,178,173,206,178,212,136,157,169,124,
13398c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                172,121,128,223,238,125,217,187,184,156,169,215,231,124,210,174,
13408c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                146,226,185,134,223,228,183,182,136,133,199,146,180,233,226,225,
13418c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                174,233,145,235,216,170,192,171,132,132,134,223,233,148,154,162,
13428c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                192,179,197,203,139,197,174,187,135,132,180,136,192,195,124,221,
13438c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                120,189,233,233,146,225,234,163,215,143,132,198,156,205,151,190,
13448c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                204,239,221,229,123,138,134,217,219,136,218,215,167,139,195,125,
13458c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                202,225,178,226,145,208,130,194,228,197,157,215,124,147,174,123,
13468c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                237,140,172,181,161,151,229,216,199,199,179,213,146,122,222,162,
13478c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                139,173,165,150,160,217,207,137,165,175,129,158,134,133,178,199,
13488c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                215,213,122,197
13498c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
13508c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, true);
13518c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mOrientation = BaseGridView.VERTICAL;
13528c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mNumRows = 3;
13538c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
13548c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
13558c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
13568c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
13578c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
13588c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(10);
13598c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
13608c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
13618c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
13628c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top1 = getCenterY(mGridView.getLayoutManager().findViewByPosition(10));
13638c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
1364f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
13658c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
13668c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to position with delta
1367f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(20, 100);
13688c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top2 = getCenterY(mGridView.getLayoutManager().findViewByPosition(20));
13698c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top2);
13708c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
13718c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to same position without delta, it will be reset
1372f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(20, 0);
13738c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top3 = getCenterY(mGridView.getLayoutManager().findViewByPosition(20));
13748c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top3);
13758c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
13768c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item after last visible item
13778c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int lastVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
13788c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getLastVisibleIndex();
1379f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(lastVisiblePos + 1, 100);
13808c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top4 = getCenterY(mGridView.getLayoutManager().findViewByPosition(lastVisiblePos + 1));
13818c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        verifyMargin();
13828c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top4);
13838c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
13848c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item before first visible item
13858c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int firstVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
13868c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getFirstVisibleIndex();
1387f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(firstVisiblePos - 1, 100);
13888c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top5 = getCenterY(mGridView.getLayoutManager().findViewByPosition(firstVisiblePos - 1));
13898c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top5);
13908c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
13918c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
1392f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(100, 100);
13938c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top6 = getCenterY(mGridView.getLayoutManager().findViewByPosition(100));
13948c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top6);
13958c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
13968c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
13978c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
13988c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
13998c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(200);
14008c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
14018c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
14028c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
14038c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Thread.sleep(500);
14048c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top7 = getCenterY(mGridView.getLayoutManager().findViewByPosition(200));
14058c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top7);
14068c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
14078c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
1408f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(10, 50);
14098c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top8 = getCenterY(mGridView.getLayoutManager().findViewByPosition(10));
14108c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 50, top8);
14118c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    }
1412f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1413f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu    public void testSmoothScrollSelectionEvents() throws Throwable {
1414f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mInstrumentation = getInstrumentation();
1415f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1416f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1417f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                R.layout.vertical_grid);
1418f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 500);
1419f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
1420f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mOrientation = BaseGridView.VERTICAL;
1421f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mNumRows = 3;
1422f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        initActivity(intent);
1423f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1424f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        runTestOnUiThread(new Runnable() {
1425f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            public void run() {
1426f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                mGridView.setSelectedPositionSmooth(30);
1427f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            }
1428f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        });
1429f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        waitForScrollIdle(mVerifyLayout);
1430f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
1431f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1432f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        final ArrayList<Integer> selectedPositions = new ArrayList<Integer>();
1433f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mGridView.setOnChildSelectedListener(new OnChildSelectedListener() {
1434f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            @Override
1435f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            public void onChildSelected(ViewGroup parent, View view, int position, long id) {
1436f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                selectedPositions.add(position);
1437f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            }
1438f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        });
1439f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1440f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        sendRepeatedKeys(10, KeyEvent.KEYCODE_DPAD_UP);
1441f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
1442f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        waitForScrollIdle(mVerifyLayout);
1443f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        // should only get childselected event for item 0 once
1444f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        assertTrue(selectedPositions.size() > 0);
1445f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        assertEquals(0, selectedPositions.get(selectedPositions.size() - 1).intValue());
1446f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        for (int i = selectedPositions.size() - 2; i >= 0; i--) {
1447f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            assertFalse(0 == selectedPositions.get(i).intValue());
1448f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        }
1449f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1450f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu    }
1451f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1452f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu    public void testSmoothScrollSelectionEventsLinear() throws Throwable {
1453f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mInstrumentation = getInstrumentation();
1454f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1455f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1456f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                R.layout.vertical_linear);
1457f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 500);
1458f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
1459f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mOrientation = BaseGridView.VERTICAL;
1460f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mNumRows = 1;
1461f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        initActivity(intent);
1462f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1463f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        runTestOnUiThread(new Runnable() {
1464f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            public void run() {
1465f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                mGridView.setSelectedPositionSmooth(10);
1466f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            }
1467f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        });
1468f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        waitForScrollIdle(mVerifyLayout);
1469f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
1470f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1471f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        final ArrayList<Integer> selectedPositions = new ArrayList<Integer>();
1472f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mGridView.setOnChildSelectedListener(new OnChildSelectedListener() {
1473f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            @Override
1474f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            public void onChildSelected(ViewGroup parent, View view, int position, long id) {
1475f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                selectedPositions.add(position);
1476f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            }
1477f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        });
1478f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1479f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        sendRepeatedKeys(10, KeyEvent.KEYCODE_DPAD_UP);
1480f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
1481f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        waitForScrollIdle(mVerifyLayout);
1482f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        // should only get childselected event for item 0 once
1483f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        assertTrue(selectedPositions.size() > 0);
1484f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        assertEquals(0, selectedPositions.get(selectedPositions.size() - 1).intValue());
1485f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        for (int i = selectedPositions.size() - 2; i >= 0; i--) {
1486f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            assertFalse(0 == selectedPositions.get(i).intValue());
1487f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        }
1488f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1489f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu    }
14907538845719cd1e588185ce9ae60320377862ef8dDake Gu
14917538845719cd1e588185ce9ae60320377862ef8dDake Gu    public void testScrollToNoneExisting() throws Throwable {
14927538845719cd1e588185ce9ae60320377862ef8dDake Gu        mInstrumentation = getInstrumentation();
14937538845719cd1e588185ce9ae60320377862ef8dDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
14947538845719cd1e588185ce9ae60320377862ef8dDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
14957538845719cd1e588185ce9ae60320377862ef8dDake Gu                R.layout.vertical_grid);
14967538845719cd1e588185ce9ae60320377862ef8dDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 100);
14977538845719cd1e588185ce9ae60320377862ef8dDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
14987538845719cd1e588185ce9ae60320377862ef8dDake Gu        mOrientation = BaseGridView.VERTICAL;
14997538845719cd1e588185ce9ae60320377862ef8dDake Gu        mNumRows = 3;
15007538845719cd1e588185ce9ae60320377862ef8dDake Gu        initActivity(intent);
15017538845719cd1e588185ce9ae60320377862ef8dDake Gu
15027538845719cd1e588185ce9ae60320377862ef8dDake Gu        runTestOnUiThread(new Runnable() {
15037538845719cd1e588185ce9ae60320377862ef8dDake Gu            public void run() {
15047538845719cd1e588185ce9ae60320377862ef8dDake Gu                mGridView.setSelectedPositionSmooth(99);
15057538845719cd1e588185ce9ae60320377862ef8dDake Gu            }
15067538845719cd1e588185ce9ae60320377862ef8dDake Gu        });
15077538845719cd1e588185ce9ae60320377862ef8dDake Gu        waitForScrollIdle(mVerifyLayout);
15087538845719cd1e588185ce9ae60320377862ef8dDake Gu        humanDelay(500);
15097538845719cd1e588185ce9ae60320377862ef8dDake Gu
15107538845719cd1e588185ce9ae60320377862ef8dDake Gu
15117538845719cd1e588185ce9ae60320377862ef8dDake Gu        runTestOnUiThread(new Runnable() {
15127538845719cd1e588185ce9ae60320377862ef8dDake Gu            public void run() {
15137538845719cd1e588185ce9ae60320377862ef8dDake Gu                mGridView.setSelectedPositionSmooth(50);
15147538845719cd1e588185ce9ae60320377862ef8dDake Gu            }
15157538845719cd1e588185ce9ae60320377862ef8dDake Gu        });
15167538845719cd1e588185ce9ae60320377862ef8dDake Gu        Thread.sleep(100);
15177538845719cd1e588185ce9ae60320377862ef8dDake Gu        runTestOnUiThread(new Runnable() {
15187538845719cd1e588185ce9ae60320377862ef8dDake Gu            public void run() {
15197538845719cd1e588185ce9ae60320377862ef8dDake Gu                mGridView.requestLayout();
15207538845719cd1e588185ce9ae60320377862ef8dDake Gu                mGridView.setSelectedPositionSmooth(0);
15217538845719cd1e588185ce9ae60320377862ef8dDake Gu            }
15227538845719cd1e588185ce9ae60320377862ef8dDake Gu        });
15237538845719cd1e588185ce9ae60320377862ef8dDake Gu        waitForScrollIdle(mVerifyLayout);
15247538845719cd1e588185ce9ae60320377862ef8dDake Gu        humanDelay(500);
15257538845719cd1e588185ce9ae60320377862ef8dDake Gu
15267538845719cd1e588185ce9ae60320377862ef8dDake Gu    }
15277538845719cd1e588185ce9ae60320377862ef8dDake Gu
15283a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu    public void testSmoothscrollerInterrupted() throws Throwable {
15293a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        mInstrumentation = getInstrumentation();
15303a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
15313a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
15323a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                R.layout.vertical_linear);
15333a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
15343a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        int[] items = new int[100];
15353a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        for (int i = 0; i < items.length; i++) {
15363a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            items[i] = 680;
15373a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        }
15383a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
15393a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
15403a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        mOrientation = BaseGridView.VERTICAL;
15413a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        mNumRows = 1;
15423a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu
15433a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        initActivity(intent);
15443a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu
15453a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        mGridView.setSelectedPositionSmooth(0);
15463a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        waitForScrollIdle(mVerifyLayout);
15473a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        assertTrue(mGridView.getChildAt(0).hasFocus());
15483a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu
15493a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        // Pressing lots of key to make sure smooth scroller is running
15503a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        for (int i = 0; i < 20; i++) {
15513a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
15523a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        }
15533a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        Thread.sleep(100);
15543a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        int total = 0;
15553a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        while (mGridView.getLayoutManager().isSmoothScrolling() ||
15563a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                mGridView.getScrollState() != BaseGridView.SCROLL_STATE_IDLE) {
15573a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            if ((total += 10) >= WAIT_FOR_SCROLL_IDLE_TIMEOUT_MS) {
15583a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                throw new RuntimeException("waitForScrollIdle Timeout");
15593a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            }
15603a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            try {
15613a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                // Repeatedly pressing to make sure pending keys does not drop to zero.
15623a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                Thread.sleep(10);
15633a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
15643a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            } catch (InterruptedException ex) {
15653a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                break;
15663a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            }
15673a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        }
15683a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu
15693a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        assertTrue("LinearSmoothScroller would not use many RV.smoothScrollBy() calls",
15703a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                ((VerticalGridViewEx) mGridView).mSmoothScrollByCalled < 10);
15713a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu    }
157257f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu
157357f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu    public void testSetNumRowsAndAddItem() throws Throwable {
157457f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        mInstrumentation = getInstrumentation();
157557f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
157657f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
157757f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu                R.layout.vertical_linear);
157857f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
157957f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        int[] items = new int[2];
158057f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        for (int i = 0; i < items.length; i++) {
158157f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu            items[i] = 300;
158257f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        }
158357f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
158457f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
158557f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        mOrientation = BaseGridView.VERTICAL;
158657f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        mNumRows = 1;
158757f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu
158857f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        initActivity(intent);
158957f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu
159057f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        mGridView.setSelectedPositionSmooth(0);
159157f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        waitForScrollIdle(mVerifyLayout);
159257f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu
159357f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        mActivity.addItems(items.length, new int[]{300});
159457f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu
159557f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        runTestOnUiThread(new Runnable() {
159657f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu            public void run() {
159757f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu                ((VerticalGridView) mGridView).setNumColumns(2);
159857f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu            }
159957f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        });
160057f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        Thread.sleep(1000);
160157f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        assertTrue(mGridView.getChildAt(2).getLeft() != mGridView.getChildAt(1).getLeft());
160257f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu    }
1603c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1604c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1605c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu    public void testRequestLayoutBugInLayout() throws Throwable {
1606c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        mInstrumentation = getInstrumentation();
1607c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1608c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1609c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                R.layout.vertical_linear);
1610c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.relative_layout);
1611c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
1612c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        int[] items = new int[100];
1613c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        for (int i = 0; i < items.length; i++) {
1614c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu            items[i] = 300;
1615c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        }
1616c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
1617c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
1618c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        mOrientation = BaseGridView.VERTICAL;
1619c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        mNumRows = 1;
1620c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1621c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        initActivity(intent);
1622c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1623c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        runTestOnUiThread(new Runnable() {
1624c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu            public void run() {
1625c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                mGridView.setSelectedPositionSmooth(1);
1626c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu            }
1627c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        });
1628c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        waitForScrollIdle(mVerifyLayout);
1629c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1630c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
1631c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        waitForScrollIdle(mVerifyLayout);
1632c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1633c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        assertEquals("Line 2", ((TextView) mGridView.findFocus()).getText().toString());
1634c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu    }
1635492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu
1636492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu
1637492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu    public void testChangeLayoutInChild() throws Throwable {
1638492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        mInstrumentation = getInstrumentation();
1639492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1640492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1641492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                R.layout.vertical_linear_wrap_content);
1642492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_LAYOUT_ONFOCUS, true);
1643492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        int[] items = new int[2];
1644492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        for (int i = 0; i < items.length; i++) {
1645492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu            items[i] = 300;
1646492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        }
1647492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
1648492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
1649492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        mOrientation = BaseGridView.VERTICAL;
1650492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        mNumRows = 1;
1651492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu
1652492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        initActivity(intent);
1653492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu
1654492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        runTestOnUiThread(new Runnable() {
1655492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu            public void run() {
1656492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                mGridView.setSelectedPositionSmooth(0);
1657492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu            }
1658492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        });
1659492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        waitForScrollIdle(mVerifyLayout);
1660492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        verifyMargin();
1661492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu
1662492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        runTestOnUiThread(new Runnable() {
1663492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu            public void run() {
1664492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                mGridView.setSelectedPositionSmooth(1);
1665492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu            }
1666492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        });
1667492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        waitForScrollIdle(mVerifyLayout);
1668492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        verifyMargin();
1669492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu    }
16701a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu
16711a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu
16721a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu    public void testZeroFixedSecondarySize() throws Throwable {
16731a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        mInstrumentation = getInstrumentation();
16741a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
16751a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
16761a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu                R.layout.vertical_linear_measured_with_zero);
16771a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        intent.putExtra(GridActivity.EXTRA_SECONDARY_SIZE_ZERO, true);
16781a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        int[] items = new int[2];
16791a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        for (int i = 0; i < items.length; i++) {
16801a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu            items[i] = 0;
16811a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        }
16821a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
16831a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
16841a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        mOrientation = BaseGridView.VERTICAL;
16851a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        mNumRows = 1;
16861a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu
16871a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        initActivity(intent);
16881a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu
16891a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu    }
16903bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
16913bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu    public void testChildStates() throws Throwable {
16923bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        mInstrumentation = getInstrumentation();
16933bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
16943bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.vertical_linear);
16953bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        int[] items = new int[100];
16963bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        for (int i = 0; i < items.length; i++) {
16973bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            items[i] = 200;
16983bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        }
16993bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
17003bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
17013bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_LAYOUT_ONFOCUS, true);
17023bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.selectable_text_view);
17033bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        mOrientation = BaseGridView.VERTICAL;
17043bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        mNumRows = 1;
17053bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
17063bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        initActivity(intent);
17073bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        mGridView.setSaveChildrenPolicy(VerticalGridView.SAVE_ALL_CHILD);
17083bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
170961e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        final SparseArray<Parcelable> container = new SparseArray<Parcelable>();
17103bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
17113bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        // 1 Save view states
17123bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        runTestOnUiThread(new Runnable() {
17133bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            public void run() {
17143bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                Selection.setSelection((Spannable)(((TextView) mGridView.getChildAt(0))
17153bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                        .getText()), 0, 1);
17163bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                Selection.setSelection((Spannable)(((TextView) mGridView.getChildAt(1))
17173bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                        .getText()), 0, 1);
17183bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                mGridView.saveHierarchyState(container);
17193bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            }
17203bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        });
17213bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
17223bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        // 2 Change view states
17233bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        runTestOnUiThread(new Runnable() {
17243bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            public void run() {
17253bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                Selection.setSelection((Spannable)(((TextView) mGridView.getChildAt(0))
17263bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                        .getText()), 1, 2);
17273bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                Selection.setSelection((Spannable)(((TextView) mGridView.getChildAt(1))
17283bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                        .getText()), 1, 2);
17293bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            }
17303bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        });
17313bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
17323bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        // 3 Detached and re-attached,  should still maintain state of (2)
17333bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        runTestOnUiThread(new Runnable() {
17343bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            public void run() {
17353bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                mGridView.setSelectedPositionSmooth(1);
17363bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            }
17373bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        });
17383bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        waitForScrollIdle(mVerifyLayout);
17393bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(0)).getSelectionStart(), 1);
17403bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(0)).getSelectionEnd(), 2);
17413bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(1)).getSelectionStart(), 1);
17423bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(1)).getSelectionEnd(), 2);
17433bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
17443bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        // 4 Recycled and rebound, should load state from (2)
17453bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        runTestOnUiThread(new Runnable() {
17463bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            public void run() {
17473bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                mGridView.setSelectedPositionSmooth(20);
17483bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            }
17493bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        });
17503bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        waitForScrollIdle(mVerifyLayout);
17513bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        runTestOnUiThread(new Runnable() {
17523bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            public void run() {
17533bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                mGridView.setSelectedPositionSmooth(0);
17543bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            }
17553bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        });
17563bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        waitForScrollIdle(mVerifyLayout);
17573bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(0)).getSelectionStart(), 1);
17583bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(0)).getSelectionEnd(), 2);
17593bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(1)).getSelectionStart(), 1);
17603bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(1)).getSelectionEnd(), 2);
17613bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu    }
17623bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
17633bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
176461e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu    public void testNoDispatchSaveChildState() throws Throwable {
176561e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        mInstrumentation = getInstrumentation();
176661e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
176761e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.vertical_linear);
176861e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        int[] items = new int[100];
176961e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        for (int i = 0; i < items.length; i++) {
177061e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            items[i] = 200;
177161e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        }
177261e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
177361e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
177461e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.selectable_text_view);
177561e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        mOrientation = BaseGridView.VERTICAL;
177661e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        mNumRows = 1;
177761e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
177861e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        initActivity(intent);
177961e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        mGridView.setSaveChildrenPolicy(VerticalGridView.SAVE_NO_CHILD);
178061e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
178161e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        final SparseArray<Parcelable> container = new SparseArray<Parcelable>();
178261e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
178361e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        // 1. Set text selection, save view states should do nothing on child
178461e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        runTestOnUiThread(new Runnable() {
178561e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            public void run() {
178661e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                for (int i = 0; i < mGridView.getChildCount(); i++) {
178761e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                    Selection.setSelection((Spannable)(((TextView) mGridView.getChildAt(i))
178861e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                            .getText()), 0, 1);
178961e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                }
179061e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                mGridView.saveHierarchyState(container);
179161e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            }
179261e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        });
179361e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
179461e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        // 2. clear the text selection
179561e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        runTestOnUiThread(new Runnable() {
179661e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            public void run() {
179761e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                for (int i = 0; i < mGridView.getChildCount(); i++) {
179861e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                    Selection.removeSelection((Spannable)(((TextView) mGridView.getChildAt(i))
179961e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                            .getText()));
180061e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                }
180161e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            }
180261e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        });
180361e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
180461e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        // 3. Restore view states should be a no-op for child
180561e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        runTestOnUiThread(new Runnable() {
180661e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            public void run() {
180761e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                mGridView.restoreHierarchyState(container);
180861e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                for (int i = 0; i < mGridView.getChildCount(); i++) {
180961e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                    assertEquals(-1, ((TextView) mGridView.getChildAt(i)).getSelectionStart());
181061e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                    assertEquals(-1, ((TextView) mGridView.getChildAt(i)).getSelectionEnd());
181161e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                }
181261e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            }
181361e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        });
181461e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu    }
181561e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
181608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
181708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static interface ViewTypeProvider {
181808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public int getViewType(int position);
181908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
182008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
182108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static interface ItemAlignmentFacetProvider {
182208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public ItemAlignmentFacet getItemAlignmentFacet(int viewType);
182308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
182408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
182508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static class TwoViewTypesProvider implements ViewTypeProvider {
182608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        static int VIEW_TYPE_FIRST = 1;
182708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        static int VIEW_TYPE_DEFAULT = 0;
182808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        @Override
182908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public int getViewType(int position) {
183008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (position == 0) {
183108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return VIEW_TYPE_FIRST;
183208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            } else {
183308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return VIEW_TYPE_DEFAULT;
183408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
183508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
183608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
183708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
183808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static class PositionItemAlignmentFacetProviderForRelativeLayout1
183908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            implements ItemAlignmentFacetProvider {
184008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        ItemAlignmentFacet mMultipleFacet;
184108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
184208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        PositionItemAlignmentFacetProviderForRelativeLayout1() {
184308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet = new ItemAlignmentFacet();
184408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            ItemAlignmentFacet.ItemAlignmentDef[] defs =
184508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                    new ItemAlignmentFacet.ItemAlignmentDef[2];
184608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0] = new ItemAlignmentFacet.ItemAlignmentDef();
184708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0].setItemAlignmentViewId(R.id.t1);
184808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1] = new ItemAlignmentFacet.ItemAlignmentDef();
184908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentViewId(R.id.t2);
185008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffsetPercent(100);
185108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffset(-10);
185208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet.setAlignmentDefs(defs);
185308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
185408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
185508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        @Override
185608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public ItemAlignmentFacet getItemAlignmentFacet(int position) {
185708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (position == 0) {
185808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return mMultipleFacet;
185908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            } else {
186008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return null;
186108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
186208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
186308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
186408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
186508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    public void testMultipleScrollPosition1() throws Throwable {
186608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mInstrumentation = getInstrumentation();
186708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
186808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
186908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                R.layout.vertical_linear);
187008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.relative_layout);
187108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
187208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int[] items = new int[100];
187308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        for (int i = 0; i < items.length; i++) {
187408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            items[i] = 300;
187508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
187608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
187708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
187808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_VIEWTYPEPROVIDER_CLASS,
187908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                TwoViewTypesProvider.class.getName());
188008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        // Set ItemAlignment for each ViewHolder and view type,  ViewHolder should
188108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        // override the view type settings.
188208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMALIGNMENTPROVIDER_CLASS,
188308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                PositionItemAlignmentFacetProviderForRelativeLayout1.class.getName());
188408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMALIGNMENTPROVIDER_VIEWTYPE_CLASS,
188508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                ViewTypePositionItemAlignmentFacetProviderForRelativeLayout2.class.getName());
188608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mOrientation = BaseGridView.VERTICAL;
188708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mNumRows = 1;
188808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
188908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        initActivity(intent);
189008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
189108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("First view is aligned with padding top",
189208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getPaddingTop(), mGridView.getChildAt(0).getTop());
189308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
189408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
189508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        waitForScrollIdle(mVerifyLayout);
189608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
189708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        final View v = mGridView.getChildAt(0);
189808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t1 = v.findViewById(R.id.t1);
189908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t1align = (t1.getTop() + t1.getBottom()) / 2;
190008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t2 = v.findViewById(R.id.t2);
190108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t2align = t2.getBottom() - 10;
190208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("Expected alignment for 2nd textview",
190308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getPaddingTop() - (t2align - t1align),
190408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                v.getTop());
190508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
190608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
190708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static class PositionItemAlignmentFacetProviderForRelativeLayout2 implements
190808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            ItemAlignmentFacetProvider {
190908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        ItemAlignmentFacet mMultipleFacet;
191008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
191108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        PositionItemAlignmentFacetProviderForRelativeLayout2() {
191208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet = new ItemAlignmentFacet();
191308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            ItemAlignmentFacet.ItemAlignmentDef[] defs = new ItemAlignmentFacet.ItemAlignmentDef[2];
191408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0] = new ItemAlignmentFacet.ItemAlignmentDef();
191508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0].setItemAlignmentViewId(R.id.t1);
191608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0].setItemAlignmentOffsetPercent(0);
191708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1] = new ItemAlignmentFacet.ItemAlignmentDef();
191808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentViewId(R.id.t2);
191908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffsetPercent(ItemAlignmentFacet.ITEM_ALIGN_OFFSET_PERCENT_DISABLED);
192008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffset(-10);
192108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet.setAlignmentDefs(defs);
192208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
192308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
192408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        @Override
192508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public ItemAlignmentFacet getItemAlignmentFacet(int position) {
192608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (position == 0) {
192708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return mMultipleFacet;
192808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            } else {
192908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return null;
193008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
193108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
193208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
193308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
193408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    public void testMultipleScrollPosition2() throws Throwable {
193508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mInstrumentation = getInstrumentation();
193608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
193708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.vertical_linear);
193808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.relative_layout);
193908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
194008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int[] items = new int[100];
194108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        for (int i = 0; i < items.length; i++) {
194208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            items[i] = 300;
194308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
194408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
194508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
194608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_VIEWTYPEPROVIDER_CLASS,
194708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                TwoViewTypesProvider.class.getName());
194808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMALIGNMENTPROVIDER_CLASS,
194908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                PositionItemAlignmentFacetProviderForRelativeLayout2.class.getName());
195008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mOrientation = BaseGridView.VERTICAL;
195108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mNumRows = 1;
195208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
195308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        initActivity(intent);
195408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
195508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("First view is aligned with padding top", mGridView.getPaddingTop(),
195608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getChildAt(0).getTop());
195708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
195808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
195908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        waitForScrollIdle(mVerifyLayout);
196008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
196108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        final View v = mGridView.getChildAt(0);
196208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t1 = v.findViewById(R.id.t1);
196308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t1align = t1.getTop();
196408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t2 = v.findViewById(R.id.t2);
196508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t2align = t2.getTop() - 10;
196608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("Expected alignment for 2nd textview",
196708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getPaddingTop() - (t2align - t1align), v.getTop());
196808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
196908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
197008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static class ViewTypePositionItemAlignmentFacetProviderForRelativeLayout2 implements
197108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            ItemAlignmentFacetProvider {
197208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        ItemAlignmentFacet mMultipleFacet;
197308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
197408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        ViewTypePositionItemAlignmentFacetProviderForRelativeLayout2() {
197508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet = new ItemAlignmentFacet();
197608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            ItemAlignmentFacet.ItemAlignmentDef[] defs = new ItemAlignmentFacet.ItemAlignmentDef[2];
197708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0] = new ItemAlignmentFacet.ItemAlignmentDef();
197808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0].setItemAlignmentViewId(R.id.t1);
197908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0].setItemAlignmentOffsetPercent(0);
198008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1] = new ItemAlignmentFacet.ItemAlignmentDef();
198108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentViewId(R.id.t2);
198208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffsetPercent(100);
198308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffset(-10);
198408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet.setAlignmentDefs(defs);
198508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
198608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
198708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        @Override
198808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public ItemAlignmentFacet getItemAlignmentFacet(int viewType) {
198908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (viewType == TwoViewTypesProvider.VIEW_TYPE_FIRST) {
199008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return mMultipleFacet;
199108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            } else {
199208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return null;
199308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
199408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
199508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
199608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
199708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    public void testMultipleScrollPosition3() throws Throwable {
199808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mInstrumentation = getInstrumentation();
199908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
200008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.vertical_linear);
200108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.relative_layout);
200208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
200308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int[] items = new int[100];
200408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        for (int i = 0; i < items.length; i++) {
200508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            items[i] = 300;
200608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
200708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
200808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
200908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_VIEWTYPEPROVIDER_CLASS,
201008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                TwoViewTypesProvider.class.getName());
201108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMALIGNMENTPROVIDER_VIEWTYPE_CLASS,
201208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                ViewTypePositionItemAlignmentFacetProviderForRelativeLayout2.class.getName());
201308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mOrientation = BaseGridView.VERTICAL;
201408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mNumRows = 1;
201508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
201608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        initActivity(intent);
201708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
201808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("First view is aligned with padding top", mGridView.getPaddingTop(),
201908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getChildAt(0).getTop());
202008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
202108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
202208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        waitForScrollIdle(mVerifyLayout);
202308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
202408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        final View v = mGridView.getChildAt(0);
202508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t1 = v.findViewById(R.id.t1);
202608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t1align = t1.getTop();
202708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t2 = v.findViewById(R.id.t2);
202808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t2align = t2.getBottom() - 10;
202908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("Expected alignment for 2nd textview",
203008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getPaddingTop() - (t2align - t1align), v.getTop());
203108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
203208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
2033db0b1afb71440b79923692d58adee982b5954838Dake Gu    public void testSelectionAndAddItemInOneCycle() throws Throwable {
2034db0b1afb71440b79923692d58adee982b5954838Dake Gu        mInstrumentation = getInstrumentation();
2035db0b1afb71440b79923692d58adee982b5954838Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
2036db0b1afb71440b79923692d58adee982b5954838Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
2037db0b1afb71440b79923692d58adee982b5954838Dake Gu                R.layout.vertical_linear);
2038db0b1afb71440b79923692d58adee982b5954838Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 0);
2039db0b1afb71440b79923692d58adee982b5954838Dake Gu        initActivity(intent);
2040db0b1afb71440b79923692d58adee982b5954838Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
2041db0b1afb71440b79923692d58adee982b5954838Dake Gu        mNumRows = 1;
2042db0b1afb71440b79923692d58adee982b5954838Dake Gu
2043db0b1afb71440b79923692d58adee982b5954838Dake Gu        runTestOnUiThread(new Runnable() {
2044db0b1afb71440b79923692d58adee982b5954838Dake Gu            public void run() {
2045db0b1afb71440b79923692d58adee982b5954838Dake Gu                mActivity.addItems(0, new int[]{300, 300});
2046db0b1afb71440b79923692d58adee982b5954838Dake Gu                mGridView.setSelectedPosition(0);
2047db0b1afb71440b79923692d58adee982b5954838Dake Gu            }
2048db0b1afb71440b79923692d58adee982b5954838Dake Gu        });
2049db0b1afb71440b79923692d58adee982b5954838Dake Gu        waitForTransientStateGone(null);
2050db0b1afb71440b79923692d58adee982b5954838Dake Gu        assertEquals(0, mGridView.getSelectedPosition());
2051db0b1afb71440b79923692d58adee982b5954838Dake Gu    }
2052db0b1afb71440b79923692d58adee982b5954838Dake Gu
2053db0b1afb71440b79923692d58adee982b5954838Dake Gu    public void testSelectionSmoothAndAddItemInOneCycle() throws Throwable {
2054db0b1afb71440b79923692d58adee982b5954838Dake Gu        mInstrumentation = getInstrumentation();
2055db0b1afb71440b79923692d58adee982b5954838Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
2056db0b1afb71440b79923692d58adee982b5954838Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
2057db0b1afb71440b79923692d58adee982b5954838Dake Gu                R.layout.vertical_linear);
2058db0b1afb71440b79923692d58adee982b5954838Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 0);
2059db0b1afb71440b79923692d58adee982b5954838Dake Gu        initActivity(intent);
2060db0b1afb71440b79923692d58adee982b5954838Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
2061db0b1afb71440b79923692d58adee982b5954838Dake Gu        mNumRows = 1;
2062db0b1afb71440b79923692d58adee982b5954838Dake Gu
2063db0b1afb71440b79923692d58adee982b5954838Dake Gu        runTestOnUiThread(new Runnable() {
2064db0b1afb71440b79923692d58adee982b5954838Dake Gu            public void run() {
2065db0b1afb71440b79923692d58adee982b5954838Dake Gu                mActivity.addItems(0, new int[]{300, 300});
2066db0b1afb71440b79923692d58adee982b5954838Dake Gu                mGridView.setSelectedPositionSmooth(0);
2067db0b1afb71440b79923692d58adee982b5954838Dake Gu            }
2068db0b1afb71440b79923692d58adee982b5954838Dake Gu        });
2069db0b1afb71440b79923692d58adee982b5954838Dake Gu        waitForTransientStateGone(null);
2070db0b1afb71440b79923692d58adee982b5954838Dake Gu        assertEquals(0, mGridView.getSelectedPosition());
2071db0b1afb71440b79923692d58adee982b5954838Dake Gu    }
207288dea72af6042049560140a70e059820dbb8f746Dake Gu
207388dea72af6042049560140a70e059820dbb8f746Dake Gu    public void testExtraLayoutSpace() throws Throwable {
207488dea72af6042049560140a70e059820dbb8f746Dake Gu        mInstrumentation = getInstrumentation();
207588dea72af6042049560140a70e059820dbb8f746Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
207688dea72af6042049560140a70e059820dbb8f746Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
207788dea72af6042049560140a70e059820dbb8f746Dake Gu                R.layout.vertical_linear);
207888dea72af6042049560140a70e059820dbb8f746Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 1000);
207988dea72af6042049560140a70e059820dbb8f746Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
208088dea72af6042049560140a70e059820dbb8f746Dake Gu        initActivity(intent);
208188dea72af6042049560140a70e059820dbb8f746Dake Gu
208288dea72af6042049560140a70e059820dbb8f746Dake Gu        final int windowSize = mGridView.getHeight();
208388dea72af6042049560140a70e059820dbb8f746Dake Gu        final int extraLayoutSize = windowSize;
208488dea72af6042049560140a70e059820dbb8f746Dake Gu        int itemLength = mActivity.mItemLengths[0];
208588dea72af6042049560140a70e059820dbb8f746Dake Gu        mOrientation = BaseGridView.VERTICAL;
208688dea72af6042049560140a70e059820dbb8f746Dake Gu        mNumRows = 1;
208788dea72af6042049560140a70e059820dbb8f746Dake Gu
208888dea72af6042049560140a70e059820dbb8f746Dake Gu        // add extra layout space
208988dea72af6042049560140a70e059820dbb8f746Dake Gu        runTestOnUiThread(new Runnable() {
209088dea72af6042049560140a70e059820dbb8f746Dake Gu            public void run() {
209188dea72af6042049560140a70e059820dbb8f746Dake Gu                mGridView.setExtraLayoutSpace(extraLayoutSize);
209288dea72af6042049560140a70e059820dbb8f746Dake Gu            }
209388dea72af6042049560140a70e059820dbb8f746Dake Gu        });
209488dea72af6042049560140a70e059820dbb8f746Dake Gu        Thread.sleep(50);
209588dea72af6042049560140a70e059820dbb8f746Dake Gu        View v;
209688dea72af6042049560140a70e059820dbb8f746Dake Gu        v = mGridView.getChildAt(mGridView.getChildCount() - 1);
209788dea72af6042049560140a70e059820dbb8f746Dake Gu        assertTrue(v.getTop() < windowSize + extraLayoutSize);
209888dea72af6042049560140a70e059820dbb8f746Dake Gu        assertTrue(v.getBottom() >= windowSize + extraLayoutSize -
209988dea72af6042049560140a70e059820dbb8f746Dake Gu                mGridView.getVerticalMargin());
210088dea72af6042049560140a70e059820dbb8f746Dake Gu
210188dea72af6042049560140a70e059820dbb8f746Dake Gu        mGridView.setSelectedPositionSmooth(150);
210288dea72af6042049560140a70e059820dbb8f746Dake Gu        waitForScrollIdle(mVerifyLayout);
210388dea72af6042049560140a70e059820dbb8f746Dake Gu        v = mGridView.getChildAt(0);
210488dea72af6042049560140a70e059820dbb8f746Dake Gu        assertTrue(v.getBottom() > - extraLayoutSize);
210588dea72af6042049560140a70e059820dbb8f746Dake Gu        assertTrue(v.getTop() <= -extraLayoutSize + mGridView.getVerticalMargin());
210688dea72af6042049560140a70e059820dbb8f746Dake Gu
210788dea72af6042049560140a70e059820dbb8f746Dake Gu        // clear extra layout space
210888dea72af6042049560140a70e059820dbb8f746Dake Gu        runTestOnUiThread(new Runnable() {
210988dea72af6042049560140a70e059820dbb8f746Dake Gu            public void run() {
211088dea72af6042049560140a70e059820dbb8f746Dake Gu                mGridView.setExtraLayoutSpace(0);
211188dea72af6042049560140a70e059820dbb8f746Dake Gu                verifyMargin();
211288dea72af6042049560140a70e059820dbb8f746Dake Gu            }
211388dea72af6042049560140a70e059820dbb8f746Dake Gu        });
211488dea72af6042049560140a70e059820dbb8f746Dake Gu        Thread.sleep(50);
211588dea72af6042049560140a70e059820dbb8f746Dake Gu        v = mGridView.getChildAt(mGridView.getChildCount() - 1);
211688dea72af6042049560140a70e059820dbb8f746Dake Gu        assertTrue(v.getTop() < windowSize);
211788dea72af6042049560140a70e059820dbb8f746Dake Gu        assertTrue(v.getBottom() >= windowSize - mGridView.getVerticalMargin());
211888dea72af6042049560140a70e059820dbb8f746Dake Gu    }
2119d1cab1b54104d55407335c5d649398635822fffdDake Gu
2120d1cab1b54104d55407335c5d649398635822fffdDake Gu    public void testAccessibility() throws Throwable {
2121d1cab1b54104d55407335c5d649398635822fffdDake Gu        mInstrumentation = getInstrumentation();
2122d1cab1b54104d55407335c5d649398635822fffdDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
2123d1cab1b54104d55407335c5d649398635822fffdDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
2124d1cab1b54104d55407335c5d649398635822fffdDake Gu                R.layout.vertical_linear);
2125d1cab1b54104d55407335c5d649398635822fffdDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 1000);
2126d1cab1b54104d55407335c5d649398635822fffdDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
2127d1cab1b54104d55407335c5d649398635822fffdDake Gu        initActivity(intent);
2128d1cab1b54104d55407335c5d649398635822fffdDake Gu        mOrientation = BaseGridView.VERTICAL;
2129d1cab1b54104d55407335c5d649398635822fffdDake Gu        mNumRows = 1;
2130d1cab1b54104d55407335c5d649398635822fffdDake Gu
2131d1cab1b54104d55407335c5d649398635822fffdDake Gu        assertTrue(0 == mGridView.getSelectedPosition());
2132d1cab1b54104d55407335c5d649398635822fffdDake Gu
2133d1cab1b54104d55407335c5d649398635822fffdDake Gu        final RecyclerViewAccessibilityDelegate delegateCompat = mGridView
2134d1cab1b54104d55407335c5d649398635822fffdDake Gu                .getCompatAccessibilityDelegate();
2135d1cab1b54104d55407335c5d649398635822fffdDake Gu        final AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
2136d1cab1b54104d55407335c5d649398635822fffdDake Gu        runTestOnUiThread(new Runnable() {
2137d1cab1b54104d55407335c5d649398635822fffdDake Gu            @Override
2138d1cab1b54104d55407335c5d649398635822fffdDake Gu            public void run() {
2139d1cab1b54104d55407335c5d649398635822fffdDake Gu                delegateCompat.onInitializeAccessibilityNodeInfo(mGridView, info);
2140d1cab1b54104d55407335c5d649398635822fffdDake Gu            }
2141d1cab1b54104d55407335c5d649398635822fffdDake Gu        });
2142d1cab1b54104d55407335c5d649398635822fffdDake Gu        assertTrue("test sanity", info.isScrollable());
2143d1cab1b54104d55407335c5d649398635822fffdDake Gu        runTestOnUiThread(new Runnable() {
2144d1cab1b54104d55407335c5d649398635822fffdDake Gu            @Override
2145d1cab1b54104d55407335c5d649398635822fffdDake Gu            public void run() {
2146d1cab1b54104d55407335c5d649398635822fffdDake Gu                delegateCompat.performAccessibilityAction(mGridView,
2147d1cab1b54104d55407335c5d649398635822fffdDake Gu                        AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD, null);
2148d1cab1b54104d55407335c5d649398635822fffdDake Gu            }
2149d1cab1b54104d55407335c5d649398635822fffdDake Gu        });
2150d1cab1b54104d55407335c5d649398635822fffdDake Gu        waitForScrollIdle(mVerifyLayout);
2151d1cab1b54104d55407335c5d649398635822fffdDake Gu        int selectedPosition1 = mGridView.getSelectedPosition();
2152d1cab1b54104d55407335c5d649398635822fffdDake Gu        assertTrue(0 < selectedPosition1);
2153d1cab1b54104d55407335c5d649398635822fffdDake Gu
2154d1cab1b54104d55407335c5d649398635822fffdDake Gu        runTestOnUiThread(new Runnable() {
2155d1cab1b54104d55407335c5d649398635822fffdDake Gu            @Override
2156d1cab1b54104d55407335c5d649398635822fffdDake Gu            public void run() {
2157d1cab1b54104d55407335c5d649398635822fffdDake Gu                delegateCompat.onInitializeAccessibilityNodeInfo(mGridView, info);
2158d1cab1b54104d55407335c5d649398635822fffdDake Gu            }
2159d1cab1b54104d55407335c5d649398635822fffdDake Gu        });
2160d1cab1b54104d55407335c5d649398635822fffdDake Gu        assertTrue("test sanity", info.isScrollable());
2161d1cab1b54104d55407335c5d649398635822fffdDake Gu        runTestOnUiThread(new Runnable() {
2162d1cab1b54104d55407335c5d649398635822fffdDake Gu            @Override
2163d1cab1b54104d55407335c5d649398635822fffdDake Gu            public void run() {
2164d1cab1b54104d55407335c5d649398635822fffdDake Gu                delegateCompat.performAccessibilityAction(mGridView,
2165d1cab1b54104d55407335c5d649398635822fffdDake Gu                        AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD, null);
2166d1cab1b54104d55407335c5d649398635822fffdDake Gu            }
2167d1cab1b54104d55407335c5d649398635822fffdDake Gu        });
2168d1cab1b54104d55407335c5d649398635822fffdDake Gu        waitForScrollIdle(mVerifyLayout);
2169d1cab1b54104d55407335c5d649398635822fffdDake Gu        int selectedPosition2 = mGridView.getSelectedPosition();
2170d1cab1b54104d55407335c5d649398635822fffdDake Gu        assertTrue(selectedPosition2 < selectedPosition1);
2171d1cab1b54104d55407335c5d649398635822fffdDake Gu    }
2172d1cab1b54104d55407335c5d649398635822fffdDake Gu
2173062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu}
2174