• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static com.android.server.display.VirtualDisplayAdapter.UNIQUE_ID_PREFIX;
20 
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertFalse;
23 import static org.junit.Assert.assertNotNull;
24 import static org.junit.Assert.assertTrue;
25 import static org.junit.Assert.fail;
26 import static org.mockito.Mockito.mock;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.when;
29 
30 import android.app.PropertyInvalidatedCache;
31 import android.compat.testing.PlatformCompatChangeRule;
32 import android.content.Context;
33 import android.graphics.Insets;
34 import android.graphics.Rect;
35 import android.hardware.display.BrightnessConfiguration;
36 import android.hardware.display.Curve;
37 import android.hardware.display.DisplayManager;
38 import android.hardware.display.DisplayManagerGlobal;
39 import android.hardware.display.DisplayViewport;
40 import android.hardware.display.DisplayedContentSample;
41 import android.hardware.display.DisplayedContentSamplingAttributes;
42 import android.hardware.display.IDisplayManagerCallback;
43 import android.hardware.display.IVirtualDisplayCallback;
44 import android.hardware.display.VirtualDisplayConfig;
45 import android.hardware.input.InputManagerInternal;
46 import android.os.Handler;
47 import android.os.IBinder;
48 import android.os.MessageQueue;
49 import android.os.Process;
50 import android.platform.test.annotations.Presubmit;
51 import android.view.Display;
52 import android.view.DisplayCutout;
53 import android.view.DisplayEventReceiver;
54 import android.view.DisplayInfo;
55 import android.view.Surface;
56 import android.view.SurfaceControl;
57 
58 import androidx.test.InstrumentationRegistry;
59 import androidx.test.filters.FlakyTest;
60 import androidx.test.filters.SmallTest;
61 import androidx.test.runner.AndroidJUnit4;
62 
63 import com.android.server.LocalServices;
64 import com.android.server.SystemService;
65 import com.android.server.display.DisplayManagerService.SyncRoot;
66 import com.android.server.lights.LightsManager;
67 import com.android.server.sensors.SensorManagerInternal;
68 import com.android.server.wm.WindowManagerInternal;
69 
70 import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
71 import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
72 
73 import org.junit.Before;
74 import org.junit.Rule;
75 import org.junit.Test;
76 import org.junit.rules.TestRule;
77 import org.junit.runner.RunWith;
78 import org.mockito.ArgumentCaptor;
79 import org.mockito.Mock;
80 import org.mockito.MockitoAnnotations;
81 
82 import java.time.Duration;
83 import java.util.Arrays;
84 import java.util.List;
85 import java.util.concurrent.CountDownLatch;
86 import java.util.concurrent.TimeUnit;
87 import java.util.stream.LongStream;
88 
89 @SmallTest
90 @Presubmit
91 @RunWith(AndroidJUnit4.class)
92 public class DisplayManagerServiceTest {
93     private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1;
94     private static final long SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS = 10;
95     private static final String VIRTUAL_DISPLAY_NAME = "Test Virtual Display";
96     private static final String PACKAGE_NAME = "com.android.frameworks.servicestests";
97     private static final long STANDARD_DISPLAY_EVENTS = DisplayManager.EVENT_FLAG_DISPLAY_ADDED
98                     | DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
99                     | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED;
100 
101     @Rule
102     public TestRule compatChangeRule = new PlatformCompatChangeRule();
103 
104     private Context mContext;
105 
106     private final DisplayManagerService.Injector mShortMockedInjector =
107             new DisplayManagerService.Injector() {
108                 @Override
109                 VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot,
110                         Context context, Handler handler, DisplayAdapter.Listener listener) {
111                     return mMockVirtualDisplayAdapter;
112                 }
113 
114                 @Override
115                 long getDefaultDisplayDelayTimeout() {
116                     return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS;
117                 }
118             };
119 
120     class BasicInjector extends DisplayManagerService.Injector {
121         @Override
getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, Handler handler, DisplayAdapter.Listener displayAdapterListener)122         VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context,
123                 Handler handler, DisplayAdapter.Listener displayAdapterListener) {
124             return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener,
125                     (String name, boolean secure) -> mMockDisplayToken);
126         }
127     }
128 
129     private final DisplayManagerService.Injector mBasicInjector = new BasicInjector();
130 
131     private final DisplayManagerService.Injector mAllowNonNativeRefreshRateOverrideInjector =
132             new BasicInjector() {
133                 @Override
134                 boolean getAllowNonNativeRefreshRateOverride() {
135                     return true;
136                 }
137             };
138 
139     private final DisplayManagerService.Injector mDenyNonNativeRefreshRateOverrideInjector =
140             new BasicInjector() {
141                 @Override
142                 boolean getAllowNonNativeRefreshRateOverride() {
143                     return false;
144                 }
145             };
146 
147     @Mock InputManagerInternal mMockInputManagerInternal;
148     @Mock IVirtualDisplayCallback.Stub mMockAppToken;
149     @Mock IVirtualDisplayCallback.Stub mMockAppToken2;
150     @Mock WindowManagerInternal mMockWindowManagerInternal;
151     @Mock LightsManager mMockLightsManager;
152     @Mock VirtualDisplayAdapter mMockVirtualDisplayAdapter;
153     @Mock IBinder mMockDisplayToken;
154     @Mock SensorManagerInternal mMockSensorManagerInternal;
155 
156     @Before
setUp()157     public void setUp() throws Exception {
158         MockitoAnnotations.initMocks(this);
159 
160         LocalServices.removeServiceForTest(InputManagerInternal.class);
161         LocalServices.addService(InputManagerInternal.class, mMockInputManagerInternal);
162         LocalServices.removeServiceForTest(WindowManagerInternal.class);
163         LocalServices.addService(WindowManagerInternal.class, mMockWindowManagerInternal);
164         LocalServices.removeServiceForTest(LightsManager.class);
165         LocalServices.addService(LightsManager.class, mMockLightsManager);
166         LocalServices.removeServiceForTest(SensorManagerInternal.class);
167         LocalServices.addService(SensorManagerInternal.class, mMockSensorManagerInternal);
168 
169         mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
170 
171         // Disable binder caches in this process.
172         PropertyInvalidatedCache.disableForTestMode();
173     }
174 
175     @Test
testCreateVirtualDisplay_sentToInputManager()176     public void testCreateVirtualDisplay_sentToInputManager() {
177         DisplayManagerService displayManager =
178                 new DisplayManagerService(mContext, mBasicInjector);
179         registerDefaultDisplays(displayManager);
180         displayManager.systemReady(false /* safeMode */, true /* onlyCore */);
181         displayManager.windowManagerAndInputReady();
182 
183         // This is effectively the DisplayManager service published to ServiceManager.
184         DisplayManagerService.BinderService bs = displayManager.new BinderService();
185 
186         String uniqueId = "uniqueId --- Test";
187         String uniqueIdPrefix = UNIQUE_ID_PREFIX + mContext.getPackageName() + ":";
188         int width = 600;
189         int height = 800;
190         int dpi = 320;
191         int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH;
192 
193         when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
194         final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
195                 VIRTUAL_DISPLAY_NAME, width, height, dpi);
196         builder.setUniqueId(uniqueId);
197         builder.setFlags(flags);
198         int displayId = bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */,
199                 null /* projection */, PACKAGE_NAME);
200 
201         displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
202 
203         // flush the handler
204         displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
205 
206         ArgumentCaptor<List<DisplayViewport>> viewportCaptor = ArgumentCaptor.forClass(List.class);
207         verify(mMockInputManagerInternal).setDisplayViewports(viewportCaptor.capture());
208         List<DisplayViewport> viewports = viewportCaptor.getValue();
209 
210         // Expect to receive at least 2 viewports: at least 1 internal, and 1 virtual
211         assertTrue(viewports.size() >= 2);
212 
213         DisplayViewport virtualViewport = null;
214         DisplayViewport internalViewport = null;
215         for (int i = 0; i < viewports.size(); i++) {
216             DisplayViewport v = viewports.get(i);
217             switch (v.type) {
218                 case DisplayViewport.VIEWPORT_INTERNAL: {
219                     // If more than one internal viewport, this will get overwritten several times,
220                     // which for the purposes of this test is fine.
221                     internalViewport = v;
222                     assertTrue(internalViewport.valid);
223                     break;
224                 }
225                 case DisplayViewport.VIEWPORT_EXTERNAL: {
226                     fail("EXTERNAL viewport should not exist.");
227                     break;
228                 }
229                 case DisplayViewport.VIEWPORT_VIRTUAL: {
230                     virtualViewport = v;
231                     break;
232                 }
233             }
234         }
235         // INTERNAL viewport gets created upon access.
236         assertNotNull(internalViewport);
237         assertNotNull(virtualViewport);
238 
239         // VIRTUAL
240         assertEquals(height, virtualViewport.deviceHeight);
241         assertEquals(width, virtualViewport.deviceWidth);
242         assertEquals(uniqueIdPrefix + uniqueId, virtualViewport.uniqueId);
243         assertEquals(displayId, virtualViewport.displayId);
244     }
245 
246     @Test
testPhysicalViewports()247     public void testPhysicalViewports() {
248         DisplayManagerService displayManager =
249                 new DisplayManagerService(mContext, mBasicInjector);
250         registerDefaultDisplays(displayManager);
251         displayManager.systemReady(false /* safeMode */, true /* onlyCore */);
252         displayManager.windowManagerAndInputReady();
253 
254         // This is effectively the DisplayManager service published to ServiceManager.
255         DisplayManagerService.BinderService bs = displayManager.new BinderService();
256 
257         when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
258 
259         final int displayIds[] = bs.getDisplayIds();
260         final int size = displayIds.length;
261         assertTrue(size > 0);
262         for (int i = 0; i < size; i++) {
263             DisplayInfo info = bs.getDisplayInfo(displayIds[i]);
264             assertEquals(info.type, Display.TYPE_INTERNAL);
265         }
266 
267         displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
268 
269         // flush the handler
270         displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
271 
272         ArgumentCaptor<List<DisplayViewport>> viewportCaptor = ArgumentCaptor.forClass(List.class);
273         verify(mMockInputManagerInternal).setDisplayViewports(viewportCaptor.capture());
274         List<DisplayViewport> viewports = viewportCaptor.getValue();
275 
276         // Due to the nature of foldables, we may have a different number of viewports than
277         // displays, just verify there's at least one.
278         final int viewportSize = viewports.size();
279         assertTrue(viewportSize > 0);
280 
281         // Now verify that each viewport's displayId is valid.
282         Arrays.sort(displayIds);
283         for (int i = 0; i < viewportSize; i++) {
284             DisplayViewport internalViewport = viewports.get(i);
285 
286             // INTERNAL is the only one actual display.
287             assertNotNull(internalViewport);
288             assertEquals(DisplayViewport.VIEWPORT_INTERNAL, internalViewport.type);
289             assertTrue(internalViewport.valid);
290             assertTrue(Arrays.binarySearch(displayIds, internalViewport.displayId) >= 0);
291         }
292     }
293 
294     @Test
testCreateVirtualDisplayRotatesWithContent()295     public void testCreateVirtualDisplayRotatesWithContent() throws Exception {
296         DisplayManagerService displayManager =
297                 new DisplayManagerService(mContext, mBasicInjector);
298         registerDefaultDisplays(displayManager);
299 
300         // This is effectively the DisplayManager service published to ServiceManager.
301         DisplayManagerService.BinderService bs = displayManager.new BinderService();
302 
303         String uniqueId = "uniqueId --- Rotates With Content Test";
304         int width = 600;
305         int height = 800;
306         int dpi = 320;
307         int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
308 
309         when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
310         final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
311                 VIRTUAL_DISPLAY_NAME, width, height, dpi);
312         builder.setFlags(flags);
313         builder.setUniqueId(uniqueId);
314         int displayId = bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */,
315                 null /* projection */, PACKAGE_NAME);
316 
317         displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
318 
319         // flush the handler
320         displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
321 
322         DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId);
323         assertNotNull(ddi);
324         assertTrue((ddi.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0);
325     }
326 
327     /**
328      * Tests that the virtual display is created along-side the default display.
329      */
330     @Test
testStartVirtualDisplayWithDefaultDisplay_Succeeds()331     public void testStartVirtualDisplayWithDefaultDisplay_Succeeds() throws Exception {
332         DisplayManagerService displayManager =
333                 new DisplayManagerService(mContext, mShortMockedInjector);
334         registerDefaultDisplays(displayManager);
335         displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
336     }
337 
338     /**
339      * Tests that there should be a display change notification to WindowManager to update its own
340      * internal state for things like display cutout when nonOverrideDisplayInfo is changed.
341      */
342     @Test
testShouldNotifyChangeWhenNonOverrideDisplayInfoChanged()343     public void testShouldNotifyChangeWhenNonOverrideDisplayInfoChanged() throws Exception {
344         DisplayManagerService displayManager =
345                 new DisplayManagerService(mContext, mShortMockedInjector);
346         registerDefaultDisplays(displayManager);
347         displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
348 
349         // Add the FakeDisplayDevice
350         FakeDisplayDevice displayDevice = new FakeDisplayDevice();
351         DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo();
352         displayDeviceInfo.width = 100;
353         displayDeviceInfo.height = 200;
354         displayDeviceInfo.supportedModes = new Display.Mode[1];
355         displayDeviceInfo.supportedModes[0] = new Display.Mode(1, 100, 200, 60f);
356         displayDeviceInfo.modeId = 1;
357         final Rect zeroRect = new Rect();
358         displayDeviceInfo.displayCutout = new DisplayCutout(
359                 Insets.of(0, 10, 0, 0),
360                 zeroRect, new Rect(0, 0, 10, 10), zeroRect, zeroRect);
361         displayDeviceInfo.flags = DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY;
362         displayDevice.setDisplayDeviceInfo(displayDeviceInfo);
363         displayManager.getDisplayDeviceRepository()
364                 .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED);
365 
366         // Find the display id of the added FakeDisplayDevice
367         DisplayManagerService.BinderService bs = displayManager.new BinderService();
368         int displayId = getDisplayIdForDisplayDevice(displayManager, bs, displayDevice);
369         // Setup override DisplayInfo
370         DisplayInfo overrideInfo = bs.getDisplayInfo(displayId);
371         displayManager.setDisplayInfoOverrideFromWindowManagerInternal(displayId, overrideInfo);
372 
373         FakeDisplayManagerCallback callback = registerDisplayListenerCallback(
374                 displayManager, bs, displayDevice);
375 
376         // Simulate DisplayDevice change
377         DisplayDeviceInfo displayDeviceInfo2 = new DisplayDeviceInfo();
378         displayDeviceInfo2.copyFrom(displayDeviceInfo);
379         displayDeviceInfo2.displayCutout = null;
380         displayDevice.setDisplayDeviceInfo(displayDeviceInfo2);
381         displayManager.getDisplayDeviceRepository()
382                 .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED);
383 
384         Handler handler = displayManager.getDisplayHandler();
385         waitForIdleHandler(handler);
386         assertTrue(callback.mDisplayChangedCalled);
387     }
388 
389     /**
390      * Tests that we get a Runtime exception when we cannot initialize the default display.
391      */
392     @Test
testStartVirtualDisplayWithDefDisplay_NoDefaultDisplay()393     public void testStartVirtualDisplayWithDefDisplay_NoDefaultDisplay() throws Exception {
394         DisplayManagerService displayManager =
395                 new DisplayManagerService(mContext, mShortMockedInjector);
396         Handler handler = displayManager.getDisplayHandler();
397         waitForIdleHandler(handler);
398 
399         try {
400             displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
401         } catch (RuntimeException e) {
402             return;
403         }
404         fail("Expected DisplayManager to throw RuntimeException when it cannot initialize the"
405                 + " default display");
406     }
407 
408     /**
409      * Tests that we get a Runtime exception when we cannot initialize the virtual display.
410      */
411     @Test
testStartVirtualDisplayWithDefDisplay_NoVirtualDisplayAdapter()412     public void testStartVirtualDisplayWithDefDisplay_NoVirtualDisplayAdapter() throws Exception {
413         DisplayManagerService displayManager = new DisplayManagerService(mContext,
414                 new DisplayManagerService.Injector() {
415                     @Override
416                     VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot,
417                             Context context, Handler handler, DisplayAdapter.Listener listener) {
418                         return null;  // return null for the adapter.  This should cause a failure.
419                     }
420 
421                     @Override
422                     long getDefaultDisplayDelayTimeout() {
423                         return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS;
424                     }
425                 });
426         try {
427             displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
428         } catch (RuntimeException e) {
429             return;
430         }
431         fail("Expected DisplayManager to throw RuntimeException when it cannot initialize the"
432                 + " virtual display adapter");
433     }
434 
435     /**
436      * Tests that an exception is raised for too dark a brightness configuration.
437      */
438     @Test
testTooDarkBrightnessConfigurationThrowException()439     public void testTooDarkBrightnessConfigurationThrowException() {
440         DisplayManagerService displayManager =
441                 new DisplayManagerService(mContext, mShortMockedInjector);
442         Curve minimumBrightnessCurve = displayManager.getMinimumBrightnessCurveInternal();
443         float[] lux = minimumBrightnessCurve.getX();
444         float[] minimumNits = minimumBrightnessCurve.getY();
445         float[] nits = new float[minimumNits.length];
446         // For every control point, assert that making it slightly lower than the minimum throws an
447         // exception.
448         for (int i = 0; i < nits.length; i++) {
449             for (int j = 0; j < nits.length; j++) {
450                 nits[j] = minimumNits[j];
451                 if (j == i) {
452                     nits[j] -= 0.1f;
453                 }
454                 if (nits[j] < 0) {
455                     nits[j] = 0;
456                 }
457             }
458             BrightnessConfiguration config =
459                     new BrightnessConfiguration.Builder(lux, nits).build();
460             Exception thrown = null;
461             try {
462                 displayManager.validateBrightnessConfiguration(config);
463             } catch (IllegalArgumentException e) {
464                 thrown = e;
465             }
466             assertNotNull("Building too dark a brightness configuration must throw an exception");
467         }
468     }
469 
470     /**
471      * Tests that no exception is raised for not too dark a brightness configuration.
472      */
473     @Test
testBrightEnoughBrightnessConfigurationDoesNotThrowException()474     public void testBrightEnoughBrightnessConfigurationDoesNotThrowException() {
475         DisplayManagerService displayManager =
476                 new DisplayManagerService(mContext, mShortMockedInjector);
477         Curve minimumBrightnessCurve = displayManager.getMinimumBrightnessCurveInternal();
478         float[] lux = minimumBrightnessCurve.getX();
479         float[] nits = minimumBrightnessCurve.getY();
480         BrightnessConfiguration config = new BrightnessConfiguration.Builder(lux, nits).build();
481         displayManager.validateBrightnessConfiguration(config);
482     }
483 
484     /**
485      * Tests that null brightness configurations are alright.
486      */
487     @Test
testNullBrightnessConfiguration()488     public void testNullBrightnessConfiguration() {
489         DisplayManagerService displayManager =
490                 new DisplayManagerService(mContext, mShortMockedInjector);
491         displayManager.validateBrightnessConfiguration(null);
492     }
493 
494     /**
495      * Tests that collection of display color sampling results are sensible.
496      */
497     @Test
testDisplayedContentSampling()498     public void testDisplayedContentSampling() {
499         DisplayManagerService displayManager =
500                 new DisplayManagerService(mContext, mShortMockedInjector);
501         registerDefaultDisplays(displayManager);
502 
503         DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(0);
504         assertNotNull(ddi);
505 
506         DisplayedContentSamplingAttributes attr =
507                 displayManager.getDisplayedContentSamplingAttributesInternal(0);
508         if (attr == null) return; //sampling not supported on device, skip remainder of test.
509 
510         boolean enabled = displayManager.setDisplayedContentSamplingEnabledInternal(0, true, 0, 0);
511         assertTrue(enabled);
512 
513         displayManager.setDisplayedContentSamplingEnabledInternal(0, false, 0, 0);
514         DisplayedContentSample sample = displayManager.getDisplayedContentSampleInternal(0, 0, 0);
515         assertNotNull(sample);
516 
517         long numPixels = ddi.width * ddi.height * sample.getNumFrames();
518         long[] samples = sample.getSampleComponent(DisplayedContentSample.ColorComponent.CHANNEL0);
519         assertTrue(samples.length == 0 || LongStream.of(samples).sum() == numPixels);
520 
521         samples = sample.getSampleComponent(DisplayedContentSample.ColorComponent.CHANNEL1);
522         assertTrue(samples.length == 0 || LongStream.of(samples).sum() == numPixels);
523 
524         samples = sample.getSampleComponent(DisplayedContentSample.ColorComponent.CHANNEL2);
525         assertTrue(samples.length == 0 || LongStream.of(samples).sum() == numPixels);
526 
527         samples = sample.getSampleComponent(DisplayedContentSample.ColorComponent.CHANNEL3);
528         assertTrue(samples.length == 0 || LongStream.of(samples).sum() == numPixels);
529     }
530 
531     /**
532      * Tests that the virtual display is created with
533      * {@link VirtualDisplayConfig.Builder#setDisplayIdToMirror(int)}
534      */
535     @Test
536     @FlakyTest(bugId = 127687569)
testCreateVirtualDisplay_displayIdToMirror()537     public void testCreateVirtualDisplay_displayIdToMirror() throws Exception {
538         DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
539         registerDefaultDisplays(displayManager);
540 
541         // This is effectively the DisplayManager service published to ServiceManager.
542         DisplayManagerService.BinderService binderService = displayManager.new BinderService();
543 
544         final String uniqueId = "uniqueId --- displayIdToMirrorTest";
545         final int width = 600;
546         final int height = 800;
547         final int dpi = 320;
548 
549         when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
550         final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
551                 VIRTUAL_DISPLAY_NAME, width, height, dpi);
552         builder.setUniqueId(uniqueId);
553         final int firstDisplayId = binderService.createVirtualDisplay(builder.build(),
554                 mMockAppToken /* callback */, null /* projection */, PACKAGE_NAME);
555 
556         // The second virtual display requests to mirror the first virtual display.
557         final String uniqueId2 = "uniqueId --- displayIdToMirrorTest #2";
558         when(mMockAppToken2.asBinder()).thenReturn(mMockAppToken2);
559         final VirtualDisplayConfig.Builder builder2 = new VirtualDisplayConfig.Builder(
560                 VIRTUAL_DISPLAY_NAME, width, height, dpi).setUniqueId(uniqueId2);
561         builder2.setUniqueId(uniqueId2);
562         builder2.setDisplayIdToMirror(firstDisplayId);
563         final int secondDisplayId = binderService.createVirtualDisplay(builder2.build(),
564                 mMockAppToken2 /* callback */, null /* projection */, PACKAGE_NAME);
565         displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
566 
567         // flush the handler
568         displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
569 
570         // The displayId to mirror should be a default display if there is none initially.
571         assertEquals(displayManager.getDisplayIdToMirrorInternal(firstDisplayId),
572                 Display.DEFAULT_DISPLAY);
573         assertEquals(displayManager.getDisplayIdToMirrorInternal(secondDisplayId),
574                 firstDisplayId);
575     }
576 
577     /**
578      * Tests that the virtual display is created with
579      * {@link VirtualDisplayConfig.Builder#setSurface(Surface)}
580      */
581     @Test
582     @FlakyTest(bugId = 127687569)
testCreateVirtualDisplay_setSurface()583     public void testCreateVirtualDisplay_setSurface() throws Exception {
584         DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
585         registerDefaultDisplays(displayManager);
586 
587         // This is effectively the DisplayManager service published to ServiceManager.
588         DisplayManagerService.BinderService binderService = displayManager.new BinderService();
589 
590         final String uniqueId = "uniqueId --- setSurface";
591         final int width = 600;
592         final int height = 800;
593         final int dpi = 320;
594         final Surface surface = new Surface();
595 
596         when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
597         final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
598                 VIRTUAL_DISPLAY_NAME, width, height, dpi);
599         builder.setSurface(surface);
600         builder.setUniqueId(uniqueId);
601         final int displayId = binderService.createVirtualDisplay(builder.build(),
602                 mMockAppToken /* callback */, null /* projection */, PACKAGE_NAME);
603 
604         displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
605 
606         // flush the handler
607         displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
608 
609         assertEquals(displayManager.getVirtualDisplaySurfaceInternal(mMockAppToken), surface);
610     }
611 
612     /**
613      * Tests that there is a display change notification if the frame rate override
614      * list is updated.
615      */
616     @Test
testShouldNotifyChangeWhenDisplayInfoFrameRateOverrideChanged()617     public void testShouldNotifyChangeWhenDisplayInfoFrameRateOverrideChanged() throws Exception {
618         DisplayManagerService displayManager =
619                 new DisplayManagerService(mContext, mShortMockedInjector);
620         DisplayManagerService.BinderService displayManagerBinderService =
621                 displayManager.new BinderService();
622         registerDefaultDisplays(displayManager);
623         displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
624 
625         FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, new float[]{60f});
626         FakeDisplayManagerCallback callback = registerDisplayListenerCallback(displayManager,
627                 displayManagerBinderService, displayDevice);
628 
629         int myUid = Process.myUid();
630         updateFrameRateOverride(displayManager, displayDevice,
631                 new DisplayEventReceiver.FrameRateOverride[]{
632                         new DisplayEventReceiver.FrameRateOverride(myUid, 30f),
633                 });
634         assertTrue(callback.mDisplayChangedCalled);
635         callback.clear();
636 
637         updateFrameRateOverride(displayManager, displayDevice,
638                 new DisplayEventReceiver.FrameRateOverride[]{
639                         new DisplayEventReceiver.FrameRateOverride(myUid, 30f),
640                         new DisplayEventReceiver.FrameRateOverride(1234, 30f),
641                 });
642         assertFalse(callback.mDisplayChangedCalled);
643 
644         updateFrameRateOverride(displayManager, displayDevice,
645                 new DisplayEventReceiver.FrameRateOverride[]{
646                         new DisplayEventReceiver.FrameRateOverride(myUid, 20f),
647                         new DisplayEventReceiver.FrameRateOverride(1234, 30f),
648                         new DisplayEventReceiver.FrameRateOverride(5678, 30f),
649                 });
650         assertTrue(callback.mDisplayChangedCalled);
651         callback.clear();
652 
653         updateFrameRateOverride(displayManager, displayDevice,
654                 new DisplayEventReceiver.FrameRateOverride[]{
655                         new DisplayEventReceiver.FrameRateOverride(1234, 30f),
656                         new DisplayEventReceiver.FrameRateOverride(5678, 30f),
657                 });
658         assertTrue(callback.mDisplayChangedCalled);
659         callback.clear();
660 
661         updateFrameRateOverride(displayManager, displayDevice,
662                 new DisplayEventReceiver.FrameRateOverride[]{
663                         new DisplayEventReceiver.FrameRateOverride(5678, 30f),
664                 });
665         assertFalse(callback.mDisplayChangedCalled);
666     }
667 
668     /**
669      * Tests that the DisplayInfo is updated correctly with a frame rate override
670      */
671     @Test
testDisplayInfoFrameRateOverride()672     public void testDisplayInfoFrameRateOverride() throws Exception {
673         DisplayManagerService displayManager =
674                 new DisplayManagerService(mContext, mShortMockedInjector);
675         DisplayManagerService.BinderService displayManagerBinderService =
676                 displayManager.new BinderService();
677         registerDefaultDisplays(displayManager);
678         displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
679 
680         FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager,
681                 new float[]{60f, 30f, 20f});
682         int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService,
683                 displayDevice);
684         DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId);
685         assertEquals(60f, displayInfo.getRefreshRate(), 0.01f);
686 
687         updateFrameRateOverride(displayManager, displayDevice,
688                 new DisplayEventReceiver.FrameRateOverride[]{
689                         new DisplayEventReceiver.FrameRateOverride(
690                                 Process.myUid(), 20f),
691                         new DisplayEventReceiver.FrameRateOverride(
692                                 Process.myUid() + 1, 30f)
693                 });
694         displayInfo = displayManagerBinderService.getDisplayInfo(displayId);
695         assertEquals(20f, displayInfo.getRefreshRate(), 0.01f);
696 
697         // Changing the mode to 30Hz should not override the refresh rate to 20Hz anymore
698         // as 20 is not a divider of 30.
699         updateModeId(displayManager, displayDevice, 2);
700         displayInfo = displayManagerBinderService.getDisplayInfo(displayId);
701         assertEquals(30f, displayInfo.getRefreshRate(), 0.01f);
702     }
703 
704     /**
705      * Tests that the frame rate override is updated accordingly to the
706      * allowNonNativeRefreshRateOverride policy.
707      */
708     @Test
testDisplayInfoNonNativeFrameRateOverride()709     public void testDisplayInfoNonNativeFrameRateOverride() throws Exception {
710         testDisplayInfoNonNativeFrameRateOverride(mDenyNonNativeRefreshRateOverrideInjector);
711         testDisplayInfoNonNativeFrameRateOverride(mAllowNonNativeRefreshRateOverrideInjector);
712     }
713 
714     /**
715      * Tests that the mode reflects the frame rate override is in compat mode
716      */
717     @Test
718     @DisableCompatChanges({DisplayManagerService.DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE})
testDisplayInfoFrameRateOverrideModeCompat()719     public  void testDisplayInfoFrameRateOverrideModeCompat() throws Exception {
720         testDisplayInfoFrameRateOverrideModeCompat(/*compatChangeEnabled*/ false);
721     }
722 
723     /**
724      * Tests that the mode reflects the physical display refresh rate when not in compat mode.
725      */
726     @Test
727     @EnableCompatChanges({DisplayManagerService.DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE})
testDisplayInfoFrameRateOverrideMode()728     public  void testDisplayInfoFrameRateOverrideMode() throws Exception {
729         testDisplayInfoFrameRateOverrideModeCompat(/*compatChangeEnabled*/ true);
730     }
731 
732     /**
733      * Tests that the mode reflects the frame rate override is in compat mode and accordingly to the
734      * allowNonNativeRefreshRateOverride policy.
735      */
736     @Test
737     @DisableCompatChanges({DisplayManagerService.DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE})
testDisplayInfoNonNativeFrameRateOverrideModeCompat()738     public void testDisplayInfoNonNativeFrameRateOverrideModeCompat() throws Exception {
739         testDisplayInfoNonNativeFrameRateOverrideMode(mDenyNonNativeRefreshRateOverrideInjector,
740                 /*compatChangeEnabled*/ false);
741         testDisplayInfoNonNativeFrameRateOverrideMode(mAllowNonNativeRefreshRateOverrideInjector,
742                 /*compatChangeEnabled*/  false);
743     }
744 
745     /**
746      * Tests that the mode reflects the physical display refresh rate when not in compat mode.
747      */
748     @Test
749     @EnableCompatChanges({DisplayManagerService.DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE})
testDisplayInfoNonNativeFrameRateOverrideMode()750     public void testDisplayInfoNonNativeFrameRateOverrideMode() throws Exception {
751         testDisplayInfoNonNativeFrameRateOverrideMode(mDenyNonNativeRefreshRateOverrideInjector,
752                 /*compatChangeEnabled*/  true);
753         testDisplayInfoNonNativeFrameRateOverrideMode(mAllowNonNativeRefreshRateOverrideInjector,
754                 /*compatChangeEnabled*/  true);
755     }
756 
757     /**
758      * Tests that EVENT_DISPLAY_ADDED is sent when a display is added.
759      */
760     @Test
testShouldNotifyDisplayAdded_WhenNewDisplayDeviceIsAdded()761     public void testShouldNotifyDisplayAdded_WhenNewDisplayDeviceIsAdded() {
762         DisplayManagerService displayManager =
763                 new DisplayManagerService(mContext, mShortMockedInjector);
764         DisplayManagerService.BinderService displayManagerBinderService =
765                 displayManager.new BinderService();
766 
767         Handler handler = displayManager.getDisplayHandler();
768         waitForIdleHandler(handler);
769 
770         // register display listener callback
771         FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback();
772         displayManagerBinderService.registerCallbackWithEventMask(
773                 callback, STANDARD_DISPLAY_EVENTS);
774 
775         waitForIdleHandler(handler);
776 
777         createFakeDisplayDevice(displayManager, new float[]{60f});
778 
779         waitForIdleHandler(handler);
780 
781         assertFalse(callback.mDisplayChangedCalled);
782         assertFalse(callback.mDisplayRemovedCalled);
783         assertTrue(callback.mDisplayAddedCalled);
784     }
785 
786     /**
787      * Tests that EVENT_DISPLAY_ADDED is not sent when a display is added and the
788      * client has a callback which is not subscribed to this event type.
789      */
790     @Test
testShouldNotNotifyDisplayAdded_WhenClientIsNotSubscribed()791     public void testShouldNotNotifyDisplayAdded_WhenClientIsNotSubscribed() {
792         DisplayManagerService displayManager =
793                 new DisplayManagerService(mContext, mShortMockedInjector);
794         DisplayManagerService.BinderService displayManagerBinderService =
795                 displayManager.new BinderService();
796 
797         Handler handler = displayManager.getDisplayHandler();
798         waitForIdleHandler(handler);
799 
800         // register display listener callback
801         FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback();
802         long allEventsExceptDisplayAdded = STANDARD_DISPLAY_EVENTS
803                 & ~DisplayManager.EVENT_FLAG_DISPLAY_ADDED;
804         displayManagerBinderService.registerCallbackWithEventMask(callback,
805                 allEventsExceptDisplayAdded);
806 
807         waitForIdleHandler(handler);
808 
809         createFakeDisplayDevice(displayManager, new float[]{60f});
810 
811         waitForIdleHandler(handler);
812 
813         assertFalse(callback.mDisplayChangedCalled);
814         assertFalse(callback.mDisplayRemovedCalled);
815         assertFalse(callback.mDisplayAddedCalled);
816     }
817 
818     /**
819      * Tests that EVENT_DISPLAY_REMOVED is sent when a display is removed.
820      */
821     @Test
testShouldNotifyDisplayRemoved_WhenDisplayDeviceIsRemoved()822     public void testShouldNotifyDisplayRemoved_WhenDisplayDeviceIsRemoved() {
823         DisplayManagerService displayManager =
824                 new DisplayManagerService(mContext, mShortMockedInjector);
825         DisplayManagerService.BinderService displayManagerBinderService =
826                 displayManager.new BinderService();
827 
828         Handler handler = displayManager.getDisplayHandler();
829         waitForIdleHandler(handler);
830 
831         FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager,
832                 new float[]{60f});
833 
834         waitForIdleHandler(handler);
835 
836         FakeDisplayManagerCallback callback = registerDisplayListenerCallback(
837                 displayManager, displayManagerBinderService, displayDevice);
838 
839         waitForIdleHandler(handler);
840 
841         displayManager.getDisplayDeviceRepository()
842                 .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED);
843 
844         waitForIdleHandler(handler);
845 
846         assertFalse(callback.mDisplayChangedCalled);
847         assertTrue(callback.mDisplayRemovedCalled);
848         assertFalse(callback.mDisplayAddedCalled);
849     }
850 
851     /**
852      * Tests that EVENT_DISPLAY_REMOVED is not sent when a display is added and the
853      * client has a callback which is not subscribed to this event type.
854      */
855     @Test
testShouldNotNotifyDisplayRemoved_WhenClientIsNotSubscribed()856     public void testShouldNotNotifyDisplayRemoved_WhenClientIsNotSubscribed() {
857         DisplayManagerService displayManager =
858                 new DisplayManagerService(mContext, mShortMockedInjector);
859         DisplayManagerService.BinderService displayManagerBinderService =
860                 displayManager.new BinderService();
861 
862         Handler handler = displayManager.getDisplayHandler();
863         waitForIdleHandler(handler);
864 
865         FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager,
866                 new float[]{60f});
867 
868         waitForIdleHandler(handler);
869 
870         FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback();
871         long allEventsExceptDisplayRemoved = STANDARD_DISPLAY_EVENTS
872                 & ~DisplayManager.EVENT_FLAG_DISPLAY_REMOVED;
873         displayManagerBinderService.registerCallbackWithEventMask(callback,
874                 allEventsExceptDisplayRemoved);
875 
876         waitForIdleHandler(handler);
877 
878         displayManager.getDisplayDeviceRepository()
879                 .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED);
880 
881         waitForIdleHandler(handler);
882 
883         assertFalse(callback.mDisplayChangedCalled);
884         assertFalse(callback.mDisplayRemovedCalled);
885         assertFalse(callback.mDisplayAddedCalled);
886     }
887 
testDisplayInfoFrameRateOverrideModeCompat(boolean compatChangeEnabled)888     private void testDisplayInfoFrameRateOverrideModeCompat(boolean compatChangeEnabled)
889             throws Exception {
890         DisplayManagerService displayManager =
891                 new DisplayManagerService(mContext, mShortMockedInjector);
892         DisplayManagerService.BinderService displayManagerBinderService =
893                 displayManager.new BinderService();
894         registerDefaultDisplays(displayManager);
895         displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
896 
897         FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager,
898                 new float[]{60f, 30f, 20f});
899         int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService,
900                 displayDevice);
901         DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId);
902         assertEquals(60f, displayInfo.getRefreshRate(), 0.01f);
903 
904         updateFrameRateOverride(displayManager, displayDevice,
905                 new DisplayEventReceiver.FrameRateOverride[]{
906                         new DisplayEventReceiver.FrameRateOverride(
907                                 Process.myUid(), 20f),
908                         new DisplayEventReceiver.FrameRateOverride(
909                                 Process.myUid() + 1, 30f)
910                 });
911         displayInfo = displayManagerBinderService.getDisplayInfo(displayId);
912         assertEquals(20f, displayInfo.getRefreshRate(), 0.01f);
913         Display.Mode expectedMode;
914         if (compatChangeEnabled) {
915             expectedMode = new Display.Mode(1, 100, 200, 60f);
916         } else {
917             expectedMode = new Display.Mode(3, 100, 200, 20f);
918         }
919         assertEquals(expectedMode, displayInfo.getMode());
920     }
921 
testDisplayInfoNonNativeFrameRateOverrideMode( DisplayManagerService.Injector injector, boolean compatChangeEnabled)922     private void testDisplayInfoNonNativeFrameRateOverrideMode(
923             DisplayManagerService.Injector injector, boolean compatChangeEnabled) {
924         DisplayManagerService displayManager =
925                 new DisplayManagerService(mContext, injector);
926         DisplayManagerService.BinderService displayManagerBinderService =
927                 displayManager.new BinderService();
928         registerDefaultDisplays(displayManager);
929         displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
930 
931         FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager,
932                 new float[]{60f});
933         int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService,
934                 displayDevice);
935         DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId);
936         assertEquals(60f, displayInfo.getRefreshRate(), 0.01f);
937 
938         updateFrameRateOverride(displayManager, displayDevice,
939                 new DisplayEventReceiver.FrameRateOverride[]{
940                         new DisplayEventReceiver.FrameRateOverride(
941                                 Process.myUid(), 20f)
942                 });
943         displayInfo = displayManagerBinderService.getDisplayInfo(displayId);
944         Display.Mode expectedMode;
945         if (compatChangeEnabled) {
946             expectedMode = new Display.Mode(1, 100, 200, 60f);
947         } else if (injector.getAllowNonNativeRefreshRateOverride()) {
948             expectedMode = new Display.Mode(255, 100, 200, 20f);
949         } else {
950             expectedMode = new Display.Mode(1, 100, 200, 60f);
951         }
952         assertEquals(expectedMode, displayInfo.getMode());
953     }
954 
testDisplayInfoNonNativeFrameRateOverride( DisplayManagerService.Injector injector)955     private void testDisplayInfoNonNativeFrameRateOverride(
956             DisplayManagerService.Injector injector) {
957         DisplayManagerService displayManager =
958                 new DisplayManagerService(mContext, injector);
959         DisplayManagerService.BinderService displayManagerBinderService =
960                 displayManager.new BinderService();
961         registerDefaultDisplays(displayManager);
962         displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
963 
964         FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager,
965                 new float[]{60f});
966         int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService,
967                 displayDevice);
968         DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId);
969         assertEquals(60f, displayInfo.getRefreshRate(), 0.01f);
970 
971         updateFrameRateOverride(displayManager, displayDevice,
972                 new DisplayEventReceiver.FrameRateOverride[]{
973                         new DisplayEventReceiver.FrameRateOverride(
974                                 Process.myUid(), 20f)
975                 });
976         displayInfo = displayManagerBinderService.getDisplayInfo(displayId);
977         float expectedRefreshRate = injector.getAllowNonNativeRefreshRateOverride() ? 20f : 60f;
978         assertEquals(expectedRefreshRate, displayInfo.getRefreshRate(), 0.01f);
979     }
980 
getDisplayIdForDisplayDevice( DisplayManagerService displayManager, DisplayManagerService.BinderService displayManagerBinderService, FakeDisplayDevice displayDevice)981     private int getDisplayIdForDisplayDevice(
982             DisplayManagerService displayManager,
983             DisplayManagerService.BinderService displayManagerBinderService,
984             FakeDisplayDevice displayDevice) {
985 
986         final int[] displayIds = displayManagerBinderService.getDisplayIds();
987         assertTrue(displayIds.length > 0);
988         int displayId = Display.INVALID_DISPLAY;
989         for (int i = 0; i < displayIds.length; i++) {
990             DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayIds[i]);
991             if (displayDevice.getDisplayDeviceInfoLocked().equals(ddi)) {
992                 displayId = displayIds[i];
993                 break;
994             }
995         }
996         assertFalse(displayId == Display.INVALID_DISPLAY);
997         return displayId;
998     }
999 
updateDisplayDeviceInfo(DisplayManagerService displayManager, FakeDisplayDevice displayDevice, DisplayDeviceInfo displayDeviceInfo)1000     private void updateDisplayDeviceInfo(DisplayManagerService displayManager,
1001             FakeDisplayDevice displayDevice,
1002             DisplayDeviceInfo displayDeviceInfo) {
1003         displayDevice.setDisplayDeviceInfo(displayDeviceInfo);
1004         displayManager.getDisplayDeviceRepository()
1005                 .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED);
1006         Handler handler = displayManager.getDisplayHandler();
1007         waitForIdleHandler(handler);
1008     }
1009 
updateFrameRateOverride(DisplayManagerService displayManager, FakeDisplayDevice displayDevice, DisplayEventReceiver.FrameRateOverride[] frameRateOverrides)1010     private void updateFrameRateOverride(DisplayManagerService displayManager,
1011             FakeDisplayDevice displayDevice,
1012             DisplayEventReceiver.FrameRateOverride[] frameRateOverrides) {
1013         DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo();
1014         displayDeviceInfo.copyFrom(displayDevice.getDisplayDeviceInfoLocked());
1015         displayDeviceInfo.frameRateOverrides = frameRateOverrides;
1016         updateDisplayDeviceInfo(displayManager, displayDevice, displayDeviceInfo);
1017     }
1018 
updateModeId(DisplayManagerService displayManager, FakeDisplayDevice displayDevice, int modeId)1019     private void updateModeId(DisplayManagerService displayManager,
1020             FakeDisplayDevice displayDevice,
1021             int modeId) {
1022         DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo();
1023         displayDeviceInfo.copyFrom(displayDevice.getDisplayDeviceInfoLocked());
1024         displayDeviceInfo.modeId = modeId;
1025         updateDisplayDeviceInfo(displayManager, displayDevice, displayDeviceInfo);
1026     }
1027 
registerDisplayListenerCallback( DisplayManagerService displayManager, DisplayManagerService.BinderService displayManagerBinderService, FakeDisplayDevice displayDevice)1028     private FakeDisplayManagerCallback registerDisplayListenerCallback(
1029             DisplayManagerService displayManager,
1030             DisplayManagerService.BinderService displayManagerBinderService,
1031             FakeDisplayDevice displayDevice) {
1032         // Find the display id of the added FakeDisplayDevice
1033         int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService,
1034                 displayDevice);
1035 
1036         Handler handler = displayManager.getDisplayHandler();
1037         waitForIdleHandler(handler);
1038 
1039         // register display listener callback
1040         FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(displayId);
1041         displayManagerBinderService.registerCallbackWithEventMask(
1042                 callback, STANDARD_DISPLAY_EVENTS);
1043         return callback;
1044     }
1045 
createFakeDisplayDevice(DisplayManagerService displayManager, float[] refreshRates)1046     private FakeDisplayDevice createFakeDisplayDevice(DisplayManagerService displayManager,
1047             float[] refreshRates) {
1048         FakeDisplayDevice displayDevice = new FakeDisplayDevice();
1049         DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo();
1050         int width = 100;
1051         int height = 200;
1052         displayDeviceInfo.supportedModes = new Display.Mode[refreshRates.length];
1053         for (int i = 0; i < refreshRates.length; i++) {
1054             displayDeviceInfo.supportedModes[i] =
1055                     new Display.Mode(i + 1, width, height, refreshRates[i]);
1056         }
1057         displayDeviceInfo.modeId = 1;
1058         displayDeviceInfo.width = width;
1059         displayDeviceInfo.height = height;
1060         final Rect zeroRect = new Rect();
1061         displayDeviceInfo.displayCutout = new DisplayCutout(
1062                 Insets.of(0, 10, 0, 0),
1063                 zeroRect, new Rect(0, 0, 10, 10), zeroRect, zeroRect);
1064         displayDeviceInfo.flags = DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY;
1065         displayDevice.setDisplayDeviceInfo(displayDeviceInfo);
1066         displayManager.getDisplayDeviceRepository()
1067                 .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED);
1068         return displayDevice;
1069     }
1070 
registerDefaultDisplays(DisplayManagerService displayManager)1071     private void registerDefaultDisplays(DisplayManagerService displayManager) {
1072         Handler handler = displayManager.getDisplayHandler();
1073         // Would prefer to call displayManager.onStart() directly here but it performs binderService
1074         // registration which triggers security exceptions when running from a test.
1075         handler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);
1076         waitForIdleHandler(handler);
1077     }
1078 
waitForIdleHandler(Handler handler)1079     private void waitForIdleHandler(Handler handler) {
1080         waitForIdleHandler(handler, Duration.ofSeconds(1));
1081     }
1082 
waitForIdleHandler(Handler handler, Duration timeout)1083     private void waitForIdleHandler(Handler handler, Duration timeout) {
1084         final MessageQueue queue = handler.getLooper().getQueue();
1085         final CountDownLatch latch = new CountDownLatch(1);
1086         queue.addIdleHandler(() -> {
1087             latch.countDown();
1088             // Remove idle handler
1089             return false;
1090         });
1091         try {
1092             latch.await(timeout.toMillis(), TimeUnit.MILLISECONDS);
1093         } catch (InterruptedException e) {
1094             fail("Interrupted unexpectedly: " + e);
1095         }
1096     }
1097 
1098     private class FakeDisplayManagerCallback extends IDisplayManagerCallback.Stub {
1099         int mDisplayId;
1100         boolean mDisplayAddedCalled = false;
1101         boolean mDisplayChangedCalled = false;
1102         boolean mDisplayRemovedCalled = false;
1103 
FakeDisplayManagerCallback(int displayId)1104         FakeDisplayManagerCallback(int displayId) {
1105             mDisplayId = displayId;
1106         }
1107 
FakeDisplayManagerCallback()1108         FakeDisplayManagerCallback() {
1109             mDisplayId = -1;
1110         }
1111 
1112         @Override
onDisplayEvent(int displayId, int event)1113         public void onDisplayEvent(int displayId, int event) {
1114             if (mDisplayId != -1 && displayId != mDisplayId) {
1115                 return;
1116             }
1117 
1118             if (event == DisplayManagerGlobal.EVENT_DISPLAY_ADDED) {
1119                 mDisplayAddedCalled = true;
1120             }
1121 
1122             if (event == DisplayManagerGlobal.EVENT_DISPLAY_CHANGED) {
1123                 mDisplayChangedCalled = true;
1124             }
1125 
1126             if (event == DisplayManagerGlobal.EVENT_DISPLAY_REMOVED) {
1127                 mDisplayRemovedCalled = true;
1128             }
1129         }
1130 
clear()1131         public void clear() {
1132             mDisplayAddedCalled = false;
1133             mDisplayChangedCalled = false;
1134             mDisplayRemovedCalled = false;
1135         }
1136     }
1137 
1138     private class FakeDisplayDevice extends DisplayDevice {
1139         private DisplayDeviceInfo mDisplayDeviceInfo;
1140 
FakeDisplayDevice()1141         FakeDisplayDevice() {
1142             super(null, null, "", mContext);
1143         }
1144 
setDisplayDeviceInfo(DisplayDeviceInfo displayDeviceInfo)1145         public void setDisplayDeviceInfo(DisplayDeviceInfo displayDeviceInfo) {
1146             mDisplayDeviceInfo = displayDeviceInfo;
1147         }
1148 
1149         @Override
hasStableUniqueId()1150         public boolean hasStableUniqueId() {
1151             return false;
1152         }
1153 
1154         @Override
getDisplayDeviceInfoLocked()1155         public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
1156             return mDisplayDeviceInfo;
1157         }
1158     }
1159 }
1160