1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.recyclerview.widget;
18 
19 import android.content.Context;
20 import android.util.AttributeSet;
21 import android.view.View;
22 
23 import androidx.test.platform.app.InstrumentationRegistry;
24 
25 import org.hamcrest.CoreMatchers;
26 import org.hamcrest.MatcherAssert;
27 
28 import java.util.concurrent.CountDownLatch;
29 import java.util.concurrent.TimeUnit;
30 
31 /**
32  * RecyclerView wrapper used in tests. This class can fake behavior like layout direction w/o
33  * playing with framework support.
34  */
35 public class WrappedRecyclerView extends RecyclerView {
36 
37     Boolean mFakeRTL;
38     private long mDrawingTimeOffsetMs;
39 
setFakeRTL(Boolean fakeRTL)40     public void setFakeRTL(Boolean fakeRTL) {
41         mFakeRTL = fakeRTL;
42     }
43 
setDrawingTimeOffset(long offsetMs)44     public void setDrawingTimeOffset(long offsetMs) {
45         mDrawingTimeOffsetMs = offsetMs;
46     }
47 
48     @Override
getDrawingTime()49     public long getDrawingTime() {
50         return super.getDrawingTime() + mDrawingTimeOffsetMs;
51     }
52 
WrappedRecyclerView(Context context)53     public WrappedRecyclerView(Context context) {
54         super(context);
55         init(context);
56     }
57 
WrappedRecyclerView(Context context, AttributeSet attrs)58     public WrappedRecyclerView(Context context, AttributeSet attrs) {
59         super(context, attrs);
60         init(context);
61     }
62 
WrappedRecyclerView(Context context, AttributeSet attrs, int defStyle)63     public WrappedRecyclerView(Context context, AttributeSet attrs, int defStyle) {
64         super(context, attrs, defStyle);
65         init(context);
66     }
67 
init(Context context)68     private void init(Context context) {
69         //initializeScrollbars(null);
70     }
71 
waitUntilLayout()72     public void waitUntilLayout() {
73         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
74         while (isLayoutRequested()) {
75             try {
76                 Thread.sleep(100);
77             } catch (InterruptedException e) {
78                 e.printStackTrace();
79             }
80         }
81     }
82 
waitUntilAnimations()83     public void waitUntilAnimations() throws InterruptedException {
84         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
85         final CountDownLatch latch = new CountDownLatch(1);
86         if (mItemAnimator == null || !mItemAnimator.isRunning(
87                 new ItemAnimator.ItemAnimatorFinishedListener() {
88                     @Override
89                     public void onAnimationsFinished() {
90                         latch.countDown();
91                     }
92                 })) {
93             latch.countDown();
94         }
95         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
96         MatcherAssert.assertThat("waiting too long for animations",
97                 latch.await(60, TimeUnit.SECONDS), CoreMatchers.is(true));
98     }
99 
100 
101     @Override
getLayoutDirection()102     public int getLayoutDirection() {
103         if (mFakeRTL == null) {
104             return super.getLayoutDirection();
105         }
106         //noinspection WrongConstant
107         return Boolean.TRUE.equals(mFakeRTL) ? View.LAYOUT_DIRECTION_RTL
108                 : View.LAYOUT_DIRECTION_LTR;
109     }
110 
111     @Override
setChildImportantForAccessibilityInternal(ViewHolder viewHolder, int importantForAccessibilityBeforeHidden)112     public boolean setChildImportantForAccessibilityInternal(ViewHolder viewHolder,
113             int importantForAccessibilityBeforeHidden) {
114         return super.setChildImportantForAccessibilityInternal(viewHolder,
115                 importantForAccessibilityBeforeHidden);
116     }
117 }