Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2017 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 android.view.inputmethod.cts.util;
     18 
     19 import android.app.Instrumentation;
     20 import androidx.annotation.NonNull;
     21 import android.support.test.InstrumentationRegistry;
     22 
     23 import java.util.concurrent.TimeoutException;
     24 import java.util.concurrent.atomic.AtomicBoolean;
     25 import java.util.concurrent.atomic.AtomicReference;
     26 import java.util.function.BooleanSupplier;
     27 import java.util.function.Supplier;
     28 
     29 public final class TestUtils {
     30     private static final long TIME_SLICE = 100;  // msec
     31 
     32     /**
     33      * Executes a call on the application's main thread, blocking until it is complete.
     34      *
     35      * <p>A simple wrapper for {@link Instrumentation#runOnMainSync(Runnable)}.</p>
     36      *
     37      * @param task task to be called on the UI thread
     38      */
     39     public static void runOnMainSync(@NonNull Runnable task) {
     40         InstrumentationRegistry.getInstrumentation().runOnMainSync(task);
     41     }
     42 
     43     /**
     44      * Retrieves a value that needs to be obtained on the main thread.
     45      *
     46      * <p>A simple utility method that helps to return an object from the UI thread.</p>
     47      *
     48      * @param supplier callback to be called on the UI thread to return a value
     49      * @param <T> Type of the value to be returned
     50      * @return Value returned from {@code supplier}
     51      */
     52     public static <T> T getOnMainSync(@NonNull Supplier<T> supplier) {
     53         final AtomicReference<T> result = new AtomicReference<>();
     54         final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
     55         instrumentation.runOnMainSync(() -> result.set(supplier.get()));
     56         return result.get();
     57     }
     58 
     59     /**
     60      * Does polling loop on the UI thread to wait until the given condition is met.
     61      *
     62      * @param condition Condition to be satisfied. This is guaranteed to run on the UI thread.
     63      * @param timeout timeout in millisecond
     64      * @param message message to display when timeout occurs.
     65      * @throws TimeoutException when the no event is matched to the given condition within
     66      *                          {@code timeout}
     67      */
     68     public static void waitOnMainUntil(
     69             @NonNull BooleanSupplier condition, long timeout, String message)
     70             throws TimeoutException {
     71         final AtomicBoolean result = new AtomicBoolean();
     72 
     73         final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
     74         while (!result.get()) {
     75             if (timeout < 0) {
     76                 throw new TimeoutException(message);
     77             }
     78             instrumentation.runOnMainSync(() -> {
     79                 if (condition.getAsBoolean()) {
     80                     result.set(true);
     81                 }
     82             });
     83             try {
     84                 Thread.sleep(TIME_SLICE);
     85             } catch (InterruptedException e) {
     86                 throw new IllegalStateException(e);
     87             }
     88             timeout -= TIME_SLICE;
     89         }
     90     }
     91 
     92     /**
     93      * Does polling loop on the UI thread to wait until the given condition is met.
     94      *
     95      * @param condition Condition to be satisfied. This is guaranteed to run on the UI thread.
     96      * @param timeout timeout in millisecond
     97      * @throws TimeoutException when the no event is matched to the given condition within
     98      *                          {@code timeout}
     99      */
    100     public static void waitOnMainUntil(@NonNull BooleanSupplier condition, long timeout)
    101             throws TimeoutException {
    102         waitOnMainUntil(condition, timeout, "");
    103     }
    104 }
    105