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.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; 20 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; 21 import static android.view.Display.DEFAULT_DISPLAY; 22 23 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; 24 25 import static org.junit.Assert.assertEquals; 26 27 import android.app.Activity; 28 import android.app.ActivityOptions; 29 import android.content.Intent; 30 import android.os.Bundle; 31 32 import com.android.compatibility.common.util.SystemUtil; 33 34 import java.lang.reflect.Array; 35 36 import javax.annotation.concurrent.GuardedBy; 37 38 public class WindowManagerTestBase extends MultiDisplayTestBase { 39 static final long TIMEOUT_WINDOW_FOCUS_CHANGED = 1000; // milliseconds 40 startActivity(Class<T> cls)41 static <T extends FocusableActivity> T startActivity(Class<T> cls) { 42 return startActivity(cls, DEFAULT_DISPLAY); 43 } 44 startActivity(Class<T> cls, int displayId)45 static <T extends FocusableActivity> T startActivity(Class<T> cls, int displayId) { 46 return startActivity(cls, displayId, true /* hasFocus */); 47 } 48 startActivity( Class<T> cls, int displayId, boolean hasFocus)49 static <T extends FocusableActivity> T startActivity( 50 Class<T> cls, int displayId, boolean hasFocus) { 51 return startActivity(cls, displayId, hasFocus, WINDOWING_MODE_UNDEFINED); 52 } 53 startActivityInWindowingMode( Class<T> cls, int windowingMode)54 static <T extends FocusableActivity> T startActivityInWindowingMode( 55 Class<T> cls, int windowingMode) { 56 return startActivity(cls, DEFAULT_DISPLAY, true /* hasFocus */, windowingMode); 57 } 58 startActivity(Class<T> cls, int displayId, boolean hasFocus, int windowingMode)59 static <T extends FocusableActivity> T startActivity(Class<T> cls, int displayId, 60 boolean hasFocus, int windowingMode) { 61 final Bundle options; 62 if (displayId == DEFAULT_DISPLAY && windowingMode == WINDOWING_MODE_UNDEFINED) { 63 options = null; 64 } else { 65 final ActivityOptions ap= ActivityOptions.makeBasic(); 66 if (displayId != DEFAULT_DISPLAY) ap.setLaunchDisplayId(displayId); 67 if (windowingMode != WINDOWING_MODE_UNDEFINED) ap.setLaunchWindowingMode(windowingMode); 68 options = ap.toBundle(); 69 } 70 final T[] activity = (T[]) Array.newInstance(FocusableActivity.class, 1); 71 SystemUtil.runWithShellPermissionIdentity(() -> { 72 activity[0] = (T) getInstrumentation().startActivitySync( 73 new Intent(getInstrumentation().getTargetContext(), cls) 74 .addFlags(FLAG_ACTIVITY_NEW_TASK), options); 75 activity[0].waitAndAssertWindowFocusState(hasFocus); 76 }); 77 return activity[0]; 78 } 79 80 static class FocusableActivity extends Activity { 81 private final Object mLockWindowFocus = new Object(); 82 83 @GuardedBy("mLockWindowFocus") 84 private boolean mHasWindowFocus; 85 getLogTag()86 final String getLogTag() { 87 return ComponentNameUtils.getLogTag(getComponentName()); 88 } 89 90 @Override onWindowFocusChanged(boolean hasFocus)91 public void onWindowFocusChanged(boolean hasFocus) { 92 synchronized (mLockWindowFocus) { 93 mHasWindowFocus = hasFocus; 94 mLockWindowFocus.notify(); 95 } 96 } 97 assertWindowFocusState(boolean hasFocus)98 void assertWindowFocusState(boolean hasFocus) { 99 synchronized (mLockWindowFocus) { 100 assertEquals(getLogTag() + " must" + (hasFocus ? "" : " not") 101 + " have window focus.", hasFocus, mHasWindowFocus); 102 } 103 } 104 waitAndAssertWindowFocusState(boolean hasFocus)105 void waitAndAssertWindowFocusState(boolean hasFocus) { 106 synchronized (mLockWindowFocus) { 107 if (mHasWindowFocus != hasFocus) { 108 try { 109 mLockWindowFocus.wait(TIMEOUT_WINDOW_FOCUS_CHANGED); 110 } catch (InterruptedException e) { 111 } 112 } 113 } 114 assertWindowFocusState(hasFocus); 115 } 116 } 117 } 118