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.view.Display; 29 import android.view.WindowManager; 30 31 import androidx.test.rule.ActivityTestRule; 32 33 import com.android.compatibility.common.util.PollingCheck; 34 35 import org.hamcrest.Matcher; 36 import org.junit.Before; 37 38 class AspectRatioTestsBase extends ActivityManagerTestBase { 39 // The delta allowed when comparing two floats for equality. We consider them equal if they are 40 // within two significant digits of each other. 41 private static final float FLOAT_EQUALITY_DELTA = .01f; 42 43 interface AssertAspectRatioCallback { assertAspectRatio(float actual, int displayId, Point activitySize, Point displaySize)44 void assertAspectRatio(float actual, int displayId, Point activitySize, Point displaySize); 45 } 46 runAspectRatioTest(final ComponentName componentName, final AssertAspectRatioCallback callback)47 void runAspectRatioTest(final ComponentName componentName, 48 final AssertAspectRatioCallback callback) { 49 launchActivity(componentName); 50 mWmState.computeState(); 51 52 final int displayId = mWmState.getDisplayByActivity(componentName); 53 final WindowManagerState.Activity activity = mWmState.getActivity(componentName); 54 final WindowManagerState.DisplayContent display = mWmState.getDisplay(displayId); 55 56 final Rect bounds = activity.getAppBounds(); 57 final int shortSide = Math.min(bounds.width(), bounds.height()); 58 final int longSide = Math.max(bounds.width(), bounds.height()); 59 final float actualAspectRatio = (float) longSide / (float) shortSide; 60 61 callback.assertAspectRatio(actualAspectRatio, display.mId, 62 new Point(bounds.width(), bounds.height()), 63 new Point(display.getAppRect().width(), display.getAppRect().height())); 64 } 65 runAspectRatioTest(final ActivityTestRule activityRule, final AssertAspectRatioCallback callback)66 void runAspectRatioTest(final ActivityTestRule activityRule, 67 final AssertAspectRatioCallback callback) { 68 final Activity activity = launchActivity(activityRule); 69 PollingCheck.waitFor(activity::hasWindowFocus); 70 try { 71 final Point displaySize = new Point(); 72 getDisplay(activity).getSize(displaySize); 73 callback.assertAspectRatio(getActivityAspectRatio(activity), 74 getDisplay(activity).getDisplayId(), 75 getActivitySize(activity), 76 displaySize); 77 } finally { 78 finishActivity(activityRule); 79 } 80 81 // TODO(b/35810513): All this rotation stuff doesn't really work yet. Need to make sure 82 // context is updated correctly here. Also, what does it mean to be holding a reference to 83 // this activity if changing the orientation will cause a relaunch? 84 // activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE); 85 // waitForIdle(); 86 // callback.assertAspectRatio(getAspectRatio(activity)); 87 // 88 // activity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT); 89 // waitForIdle(); 90 // callback.assertAspectRatio(getAspectRatio(activity)); 91 } 92 93 @Before wakeUpAndUnlock()94 public void wakeUpAndUnlock() { 95 UiDeviceUtils.pressWakeupButton(); 96 UiDeviceUtils.pressUnlockButton(); 97 } 98 getDisplayAspectRatio(ComponentName componentName)99 float getDisplayAspectRatio(ComponentName componentName) { 100 final int displayId = mWmState.getDisplayByActivity(componentName); 101 final WindowManagerState.DisplayContent display = mWmState.getDisplay(displayId); 102 103 final Rect appRect = display.getAppRect(); 104 final int shortSide = Math.min(appRect.width(), appRect.height()); 105 final int longSide = Math.max(appRect.width(), appRect.height()); 106 return (float) longSide / (float) shortSide; 107 } 108 getMinimalTaskSize(ComponentName componentName)109 int getMinimalTaskSize(ComponentName componentName) { 110 final int displayId = mWmState.getDisplayByActivity(componentName); 111 return mWmState.defaultMinimalTaskSize(displayId); 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