164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown/* 264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * Copyright (C) 2012 The Android Open Source Project 364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * 464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * you may not use this file except in compliance with the License. 664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * You may obtain a copy of the License at 764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * 864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * 1064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * Unless required by applicable law or agreed to in writing, software 1164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 1264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * See the License for the specific language governing permissions and 1464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * limitations under the License. 1564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown */ 1664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown 1764a55af0ac700baecb0877235eb42caac59a3560Jeff Brownpackage com.android.server.display; 1864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown 1949e7ff9647e6547c2b852944a5435a05794b9951Adam Powellimport android.content.res.Resources; 205d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brownimport com.android.server.LocalServices; 215d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brownimport com.android.server.lights.Light; 225d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brownimport com.android.server.lights.LightsManager; 235d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown 2464a55af0ac700baecb0877235eb42caac59a3560Jeff Brownimport android.content.Context; 25d3c454db291e2780c4ad5fe8b5d9e8ce3fbea114Griff Hazenimport android.os.Build; 264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.os.Handler; 2764a55af0ac700baecb0877235eb42caac59a3560Jeff Brownimport android.os.IBinder; 28e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brownimport android.os.Looper; 295d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brownimport android.os.PowerManager; 3027f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brownimport android.os.SystemProperties; 313edf5272fb2185403dfe64b9722b9fc9b9de80f8Jeff Brownimport android.os.Trace; 3200101052b5bf99a29acea3525864ed64b709c16cDan Stozaimport android.util.Slog; 334ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.util.SparseArray; 3492130f6407dc51c58b3b941d28a6daf4e04b8d62Jeff Brownimport android.view.Display; 35e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brownimport android.view.DisplayEventReceiver; 3664a55af0ac700baecb0877235eb42caac59a3560Jeff Brownimport android.view.Surface; 373866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopianimport android.view.SurfaceControl; 3864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown 394ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport java.io.PrintWriter; 40b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligandimport java.util.ArrayList; 4158e829f71d2c525309e5bb5a1c02dc64397df221Michael Wrightimport java.util.Arrays; 421c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wrightimport java.util.Collections; 431c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wrightimport java.util.List; 444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 4564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown/** 4664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown * A display adapter for the local displays managed by Surface Flinger. 47bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * <p> 484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * Display adapters are guarded by the {@link DisplayManagerService.SyncRoot} lock. 49bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * </p> 5064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown */ 514ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownfinal class LocalDisplayAdapter extends DisplayAdapter { 52bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown private static final String TAG = "LocalDisplayAdapter"; 535d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown private static final boolean DEBUG = false; 5464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown 55361ca21acc0831a9f8bbb259bb30218c252a2aa0Wale Ogunwale private static final String UNIQUE_ID_PREFIX = "local:"; 56361ca21acc0831a9f8bbb259bb30218c252a2aa0Wale Ogunwale 5701f280d376218c5a007fc29f70b876375ad24204Adam Powell private static final String PROPERTY_EMULATOR_CIRCULAR = "ro.emulator.circular"; 5801f280d376218c5a007fc29f70b876375ad24204Adam Powell 594ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private static final int[] BUILT_IN_DISPLAY_IDS_TO_SCAN = new int[] { 603866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN, 613866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian SurfaceControl.BUILT_IN_DISPLAY_ID_HDMI, 624ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown }; 634ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 644ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final SparseArray<LocalDisplayDevice> mDevices = 654ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown new SparseArray<LocalDisplayDevice>(); 66b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand @SuppressWarnings("unused") // Becomes active at instantiation time. 6766692500344cab2f53cdb6ee1545c567fff7cb16Jeff Brown private HotplugDisplayEventReceiver mHotplugReceiver; 684ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 6966692500344cab2f53cdb6ee1545c567fff7cb16Jeff Brown // Called with SyncRoot lock held. 704ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public LocalDisplayAdapter(DisplayManagerService.SyncRoot syncRoot, 714ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown Context context, Handler handler, Listener listener) { 724ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown super(syncRoot, context, handler, listener, TAG); 7364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 7464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown 7564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown @Override 764ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void registerLocked() { 774ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown super.registerLocked(); 7866692500344cab2f53cdb6ee1545c567fff7cb16Jeff Brown 7966692500344cab2f53cdb6ee1545c567fff7cb16Jeff Brown mHotplugReceiver = new HotplugDisplayEventReceiver(getHandler().getLooper()); 804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 814ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown for (int builtInDisplayId : BUILT_IN_DISPLAY_IDS_TO_SCAN) { 82e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall tryConnectDisplayLocked(builtInDisplayId); 83e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall } 84e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall } 85e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall 86e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall private void tryConnectDisplayLocked(int builtInDisplayId) { 873866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian IBinder displayToken = SurfaceControl.getBuiltInDisplay(builtInDisplayId); 8800101052b5bf99a29acea3525864ed64b709c16cDan Stoza if (displayToken != null) { 8900101052b5bf99a29acea3525864ed64b709c16cDan Stoza SurfaceControl.PhysicalDisplayInfo[] configs = 9000101052b5bf99a29acea3525864ed64b709c16cDan Stoza SurfaceControl.getDisplayConfigs(displayToken); 9100101052b5bf99a29acea3525864ed64b709c16cDan Stoza if (configs == null) { 9200101052b5bf99a29acea3525864ed64b709c16cDan Stoza // There are no valid configs for this device, so we can't use it 9300101052b5bf99a29acea3525864ed64b709c16cDan Stoza Slog.w(TAG, "No valid configs found for display device " + 9400101052b5bf99a29acea3525864ed64b709c16cDan Stoza builtInDisplayId); 9500101052b5bf99a29acea3525864ed64b709c16cDan Stoza return; 9600101052b5bf99a29acea3525864ed64b709c16cDan Stoza } 9700101052b5bf99a29acea3525864ed64b709c16cDan Stoza int activeConfig = SurfaceControl.getActiveConfig(displayToken); 9800101052b5bf99a29acea3525864ed64b709c16cDan Stoza if (activeConfig < 0) { 9900101052b5bf99a29acea3525864ed64b709c16cDan Stoza // There is no active config, and for now we don't have the 10000101052b5bf99a29acea3525864ed64b709c16cDan Stoza // policy to set one. 10100101052b5bf99a29acea3525864ed64b709c16cDan Stoza Slog.w(TAG, "No active config found for display device " + 10200101052b5bf99a29acea3525864ed64b709c16cDan Stoza builtInDisplayId); 10300101052b5bf99a29acea3525864ed64b709c16cDan Stoza return; 10400101052b5bf99a29acea3525864ed64b709c16cDan Stoza } 1051c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright int activeColorMode = SurfaceControl.getActiveColorMode(displayToken); 1061c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright if (activeColorMode < 0) { 1071c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright // We failed to get the active color mode. We don't bail out here since on the next 1081c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright // configuration pass we'll go ahead and set it to whatever it was set to last (or 1091c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright // COLOR_MODE_NATIVE if this is the first configuration). 1101c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright Slog.w(TAG, "Unable to get active color mode for display device " + 1111c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright builtInDisplayId); 1121c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright activeColorMode = Display.COLOR_MODE_INVALID; 1131c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright } 1141c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright int[] colorModes = SurfaceControl.getDisplayColorModes(displayToken); 115e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall LocalDisplayDevice device = mDevices.get(builtInDisplayId); 116e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall if (device == null) { 117e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall // Display was added. 11800101052b5bf99a29acea3525864ed64b709c16cDan Stoza device = new LocalDisplayDevice(displayToken, builtInDisplayId, 1191c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright configs, activeConfig, colorModes, activeColorMode); 120e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall mDevices.put(builtInDisplayId, device); 121e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED); 1221c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright } else if (device.updatePhysicalDisplayInfoLocked(configs, activeConfig, 1231c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright colorModes, activeColorMode)) { 124e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall // Display properties changed. 125e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_CHANGED); 1264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 127e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall } else { 128e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall // The display is no longer available. Ignore the attempt to add it. 129e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall // If it was connected but has already been disconnected, we'll get a 130e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall // disconnect event that will remove it from mDevices. 131e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall } 132e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall } 133e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall 134e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall private void tryDisconnectDisplayLocked(int builtInDisplayId) { 135e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall LocalDisplayDevice device = mDevices.get(builtInDisplayId); 136e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall if (device != null) { 137e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall // Display was removed. 138e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall mDevices.remove(builtInDisplayId); 139e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_REMOVED); 1404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 14164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 14264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown 143c55929a2a5686fe456b19cd54a73b8bde2a4332bPrashant Malani static int getPowerModeForState(int state) { 144c55929a2a5686fe456b19cd54a73b8bde2a4332bPrashant Malani switch (state) { 145c55929a2a5686fe456b19cd54a73b8bde2a4332bPrashant Malani case Display.STATE_OFF: 146c55929a2a5686fe456b19cd54a73b8bde2a4332bPrashant Malani return SurfaceControl.POWER_MODE_OFF; 1475dc219142a756d57355b511c8f8ab913c01710daJeff Brown case Display.STATE_DOZE: 148c55929a2a5686fe456b19cd54a73b8bde2a4332bPrashant Malani return SurfaceControl.POWER_MODE_DOZE; 1495dc219142a756d57355b511c8f8ab913c01710daJeff Brown case Display.STATE_DOZE_SUSPEND: 1505dc219142a756d57355b511c8f8ab913c01710daJeff Brown return SurfaceControl.POWER_MODE_DOZE_SUSPEND; 151c55929a2a5686fe456b19cd54a73b8bde2a4332bPrashant Malani default: 152c55929a2a5686fe456b19cd54a73b8bde2a4332bPrashant Malani return SurfaceControl.POWER_MODE_NORMAL; 153c55929a2a5686fe456b19cd54a73b8bde2a4332bPrashant Malani } 15444b1f76474218349c9327da9fe482e19aad98795Jeff Brown } 15544b1f76474218349c9327da9fe482e19aad98795Jeff Brown 15664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown private final class LocalDisplayDevice extends DisplayDevice { 1574ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final int mBuiltInDisplayId; 1585d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown private final Light mBacklight; 159b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand private final SparseArray<DisplayModeRecord> mSupportedModes = new SparseArray<>(); 1601c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright private final ArrayList<Integer> mSupportedColorModes = new ArrayList<>(); 16164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown 1624ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private DisplayDeviceInfo mInfo; 1634ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private boolean mHavePendingChanges; 164037c33eae74bee2774897d969d48947f9abe254fJeff Brown private int mState = Display.STATE_UNKNOWN; 1655d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown private int mBrightness = PowerManager.BRIGHTNESS_DEFAULT; 16658e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright private int mActivePhysIndex; 167b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand private int mDefaultModeId; 168b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand private int mActiveModeId; 169b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand private boolean mActiveModeInvalid; 1701c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright private int mActiveColorMode; 1711c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright private boolean mActiveColorModeInvalid; 1729ff94c0251722c44eece7c3561b4ed36b286d4a8Michael Wright private Display.HdrCapabilities mHdrCapabilities; 17358e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright 17458e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright private SurfaceControl.PhysicalDisplayInfo mDisplayInfos[]; 1755d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown 1764ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public LocalDisplayDevice(IBinder displayToken, int builtInDisplayId, 1771c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo, 1781c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright int[] colorModes, int activeColorMode) { 179361ca21acc0831a9f8bbb259bb30218c252a2aa0Wale Ogunwale super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + builtInDisplayId); 1804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mBuiltInDisplayId = builtInDisplayId; 1811c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright updatePhysicalDisplayInfoLocked(physicalDisplayInfos, activeDisplayInfo, 1821c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright colorModes, activeColorMode); 1831c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright updateColorModesLocked(colorModes, activeColorMode); 1845d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) { 1855d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown LightsManager lights = LocalServices.getService(LightsManager.class); 1865d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT); 1875d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown } else { 1885d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown mBacklight = null; 1895d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown } 1909ff94c0251722c44eece7c3561b4ed36b286d4a8Michael Wright mHdrCapabilities = SurfaceControl.getHdrCapabilities(displayToken); 1914ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1924ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1931c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright @Override 1941c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright public boolean hasStableUniqueId() { 1951c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright return true; 1961c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright } 1971c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright 1983f145a2f958320766ae9240c7a57debc20d578aaMichael Wright public boolean updatePhysicalDisplayInfoLocked( 1991c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo, 2001c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright int[] colorModes, int activeColorMode) { 20158e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright mDisplayInfos = Arrays.copyOf(physicalDisplayInfos, physicalDisplayInfos.length); 20258e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright mActivePhysIndex = activeDisplayInfo; 203b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand // Build an updated list of all existing modes. 204b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand ArrayList<DisplayModeRecord> records = new ArrayList<DisplayModeRecord>(); 20558e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright boolean modesAdded = false; 206b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand for (int i = 0; i < physicalDisplayInfos.length; i++) { 207b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand SurfaceControl.PhysicalDisplayInfo info = physicalDisplayInfos[i]; 20858e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright // First, check to see if we've already added a matching mode. Since not all 20958e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright // configuration options are exposed via Display.Mode, it's possible that we have 21058e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright // multiple PhysicalDisplayInfos that would generate the same Display.Mode. 21158e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright boolean existingMode = false; 21258e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright for (int j = 0; j < records.size(); j++) { 21358e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright if (records.get(j).hasMatchingMode(info)) { 21458e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright existingMode = true; 21558e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright break; 21658e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright } 21758e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright } 21858e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright if (existingMode) { 21958e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright continue; 22058e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright } 22158e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright // If we haven't already added a mode for this configuration to the new set of 22258e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright // supported modes then check to see if we have one in the prior set of supported 22358e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright // modes to reuse. 224b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand DisplayModeRecord record = findDisplayModeRecord(info); 22558e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright if (record == null) { 22658e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright record = new DisplayModeRecord(info); 227b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand modesAdded = true; 228b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand } 229b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand records.add(record); 23058e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright } 23158e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright 23258e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright // Get the currently active mode 23358e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright DisplayModeRecord activeRecord = null; 23458e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright for (int i = 0; i < records.size(); i++) { 23558e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright DisplayModeRecord record = records.get(i); 23658e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright if (record.hasMatchingMode(physicalDisplayInfos[activeDisplayInfo])){ 237b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand activeRecord = record; 23858e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright break; 239b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand } 240b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand } 241b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand // Check whether surface flinger spontaneously changed modes out from under us. Schedule 242b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand // traversals to ensure that the correct state is reapplied if necessary. 243b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand if (mActiveModeId != 0 244b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand && mActiveModeId != activeRecord.mMode.getModeId()) { 245b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand mActiveModeInvalid = true; 246b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand sendTraversalRequestLocked(); 247b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand } 24858e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright 24958e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright boolean recordsChanged = records.size() != mSupportedModes.size() || modesAdded; 2501c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright // If the records haven't changed then we're done here. 2511c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright if (!recordsChanged) { 252b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand return false; 253b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand } 254b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand // Update the index of modes. 255b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand mHavePendingChanges = true; 25658e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright 257b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand mSupportedModes.clear(); 258b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand for (DisplayModeRecord record : records) { 259b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand mSupportedModes.put(record.mMode.getModeId(), record); 260b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand } 2611c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright // Update the default mode, if needed. 2621c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright if (findDisplayInfoIndexLocked(mDefaultModeId) < 0) { 263b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand if (mDefaultModeId != 0) { 26458e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright Slog.w(TAG, "Default display mode no longer available, using currently" 26558e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright + " active mode as default."); 266b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand } 267b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand mDefaultModeId = activeRecord.mMode.getModeId(); 268b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand } 269b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand // Determine whether the active mode is still there. 270b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand if (mSupportedModes.indexOfKey(mActiveModeId) < 0) { 271b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand if (mActiveModeId != 0) { 272b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand Slog.w(TAG, "Active display mode no longer available, reverting to default" 273b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand + " mode."); 274b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand } 275b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand mActiveModeId = mDefaultModeId; 276b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand mActiveModeInvalid = true; 277b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand } 27858e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright 279b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand // Schedule traversals so that we apply pending changes. 280b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand sendTraversalRequestLocked(); 281b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand return true; 282b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand } 283b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand 2841c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright private boolean updateColorModesLocked(int[] colorModes, 2851c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright int activeColorMode) { 2861c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright List<Integer> pendingColorModes = new ArrayList<>(); 2871c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright 288b34c8104cbb8acc554c4039a2a283ea4d1fcc92fthecrazyskull if (colorModes == null) return false; 2891c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright // Build an updated list of all existing color modes. 2901c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright boolean colorModesAdded = false; 2911c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright for (int colorMode: colorModes) { 2921c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright if (!mSupportedColorModes.contains(colorMode)) { 2931c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright colorModesAdded = true; 2941c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright } 2951c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright pendingColorModes.add(colorMode); 2961c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright } 2971c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright 2981c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright boolean colorModesChanged = 2991c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright pendingColorModes.size() != mSupportedColorModes.size() 3001c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright || colorModesAdded; 3011c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright 3021c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright // If the supported color modes haven't changed then we're done here. 3031c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright if (!colorModesChanged) { 3041c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright return false; 3051c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright } 3061c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright 3071c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright mHavePendingChanges = true; 3081c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright 3091c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright mSupportedColorModes.clear(); 3101c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright mSupportedColorModes.addAll(pendingColorModes); 3111c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright Collections.sort(mSupportedColorModes); 3121c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright 3131c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright // Determine whether the active color mode is still there. 3141c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright if (!mSupportedColorModes.contains(mActiveColorMode)) { 3151c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright if (mActiveColorMode != 0) { 3161c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright Slog.w(TAG, "Active color mode no longer available, reverting" 3171c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright + " to default mode."); 3181c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright mActiveColorMode = Display.COLOR_MODE_DEFAULT; 3191c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright mActiveColorModeInvalid = true; 3201c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright } else { 3211c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright if (!mSupportedColorModes.isEmpty()) { 3221c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright // This should never happen. 3231c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright Slog.e(TAG, "Default and active color mode is no longer available!" 3241c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright + " Reverting to first available mode."); 3251c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright mActiveColorMode = mSupportedColorModes.get(0); 3261c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright mActiveColorModeInvalid = true; 3271c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright } else { 3281c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright // This should really never happen. 3291c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright Slog.e(TAG, "No color modes available!"); 3301c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright } 3311c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright } 3321c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright } 3331c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright return true; 3341c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright } 3351c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright 336b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand private DisplayModeRecord findDisplayModeRecord(SurfaceControl.PhysicalDisplayInfo info) { 337b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand for (int i = 0; i < mSupportedModes.size(); i++) { 338b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand DisplayModeRecord record = mSupportedModes.valueAt(i); 33958e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright if (record.hasMatchingMode(info)) { 340b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand return record; 341b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand } 3424ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 343b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand return null; 34464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 34564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown 34664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown @Override 3474ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void applyPendingDisplayDeviceInfoChangesLocked() { 3484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (mHavePendingChanges) { 3494ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mInfo = null; 3504ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mHavePendingChanges = false; 351bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 35264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 3534ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3544ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 3554ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public DisplayDeviceInfo getDisplayDeviceInfoLocked() { 3564ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (mInfo == null) { 35758e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright SurfaceControl.PhysicalDisplayInfo phys = mDisplayInfos[mActivePhysIndex]; 3584ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mInfo = new DisplayDeviceInfo(); 359b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand mInfo.width = phys.width; 360b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand mInfo.height = phys.height; 361b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand mInfo.modeId = mActiveModeId; 362b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand mInfo.defaultModeId = mDefaultModeId; 363b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand mInfo.supportedModes = new Display.Mode[mSupportedModes.size()]; 364b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand for (int i = 0; i < mSupportedModes.size(); i++) { 365b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand DisplayModeRecord record = mSupportedModes.valueAt(i); 366b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand mInfo.supportedModes[i] = record.mMode; 367b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand } 3681c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright mInfo.colorMode = mActiveColorMode; 3691c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright mInfo.supportedColorModes = 3701c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright new int[mSupportedColorModes.size()]; 3711c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright for (int i = 0; i < mSupportedColorModes.size(); i++) { 3721c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright mInfo.supportedColorModes[i] = mSupportedColorModes.get(i); 37358e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright } 3749ff94c0251722c44eece7c3561b4ed36b286d4a8Michael Wright mInfo.hdrCapabilities = mHdrCapabilities; 375b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand mInfo.appVsyncOffsetNanos = phys.appVsyncOffsetNanos; 376b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand mInfo.presentationDeadlineNanos = phys.presentationDeadlineNanos; 377037c33eae74bee2774897d969d48947f9abe254fJeff Brown mInfo.state = mState; 378361ca21acc0831a9f8bbb259bb30218c252a2aa0Wale Ogunwale mInfo.uniqueId = getUniqueId(); 37977aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown 380f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown // Assume that all built-in displays that have secure output (eg. HDCP) also 38177aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown // support compositing from gralloc protected buffers. 382b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand if (phys.secure) { 383f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown mInfo.flags = DisplayDeviceInfo.FLAG_SECURE 384f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown | DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS; 385f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown } 38677aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown 3874b0fa173defb5c31832ddccf86485fb35f10dae2Michael Wright final Resources res = getContext().getResources(); 3883866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) { 38949e7ff9647e6547c2b852944a5435a05794b9951Adam Powell mInfo.name = res.getString( 3904ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown com.android.internal.R.string.display_manager_built_in_display_name); 39177aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY 39227f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown | DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT; 39301f280d376218c5a007fc29f70b876375ad24204Adam Powell if (res.getBoolean(com.android.internal.R.bool.config_mainBuiltInDisplayIsRound) 394d3c454db291e2780c4ad5fe8b5d9e8ce3fbea114Griff Hazen || (Build.IS_EMULATOR 39501f280d376218c5a007fc29f70b876375ad24204Adam Powell && SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false))) { 39649e7ff9647e6547c2b852944a5435a05794b9951Adam Powell mInfo.flags |= DisplayDeviceInfo.FLAG_ROUND; 39749e7ff9647e6547c2b852944a5435a05794b9951Adam Powell } 39892130f6407dc51c58b3b941d28a6daf4e04b8d62Jeff Brown mInfo.type = Display.TYPE_BUILT_IN; 399b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand mInfo.densityDpi = (int)(phys.density * 160 + 0.5f); 400b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand mInfo.xDpi = phys.xDpi; 401b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand mInfo.yDpi = phys.yDpi; 402d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown mInfo.touch = DisplayDeviceInfo.TOUCH_INTERNAL; 4034ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } else { 40492130f6407dc51c58b3b941d28a6daf4e04b8d62Jeff Brown mInfo.type = Display.TYPE_HDMI; 4057d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown mInfo.flags |= DisplayDeviceInfo.FLAG_PRESENTATION; 4064ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mInfo.name = getContext().getResources().getString( 4074ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown com.android.internal.R.string.display_manager_hdmi_display_name); 408d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown mInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL; 409b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand mInfo.setAssumedDensityForExternalDisplay(phys.width, phys.height); 41027f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown 41127f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown // For demonstration purposes, allow rotation of the external display. 41227f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown // In the future we might allow the user to configure this directly. 41327f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) { 41427f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown mInfo.rotation = Surface.ROTATION_270; 41527f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown } 4168786ed9b2bfa912a84e298d907bb4d89482d78f9Scott Anderson 4178786ed9b2bfa912a84e298d907bb4d89482d78f9Scott Anderson // For demonstration purposes, allow rotation of the external display 4188786ed9b2bfa912a84e298d907bb4d89482d78f9Scott Anderson // to follow the built-in display. 4198786ed9b2bfa912a84e298d907bb4d89482d78f9Scott Anderson if (SystemProperties.getBoolean("persist.demo.hdmirotates", false)) { 4208786ed9b2bfa912a84e298d907bb4d89482d78f9Scott Anderson mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT; 4218786ed9b2bfa912a84e298d907bb4d89482d78f9Scott Anderson } 4224b0fa173defb5c31832ddccf86485fb35f10dae2Michael Wright 4234b0fa173defb5c31832ddccf86485fb35f10dae2Michael Wright if (!res.getBoolean( 4244b0fa173defb5c31832ddccf86485fb35f10dae2Michael Wright com.android.internal.R.bool.config_localDisplaysMirrorContent)) { 4254b0fa173defb5c31832ddccf86485fb35f10dae2Michael Wright mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY; 4264b0fa173defb5c31832ddccf86485fb35f10dae2Michael Wright } 4274ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 4284ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 4294ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return mInfo; 4304ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 4314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 4324ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 4335d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown public Runnable requestDisplayStateLocked(final int state, final int brightness) { 4345d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown // Assume that the brightness is off if the display is being turned off. 4355d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown assert state != Display.STATE_OFF || brightness == PowerManager.BRIGHTNESS_OFF; 4365d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown 4375d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown final boolean stateChanged = (mState != state); 4385d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown final boolean brightnessChanged = (mBrightness != brightness) && mBacklight != null; 4395d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown if (stateChanged || brightnessChanged) { 440e75926d6dc49878682631508c996e472d79a8d41Jeff Brown final int displayId = mBuiltInDisplayId; 441e75926d6dc49878682631508c996e472d79a8d41Jeff Brown final IBinder token = getDisplayTokenLocked(); 4425d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown final int oldState = mState; 4435d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown 4445d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown if (stateChanged) { 4455d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown mState = state; 4465d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown updateDeviceInfoLocked(); 4475d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown } 448e75926d6dc49878682631508c996e472d79a8d41Jeff Brown 4495d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown if (brightnessChanged) { 4505d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown mBrightness = brightness; 4515d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown } 4525d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown 4535d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown // Defer actually setting the display state until after we have exited 454e75926d6dc49878682631508c996e472d79a8d41Jeff Brown // the critical section since it can take hundreds of milliseconds 455e75926d6dc49878682631508c996e472d79a8d41Jeff Brown // to complete. 456e75926d6dc49878682631508c996e472d79a8d41Jeff Brown return new Runnable() { 457e75926d6dc49878682631508c996e472d79a8d41Jeff Brown @Override 458e75926d6dc49878682631508c996e472d79a8d41Jeff Brown public void run() { 4595d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown // Exit a suspended state before making any changes. 4605d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown int currentState = oldState; 4615d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown if (Display.isSuspendedState(oldState) 4625d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown || oldState == Display.STATE_UNKNOWN) { 4635d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown if (!Display.isSuspendedState(state)) { 4645d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown setDisplayState(state); 4655d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown currentState = state; 4665d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown } else if (state == Display.STATE_DOZE_SUSPEND 4675d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown || oldState == Display.STATE_DOZE_SUSPEND) { 4685d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown setDisplayState(Display.STATE_DOZE); 4695d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown currentState = Display.STATE_DOZE; 4705d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown } else { 4715d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown return; // old state and new state is off 4725d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown } 4735d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown } 4745d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown 475d6a5660a2c9f70c9a363d388a091542a378d57d1Santos Cordon // If the state change was from or to VR, then we need to tell the light 47666855315850bda0a0184a56bdd3099f4faa8b984Karthik Ravi Shankar // so that it can apply appropriate VR brightness settings. Also, update the 47766855315850bda0a0184a56bdd3099f4faa8b984Karthik Ravi Shankar // brightness so the state is propogated to light. 47866855315850bda0a0184a56bdd3099f4faa8b984Karthik Ravi Shankar boolean vrModeChange = false; 479d6a5660a2c9f70c9a363d388a091542a378d57d1Santos Cordon if ((state == Display.STATE_VR || currentState == Display.STATE_VR) && 480d6a5660a2c9f70c9a363d388a091542a378d57d1Santos Cordon currentState != state) { 481d6a5660a2c9f70c9a363d388a091542a378d57d1Santos Cordon setVrMode(state == Display.STATE_VR); 48266855315850bda0a0184a56bdd3099f4faa8b984Karthik Ravi Shankar vrModeChange = true; 483d6a5660a2c9f70c9a363d388a091542a378d57d1Santos Cordon } 484d6a5660a2c9f70c9a363d388a091542a378d57d1Santos Cordon 485d6a5660a2c9f70c9a363d388a091542a378d57d1Santos Cordon 4865d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown // Apply brightness changes given that we are in a non-suspended state. 48766855315850bda0a0184a56bdd3099f4faa8b984Karthik Ravi Shankar if (brightnessChanged || vrModeChange) { 4885d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown setDisplayBrightness(brightness); 4895d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown } 4905d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown 4915d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown // Enter the final desired state, possibly suspended. 4925d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown if (state != currentState) { 4935d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown setDisplayState(state); 4945d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown } 4955d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown } 4965d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown 497d6a5660a2c9f70c9a363d388a091542a378d57d1Santos Cordon private void setVrMode(boolean isVrEnabled) { 498d6a5660a2c9f70c9a363d388a091542a378d57d1Santos Cordon if (DEBUG) { 499d6a5660a2c9f70c9a363d388a091542a378d57d1Santos Cordon Slog.d(TAG, "setVrMode(" 500d6a5660a2c9f70c9a363d388a091542a378d57d1Santos Cordon + "id=" + displayId 501d6a5660a2c9f70c9a363d388a091542a378d57d1Santos Cordon + ", state=" + Display.stateToString(state) + ")"); 502d6a5660a2c9f70c9a363d388a091542a378d57d1Santos Cordon } 503d6a5660a2c9f70c9a363d388a091542a378d57d1Santos Cordon mBacklight.setVrMode(isVrEnabled); 504d6a5660a2c9f70c9a363d388a091542a378d57d1Santos Cordon } 505d6a5660a2c9f70c9a363d388a091542a378d57d1Santos Cordon 5065d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown private void setDisplayState(int state) { 5075d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown if (DEBUG) { 5085d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown Slog.d(TAG, "setDisplayState(" 5095d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown + "id=" + displayId 5105d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown + ", state=" + Display.stateToString(state) + ")"); 5115d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown } 5125d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown 5135d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayState(" 5145d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown + "id=" + displayId 5155d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown + ", state=" + Display.stateToString(state) + ")"); 516e75926d6dc49878682631508c996e472d79a8d41Jeff Brown try { 5175d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown final int mode = getPowerModeForState(state); 518e75926d6dc49878682631508c996e472d79a8d41Jeff Brown SurfaceControl.setDisplayPowerMode(token, mode); 519c3e6af876933a5aa7daac096a56988a42053d4f3Michael Wright Trace.traceCounter(Trace.TRACE_TAG_POWER, "DisplayPowerMode", mode); 520e75926d6dc49878682631508c996e472d79a8d41Jeff Brown } finally { 521e75926d6dc49878682631508c996e472d79a8d41Jeff Brown Trace.traceEnd(Trace.TRACE_TAG_POWER); 522e75926d6dc49878682631508c996e472d79a8d41Jeff Brown } 523e75926d6dc49878682631508c996e472d79a8d41Jeff Brown } 5245d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown 5255d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown private void setDisplayBrightness(int brightness) { 5265d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown if (DEBUG) { 5275d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown Slog.d(TAG, "setDisplayBrightness(" 5285d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown + "id=" + displayId + ", brightness=" + brightness + ")"); 5295d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown } 5305d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown 5315d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayBrightness(" 5325d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown + "id=" + displayId + ", brightness=" + brightness + ")"); 5335d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown try { 5345d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown mBacklight.setBrightness(brightness); 535c3e6af876933a5aa7daac096a56988a42053d4f3Michael Wright Trace.traceCounter(Trace.TRACE_TAG_POWER, 536a9f37abc7d3205f1f2aaca7c8bfcf1cdc7d99959Michael Wright "ScreenBrightness", brightness); 5375d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown } finally { 5385d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown Trace.traceEnd(Trace.TRACE_TAG_POWER); 5395d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown } 5405d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown } 541e75926d6dc49878682631508c996e472d79a8d41Jeff Brown }; 542037c33eae74bee2774897d969d48947f9abe254fJeff Brown } 543e75926d6dc49878682631508c996e472d79a8d41Jeff Brown return null; 5449e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown } 5459e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown 5469e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown @Override 5471c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright public void requestDisplayModesInTransactionLocked( 5481c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright int colorMode, int modeId) { 5491c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright if (requestModeInTransactionLocked(modeId) || 5501c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright requestColorModeInTransactionLocked(colorMode)) { 5511c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright updateDeviceInfoLocked(); 5521c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright } 5531c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright } 5541c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright 5551c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright public boolean requestModeInTransactionLocked(int modeId) { 556b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand if (modeId == 0) { 557b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand modeId = mDefaultModeId; 558b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand } else if (mSupportedModes.indexOfKey(modeId) < 0) { 559b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand Slog.w(TAG, "Requested mode " + modeId + " is not supported by this display," 560b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand + " reverting to default display mode."); 561b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand modeId = mDefaultModeId; 5623f145a2f958320766ae9240c7a57debc20d578aaMichael Wright } 56358e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright 5641c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright int physIndex = findDisplayInfoIndexLocked(modeId); 56558e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright if (physIndex < 0) { 5661c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright Slog.w(TAG, "Requested mode ID " + modeId + " not available," 5671c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright + " trying with default mode ID"); 56858e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright modeId = mDefaultModeId; 5691c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright physIndex = findDisplayInfoIndexLocked(modeId); 57058e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright } 5713b3cbb5325e1a8bce09200644b5667fb321d9b90Jorim Jaggi if (mActivePhysIndex == physIndex) { 5721c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright return false; 5733f145a2f958320766ae9240c7a57debc20d578aaMichael Wright } 57458e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright SurfaceControl.setActiveConfig(getDisplayTokenLocked(), physIndex); 57558e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright mActivePhysIndex = physIndex; 576b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand mActiveModeId = modeId; 577b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand mActiveModeInvalid = false; 5781c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright return true; 5791c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright } 5801c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright 5811c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright public boolean requestColorModeInTransactionLocked(int colorMode) { 5821c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright if (mActiveColorMode == colorMode) { 5831c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright return false; 5841c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright } 5851c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright if (!mSupportedColorModes.contains(colorMode)) { 5861c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright Slog.w(TAG, "Unable to find color mode " + colorMode 5871c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright + ", ignoring request."); 5881c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright return false; 5891c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright } 5901c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright SurfaceControl.setActiveColorMode(getDisplayTokenLocked(), colorMode); 5911c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright mActiveColorMode = colorMode; 5921c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright mActiveColorModeInvalid = false; 5931c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright return true; 5943f145a2f958320766ae9240c7a57debc20d578aaMichael Wright } 5953f145a2f958320766ae9240c7a57debc20d578aaMichael Wright 5963f145a2f958320766ae9240c7a57debc20d578aaMichael Wright @Override 5974ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void dumpLocked(PrintWriter pw) { 5984ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown super.dumpLocked(pw); 5994ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown pw.println("mBuiltInDisplayId=" + mBuiltInDisplayId); 60058e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright pw.println("mActivePhysIndex=" + mActivePhysIndex); 601b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand pw.println("mActiveModeId=" + mActiveModeId); 6021c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright pw.println("mActiveColorMode=" + mActiveColorMode); 603037c33eae74bee2774897d969d48947f9abe254fJeff Brown pw.println("mState=" + Display.stateToString(mState)); 6045d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown pw.println("mBrightness=" + mBrightness); 6055d6443bf7c087167e47ea39b13e6af09cb43ad97Jeff Brown pw.println("mBacklight=" + mBacklight); 60658e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright pw.println("mDisplayInfos="); 60758e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright for (int i = 0; i < mDisplayInfos.length; i++) { 60858e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright pw.println(" " + mDisplayInfos[i]); 60958e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright } 61058e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright pw.println("mSupportedModes="); 61158e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright for (int i = 0; i < mSupportedModes.size(); i++) { 61258e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright pw.println(" " + mSupportedModes.valueAt(i)); 61358e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright } 6141c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright pw.print("mSupportedColorModes=["); 6151c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright for (int i = 0; i < mSupportedColorModes.size(); i++) { 61658e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright if (i != 0) { 61758e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright pw.print(", "); 61858e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright } 6191c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright pw.print(mSupportedColorModes.get(i)); 62058e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright } 62158e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright pw.println("]"); 62258e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright } 62358e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright 6241c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright private int findDisplayInfoIndexLocked(int modeId) { 62558e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright DisplayModeRecord record = mSupportedModes.get(modeId); 6261c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright if (record != null) { 62758e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright for (int i = 0; i < mDisplayInfos.length; i++) { 62858e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright SurfaceControl.PhysicalDisplayInfo info = mDisplayInfos[i]; 6291c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright if (record.hasMatchingMode(info)){ 63058e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright return i; 63158e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright } 63258e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright } 63358e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright } 63458e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright return -1; 635037c33eae74bee2774897d969d48947f9abe254fJeff Brown } 636037c33eae74bee2774897d969d48947f9abe254fJeff Brown 637037c33eae74bee2774897d969d48947f9abe254fJeff Brown private void updateDeviceInfoLocked() { 638037c33eae74bee2774897d969d48947f9abe254fJeff Brown mInfo = null; 639037c33eae74bee2774897d969d48947f9abe254fJeff Brown sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED); 6404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 641b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand } 6423f145a2f958320766ae9240c7a57debc20d578aaMichael Wright 643b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand /** 644b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand * Keeps track of a display configuration. 645b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand */ 646b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand private static final class DisplayModeRecord { 647b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand public final Display.Mode mMode; 648b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand 64958e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright public DisplayModeRecord(SurfaceControl.PhysicalDisplayInfo phys) { 650b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand mMode = createMode(phys.width, phys.height, phys.refreshRate); 65158e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright } 65258e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright 65358e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright /** 65458e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright * Returns whether the mode generated by the given PhysicalDisplayInfo matches the mode 65558e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright * contained by the record modulo mode ID. 65658e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright * 65758e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright * Note that this doesn't necessarily mean the the PhysicalDisplayInfos are identical, just 65858e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright * that they generate identical modes. 65958e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright */ 66058e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright public boolean hasMatchingMode(SurfaceControl.PhysicalDisplayInfo info) { 66158e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright int modeRefreshRate = Float.floatToIntBits(mMode.getRefreshRate()); 66258e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright int displayInfoRefreshRate = Float.floatToIntBits(info.refreshRate); 66358e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright return mMode.getPhysicalWidth() == info.width 66458e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright && mMode.getPhysicalHeight() == info.height 66558e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright && modeRefreshRate == displayInfoRefreshRate; 66658e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright } 66758e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright 66858e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright public String toString() { 66958e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright return "DisplayModeRecord{mMode=" + mMode + "}"; 6703f145a2f958320766ae9240c7a57debc20d578aaMichael Wright } 67164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown } 672e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown 673e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown private final class HotplugDisplayEventReceiver extends DisplayEventReceiver { 674e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown public HotplugDisplayEventReceiver(Looper looper) { 67534a0cdb98eb5561774ea4e7b3b602aad80c4a3ccJorim Jaggi super(looper, VSYNC_SOURCE_APP); 676e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown } 677e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown 678e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown @Override 679e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown public void onHotplug(long timestampNanos, int builtInDisplayId, boolean connected) { 680e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown synchronized (getSyncRoot()) { 681e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall if (connected) { 682e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall tryConnectDisplayLocked(builtInDisplayId); 683e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall } else { 684e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall tryDisconnectDisplayLocked(builtInDisplayId); 685e244db42da1cb07f53a1fc921b45d498000b56e8Jesse Hall } 686e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown } 687e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown } 688e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown } 68900101052b5bf99a29acea3525864ed64b709c16cDan Stoza} 690