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.am; 18 19 import static android.server.am.ComponentNameUtils.getActivityName; 20 import static android.server.am.Components.ALT_LAUNCHING_ACTIVITY; 21 import static android.server.am.Components.LAUNCHING_ACTIVITY; 22 import static android.server.am.Components.RESIZEABLE_ACTIVITY; 23 import static android.server.am.Components.VR_TEST_ACTIVITY; 24 import static android.view.Display.DEFAULT_DISPLAY; 25 26 import static org.junit.Assert.assertEquals; 27 import static org.junit.Assert.assertNotNull; 28 import static org.junit.Assume.assumeFalse; 29 import static org.junit.Assume.assumeTrue; 30 31 import android.server.am.ActivityManagerState.ActivityDisplay; 32 33 import org.junit.Before; 34 import org.junit.Test; 35 36 import java.util.List; 37 38 /** 39 * Build/Install/Run: 40 * atest CtsActivityManagerDeviceTestCases:ActivityManagerVrDisplayTests 41 */ 42 public class ActivityManagerVrDisplayTests extends ActivityManagerDisplayTestBase { 43 private static final int VR_VIRTUAL_DISPLAY_WIDTH = 700; 44 private static final int VR_VIRTUAL_DISPLAY_HEIGHT = 900; 45 private static final int VR_VIRTUAL_DISPLAY_DPI = 320; 46 47 48 @Before 49 @Override setUp()50 public void setUp() throws Exception { 51 super.setUp(); 52 53 assumeTrue(supportsVrMode()); 54 } 55 56 /** 57 * VrModeSession is used to enable or disable persistent vr mode and the vr virtual display. For 58 * standalone vr devices, VrModeSession has no effect, because the device is already in 59 * persistent vr mode whenever it's on, and turning off persistent vr mode on a standalone vr 60 * device puts the device in a bad state. 61 */ 62 private static class VrModeSession implements AutoCloseable { 63 private boolean applyVrModeChanges = !ActivityManagerTestBase.isUiModeLockedToVrHeadset(); 64 enablePersistentVrMode()65 void enablePersistentVrMode() throws Exception { 66 if (!applyVrModeChanges) { return; } 67 executeShellCommand("setprop vr_virtualdisplay true"); 68 executeShellCommand("vr set-persistent-vr-mode-enabled true"); 69 } 70 71 @Override close()72 public void close() throws Exception { 73 if (!applyVrModeChanges) { return; } 74 executeShellCommand("vr set-persistent-vr-mode-enabled false"); 75 executeShellCommand("setprop vr_virtualdisplay false"); 76 } 77 } 78 79 /** 80 * Tests that any new activity launch in Vr mode is in Vr display. 81 */ 82 @Test testVrActivityLaunch()83 public void testVrActivityLaunch() throws Exception { 84 assumeTrue(supportsMultiDisplay()); 85 86 try (final VrModeSession vrModeSession = new VrModeSession()) { 87 // Put the device in persistent vr mode. 88 vrModeSession.enablePersistentVrMode(); 89 90 // Launch the VR activity. 91 launchActivity(VR_TEST_ACTIVITY); 92 mAmWmState.computeState(VR_TEST_ACTIVITY); 93 mAmWmState.assertVisibility(VR_TEST_ACTIVITY, true /* visible */); 94 95 // Launch the non-VR 2D activity and check where it ends up. 96 launchActivity(LAUNCHING_ACTIVITY); 97 mAmWmState.computeState(LAUNCHING_ACTIVITY); 98 99 // Ensure that the subsequent activity is visible 100 mAmWmState.assertVisibility(LAUNCHING_ACTIVITY, true /* visible */); 101 102 // Check that activity is launched in focused stack on primary display. 103 mAmWmState.assertFocusedActivity("Launched activity must be focused", 104 LAUNCHING_ACTIVITY); 105 final int focusedStackId = mAmWmState.getAmState().getFocusedStackId(); 106 final ActivityManagerState.ActivityStack focusedStack 107 = mAmWmState.getAmState().getStackById(focusedStackId); 108 assertEquals("Launched activity must be resumed in focused stack", 109 getActivityName(LAUNCHING_ACTIVITY), focusedStack.mResumedActivity); 110 111 // Check if the launch activity is in Vr virtual display id. 112 final List<ActivityDisplay> reportedDisplays = getDisplaysStates(); 113 final ActivityDisplay vrDisplay = getDisplayState(reportedDisplays, 114 VR_VIRTUAL_DISPLAY_WIDTH, VR_VIRTUAL_DISPLAY_HEIGHT, VR_VIRTUAL_DISPLAY_DPI); 115 assertNotNull("Vr mode should have a virtual display", vrDisplay); 116 117 // Check if the focused activity is on this virtual stack. 118 assertEquals("Launch in Vr mode should be in virtual stack", vrDisplay.mId, 119 focusedStack.mDisplayId); 120 } 121 } 122 123 /** 124 * Tests that any activity already present is re-launched in Vr display in vr mode. 125 */ 126 @Test testVrActivityReLaunch()127 public void testVrActivityReLaunch() throws Exception { 128 assumeTrue(supportsMultiDisplay()); 129 130 // Launch a 2D activity. 131 launchActivity(LAUNCHING_ACTIVITY); 132 133 try (final VrModeSession vrModeSession = new VrModeSession()) { 134 // Put the device in persistent vr mode. 135 vrModeSession.enablePersistentVrMode(); 136 137 // Launch the VR activity. 138 launchActivity(VR_TEST_ACTIVITY); 139 mAmWmState.computeState(VR_TEST_ACTIVITY); 140 mAmWmState.assertVisibility(VR_TEST_ACTIVITY, true /* visible */); 141 142 // Re-launch the non-VR 2D activity and check where it ends up. 143 launchActivity(LAUNCHING_ACTIVITY); 144 mAmWmState.computeState(LAUNCHING_ACTIVITY); 145 146 // Ensure that the subsequent activity is visible 147 mAmWmState.assertVisibility(LAUNCHING_ACTIVITY, true /* visible */); 148 149 // Check that activity is launched in focused stack on primary display. 150 mAmWmState.assertFocusedActivity("Launched activity must be focused", 151 LAUNCHING_ACTIVITY); 152 final int focusedStackId = mAmWmState.getAmState().getFocusedStackId(); 153 final ActivityManagerState.ActivityStack focusedStack 154 = mAmWmState.getAmState().getStackById(focusedStackId); 155 assertEquals("Launched activity must be resumed in focused stack", 156 getActivityName(LAUNCHING_ACTIVITY), focusedStack.mResumedActivity); 157 158 // Check if the launch activity is in Vr virtual display id. 159 final List<ActivityDisplay> reportedDisplays = getDisplaysStates(); 160 final ActivityDisplay vrDisplay = getDisplayState(reportedDisplays, 161 VR_VIRTUAL_DISPLAY_WIDTH, VR_VIRTUAL_DISPLAY_HEIGHT, VR_VIRTUAL_DISPLAY_DPI); 162 assertNotNull("Vr mode should have a virtual display", vrDisplay); 163 164 // Check if the focused activity is on this virtual stack. 165 assertEquals("Launch in Vr mode should be in virtual stack", vrDisplay.mId, 166 focusedStack.mDisplayId); 167 } 168 } 169 170 /** 171 * Tests that any new activity launch post Vr mode is in the main display. 172 */ 173 @Test testActivityLaunchPostVr()174 public void testActivityLaunchPostVr() throws Exception { 175 assumeTrue(supportsMultiDisplay()); 176 // This test doesn't apply to a standalone vr device, since vr is always enabled, and 177 // there is no "post vr" behavior to verify. 178 assumeFalse(isUiModeLockedToVrHeadset()); 179 180 try (final VrModeSession vrModeSession = new VrModeSession()) { 181 // Put the device in persistent vr mode. 182 vrModeSession.enablePersistentVrMode(); 183 184 // Launch the VR activity. 185 launchActivity(VR_TEST_ACTIVITY); 186 mAmWmState.computeState(VR_TEST_ACTIVITY); 187 mAmWmState.assertVisibility(VR_TEST_ACTIVITY, true /* visible */); 188 189 // Launch the non-VR 2D activity and check where it ends up. 190 launchActivity(ALT_LAUNCHING_ACTIVITY); 191 mAmWmState.computeState(ALT_LAUNCHING_ACTIVITY); 192 193 // Ensure that the subsequent activity is visible 194 mAmWmState.assertVisibility(ALT_LAUNCHING_ACTIVITY, true /* visible */); 195 196 // Check that activity is launched in focused stack on primary display. 197 mAmWmState.assertFocusedActivity("Launched activity must be focused", 198 ALT_LAUNCHING_ACTIVITY); 199 final int focusedStackId = mAmWmState.getAmState().getFocusedStackId(); 200 final ActivityManagerState.ActivityStack focusedStack 201 = mAmWmState.getAmState().getStackById(focusedStackId); 202 assertEquals("Launched activity must be resumed in focused stack", 203 getActivityName(ALT_LAUNCHING_ACTIVITY), 204 focusedStack.mResumedActivity); 205 206 // Check if the launch activity is in Vr virtual display id. 207 final List<ActivityDisplay> reportedDisplays = getDisplaysStates(); 208 final ActivityDisplay vrDisplay = getDisplayState(reportedDisplays, 209 VR_VIRTUAL_DISPLAY_WIDTH, VR_VIRTUAL_DISPLAY_HEIGHT, 210 VR_VIRTUAL_DISPLAY_DPI); 211 assertNotNull("Vr mode should have a virtual display", vrDisplay); 212 213 // Check if the focused activity is on this virtual stack. 214 assertEquals("Launch in Vr mode should be in virtual stack", vrDisplay.mId, 215 focusedStack.mDisplayId); 216 217 } 218 219 // There isn't a direct launch of activity which can take an user out of persistent VR mode. 220 // This sleep is to account for that delay and let device settle once it comes out of VR 221 // mode. 222 try { 223 Thread.sleep(2000); 224 } catch (Exception e) { 225 e.printStackTrace(); 226 } 227 228 // Launch the non-VR 2D activity and check where it ends up. 229 launchActivity(RESIZEABLE_ACTIVITY); 230 mAmWmState.computeState(RESIZEABLE_ACTIVITY); 231 232 // Ensure that the subsequent activity is visible 233 mAmWmState.assertVisibility(RESIZEABLE_ACTIVITY, true /* visible */); 234 235 // Check that activity is launched in focused stack on primary display. 236 mAmWmState.assertFocusedActivity("Launched activity must be focused", RESIZEABLE_ACTIVITY); 237 final int frontStackId = mAmWmState.getAmState().getFrontStackId(DEFAULT_DISPLAY); 238 final ActivityManagerState.ActivityStack frontStack 239 = mAmWmState.getAmState().getStackById(frontStackId); 240 assertEquals("Launched activity must be resumed in front stack", 241 getActivityName(RESIZEABLE_ACTIVITY), frontStack.mResumedActivity); 242 assertEquals("Front stack must be on primary display", 243 DEFAULT_DISPLAY, frontStack.mDisplayId); 244 } 245 } 246