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