PollingCheck.java revision b31c3281d870e9abb673db239234d580dcc4feff
1/*
2 * Copyright (C) 2016 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 */
16package androidx.leanback.testutils;
17
18import static org.junit.Assert.fail;
19
20import android.app.Activity;
21import android.view.View;
22
23public abstract class PollingCheck {
24
25    private static final long TIME_SLICE = 250;
26    private long mTimeout = 5000;
27
28    public abstract static class PollingCheckCondition {
29        public abstract boolean canProceed();
30
31        public boolean canPreProceed() {
32            return canProceed();
33        }
34    }
35
36    public PollingCheck() {
37    }
38
39    public PollingCheck(long timeout) {
40        mTimeout = timeout;
41    }
42
43    protected abstract boolean check();
44
45    protected boolean preCheck() {
46        return check();
47    }
48
49    public void run() {
50        if (preCheck()) {
51            return;
52        }
53
54        long timeout = mTimeout;
55        while (timeout > 0) {
56            try {
57                Thread.sleep(TIME_SLICE);
58            } catch (InterruptedException e) {
59                fail("unexpected InterruptedException");
60            }
61
62            if (check()) {
63                return;
64            }
65
66            timeout -= TIME_SLICE;
67        }
68
69        fail("unexpected timeout");
70    }
71
72    public static void waitFor(final PollingCheckCondition condition) {
73        new PollingCheck() {
74            @Override
75            protected boolean check() {
76                return condition.canProceed();
77            }
78
79            @Override
80            protected boolean preCheck() {
81                return condition.canPreProceed();
82            }
83        }.run();
84    }
85
86    public static void waitFor(long timeout, final PollingCheckCondition condition) {
87        new PollingCheck(timeout) {
88            @Override
89            protected boolean check() {
90                return condition.canProceed();
91            }
92        }.run();
93    }
94
95    public static class ViewScreenPositionDetector {
96
97        int[] lastLocation = null;
98        int[] newLocation = new int[2];
99
100        public boolean isViewStableOnScreen(View view) {
101            if (lastLocation == null) {
102                // get initial location
103                lastLocation = new int[2];
104                view.getLocationInWindow(lastLocation);
105            } else {
106                // get new location and compare to old location
107                view.getLocationInWindow(newLocation);
108                if (newLocation[0] == lastLocation[0]
109                        && newLocation[1] == lastLocation[1]) {
110                    // location stable,  animation finished
111                    return true;
112                }
113                lastLocation[0] = newLocation[0];
114                lastLocation[1] = newLocation[1];
115            }
116            return false;
117        }
118    }
119
120    public static class ViewStableOnScreen extends PollingCheckCondition {
121
122        View mView;
123        ViewScreenPositionDetector mDector = new ViewScreenPositionDetector();
124
125        public ViewStableOnScreen(View view) {
126            mView = view;
127        }
128
129        @Override
130        public boolean canPreProceed() {
131            return false;
132        }
133
134        @Override
135        public boolean canProceed() {
136            return mDector.isViewStableOnScreen(mView);
137        }
138
139    }
140
141    public static class ActivityDestroy extends PollingCheckCondition {
142
143        Activity mActivity;
144
145        public ActivityDestroy(Activity activity) {
146            mActivity = activity;
147        }
148
149        @Override
150        public boolean canProceed() {
151            return mActivity.isDestroyed();
152        }
153
154    }
155
156}