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.am;
18 
19 import static android.content.Context.WINDOW_SERVICE;
20 import static android.content.pm.PackageManager.FEATURE_WATCH;
21 
22 import static org.junit.Assert.fail;
23 
24 import android.app.Activity;
25 import android.content.Context;
26 import android.platform.test.annotations.Presubmit;
27 import android.support.test.InstrumentationRegistry;
28 import android.support.test.rule.ActivityTestRule;
29 import android.support.test.runner.AndroidJUnit4;
30 import android.util.DisplayMetrics;
31 import android.view.Display;
32 import android.view.WindowManager;
33 
34 import com.android.compatibility.common.util.PollingCheck;
35 
36 import org.junit.Rule;
37 import org.junit.Test;
38 import org.junit.runner.RunWith;
39 
40 /**
41  * Build/Install/Run:
42  *     atest CtsActivityManagerDeviceTestCases:AspectRatioTests
43  */
44 @RunWith(AndroidJUnit4.class)
45 @Presubmit
46 public class AspectRatioTests extends AspectRatioTestsBase {
47 
48     // The max. aspect ratio the test activities are using.
49     private static final float MAX_ASPECT_RATIO = 1.0f;
50 
51     // The minimum supported device aspect ratio.
52     private static final float MIN_DEVICE_ASPECT_RATIO = 1.333f;
53 
54     // The minimum supported device aspect ratio for watches.
55     private static final float MIN_WATCH_DEVICE_ASPECT_RATIO = 1.0f;
56 
57     // Test target activity that has maxAspectRatio="true" and resizeableActivity="false".
58     public static class MaxAspectRatioActivity extends Activity {
59     }
60 
61     // Test target activity that has maxAspectRatio="1.0" and resizeableActivity="true".
62     public static class MaxAspectRatioResizeableActivity extends Activity {
63     }
64 
65     // Test target activity that has no maxAspectRatio defined and resizeableActivity="false".
66     public static class MaxAspectRatioUnsetActivity extends Activity {
67     }
68 
69     // Test target activity that has maxAspectRatio defined as
70     //   <meta-data android:name="android.max_aspect" android:value="1.0" />
71     // and resizeableActivity="false".
72     public static class MetaDataMaxAspectRatioActivity extends Activity {
73     }
74 
75     @Rule
76     public ActivityTestRule<MaxAspectRatioActivity> mMaxAspectRatioActivity =
77             new ActivityTestRule<>(MaxAspectRatioActivity.class,
78                     false /* initialTouchMode */, false /* launchActivity */);
79 
80     @Rule
81     public ActivityTestRule<MaxAspectRatioResizeableActivity> mMaxAspectRatioResizeableActivity =
82             new ActivityTestRule<>(MaxAspectRatioResizeableActivity.class,
83                     false /* initialTouchMode */, false /* launchActivity */);
84 
85     @Rule
86     public ActivityTestRule<MetaDataMaxAspectRatioActivity> mMetaDataMaxAspectRatioActivity =
87             new ActivityTestRule<>(MetaDataMaxAspectRatioActivity.class,
88                     false /* initialTouchMode */, false /* launchActivity */);
89 
90     @Rule
91     public ActivityTestRule<MaxAspectRatioUnsetActivity> mMaxAspectRatioUnsetActivity =
92             new ActivityTestRule<>(MaxAspectRatioUnsetActivity.class,
93                     false /* initialTouchMode */, false /* launchActivity */);
94 
95     @Test
testDeviceAspectRatio()96     public void testDeviceAspectRatio() throws Exception {
97         final Context context = InstrumentationRegistry.getInstrumentation().getContext();
98         final WindowManager wm = (WindowManager) context.getSystemService(WINDOW_SERVICE);
99         final Display display = wm.getDefaultDisplay();
100         final DisplayMetrics metrics = new DisplayMetrics();
101         display.getRealMetrics(metrics);
102 
103         float longSide = Math.max(metrics.widthPixels, metrics.heightPixels);
104         float shortSide = Math.min(metrics.widthPixels, metrics.heightPixels);
105         float deviceAspectRatio = longSide / shortSide;
106         float expectedMinAspectRatio = context.getPackageManager().hasSystemFeature(FEATURE_WATCH)
107                 ? MIN_WATCH_DEVICE_ASPECT_RATIO : MIN_DEVICE_ASPECT_RATIO;
108 
109         if (deviceAspectRatio < expectedMinAspectRatio) {
110             fail("deviceAspectRatio=" + deviceAspectRatio
111                     + " is less than expectedMinAspectRatio=" + expectedMinAspectRatio);
112         }
113     }
114 
115     @Test
testMaxAspectRatio()116     public void testMaxAspectRatio() throws Exception {
117         runAspectRatioTest(mMaxAspectRatioActivity, actual -> {
118             if (MAX_ASPECT_RATIO >= actual) return;
119             fail("actual=" + actual + " is greater than expected=" + MAX_ASPECT_RATIO);
120         });
121     }
122 
123     @Test
testMetaDataMaxAspectRatio()124     public void testMetaDataMaxAspectRatio() throws Exception {
125         runAspectRatioTest(mMetaDataMaxAspectRatioActivity, actual -> {
126             if (MAX_ASPECT_RATIO >= actual) return;
127             fail("actual=" + actual + " is greater than expected=" + MAX_ASPECT_RATIO);
128         });
129     }
130 
131     @Test
testMaxAspectRatioResizeableActivity()132     public void testMaxAspectRatioResizeableActivity() throws Exception {
133         final Context context = InstrumentationRegistry.getInstrumentation().getContext();
134         final float expected = getAspectRatio(context);
135         final Activity testActivity = launchActivity(mMaxAspectRatioResizeableActivity);
136         PollingCheck.waitFor(testActivity::hasWindowFocus);
137 
138         Display testDisplay = testActivity.findViewById(android.R.id.content).getDisplay();
139 
140         // TODO(b/69982434): Fix DisplayManager NPE when getting display from Instrumentation
141         // context, then can use DisplayManager to get the aspect ratio of the correct display.
142         if (testDisplay.getDisplayId() != Display.DEFAULT_DISPLAY) {
143             return;
144         }
145 
146         // Since this activity is resizeable, its aspect ratio shouldn't be less than the device's
147         runTest(testActivity, actual -> {
148             if (aspectRatioEqual(expected, actual) || expected < actual) return;
149             fail("actual=" + actual + " is less than expected=" + expected);
150         });
151     }
152 
153     @Test
testMaxAspectRatioUnsetActivity()154     public void testMaxAspectRatioUnsetActivity() throws Exception {
155         final Context context = InstrumentationRegistry.getInstrumentation().getContext();
156         final float expected = getAspectRatio(context);
157 
158         // Since this activity didn't set an aspect ratio, its aspect ratio shouldn't be less than
159         // the device's
160         runAspectRatioTest(mMaxAspectRatioUnsetActivity, actual -> {
161             if (aspectRatioEqual(expected, actual) || expected < actual) return;
162             fail("actual=" + actual + " is less than expected=" + expected);
163         });
164     }
165 }
166