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.server.wm; 18 19 import static androidx.test.InstrumentationRegistry.getInstrumentation; 20 21 import static org.hamcrest.Matchers.greaterThanOrEqualTo; 22 import static org.hamcrest.Matchers.lessThanOrEqualTo; 23 24 import android.app.Activity; 25 import android.content.ComponentName; 26 import android.graphics.Point; 27 import android.graphics.Rect; 28 import android.server.wm.WindowManagerState.DisplayArea; 29 import android.view.Display; 30 import android.view.WindowManager; 31 32 import androidx.test.rule.ActivityTestRule; 33 34 import com.android.compatibility.common.util.WindowUtil; 35 36 import org.hamcrest.Matcher; 37 import org.junit.Before; 38 39 class AspectRatioTestsBase extends ActivityManagerTestBase { 40 // The delta allowed when comparing two floats for equality. We consider them equal if they are 41 // within two significant digits of each other. 42 private static final float FLOAT_EQUALITY_DELTA = .01f; 43 44 interface AssertAspectRatioCallback { assertAspectRatio(float actual, int displayId, Point activitySize, Point displaySize)45 void assertAspectRatio(float actual, int displayId, Point activitySize, Point displaySize); 46 } 47 runAspectRatioTest(final ComponentName componentName, int windowingMode, final AssertAspectRatioCallback callback)48 void runAspectRatioTest(final ComponentName componentName, int windowingMode, 49 final AssertAspectRatioCallback callback) { 50 launchActivity(componentName, windowingMode); 51 mWmState.computeState(); 52 53 final int displayId = mWmState.getDisplayByActivity(componentName); 54 final WindowManagerState.Activity activity = mWmState.getActivity(componentName); 55 final WindowManagerState.DisplayContent display = mWmState.getDisplay(displayId); 56 57 final Rect bounds = activity.getAppBounds(); 58 final int shortSide = Math.min(bounds.width(), bounds.height()); 59 final int longSide = Math.max(bounds.width(), bounds.height()); 60 final float actualAspectRatio = (float) longSide / (float) shortSide; 61 62 callback.assertAspectRatio(actualAspectRatio, display.mId, 63 new Point(bounds.width(), bounds.height()), 64 new Point(display.getAppRect().width(), display.getAppRect().height())); 65 } 66 runAspectRatioTest(final ActivityTestRule activityRule, final AssertAspectRatioCallback callback)67 void runAspectRatioTest(final ActivityTestRule activityRule, 68 final AssertAspectRatioCallback callback) { 69 final Activity activity = launchActivity(activityRule); 70 WindowUtil.waitForFocus(activity); 71 try { 72 final Point displaySize = new Point(); 73 getDisplay(activity).getSize(displaySize); 74 callback.assertAspectRatio(getActivityAspectRatio(activity), 75 getDisplay(activity).getDisplayId(), 76 getActivitySize(activity), 77 displaySize); 78 } finally { 79 finishActivity(activityRule); 80 } 81 82 // TODO(b/35810513): All this rotation stuff doesn't really work yet. Need to make sure 83 // context is updated correctly here. Also, what does it mean to be holding a reference to 84 // this activity if changing the orientation will cause a relaunch? 85 // activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE); 86 // waitForIdle(); 87 // callback.assertAspectRatio(getAspectRatio(activity)); 88 // 89 // activity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT); 90 // waitForIdle(); 91 // callback.assertAspectRatio(getAspectRatio(activity)); 92 } 93 94 @Before wakeUpAndUnlock()95 public void wakeUpAndUnlock() { 96 UiDeviceUtils.pressWakeupButton(); 97 UiDeviceUtils.pressUnlockButton(); 98 } 99 getDisplayAspectRatio(ComponentName componentName)100 float getDisplayAspectRatio(ComponentName componentName) { 101 final DisplayArea tda = mWmState.getTaskDisplayArea(componentName); 102 final Rect appRect = tda.getAppBounds(); 103 final int shortSide = Math.min(appRect.width(), appRect.height()); 104 final int longSide = Math.max(appRect.width(), appRect.height()); 105 return (float) longSide / (float) shortSide; 106 } 107 getMinimalTaskSize(ComponentName componentName)108 int getMinimalTaskSize(ComponentName componentName) { 109 final int displayId = mWmState.getDisplayByActivity(componentName); 110 final WindowManagerState.DisplayContent displayContent = mWmState.getDisplay(displayId); 111 return displayContent.mMinSizeOfResizeableTaskDp; 112 } 113 getDefaultDisplayAspectRatio()114 static float getDefaultDisplayAspectRatio() { 115 return getAspectRatio(getInstrumentation().getContext().getSystemService( 116 WindowManager.class).getDefaultDisplay()); 117 } 118 getActivityAspectRatio(Activity activity)119 private static float getActivityAspectRatio(Activity activity) { 120 return getAspectRatio(getDisplay(activity)); 121 } 122 getActivitySize(Activity activity)123 private static Point getActivitySize(Activity activity) { 124 final Point size = new Point(); 125 getDisplay(activity).getSize(size); 126 return size; 127 } 128 getDisplay(Activity activity)129 private static Display getDisplay(Activity activity) { 130 return activity.getWindow().peekDecorView().getDisplay(); 131 } 132 getAspectRatio(Display display)133 private static float getAspectRatio(Display display) { 134 final Point size = new Point(); 135 display.getSize(size); 136 final float longSide = Math.max(size.x, size.y); 137 final float shortSide = Math.min(size.x, size.y); 138 return longSide / shortSide; 139 } 140 launchActivity(final ActivityTestRule activityRule)141 protected Activity launchActivity(final ActivityTestRule activityRule) { 142 final Activity activity = activityRule.launchActivity(null); 143 waitForIdle(); 144 return activity; 145 } 146 finishActivity(ActivityTestRule activityRule)147 private void finishActivity(ActivityTestRule activityRule) { 148 final Activity activity = activityRule.getActivity(); 149 if (activity != null) { 150 activity.finish(); 151 } 152 } 153 greaterThanOrEqualToInexact(float expected)154 static Matcher<Float> greaterThanOrEqualToInexact(float expected) { 155 return greaterThanOrEqualTo(expected - FLOAT_EQUALITY_DELTA); 156 } 157 lessThanOrEqualToInexact(float expected)158 static Matcher<Float> lessThanOrEqualToInexact(float expected) { 159 return lessThanOrEqualTo(expected + FLOAT_EQUALITY_DELTA); 160 } 161 } 162