1// CHECKSTYLE:OFF Generated code
2/* This file is auto-generated from RowsFragmentTest.java.  DO NOT MODIFY. */
3
4/*
5 * Copyright (C) 2016 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19package android.support.v17.leanback.app;
20
21import static org.junit.Assert.assertEquals;
22import static org.junit.Assert.assertNotNull;
23import static org.junit.Assert.assertSame;
24import static org.junit.Assert.assertTrue;
25
26import android.graphics.Rect;
27import android.os.Build;
28import android.os.Bundle;
29import android.os.Handler;
30import android.os.SystemClock;
31import android.support.test.InstrumentationRegistry;
32import android.support.test.filters.LargeTest;
33import android.support.test.filters.SdkSuppress;
34import android.support.test.runner.AndroidJUnit4;
35import android.support.v17.leanback.R;
36import android.support.v17.leanback.testutils.PollingCheck;
37import android.support.v17.leanback.widget.ArrayObjectAdapter;
38import android.support.v17.leanback.widget.HeaderItem;
39import android.support.v17.leanback.widget.HorizontalGridView;
40import android.support.v17.leanback.widget.ItemBridgeAdapter;
41import android.support.v17.leanback.widget.ListRow;
42import android.support.v17.leanback.widget.ListRowPresenter;
43import android.support.v17.leanback.widget.ObjectAdapter;
44import android.support.v17.leanback.widget.OnItemViewClickedListener;
45import android.support.v17.leanback.widget.Presenter;
46import android.support.v17.leanback.widget.Row;
47import android.support.v17.leanback.widget.RowPresenter;
48import android.support.v17.leanback.widget.SinglePresenterSelector;
49import android.support.v17.leanback.widget.VerticalGridView;
50import android.view.KeyEvent;
51import android.view.View;
52
53import org.junit.Test;
54import org.junit.runner.RunWith;
55
56import java.lang.ref.WeakReference;
57import java.util.ArrayList;
58
59@LargeTest
60@RunWith(AndroidJUnit4.class)
61public class RowsSupportFragmentTest extends SingleSupportFragmentTestBase {
62
63    static final StringPresenter sCardPresenter = new StringPresenter();
64
65    static void loadData(ArrayObjectAdapter adapter, int numRows, int repeatPerRow) {
66        for (int i = 0; i < numRows; ++i) {
67            ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(sCardPresenter);
68            int index = 0;
69            for (int j = 0; j < repeatPerRow; ++j) {
70                listRowAdapter.add("Hello world-" + (index++));
71                listRowAdapter.add("This is a test-" + (index++));
72                listRowAdapter.add("Android TV-" + (index++));
73                listRowAdapter.add("Leanback-" + (index++));
74                listRowAdapter.add("Hello world-" + (index++));
75                listRowAdapter.add("Android TV-" + (index++));
76                listRowAdapter.add("Leanback-" + (index++));
77                listRowAdapter.add("GuidedStepSupportFragment-" + (index++));
78            }
79            HeaderItem header = new HeaderItem(i, "Row " + i);
80            adapter.add(new ListRow(header, listRowAdapter));
81        }
82    }
83
84    public static class F_defaultAlignment extends RowsSupportFragment {
85        @Override
86        public void onCreate(Bundle savedInstanceState) {
87            super.onCreate(savedInstanceState);
88            ListRowPresenter lrp = new ListRowPresenter();
89            ArrayObjectAdapter adapter = new ArrayObjectAdapter(lrp);
90            setAdapter(adapter);
91            loadData(adapter, 10, 1);
92        }
93    }
94
95    @Test
96    public void defaultAlignment() throws Throwable {
97        SingleSupportFragmentTestActivity activity = launchAndWaitActivity(F_defaultAlignment.class, 1000);
98
99        final Rect rect = new Rect();
100
101        final VerticalGridView gridView = ((RowsSupportFragment) activity.getTestFragment())
102                .getVerticalGridView();
103        View row0 = gridView.findViewHolderForAdapterPosition(0).itemView;
104        rect.set(0, 0, row0.getWidth(), row0.getHeight());
105        gridView.offsetDescendantRectToMyCoords(row0, rect);
106        assertEquals("First row is initially aligned to top of screen", 0, rect.top);
107
108        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
109        waitForScrollIdle(gridView);
110        View row1 = gridView.findViewHolderForAdapterPosition(1).itemView;
111        PollingCheck.waitFor(new PollingCheck.ViewStableOnScreen(row1));
112
113        rect.set(0, 0, row1.getWidth(), row1.getHeight());
114        gridView.offsetDescendantRectToMyCoords(row1, rect);
115        assertTrue("Second row should not be aligned to top of screen", rect.top > 0);
116    }
117
118    public static class F_selectBeforeSetAdapter extends RowsSupportFragment {
119        @Override
120        public void onCreate(Bundle savedInstanceState) {
121            super.onCreate(savedInstanceState);
122            setSelectedPosition(7, false);
123            new Handler().postDelayed(new Runnable() {
124                @Override
125                public void run() {
126                    getVerticalGridView().requestLayout();
127                }
128            }, 100);
129            new Handler().postDelayed(new Runnable() {
130                @Override
131                public void run() {
132                    ListRowPresenter lrp = new ListRowPresenter();
133                    ArrayObjectAdapter adapter = new ArrayObjectAdapter(lrp);
134                    setAdapter(adapter);
135                    loadData(adapter, 10, 1);
136                }
137            }, 1000);
138        }
139    }
140
141    @Test
142    public void selectBeforeSetAdapter() throws InterruptedException {
143        SingleSupportFragmentTestActivity activity =
144                launchAndWaitActivity(F_selectBeforeSetAdapter.class, 2000);
145
146        final VerticalGridView gridView = ((RowsSupportFragment) activity.getTestFragment())
147                .getVerticalGridView();
148        assertEquals(7, gridView.getSelectedPosition());
149        assertNotNull(gridView.findViewHolderForAdapterPosition(7));
150    }
151
152    public static class F_selectBeforeAddData extends RowsSupportFragment {
153        @Override
154        public void onCreate(Bundle savedInstanceState) {
155            super.onCreate(savedInstanceState);
156            ListRowPresenter lrp = new ListRowPresenter();
157            final ArrayObjectAdapter adapter = new ArrayObjectAdapter(lrp);
158            setAdapter(adapter);
159            setSelectedPosition(7, false);
160            new Handler().postDelayed(new Runnable() {
161                @Override
162                public void run() {
163                    getVerticalGridView().requestLayout();
164                }
165            }, 100);
166            new Handler().postDelayed(new Runnable() {
167                @Override
168                public void run() {
169                    loadData(adapter, 10, 1);
170                }
171            }, 1000);
172        }
173    }
174
175    @Test
176    public void selectBeforeAddData() throws InterruptedException {
177        SingleSupportFragmentTestActivity activity =
178                launchAndWaitActivity(F_selectBeforeAddData.class, 2000);
179
180        final VerticalGridView gridView = ((RowsSupportFragment) activity.getTestFragment())
181                .getVerticalGridView();
182        assertEquals(7, gridView.getSelectedPosition());
183        assertNotNull(gridView.findViewHolderForAdapterPosition(7));
184    }
185
186    public static class F_selectAfterAddData extends RowsSupportFragment {
187        @Override
188        public void onCreate(Bundle savedInstanceState) {
189            super.onCreate(savedInstanceState);
190            ListRowPresenter lrp = new ListRowPresenter();
191            final ArrayObjectAdapter adapter = new ArrayObjectAdapter(lrp);
192            setAdapter(adapter);
193            loadData(adapter, 10, 1);
194            new Handler().postDelayed(new Runnable() {
195                @Override
196                public void run() {
197                    setSelectedPosition(7, false);
198                }
199            }, 1000);
200        }
201    }
202
203    @Test
204    public void selectAfterAddData() throws InterruptedException {
205        SingleSupportFragmentTestActivity activity =
206                launchAndWaitActivity(F_selectAfterAddData.class, 2000);
207
208        final VerticalGridView gridView = ((RowsSupportFragment) activity.getTestFragment())
209                .getVerticalGridView();
210        assertEquals(7, gridView.getSelectedPosition());
211        assertNotNull(gridView.findViewHolderForAdapterPosition(7));
212    }
213
214    static WeakReference<F_restoreSelection> sLastF_restoreSelection;
215
216    public static class F_restoreSelection extends RowsSupportFragment {
217        public F_restoreSelection() {
218            sLastF_restoreSelection = new WeakReference<F_restoreSelection>(this);
219        }
220
221        @Override
222        public void onCreate(Bundle savedInstanceState) {
223            super.onCreate(savedInstanceState);
224            ListRowPresenter lrp = new ListRowPresenter();
225            final ArrayObjectAdapter adapter = new ArrayObjectAdapter(lrp);
226            setAdapter(adapter);
227            loadData(adapter, 10, 1);
228            if (savedInstanceState == null) {
229                setSelectedPosition(7, false);
230            }
231        }
232    }
233
234    @Test
235    public void restoreSelection() {
236        final SingleSupportFragmentTestActivity activity =
237                launchAndWaitActivity(F_restoreSelection.class, 1000);
238
239        InstrumentationRegistry.getInstrumentation().runOnMainSync(
240                new Runnable() {
241                    @Override
242                    public void run() {
243                        activity.recreate();
244                    }
245                }
246        );
247        SystemClock.sleep(1000);
248
249        // mActivity is invalid after recreate(), a new Activity instance is created
250        // but we could get Fragment from static variable.
251        RowsSupportFragment fragment = sLastF_restoreSelection.get();
252        final VerticalGridView gridView = fragment.getVerticalGridView();
253        assertEquals(7, gridView.getSelectedPosition());
254        assertNotNull(gridView.findViewHolderForAdapterPosition(7));
255
256    }
257
258    public static class F_ListRowWithOnClick extends RowsSupportFragment {
259        Presenter.ViewHolder mLastClickedItemViewHolder;
260        @Override
261        public void onCreate(Bundle savedInstanceState) {
262            super.onCreate(savedInstanceState);
263            setOnItemViewClickedListener(new OnItemViewClickedListener() {
264                @Override
265                public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
266                        RowPresenter.ViewHolder rowViewHolder, Row row) {
267                    mLastClickedItemViewHolder = itemViewHolder;
268                }
269            });
270            ListRowPresenter lrp = new ListRowPresenter();
271            ArrayObjectAdapter adapter = new ArrayObjectAdapter(lrp);
272            setAdapter(adapter);
273            loadData(adapter, 10, 1);
274        }
275    }
276
277    @Test
278    public void prefetchChildItemsBeforeAttach() throws Throwable {
279        SingleSupportFragmentTestActivity activity =
280                launchAndWaitActivity(F_ListRowWithOnClick.class, 1000);
281
282        F_ListRowWithOnClick fragment = (F_ListRowWithOnClick) activity.getTestFragment();
283        final VerticalGridView gridView = fragment.getVerticalGridView();
284        View lastRow = gridView.getChildAt(gridView.getChildCount() - 1);
285        final int lastRowPos = gridView.getChildAdapterPosition(lastRow);
286        InstrumentationRegistry.getInstrumentation().runOnMainSync(
287                new Runnable() {
288                    public void run() {
289                        gridView.setSelectedPositionSmooth(lastRowPos);
290                    }
291                }
292        );
293        waitForScrollIdle(gridView);
294        ItemBridgeAdapter.ViewHolder prefetchedBridgeVh = (ItemBridgeAdapter.ViewHolder)
295                gridView.findViewHolderForAdapterPosition(lastRowPos + 1);
296        RowPresenter prefetchedRowPresenter = (RowPresenter) prefetchedBridgeVh.getPresenter();
297        final ListRowPresenter.ViewHolder prefetchedListRowVh = (ListRowPresenter.ViewHolder)
298                prefetchedRowPresenter.getRowViewHolder(prefetchedBridgeVh.getViewHolder());
299
300        fragment.mLastClickedItemViewHolder = null;
301        InstrumentationRegistry.getInstrumentation().runOnMainSync(
302                new Runnable() {
303                    public void run() {
304                        prefetchedListRowVh.getItemViewHolder(0).view.performClick();
305                    }
306                }
307        );
308        assertSame(prefetchedListRowVh.getItemViewHolder(0), fragment.mLastClickedItemViewHolder);
309    }
310
311    @Test
312    public void changeHasStableIdToTrueAfterViewCreated() throws InterruptedException {
313        SingleSupportFragmentTestActivity activity =
314                launchAndWaitActivity(RowsSupportFragment.class, 2000);
315        final RowsSupportFragment fragment = (RowsSupportFragment) activity.getTestFragment();
316
317        InstrumentationRegistry.getInstrumentation().runOnMainSync(
318                new Runnable() {
319                    public void run() {
320                        ObjectAdapter adapter = new ObjectAdapter() {
321                            @Override
322                            public int size() {
323                                return 0;
324                            }
325
326                            @Override
327                            public Object get(int position) {
328                                return null;
329                            }
330
331                            @Override
332                            public long getId(int position) {
333                                return 1;
334                            }
335                        };
336                        adapter.setHasStableIds(true);
337                        fragment.setAdapter(adapter);
338                    }
339                }
340        );
341    }
342
343    static class StableIdAdapter extends ObjectAdapter {
344        ArrayList<Integer> mList = new ArrayList();
345
346        @Override
347        public long getId(int position) {
348            return mList.get(position).longValue();
349        }
350
351        @Override
352        public Object get(int position) {
353            return mList.get(position);
354        }
355
356        @Override
357        public int size() {
358            return mList.size();
359        }
360    }
361
362    public static class F_rowNotifyItemRangeChange extends BrowseSupportFragment {
363
364        @Override
365        public void onCreate(Bundle savedInstanceState) {
366            super.onCreate(savedInstanceState);
367            ListRowPresenter lrp = new ListRowPresenter();
368            final ArrayObjectAdapter adapter = new ArrayObjectAdapter(lrp);
369            for (int i = 0; i < 2; i++) {
370                StableIdAdapter listRowAdapter = new StableIdAdapter();
371                listRowAdapter.setHasStableIds(true);
372                listRowAdapter.setPresenterSelector(
373                        new SinglePresenterSelector(sCardPresenter));
374                int index = 0;
375                listRowAdapter.mList.add(index++);
376                listRowAdapter.mList.add(index++);
377                listRowAdapter.mList.add(index++);
378                HeaderItem header = new HeaderItem(i, "Row " + i);
379                adapter.add(new ListRow(header, listRowAdapter));
380            }
381            setAdapter(adapter);
382            new Handler().postDelayed(new Runnable() {
383                @Override
384                public void run() {
385                    StableIdAdapter rowAdapter = (StableIdAdapter)
386                            ((ListRow) adapter.get(1)).getAdapter();
387                    rowAdapter.notifyItemRangeChanged(0, 3);
388                }
389            }, 500);
390        }
391    }
392
393    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.LOLLIPOP)
394    @Test
395    public void rowNotifyItemRangeChange() throws InterruptedException {
396        SingleSupportFragmentTestActivity activity = launchAndWaitActivity(
397                RowsSupportFragmentTest.F_rowNotifyItemRangeChange.class, 2000);
398
399        VerticalGridView verticalGridView = ((BrowseSupportFragment) activity.getTestFragment())
400                .getRowsSupportFragment().getVerticalGridView();
401        for (int i = 0; i < verticalGridView.getChildCount(); i++) {
402            HorizontalGridView horizontalGridView = verticalGridView.getChildAt(i)
403                    .findViewById(R.id.row_content);
404            for (int j = 0; j < horizontalGridView.getChildCount(); j++) {
405                assertEquals(horizontalGridView.getPaddingTop(),
406                        horizontalGridView.getChildAt(j).getTop());
407            }
408        }
409    }
410
411    public static class F_rowNotifyItemRangeChangeWithTransition extends BrowseSupportFragment {
412
413        @Override
414        public void onCreate(Bundle savedInstanceState) {
415            super.onCreate(savedInstanceState);
416            ListRowPresenter lrp = new ListRowPresenter();
417            prepareEntranceTransition();
418            final ArrayObjectAdapter adapter = new ArrayObjectAdapter(lrp);
419            for (int i = 0; i < 2; i++) {
420                StableIdAdapter listRowAdapter = new StableIdAdapter();
421                listRowAdapter.setHasStableIds(true);
422                listRowAdapter.setPresenterSelector(
423                        new SinglePresenterSelector(sCardPresenter));
424                int index = 0;
425                listRowAdapter.mList.add(index++);
426                listRowAdapter.mList.add(index++);
427                listRowAdapter.mList.add(index++);
428                HeaderItem header = new HeaderItem(i, "Row " + i);
429                adapter.add(new ListRow(header, listRowAdapter));
430            }
431            setAdapter(adapter);
432            new Handler().postDelayed(new Runnable() {
433                @Override
434                public void run() {
435                    StableIdAdapter rowAdapter = (StableIdAdapter)
436                            ((ListRow) adapter.get(1)).getAdapter();
437                    rowAdapter.notifyItemRangeChanged(0, 3);
438                }
439            }, 500);
440            new Handler().postDelayed(new Runnable() {
441                @Override
442                public void run() {
443                    startEntranceTransition();
444                }
445            }, 520);
446        }
447    }
448
449    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.LOLLIPOP)
450    @Test
451    public void rowNotifyItemRangeChangeWithTransition() throws InterruptedException {
452        SingleSupportFragmentTestActivity activity = launchAndWaitActivity(
453                        RowsSupportFragmentTest.F_rowNotifyItemRangeChangeWithTransition.class, 3000);
454
455        VerticalGridView verticalGridView = ((BrowseSupportFragment) activity.getTestFragment())
456                .getRowsSupportFragment().getVerticalGridView();
457        for (int i = 0; i < verticalGridView.getChildCount(); i++) {
458            HorizontalGridView horizontalGridView = verticalGridView.getChildAt(i)
459                    .findViewById(R.id.row_content);
460            for (int j = 0; j < horizontalGridView.getChildCount(); j++) {
461                assertEquals(horizontalGridView.getPaddingTop(),
462                        horizontalGridView.getChildAt(j).getTop());
463                assertEquals(0, horizontalGridView.getChildAt(j).getTranslationY(), 0.1f);
464            }
465        }
466    }
467}
468