• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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.server.wm.ShellCommandHelper.executeShellCommand;
20 import static android.server.wm.ShellCommandHelper.executeShellCommandAndGetStdout;
21 import static android.server.wm.app.Components.TEST_ACTIVITY;
22 import static android.server.wm.displaysize.Components.SMALLEST_WIDTH_ACTIVITY;
23 
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertTrue;
26 
27 import android.graphics.Point;
28 import android.hardware.display.DisplayManager;
29 import android.hardware.display.VirtualDisplay;
30 import android.os.Build;
31 import android.os.Handler;
32 import android.os.Looper;
33 import android.platform.test.annotations.Presubmit;
34 import android.view.Display;
35 
36 import org.junit.After;
37 import org.junit.Test;
38 
39 /**
40  * Ensure that compatibility dialog is shown when launching an application with
41  * an unsupported smallest width.
42  *
43  * <p>Build/Install/Run:
44  *     atest CtsWindowManagerDeviceTestCases:DisplaySizeTest
45  */
46 @Presubmit
47 @android.server.wm.annotation.Group3
48 public class DisplaySizeTest extends ActivityManagerTestBase {
49 
50     /** @see com.android.server.wm.UnsupportedDisplaySizeDialog */
51     private static final String UNSUPPORTED_DISPLAY_SIZE_DIALOG_NAME =
52             "UnsupportedDisplaySizeDialog";
53 
54     @After
tearDown()55     public void tearDown() {
56         // Ensure app process is stopped.
57         stopTestPackage(SMALLEST_WIDTH_ACTIVITY.getPackageName());
58         stopTestPackage(TEST_ACTIVITY.getPackageName());
59     }
60 
61     @Test
testCompatibilityDialog()62     public void testCompatibilityDialog() {
63         // Launch some other app (not to perform density change on launcher).
64         launchActivity(TEST_ACTIVITY);
65         mWmState.assertActivityDisplayed(TEST_ACTIVITY);
66 
67         createManagedScreenDensitySession().setUnsupportedDensity();
68 
69         // Launch target app.
70         launchActivity(SMALLEST_WIDTH_ACTIVITY);
71         mWmState.assertActivityDisplayed(SMALLEST_WIDTH_ACTIVITY);
72         mWmState.assertWindowDisplayed(UNSUPPORTED_DISPLAY_SIZE_DIALOG_NAME);
73     }
74 
75     @Test
testCompatibilityDialogWhenFocused()76     public void testCompatibilityDialogWhenFocused() {
77         launchActivity(SMALLEST_WIDTH_ACTIVITY);
78         mWmState.assertActivityDisplayed(SMALLEST_WIDTH_ACTIVITY);
79 
80         createManagedScreenDensitySession().setUnsupportedDensity();
81 
82         mWmState.assertWindowDisplayed(UNSUPPORTED_DISPLAY_SIZE_DIALOG_NAME);
83     }
84 
85     @Test
testCompatibilityDialogAfterReturn()86     public void testCompatibilityDialogAfterReturn() {
87         // Launch target app.
88         launchActivity(SMALLEST_WIDTH_ACTIVITY);
89         mWmState.assertActivityDisplayed(SMALLEST_WIDTH_ACTIVITY);
90         // Launch another activity.
91         final CommandSession.ActivitySession activity = createManagedActivityClientSession()
92                 .startActivity(getLaunchActivityBuilder().setUseInstrumentation()
93                         .setTargetActivity(TEST_ACTIVITY));
94         mWmState.assertActivityDisplayed(TEST_ACTIVITY);
95         separateTestJournal();
96 
97         createManagedScreenDensitySession().setUnsupportedDensity();
98 
99         assertActivityLifecycle(TEST_ACTIVITY, true /* relaunched */);
100         activity.finish();
101 
102         mWmState.assertActivityDisplayed(SMALLEST_WIDTH_ACTIVITY);
103         mWmState.assertWindowDisplayed(UNSUPPORTED_DISPLAY_SIZE_DIALOG_NAME);
104     }
105 
106     @Test
testSizeRangesAfterSettingDisplaySize()107     public void testSizeRangesAfterSettingDisplaySize() throws InterruptedException {
108         VirtualDisplay virtualDisplay = null;
109         try {
110             final int initialLength = 500;
111             final int newLength = 1000;
112             final DisplayManager displayManager = mDm;
113             virtualDisplay = displayManager.createVirtualDisplay("CtsDisplay", initialLength,
114                     initialLength, 160 /* densityDpi */, null /* surface */, 0 /* flags */);
115             final Display targetDisplay = virtualDisplay.getDisplay();
116             final int targetDisplayId = targetDisplay.getDisplayId();
117             final boolean[] displayChanged = { false };
118             displayManager.registerDisplayListener(new DisplayManager.DisplayListener() {
119                 @Override
120                 public void onDisplayAdded(int displayId) {}
121 
122                 @Override
123                 public void onDisplayRemoved(int displayId) {}
124 
125                 @Override
126                 public void onDisplayChanged(int displayId) {
127                     if (displayId == targetDisplayId) {
128                         synchronized (displayManager) {
129                             displayChanged[0] = true;
130                             displayManager.notify();
131                         }
132                         displayManager.unregisterDisplayListener(this);
133                     }
134                 }
135             }, new Handler(Looper.getMainLooper()));
136 
137             executeShellCommand(String.format("wm size %sx%s -d %s",
138                     newLength, newLength, targetDisplayId));
139 
140             synchronized (displayManager) {
141                 if (!displayChanged[0]) {
142                     displayManager.wait(3000 /* milliseconds */);
143                 }
144                 assertTrue("DisplayManager must receive onDisplayChanged event", displayChanged[0]);
145             }
146 
147             final Point expectedSize = new Point(newLength, newLength);
148             final Point smallestSize = new Point();
149             final Point largestSize = new Point();
150             targetDisplay.getCurrentSizeRange(smallestSize, largestSize);
151             assertEquals("Smallest size must be changed.", expectedSize, smallestSize);
152             assertEquals("Largest size must be changed.", expectedSize, largestSize);
153         } finally {
154             if (virtualDisplay != null) {
155                 virtualDisplay.release();
156             }
157         }
158     }
159 
createManagedScreenDensitySession()160     protected ScreenDensitySession createManagedScreenDensitySession() {
161         return mObjectTracker.manage(new ScreenDensitySession());
162     }
163 
164     private static class ScreenDensitySession implements AutoCloseable {
165         private static final String DENSITY_PROP_DEVICE = "ro.sf.lcd_density";
166         private static final String DENSITY_PROP_EMULATOR = "qemu.sf.lcd_density";
167 
setUnsupportedDensity()168         void setUnsupportedDensity() {
169             // Set device to 0.85 zoom. It doesn't matter that we're zooming out
170             // since the feature verifies that we're in a non-default density.
171             final int stableDensity = getStableDensity();
172             final int targetDensity = (int) (stableDensity * 0.85);
173             setDensity(targetDensity);
174         }
175 
176         @Override
close()177         public void close() throws Exception {
178             resetDensity();
179         }
180 
getStableDensity()181         private int getStableDensity() {
182             final String densityProp;
183             if (Build.IS_EMULATOR) {
184                 densityProp = DENSITY_PROP_EMULATOR;
185             } else {
186                 densityProp = DENSITY_PROP_DEVICE;
187             }
188 
189             return Integer.parseInt(
190                     executeShellCommandAndGetStdout("getprop " + densityProp).trim());
191         }
192 
setDensity(int targetDensity)193         private void setDensity(int targetDensity) {
194             executeShellCommand("wm density " + targetDensity);
195 
196             // Verify that the density is changed.
197             final String output = executeShellCommandAndGetStdout("wm density");
198             final boolean success = output.contains("Override density: " + targetDensity);
199 
200             assertTrue("Failed to set density to " + targetDensity, success);
201         }
202 
resetDensity()203         private void resetDensity() {
204             executeShellCommand("wm density reset");
205         }
206     }
207 }
208