blob: 77df10bf536aa287f1156f827b536788dccffbda [file] [log] [blame]
Jeff Brown64a55af2012-08-26 02:47:39 -07001/*
2 * Copyright (C) 2012 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
17package com.android.server.display;
18
Adrian Roos30f53212018-01-05 16:14:34 +010019import android.app.ActivityThread;
Jeff Brown64a55af2012-08-26 02:47:39 -070020import android.content.Context;
Dominik Laskowski3316a0a2019-01-25 02:56:41 -080021import android.content.res.Resources;
Chris Phoenixbc839a32017-10-21 14:46:15 -070022import android.hardware.sidekick.SidekickInternal;
Griff Hazend3c454d2016-03-25 07:30:34 -070023import android.os.Build;
Jeff Brown4ed8fe72012-08-30 18:18:29 -070024import android.os.Handler;
Jeff Brown64a55af2012-08-26 02:47:39 -070025import android.os.IBinder;
Jeff Browne87bf032012-09-20 18:30:13 -070026import android.os.Looper;
Jeff Brown5d6443b2015-04-10 20:15:01 -070027import android.os.PowerManager;
Jeff Brown27f1d672012-10-17 18:32:34 -070028import android.os.SystemProperties;
Jeff Brown3edf5272014-08-14 19:25:14 -070029import android.os.Trace;
Dominik Laskowski3316a0a2019-01-25 02:56:41 -080030import android.util.LongSparseArray;
Dan Stoza00101052014-05-02 15:23:40 -070031import android.util.Slog;
Jeff Brown4ed8fe72012-08-30 18:18:29 -070032import android.util.SparseArray;
Jeff Brown92130f62012-10-24 21:28:33 -070033import android.view.Display;
Dominik Laskowskidb845962019-01-27 21:20:00 -080034import android.view.DisplayAddress;
Adrian Roos1cf585052018-01-03 18:43:27 +010035import android.view.DisplayCutout;
Jeff Browne87bf032012-09-20 18:30:13 -070036import android.view.DisplayEventReceiver;
Jeff Brown64a55af2012-08-26 02:47:39 -070037import android.view.Surface;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080038import android.view.SurfaceControl;
Dominik Laskowski3316a0a2019-01-25 02:56:41 -080039
40import com.android.server.LocalServices;
41import com.android.server.lights.Light;
42import com.android.server.lights.LightsManager;
43
Jeff Brown4ed8fe72012-08-30 18:18:29 -070044import java.io.PrintWriter;
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -070045import java.util.ArrayList;
Michael Wright58e829f2015-09-15 00:13:26 +010046import java.util.Arrays;
Michael Wright1c9977b2016-07-12 13:30:10 -070047import java.util.Collections;
48import java.util.List;
Jeff Brown4ed8fe72012-08-30 18:18:29 -070049
Jeff Brown64a55af2012-08-26 02:47:39 -070050/**
51 * A display adapter for the local displays managed by Surface Flinger.
Jeff Brownbd6e1502012-08-28 03:27:37 -070052 * <p>
Jeff Brown4ed8fe72012-08-30 18:18:29 -070053 * Display adapters are guarded by the {@link DisplayManagerService.SyncRoot} lock.
Jeff Brownbd6e1502012-08-28 03:27:37 -070054 * </p>
Jeff Brown64a55af2012-08-26 02:47:39 -070055 */
Jeff Brown4ed8fe72012-08-30 18:18:29 -070056final class LocalDisplayAdapter extends DisplayAdapter {
Jeff Brownbd6e1502012-08-28 03:27:37 -070057 private static final String TAG = "LocalDisplayAdapter";
Jeff Brown5d6443b2015-04-10 20:15:01 -070058 private static final boolean DEBUG = false;
Jeff Brown64a55af2012-08-26 02:47:39 -070059
Wale Ogunwale361ca212014-11-20 11:42:38 -080060 private static final String UNIQUE_ID_PREFIX = "local:";
61
Adam Powell01f280d2015-05-18 16:07:42 -070062 private static final String PROPERTY_EMULATOR_CIRCULAR = "ro.emulator.circular";
63
Dominik Laskowski3316a0a2019-01-25 02:56:41 -080064 private final LongSparseArray<LocalDisplayDevice> mDevices =
65 new LongSparseArray<LocalDisplayDevice>();
Jeff Brown4ed8fe72012-08-30 18:18:29 -070066
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -070067 @SuppressWarnings("unused") // Becomes active at instantiation time.
Ady Abrahama5a21f72019-02-13 16:41:59 -080068 private PhysicalDisplayEventReceiver mPhysicalDisplayEventReceiver;
69
Jeff Brown4ed8fe72012-08-30 18:18:29 -070070
Jeff Brown66692502012-10-18 16:13:44 -070071 // Called with SyncRoot lock held.
Jeff Brown4ed8fe72012-08-30 18:18:29 -070072 public LocalDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
73 Context context, Handler handler, Listener listener) {
74 super(syncRoot, context, handler, listener, TAG);
Jeff Brown64a55af2012-08-26 02:47:39 -070075 }
76
77 @Override
Jeff Brown4ed8fe72012-08-30 18:18:29 -070078 public void registerLocked() {
Jeff Brown4ed8fe72012-08-30 18:18:29 -070079 super.registerLocked();
Jeff Brown66692502012-10-18 16:13:44 -070080
Ady Abrahama5a21f72019-02-13 16:41:59 -080081 mPhysicalDisplayEventReceiver = new PhysicalDisplayEventReceiver(getHandler().getLooper());
Jesse Halle244db42012-11-08 11:55:14 -080082
Dominik Laskowski3316a0a2019-01-25 02:56:41 -080083 for (long physicalDisplayId : SurfaceControl.getPhysicalDisplayIds()) {
84 tryConnectDisplayLocked(physicalDisplayId);
Jesse Halle244db42012-11-08 11:55:14 -080085 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -070086 }
87
Dominik Laskowski3316a0a2019-01-25 02:56:41 -080088 private void tryConnectDisplayLocked(long physicalDisplayId) {
89 final IBinder displayToken = SurfaceControl.getPhysicalDisplayToken(physicalDisplayId);
Dan Stoza00101052014-05-02 15:23:40 -070090 if (displayToken != null) {
91 SurfaceControl.PhysicalDisplayInfo[] configs =
92 SurfaceControl.getDisplayConfigs(displayToken);
93 if (configs == null) {
94 // There are no valid configs for this device, so we can't use it
Dominik Laskowski3316a0a2019-01-25 02:56:41 -080095 Slog.w(TAG, "No valid configs found for display device " + physicalDisplayId);
Dan Stoza00101052014-05-02 15:23:40 -070096 return;
97 }
98 int activeConfig = SurfaceControl.getActiveConfig(displayToken);
99 if (activeConfig < 0) {
100 // There is no active config, and for now we don't have the
101 // policy to set one.
Dominik Laskowski3316a0a2019-01-25 02:56:41 -0800102 Slog.w(TAG, "No active config found for display device " + physicalDisplayId);
Dan Stoza00101052014-05-02 15:23:40 -0700103 return;
104 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700105 int activeColorMode = SurfaceControl.getActiveColorMode(displayToken);
106 if (activeColorMode < 0) {
107 // We failed to get the active color mode. We don't bail out here since on the next
108 // configuration pass we'll go ahead and set it to whatever it was set to last (or
109 // COLOR_MODE_NATIVE if this is the first configuration).
110 Slog.w(TAG, "Unable to get active color mode for display device " +
Dominik Laskowski3316a0a2019-01-25 02:56:41 -0800111 physicalDisplayId);
Michael Wright1c9977b2016-07-12 13:30:10 -0700112 activeColorMode = Display.COLOR_MODE_INVALID;
113 }
114 int[] colorModes = SurfaceControl.getDisplayColorModes(displayToken);
Dominik Laskowski3316a0a2019-01-25 02:56:41 -0800115 LocalDisplayDevice device = mDevices.get(physicalDisplayId);
Jesse Halle244db42012-11-08 11:55:14 -0800116 if (device == null) {
117 // Display was added.
Dominik Laskowski3316a0a2019-01-25 02:56:41 -0800118 final boolean isInternal = mDevices.size() == 0;
119 device = new LocalDisplayDevice(displayToken, physicalDisplayId,
120 configs, activeConfig, colorModes, activeColorMode, isInternal);
121 mDevices.put(physicalDisplayId, device);
Jesse Halle244db42012-11-08 11:55:14 -0800122 sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
Michael Wright1c9977b2016-07-12 13:30:10 -0700123 } else if (device.updatePhysicalDisplayInfoLocked(configs, activeConfig,
124 colorModes, activeColorMode)) {
Jesse Halle244db42012-11-08 11:55:14 -0800125 // Display properties changed.
126 sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_CHANGED);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700127 }
Jesse Halle244db42012-11-08 11:55:14 -0800128 } else {
129 // The display is no longer available. Ignore the attempt to add it.
130 // If it was connected but has already been disconnected, we'll get a
131 // disconnect event that will remove it from mDevices.
132 }
133 }
134
Dominik Laskowski3316a0a2019-01-25 02:56:41 -0800135 private void tryDisconnectDisplayLocked(long physicalDisplayId) {
136 LocalDisplayDevice device = mDevices.get(physicalDisplayId);
Jesse Halle244db42012-11-08 11:55:14 -0800137 if (device != null) {
138 // Display was removed.
Dominik Laskowski3316a0a2019-01-25 02:56:41 -0800139 mDevices.remove(physicalDisplayId);
Jesse Halle244db42012-11-08 11:55:14 -0800140 sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_REMOVED);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700141 }
Jeff Brown64a55af2012-08-26 02:47:39 -0700142 }
143
Prashant Malanic55929a2014-05-25 01:59:21 -0700144 static int getPowerModeForState(int state) {
145 switch (state) {
146 case Display.STATE_OFF:
147 return SurfaceControl.POWER_MODE_OFF;
Jeff Brown5dc21912014-07-17 18:50:18 -0700148 case Display.STATE_DOZE:
Prashant Malanic55929a2014-05-25 01:59:21 -0700149 return SurfaceControl.POWER_MODE_DOZE;
Jeff Brown5dc21912014-07-17 18:50:18 -0700150 case Display.STATE_DOZE_SUSPEND:
151 return SurfaceControl.POWER_MODE_DOZE_SUSPEND;
Chris Phoenix10a4a642017-09-25 13:21:00 -0700152 case Display.STATE_ON_SUSPEND:
153 return SurfaceControl.POWER_MODE_ON_SUSPEND;
Prashant Malanic55929a2014-05-25 01:59:21 -0700154 default:
155 return SurfaceControl.POWER_MODE_NORMAL;
156 }
Jeff Brown44b1f762014-04-22 18:07:24 -0700157 }
158
Jeff Brown64a55af2012-08-26 02:47:39 -0700159 private final class LocalDisplayDevice extends DisplayDevice {
Dominik Laskowski3316a0a2019-01-25 02:56:41 -0800160 private final long mPhysicalDisplayId;
Jeff Brown5d6443b2015-04-10 20:15:01 -0700161 private final Light mBacklight;
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700162 private final SparseArray<DisplayModeRecord> mSupportedModes = new SparseArray<>();
Michael Wright1c9977b2016-07-12 13:30:10 -0700163 private final ArrayList<Integer> mSupportedColorModes = new ArrayList<>();
Dominik Laskowski3316a0a2019-01-25 02:56:41 -0800164 private final boolean mIsInternal;
Jeff Brown64a55af2012-08-26 02:47:39 -0700165
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700166 private DisplayDeviceInfo mInfo;
167 private boolean mHavePendingChanges;
Jeff Brown037c33e2014-04-09 00:31:55 -0700168 private int mState = Display.STATE_UNKNOWN;
Jeff Brown5d6443b2015-04-10 20:15:01 -0700169 private int mBrightness = PowerManager.BRIGHTNESS_DEFAULT;
Michael Wright58e829f2015-09-15 00:13:26 +0100170 private int mActivePhysIndex;
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700171 private int mDefaultModeId;
172 private int mActiveModeId;
173 private boolean mActiveModeInvalid;
Michael Wright1c9977b2016-07-12 13:30:10 -0700174 private int mActiveColorMode;
175 private boolean mActiveColorModeInvalid;
Michael Wright9ff94c02016-03-30 18:05:40 -0700176 private Display.HdrCapabilities mHdrCapabilities;
Chris Phoenixbc839a32017-10-21 14:46:15 -0700177 private boolean mSidekickActive;
178 private SidekickInternal mSidekickInternal;
Michael Wright58e829f2015-09-15 00:13:26 +0100179
180 private SurfaceControl.PhysicalDisplayInfo mDisplayInfos[];
Jeff Brown5d6443b2015-04-10 20:15:01 -0700181
Dominik Laskowski3316a0a2019-01-25 02:56:41 -0800182 LocalDisplayDevice(IBinder displayToken, long physicalDisplayId,
Michael Wright1c9977b2016-07-12 13:30:10 -0700183 SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo,
Dominik Laskowski3316a0a2019-01-25 02:56:41 -0800184 int[] colorModes, int activeColorMode, boolean isInternal) {
185 super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + physicalDisplayId);
186 mPhysicalDisplayId = physicalDisplayId;
187 mIsInternal = isInternal;
Michael Wright1c9977b2016-07-12 13:30:10 -0700188 updatePhysicalDisplayInfoLocked(physicalDisplayInfos, activeDisplayInfo,
189 colorModes, activeColorMode);
190 updateColorModesLocked(colorModes, activeColorMode);
Chris Phoenixbc839a32017-10-21 14:46:15 -0700191 mSidekickInternal = LocalServices.getService(SidekickInternal.class);
Dominik Laskowski3316a0a2019-01-25 02:56:41 -0800192 if (mIsInternal) {
Jeff Brown5d6443b2015-04-10 20:15:01 -0700193 LightsManager lights = LocalServices.getService(LightsManager.class);
194 mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
195 } else {
196 mBacklight = null;
197 }
Michael Wright9ff94c02016-03-30 18:05:40 -0700198 mHdrCapabilities = SurfaceControl.getHdrCapabilities(displayToken);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700199 }
200
Michael Wright1c9977b2016-07-12 13:30:10 -0700201 @Override
202 public boolean hasStableUniqueId() {
203 return true;
204 }
205
Michael Wright3f145a22014-07-22 19:46:03 -0700206 public boolean updatePhysicalDisplayInfoLocked(
Michael Wright1c9977b2016-07-12 13:30:10 -0700207 SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo,
208 int[] colorModes, int activeColorMode) {
Michael Wright58e829f2015-09-15 00:13:26 +0100209 mDisplayInfos = Arrays.copyOf(physicalDisplayInfos, physicalDisplayInfos.length);
210 mActivePhysIndex = activeDisplayInfo;
Michael Wright58e829f2015-09-15 00:13:26 +0100211 // Build an updated list of all existing modes.
212 ArrayList<DisplayModeRecord> records = new ArrayList<DisplayModeRecord>();
213 boolean modesAdded = false;
214 for (int i = 0; i < physicalDisplayInfos.length; i++) {
215 SurfaceControl.PhysicalDisplayInfo info = physicalDisplayInfos[i];
216 // First, check to see if we've already added a matching mode. Since not all
217 // configuration options are exposed via Display.Mode, it's possible that we have
218 // multiple PhysicalDisplayInfos that would generate the same Display.Mode.
219 boolean existingMode = false;
220 for (int j = 0; j < records.size(); j++) {
221 if (records.get(j).hasMatchingMode(info)) {
222 existingMode = true;
223 break;
224 }
225 }
226 if (existingMode) {
227 continue;
228 }
229 // If we haven't already added a mode for this configuration to the new set of
230 // supported modes then check to see if we have one in the prior set of supported
231 // modes to reuse.
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700232 DisplayModeRecord record = findDisplayModeRecord(info);
Michael Wright58e829f2015-09-15 00:13:26 +0100233 if (record == null) {
234 record = new DisplayModeRecord(info);
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700235 modesAdded = true;
236 }
237 records.add(record);
Michael Wright58e829f2015-09-15 00:13:26 +0100238 }
239
240 // Get the currently active mode
241 DisplayModeRecord activeRecord = null;
242 for (int i = 0; i < records.size(); i++) {
243 DisplayModeRecord record = records.get(i);
244 if (record.hasMatchingMode(physicalDisplayInfos[activeDisplayInfo])){
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700245 activeRecord = record;
Michael Wright58e829f2015-09-15 00:13:26 +0100246 break;
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700247 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700248 }
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700249 // Check whether surface flinger spontaneously changed modes out from under us. Schedule
250 // traversals to ensure that the correct state is reapplied if necessary.
251 if (mActiveModeId != 0
252 && mActiveModeId != activeRecord.mMode.getModeId()) {
253 mActiveModeInvalid = true;
254 sendTraversalRequestLocked();
255 }
Michael Wright58e829f2015-09-15 00:13:26 +0100256
Michael Wright58e829f2015-09-15 00:13:26 +0100257 boolean recordsChanged = records.size() != mSupportedModes.size() || modesAdded;
Michael Wright1c9977b2016-07-12 13:30:10 -0700258 // If the records haven't changed then we're done here.
259 if (!recordsChanged) {
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700260 return false;
261 }
262 // Update the index of modes.
263 mHavePendingChanges = true;
Michael Wright58e829f2015-09-15 00:13:26 +0100264
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700265 mSupportedModes.clear();
266 for (DisplayModeRecord record : records) {
267 mSupportedModes.put(record.mMode.getModeId(), record);
268 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700269 // Update the default mode, if needed.
270 if (findDisplayInfoIndexLocked(mDefaultModeId) < 0) {
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700271 if (mDefaultModeId != 0) {
Michael Wright58e829f2015-09-15 00:13:26 +0100272 Slog.w(TAG, "Default display mode no longer available, using currently"
273 + " active mode as default.");
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700274 }
275 mDefaultModeId = activeRecord.mMode.getModeId();
276 }
277 // Determine whether the active mode is still there.
278 if (mSupportedModes.indexOfKey(mActiveModeId) < 0) {
279 if (mActiveModeId != 0) {
280 Slog.w(TAG, "Active display mode no longer available, reverting to default"
281 + " mode.");
282 }
283 mActiveModeId = mDefaultModeId;
284 mActiveModeInvalid = true;
285 }
Michael Wright58e829f2015-09-15 00:13:26 +0100286
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700287 // Schedule traversals so that we apply pending changes.
288 sendTraversalRequestLocked();
289 return true;
290 }
291
Michael Wright1c9977b2016-07-12 13:30:10 -0700292 private boolean updateColorModesLocked(int[] colorModes,
293 int activeColorMode) {
294 List<Integer> pendingColorModes = new ArrayList<>();
295
thecrazyskullb34c81042016-12-18 12:48:20 -0500296 if (colorModes == null) return false;
Michael Wright1c9977b2016-07-12 13:30:10 -0700297 // Build an updated list of all existing color modes.
298 boolean colorModesAdded = false;
299 for (int colorMode: colorModes) {
300 if (!mSupportedColorModes.contains(colorMode)) {
301 colorModesAdded = true;
302 }
303 pendingColorModes.add(colorMode);
304 }
305
306 boolean colorModesChanged =
307 pendingColorModes.size() != mSupportedColorModes.size()
308 || colorModesAdded;
309
310 // If the supported color modes haven't changed then we're done here.
311 if (!colorModesChanged) {
312 return false;
313 }
314
315 mHavePendingChanges = true;
316
317 mSupportedColorModes.clear();
318 mSupportedColorModes.addAll(pendingColorModes);
319 Collections.sort(mSupportedColorModes);
320
321 // Determine whether the active color mode is still there.
322 if (!mSupportedColorModes.contains(mActiveColorMode)) {
323 if (mActiveColorMode != 0) {
324 Slog.w(TAG, "Active color mode no longer available, reverting"
325 + " to default mode.");
326 mActiveColorMode = Display.COLOR_MODE_DEFAULT;
327 mActiveColorModeInvalid = true;
328 } else {
329 if (!mSupportedColorModes.isEmpty()) {
330 // This should never happen.
331 Slog.e(TAG, "Default and active color mode is no longer available!"
332 + " Reverting to first available mode.");
333 mActiveColorMode = mSupportedColorModes.get(0);
334 mActiveColorModeInvalid = true;
335 } else {
336 // This should really never happen.
337 Slog.e(TAG, "No color modes available!");
338 }
339 }
340 }
341 return true;
342 }
343
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700344 private DisplayModeRecord findDisplayModeRecord(SurfaceControl.PhysicalDisplayInfo info) {
345 for (int i = 0; i < mSupportedModes.size(); i++) {
346 DisplayModeRecord record = mSupportedModes.valueAt(i);
Michael Wright58e829f2015-09-15 00:13:26 +0100347 if (record.hasMatchingMode(info)) {
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700348 return record;
349 }
350 }
351 return null;
Jeff Brown64a55af2012-08-26 02:47:39 -0700352 }
353
354 @Override
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700355 public void applyPendingDisplayDeviceInfoChangesLocked() {
356 if (mHavePendingChanges) {
357 mInfo = null;
358 mHavePendingChanges = false;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700359 }
Jeff Brown64a55af2012-08-26 02:47:39 -0700360 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700361
362 @Override
363 public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
364 if (mInfo == null) {
Michael Wright58e829f2015-09-15 00:13:26 +0100365 SurfaceControl.PhysicalDisplayInfo phys = mDisplayInfos[mActivePhysIndex];
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700366 mInfo = new DisplayDeviceInfo();
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700367 mInfo.width = phys.width;
368 mInfo.height = phys.height;
369 mInfo.modeId = mActiveModeId;
370 mInfo.defaultModeId = mDefaultModeId;
371 mInfo.supportedModes = new Display.Mode[mSupportedModes.size()];
372 for (int i = 0; i < mSupportedModes.size(); i++) {
373 DisplayModeRecord record = mSupportedModes.valueAt(i);
374 mInfo.supportedModes[i] = record.mMode;
375 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700376 mInfo.colorMode = mActiveColorMode;
377 mInfo.supportedColorModes =
378 new int[mSupportedColorModes.size()];
379 for (int i = 0; i < mSupportedColorModes.size(); i++) {
380 mInfo.supportedColorModes[i] = mSupportedColorModes.get(i);
Michael Wright58e829f2015-09-15 00:13:26 +0100381 }
Michael Wright9ff94c02016-03-30 18:05:40 -0700382 mInfo.hdrCapabilities = mHdrCapabilities;
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700383 mInfo.appVsyncOffsetNanos = phys.appVsyncOffsetNanos;
384 mInfo.presentationDeadlineNanos = phys.presentationDeadlineNanos;
Jeff Brown037c33e2014-04-09 00:31:55 -0700385 mInfo.state = mState;
Wale Ogunwale361ca212014-11-20 11:42:38 -0800386 mInfo.uniqueId = getUniqueId();
Dominik Laskowskidb845962019-01-27 21:20:00 -0800387 mInfo.address = DisplayAddress.fromPhysicalDisplayId(mPhysicalDisplayId);
Jeff Brown77aebfd2012-10-01 21:07:03 -0700388
Jeff Brownf0681b32012-10-23 17:35:57 -0700389 // Assume that all built-in displays that have secure output (eg. HDCP) also
Jeff Brown77aebfd2012-10-01 21:07:03 -0700390 // support compositing from gralloc protected buffers.
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700391 if (phys.secure) {
Jeff Brownf0681b32012-10-23 17:35:57 -0700392 mInfo.flags = DisplayDeviceInfo.FLAG_SECURE
393 | DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS;
394 }
Jeff Brown77aebfd2012-10-01 21:07:03 -0700395
Adrian Roos30f53212018-01-05 16:14:34 +0100396 final Resources res = getOverlayContext().getResources();
Dominik Laskowski3316a0a2019-01-25 02:56:41 -0800397 if (mIsInternal) {
Adam Powell49e7ff92015-05-14 16:18:53 -0700398 mInfo.name = res.getString(
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700399 com.android.internal.R.string.display_manager_built_in_display_name);
Jeff Brown77aebfd2012-10-01 21:07:03 -0700400 mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY
Jeff Brown27f1d672012-10-17 18:32:34 -0700401 | DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
Adam Powell01f280d2015-05-18 16:07:42 -0700402 if (res.getBoolean(com.android.internal.R.bool.config_mainBuiltInDisplayIsRound)
Griff Hazend3c454d2016-03-25 07:30:34 -0700403 || (Build.IS_EMULATOR
Adam Powell01f280d2015-05-18 16:07:42 -0700404 && SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false))) {
Adam Powell49e7ff92015-05-14 16:18:53 -0700405 mInfo.flags |= DisplayDeviceInfo.FLAG_ROUND;
406 }
Adrian Roos8c28c7c2018-08-20 13:43:38 +0200407 if (res.getBoolean(
408 com.android.internal.R.bool.config_maskMainBuiltInDisplayCutout)) {
409 mInfo.flags |= DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT;
410 }
Jorim Jaggi60640512018-06-29 01:14:31 +0200411 mInfo.displayCutout = DisplayCutout.fromResourcesRectApproximation(res,
412 mInfo.width, mInfo.height);
Jeff Brown92130f62012-10-24 21:28:33 -0700413 mInfo.type = Display.TYPE_BUILT_IN;
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700414 mInfo.densityDpi = (int)(phys.density * 160 + 0.5f);
415 mInfo.xDpi = phys.xDpi;
416 mInfo.yDpi = phys.yDpi;
Jeff Brownd728bf52012-09-08 18:05:28 -0700417 mInfo.touch = DisplayDeviceInfo.TOUCH_INTERNAL;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700418 } else {
Adrian Roos1cf585052018-01-03 18:43:27 +0100419 mInfo.displayCutout = null;
Jeff Brown92130f62012-10-24 21:28:33 -0700420 mInfo.type = Display.TYPE_HDMI;
Jeff Brown7d00aff2013-08-02 19:03:49 -0700421 mInfo.flags |= DisplayDeviceInfo.FLAG_PRESENTATION;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700422 mInfo.name = getContext().getResources().getString(
423 com.android.internal.R.string.display_manager_hdmi_display_name);
Jeff Brownd728bf52012-09-08 18:05:28 -0700424 mInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL;
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700425 mInfo.setAssumedDensityForExternalDisplay(phys.width, phys.height);
Jeff Brown27f1d672012-10-17 18:32:34 -0700426
427 // For demonstration purposes, allow rotation of the external display.
428 // In the future we might allow the user to configure this directly.
429 if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
430 mInfo.rotation = Surface.ROTATION_270;
431 }
Scott Anderson8786ed92013-11-01 13:27:39 -0700432
433 // For demonstration purposes, allow rotation of the external display
434 // to follow the built-in display.
435 if (SystemProperties.getBoolean("persist.demo.hdmirotates", false)) {
436 mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
437 }
Michael Wright4b0fa172016-03-11 17:15:24 -0800438
439 if (!res.getBoolean(
440 com.android.internal.R.bool.config_localDisplaysMirrorContent)) {
441 mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY;
442 }
Pavel Maltseva6fec7b2018-04-04 10:14:55 -0700443
444 if (res.getBoolean(com.android.internal.R.bool.config_localDisplaysPrivate)) {
445 mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE;
446 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700447 }
448 }
449 return mInfo;
450 }
451
452 @Override
Jeff Brown5d6443b2015-04-10 20:15:01 -0700453 public Runnable requestDisplayStateLocked(final int state, final int brightness) {
454 // Assume that the brightness is off if the display is being turned off.
455 assert state != Display.STATE_OFF || brightness == PowerManager.BRIGHTNESS_OFF;
456
457 final boolean stateChanged = (mState != state);
458 final boolean brightnessChanged = (mBrightness != brightness) && mBacklight != null;
459 if (stateChanged || brightnessChanged) {
Dominik Laskowski3316a0a2019-01-25 02:56:41 -0800460 final long physicalDisplayId = mPhysicalDisplayId;
Jeff Browne75926d2014-09-18 15:24:49 -0700461 final IBinder token = getDisplayTokenLocked();
Jeff Brown5d6443b2015-04-10 20:15:01 -0700462 final int oldState = mState;
Jeff Browne75926d2014-09-18 15:24:49 -0700463
Jeff Brown5d6443b2015-04-10 20:15:01 -0700464 if (stateChanged) {
465 mState = state;
466 updateDeviceInfoLocked();
467 }
468
469 if (brightnessChanged) {
470 mBrightness = brightness;
471 }
472
473 // Defer actually setting the display state until after we have exited
Jeff Browne75926d2014-09-18 15:24:49 -0700474 // the critical section since it can take hundreds of milliseconds
475 // to complete.
476 return new Runnable() {
477 @Override
478 public void run() {
Jeff Brown5d6443b2015-04-10 20:15:01 -0700479 // Exit a suspended state before making any changes.
480 int currentState = oldState;
481 if (Display.isSuspendedState(oldState)
482 || oldState == Display.STATE_UNKNOWN) {
483 if (!Display.isSuspendedState(state)) {
484 setDisplayState(state);
485 currentState = state;
486 } else if (state == Display.STATE_DOZE_SUSPEND
487 || oldState == Display.STATE_DOZE_SUSPEND) {
488 setDisplayState(Display.STATE_DOZE);
489 currentState = Display.STATE_DOZE;
Chris Phoenix10a4a642017-09-25 13:21:00 -0700490 } else if (state == Display.STATE_ON_SUSPEND
491 || oldState == Display.STATE_ON_SUSPEND) {
492 setDisplayState(Display.STATE_ON);
493 currentState = Display.STATE_ON;
Jeff Brown5d6443b2015-04-10 20:15:01 -0700494 } else {
495 return; // old state and new state is off
496 }
497 }
498
Santos Cordond6a56602016-09-20 15:50:35 -0700499 // If the state change was from or to VR, then we need to tell the light
Karthik Ravi Shankar66855312017-10-04 13:30:13 -0700500 // so that it can apply appropriate VR brightness settings. Also, update the
501 // brightness so the state is propogated to light.
502 boolean vrModeChange = false;
Santos Cordond6a56602016-09-20 15:50:35 -0700503 if ((state == Display.STATE_VR || currentState == Display.STATE_VR) &&
504 currentState != state) {
505 setVrMode(state == Display.STATE_VR);
Karthik Ravi Shankar66855312017-10-04 13:30:13 -0700506 vrModeChange = true;
Santos Cordond6a56602016-09-20 15:50:35 -0700507 }
508
509
Jeff Brown5d6443b2015-04-10 20:15:01 -0700510 // Apply brightness changes given that we are in a non-suspended state.
Karthik Ravi Shankar66855312017-10-04 13:30:13 -0700511 if (brightnessChanged || vrModeChange) {
Jeff Brown5d6443b2015-04-10 20:15:01 -0700512 setDisplayBrightness(brightness);
513 }
514
515 // Enter the final desired state, possibly suspended.
516 if (state != currentState) {
517 setDisplayState(state);
518 }
519 }
520
Santos Cordond6a56602016-09-20 15:50:35 -0700521 private void setVrMode(boolean isVrEnabled) {
522 if (DEBUG) {
523 Slog.d(TAG, "setVrMode("
Dominik Laskowski3316a0a2019-01-25 02:56:41 -0800524 + "id=" + physicalDisplayId
Santos Cordond6a56602016-09-20 15:50:35 -0700525 + ", state=" + Display.stateToString(state) + ")");
526 }
527 mBacklight.setVrMode(isVrEnabled);
528 }
529
Jeff Brown5d6443b2015-04-10 20:15:01 -0700530 private void setDisplayState(int state) {
531 if (DEBUG) {
532 Slog.d(TAG, "setDisplayState("
Dominik Laskowski3316a0a2019-01-25 02:56:41 -0800533 + "id=" + physicalDisplayId
Jeff Brown5d6443b2015-04-10 20:15:01 -0700534 + ", state=" + Display.stateToString(state) + ")");
535 }
536
Chris Phoenixbc839a32017-10-21 14:46:15 -0700537 // We must tell sidekick to stop controlling the display before we
538 // can change its power mode, so do that first.
539 if (mSidekickActive) {
540 Trace.traceBegin(Trace.TRACE_TAG_POWER,
541 "SidekickInternal#endDisplayControl");
542 try {
543 mSidekickInternal.endDisplayControl();
544 } finally {
545 Trace.traceEnd(Trace.TRACE_TAG_POWER);
546 }
547 mSidekickActive = false;
548 }
549 final int mode = getPowerModeForState(state);
Jeff Brown5d6443b2015-04-10 20:15:01 -0700550 Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayState("
Dominik Laskowski3316a0a2019-01-25 02:56:41 -0800551 + "id=" + physicalDisplayId
Jeff Brown5d6443b2015-04-10 20:15:01 -0700552 + ", state=" + Display.stateToString(state) + ")");
Jeff Browne75926d2014-09-18 15:24:49 -0700553 try {
554 SurfaceControl.setDisplayPowerMode(token, mode);
Michael Wrightc3e6af82017-07-25 22:31:03 +0100555 Trace.traceCounter(Trace.TRACE_TAG_POWER, "DisplayPowerMode", mode);
Jeff Browne75926d2014-09-18 15:24:49 -0700556 } finally {
557 Trace.traceEnd(Trace.TRACE_TAG_POWER);
558 }
Chris Phoenixbc839a32017-10-21 14:46:15 -0700559 // If we're entering a suspended (but not OFF) power state and we
560 // have a sidekick available, tell it now that it can take control.
561 if (Display.isSuspendedState(state) && state != Display.STATE_OFF
562 && mSidekickInternal != null && !mSidekickActive) {
563 Trace.traceBegin(Trace.TRACE_TAG_POWER,
564 "SidekickInternal#startDisplayControl");
565 try {
566 mSidekickActive = mSidekickInternal.startDisplayControl(state);
567 } finally {
568 Trace.traceEnd(Trace.TRACE_TAG_POWER);
569 }
570 }
Jeff Browne75926d2014-09-18 15:24:49 -0700571 }
Jeff Brown5d6443b2015-04-10 20:15:01 -0700572
573 private void setDisplayBrightness(int brightness) {
574 if (DEBUG) {
575 Slog.d(TAG, "setDisplayBrightness("
Dominik Laskowski3316a0a2019-01-25 02:56:41 -0800576 + "id=" + physicalDisplayId
577 + ", brightness=" + brightness + ")");
Jeff Brown5d6443b2015-04-10 20:15:01 -0700578 }
579
580 Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayBrightness("
Dominik Laskowski3316a0a2019-01-25 02:56:41 -0800581 + "id=" + physicalDisplayId + ", brightness=" + brightness + ")");
Jeff Brown5d6443b2015-04-10 20:15:01 -0700582 try {
583 mBacklight.setBrightness(brightness);
Michael Wrightc3e6af82017-07-25 22:31:03 +0100584 Trace.traceCounter(Trace.TRACE_TAG_POWER,
Michael Wrighta9f37ab2017-08-15 17:14:20 +0100585 "ScreenBrightness", brightness);
Jeff Brown5d6443b2015-04-10 20:15:01 -0700586 } finally {
587 Trace.traceEnd(Trace.TRACE_TAG_POWER);
588 }
589 }
Jeff Browne75926d2014-09-18 15:24:49 -0700590 };
Jeff Brown037c33e2014-04-09 00:31:55 -0700591 }
Jeff Browne75926d2014-09-18 15:24:49 -0700592 return null;
Jeff Brown9e316a12012-10-08 19:17:06 -0700593 }
594
595 @Override
Robert Carrae606b42018-02-15 15:36:23 -0800596 public void requestDisplayModesLocked(int colorMode, int modeId) {
597 if (requestModeLocked(modeId) ||
598 requestColorModeLocked(colorMode)) {
Michael Wright1c9977b2016-07-12 13:30:10 -0700599 updateDeviceInfoLocked();
600 }
601 }
602
Adrian Roos898ec382018-01-17 12:54:50 +0100603 @Override
604 public void onOverlayChangedLocked() {
605 updateDeviceInfoLocked();
606 }
607
Robert Carrae606b42018-02-15 15:36:23 -0800608 public boolean requestModeLocked(int modeId) {
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700609 if (modeId == 0) {
610 modeId = mDefaultModeId;
611 } else if (mSupportedModes.indexOfKey(modeId) < 0) {
612 Slog.w(TAG, "Requested mode " + modeId + " is not supported by this display,"
613 + " reverting to default display mode.");
614 modeId = mDefaultModeId;
615 }
Michael Wright58e829f2015-09-15 00:13:26 +0100616
Michael Wright1c9977b2016-07-12 13:30:10 -0700617 int physIndex = findDisplayInfoIndexLocked(modeId);
Michael Wright58e829f2015-09-15 00:13:26 +0100618 if (physIndex < 0) {
Michael Wright1c9977b2016-07-12 13:30:10 -0700619 Slog.w(TAG, "Requested mode ID " + modeId + " not available,"
620 + " trying with default mode ID");
Michael Wright58e829f2015-09-15 00:13:26 +0100621 modeId = mDefaultModeId;
Michael Wright1c9977b2016-07-12 13:30:10 -0700622 physIndex = findDisplayInfoIndexLocked(modeId);
Michael Wright58e829f2015-09-15 00:13:26 +0100623 }
Jorim Jaggi3b3cbb52015-09-24 17:35:58 -0700624 if (mActivePhysIndex == physIndex) {
Michael Wright1c9977b2016-07-12 13:30:10 -0700625 return false;
Michael Wright3f145a22014-07-22 19:46:03 -0700626 }
Michael Wright58e829f2015-09-15 00:13:26 +0100627 SurfaceControl.setActiveConfig(getDisplayTokenLocked(), physIndex);
628 mActivePhysIndex = physIndex;
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700629 mActiveModeId = modeId;
630 mActiveModeInvalid = false;
Michael Wright1c9977b2016-07-12 13:30:10 -0700631 return true;
632 }
633
Robert Carrae606b42018-02-15 15:36:23 -0800634 public boolean requestColorModeLocked(int colorMode) {
Michael Wright1c9977b2016-07-12 13:30:10 -0700635 if (mActiveColorMode == colorMode) {
636 return false;
637 }
638 if (!mSupportedColorModes.contains(colorMode)) {
639 Slog.w(TAG, "Unable to find color mode " + colorMode
640 + ", ignoring request.");
641 return false;
642 }
643 SurfaceControl.setActiveColorMode(getDisplayTokenLocked(), colorMode);
644 mActiveColorMode = colorMode;
645 mActiveColorModeInvalid = false;
646 return true;
Michael Wright3f145a22014-07-22 19:46:03 -0700647 }
648
649 @Override
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700650 public void dumpLocked(PrintWriter pw) {
651 super.dumpLocked(pw);
Dominik Laskowski3316a0a2019-01-25 02:56:41 -0800652 pw.println("mPhysicalDisplayId=" + mPhysicalDisplayId);
Michael Wright58e829f2015-09-15 00:13:26 +0100653 pw.println("mActivePhysIndex=" + mActivePhysIndex);
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700654 pw.println("mActiveModeId=" + mActiveModeId);
Michael Wright1c9977b2016-07-12 13:30:10 -0700655 pw.println("mActiveColorMode=" + mActiveColorMode);
Jeff Brown037c33e2014-04-09 00:31:55 -0700656 pw.println("mState=" + Display.stateToString(mState));
Jeff Brown5d6443b2015-04-10 20:15:01 -0700657 pw.println("mBrightness=" + mBrightness);
658 pw.println("mBacklight=" + mBacklight);
Michael Wright58e829f2015-09-15 00:13:26 +0100659 pw.println("mDisplayInfos=");
660 for (int i = 0; i < mDisplayInfos.length; i++) {
661 pw.println(" " + mDisplayInfos[i]);
662 }
663 pw.println("mSupportedModes=");
664 for (int i = 0; i < mSupportedModes.size(); i++) {
665 pw.println(" " + mSupportedModes.valueAt(i));
666 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700667 pw.print("mSupportedColorModes=[");
668 for (int i = 0; i < mSupportedColorModes.size(); i++) {
Michael Wright58e829f2015-09-15 00:13:26 +0100669 if (i != 0) {
670 pw.print(", ");
671 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700672 pw.print(mSupportedColorModes.get(i));
Michael Wright58e829f2015-09-15 00:13:26 +0100673 }
674 pw.println("]");
675 }
676
Michael Wright1c9977b2016-07-12 13:30:10 -0700677 private int findDisplayInfoIndexLocked(int modeId) {
Michael Wright58e829f2015-09-15 00:13:26 +0100678 DisplayModeRecord record = mSupportedModes.get(modeId);
Michael Wright1c9977b2016-07-12 13:30:10 -0700679 if (record != null) {
Michael Wright58e829f2015-09-15 00:13:26 +0100680 for (int i = 0; i < mDisplayInfos.length; i++) {
681 SurfaceControl.PhysicalDisplayInfo info = mDisplayInfos[i];
Michael Wright1c9977b2016-07-12 13:30:10 -0700682 if (record.hasMatchingMode(info)){
Michael Wright58e829f2015-09-15 00:13:26 +0100683 return i;
684 }
685 }
686 }
687 return -1;
Jeff Brown037c33e2014-04-09 00:31:55 -0700688 }
689
690 private void updateDeviceInfoLocked() {
691 mInfo = null;
692 sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700693 }
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700694 }
Michael Wright3f145a22014-07-22 19:46:03 -0700695
Adrian Roos30f53212018-01-05 16:14:34 +0100696 /** Supplies a context whose Resources apply runtime-overlays */
697 Context getOverlayContext() {
698 return ActivityThread.currentActivityThread().getSystemUiContext();
699 }
700
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700701 /**
702 * Keeps track of a display configuration.
703 */
704 private static final class DisplayModeRecord {
705 public final Display.Mode mMode;
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700706
Michael Wright58e829f2015-09-15 00:13:26 +0100707 public DisplayModeRecord(SurfaceControl.PhysicalDisplayInfo phys) {
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700708 mMode = createMode(phys.width, phys.height, phys.refreshRate);
Michael Wright58e829f2015-09-15 00:13:26 +0100709 }
710
711 /**
712 * Returns whether the mode generated by the given PhysicalDisplayInfo matches the mode
713 * contained by the record modulo mode ID.
714 *
715 * Note that this doesn't necessarily mean the the PhysicalDisplayInfos are identical, just
716 * that they generate identical modes.
717 */
718 public boolean hasMatchingMode(SurfaceControl.PhysicalDisplayInfo info) {
719 int modeRefreshRate = Float.floatToIntBits(mMode.getRefreshRate());
720 int displayInfoRefreshRate = Float.floatToIntBits(info.refreshRate);
721 return mMode.getPhysicalWidth() == info.width
722 && mMode.getPhysicalHeight() == info.height
723 && modeRefreshRate == displayInfoRefreshRate;
724 }
725
726 public String toString() {
727 return "DisplayModeRecord{mMode=" + mMode + "}";
Michael Wright3f145a22014-07-22 19:46:03 -0700728 }
Jeff Brown64a55af2012-08-26 02:47:39 -0700729 }
Jeff Browne87bf032012-09-20 18:30:13 -0700730
Ady Abrahama5a21f72019-02-13 16:41:59 -0800731 private final class PhysicalDisplayEventReceiver extends DisplayEventReceiver {
732 PhysicalDisplayEventReceiver(Looper looper) {
Jorim Jaggi34a0cdb2017-06-08 15:40:38 -0700733 super(looper, VSYNC_SOURCE_APP);
Jeff Browne87bf032012-09-20 18:30:13 -0700734 }
735
736 @Override
Dominik Laskowski3316a0a2019-01-25 02:56:41 -0800737 public void onHotplug(long timestampNanos, long physicalDisplayId, boolean connected) {
Jeff Browne87bf032012-09-20 18:30:13 -0700738 synchronized (getSyncRoot()) {
Jesse Halle244db42012-11-08 11:55:14 -0800739 if (connected) {
Dominik Laskowski3316a0a2019-01-25 02:56:41 -0800740 tryConnectDisplayLocked(physicalDisplayId);
Jesse Halle244db42012-11-08 11:55:14 -0800741 } else {
Dominik Laskowski3316a0a2019-01-25 02:56:41 -0800742 tryDisconnectDisplayLocked(physicalDisplayId);
Jesse Halle244db42012-11-08 11:55:14 -0800743 }
Jeff Browne87bf032012-09-20 18:30:13 -0700744 }
745 }
Ady Abrahama5a21f72019-02-13 16:41:59 -0800746
747 @Override
748 public void onConfigChanged(long timestampNanos, long physicalDisplayId, int configId) {
749 if (DEBUG) {
750 Slog.d(TAG, "onConfigChanged("
751 + "timestampNanos=" + timestampNanos
752 + ", builtInDisplayId=" + physicalDisplayId
753 + ", configId=" + configId + ")");
754 }
755 }
Jeff Browne87bf032012-09-20 18:30:13 -0700756 }
Dan Stoza00101052014-05-02 15:23:40 -0700757}