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