GridWidgetTest.java revision ff3b38c570fa25327bb6a9bca1753827d9f9d7fd
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
540ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu    public void testScrollAndRemove() throws Throwable {
541ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
542ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mInstrumentation = getInstrumentation();
543ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
544ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
545ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                R.layout.horizontal_linear);
546ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 50);
547ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        initActivity(intent);
548ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mOrientation = BaseGridView.HORIZONTAL;
549ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mNumRows = 1;
550ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
551ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        final int focusToIndex = mGridView.getChildCount() - 1;
552ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        runTestOnUiThread(new Runnable() {
553ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            public void run() {
554ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.setSelectedPositionSmooth(focusToIndex);
555ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            }
556ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        });
557ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
558ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        runTestOnUiThread(new Runnable() {
559ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            public void run() {
560ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mActivity.removeItems(focusToIndex, 1);
561ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            }
562ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        });
563ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
564ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForTransientStateGone(null);
565ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForScrollIdle();
566ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        int leftEdge = mGridView.getLayoutManager().findViewByPosition(focusToIndex).getLeft();
567ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
568ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        runTestOnUiThread(new Runnable() {
569ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            public void run() {
570ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.requestLayout();
571ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            }
572ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        });
573ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForTransientStateGone(null);
574ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForScrollIdle();
575ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        assertEquals(leftEdge,
576ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.getLayoutManager().findViewByPosition(focusToIndex).getLeft());
577ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu    }
578ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
579ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu    public void testSmoothScrollAndRemove() throws Throwable {
580ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
581ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mInstrumentation = getInstrumentation();
582ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
583ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
584ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                R.layout.horizontal_linear);
585ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 50);
586ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        initActivity(intent);
587ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mOrientation = BaseGridView.HORIZONTAL;
588ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mNumRows = 1;
589ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
590ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        final int focusToIndex = 40;
591ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        runTestOnUiThread(new Runnable() {
592ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            public void run() {
593ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.setSelectedPositionSmooth(focusToIndex);
594ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            }
595ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        });
596ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
597ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        runTestOnUiThread(new Runnable() {
598ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            public void run() {
599ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mActivity.removeItems(focusToIndex, 1);
600ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            }
601ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        });
602ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
603ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        Thread.sleep(20); // wait for layout
604ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        assertTrue("removing the index of not attached child should not affect smooth scroller",
605ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.getLayoutManager().isSmoothScrolling());
606ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForTransientStateGone(null);
607ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForScrollIdle();
608ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        int leftEdge = mGridView.getLayoutManager().findViewByPosition(focusToIndex).getLeft();
609ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
610ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        runTestOnUiThread(new Runnable() {
611ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            public void run() {
612ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.requestLayout();
613ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            }
614ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        });
615ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForTransientStateGone(null);
616ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForScrollIdle();
617ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        assertEquals(leftEdge,
618ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.getLayoutManager().findViewByPosition(focusToIndex).getLeft());
619ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu    }
620ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
621ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu    public void testSmoothScrollAndRemove2() throws Throwable {
622ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
623ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mInstrumentation = getInstrumentation();
624ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
625ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
626ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                R.layout.horizontal_linear);
627ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 50);
628ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        initActivity(intent);
629ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mOrientation = BaseGridView.HORIZONTAL;
630ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mNumRows = 1;
631ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
632ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        final int focusToIndex = 40;
633ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        runTestOnUiThread(new Runnable() {
634ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            public void run() {
635ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.setSelectedPositionSmooth(focusToIndex);
636ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            }
637ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        });
638ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
639ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        final int removeIndex = mGridView.getChildCount() - 1;
640ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        runTestOnUiThread(new Runnable() {
641ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            public void run() {
642ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mActivity.removeItems(removeIndex, 1);
643ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            }
644ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        });
645ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
646ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        Thread.sleep(20); // wait for layout
647ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        assertFalse("removing the index of attached child should kill smooth scroller",
648ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.getLayoutManager().isSmoothScrolling());
649ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForTransientStateGone(null);
650ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForScrollIdle();
651ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        int leftEdge = mGridView.getLayoutManager().findViewByPosition(focusToIndex).getLeft();
652ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
653ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        runTestOnUiThread(new Runnable() {
654ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            public void run() {
655ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.requestLayout();
656ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            }
657ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        });
658ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForTransientStateGone(null);
659ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForScrollIdle();
660ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        assertEquals(leftEdge,
661ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.getLayoutManager().findViewByPosition(focusToIndex).getLeft());
662ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu    }
663ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
664ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu    public void testPendingSmoothScrollAndRemove() throws Throwable {
665ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mInstrumentation = getInstrumentation();
666ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
667ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
668ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                R.layout.vertical_linear);
669ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
670ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        int[] items = new int[100];
671ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        for (int i = 0; i < items.length; i++) {
672ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            items[i] = 630 + (int)(Math.random() * 100);
673ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        }
674ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
675ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, true);
676ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mOrientation = BaseGridView.VERTICAL;
677ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mNumRows = 1;
678ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
679ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        initActivity(intent);
680ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
681ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        mGridView.setSelectedPositionSmooth(0);
682ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForScrollIdle(mVerifyLayout);
683ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        assertTrue(mGridView.getChildAt(0).hasFocus());
684ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
685ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        // Pressing lots of key to make sure smooth scroller is running
686ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        for (int i = 0; i < 20; i++) {
687ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
688ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        }
689ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        Thread.sleep(100);
690ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
691ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        assertTrue(mGridView.getLayoutManager().isSmoothScrolling());
692ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        final int removeIndex = mGridView.getChildCount() - 1;
693ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        runTestOnUiThread(new Runnable() {
694ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            public void run() {
695ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mActivity.removeItems(removeIndex, 1);
696ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            }
697ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        });
698ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
699ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        Thread.sleep(20); // wait for layout
700ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        assertFalse("removing the index of attached child should kill smooth scroller",
701ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.getLayoutManager().isSmoothScrolling());
702ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
703ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForTransientStateGone(null);
704ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForScrollIdle();
705ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        int focusIndex = mGridView.getSelectedPosition();
706ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        int leftEdge = mGridView.getLayoutManager().findViewByPosition(focusIndex).getLeft();
707ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
708ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        runTestOnUiThread(new Runnable() {
709ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            public void run() {
710ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.requestLayout();
711ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu            }
712ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        });
713ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForTransientStateGone(null);
714ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        waitForScrollIdle();
715ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu        assertEquals(leftEdge,
716ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu                mGridView.getLayoutManager().findViewByPosition(focusIndex).getLeft());
717ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu    }
718ff3b38c570fa25327bb6a9bca1753827d9f9d7fdDake Gu
7199c56475370d1df940252ff1360b92de50022fff6Dake Gu    public void testFocusToFirstItem() throws Throwable {
7209c56475370d1df940252ff1360b92de50022fff6Dake Gu
7219c56475370d1df940252ff1360b92de50022fff6Dake Gu        mInstrumentation = getInstrumentation();
7229c56475370d1df940252ff1360b92de50022fff6Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
7239c56475370d1df940252ff1360b92de50022fff6Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
7249c56475370d1df940252ff1360b92de50022fff6Dake Gu                R.layout.horizontal_grid);
7259c56475370d1df940252ff1360b92de50022fff6Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 200);
7269c56475370d1df940252ff1360b92de50022fff6Dake Gu        initActivity(intent);
7279c56475370d1df940252ff1360b92de50022fff6Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
7289c56475370d1df940252ff1360b92de50022fff6Dake Gu        mNumRows = 3;
7299c56475370d1df940252ff1360b92de50022fff6Dake Gu
7309c56475370d1df940252ff1360b92de50022fff6Dake Gu        int[] removedItems = mActivity.removeItems(0, 200);
7319c56475370d1df940252ff1360b92de50022fff6Dake Gu
7329c56475370d1df940252ff1360b92de50022fff6Dake Gu        waitForTransientStateGone(null);
733f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
7349c56475370d1df940252ff1360b92de50022fff6Dake Gu        mActivity.addItems(0, removedItems);
7359c56475370d1df940252ff1360b92de50022fff6Dake Gu
7369c56475370d1df940252ff1360b92de50022fff6Dake Gu        waitForTransientStateGone(null);
737f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
7389c56475370d1df940252ff1360b92de50022fff6Dake Gu        assertTrue(mGridView.getLayoutManager().findViewByPosition(0).hasFocus());
7399c56475370d1df940252ff1360b92de50022fff6Dake Gu
740f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(0);
7419c56475370d1df940252ff1360b92de50022fff6Dake Gu
742f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(200);
7439c56475370d1df940252ff1360b92de50022fff6Dake Gu        assertTrue(mGridView.getLayoutManager().findViewByPosition(0).hasFocus());
7449c56475370d1df940252ff1360b92de50022fff6Dake Gu    }
7459c56475370d1df940252ff1360b92de50022fff6Dake Gu
74677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu    public void testNonFocusableHorizontal() throws Throwable {
74777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int numItems = 200;
74877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int startPos = 45;
74977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int skips = 20;
75077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int numColumns = 3;
75177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int endPos = startPos + numColumns * (skips + 1);
75277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
75377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mInstrumentation = getInstrumentation();
75477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
75577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
75677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu                R.layout.horizontal_grid);
75777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, numItems);
75877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
75977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mOrientation = BaseGridView.HORIZONTAL;
76077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mNumRows = numColumns;
76177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        boolean[] focusable = new boolean[numItems];
76277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        for (int i = 0; i < focusable.length; i++) {
76377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            focusable[i] = true;
76477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
76577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        for (int i = startPos + mNumRows, j = 0; j < skips; i += mNumRows, j++) {
76677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            focusable[i] = false;
76777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
76877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS_FOCUSABLE, focusable);
7698c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
77077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
77177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mGridView.setSelectedPositionSmooth(startPos);
77277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
77377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
77477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        if (mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL) {
77577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
77677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        } else {
77777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
77877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
77977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
78077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        assertEquals(endPos, mGridView.getSelectedPosition());
78177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
78277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        if (mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL) {
78377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
78477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        } else {
78577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
78677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
78777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
78877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        assertEquals(startPos, mGridView.getSelectedPosition());
78977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
79077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu    }
79177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
79277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
79377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu    public void testNonFocusableVertical() throws Throwable {
79477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int numItems = 200;
79577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int startPos = 44;
79677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int skips = 20;
79777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int numColumns = 3;
79877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        final int endPos = startPos + numColumns * (skips + 1);
79977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
80077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mInstrumentation = getInstrumentation();
80177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
80277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
80377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu                R.layout.vertical_grid);
80477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, numItems);
80577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
80677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mOrientation = BaseGridView.VERTICAL;
80777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mNumRows = numColumns;
80877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        boolean[] focusable = new boolean[numItems];
80977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        for (int i = 0; i < focusable.length; i++) {
81077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            focusable[i] = true;
81177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
81277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        for (int i = startPos + mNumRows, j = 0; j < skips; i += mNumRows, j++) {
81377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu            focusable[i] = false;
81477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        }
81577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS_FOCUSABLE, focusable);
8168c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
81777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
81877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        mGridView.setSelectedPositionSmooth(startPos);
81977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
82077b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
82177b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
82277b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
82377b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        assertEquals(endPos, mGridView.getSelectedPosition());
82477b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
82577b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
82677b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        waitForScrollIdle(mVerifyLayout);
82777b17ebed6d1f8488b150b25e2b6754971480caeDake Gu        assertEquals(startPos, mGridView.getSelectedPosition());
82877b17ebed6d1f8488b150b25e2b6754971480caeDake Gu
82977b17ebed6d1f8488b150b25e2b6754971480caeDake Gu    }
8306b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
8316b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu    public void testTransferFocusable() throws Throwable {
8326b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int numItems = 200;
8336b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int numColumns = 3;
8346b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int startPos = 1;
8356b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
8366b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mInstrumentation = getInstrumentation();
8376b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
8386b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
8396b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu                R.layout.horizontal_grid);
8406b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, numItems);
8416b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
8426b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mOrientation = BaseGridView.HORIZONTAL;
8436b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mNumRows = numColumns;
8446b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        boolean[] focusable = new boolean[numItems];
8456b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        for (int i = 0; i < focusable.length; i++) {
8466b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu            focusable[i] = true;
8476b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        }
8486b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        for (int i = 0; i < startPos; i++) {
8496b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu            focusable[i] = false;
8506b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        }
8516b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS_FOCUSABLE, focusable);
8528c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
8536b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
854f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(0);
8556b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        assertTrue(mGridView.isFocused());
8566b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
857f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(numItems);
8586b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        assertTrue(mGridView.getLayoutManager().findViewByPosition(startPos).hasFocus());
8596b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu    }
8606b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
8616b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu    public void testTransferFocusable2() throws Throwable {
8626b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int numItems = 200;
8636b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int numColumns = 3;
8646b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        final int startPos = 10;
8656b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
8666b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mInstrumentation = getInstrumentation();
8676b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
8686b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
8696b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu                R.layout.horizontal_grid);
8706b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, numItems);
8716b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, true);
8726b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mOrientation = BaseGridView.HORIZONTAL;
8736b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        mNumRows = numColumns;
8746b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        boolean[] focusable = new boolean[numItems];
8756b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        for (int i = 0; i < focusable.length; i++) {
8766b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu            focusable[i] = true;
8776b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        }
8786b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        for (int i = 0; i < startPos; i++) {
8796b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu            focusable[i] = false;
8806b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        }
8816b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS_FOCUSABLE, focusable);
8828c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
8836b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
884f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(0);
8856b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        assertTrue(mGridView.isFocused());
8866b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu
887f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        changeArraySize(numItems);
8886b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu        assertTrue(mGridView.getLayoutManager().findViewByPosition(startPos).hasFocus());
8896b22c4c875d7a540e705b2b6b65bf52c7a89299aDake Gu    }
890fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
8918c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    public void testNonFocusableLoseInFastLayout() throws Throwable {
892fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        mInstrumentation = getInstrumentation();
893fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
894fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
895fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu                R.layout.vertical_linear);
896fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        int[] items = new int[300];
897fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        for (int i = 0; i < items.length; i++) {
898fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu            items[i] = 480;
899fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        }
900fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
901fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
902fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_LAYOUT_ONFOCUS, true);
903fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        mOrientation = BaseGridView.VERTICAL;
904fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        mNumRows = 1;
905fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        int pressDown = 15;
906fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
9078c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
908fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
909fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        mGridView.setSelectedPositionSmooth(0);
910f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        waitForScrollIdle(mVerifyLayout);
911fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
912fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        for (int i = 0; i < pressDown; i++) {
913fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
914fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        }
915fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        waitForScrollIdle(mVerifyLayout);
916fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu        assertFalse(mGridView.isFocused());
917fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
918fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu    }
919fa5f60106a84a2b475c38cc6b8baa347bbd6ae1dDake Gu
9208c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    public void testSetSelectionWithDelta() throws Throwable {
9218c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mInstrumentation = getInstrumentation();
9228c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
9238c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
9248c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                R.layout.vertical_linear);
9258c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 300);
9268c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
9278c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mOrientation = BaseGridView.VERTICAL;
9288c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mNumRows = 1;
9298c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9308c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
9318c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9328c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
9338c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
9348c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(3);
9358c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
9368c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
9378c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
9388c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top1 = mGridView.getLayoutManager().findViewByPosition(3).getTop();
9398c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
940f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(1000);
9418c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9428c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to position with delta
943f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(3, 100);
9448c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top2 = mGridView.getLayoutManager().findViewByPosition(3).getTop();
9458c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top2);
9468c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9478c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to same position without delta, it will be reset
948f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(3, 0);
9498c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top3 = mGridView.getLayoutManager().findViewByPosition(3).getTop();
9508c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top3);
9518c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9528c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item after last visible item
9538c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int lastVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
9548c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getLastVisibleIndex();
955f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(lastVisiblePos + 1, 100);
9568c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top4 = mGridView.getLayoutManager().findViewByPosition(lastVisiblePos + 1).getTop();
9578c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top4);
9588c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9598c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item before first visible item
9608c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int firstVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
9618c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getFirstVisibleIndex();
962f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(firstVisiblePos - 1, 100);
9638c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top5 = mGridView.getLayoutManager().findViewByPosition(firstVisiblePos - 1).getTop();
9648c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top5);
9658c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9668c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
967f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(50, 100);
9688c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top6 = mGridView.getLayoutManager().findViewByPosition(50).getTop();
9698c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top6);
9708c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9718c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
9728c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
9738c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
9748c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(100);
9758c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
9768c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
9778c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
9788c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top7 = mGridView.getLayoutManager().findViewByPosition(100).getTop();
9798c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top7);
9808c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9818c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
982f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(10, 50);
9838c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top8 = mGridView.getLayoutManager().findViewByPosition(10).getTop();
9848c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 50, top8);
9858c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    }
9868c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9878c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    public void testSetSelectionWithDeltaInGrid() throws Throwable {
9888c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mInstrumentation = getInstrumentation();
9898c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
9908c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
9918c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                R.layout.vertical_grid);
9928c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 500);
9938c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, true);
9948c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mOrientation = BaseGridView.VERTICAL;
9958c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mNumRows = 3;
9968c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9978c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
9988c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
9998c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
10008c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
10018c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(10);
10028c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
10038c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
10048c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
10058c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top1 = getCenterY(mGridView.getLayoutManager().findViewByPosition(10));
10068c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
1007f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
10088c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
10098c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to position with delta
1010f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(20, 100);
10118c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top2 = getCenterY(mGridView.getLayoutManager().findViewByPosition(20));
10128c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top2);
10138c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
10148c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to same position without delta, it will be reset
1015f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(20, 0);
10168c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top3 = getCenterY(mGridView.getLayoutManager().findViewByPosition(20));
10178c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top3);
10188c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
10198c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item after last visible item
10208c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int lastVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
10218c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getLastVisibleIndex();
1022f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(lastVisiblePos + 1, 100);
10238c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top4 = getCenterY(mGridView.getLayoutManager().findViewByPosition(lastVisiblePos + 1));
10248c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        verifyMargin();
10258c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top4);
10268c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
10278c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item before first visible item
10288c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int firstVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
10298c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getFirstVisibleIndex();
1030f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(firstVisiblePos - 1, 100);
10318c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top5 = getCenterY(mGridView.getLayoutManager().findViewByPosition(firstVisiblePos - 1));
10328c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top5);
10338c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
10348c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
1035f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(100, 100);
10368c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top6 = getCenterY(mGridView.getLayoutManager().findViewByPosition(100));
10378c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top6);
10388c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
10398c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
10408c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
10418c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
10428c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(200);
10438c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
10448c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
10458c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
10468c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Thread.sleep(500);
10478c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top7 = getCenterY(mGridView.getLayoutManager().findViewByPosition(200));
10488c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top7);
10498c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
10508c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
1051f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(10, 50);
10528c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top8 = getCenterY(mGridView.getLayoutManager().findViewByPosition(10));
10538c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 50, top8);
10548c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    }
10558c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
10568c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
10578c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    public void testSetSelectionWithDeltaInGrid1() throws Throwable {
10588c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mInstrumentation = getInstrumentation();
10598c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
10608c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
10618c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                R.layout.vertical_grid);
10628c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, new int[]{
10638c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                193,176,153,141,203,184,232,139,177,206,222,136,132,237,172,137,
10648c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                188,172,163,213,158,219,209,147,133,229,170,197,138,215,188,205,
10658c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                223,192,225,170,195,127,229,229,210,195,134,142,160,139,130,222,
10668c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                150,163,180,176,157,137,234,169,159,167,182,150,224,231,202,236,
10678c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                123,140,181,223,120,185,183,221,123,210,134,158,166,208,149,128,
10688c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                192,214,212,198,133,140,158,133,229,173,226,141,180,128,127,218,
10698c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                192,235,183,213,216,150,143,193,125,141,219,210,195,195,192,191,
10708c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                212,236,157,189,160,220,147,158,220,199,233,231,201,180,168,141,
10718c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                156,204,191,183,190,153,123,210,238,151,139,221,223,200,175,191,
10728c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                132,184,197,204,236,157,230,151,195,219,212,143,172,149,219,184,
10738c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                164,211,132,187,172,142,174,146,127,147,206,238,188,129,199,226,
10748c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                132,220,210,159,235,153,208,182,196,123,180,159,131,135,175,226,
10758c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                127,134,237,211,133,225,132,124,160,226,224,200,173,137,217,169,
10768c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                182,183,176,185,122,168,195,159,172,129,126,129,166,136,149,220,
10778c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                178,191,192,238,180,208,234,154,222,206,239,228,129,140,203,125,
10788c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                214,175,125,169,196,132,234,138,192,142,234,190,215,232,239,122,
10798c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                188,158,128,221,159,237,207,157,232,138,132,214,122,199,121,191,
10808c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                199,209,126,164,175,187,173,186,194,224,191,196,146,208,213,210,
10818c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                164,176,202,213,123,157,179,138,217,129,186,166,237,211,157,130,
10828c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                137,132,171,232,216,239,180,151,137,132,190,133,218,155,171,227,
10838c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                193,147,197,164,120,218,193,154,170,196,138,222,161,235,143,154,
10848c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                192,178,228,195,178,133,203,178,173,206,178,212,136,157,169,124,
10858c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                172,121,128,223,238,125,217,187,184,156,169,215,231,124,210,174,
10868c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                146,226,185,134,223,228,183,182,136,133,199,146,180,233,226,225,
10878c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                174,233,145,235,216,170,192,171,132,132,134,223,233,148,154,162,
10888c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                192,179,197,203,139,197,174,187,135,132,180,136,192,195,124,221,
10898c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                120,189,233,233,146,225,234,163,215,143,132,198,156,205,151,190,
10908c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                204,239,221,229,123,138,134,217,219,136,218,215,167,139,195,125,
10918c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                202,225,178,226,145,208,130,194,228,197,157,215,124,147,174,123,
10928c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                237,140,172,181,161,151,229,216,199,199,179,213,146,122,222,162,
10938c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                139,173,165,150,160,217,207,137,165,175,129,158,134,133,178,199,
10948c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                215,213,122,197
10958c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
10968c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, true);
10978c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mOrientation = BaseGridView.VERTICAL;
10988c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        mNumRows = 3;
10998c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
11008c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        initActivity(intent);
11018c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
11028c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
11038c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
11048c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(10);
11058c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
11068c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
11078c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
11088c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top1 = getCenterY(mGridView.getLayoutManager().findViewByPosition(10));
11098c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
1110f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
11118c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
11128c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to position with delta
1113f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(20, 100);
11148c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top2 = getCenterY(mGridView.getLayoutManager().findViewByPosition(20));
11158c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top2);
11168c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
11178c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to same position without delta, it will be reset
1118f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(20, 0);
11198c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top3 = getCenterY(mGridView.getLayoutManager().findViewByPosition(20));
11208c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top3);
11218c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
11228c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item after last visible item
11238c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int lastVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
11248c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getLastVisibleIndex();
1125f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(lastVisiblePos + 1, 100);
11268c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top4 = getCenterY(mGridView.getLayoutManager().findViewByPosition(lastVisiblePos + 1));
11278c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        verifyMargin();
11288c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top4);
11298c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
11308c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll invisible item before first visible item
11318c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        final int firstVisiblePos = ((GridLayoutManager)mGridView.getLayoutManager())
11328c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                .mGrid.getFirstVisibleIndex();
1133f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(firstVisiblePos - 1, 100);
11348c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top5 = getCenterY(mGridView.getLayoutManager().findViewByPosition(firstVisiblePos - 1));
11358c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top5);
11368c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
11378c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
1138f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(100, 100);
11398c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top6 = getCenterY(mGridView.getLayoutManager().findViewByPosition(100));
11408c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 100, top6);
11418c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
11428c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
11438c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        runTestOnUiThread(new Runnable() {
11448c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            public void run() {
11458c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu                mGridView.setSelectedPositionSmooth(200);
11468c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu            }
11478c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        });
11488c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        waitForScrollIdle(mVerifyLayout);
11498c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        Thread.sleep(500);
11508c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top7 = getCenterY(mGridView.getLayoutManager().findViewByPosition(200));
11518c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1, top7);
11528c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu
11538c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        // scroll to invisible item that is far away.
1154f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        setSelectedPosition(10, 50);
11558c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        int top8 = getCenterY(mGridView.getLayoutManager().findViewByPosition(10));
11568c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu        assertEquals(top1 - 50, top8);
11578c5d3b45f6afa838e64e4cf011a385c191d557c6Dake Gu    }
1158f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1159f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu    public void testSmoothScrollSelectionEvents() throws Throwable {
1160f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mInstrumentation = getInstrumentation();
1161f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1162f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1163f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                R.layout.vertical_grid);
1164f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 500);
1165f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
1166f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mOrientation = BaseGridView.VERTICAL;
1167f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mNumRows = 3;
1168f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        initActivity(intent);
1169f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1170f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        runTestOnUiThread(new Runnable() {
1171f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            public void run() {
1172f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                mGridView.setSelectedPositionSmooth(30);
1173f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            }
1174f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        });
1175f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        waitForScrollIdle(mVerifyLayout);
1176f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
1177f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1178f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        final ArrayList<Integer> selectedPositions = new ArrayList<Integer>();
1179f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mGridView.setOnChildSelectedListener(new OnChildSelectedListener() {
1180f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            @Override
1181f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            public void onChildSelected(ViewGroup parent, View view, int position, long id) {
1182f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                selectedPositions.add(position);
1183f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            }
1184f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        });
1185f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1186f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        sendRepeatedKeys(10, KeyEvent.KEYCODE_DPAD_UP);
1187f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
1188f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        waitForScrollIdle(mVerifyLayout);
1189f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        // should only get childselected event for item 0 once
1190f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        assertTrue(selectedPositions.size() > 0);
1191f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        assertEquals(0, selectedPositions.get(selectedPositions.size() - 1).intValue());
1192f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        for (int i = selectedPositions.size() - 2; i >= 0; i--) {
1193f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            assertFalse(0 == selectedPositions.get(i).intValue());
1194f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        }
1195f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1196f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu    }
1197f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1198f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu    public void testSmoothScrollSelectionEventsLinear() throws Throwable {
1199f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mInstrumentation = getInstrumentation();
1200f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1201f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1202f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                R.layout.vertical_linear);
1203f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 500);
1204f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
1205f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mOrientation = BaseGridView.VERTICAL;
1206f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mNumRows = 1;
1207f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        initActivity(intent);
1208f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1209f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        runTestOnUiThread(new Runnable() {
1210f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            public void run() {
1211f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                mGridView.setSelectedPositionSmooth(10);
1212f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            }
1213f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        });
1214f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        waitForScrollIdle(mVerifyLayout);
1215f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
1216f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1217f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        final ArrayList<Integer> selectedPositions = new ArrayList<Integer>();
1218f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        mGridView.setOnChildSelectedListener(new OnChildSelectedListener() {
1219f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            @Override
1220f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            public void onChildSelected(ViewGroup parent, View view, int position, long id) {
1221f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu                selectedPositions.add(position);
1222f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            }
1223f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        });
1224f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1225f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        sendRepeatedKeys(10, KeyEvent.KEYCODE_DPAD_UP);
1226f518dc6b5898d16d0b8818ff4d06425b2bb0b3d0Dake Gu        humanDelay(500);
1227f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        waitForScrollIdle(mVerifyLayout);
1228f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        // should only get childselected event for item 0 once
1229f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        assertTrue(selectedPositions.size() > 0);
1230f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        assertEquals(0, selectedPositions.get(selectedPositions.size() - 1).intValue());
1231f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        for (int i = selectedPositions.size() - 2; i >= 0; i--) {
1232f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu            assertFalse(0 == selectedPositions.get(i).intValue());
1233f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu        }
1234f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu
1235f80ef0d6b0b6403f3cd94e7197bc4a39d285280aDake Gu    }
12367538845719cd1e588185ce9ae60320377862ef8dDake Gu
12377538845719cd1e588185ce9ae60320377862ef8dDake Gu    public void testScrollToNoneExisting() throws Throwable {
12387538845719cd1e588185ce9ae60320377862ef8dDake Gu        mInstrumentation = getInstrumentation();
12397538845719cd1e588185ce9ae60320377862ef8dDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
12407538845719cd1e588185ce9ae60320377862ef8dDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
12417538845719cd1e588185ce9ae60320377862ef8dDake Gu                R.layout.vertical_grid);
12427538845719cd1e588185ce9ae60320377862ef8dDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 100);
12437538845719cd1e588185ce9ae60320377862ef8dDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
12447538845719cd1e588185ce9ae60320377862ef8dDake Gu        mOrientation = BaseGridView.VERTICAL;
12457538845719cd1e588185ce9ae60320377862ef8dDake Gu        mNumRows = 3;
12467538845719cd1e588185ce9ae60320377862ef8dDake Gu        initActivity(intent);
12477538845719cd1e588185ce9ae60320377862ef8dDake Gu
12487538845719cd1e588185ce9ae60320377862ef8dDake Gu        runTestOnUiThread(new Runnable() {
12497538845719cd1e588185ce9ae60320377862ef8dDake Gu            public void run() {
12507538845719cd1e588185ce9ae60320377862ef8dDake Gu                mGridView.setSelectedPositionSmooth(99);
12517538845719cd1e588185ce9ae60320377862ef8dDake Gu            }
12527538845719cd1e588185ce9ae60320377862ef8dDake Gu        });
12537538845719cd1e588185ce9ae60320377862ef8dDake Gu        waitForScrollIdle(mVerifyLayout);
12547538845719cd1e588185ce9ae60320377862ef8dDake Gu        humanDelay(500);
12557538845719cd1e588185ce9ae60320377862ef8dDake Gu
12567538845719cd1e588185ce9ae60320377862ef8dDake Gu
12577538845719cd1e588185ce9ae60320377862ef8dDake Gu        runTestOnUiThread(new Runnable() {
12587538845719cd1e588185ce9ae60320377862ef8dDake Gu            public void run() {
12597538845719cd1e588185ce9ae60320377862ef8dDake Gu                mGridView.setSelectedPositionSmooth(50);
12607538845719cd1e588185ce9ae60320377862ef8dDake Gu            }
12617538845719cd1e588185ce9ae60320377862ef8dDake Gu        });
12627538845719cd1e588185ce9ae60320377862ef8dDake Gu        Thread.sleep(100);
12637538845719cd1e588185ce9ae60320377862ef8dDake Gu        runTestOnUiThread(new Runnable() {
12647538845719cd1e588185ce9ae60320377862ef8dDake Gu            public void run() {
12657538845719cd1e588185ce9ae60320377862ef8dDake Gu                mGridView.requestLayout();
12667538845719cd1e588185ce9ae60320377862ef8dDake Gu                mGridView.setSelectedPositionSmooth(0);
12677538845719cd1e588185ce9ae60320377862ef8dDake Gu            }
12687538845719cd1e588185ce9ae60320377862ef8dDake Gu        });
12697538845719cd1e588185ce9ae60320377862ef8dDake Gu        waitForScrollIdle(mVerifyLayout);
12707538845719cd1e588185ce9ae60320377862ef8dDake Gu        humanDelay(500);
12717538845719cd1e588185ce9ae60320377862ef8dDake Gu
12727538845719cd1e588185ce9ae60320377862ef8dDake Gu    }
12737538845719cd1e588185ce9ae60320377862ef8dDake Gu
12743a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu    public void testSmoothscrollerInterrupted() throws Throwable {
12753a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        mInstrumentation = getInstrumentation();
12763a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
12773a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
12783a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                R.layout.vertical_linear);
12793a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
12803a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        int[] items = new int[100];
12813a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        for (int i = 0; i < items.length; i++) {
12823a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            items[i] = 680;
12833a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        }
12843a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
12853a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
12863a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        mOrientation = BaseGridView.VERTICAL;
12873a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        mNumRows = 1;
12883a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu
12893a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        initActivity(intent);
12903a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu
12913a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        mGridView.setSelectedPositionSmooth(0);
12923a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        waitForScrollIdle(mVerifyLayout);
12933a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        assertTrue(mGridView.getChildAt(0).hasFocus());
12943a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu
12953a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        // Pressing lots of key to make sure smooth scroller is running
12963a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        for (int i = 0; i < 20; i++) {
12973a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
12983a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        }
12993a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        Thread.sleep(100);
13003a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        int total = 0;
13013a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        while (mGridView.getLayoutManager().isSmoothScrolling() ||
13023a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                mGridView.getScrollState() != BaseGridView.SCROLL_STATE_IDLE) {
13033a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            if ((total += 10) >= WAIT_FOR_SCROLL_IDLE_TIMEOUT_MS) {
13043a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                throw new RuntimeException("waitForScrollIdle Timeout");
13053a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            }
13063a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            try {
13073a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                // Repeatedly pressing to make sure pending keys does not drop to zero.
13083a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                Thread.sleep(10);
13093a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
13103a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            } catch (InterruptedException ex) {
13113a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                break;
13123a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu            }
13133a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        }
13143a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu
13153a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu        assertTrue("LinearSmoothScroller would not use many RV.smoothScrollBy() calls",
13163a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu                ((VerticalGridViewEx) mGridView).mSmoothScrollByCalled < 10);
13173a7aa9cd68bd39f3a843291817dc209d1d9a45aaDake Gu    }
131857f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu
131957f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu    public void testSetNumRowsAndAddItem() throws Throwable {
132057f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        mInstrumentation = getInstrumentation();
132157f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
132257f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
132357f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu                R.layout.vertical_linear);
132457f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
132557f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        int[] items = new int[2];
132657f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        for (int i = 0; i < items.length; i++) {
132757f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu            items[i] = 300;
132857f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        }
132957f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
133057f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
133157f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        mOrientation = BaseGridView.VERTICAL;
133257f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        mNumRows = 1;
133357f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu
133457f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        initActivity(intent);
133557f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu
133657f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        mGridView.setSelectedPositionSmooth(0);
133757f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        waitForScrollIdle(mVerifyLayout);
133857f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu
133957f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        mActivity.addItems(items.length, new int[]{300});
134057f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu
134157f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        runTestOnUiThread(new Runnable() {
134257f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu            public void run() {
134357f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu                ((VerticalGridView) mGridView).setNumColumns(2);
134457f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu            }
134557f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        });
134657f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        Thread.sleep(1000);
134757f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu        assertTrue(mGridView.getChildAt(2).getLeft() != mGridView.getChildAt(1).getLeft());
134857f5baa07260dad2a9641e9ceb80567ce2784e9aDake Gu    }
1349c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1350c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1351c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu    public void testRequestLayoutBugInLayout() throws Throwable {
1352c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        mInstrumentation = getInstrumentation();
1353c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1354c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1355c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                R.layout.vertical_linear);
1356c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.relative_layout);
1357c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
1358c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        int[] items = new int[100];
1359c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        for (int i = 0; i < items.length; i++) {
1360c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu            items[i] = 300;
1361c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        }
1362c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
1363c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
1364c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        mOrientation = BaseGridView.VERTICAL;
1365c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        mNumRows = 1;
1366c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1367c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        initActivity(intent);
1368c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1369c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        runTestOnUiThread(new Runnable() {
1370c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu            public void run() {
1371c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu                mGridView.setSelectedPositionSmooth(1);
1372c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu            }
1373c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        });
1374c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        waitForScrollIdle(mVerifyLayout);
1375c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1376c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
1377c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        waitForScrollIdle(mVerifyLayout);
1378c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu
1379c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu        assertEquals("Line 2", ((TextView) mGridView.findFocus()).getText().toString());
1380c0b265dd2df42b399ba1f959b3dfd14dd14012b5Dake Gu    }
1381492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu
1382492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu
1383492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu    public void testChangeLayoutInChild() throws Throwable {
1384492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        mInstrumentation = getInstrumentation();
1385492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1386492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1387492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                R.layout.vertical_linear_wrap_content);
1388492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_LAYOUT_ONFOCUS, true);
1389492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        int[] items = new int[2];
1390492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        for (int i = 0; i < items.length; i++) {
1391492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu            items[i] = 300;
1392492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        }
1393492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
1394492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
1395492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        mOrientation = BaseGridView.VERTICAL;
1396492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        mNumRows = 1;
1397492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu
1398492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        initActivity(intent);
1399492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu
1400492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        runTestOnUiThread(new Runnable() {
1401492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu            public void run() {
1402492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                mGridView.setSelectedPositionSmooth(0);
1403492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu            }
1404492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        });
1405492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        waitForScrollIdle(mVerifyLayout);
1406492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        verifyMargin();
1407492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu
1408492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        runTestOnUiThread(new Runnable() {
1409492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu            public void run() {
1410492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu                mGridView.setSelectedPositionSmooth(1);
1411492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu            }
1412492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        });
1413492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        waitForScrollIdle(mVerifyLayout);
1414492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu        verifyMargin();
1415492506cede17ecee39ce7fa35ee7a347ff31c5baDake Gu    }
14161a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu
14171a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu
14181a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu    public void testZeroFixedSecondarySize() throws Throwable {
14191a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        mInstrumentation = getInstrumentation();
14201a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
14211a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
14221a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu                R.layout.vertical_linear_measured_with_zero);
14231a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        intent.putExtra(GridActivity.EXTRA_SECONDARY_SIZE_ZERO, true);
14241a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        int[] items = new int[2];
14251a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        for (int i = 0; i < items.length; i++) {
14261a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu            items[i] = 0;
14271a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        }
14281a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
14291a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
14301a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        mOrientation = BaseGridView.VERTICAL;
14311a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        mNumRows = 1;
14321a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu
14331a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu        initActivity(intent);
14341a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu
14351a5a2c58890e69b0554a82f22e3c0d1ffb238366Dake Gu    }
14363bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
14373bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu    public void testChildStates() throws Throwable {
14383bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        mInstrumentation = getInstrumentation();
14393bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
14403bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.vertical_linear);
14413bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        int[] items = new int[100];
14423bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        for (int i = 0; i < items.length; i++) {
14433bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            items[i] = 200;
14443bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        }
14453bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
14463bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
14473bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_LAYOUT_ONFOCUS, true);
14483bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.selectable_text_view);
14493bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        mOrientation = BaseGridView.VERTICAL;
14503bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        mNumRows = 1;
14513bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
14523bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        initActivity(intent);
14533bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        mGridView.setSaveChildrenPolicy(VerticalGridView.SAVE_ALL_CHILD);
14543bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
145561e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        final SparseArray<Parcelable> container = new SparseArray<Parcelable>();
14563bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
14573bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        // 1 Save view states
14583bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        runTestOnUiThread(new Runnable() {
14593bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            public void run() {
14603bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                Selection.setSelection((Spannable)(((TextView) mGridView.getChildAt(0))
14613bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                        .getText()), 0, 1);
14623bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                Selection.setSelection((Spannable)(((TextView) mGridView.getChildAt(1))
14633bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                        .getText()), 0, 1);
14643bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                mGridView.saveHierarchyState(container);
14653bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            }
14663bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        });
14673bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
14683bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        // 2 Change view states
14693bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        runTestOnUiThread(new Runnable() {
14703bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            public void run() {
14713bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                Selection.setSelection((Spannable)(((TextView) mGridView.getChildAt(0))
14723bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                        .getText()), 1, 2);
14733bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                Selection.setSelection((Spannable)(((TextView) mGridView.getChildAt(1))
14743bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                        .getText()), 1, 2);
14753bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            }
14763bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        });
14773bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
14783bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        // 3 Detached and re-attached,  should still maintain state of (2)
14793bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        runTestOnUiThread(new Runnable() {
14803bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            public void run() {
14813bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                mGridView.setSelectedPositionSmooth(1);
14823bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            }
14833bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        });
14843bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        waitForScrollIdle(mVerifyLayout);
14853bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(0)).getSelectionStart(), 1);
14863bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(0)).getSelectionEnd(), 2);
14873bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(1)).getSelectionStart(), 1);
14883bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(1)).getSelectionEnd(), 2);
14893bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
14903bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        // 4 Recycled and rebound, should load state from (2)
14913bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        runTestOnUiThread(new Runnable() {
14923bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            public void run() {
14933bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                mGridView.setSelectedPositionSmooth(20);
14943bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            }
14953bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        });
14963bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        waitForScrollIdle(mVerifyLayout);
14973bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        runTestOnUiThread(new Runnable() {
14983bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            public void run() {
14993bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu                mGridView.setSelectedPositionSmooth(0);
15003bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu            }
15013bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        });
15023bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        waitForScrollIdle(mVerifyLayout);
15033bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(0)).getSelectionStart(), 1);
15043bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(0)).getSelectionEnd(), 2);
15053bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(1)).getSelectionStart(), 1);
15063bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu        assertEquals(((TextView) mGridView.getChildAt(1)).getSelectionEnd(), 2);
15073bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu    }
15083bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
15093bd331ac6fe8ef25a2deb3559b0b5958573c231bDake Gu
151061e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu    public void testNoDispatchSaveChildState() throws Throwable {
151161e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        mInstrumentation = getInstrumentation();
151261e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
151361e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.vertical_linear);
151461e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        int[] items = new int[100];
151561e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        for (int i = 0; i < items.length; i++) {
151661e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            items[i] = 200;
151761e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        }
151861e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
151961e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
152061e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.selectable_text_view);
152161e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        mOrientation = BaseGridView.VERTICAL;
152261e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        mNumRows = 1;
152361e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
152461e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        initActivity(intent);
152561e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        mGridView.setSaveChildrenPolicy(VerticalGridView.SAVE_NO_CHILD);
152661e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
152761e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        final SparseArray<Parcelable> container = new SparseArray<Parcelable>();
152861e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
152961e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        // 1. Set text selection, save view states should do nothing on child
153061e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        runTestOnUiThread(new Runnable() {
153161e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            public void run() {
153261e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                for (int i = 0; i < mGridView.getChildCount(); i++) {
153361e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                    Selection.setSelection((Spannable)(((TextView) mGridView.getChildAt(i))
153461e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                            .getText()), 0, 1);
153561e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                }
153661e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                mGridView.saveHierarchyState(container);
153761e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            }
153861e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        });
153961e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
154061e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        // 2. clear the text selection
154161e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        runTestOnUiThread(new Runnable() {
154261e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            public void run() {
154361e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                for (int i = 0; i < mGridView.getChildCount(); i++) {
154461e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                    Selection.removeSelection((Spannable)(((TextView) mGridView.getChildAt(i))
154561e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                            .getText()));
154661e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                }
154761e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            }
154861e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        });
154961e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
155061e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        // 3. Restore view states should be a no-op for child
155161e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        runTestOnUiThread(new Runnable() {
155261e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            public void run() {
155361e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                mGridView.restoreHierarchyState(container);
155461e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                for (int i = 0; i < mGridView.getChildCount(); i++) {
155561e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                    assertEquals(-1, ((TextView) mGridView.getChildAt(i)).getSelectionStart());
155661e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                    assertEquals(-1, ((TextView) mGridView.getChildAt(i)).getSelectionEnd());
155761e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu                }
155861e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu            }
155961e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu        });
156061e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu    }
156161e5a56ed066815e69be7526e3d1bee2d5268d20Dake Gu
156208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
156308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static interface ViewTypeProvider {
156408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public int getViewType(int position);
156508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
156608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
156708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static interface ItemAlignmentFacetProvider {
156808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public ItemAlignmentFacet getItemAlignmentFacet(int viewType);
156908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
157008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
157108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static class TwoViewTypesProvider implements ViewTypeProvider {
157208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        static int VIEW_TYPE_FIRST = 1;
157308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        static int VIEW_TYPE_DEFAULT = 0;
157408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        @Override
157508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public int getViewType(int position) {
157608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (position == 0) {
157708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return VIEW_TYPE_FIRST;
157808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            } else {
157908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return VIEW_TYPE_DEFAULT;
158008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
158108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
158208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
158308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
158408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static class PositionItemAlignmentFacetProviderForRelativeLayout1
158508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            implements ItemAlignmentFacetProvider {
158608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        ItemAlignmentFacet mMultipleFacet;
158708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
158808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        PositionItemAlignmentFacetProviderForRelativeLayout1() {
158908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet = new ItemAlignmentFacet();
159008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            ItemAlignmentFacet.ItemAlignmentDef[] defs =
159108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                    new ItemAlignmentFacet.ItemAlignmentDef[2];
159208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0] = new ItemAlignmentFacet.ItemAlignmentDef();
159308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0].setItemAlignmentViewId(R.id.t1);
159408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1] = new ItemAlignmentFacet.ItemAlignmentDef();
159508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentViewId(R.id.t2);
159608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffsetPercent(100);
159708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffset(-10);
159808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet.setAlignmentDefs(defs);
159908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
160008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
160108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        @Override
160208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public ItemAlignmentFacet getItemAlignmentFacet(int position) {
160308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (position == 0) {
160408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return mMultipleFacet;
160508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            } else {
160608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return null;
160708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
160808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
160908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
161008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
161108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    public void testMultipleScrollPosition1() throws Throwable {
161208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mInstrumentation = getInstrumentation();
161308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
161408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
161508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                R.layout.vertical_linear);
161608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.relative_layout);
161708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
161808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int[] items = new int[100];
161908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        for (int i = 0; i < items.length; i++) {
162008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            items[i] = 300;
162108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
162208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
162308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
162408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_VIEWTYPEPROVIDER_CLASS,
162508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                TwoViewTypesProvider.class.getName());
162608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        // Set ItemAlignment for each ViewHolder and view type,  ViewHolder should
162708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        // override the view type settings.
162808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMALIGNMENTPROVIDER_CLASS,
162908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                PositionItemAlignmentFacetProviderForRelativeLayout1.class.getName());
163008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMALIGNMENTPROVIDER_VIEWTYPE_CLASS,
163108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                ViewTypePositionItemAlignmentFacetProviderForRelativeLayout2.class.getName());
163208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mOrientation = BaseGridView.VERTICAL;
163308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mNumRows = 1;
163408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
163508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        initActivity(intent);
163608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
163708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("First view is aligned with padding top",
163808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getPaddingTop(), mGridView.getChildAt(0).getTop());
163908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
164008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
164108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        waitForScrollIdle(mVerifyLayout);
164208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
164308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        final View v = mGridView.getChildAt(0);
164408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t1 = v.findViewById(R.id.t1);
164508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t1align = (t1.getTop() + t1.getBottom()) / 2;
164608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t2 = v.findViewById(R.id.t2);
164708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t2align = t2.getBottom() - 10;
164808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("Expected alignment for 2nd textview",
164908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getPaddingTop() - (t2align - t1align),
165008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                v.getTop());
165108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
165208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
165308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static class PositionItemAlignmentFacetProviderForRelativeLayout2 implements
165408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            ItemAlignmentFacetProvider {
165508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        ItemAlignmentFacet mMultipleFacet;
165608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
165708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        PositionItemAlignmentFacetProviderForRelativeLayout2() {
165808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet = new ItemAlignmentFacet();
165908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            ItemAlignmentFacet.ItemAlignmentDef[] defs = new ItemAlignmentFacet.ItemAlignmentDef[2];
166008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0] = new ItemAlignmentFacet.ItemAlignmentDef();
166108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0].setItemAlignmentViewId(R.id.t1);
166208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0].setItemAlignmentOffsetPercent(0);
166308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1] = new ItemAlignmentFacet.ItemAlignmentDef();
166408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentViewId(R.id.t2);
166508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffsetPercent(ItemAlignmentFacet.ITEM_ALIGN_OFFSET_PERCENT_DISABLED);
166608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffset(-10);
166708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet.setAlignmentDefs(defs);
166808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
166908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
167008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        @Override
167108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public ItemAlignmentFacet getItemAlignmentFacet(int position) {
167208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (position == 0) {
167308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return mMultipleFacet;
167408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            } else {
167508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return null;
167608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
167708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
167808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
167908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
168008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    public void testMultipleScrollPosition2() throws Throwable {
168108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mInstrumentation = getInstrumentation();
168208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
168308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.vertical_linear);
168408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.relative_layout);
168508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
168608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int[] items = new int[100];
168708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        for (int i = 0; i < items.length; i++) {
168808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            items[i] = 300;
168908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
169008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
169108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
169208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_VIEWTYPEPROVIDER_CLASS,
169308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                TwoViewTypesProvider.class.getName());
169408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMALIGNMENTPROVIDER_CLASS,
169508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                PositionItemAlignmentFacetProviderForRelativeLayout2.class.getName());
169608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mOrientation = BaseGridView.VERTICAL;
169708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mNumRows = 1;
169808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
169908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        initActivity(intent);
170008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
170108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("First view is aligned with padding top", mGridView.getPaddingTop(),
170208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getChildAt(0).getTop());
170308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
170408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
170508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        waitForScrollIdle(mVerifyLayout);
170608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
170708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        final View v = mGridView.getChildAt(0);
170808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t1 = v.findViewById(R.id.t1);
170908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t1align = t1.getTop();
171008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t2 = v.findViewById(R.id.t2);
171108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t2align = t2.getTop() - 10;
171208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("Expected alignment for 2nd textview",
171308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getPaddingTop() - (t2align - t1align), v.getTop());
171408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
171508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
171608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    static class ViewTypePositionItemAlignmentFacetProviderForRelativeLayout2 implements
171708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            ItemAlignmentFacetProvider {
171808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        ItemAlignmentFacet mMultipleFacet;
171908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
172008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        ViewTypePositionItemAlignmentFacetProviderForRelativeLayout2() {
172108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet = new ItemAlignmentFacet();
172208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            ItemAlignmentFacet.ItemAlignmentDef[] defs = new ItemAlignmentFacet.ItemAlignmentDef[2];
172308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0] = new ItemAlignmentFacet.ItemAlignmentDef();
172408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0].setItemAlignmentViewId(R.id.t1);
172508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[0].setItemAlignmentOffsetPercent(0);
172608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1] = new ItemAlignmentFacet.ItemAlignmentDef();
172708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentViewId(R.id.t2);
172808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffsetPercent(100);
172908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            defs[1].setItemAlignmentOffset(-10);
173008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            mMultipleFacet.setAlignmentDefs(defs);
173108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
173208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
173308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        @Override
173408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        public ItemAlignmentFacet getItemAlignmentFacet(int viewType) {
173508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            if (viewType == TwoViewTypesProvider.VIEW_TYPE_FIRST) {
173608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return mMultipleFacet;
173708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            } else {
173808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                return null;
173908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            }
174008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
174108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
174208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
174308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    public void testMultipleScrollPosition3() throws Throwable {
174408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mInstrumentation = getInstrumentation();
174508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
174608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.vertical_linear);
174708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_CHILD_LAYOUT_ID, R.layout.relative_layout);
174808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
174908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int[] items = new int[100];
175008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        for (int i = 0; i < items.length; i++) {
175108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu            items[i] = 300;
175208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        }
175308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
175408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
175508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_VIEWTYPEPROVIDER_CLASS,
175608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                TwoViewTypesProvider.class.getName());
175708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        intent.putExtra(GridActivity.EXTRA_ITEMALIGNMENTPROVIDER_VIEWTYPE_CLASS,
175808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                ViewTypePositionItemAlignmentFacetProviderForRelativeLayout2.class.getName());
175908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mOrientation = BaseGridView.VERTICAL;
176008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        mNumRows = 1;
176108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
176208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        initActivity(intent);
176308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
176408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("First view is aligned with padding top", mGridView.getPaddingTop(),
176508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getChildAt(0).getTop());
176608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
176708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
176808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        waitForScrollIdle(mVerifyLayout);
176908c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
177008c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        final View v = mGridView.getChildAt(0);
177108c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t1 = v.findViewById(R.id.t1);
177208c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t1align = t1.getTop();
177308c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        View t2 = v.findViewById(R.id.t2);
177408c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        int t2align = t2.getBottom() - 10;
177508c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu        assertEquals("Expected alignment for 2nd textview",
177608c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu                mGridView.getPaddingTop() - (t2align - t1align), v.getTop());
177708c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu    }
177808c56822b71ab0aa0b9bb03e5fd45e28f6e358b8Dake Gu
1779db0b1afb71440b79923692d58adee982b5954838Dake Gu    public void testSelectionAndAddItemInOneCycle() throws Throwable {
1780db0b1afb71440b79923692d58adee982b5954838Dake Gu        mInstrumentation = getInstrumentation();
1781db0b1afb71440b79923692d58adee982b5954838Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1782db0b1afb71440b79923692d58adee982b5954838Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1783db0b1afb71440b79923692d58adee982b5954838Dake Gu                R.layout.vertical_linear);
1784db0b1afb71440b79923692d58adee982b5954838Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 0);
1785db0b1afb71440b79923692d58adee982b5954838Dake Gu        initActivity(intent);
1786db0b1afb71440b79923692d58adee982b5954838Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
1787db0b1afb71440b79923692d58adee982b5954838Dake Gu        mNumRows = 1;
1788db0b1afb71440b79923692d58adee982b5954838Dake Gu
1789db0b1afb71440b79923692d58adee982b5954838Dake Gu        runTestOnUiThread(new Runnable() {
1790db0b1afb71440b79923692d58adee982b5954838Dake Gu            public void run() {
1791db0b1afb71440b79923692d58adee982b5954838Dake Gu                mActivity.addItems(0, new int[]{300, 300});
1792db0b1afb71440b79923692d58adee982b5954838Dake Gu                mGridView.setSelectedPosition(0);
1793db0b1afb71440b79923692d58adee982b5954838Dake Gu            }
1794db0b1afb71440b79923692d58adee982b5954838Dake Gu        });
1795db0b1afb71440b79923692d58adee982b5954838Dake Gu        waitForTransientStateGone(null);
1796db0b1afb71440b79923692d58adee982b5954838Dake Gu        assertEquals(0, mGridView.getSelectedPosition());
1797db0b1afb71440b79923692d58adee982b5954838Dake Gu    }
1798db0b1afb71440b79923692d58adee982b5954838Dake Gu
1799db0b1afb71440b79923692d58adee982b5954838Dake Gu    public void testSelectionSmoothAndAddItemInOneCycle() throws Throwable {
1800db0b1afb71440b79923692d58adee982b5954838Dake Gu        mInstrumentation = getInstrumentation();
1801db0b1afb71440b79923692d58adee982b5954838Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1802db0b1afb71440b79923692d58adee982b5954838Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1803db0b1afb71440b79923692d58adee982b5954838Dake Gu                R.layout.vertical_linear);
1804db0b1afb71440b79923692d58adee982b5954838Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 0);
1805db0b1afb71440b79923692d58adee982b5954838Dake Gu        initActivity(intent);
1806db0b1afb71440b79923692d58adee982b5954838Dake Gu        mOrientation = BaseGridView.HORIZONTAL;
1807db0b1afb71440b79923692d58adee982b5954838Dake Gu        mNumRows = 1;
1808db0b1afb71440b79923692d58adee982b5954838Dake Gu
1809db0b1afb71440b79923692d58adee982b5954838Dake Gu        runTestOnUiThread(new Runnable() {
1810db0b1afb71440b79923692d58adee982b5954838Dake Gu            public void run() {
1811db0b1afb71440b79923692d58adee982b5954838Dake Gu                mActivity.addItems(0, new int[]{300, 300});
1812db0b1afb71440b79923692d58adee982b5954838Dake Gu                mGridView.setSelectedPositionSmooth(0);
1813db0b1afb71440b79923692d58adee982b5954838Dake Gu            }
1814db0b1afb71440b79923692d58adee982b5954838Dake Gu        });
1815db0b1afb71440b79923692d58adee982b5954838Dake Gu        waitForTransientStateGone(null);
1816db0b1afb71440b79923692d58adee982b5954838Dake Gu        assertEquals(0, mGridView.getSelectedPosition());
1817db0b1afb71440b79923692d58adee982b5954838Dake Gu    }
181888dea72af6042049560140a70e059820dbb8f746Dake Gu
181988dea72af6042049560140a70e059820dbb8f746Dake Gu    public void testExtraLayoutSpace() throws Throwable {
182088dea72af6042049560140a70e059820dbb8f746Dake Gu        mInstrumentation = getInstrumentation();
182188dea72af6042049560140a70e059820dbb8f746Dake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
182288dea72af6042049560140a70e059820dbb8f746Dake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
182388dea72af6042049560140a70e059820dbb8f746Dake Gu                R.layout.vertical_linear);
182488dea72af6042049560140a70e059820dbb8f746Dake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 1000);
182588dea72af6042049560140a70e059820dbb8f746Dake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
182688dea72af6042049560140a70e059820dbb8f746Dake Gu        initActivity(intent);
182788dea72af6042049560140a70e059820dbb8f746Dake Gu
182888dea72af6042049560140a70e059820dbb8f746Dake Gu        final int windowSize = mGridView.getHeight();
182988dea72af6042049560140a70e059820dbb8f746Dake Gu        final int extraLayoutSize = windowSize;
183088dea72af6042049560140a70e059820dbb8f746Dake Gu        int itemLength = mActivity.mItemLengths[0];
183188dea72af6042049560140a70e059820dbb8f746Dake Gu        mOrientation = BaseGridView.VERTICAL;
183288dea72af6042049560140a70e059820dbb8f746Dake Gu        mNumRows = 1;
183388dea72af6042049560140a70e059820dbb8f746Dake Gu
183488dea72af6042049560140a70e059820dbb8f746Dake Gu        // add extra layout space
183588dea72af6042049560140a70e059820dbb8f746Dake Gu        runTestOnUiThread(new Runnable() {
183688dea72af6042049560140a70e059820dbb8f746Dake Gu            public void run() {
183788dea72af6042049560140a70e059820dbb8f746Dake Gu                mGridView.setExtraLayoutSpace(extraLayoutSize);
183888dea72af6042049560140a70e059820dbb8f746Dake Gu            }
183988dea72af6042049560140a70e059820dbb8f746Dake Gu        });
184088dea72af6042049560140a70e059820dbb8f746Dake Gu        Thread.sleep(50);
184188dea72af6042049560140a70e059820dbb8f746Dake Gu        View v;
184288dea72af6042049560140a70e059820dbb8f746Dake Gu        v = mGridView.getChildAt(mGridView.getChildCount() - 1);
184388dea72af6042049560140a70e059820dbb8f746Dake Gu        assertTrue(v.getTop() < windowSize + extraLayoutSize);
184488dea72af6042049560140a70e059820dbb8f746Dake Gu        assertTrue(v.getBottom() >= windowSize + extraLayoutSize -
184588dea72af6042049560140a70e059820dbb8f746Dake Gu                mGridView.getVerticalMargin());
184688dea72af6042049560140a70e059820dbb8f746Dake Gu
184788dea72af6042049560140a70e059820dbb8f746Dake Gu        mGridView.setSelectedPositionSmooth(150);
184888dea72af6042049560140a70e059820dbb8f746Dake Gu        waitForScrollIdle(mVerifyLayout);
184988dea72af6042049560140a70e059820dbb8f746Dake Gu        v = mGridView.getChildAt(0);
185088dea72af6042049560140a70e059820dbb8f746Dake Gu        assertTrue(v.getBottom() > - extraLayoutSize);
185188dea72af6042049560140a70e059820dbb8f746Dake Gu        assertTrue(v.getTop() <= -extraLayoutSize + mGridView.getVerticalMargin());
185288dea72af6042049560140a70e059820dbb8f746Dake Gu
185388dea72af6042049560140a70e059820dbb8f746Dake Gu        // clear extra layout space
185488dea72af6042049560140a70e059820dbb8f746Dake Gu        runTestOnUiThread(new Runnable() {
185588dea72af6042049560140a70e059820dbb8f746Dake Gu            public void run() {
185688dea72af6042049560140a70e059820dbb8f746Dake Gu                mGridView.setExtraLayoutSpace(0);
185788dea72af6042049560140a70e059820dbb8f746Dake Gu                verifyMargin();
185888dea72af6042049560140a70e059820dbb8f746Dake Gu            }
185988dea72af6042049560140a70e059820dbb8f746Dake Gu        });
186088dea72af6042049560140a70e059820dbb8f746Dake Gu        Thread.sleep(50);
186188dea72af6042049560140a70e059820dbb8f746Dake Gu        v = mGridView.getChildAt(mGridView.getChildCount() - 1);
186288dea72af6042049560140a70e059820dbb8f746Dake Gu        assertTrue(v.getTop() < windowSize);
186388dea72af6042049560140a70e059820dbb8f746Dake Gu        assertTrue(v.getBottom() >= windowSize - mGridView.getVerticalMargin());
186488dea72af6042049560140a70e059820dbb8f746Dake Gu    }
1865d1cab1b54104d55407335c5d649398635822fffdDake Gu
1866d1cab1b54104d55407335c5d649398635822fffdDake Gu    public void testAccessibility() throws Throwable {
1867d1cab1b54104d55407335c5d649398635822fffdDake Gu        mInstrumentation = getInstrumentation();
1868d1cab1b54104d55407335c5d649398635822fffdDake Gu        Intent intent = new Intent(mInstrumentation.getContext(), GridActivity.class);
1869d1cab1b54104d55407335c5d649398635822fffdDake Gu        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
1870d1cab1b54104d55407335c5d649398635822fffdDake Gu                R.layout.vertical_linear);
1871d1cab1b54104d55407335c5d649398635822fffdDake Gu        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 1000);
1872d1cab1b54104d55407335c5d649398635822fffdDake Gu        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
1873d1cab1b54104d55407335c5d649398635822fffdDake Gu        initActivity(intent);
1874d1cab1b54104d55407335c5d649398635822fffdDake Gu        mOrientation = BaseGridView.VERTICAL;
1875d1cab1b54104d55407335c5d649398635822fffdDake Gu        mNumRows = 1;
1876d1cab1b54104d55407335c5d649398635822fffdDake Gu
1877d1cab1b54104d55407335c5d649398635822fffdDake Gu        assertTrue(0 == mGridView.getSelectedPosition());
1878d1cab1b54104d55407335c5d649398635822fffdDake Gu
1879d1cab1b54104d55407335c5d649398635822fffdDake Gu        final RecyclerViewAccessibilityDelegate delegateCompat = mGridView
1880d1cab1b54104d55407335c5d649398635822fffdDake Gu                .getCompatAccessibilityDelegate();
1881d1cab1b54104d55407335c5d649398635822fffdDake Gu        final AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
1882d1cab1b54104d55407335c5d649398635822fffdDake Gu        runTestOnUiThread(new Runnable() {
1883d1cab1b54104d55407335c5d649398635822fffdDake Gu            @Override
1884d1cab1b54104d55407335c5d649398635822fffdDake Gu            public void run() {
1885d1cab1b54104d55407335c5d649398635822fffdDake Gu                delegateCompat.onInitializeAccessibilityNodeInfo(mGridView, info);
1886d1cab1b54104d55407335c5d649398635822fffdDake Gu            }
1887d1cab1b54104d55407335c5d649398635822fffdDake Gu        });
1888d1cab1b54104d55407335c5d649398635822fffdDake Gu        assertTrue("test sanity", info.isScrollable());
1889d1cab1b54104d55407335c5d649398635822fffdDake Gu        runTestOnUiThread(new Runnable() {
1890d1cab1b54104d55407335c5d649398635822fffdDake Gu            @Override
1891d1cab1b54104d55407335c5d649398635822fffdDake Gu            public void run() {
1892d1cab1b54104d55407335c5d649398635822fffdDake Gu                delegateCompat.performAccessibilityAction(mGridView,
1893d1cab1b54104d55407335c5d649398635822fffdDake Gu                        AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD, null);
1894d1cab1b54104d55407335c5d649398635822fffdDake Gu            }
1895d1cab1b54104d55407335c5d649398635822fffdDake Gu        });
1896d1cab1b54104d55407335c5d649398635822fffdDake Gu        waitForScrollIdle(mVerifyLayout);
1897d1cab1b54104d55407335c5d649398635822fffdDake Gu        int selectedPosition1 = mGridView.getSelectedPosition();
1898d1cab1b54104d55407335c5d649398635822fffdDake Gu        assertTrue(0 < selectedPosition1);
1899d1cab1b54104d55407335c5d649398635822fffdDake Gu
1900d1cab1b54104d55407335c5d649398635822fffdDake Gu        runTestOnUiThread(new Runnable() {
1901d1cab1b54104d55407335c5d649398635822fffdDake Gu            @Override
1902d1cab1b54104d55407335c5d649398635822fffdDake Gu            public void run() {
1903d1cab1b54104d55407335c5d649398635822fffdDake Gu                delegateCompat.onInitializeAccessibilityNodeInfo(mGridView, info);
1904d1cab1b54104d55407335c5d649398635822fffdDake Gu            }
1905d1cab1b54104d55407335c5d649398635822fffdDake Gu        });
1906d1cab1b54104d55407335c5d649398635822fffdDake Gu        assertTrue("test sanity", info.isScrollable());
1907d1cab1b54104d55407335c5d649398635822fffdDake Gu        runTestOnUiThread(new Runnable() {
1908d1cab1b54104d55407335c5d649398635822fffdDake Gu            @Override
1909d1cab1b54104d55407335c5d649398635822fffdDake Gu            public void run() {
1910d1cab1b54104d55407335c5d649398635822fffdDake Gu                delegateCompat.performAccessibilityAction(mGridView,
1911d1cab1b54104d55407335c5d649398635822fffdDake Gu                        AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD, null);
1912d1cab1b54104d55407335c5d649398635822fffdDake Gu            }
1913d1cab1b54104d55407335c5d649398635822fffdDake Gu        });
1914d1cab1b54104d55407335c5d649398635822fffdDake Gu        waitForScrollIdle(mVerifyLayout);
1915d1cab1b54104d55407335c5d649398635822fffdDake Gu        int selectedPosition2 = mGridView.getSelectedPosition();
1916d1cab1b54104d55407335c5d649398635822fffdDake Gu        assertTrue(selectedPosition2 < selectedPosition1);
1917d1cab1b54104d55407335c5d649398635822fffdDake Gu    }
1918d1cab1b54104d55407335c5d649398635822fffdDake Gu
1919062f7f7667bce6e9bf4814d0bb5344fe518ed89eDake Gu}
1920