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 com.android.server.display; 18 19 import android.content.Context; 20 import android.hardware.display.DisplayManager; 21 import android.hardware.display.DisplayViewport; 22 import android.hardware.display.IVirtualDisplayCallback; 23 import android.hardware.input.InputManagerInternal; 24 import android.os.Handler; 25 import android.os.IBinder; 26 import android.test.AndroidTestCase; 27 import android.test.suitebuilder.annotation.SmallTest; 28 import android.view.SurfaceControl; 29 import android.view.WindowManagerInternal; 30 31 import com.android.server.LocalServices; 32 import com.android.server.SystemService; 33 import com.android.server.display.DisplayDeviceInfo; 34 import com.android.server.display.DisplayManagerService.SyncRoot; 35 import com.android.server.display.VirtualDisplayAdapter.SurfaceControlDisplayFactory; 36 import com.android.server.lights.LightsManager; 37 38 import org.mockito.ArgumentCaptor; 39 import org.mockito.Mock; 40 import org.mockito.MockitoAnnotations; 41 42 import java.util.List; 43 44 import static org.mockito.Matchers.any; 45 import static org.mockito.Mockito.verify; 46 import static org.mockito.Mockito.when; 47 48 @SmallTest 49 public class DisplayManagerServiceTest extends AndroidTestCase { 50 private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1; 51 private static final long SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS = 10; 52 53 private final DisplayManagerService.Injector mShortMockedInjector = 54 new DisplayManagerService.Injector() { 55 @Override 56 VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, 57 Context context, Handler handler, DisplayAdapter.Listener listener) { 58 return mMockVirtualDisplayAdapter; 59 } 60 61 @Override 62 long getDefaultDisplayDelayTimeout() { 63 return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS; 64 } 65 }; 66 private final DisplayManagerService.Injector mBasicInjector = 67 new DisplayManagerService.Injector() { 68 @Override 69 VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, 70 Context context, Handler handler, 71 DisplayAdapter.Listener displayAdapterListener) { 72 return new VirtualDisplayAdapter(syncRoot, context, handler, 73 displayAdapterListener, 74 (String name, boolean secure) -> mMockDisplayToken); 75 } 76 }; 77 78 @Mock InputManagerInternal mMockInputManagerInternal; 79 @Mock IVirtualDisplayCallback.Stub mMockAppToken; 80 @Mock WindowManagerInternal mMockWindowManagerInternal; 81 @Mock LightsManager mMockLightsManager; 82 @Mock VirtualDisplayAdapter mMockVirtualDisplayAdapter; 83 @Mock IBinder mMockDisplayToken; 84 85 @Override 86 protected void setUp() throws Exception { 87 MockitoAnnotations.initMocks(this); 88 89 LocalServices.removeServiceForTest(InputManagerInternal.class); 90 LocalServices.addService(InputManagerInternal.class, mMockInputManagerInternal); 91 LocalServices.removeServiceForTest(WindowManagerInternal.class); 92 LocalServices.addService(WindowManagerInternal.class, mMockWindowManagerInternal); 93 LocalServices.removeServiceForTest(LightsManager.class); 94 LocalServices.addService(LightsManager.class, mMockLightsManager); 95 super.setUp(); 96 } 97 98 @Override 99 protected void tearDown() throws Exception { 100 super.tearDown(); 101 } 102 103 public void testCreateVirtualDisplay_sentToInputManager() throws Exception { 104 DisplayManagerService displayManager = 105 new DisplayManagerService(mContext, mBasicInjector); 106 registerDefaultDisplays(displayManager); 107 displayManager.systemReady(false /* safeMode */, true /* onlyCore */); 108 displayManager.windowManagerAndInputReady(); 109 110 // This is effectively the DisplayManager service published to ServiceManager. 111 DisplayManagerService.BinderService bs = displayManager.new BinderService(); 112 113 String uniqueId = "uniqueId --- Test"; 114 String uniqueIdPrefix = "virtual:" + mContext.getPackageName() + ":"; 115 int width = 600; 116 int height = 800; 117 int dpi = 320; 118 int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH; 119 120 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 121 int displayId = bs.createVirtualDisplay(mMockAppToken /* callback */, 122 null /* projection */, "com.android.frameworks.servicestests", 123 "Test Virtual Display", width, height, dpi, null /* surface */, flags /* flags */, 124 uniqueId); 125 126 displayManager.performTraversalInTransactionFromWindowManagerInternal(); 127 128 // flush the handler 129 displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); 130 131 ArgumentCaptor<List<DisplayViewport>> virtualViewportCaptor = 132 ArgumentCaptor.forClass(List.class); 133 verify(mMockInputManagerInternal).setDisplayViewports( 134 any(), any(), virtualViewportCaptor.capture()); 135 136 assertEquals(1, virtualViewportCaptor.getValue().size()); 137 DisplayViewport dv = virtualViewportCaptor.getValue().get(0); 138 assertEquals(height, dv.deviceHeight); 139 assertEquals(width, dv.deviceWidth); 140 assertEquals(uniqueIdPrefix + uniqueId, dv.uniqueId); 141 assertEquals(displayId, dv.displayId); 142 } 143 144 public void testCreateVirtualDisplayRotatesWithContent() throws Exception { 145 DisplayManagerService displayManager = 146 new DisplayManagerService(mContext, mBasicInjector); 147 registerDefaultDisplays(displayManager); 148 149 // This is effectively the DisplayManager service published to ServiceManager. 150 DisplayManagerService.BinderService bs = displayManager.new BinderService(); 151 152 String uniqueId = "uniqueId --- Rotates With Content Test"; 153 int width = 600; 154 int height = 800; 155 int dpi = 320; 156 int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT; 157 158 when(mMockAppToken.asBinder()).thenReturn(mMockAppToken); 159 int displayId = bs.createVirtualDisplay(mMockAppToken /* callback */, 160 null /* projection */, "com.android.frameworks.servicestests", 161 "Test Virtual Display", width, height, dpi, null /* surface */, flags /* flags */, 162 uniqueId); 163 164 displayManager.performTraversalInTransactionFromWindowManagerInternal(); 165 166 // flush the handler 167 displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); 168 169 DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId); 170 assertNotNull(ddi); 171 assertTrue((ddi.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0); 172 } 173 174 /** 175 * Tests that the virtual display is created along-side the default display. 176 */ 177 public void testStartVirtualDisplayWithDefaultDisplay_Succeeds() throws Exception { 178 DisplayManagerService displayManager = 179 new DisplayManagerService(mContext, mShortMockedInjector); 180 registerDefaultDisplays(displayManager); 181 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 182 } 183 184 /** 185 * Tests that we get a Runtime exception when we cannot initialize the default display. 186 */ 187 public void testStartVirtualDisplayWithDefDisplay_NoDefaultDisplay() throws Exception { 188 DisplayManagerService displayManager = 189 new DisplayManagerService(mContext, mShortMockedInjector); 190 Handler handler = displayManager.getDisplayHandler(); 191 handler.runWithScissors(() -> {}, 0 /* now */); 192 193 try { 194 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 195 } catch (RuntimeException e) { 196 return; 197 } 198 fail("Expected DisplayManager to throw RuntimeException when it cannot initialize the" 199 + " default display"); 200 } 201 202 /** 203 * Tests that we get a Runtime exception when we cannot initialize the virtual display. 204 */ 205 public void testStartVirtualDisplayWithDefDisplay_NoVirtualDisplayAdapter() throws Exception { 206 DisplayManagerService displayManager = new DisplayManagerService(mContext, 207 new DisplayManagerService.Injector() { 208 @Override 209 VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, 210 Context context, Handler handler, DisplayAdapter.Listener listener) { 211 return null; // return null for the adapter. This should cause a failure. 212 } 213 214 @Override 215 long getDefaultDisplayDelayTimeout() { 216 return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS; 217 } 218 }); 219 try { 220 displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); 221 } catch (RuntimeException e) { 222 return; 223 } 224 fail("Expected DisplayManager to throw RuntimeException when it cannot initialize the" 225 + " virtual display adapter"); 226 } 227 228 private void registerDefaultDisplays(DisplayManagerService displayManager) { 229 Handler handler = displayManager.getDisplayHandler(); 230 // Would prefer to call displayManager.onStart() directly here but it performs binderService 231 // registration which triggers security exceptions when running from a test. 232 handler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS); 233 // flush the handler 234 handler.runWithScissors(() -> {}, 0 /* now */); 235 } 236 } 237