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