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