1ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon/*
2ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon * Copyright (C) 2017 The Android Open Source Project
3ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon *
4ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon * Licensed under the Apache License, Version 2.0 (the "License");
5ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon * you may not use this file except in compliance with the License.
6ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon * You may obtain a copy of the License at
7ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon *
8ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon *      http://www.apache.org/licenses/LICENSE-2.0
9ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon *
10ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon * Unless required by applicable law or agreed to in writing, software
11ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon * distributed under the License is distributed on an "AS IS" BASIS,
12ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon * See the License for the specific language governing permissions and
14ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon * limitations under the License
15ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon */
16ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon
17ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordonpackage com.android.server.display;
18ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon
19ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordonimport android.content.Context;
20122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittikimport android.hardware.display.BrightnessConfiguration;
21122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittikimport android.hardware.display.Curve;
22ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordonimport android.hardware.display.DisplayManager;
23ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordonimport android.hardware.display.DisplayViewport;
24ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordonimport android.hardware.display.IVirtualDisplayCallback;
25ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordonimport android.hardware.input.InputManagerInternal;
26ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordonimport android.os.Handler;
27ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordonimport android.os.IBinder;
28122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittikimport android.os.UserHandle;
29ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordonimport android.test.AndroidTestCase;
30ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordonimport android.test.suitebuilder.annotation.SmallTest;
31ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordonimport android.view.SurfaceControl;
32ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon
33ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordonimport com.android.server.LocalServices;
34c22c56397636729b3717c3935816b88dc72fac26Santos Cordonimport com.android.server.SystemService;
35879d24f4237f5c9c6def64087845578513711386Alex Sakhartchoukimport com.android.server.display.DisplayDeviceInfo;
36ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordonimport com.android.server.display.DisplayManagerService.SyncRoot;
37ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordonimport com.android.server.display.VirtualDisplayAdapter.SurfaceControlDisplayFactory;
38c22c56397636729b3717c3935816b88dc72fac26Santos Cordonimport com.android.server.lights.LightsManager;
39e99bc0501a288735d337f2ff64f8fa47f766a59bAdrian Roosimport com.android.server.wm.WindowManagerInternal;
40ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon
41ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordonimport org.mockito.ArgumentCaptor;
42ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordonimport org.mockito.Mock;
43ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordonimport org.mockito.MockitoAnnotations;
44ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon
45ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordonimport java.util.List;
46ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon
47ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordonimport static org.mockito.Matchers.any;
48ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordonimport static org.mockito.Mockito.verify;
49ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordonimport static org.mockito.Mockito.when;
50ae606b44578419b70fdc346525905778528fb7f6Robert Carrimport static org.mockito.Mockito.mock;
51ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon
52ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon@SmallTest
53ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordonpublic class DisplayManagerServiceTest extends AndroidTestCase {
54c22c56397636729b3717c3935816b88dc72fac26Santos Cordon    private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1;
55c22c56397636729b3717c3935816b88dc72fac26Santos Cordon    private static final long SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS = 10;
56c22c56397636729b3717c3935816b88dc72fac26Santos Cordon
57c22c56397636729b3717c3935816b88dc72fac26Santos Cordon    private final DisplayManagerService.Injector mShortMockedInjector =
58c22c56397636729b3717c3935816b88dc72fac26Santos Cordon            new DisplayManagerService.Injector() {
59c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                @Override
60c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot,
61c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                        Context context, Handler handler, DisplayAdapter.Listener listener) {
62c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                    return mMockVirtualDisplayAdapter;
63c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                }
64c22c56397636729b3717c3935816b88dc72fac26Santos Cordon
65c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                @Override
66c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                long getDefaultDisplayDelayTimeout() {
67c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                    return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS;
68c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                }
69c22c56397636729b3717c3935816b88dc72fac26Santos Cordon            };
70c22c56397636729b3717c3935816b88dc72fac26Santos Cordon    private final DisplayManagerService.Injector mBasicInjector =
71c22c56397636729b3717c3935816b88dc72fac26Santos Cordon            new DisplayManagerService.Injector() {
72c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                @Override
73c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot,
74c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                        Context context, Handler handler,
75c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                        DisplayAdapter.Listener displayAdapterListener) {
76c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                    return new VirtualDisplayAdapter(syncRoot, context, handler,
77c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                            displayAdapterListener,
78c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                            (String name, boolean secure) -> mMockDisplayToken);
79c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                }
80c22c56397636729b3717c3935816b88dc72fac26Santos Cordon            };
81c22c56397636729b3717c3935816b88dc72fac26Santos Cordon
82ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon    @Mock InputManagerInternal mMockInputManagerInternal;
83ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon    @Mock IVirtualDisplayCallback.Stub mMockAppToken;
84ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon    @Mock WindowManagerInternal mMockWindowManagerInternal;
85c22c56397636729b3717c3935816b88dc72fac26Santos Cordon    @Mock LightsManager mMockLightsManager;
86ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon    @Mock VirtualDisplayAdapter mMockVirtualDisplayAdapter;
87ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon    @Mock IBinder mMockDisplayToken;
88ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon
89ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon    @Override
90ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon    protected void setUp() throws Exception {
91ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        MockitoAnnotations.initMocks(this);
92ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon
93ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        LocalServices.removeServiceForTest(InputManagerInternal.class);
94ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        LocalServices.addService(InputManagerInternal.class, mMockInputManagerInternal);
95ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        LocalServices.removeServiceForTest(WindowManagerInternal.class);
96ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        LocalServices.addService(WindowManagerInternal.class, mMockWindowManagerInternal);
97c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        LocalServices.removeServiceForTest(LightsManager.class);
98c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        LocalServices.addService(LightsManager.class, mMockLightsManager);
99ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        super.setUp();
100ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon    }
101ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon
102ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon    @Override
103ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon    protected void tearDown() throws Exception {
104ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        super.tearDown();
105ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon    }
106ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon
107ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon    public void testCreateVirtualDisplay_sentToInputManager() throws Exception {
108c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        DisplayManagerService displayManager =
109c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                new DisplayManagerService(mContext, mBasicInjector);
110c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        registerDefaultDisplays(displayManager);
111c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        displayManager.systemReady(false /* safeMode */, true /* onlyCore */);
112c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        displayManager.windowManagerAndInputReady();
113c22c56397636729b3717c3935816b88dc72fac26Santos Cordon
114ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        // This is effectively the DisplayManager service published to ServiceManager.
115c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        DisplayManagerService.BinderService bs = displayManager.new BinderService();
116ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon
117ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        String uniqueId = "uniqueId --- Test";
118ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        String uniqueIdPrefix = "virtual:" + mContext.getPackageName() + ":";
119ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        int width = 600;
120ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        int height = 800;
121ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        int dpi = 320;
122ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH;
123ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon
124ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
125ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        int displayId = bs.createVirtualDisplay(mMockAppToken /* callback */,
126ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon                null /* projection */, "com.android.frameworks.servicestests",
127ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon                "Test Virtual Display", width, height, dpi, null /* surface */, flags /* flags */,
128ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon                uniqueId);
129ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon
130ae606b44578419b70fdc346525905778528fb7f6Robert Carr        displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
131ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon
132ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        // flush the handler
133c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
134ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon
135ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        ArgumentCaptor<List<DisplayViewport>> virtualViewportCaptor =
136ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon                ArgumentCaptor.forClass(List.class);
137ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        verify(mMockInputManagerInternal).setDisplayViewports(
138ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon                any(), any(), virtualViewportCaptor.capture());
139ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon
140ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        assertEquals(1, virtualViewportCaptor.getValue().size());
141ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        DisplayViewport dv = virtualViewportCaptor.getValue().get(0);
142ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        assertEquals(height, dv.deviceHeight);
143ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        assertEquals(width, dv.deviceWidth);
144ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        assertEquals(uniqueIdPrefix + uniqueId, dv.uniqueId);
145ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon        assertEquals(displayId, dv.displayId);
146ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon    }
147879d24f4237f5c9c6def64087845578513711386Alex Sakhartchouk
148879d24f4237f5c9c6def64087845578513711386Alex Sakhartchouk    public void testCreateVirtualDisplayRotatesWithContent() throws Exception {
149c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        DisplayManagerService displayManager =
150c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                new DisplayManagerService(mContext, mBasicInjector);
151c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        registerDefaultDisplays(displayManager);
152c22c56397636729b3717c3935816b88dc72fac26Santos Cordon
153879d24f4237f5c9c6def64087845578513711386Alex Sakhartchouk        // This is effectively the DisplayManager service published to ServiceManager.
154c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        DisplayManagerService.BinderService bs = displayManager.new BinderService();
155879d24f4237f5c9c6def64087845578513711386Alex Sakhartchouk
156879d24f4237f5c9c6def64087845578513711386Alex Sakhartchouk        String uniqueId = "uniqueId --- Rotates With Content Test";
157879d24f4237f5c9c6def64087845578513711386Alex Sakhartchouk        int width = 600;
158879d24f4237f5c9c6def64087845578513711386Alex Sakhartchouk        int height = 800;
159879d24f4237f5c9c6def64087845578513711386Alex Sakhartchouk        int dpi = 320;
160879d24f4237f5c9c6def64087845578513711386Alex Sakhartchouk        int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
161879d24f4237f5c9c6def64087845578513711386Alex Sakhartchouk
162879d24f4237f5c9c6def64087845578513711386Alex Sakhartchouk        when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
163879d24f4237f5c9c6def64087845578513711386Alex Sakhartchouk        int displayId = bs.createVirtualDisplay(mMockAppToken /* callback */,
164879d24f4237f5c9c6def64087845578513711386Alex Sakhartchouk                null /* projection */, "com.android.frameworks.servicestests",
165879d24f4237f5c9c6def64087845578513711386Alex Sakhartchouk                "Test Virtual Display", width, height, dpi, null /* surface */, flags /* flags */,
166879d24f4237f5c9c6def64087845578513711386Alex Sakhartchouk                uniqueId);
167879d24f4237f5c9c6def64087845578513711386Alex Sakhartchouk
168ae606b44578419b70fdc346525905778528fb7f6Robert Carr        displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
169879d24f4237f5c9c6def64087845578513711386Alex Sakhartchouk
170879d24f4237f5c9c6def64087845578513711386Alex Sakhartchouk        // flush the handler
171c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
172879d24f4237f5c9c6def64087845578513711386Alex Sakhartchouk
173c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId);
174879d24f4237f5c9c6def64087845578513711386Alex Sakhartchouk        assertNotNull(ddi);
175879d24f4237f5c9c6def64087845578513711386Alex Sakhartchouk        assertTrue((ddi.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0);
176879d24f4237f5c9c6def64087845578513711386Alex Sakhartchouk    }
177c22c56397636729b3717c3935816b88dc72fac26Santos Cordon
178c22c56397636729b3717c3935816b88dc72fac26Santos Cordon    /**
179c22c56397636729b3717c3935816b88dc72fac26Santos Cordon     * Tests that the virtual display is created along-side the default display.
180c22c56397636729b3717c3935816b88dc72fac26Santos Cordon     */
181c22c56397636729b3717c3935816b88dc72fac26Santos Cordon    public void testStartVirtualDisplayWithDefaultDisplay_Succeeds() throws Exception {
182c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        DisplayManagerService displayManager =
183c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                new DisplayManagerService(mContext, mShortMockedInjector);
184c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        registerDefaultDisplays(displayManager);
185c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
186c22c56397636729b3717c3935816b88dc72fac26Santos Cordon    }
187c22c56397636729b3717c3935816b88dc72fac26Santos Cordon
188c22c56397636729b3717c3935816b88dc72fac26Santos Cordon    /**
189c22c56397636729b3717c3935816b88dc72fac26Santos Cordon     * Tests that we get a Runtime exception when we cannot initialize the default display.
190c22c56397636729b3717c3935816b88dc72fac26Santos Cordon     */
191c22c56397636729b3717c3935816b88dc72fac26Santos Cordon    public void testStartVirtualDisplayWithDefDisplay_NoDefaultDisplay() throws Exception {
192c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        DisplayManagerService displayManager =
193c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                new DisplayManagerService(mContext, mShortMockedInjector);
194c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        Handler handler = displayManager.getDisplayHandler();
195c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        handler.runWithScissors(() -> {}, 0 /* now */);
196c22c56397636729b3717c3935816b88dc72fac26Santos Cordon
197c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        try {
198c22c56397636729b3717c3935816b88dc72fac26Santos Cordon            displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
199c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        } catch (RuntimeException e) {
200c22c56397636729b3717c3935816b88dc72fac26Santos Cordon            return;
201c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        }
202c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        fail("Expected DisplayManager to throw RuntimeException when it cannot initialize the"
203c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                + " default display");
204c22c56397636729b3717c3935816b88dc72fac26Santos Cordon    }
205c22c56397636729b3717c3935816b88dc72fac26Santos Cordon
206c22c56397636729b3717c3935816b88dc72fac26Santos Cordon    /**
207c22c56397636729b3717c3935816b88dc72fac26Santos Cordon     * Tests that we get a Runtime exception when we cannot initialize the virtual display.
208c22c56397636729b3717c3935816b88dc72fac26Santos Cordon     */
209c22c56397636729b3717c3935816b88dc72fac26Santos Cordon    public void testStartVirtualDisplayWithDefDisplay_NoVirtualDisplayAdapter() throws Exception {
210c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        DisplayManagerService displayManager = new DisplayManagerService(mContext,
211c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                new DisplayManagerService.Injector() {
212c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                    @Override
213c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                    VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot,
214c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                            Context context, Handler handler, DisplayAdapter.Listener listener) {
215c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                        return null;  // return null for the adapter.  This should cause a failure.
216c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                    }
217c22c56397636729b3717c3935816b88dc72fac26Santos Cordon
218c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                    @Override
219c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                    long getDefaultDisplayDelayTimeout() {
220c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                        return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS;
221c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                    }
222c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                });
223c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        try {
224c22c56397636729b3717c3935816b88dc72fac26Santos Cordon            displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
225c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        } catch (RuntimeException e) {
226c22c56397636729b3717c3935816b88dc72fac26Santos Cordon            return;
227c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        }
228c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        fail("Expected DisplayManager to throw RuntimeException when it cannot initialize the"
229c22c56397636729b3717c3935816b88dc72fac26Santos Cordon                + " virtual display adapter");
230c22c56397636729b3717c3935816b88dc72fac26Santos Cordon    }
231c22c56397636729b3717c3935816b88dc72fac26Santos Cordon
232122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik    /**
233122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik     * Tests that an exception is raised for too dark a brightness configuration.
234122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik     */
235122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik    public void testTooDarkBrightnessConfigurationThrowException() {
236122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik        DisplayManagerService displayManager =
237122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik                new DisplayManagerService(mContext, mShortMockedInjector);
238122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik        Curve minimumBrightnessCurve = displayManager.getMinimumBrightnessCurveInternal();
239122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik        float[] lux = minimumBrightnessCurve.getX();
240122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik        float[] minimumNits = minimumBrightnessCurve.getY();
241122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik        float[] nits = new float[minimumNits.length];
242122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik        // For every control point, assert that making it slightly lower than the minimum throws an
243122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik        // exception.
244122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik        for (int i = 0; i < nits.length; i++) {
245122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik            for (int j = 0; j < nits.length; j++) {
246122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik                nits[j] = minimumNits[j];
247122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik                if (j == i) {
248122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik                    nits[j] -= 0.1f;
249122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik                }
250122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik                if (nits[j] < 0) {
251122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik                    nits[j] = 0;
252122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik                }
253122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik            }
254122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik            BrightnessConfiguration config =
255122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik                    new BrightnessConfiguration.Builder(lux, nits).build();
256122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik            Exception thrown = null;
257122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik            try {
258122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik                displayManager.validateBrightnessConfiguration(config);
259122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik            } catch (IllegalArgumentException e) {
260122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik                thrown = e;
261122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik            }
262122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik            assertNotNull("Building too dark a brightness configuration must throw an exception");
263122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik        }
264122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik    }
265122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik
266122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik    /**
267122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik     * Tests that no exception is raised for not too dark a brightness configuration.
268122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik     */
269122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik    public void testBrightEnoughBrightnessConfigurationDoesNotThrowException() {
270122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik        DisplayManagerService displayManager =
271122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik                new DisplayManagerService(mContext, mShortMockedInjector);
272122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik        Curve minimumBrightnessCurve = displayManager.getMinimumBrightnessCurveInternal();
273122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik        float[] lux = minimumBrightnessCurve.getX();
274122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik        float[] nits = minimumBrightnessCurve.getY();
275122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik        BrightnessConfiguration config = new BrightnessConfiguration.Builder(lux, nits).build();
276122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik        displayManager.validateBrightnessConfiguration(config);
277122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik    }
278122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik
279122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik    /**
280122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik     * Tests that null brightness configurations are alright.
281122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik     */
282122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik    public void testNullBrightnessConfiguration() {
283122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik        DisplayManagerService displayManager =
284122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik                new DisplayManagerService(mContext, mShortMockedInjector);
285122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik        displayManager.validateBrightnessConfiguration(null);
286122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik    }
287122df868919f3e2b9a92d6e9dc66808884f3f080Dan Gittik
288c22c56397636729b3717c3935816b88dc72fac26Santos Cordon    private void registerDefaultDisplays(DisplayManagerService displayManager) {
289c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        Handler handler = displayManager.getDisplayHandler();
290c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        // Would prefer to call displayManager.onStart() directly here but it performs binderService
291c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        // registration which triggers security exceptions when running from a test.
292c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        handler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);
293c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        // flush the handler
294c22c56397636729b3717c3935816b88dc72fac26Santos Cordon        handler.runWithScissors(() -> {}, 0 /* now */);
295c22c56397636729b3717c3935816b88dc72fac26Santos Cordon    }
296ee8931e258c07410b2affd6d5e8b9239b170c504Santos Cordon}
297