Home | History | Annotate | Download | only in display
      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