1 /* 2 * Copyright (C) 2019 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 android.server.wm.UiDeviceUtils.pressHomeButton; 20 import static android.server.wm.UiDeviceUtils.pressUnlockButton; 21 import static android.server.wm.UiDeviceUtils.pressWakeupButton; 22 23 import static org.junit.Assert.assertEquals; 24 25 import android.app.Activity; 26 import android.app.Instrumentation; 27 import android.graphics.Point; 28 import android.graphics.Rect; 29 import android.view.Gravity; 30 import android.view.View; 31 import android.view.WindowInsets; 32 import android.view.WindowManager; 33 34 import androidx.test.InstrumentationRegistry; 35 import androidx.test.filters.FlakyTest; 36 import androidx.test.rule.ActivityTestRule; 37 38 import com.android.compatibility.common.util.CtsTouchUtils; 39 40 import org.junit.Before; 41 import org.junit.Test; 42 43 import java.util.Random; 44 45 /** 46 * Ensure moving windows and tapping is done synchronously. 47 * 48 * Build/Install/Run: 49 * atest CtsWindowManagerDeviceTestCases:WindowInputTests 50 */ 51 @FlakyTest 52 public class WindowInputTests { 53 private final int TOTAL_NUMBER_OF_CLICKS = 100; 54 private final ActivityTestRule<Activity> mActivityRule = new ActivityTestRule<>(Activity.class); 55 56 private Instrumentation mInstrumentation; 57 private Activity mActivity; 58 private View mView; 59 private final Random mRandom = new Random(); 60 61 private int mClickCount = 0; 62 63 @Before 64 public void setUp() { 65 pressWakeupButton(); 66 pressUnlockButton(); 67 pressHomeButton(); 68 69 mInstrumentation = InstrumentationRegistry.getInstrumentation(); 70 mActivity = mActivityRule.launchActivity(null); 71 mInstrumentation.waitForIdleSync(); 72 mClickCount = 0; 73 } 74 75 @Test 76 public void testMoveWindowAndTap() throws Throwable { 77 final WindowManager wm = mActivity.getWindowManager(); 78 Point displaySize = new Point(); 79 mActivity.getDisplay().getSize(displaySize); 80 81 final WindowManager.LayoutParams p = new WindowManager.LayoutParams(); 82 mClickCount = 0; 83 84 // Set up window. 85 mActivityRule.runOnUiThread(() -> { 86 mView = new View(mActivity); 87 p.width = 20; 88 p.height = 20; 89 p.gravity = Gravity.LEFT | Gravity.TOP; 90 mView.setOnClickListener((v) -> { 91 mClickCount++; 92 }); 93 wm.addView(mView, p); 94 }); 95 mInstrumentation.waitForIdleSync(); 96 97 WindowInsets insets = mActivity.getWindow().getDecorView().getRootWindowInsets(); 98 final Rect windowBounds = new Rect(insets.getSystemWindowInsetLeft(), 99 insets.getSystemWindowInsetTop(), 100 displaySize.x - insets.getSystemWindowInsetRight(), 101 displaySize.y - insets.getSystemWindowInsetBottom()); 102 103 // Move the window to a random location in the window and attempt to tap on view multiple 104 // times. 105 final Point locationInWindow = new Point(); 106 for (int i = 0; i < TOTAL_NUMBER_OF_CLICKS; i++) { 107 selectRandomLocationInWindow(windowBounds, locationInWindow); 108 mActivityRule.runOnUiThread(() -> { 109 p.x = locationInWindow.x; 110 p.y = locationInWindow.y; 111 wm.updateViewLayout(mView, p); 112 }); 113 mInstrumentation.waitForIdleSync(); 114 CtsTouchUtils.emulateTapOnViewCenter(mInstrumentation, mActivityRule, mView); 115 } 116 117 assertEquals(TOTAL_NUMBER_OF_CLICKS, mClickCount); 118 } 119 120 private void selectRandomLocationInWindow(Rect bounds, Point outLocation) { 121 int randomX = mRandom.nextInt(bounds.right - bounds.left) + bounds.left; 122 int randomY = mRandom.nextInt(bounds.bottom - bounds.top) + bounds.top; 123 outLocation.set(randomX, randomY); 124 } 125 } 126