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 
888 
889 
890     @Test
testSettingTwoBrightnessConfigurationsOnMultiDisplay()891     public void testSettingTwoBrightnessConfigurationsOnMultiDisplay() {
892         Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
893         DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
894 
895         // get the first two internal displays
896         Display[] displays = displayManager.getDisplays();
897         Display internalDisplayOne = null;
898         Display internalDisplayTwo = null;
899         for (Display display : displays) {
900             if (display.getType() == Display.TYPE_INTERNAL) {
901                 if (internalDisplayOne == null) {
902                     internalDisplayOne = display;
903                 } else {
904                     internalDisplayTwo = display;
905                     break;
906                 }
907             }
908         }
909 
910         // return if there are fewer than 2 displays on this device
911         if (internalDisplayOne == null || internalDisplayTwo == null) {
912             return;
913         }
914 
915         final String uniqueDisplayIdOne = internalDisplayOne.getUniqueId();
916         final String uniqueDisplayIdTwo = internalDisplayTwo.getUniqueId();
917 
918         BrightnessConfiguration configOne =
919                 new BrightnessConfiguration.Builder(
920                         new float[]{0.0f, 12345.0f}, new float[]{15.0f, 400.0f})
921                         .setDescription("model:1").build();
922         BrightnessConfiguration configTwo =
923                 new BrightnessConfiguration.Builder(
924                         new float[]{0.0f, 6789.0f}, new float[]{12.0f, 300.0f})
925                         .setDescription("model:2").build();
926 
927         displayManager.setBrightnessConfigurationForDisplay(configOne,
928                 uniqueDisplayIdOne);
929         displayManager.setBrightnessConfigurationForDisplay(configTwo,
930                 uniqueDisplayIdTwo);
931 
932         BrightnessConfiguration configFromOne =
933                 displayManager.getBrightnessConfigurationForDisplay(uniqueDisplayIdOne);
934         BrightnessConfiguration configFromTwo =
935                 displayManager.getBrightnessConfigurationForDisplay(uniqueDisplayIdTwo);
936 
937         assertNotNull(configFromOne);
938         assertEquals(configOne, configFromOne);
939         assertEquals(configTwo, configFromTwo);
940 
941     }
942 
testDisplayInfoFrameRateOverrideModeCompat(boolean compatChangeEnabled)943     private void testDisplayInfoFrameRateOverrideModeCompat(boolean compatChangeEnabled)
944             throws Exception {
945         DisplayManagerService displayManager =
946                 new DisplayManagerService(mContext, mShortMockedInjector);
947         DisplayManagerService.BinderService displayManagerBinderService =
948                 displayManager.new BinderService();
949         registerDefaultDisplays(displayManager);
950         displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
951 
952         FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager,
953                 new float[]{60f, 30f, 20f});
954         int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService,
955                 displayDevice);
956         DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId);
957         assertEquals(60f, displayInfo.getRefreshRate(), 0.01f);
958 
959         updateFrameRateOverride(displayManager, displayDevice,
960                 new DisplayEventReceiver.FrameRateOverride[]{
961                         new DisplayEventReceiver.FrameRateOverride(
962                                 Process.myUid(), 20f),
963                         new DisplayEventReceiver.FrameRateOverride(
964                                 Process.myUid() + 1, 30f)
965                 });
966         displayInfo = displayManagerBinderService.getDisplayInfo(displayId);
967         assertEquals(20f, displayInfo.getRefreshRate(), 0.01f);
968         Display.Mode expectedMode;
969         if (compatChangeEnabled) {
970             expectedMode = new Display.Mode(1, 100, 200, 60f);
971         } else {
972             expectedMode = new Display.Mode(3, 100, 200, 20f);
973         }
974         assertEquals(expectedMode, displayInfo.getMode());
975     }
976 
testDisplayInfoNonNativeFrameRateOverrideMode( DisplayManagerService.Injector injector, boolean compatChangeEnabled)977     private void testDisplayInfoNonNativeFrameRateOverrideMode(
978             DisplayManagerService.Injector injector, boolean compatChangeEnabled) {
979         DisplayManagerService displayManager =
980                 new DisplayManagerService(mContext, injector);
981         DisplayManagerService.BinderService displayManagerBinderService =
982                 displayManager.new BinderService();
983         registerDefaultDisplays(displayManager);
984         displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
985 
986         FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager,
987                 new float[]{60f});
988         int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService,
989                 displayDevice);
990         DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId);
991         assertEquals(60f, displayInfo.getRefreshRate(), 0.01f);
992 
993         updateFrameRateOverride(displayManager, displayDevice,
994                 new DisplayEventReceiver.FrameRateOverride[]{
995                         new DisplayEventReceiver.FrameRateOverride(
996                                 Process.myUid(), 20f)
997                 });
998         displayInfo = displayManagerBinderService.getDisplayInfo(displayId);
999         Display.Mode expectedMode;
1000         if (compatChangeEnabled) {
1001             expectedMode = new Display.Mode(1, 100, 200, 60f);
1002         } else if (injector.getAllowNonNativeRefreshRateOverride()) {
1003             expectedMode = new Display.Mode(255, 100, 200, 20f);
1004         } else {
1005             expectedMode = new Display.Mode(1, 100, 200, 60f);
1006         }
1007         assertEquals(expectedMode, displayInfo.getMode());
1008     }
1009 
testDisplayInfoNonNativeFrameRateOverride( DisplayManagerService.Injector injector)1010     private void testDisplayInfoNonNativeFrameRateOverride(
1011             DisplayManagerService.Injector injector) {
1012         DisplayManagerService displayManager =
1013                 new DisplayManagerService(mContext, injector);
1014         DisplayManagerService.BinderService displayManagerBinderService =
1015                 displayManager.new BinderService();
1016         registerDefaultDisplays(displayManager);
1017         displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
1018 
1019         FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager,
1020                 new float[]{60f});
1021         int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService,
1022                 displayDevice);
1023         DisplayInfo displayInfo = displayManagerBinderService.getDisplayInfo(displayId);
1024         assertEquals(60f, displayInfo.getRefreshRate(), 0.01f);
1025 
1026         updateFrameRateOverride(displayManager, displayDevice,
1027                 new DisplayEventReceiver.FrameRateOverride[]{
1028                         new DisplayEventReceiver.FrameRateOverride(
1029                                 Process.myUid(), 20f)
1030                 });
1031         displayInfo = displayManagerBinderService.getDisplayInfo(displayId);
1032         float expectedRefreshRate = injector.getAllowNonNativeRefreshRateOverride() ? 20f : 60f;
1033         assertEquals(expectedRefreshRate, displayInfo.getRefreshRate(), 0.01f);
1034     }
1035 
getDisplayIdForDisplayDevice( DisplayManagerService displayManager, DisplayManagerService.BinderService displayManagerBinderService, FakeDisplayDevice displayDevice)1036     private int getDisplayIdForDisplayDevice(
1037             DisplayManagerService displayManager,
1038             DisplayManagerService.BinderService displayManagerBinderService,
1039             FakeDisplayDevice displayDevice) {
1040 
1041         final int[] displayIds = displayManagerBinderService.getDisplayIds();
1042         assertTrue(displayIds.length > 0);
1043         int displayId = Display.INVALID_DISPLAY;
1044         for (int i = 0; i < displayIds.length; i++) {
1045             DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayIds[i]);
1046             if (displayDevice.getDisplayDeviceInfoLocked().equals(ddi)) {
1047                 displayId = displayIds[i];
1048                 break;
1049             }
1050         }
1051         assertFalse(displayId == Display.INVALID_DISPLAY);
1052         return displayId;
1053     }
1054 
updateDisplayDeviceInfo(DisplayManagerService displayManager, FakeDisplayDevice displayDevice, DisplayDeviceInfo displayDeviceInfo)1055     private void updateDisplayDeviceInfo(DisplayManagerService displayManager,
1056             FakeDisplayDevice displayDevice,
1057             DisplayDeviceInfo displayDeviceInfo) {
1058         displayDevice.setDisplayDeviceInfo(displayDeviceInfo);
1059         displayManager.getDisplayDeviceRepository()
1060                 .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED);
1061         Handler handler = displayManager.getDisplayHandler();
1062         waitForIdleHandler(handler);
1063     }
1064 
updateFrameRateOverride(DisplayManagerService displayManager, FakeDisplayDevice displayDevice, DisplayEventReceiver.FrameRateOverride[] frameRateOverrides)1065     private void updateFrameRateOverride(DisplayManagerService displayManager,
1066             FakeDisplayDevice displayDevice,
1067             DisplayEventReceiver.FrameRateOverride[] frameRateOverrides) {
1068         DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo();
1069         displayDeviceInfo.copyFrom(displayDevice.getDisplayDeviceInfoLocked());
1070         displayDeviceInfo.frameRateOverrides = frameRateOverrides;
1071         updateDisplayDeviceInfo(displayManager, displayDevice, displayDeviceInfo);
1072     }
1073 
updateModeId(DisplayManagerService displayManager, FakeDisplayDevice displayDevice, int modeId)1074     private void updateModeId(DisplayManagerService displayManager,
1075             FakeDisplayDevice displayDevice,
1076             int modeId) {
1077         DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo();
1078         displayDeviceInfo.copyFrom(displayDevice.getDisplayDeviceInfoLocked());
1079         displayDeviceInfo.modeId = modeId;
1080         updateDisplayDeviceInfo(displayManager, displayDevice, displayDeviceInfo);
1081     }
1082 
registerDisplayListenerCallback( DisplayManagerService displayManager, DisplayManagerService.BinderService displayManagerBinderService, FakeDisplayDevice displayDevice)1083     private FakeDisplayManagerCallback registerDisplayListenerCallback(
1084             DisplayManagerService displayManager,
1085             DisplayManagerService.BinderService displayManagerBinderService,
1086             FakeDisplayDevice displayDevice) {
1087         // Find the display id of the added FakeDisplayDevice
1088         int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService,
1089                 displayDevice);
1090 
1091         Handler handler = displayManager.getDisplayHandler();
1092         waitForIdleHandler(handler);
1093 
1094         // register display listener callback
1095         FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(displayId);
1096         displayManagerBinderService.registerCallbackWithEventMask(
1097                 callback, STANDARD_DISPLAY_EVENTS);
1098         return callback;
1099     }
1100 
createFakeDisplayDevice(DisplayManagerService displayManager, float[] refreshRates)1101     private FakeDisplayDevice createFakeDisplayDevice(DisplayManagerService displayManager,
1102             float[] refreshRates) {
1103         FakeDisplayDevice displayDevice = new FakeDisplayDevice();
1104         DisplayDeviceInfo displayDeviceInfo = new DisplayDeviceInfo();
1105         int width = 100;
1106         int height = 200;
1107         displayDeviceInfo.supportedModes = new Display.Mode[refreshRates.length];
1108         for (int i = 0; i < refreshRates.length; i++) {
1109             displayDeviceInfo.supportedModes[i] =
1110                     new Display.Mode(i + 1, width, height, refreshRates[i]);
1111         }
1112         displayDeviceInfo.modeId = 1;
1113         displayDeviceInfo.width = width;
1114         displayDeviceInfo.height = height;
1115         final Rect zeroRect = new Rect();
1116         displayDeviceInfo.displayCutout = new DisplayCutout(
1117                 Insets.of(0, 10, 0, 0),
1118                 zeroRect, new Rect(0, 0, 10, 10), zeroRect, zeroRect);
1119         displayDeviceInfo.flags = DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY;
1120         displayDevice.setDisplayDeviceInfo(displayDeviceInfo);
1121         displayManager.getDisplayDeviceRepository()
1122                 .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED);
1123         return displayDevice;
1124     }
1125 
registerDefaultDisplays(DisplayManagerService displayManager)1126     private void registerDefaultDisplays(DisplayManagerService displayManager) {
1127         Handler handler = displayManager.getDisplayHandler();
1128         // Would prefer to call displayManager.onStart() directly here but it performs binderService
1129         // registration which triggers security exceptions when running from a test.
1130         handler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);
1131         waitForIdleHandler(handler);
1132     }
1133 
waitForIdleHandler(Handler handler)1134     private void waitForIdleHandler(Handler handler) {
1135         waitForIdleHandler(handler, Duration.ofSeconds(1));
1136     }
1137 
waitForIdleHandler(Handler handler, Duration timeout)1138     private void waitForIdleHandler(Handler handler, Duration timeout) {
1139         final MessageQueue queue = handler.getLooper().getQueue();
1140         final CountDownLatch latch = new CountDownLatch(1);
1141         queue.addIdleHandler(() -> {
1142             latch.countDown();
1143             // Remove idle handler
1144             return false;
1145         });
1146         try {
1147             latch.await(timeout.toMillis(), TimeUnit.MILLISECONDS);
1148         } catch (InterruptedException e) {
1149             fail("Interrupted unexpectedly: " + e);
1150         }
1151     }
1152 
1153     private class FakeDisplayManagerCallback extends IDisplayManagerCallback.Stub {
1154         int mDisplayId;
1155         boolean mDisplayAddedCalled = false;
1156         boolean mDisplayChangedCalled = false;
1157         boolean mDisplayRemovedCalled = false;
1158 
FakeDisplayManagerCallback(int displayId)1159         FakeDisplayManagerCallback(int displayId) {
1160             mDisplayId = displayId;
1161         }
1162 
FakeDisplayManagerCallback()1163         FakeDisplayManagerCallback() {
1164             mDisplayId = -1;
1165         }
1166 
1167         @Override
onDisplayEvent(int displayId, int event)1168         public void onDisplayEvent(int displayId, int event) {
1169             if (mDisplayId != -1 && displayId != mDisplayId) {
1170                 return;
1171             }
1172 
1173             if (event == DisplayManagerGlobal.EVENT_DISPLAY_ADDED) {
1174                 mDisplayAddedCalled = true;
1175             }
1176 
1177             if (event == DisplayManagerGlobal.EVENT_DISPLAY_CHANGED) {
1178                 mDisplayChangedCalled = true;
1179             }
1180 
1181             if (event == DisplayManagerGlobal.EVENT_DISPLAY_REMOVED) {
1182                 mDisplayRemovedCalled = true;
1183             }
1184         }
1185 
clear()1186         public void clear() {
1187             mDisplayAddedCalled = false;
1188             mDisplayChangedCalled = false;
1189             mDisplayRemovedCalled = false;
1190         }
1191     }
1192 
1193     private class FakeDisplayDevice extends DisplayDevice {
1194         private DisplayDeviceInfo mDisplayDeviceInfo;
1195 
FakeDisplayDevice()1196         FakeDisplayDevice() {
1197             super(null, null, "", mContext);
1198         }
1199 
setDisplayDeviceInfo(DisplayDeviceInfo displayDeviceInfo)1200         public void setDisplayDeviceInfo(DisplayDeviceInfo displayDeviceInfo) {
1201             mDisplayDeviceInfo = displayDeviceInfo;
1202         }
1203 
1204         @Override
hasStableUniqueId()1205         public boolean hasStableUniqueId() {
1206             return false;
1207         }
1208 
1209         @Override
getDisplayDeviceInfoLocked()1210         public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
1211             return mDisplayDeviceInfo;
1212         }
1213     }
1214 }
1215