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 run()57 public void run() { 58 if (check()) { 59 return; 60 } 61 62 long timeout = mTimeout; 63 while (timeout > 0) { 64 try { 65 Thread.sleep(TIME_SLICE); 66 } catch (InterruptedException e) { 67 Assert.fail("unexpected InterruptedException"); 68 } 69 70 if (check()) { 71 return; 72 } 73 74 timeout -= TIME_SLICE; 75 } 76 77 Assert.assertTrue(mErrorMessage, check()); 78 } 79 runWaitAndReturnResult(Supplier<E> supplier, Function<E, Boolean> condition)80 public <E> E runWaitAndReturnResult(Supplier<E> supplier, Function<E, Boolean> condition) { 81 E output = supplier.get(); 82 if (condition.apply(output)) { 83 return output; 84 } 85 long timeout = mTimeout; 86 while (timeout > 0) { 87 try { 88 Thread.sleep(TIME_SLICE); 89 } catch (InterruptedException e) { 90 Assert.fail("unexpected InterruptedException"); 91 } 92 93 output = supplier.get(); 94 if (condition.apply(output)) { 95 return output; 96 } 97 98 timeout -= TIME_SLICE; 99 } 100 101 return output; 102 } 103 check(CharSequence message, long timeout, Callable<Boolean> condition)104 public static void check(CharSequence message, long timeout, Callable<Boolean> condition) 105 throws Exception { 106 while (timeout > 0) { 107 if (condition.call()) { 108 return; 109 } 110 111 Thread.sleep(TIME_SLICE); 112 timeout -= TIME_SLICE; 113 } 114 115 Assert.fail(message.toString()); 116 } 117 waitFor(final PollingCheckCondition condition)118 public static void waitFor(final PollingCheckCondition condition) { 119 new PollingCheck() { 120 @Override 121 protected boolean check() { 122 return condition.canProceed(); 123 } 124 }.run(); 125 } 126 waitFor(final PollingCheckCondition condition, String errorMessage)127 public static void waitFor(final PollingCheckCondition condition, String errorMessage) { 128 new PollingCheck(errorMessage) { 129 @Override 130 protected boolean check() { 131 return condition.canProceed(); 132 } 133 }.run(); 134 } 135 waitFor(long timeout, final PollingCheckCondition condition)136 public static void waitFor(long timeout, final PollingCheckCondition condition) { 137 new PollingCheck(timeout) { 138 @Override 139 protected boolean check() { 140 return condition.canProceed(); 141 } 142 }.run(); 143 } 144 waitFor(long timeout, BooleanSupplier condition, String errorMessage)145 public static void waitFor(long timeout, BooleanSupplier condition, String errorMessage) { 146 new PollingCheck(timeout, errorMessage) { 147 @Override 148 protected boolean check() { 149 return condition.getAsBoolean(); 150 } 151 }.run(); 152 } 153 waitFor(long timeout, Supplier<E> supplier, Function<E, Boolean> condition)154 public static <E> E waitFor(long timeout, Supplier<E> supplier, 155 Function<E, Boolean> condition) { 156 return new PollingCheck(timeout) { 157 // Not used in the corresponding runWaitAndReturnResult function, Added just to provide 158 // default implementation of abstract check function. 159 @Override 160 protected boolean check() { 161 return true; 162 } 163 }.runWaitAndReturnResult(supplier, condition); 164 } 165 } 166