1 /* 2 * Copyright (C) 2012 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 com.android.compatibility.common.util; 18 19 import junit.framework.Assert; 20 21 import java.util.concurrent.Callable; 22 import java.util.function.BooleanSupplier; 23 import java.util.function.Function; 24 import java.util.function.Supplier; 25 26 public abstract class PollingCheck { 27 private static final long TIME_SLICE = 50; 28 private static final long DEFAULT_TIMEOUT = 3_000; 29 private static final String DEFAULT_ERROR_MESSAGE = "unexpected timeout"; 30 31 private final long mTimeout; 32 private final String mErrorMessage; 33 34 public static interface PollingCheckCondition { canProceed()35 boolean canProceed(); 36 } 37 PollingCheck()38 public PollingCheck() { 39 this(DEFAULT_TIMEOUT, DEFAULT_ERROR_MESSAGE); 40 } 41 PollingCheck(long timeout)42 public PollingCheck(long timeout) { 43 this(timeout, DEFAULT_ERROR_MESSAGE); 44 } 45 PollingCheck(long timeout, String errorMessage)46 public PollingCheck(long timeout, String errorMessage) { 47 mTimeout = timeout; 48 mErrorMessage = errorMessage; 49 } 50 PollingCheck(String errorMessage)51 public PollingCheck(String errorMessage) { 52 this(DEFAULT_TIMEOUT, errorMessage); 53 } 54 check()55 protected abstract boolean check(); 56 getErrorMessage()57 protected String getErrorMessage() { 58 return mErrorMessage; 59 } 60 run()61 public void run() { 62 if (check()) { 63 return; 64 } 65 66 long timeout = mTimeout; 67 while (timeout > 0) { 68 try { 69 Thread.sleep(TIME_SLICE); 70 } catch (InterruptedException e) { 71 Assert.fail("unexpected InterruptedException"); 72 } 73 74 if (check()) { 75 return; 76 } 77 78 timeout -= TIME_SLICE; 79 } 80 81 Assert.assertTrue(getErrorMessage(), check()); 82 } 83 runWaitAndReturnResult(Supplier<E> supplier, Function<E, Boolean> condition)84 public <E> E runWaitAndReturnResult(Supplier<E> supplier, Function<E, Boolean> condition) { 85 E output = supplier.get(); 86 if (condition.apply(output)) { 87 return output; 88 } 89 long timeout = mTimeout; 90 while (timeout > 0) { 91 try { 92 Thread.sleep(TIME_SLICE); 93 } catch (InterruptedException e) { 94 Assert.fail("unexpected InterruptedException"); 95 } 96 97 output = supplier.get(); 98 if (condition.apply(output)) { 99 return output; 100 } 101 102 timeout -= TIME_SLICE; 103 } 104 105 return output; 106 } 107 check(CharSequence message, long timeout, Callable<Boolean> condition)108 public static void check(CharSequence message, long timeout, Callable<Boolean> condition) 109 throws Exception { 110 while (timeout > 0) { 111 if (condition.call()) { 112 return; 113 } 114 115 Thread.sleep(TIME_SLICE); 116 timeout -= TIME_SLICE; 117 } 118 119 Assert.fail(message.toString()); 120 } 121 waitFor(final PollingCheckCondition condition)122 public static void waitFor(final PollingCheckCondition condition) { 123 new PollingCheck() { 124 @Override 125 protected boolean check() { 126 return condition.canProceed(); 127 } 128 }.run(); 129 } 130 waitFor(final PollingCheckCondition condition, String errorMessage)131 public static void waitFor(final PollingCheckCondition condition, String errorMessage) { 132 new PollingCheck(errorMessage) { 133 @Override 134 protected boolean check() { 135 return condition.canProceed(); 136 } 137 }.run(); 138 } 139 waitFor(long timeout, final PollingCheckCondition condition)140 public static void waitFor(long timeout, final PollingCheckCondition condition) { 141 new PollingCheck(timeout) { 142 @Override 143 protected boolean check() { 144 return condition.canProceed(); 145 } 146 }.run(); 147 } 148 waitFor(long timeout, final PollingCheckCondition condition, Supplier<String> errorMessage)149 public static void waitFor(long timeout, final PollingCheckCondition condition, 150 Supplier<String> errorMessage) { 151 new PollingCheck(timeout) { 152 @Override 153 protected boolean check() { 154 return condition.canProceed(); 155 } 156 157 @Override 158 protected String getErrorMessage() { 159 return errorMessage.get(); 160 } 161 }.run(); 162 } 163 waitFor(long timeout, BooleanSupplier condition, String errorMessage)164 public static void waitFor(long timeout, BooleanSupplier condition, String errorMessage) { 165 new PollingCheck(timeout, errorMessage) { 166 @Override 167 protected boolean check() { 168 return condition.getAsBoolean(); 169 } 170 }.run(); 171 } 172 waitFor(long timeout, Supplier<E> supplier, Function<E, Boolean> condition)173 public static <E> E waitFor(long timeout, Supplier<E> supplier, 174 Function<E, Boolean> condition) { 175 return new PollingCheck(timeout) { 176 // Not used in the corresponding runWaitAndReturnResult function, Added just to provide 177 // default implementation of abstract check function. 178 @Override 179 protected boolean check() { 180 return true; 181 } 182 }.runWaitAndReturnResult(supplier, condition); 183 } 184 } 185