• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.server.wm;
18 
19 import static org.junit.Assert.assertTrue;
20 
21 import android.app.Instrumentation;
22 import android.app.UiAutomation;
23 import android.os.SystemClock;
24 
25 import androidx.annotation.NonNull;
26 import androidx.test.platform.app.InstrumentationRegistry;
27 
28 import com.android.cts.mockime.Watermark;
29 
30 import java.util.concurrent.CountDownLatch;
31 import java.util.concurrent.TimeUnit;
32 import java.util.function.Predicate;
33 
34 /**
35  * Provides utility methods to test whether test IMEs are visible to the user or not.
36  */
37 public final class InputMethodVisibilityVerifier {
38 
39     private static final long SCREENSHOT_DELAY = 100;  // msec
40     private static final long SCREENSHOT_TIME_SLICE = 500;  // msec
41 
42     /**
43      * Not intended to be instantiated.
44      */
InputMethodVisibilityVerifier()45     private InputMethodVisibilityVerifier() {
46     }
47 
48     @NonNull
containsWatermark(@onNull UiAutomation uiAutomation)49     private static boolean containsWatermark(@NonNull UiAutomation uiAutomation) {
50         return Watermark.detect(uiAutomation.takeScreenshot());
51     }
52 
53     @NonNull
notContainsWatermark(@onNull UiAutomation uiAutomation)54     private static boolean notContainsWatermark(@NonNull UiAutomation uiAutomation) {
55         return !Watermark.detect(uiAutomation.takeScreenshot());
56     }
57 
waitUntil(long timeout, @NonNull Predicate<UiAutomation> condition)58     private static boolean waitUntil(long timeout, @NonNull Predicate<UiAutomation> condition) {
59         final long startTime = SystemClock.elapsedRealtime();
60         SystemClock.sleep(SCREENSHOT_DELAY);
61 
62         final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
63 
64         // Wait until the main thread becomes idle.
65         final CountDownLatch latch = new CountDownLatch(1);
66         instrumentation.waitForIdle(latch::countDown);
67         try {
68             if (!latch.await(timeout, TimeUnit.MILLISECONDS)) {
69                 return false;
70             }
71         } catch (InterruptedException e) {
72         }
73 
74         final UiAutomation uiAutomation = instrumentation.getUiAutomation();
75         if (condition.test(uiAutomation)) {
76             return true;
77         }
78         while ((SystemClock.elapsedRealtime() - startTime) < timeout) {
79             SystemClock.sleep(SCREENSHOT_TIME_SLICE);
80             if (condition.test(uiAutomation)) {
81                 return true;
82             }
83         }
84         return condition.test(uiAutomation);
85     }
86 
87     /**
88      * Asserts that {@link com.android.cts.mockime.MockIme} is visible to the user.
89      *
90      * <p>This never succeeds when
91      * {@link com.android.cts.mockime.ImeSettings.Builder#setWatermarkEnabled(boolean)} is
92      * explicitly called with {@code false}.</p>
93      *
94      * @param timeout timeout in milliseconds.
95      */
expectImeVisible(long timeout)96     public static void expectImeVisible(long timeout) {
97         assertTrue(waitUntil(timeout, InputMethodVisibilityVerifier::containsWatermark));
98     }
99 
100     /**
101      * Asserts that {@link com.android.cts.mockime.MockIme} is not visible to the user.
102      *
103      * <p>This always succeeds when
104      * {@link com.android.cts.mockime.ImeSettings.Builder#setWatermarkEnabled(boolean)} is
105      * explicitly called with {@code false}.</p>
106      *
107      * @param timeout timeout in milliseconds.
108      */
expectImeInvisible(long timeout)109     public static void expectImeInvisible(long timeout) {
110         assertTrue(waitUntil(timeout, InputMethodVisibilityVerifier::notContainsWatermark));
111     }
112 }
113