DisplayManagerService.java revision 0bf6ec9e377f9fafb67a36f7fb54d3f6676634fc
1fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown/*
2fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * Copyright (C) 2012 The Android Open Source Project
3fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown *
4fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
5fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * you may not use this file except in compliance with the License.
6fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * You may obtain a copy of the License at
7fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown *
8fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
9fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown *
10fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * Unless required by applicable law or agreed to in writing, software
11fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
12fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * See the License for the specific language governing permissions and
14fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * limitations under the License.
15fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown */
16fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown
17fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownpackage com.android.server.display;
18fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown
19bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport com.android.internal.util.IndentingPrintWriter;
20bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
21fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownimport android.Manifest;
22fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownimport android.content.Context;
23fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownimport android.content.pm.PackageManager;
24bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.hardware.display.DisplayManagerGlobal;
25fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownimport android.hardware.display.IDisplayManager;
26bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.hardware.display.IDisplayManagerCallback;
27e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brownimport android.hardware.display.WifiDisplayStatus;
28fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownimport android.os.Binder;
29bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.os.Handler;
3064a55af0ac700baecb0877235eb42caac59a3560Jeff Brownimport android.os.IBinder;
31bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.os.Looper;
32bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.os.Message;
33bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.os.RemoteException;
34bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.os.SystemClock;
35fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownimport android.os.SystemProperties;
36bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.util.Slog;
37bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.util.SparseArray;
38fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownimport android.view.Display;
39fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownimport android.view.DisplayInfo;
40fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown
41fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownimport java.io.FileDescriptor;
42fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownimport java.io.PrintWriter;
43fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownimport java.util.ArrayList;
447f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brownimport java.util.concurrent.CopyOnWriteArrayList;
45fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown
46fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown/**
47bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * Manages attached displays.
48fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * <p>
49bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * The {@link DisplayManagerService} manages the global lifecycle of displays,
50bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * decides how to configure logical displays based on the physical display devices currently
51bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * attached, sends notifications to the system and to applications when the state
52bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * changes, and so on.
53bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * </p><p>
54bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * The display manager service relies on a collection of {@link DisplayAdapter} components,
55bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * for discovering and configuring physical display devices attached to the system.
56bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * There are separate display adapters for each manner that devices are attached:
57bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * one display adapter for built-in local displays, one for simulated non-functional
58bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * displays when the system is headless, one for simulated overlay displays used for
59bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * development, one for wifi displays, etc.
60bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * </p><p>
61bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * Display adapters are only weakly coupled to the display manager service.
62bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * Display adapters communicate changes in display device state to the display manager
63722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner * service asynchronously via a {@link DisplayAdapter.Listener} registered
64bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * by the display manager service.  This separation of concerns is important for
65bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * two main reasons.  First, it neatly encapsulates the responsibilities of these
66bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * two classes: display adapters handle individual display devices whereas
67bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * the display manager service handles the global state.  Second, it eliminates
68bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * the potential for deadlocks resulting from asynchronous display device discovery.
694ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * </p>
704ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown *
714ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * <h3>Synchronization</h3>
724ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * <p>
734ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * Because the display manager may be accessed by multiple threads, the synchronization
744ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * story gets a little complicated.  In particular, the window manager may call into
754ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * the display manager while holding a surface transaction with the expectation that
764ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * it can apply changes immediately.  Unfortunately, that means we can't just do
774ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * everything asynchronously (*grump*).
78bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * </p><p>
794ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * To make this work, all of the objects that belong to the display manager must
804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * use the same lock.  We call this lock the synchronization root and it has a unique
814ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * type {@link DisplayManagerService.SyncRoot}.  Methods that require this lock are
824ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * named with the "Locked" suffix.
834ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * </p><p>
844ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * Where things get tricky is that the display manager is not allowed to make
854ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * any potentially reentrant calls, especially into the window manager.  We generally
864ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * avoid this by making all potentially reentrant out-calls asynchronous.
87fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * </p>
88fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown */
89fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownpublic final class DisplayManagerService extends IDisplayManager.Stub {
90fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown    private static final String TAG = "DisplayManagerService";
91bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final boolean DEBUG = false;
92fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown
93bbd28a293f84baeafed469c5e223eff82c1117c0Jeff Brown    // When this system property is set to 0, WFD is forcibly disabled on boot.
94bbd28a293f84baeafed469c5e223eff82c1117c0Jeff Brown    // When this system property is set to 1, WFD is forcibly enabled on boot.
95bbd28a293f84baeafed469c5e223eff82c1117c0Jeff Brown    // Otherwise WFD is enabled according to the value of config_enableWifiDisplay.
96bbd28a293f84baeafed469c5e223eff82c1117c0Jeff Brown    private static final String FORCE_WIFI_DISPLAY_ENABLE = "persist.debug.wfd.enable";
97bbd28a293f84baeafed469c5e223eff82c1117c0Jeff Brown
98fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown    private static final String SYSTEM_HEADLESS = "ro.config.headless";
99bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000;
100bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
101bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER = 1;
102bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final int MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS = 2;
103bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final int MSG_DELIVER_DISPLAY_EVENT = 3;
1044ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private static final int MSG_REQUEST_TRAVERSAL = 4;
105d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    private static final int MSG_UPDATE_VIEWPORT = 5;
106fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown
1079e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    private static final int DISPLAY_BLANK_STATE_UNKNOWN = 0;
1089e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    private static final int DISPLAY_BLANK_STATE_BLANKED = 1;
1099e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    private static final int DISPLAY_BLANK_STATE_UNBLANKED = 2;
1109e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown
111848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown    private final Context mContext;
112fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown    private final boolean mHeadless;
113bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private final DisplayManagerHandler mHandler;
1144ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private final Handler mUiHandler;
1154ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private final DisplayAdapterListener mDisplayAdapterListener;
1164ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private WindowManagerFuncs mWindowManagerFuncs;
117d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    private InputManagerFuncs mInputManagerFuncs;
1184ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
1194ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // The synchronization root for the display manager.
1204ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // This lock guards most of the display manager's state.
1210bf6ec9e377f9fafb67a36f7fb54d3f6676634fcCraig Mautner    // NOTE: This is synchronized on while holding WindowManagerService.mWindowMap so never call
1220bf6ec9e377f9fafb67a36f7fb54d3f6676634fcCraig Mautner    // into WindowManagerService methods that require mWindowMap while holding this unless you are
1230bf6ec9e377f9fafb67a36f7fb54d3f6676634fcCraig Mautner    // very very sure that no deadlock can occur.
1244ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private final SyncRoot mSyncRoot = new SyncRoot();
1254ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
1264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // True if in safe mode.
1274ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // This option may disable certain display adapters.
1284ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public boolean mSafeMode;
1294ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
1304ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // True if we are in a special boot mode where only core applications and
1314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // services should be started.  This option may disable certain display adapters.
1324ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public boolean mOnlyCore;
1334ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
13427f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown    // True if the display manager service should pretend there is only one display
13527f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown    // and only tell applications about the existence of the default logical display.
13627f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown    // The display manager can still mirror content to secondary displays but applications
13727f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown    // cannot present unique content on those displays.
13827f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown    // Used for demonstration purposes only.
13927f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown    private final boolean mSingleDisplayDemoMode;
14027f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown
1414ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // All callback records indexed by calling process id.
1424ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public final SparseArray<CallbackRecord> mCallbacks =
143bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            new SparseArray<CallbackRecord>();
144bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
145bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    // List of all currently registered display adapters.
146fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown    private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
147fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown
148bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    // List of all currently connected display devices.
149bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>();
150bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1514ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // List of all removed display devices.
1524ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private final ArrayList<DisplayDevice> mRemovedDisplayDevices = new ArrayList<DisplayDevice>();
153bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1544ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // List of all logical displays indexed by logical display id.
1554ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private final SparseArray<LogicalDisplay> mLogicalDisplays =
1564ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            new SparseArray<LogicalDisplay>();
1574ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1;
158bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1597f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown    // List of all display transaction listeners.
1607f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown    private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners =
1617f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown            new CopyOnWriteArrayList<DisplayTransactionListener>();
1627f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown
1639e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    // Set to true if all displays have been blanked by the power manager.
1640bf6ec9e377f9fafb67a36f7fb54d3f6676634fcCraig Mautner    private int mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_UNKNOWN;
1659e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown
1664ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // Set to true when there are pending display changes that have yet to be applied
1674ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // to the surface flinger state.
1684ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private boolean mPendingTraversal;
169bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
170e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    // The Wifi display adapter, or null if not registered.
171e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    private WifiDisplayAdapter mWifiDisplayAdapter;
172e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown
173d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    // Viewports of the default display and the display that should receive touch
174d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    // input from an external source.  Used by the input system.
175d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    private final DisplayViewport mDefaultViewport = new DisplayViewport();
176d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    private final DisplayViewport mExternalTouchViewport = new DisplayViewport();
177d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown
17889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    // Persistent data store for all internal settings maintained by the display manager service.
17989d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    private final PersistentDataStore mPersistentDataStore = new PersistentDataStore();
18089d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown
181bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    // Temporary callback list, used when sending display events to applications.
1824ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // May be used outside of the lock but only on the handler thread.
1834ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private final ArrayList<CallbackRecord> mTempCallbacks = new ArrayList<CallbackRecord>();
184bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1854ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // Temporary display info, used for comparing display configurations.
1864ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private final DisplayInfo mTempDisplayInfo = new DisplayInfo();
1874ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
188d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    // Temporary viewports, used when sending new viewport information to the
189d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    // input system.  May be used outside of the lock but only on the handler thread.
190d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    private final DisplayViewport mTempDefaultViewport = new DisplayViewport();
191d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    private final DisplayViewport mTempExternalTouchViewport = new DisplayViewport();
192d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown
1934ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public DisplayManagerService(Context context, Handler mainHandler, Handler uiHandler) {
194848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown        mContext = context;
195fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown        mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1");
196848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown
1974ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        mHandler = new DisplayManagerHandler(mainHandler.getLooper());
1984ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        mUiHandler = uiHandler;
1994ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        mDisplayAdapterListener = new DisplayAdapterListener();
20027f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown        mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
2014ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
202bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER);
203bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
204bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
205bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    /**
206bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown     * Pauses the boot process to wait for the first display to be initialized.
207bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown     */
208bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    public boolean waitForDefaultDisplay() {
2094ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
210bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            long timeout = SystemClock.uptimeMillis() + WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
211bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null) {
212bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                long delay = timeout - SystemClock.uptimeMillis();
213bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                if (delay <= 0) {
214bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    return false;
215bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                }
216bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                if (DEBUG) {
217bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay);
218bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                }
219bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                try {
2204ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    mSyncRoot.wait(delay);
221bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                } catch (InterruptedException ex) {
222bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                }
223bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
224bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
225bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        return true;
226bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
227bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
228bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    /**
229d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown     * Called during initialization to associate the display manager with the
2304ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * window manager.
2314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     */
2324ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public void setWindowManager(WindowManagerFuncs windowManagerFuncs) {
2334ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
2344ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mWindowManagerFuncs = windowManagerFuncs;
23565d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner            scheduleTraversalLocked(false);
2364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
2374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
2384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
2394ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    /**
240d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown     * Called during initialization to associate the display manager with the
241d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown     * input manager.
242d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown     */
243d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    public void setInputManager(InputManagerFuncs inputManagerFuncs) {
244d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        synchronized (mSyncRoot) {
245d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            mInputManagerFuncs = inputManagerFuncs;
24665d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner            scheduleTraversalLocked(false);
247d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        }
248d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    }
249d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown
250d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    /**
251bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown     * Called when the system is ready to go.
252bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown     */
253bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    public void systemReady(boolean safeMode, boolean onlyCore) {
2544ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
255bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mSafeMode = safeMode;
256bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mOnlyCore = onlyCore;
257bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
258bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
2594ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
260fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown    }
261fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown
262848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown    /**
263848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown     * Returns true if the device is headless.
264848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown     *
265848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown     * @return True if the device is headless.
266848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown     */
267fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown    public boolean isHeadless() {
268fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown        return mHeadless;
269fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown    }
270fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown
2714f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner    /**
2727f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown     * Registers a display transaction listener to provide the client a chance to
2737f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown     * update its surfaces within the same transaction as any display layout updates.
2747f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown     *
2757f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown     * @param listener The listener to register.
2767f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown     */
2777f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown    public void registerDisplayTransactionListener(DisplayTransactionListener listener) {
2787f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown        if (listener == null) {
2797f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown            throw new IllegalArgumentException("listener must not be null");
2807f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown        }
2817f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown
2827f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown        // List is self-synchronized copy-on-write.
2837f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown        mDisplayTransactionListeners.add(listener);
2847f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown    }
2857f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown
2867f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown    /**
2877f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown     * Unregisters a display transaction listener to provide the client a chance to
2887f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown     * update its surfaces within the same transaction as any display layout updates.
2897f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown     *
2907f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown     * @param listener The listener to unregister.
2917f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown     */
2927f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown    public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) {
2937f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown        if (listener == null) {
2947f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown            throw new IllegalArgumentException("listener must not be null");
2957f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown        }
2967f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown
2977f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown        // List is self-synchronized copy-on-write.
2987f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown        mDisplayTransactionListeners.remove(listener);
2997f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown    }
3007f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown
3017f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown    /**
3024ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * Overrides the display information of a particular logical display.
3034ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * This is used by the window manager to control the size and characteristics
3044ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * of the default display.  It is expected to apply the requested change
3054ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * to the display information synchronously so that applications will immediately
3064ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * observe the new state.
307bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown     *
30864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @param displayId The logical display id.
3094ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * @param info The new data to be stored.
31064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
3114ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public void setDisplayInfoOverrideFromWindowManager(
3124ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            int displayId, DisplayInfo info) {
3134ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
314bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            LogicalDisplay display = mLogicalDisplays.get(displayId);
3154ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            if (display != null) {
3164ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
3174ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                display.setDisplayInfoOverrideFromWindowManagerLocked(info);
3184ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
3194ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
32065d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner                    scheduleTraversalLocked(false);
32164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                }
32264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
32364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
32464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
32564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
32664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
3274ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * Called by the window manager to perform traversals while holding a
3284ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * surface flinger transaction.
3294f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner     */
3304ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public void performTraversalInTransactionFromWindowManager() {
3314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
3324ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            if (!mPendingTraversal) {
3334ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                return;
3344f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner            }
3354ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mPendingTraversal = false;
3364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
3374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            performTraversalInTransactionLocked();
3384f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner        }
3397f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown
3407f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown        // List is self-synchronized copy-on-write.
3417f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown        for (DisplayTransactionListener listener : mDisplayTransactionListeners) {
3427f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown            listener.onDisplayTransaction();
3437f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown        }
3444f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner    }
3454f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner
3464f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner    /**
3479e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown     * Called by the power manager to blank all displays.
3489e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown     */
3499e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    public void blankAllDisplaysFromPowerManager() {
3509e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown        synchronized (mSyncRoot) {
3519e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            if (mAllDisplayBlankStateFromPowerManager != DISPLAY_BLANK_STATE_BLANKED) {
3529e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown                mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_BLANKED;
3539e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown
3549e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown                final int count = mDisplayDevices.size();
3559e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown                for (int i = 0; i < count; i++) {
3569e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown                    DisplayDevice device = mDisplayDevices.get(i);
3579e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown                    device.blankLocked();
3589e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown                }
3598ec0943a7963178da838e4b6b842ec1109707b35Jeff Brown
3608ec0943a7963178da838e4b6b842ec1109707b35Jeff Brown                scheduleTraversalLocked(false);
3619e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            }
3629e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown        }
3639e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    }
3649e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown
3659e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    /**
3669e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown     * Called by the power manager to unblank all displays.
3679e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown     */
3689e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    public void unblankAllDisplaysFromPowerManager() {
3699e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown        synchronized (mSyncRoot) {
3709e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            if (mAllDisplayBlankStateFromPowerManager != DISPLAY_BLANK_STATE_UNBLANKED) {
3719e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown                mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_UNBLANKED;
3729e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown
3739e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown                final int count = mDisplayDevices.size();
3749e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown                for (int i = 0; i < count; i++) {
3759e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown                    DisplayDevice device = mDisplayDevices.get(i);
3769e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown                    device.unblankLocked();
3779e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown                }
3788ec0943a7963178da838e4b6b842ec1109707b35Jeff Brown
3798ec0943a7963178da838e4b6b842ec1109707b35Jeff Brown                scheduleTraversalLocked(false);
3809e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            }
3819e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown        }
3829e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    }
3839e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown
3849e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    /**
385bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown     * Returns information about the specified logical display.
386bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown     *
387bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown     * @param displayId The logical display id.
388722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     * @return The logical display info, or null if the display does not exist.  The
389722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     * returned object must be treated as immutable.
3904f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner     */
391fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown    @Override // Binder call
392bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    public DisplayInfo getDisplayInfo(int displayId) {
3934ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
394bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            LogicalDisplay display = mLogicalDisplays.get(displayId);
395bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            if (display != null) {
3964ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                return display.getDisplayInfoLocked();
3974f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner            }
398bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            return null;
3994f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner        }
4004f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner    }
4014f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner
4024ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    /**
4034ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * Returns the list of all display ids.
4044ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     */
405bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    @Override // Binder call
406bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    public int[] getDisplayIds() {
4074ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
408bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            final int count = mLogicalDisplays.size();
409bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            int[] displayIds = new int[count];
4104ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            for (int i = 0; i < count; i++) {
411bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                displayIds[i] = mLogicalDisplays.keyAt(i);
4124f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner            }
413bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            return displayIds;
414bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
415bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
4164f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner
417bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    @Override // Binder call
418bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    public void registerCallback(IDisplayManagerCallback callback) {
419bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        if (callback == null) {
420bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            throw new IllegalArgumentException("listener must not be null");
421bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
422bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
4234ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
424bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            int callingPid = Binder.getCallingPid();
425bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            if (mCallbacks.get(callingPid) != null) {
426bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                throw new SecurityException("The calling process has already "
427bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                        + "registered an IDisplayManagerCallback.");
4284f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner            }
429bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
430bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            CallbackRecord record = new CallbackRecord(callingPid, callback);
431bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            try {
432bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                IBinder binder = callback.asBinder();
433bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                binder.linkToDeath(record, 0);
434bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            } catch (RemoteException ex) {
435bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                // give up
436bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                throw new RuntimeException(ex);
437bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
438bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
439bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mCallbacks.put(callingPid, record);
440bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
4419de4936c99b979f6010440b043edc6d6142d1980Craig Mautner    }
4429de4936c99b979f6010440b043edc6d6142d1980Craig Mautner
443bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private void onCallbackDied(int pid) {
4444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
445bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mCallbacks.remove(pid);
446bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
447bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
448bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
449e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    @Override // Binder call
450e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    public void scanWifiDisplays() {
451e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        final long token = Binder.clearCallingIdentity();
452e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        try {
453e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            synchronized (mSyncRoot) {
45421c7153d30071dcbeb92daa1fd48ed181e42aef3Jeff Brown                if (mWifiDisplayAdapter != null) {
45521c7153d30071dcbeb92daa1fd48ed181e42aef3Jeff Brown                    mWifiDisplayAdapter.requestScanLocked();
45621c7153d30071dcbeb92daa1fd48ed181e42aef3Jeff Brown                }
457e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            }
458e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        } finally {
459e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            Binder.restoreCallingIdentity(token);
460e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        }
461e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    }
462e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown
463e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    @Override // Binder call
464e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    public void connectWifiDisplay(String address) {
465e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        if (address == null) {
466e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            throw new IllegalArgumentException("address must not be null");
467e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        }
468e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown
469bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown        final boolean trusted = canCallerConfigureWifiDisplay();
470e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        final long token = Binder.clearCallingIdentity();
471e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        try {
472e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            synchronized (mSyncRoot) {
47321c7153d30071dcbeb92daa1fd48ed181e42aef3Jeff Brown                if (mWifiDisplayAdapter != null) {
474bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown                    mWifiDisplayAdapter.requestConnectLocked(address, trusted);
47521c7153d30071dcbeb92daa1fd48ed181e42aef3Jeff Brown                }
476e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            }
477e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        } finally {
478e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            Binder.restoreCallingIdentity(token);
479e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        }
480e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    }
481e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown
482e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    @Override // Binder call
483e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    public void disconnectWifiDisplay() {
484e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        final long token = Binder.clearCallingIdentity();
485e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        try {
486e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            synchronized (mSyncRoot) {
48721c7153d30071dcbeb92daa1fd48ed181e42aef3Jeff Brown                if (mWifiDisplayAdapter != null) {
48821c7153d30071dcbeb92daa1fd48ed181e42aef3Jeff Brown                    mWifiDisplayAdapter.requestDisconnectLocked();
48921c7153d30071dcbeb92daa1fd48ed181e42aef3Jeff Brown                }
490e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            }
491e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        } finally {
492e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            Binder.restoreCallingIdentity(token);
493e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        }
494e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    }
495e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown
496e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    @Override // Binder call
49789d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    public void renameWifiDisplay(String address, String alias) {
49889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        if (address == null) {
49989d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown            throw new IllegalArgumentException("address must not be null");
50089d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        }
501bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown        if (!canCallerConfigureWifiDisplay()) {
502bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown            throw new SecurityException("Requires CONFIGURE_WIFI_DISPLAY permission to "
503bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown                    + "rename a wifi display.");
504bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown        }
50589d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown
50689d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        final long token = Binder.clearCallingIdentity();
50789d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        try {
50889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown            synchronized (mSyncRoot) {
50989d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown                if (mWifiDisplayAdapter != null) {
51089d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown                    mWifiDisplayAdapter.requestRenameLocked(address, alias);
51189d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown                }
51289d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown            }
51389d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        } finally {
51489d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown            Binder.restoreCallingIdentity(token);
51589d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        }
51689d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    }
51789d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown
51889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    @Override // Binder call
51989d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    public void forgetWifiDisplay(String address) {
52089d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        if (address == null) {
52189d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown            throw new IllegalArgumentException("address must not be null");
52289d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        }
523bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown        if (!canCallerConfigureWifiDisplay()) {
524bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown            throw new SecurityException("Requires CONFIGURE_WIFI_DISPLAY permission to "
525bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown                    + "forget a wifi display.");
526bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown        }
52789d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown
52889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        final long token = Binder.clearCallingIdentity();
52989d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        try {
53089d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown            synchronized (mSyncRoot) {
53189d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown                if (mWifiDisplayAdapter != null) {
53289d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown                    mWifiDisplayAdapter.requestForgetLocked(address);
53389d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown                }
53489d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown            }
53589d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        } finally {
53689d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown            Binder.restoreCallingIdentity(token);
53789d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        }
53889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    }
53989d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown
54089d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    @Override // Binder call
541e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    public WifiDisplayStatus getWifiDisplayStatus() {
542e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        final long token = Binder.clearCallingIdentity();
543e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        try {
544e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            synchronized (mSyncRoot) {
54521c7153d30071dcbeb92daa1fd48ed181e42aef3Jeff Brown                if (mWifiDisplayAdapter != null) {
54621c7153d30071dcbeb92daa1fd48ed181e42aef3Jeff Brown                    return mWifiDisplayAdapter.getWifiDisplayStatusLocked();
54721c7153d30071dcbeb92daa1fd48ed181e42aef3Jeff Brown                }
5480bf6ec9e377f9fafb67a36f7fb54d3f6676634fcCraig Mautner                return new WifiDisplayStatus();
549e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            }
550e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        } finally {
551e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            Binder.restoreCallingIdentity(token);
552e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        }
553e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    }
554e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown
555bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown    private boolean canCallerConfigureWifiDisplay() {
556bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown        return mContext.checkCallingPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
557bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown                == PackageManager.PERMISSION_GRANTED;
558bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown    }
559bc335457462a12434a9df6955de1dd693cdccac7Jeff Brown
5604ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private void registerDefaultDisplayAdapter() {
5614ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Register default display adapter.
5624ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
5634ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            if (mHeadless) {
5644ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                registerDisplayAdapterLocked(new HeadlessDisplayAdapter(
5654ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                        mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
5664ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            } else {
5674ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                registerDisplayAdapterLocked(new LocalDisplayAdapter(
5684ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                        mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
569bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
5704ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
5714ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
572bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
5734ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private void registerAdditionalDisplayAdapters() {
5744ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
5754ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            if (shouldRegisterNonEssentialDisplayAdaptersLocked()) {
57689d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown                registerOverlayDisplayAdapterLocked();
57789d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown                registerWifiDisplayAdapterLocked();
578bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
5794ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
5804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
581bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
58289d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    private void registerOverlayDisplayAdapterLocked() {
58389d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        registerDisplayAdapterLocked(new OverlayDisplayAdapter(
58489d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown                mSyncRoot, mContext, mHandler, mDisplayAdapterListener, mUiHandler));
58589d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    }
58689d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown
58789d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    private void registerWifiDisplayAdapterLocked() {
58889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        if (mContext.getResources().getBoolean(
589bbd28a293f84baeafed469c5e223eff82c1117c0Jeff Brown                com.android.internal.R.bool.config_enableWifiDisplay)
590bbd28a293f84baeafed469c5e223eff82c1117c0Jeff Brown                || SystemProperties.getInt(FORCE_WIFI_DISPLAY_ENABLE, -1) == 1) {
59189d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown            mWifiDisplayAdapter = new WifiDisplayAdapter(
59289d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown                    mSyncRoot, mContext, mHandler, mDisplayAdapterListener,
59389d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown                    mPersistentDataStore);
59489d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown            registerDisplayAdapterLocked(mWifiDisplayAdapter);
59589d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        }
59689d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    }
59789d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown
5984ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() {
5994ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // In safe mode, we disable non-essential display adapters to give the user
6004ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // an opportunity to fix broken settings or other problems that might affect
6014ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // system stability.
6024ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // In only-core mode, we disable non-essential display adapters to minimize
6034ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // the number of dependencies that are started while in this mode and to
6044ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // prevent problems that might occur due to the device being encrypted.
6054ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        return !mSafeMode && !mOnlyCore;
6064ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
607bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
6084ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private void registerDisplayAdapterLocked(DisplayAdapter adapter) {
6094ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        mDisplayAdapters.add(adapter);
6104ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        adapter.registerLocked();
6114ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
612bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
6134ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private void handleDisplayDeviceAdded(DisplayDevice device) {
6144ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
6154ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            if (mDisplayDevices.contains(device)) {
6164ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                Slog.w(TAG, "Attempted to add already added display device: "
6174ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                        + device.getDisplayDeviceInfoLocked());
6184ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                return;
619bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
6204ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
621e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown            Slog.i(TAG, "Display device added: " + device.getDisplayDeviceInfoLocked());
622e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown
6234ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mDisplayDevices.add(device);
6244ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            addLogicalDisplayLocked(device);
62565d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner            scheduleTraversalLocked(false);
6269e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown
6279e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            // Blank or unblank the display immediately to match the state requested
6289e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            // by the power manager (if known).
6299e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            switch (mAllDisplayBlankStateFromPowerManager) {
6309e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown                case DISPLAY_BLANK_STATE_BLANKED:
6319e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown                    device.blankLocked();
6329e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown                    break;
6339e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown                case DISPLAY_BLANK_STATE_UNBLANKED:
6349e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown                    device.unblankLocked();
6359e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown                    break;
6369e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            }
637bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
638bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
639bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
640bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private void handleDisplayDeviceChanged(DisplayDevice device) {
6414ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
642bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            if (!mDisplayDevices.contains(device)) {
6434ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                Slog.w(TAG, "Attempted to change non-existent display device: "
6444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                        + device.getDisplayDeviceInfoLocked());
645bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                return;
646bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
647bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
648e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown            Slog.i(TAG, "Display device changed: " + device.getDisplayDeviceInfoLocked());
649e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown
6504ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            device.applyPendingDisplayDeviceInfoChangesLocked();
6514ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            if (updateLogicalDisplaysLocked()) {
65265d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner                scheduleTraversalLocked(false);
653bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
654bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
655bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
656bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
657bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private void handleDisplayDeviceRemoved(DisplayDevice device) {
6584ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
659bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            if (!mDisplayDevices.remove(device)) {
6604ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                Slog.w(TAG, "Attempted to remove non-existent display device: "
6614ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                        + device.getDisplayDeviceInfoLocked());
662bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                return;
663bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
664bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
665e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown            Slog.i(TAG, "Display device removed: " + device.getDisplayDeviceInfoLocked());
666e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown
6674ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mRemovedDisplayDevices.add(device);
6684ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            updateLogicalDisplaysLocked();
66965d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner            scheduleTraversalLocked(false);
6704ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
6714ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
6724ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
6734ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // Adds a new logical display based on the given display device.
6744ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // Sends notifications if needed.
6754ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private void addLogicalDisplayLocked(DisplayDevice device) {
6764ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
6774ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        boolean isDefault = (deviceInfo.flags
6784ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0;
6794ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        if (isDefault && mLogicalDisplays.get(Display.DEFAULT_DISPLAY) != null) {
6804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            Slog.w(TAG, "Ignoring attempt to add a second default display: " + deviceInfo);
6814ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            isDefault = false;
6824ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
6834ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
68427f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown        if (!isDefault && mSingleDisplayDemoMode) {
68527f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown            Slog.i(TAG, "Not creating a logical display for a secondary display "
68627f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown                    + " because single display demo mode is enabled: " + deviceInfo);
68727f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown            return;
68827f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown        }
68927f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown
6904ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        final int displayId = assignDisplayIdLocked(isDefault);
6914ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        final int layerStack = assignLayerStackLocked(displayId);
6924ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
693d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
6944ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        display.updateLocked(mDisplayDevices);
6954ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        if (!display.isValidLocked()) {
6964ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            // This should never happen currently.
6974ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            Slog.w(TAG, "Ignoring display device because the logical display "
6984ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    + "created from it was not considered valid: " + deviceInfo);
6994ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            return;
7004ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
7014ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
7024ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        mLogicalDisplays.put(displayId, display);
7034ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
7044ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Wake up waitForDefaultDisplay.
7054ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        if (isDefault) {
7064ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mSyncRoot.notifyAll();
7074ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
7084ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
7094ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED);
7104ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
7114ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
7124ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private int assignDisplayIdLocked(boolean isDefault) {
7134ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        return isDefault ? Display.DEFAULT_DISPLAY : mNextNonDefaultDisplayId++;
7144ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
7154ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
7164ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private int assignLayerStackLocked(int displayId) {
7174ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Currently layer stacks and display ids are the same.
7184ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // This need not be the case.
7194ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        return displayId;
7204ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
7214ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
7224ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // Updates all existing logical displays given the current set of display devices.
7234ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // Removes invalid logical displays.
7244ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // Sends notifications if needed.
7254ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private boolean updateLogicalDisplaysLocked() {
7264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        boolean changed = false;
7274ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        for (int i = mLogicalDisplays.size(); i-- > 0; ) {
7284ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            final int displayId = mLogicalDisplays.keyAt(i);
7294ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            LogicalDisplay display = mLogicalDisplays.valueAt(i);
7304ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
7314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
7324ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            display.updateLocked(mDisplayDevices);
7334ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            if (!display.isValidLocked()) {
7344ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                mLogicalDisplays.removeAt(i);
7354ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED);
7364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                changed = true;
7374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
7384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
7394ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                changed = true;
740bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
741bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
7424ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        return changed;
7434ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
7444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
7454ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private void performTraversalInTransactionLocked() {
7464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Perform one last traversal for each removed display device.
7474ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        final int removedCount = mRemovedDisplayDevices.size();
7484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        for (int i = 0; i < removedCount; i++) {
7494ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            DisplayDevice device = mRemovedDisplayDevices.get(i);
7504ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            device.performTraversalInTransactionLocked();
7514ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
7524ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        mRemovedDisplayDevices.clear();
7534ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
754d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        // Clear all viewports before configuring displays so that we can keep
755d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        // track of which ones we have configured.
756d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        clearViewportsLocked();
757d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown
7584ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Configure each display device.
7594ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        final int count = mDisplayDevices.size();
7604ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        for (int i = 0; i < count; i++) {
7614ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            DisplayDevice device = mDisplayDevices.get(i);
7624ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            configureDisplayInTransactionLocked(device);
7634ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            device.performTraversalInTransactionLocked();
7644ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
765d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown
766d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        // Tell the input system about these new viewports.
767d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        if (mInputManagerFuncs != null) {
768d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            mHandler.sendEmptyMessage(MSG_UPDATE_VIEWPORT);
769d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        }
7704ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
7714ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
772722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner    /**
773722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     * Tells the display manager whether there is interesting unique content on the
774722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     * specified logical display.  This is used to control automatic mirroring.
775722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     * <p>
776722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     * If the display has unique content, then the display manager arranges for it
777722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     * to be presented on a physical display if appropriate.  Otherwise, the display manager
778722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     * may choose to make the physical display mirror some other logical display.
779722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     * </p>
780722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     *
781722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     * @param displayId The logical display id to update.
782722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     * @param hasContent True if the logical display has content.
78365d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner     * @param inTraversal True if called from WindowManagerService during a window traversal prior
78465d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner     * to call to performTraversalInTransactionFromWindowManager.
785722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     */
78665d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner    public void setDisplayHasContent(int displayId, boolean hasContent, boolean inTraversal) {
787722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner        synchronized (mSyncRoot) {
788722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner            LogicalDisplay display = mLogicalDisplays.get(displayId);
789722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner            if (display != null && display.hasContentLocked() != hasContent) {
790722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner                display.setHasContentLocked(hasContent);
79165d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner                scheduleTraversalLocked(inTraversal);
792722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner            }
793722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner        }
794d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    }
7954ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
796d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    private void clearViewportsLocked() {
797d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        mDefaultViewport.valid = false;
798d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        mExternalTouchViewport.valid = false;
799722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner    }
800722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner
801722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner    private void configureDisplayInTransactionLocked(DisplayDevice device) {
8024ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Find the logical display that the display device is showing.
803722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner        LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
804722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner        if (display != null && !display.hasContentLocked()) {
805722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner            display = null;
8064ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
8074ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        if (display == null) {
8084ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY);
8094ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
8104ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
8114ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Apply the logical display configuration to the display device.
8124ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        if (display == null) {
8134ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            // TODO: no logical display for the device, blank it
814d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            Slog.w(TAG, "Missing logical display to use for physical display device: "
8154ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    + device.getDisplayDeviceInfoLocked());
816d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            return;
8174ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
8180bf6ec9e377f9fafb67a36f7fb54d3f6676634fcCraig Mautner        boolean isBlanked = (mAllDisplayBlankStateFromPowerManager == DISPLAY_BLANK_STATE_BLANKED);
8190bf6ec9e377f9fafb67a36f7fb54d3f6676634fcCraig Mautner        display.configureDisplayInTransactionLocked(device, isBlanked);
820d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown
821d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        // Update the viewports if needed.
822d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
823d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        if (!mDefaultViewport.valid
824d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                && (info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
825d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            setViewportLocked(mDefaultViewport, display, device);
826d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        }
827d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        if (!mExternalTouchViewport.valid
828d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                && info.touch == DisplayDeviceInfo.TOUCH_EXTERNAL) {
829d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            setViewportLocked(mExternalTouchViewport, display, device);
830d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        }
831d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    }
832d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown
833d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    private static void setViewportLocked(DisplayViewport viewport,
834d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            LogicalDisplay display, DisplayDevice device) {
835d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        viewport.valid = true;
836d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        viewport.displayId = display.getDisplayIdLocked();
837d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        device.populateViewportLocked(viewport);
8384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
8394ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
8404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private LogicalDisplay findLogicalDisplayForDeviceLocked(DisplayDevice device) {
8414ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        final int count = mLogicalDisplays.size();
8424ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        for (int i = 0; i < count; i++) {
8434ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            LogicalDisplay display = mLogicalDisplays.valueAt(i);
8444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            if (display.getPrimaryDisplayDeviceLocked() == device) {
8454ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                return display;
8464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            }
8474ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
8484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        return null;
849bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
850bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
851bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private void sendDisplayEventLocked(int displayId, int event) {
852bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT, displayId, event);
853bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        mHandler.sendMessage(msg);
854bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
855bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
8564ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // Requests that performTraversalsInTransactionFromWindowManager be called at a
8574ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // later time to apply changes to surfaces and displays.
85865d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner    private void scheduleTraversalLocked(boolean inTraversal) {
8594ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        if (!mPendingTraversal && mWindowManagerFuncs != null) {
8604ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mPendingTraversal = true;
86165d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner            if (!inTraversal) {
86265d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner                mHandler.sendEmptyMessage(MSG_REQUEST_TRAVERSAL);
86365d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner            }
8644ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
8654ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
8664ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
8674ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // Runs on Handler thread.
8684ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // Delivers display event notifications to callbacks.
869bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private void deliverDisplayEvent(int displayId, int event) {
870bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        if (DEBUG) {
8714ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            Slog.d(TAG, "Delivering display event: displayId="
8724ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    + displayId + ", event=" + event);
873bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
874bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
8754ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Grab the lock and copy the callbacks.
876bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        final int count;
8774ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
878bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            count = mCallbacks.size();
879bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mTempCallbacks.clear();
880bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            for (int i = 0; i < count; i++) {
881bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mTempCallbacks.add(mCallbacks.valueAt(i));
882bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
883bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
884bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
8854ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // After releasing the lock, send the notifications out.
886bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        for (int i = 0; i < count; i++) {
887bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mTempCallbacks.get(i).notifyDisplayEventAsync(displayId, event);
888bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
889bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        mTempCallbacks.clear();
8904f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner    }
8914f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner
892fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown    @Override // Binder call
893bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
894fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown        if (mContext == null
895fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown                || mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
896fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown                        != PackageManager.PERMISSION_GRANTED) {
897fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown            pw.println("Permission Denial: can't dump DisplayManager from from pid="
898fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
899fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown            return;
900fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown        }
901fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown
902bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        pw.println("DISPLAY MANAGER (dumpsys display)");
903fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown
9044ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
9059e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            pw.println("  mHeadless=" + mHeadless);
9069e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            pw.println("  mOnlyCode=" + mOnlyCore);
9079e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            pw.println("  mSafeMode=" + mSafeMode);
9089e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            pw.println("  mPendingTraversal=" + mPendingTraversal);
9099e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            pw.println("  mAllDisplayBlankStateFromPowerManager="
9109e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown                    + mAllDisplayBlankStateFromPowerManager);
9119e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            pw.println("  mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId);
9129e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            pw.println("  mDefaultViewport=" + mDefaultViewport);
9139e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            pw.println("  mExternalTouchViewport=" + mExternalTouchViewport);
91427f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown            pw.println("  mSingleDisplayDemoMode=" + mSingleDisplayDemoMode);
9159e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown
916bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "    ");
9174ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            ipw.increaseIndent();
918bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
919bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            pw.println();
920bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            pw.println("Display Adapters: size=" + mDisplayAdapters.size());
921848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown            for (DisplayAdapter adapter : mDisplayAdapters) {
922bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                pw.println("  " + adapter.getName());
9234ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                adapter.dumpLocked(ipw);
924848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown            }
9259de4936c99b979f6010440b043edc6d6142d1980Craig Mautner
926bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            pw.println();
927bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            pw.println("Display Devices: size=" + mDisplayDevices.size());
928bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            for (DisplayDevice device : mDisplayDevices) {
9294ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                pw.println("  " + device.getDisplayDeviceInfoLocked());
9304ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                device.dumpLocked(ipw);
931bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
932bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
933bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            final int logicalDisplayCount = mLogicalDisplays.size();
934bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            pw.println();
935bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            pw.println("Logical Displays: size=" + logicalDisplayCount);
936bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            for (int i = 0; i < logicalDisplayCount; i++) {
937bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                int displayId = mLogicalDisplays.keyAt(i);
938bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                LogicalDisplay display = mLogicalDisplays.valueAt(i);
939bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                pw.println("  Display " + displayId + ":");
9404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                display.dumpLocked(ipw);
941bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
942bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
943bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
944bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
9454ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    /**
9464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * This is the object that everything in the display manager locks on.
9474ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * We make it an inner class within the {@link DisplayManagerService} to so that it is
9484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * clear that the object belongs to the display manager service and that it is
9494ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * a unique object with a special purpose.
9504ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     */
9514ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public static final class SyncRoot {
9524ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
9534ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
9544ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    /**
9554ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * Private interface to the window manager.
9564ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     */
9574ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public interface WindowManagerFuncs {
9584ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        /**
959722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner         * Request that the window manager call
960722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner         * {@link #performTraversalInTransactionFromWindowManager} within a surface
961722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner         * transaction at a later time.
9624ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown         */
9634ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        void requestTraversal();
9644ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
9654ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
966d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    /**
967d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown     * Private interface to the input manager.
968d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown     */
969d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    public interface InputManagerFuncs {
970d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        /**
971d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown         * Sets information about the displays as needed by the input system.
972d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown         * The input system should copy this information if required.
973d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown         */
974d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        void setDisplayViewports(DisplayViewport defaultViewport,
975d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                DisplayViewport externalTouchViewport);
976d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    }
977d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown
978bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private final class DisplayManagerHandler extends Handler {
979bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        public DisplayManagerHandler(Looper looper) {
980bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            super(looper, null, true /*async*/);
981848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown        }
982bf5740e75efd87ae0213486e78e029403804c6f0Jeff Brown
983bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        @Override
984bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        public void handleMessage(Message msg) {
985bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            switch (msg.what) {
986bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER:
987bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    registerDefaultDisplayAdapter();
988bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    break;
989bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
990bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS:
991bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    registerAdditionalDisplayAdapters();
992bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    break;
993bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
994bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                case MSG_DELIVER_DISPLAY_EVENT:
995bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    deliverDisplayEvent(msg.arg1, msg.arg2);
996bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    break;
9974ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
9984ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                case MSG_REQUEST_TRAVERSAL:
9994ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    mWindowManagerFuncs.requestTraversal();
10004ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    break;
1001d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown
1002d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                case MSG_UPDATE_VIEWPORT: {
1003d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                    synchronized (mSyncRoot) {
1004d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                        mTempDefaultViewport.copyFrom(mDefaultViewport);
1005d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                        mTempExternalTouchViewport.copyFrom(mExternalTouchViewport);
1006d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                    }
1007d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                    mInputManagerFuncs.setDisplayViewports(
1008d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                            mTempDefaultViewport, mTempExternalTouchViewport);
1009d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                    break;
1010d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                }
1011bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
1012bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
1013bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
1014bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1015bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private final class DisplayAdapterListener implements DisplayAdapter.Listener {
1016bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        @Override
1017bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        public void onDisplayDeviceEvent(DisplayDevice device, int event) {
1018bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            switch (event) {
1019bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                case DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED:
1020bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    handleDisplayDeviceAdded(device);
1021bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    break;
1022bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1023bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                case DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED:
1024bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    handleDisplayDeviceChanged(device);
1025bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    break;
1026bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1027bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                case DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED:
1028bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    handleDisplayDeviceRemoved(device);
1029bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    break;
1030bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
1031bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
10324ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
10334ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        @Override
10344ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        public void onTraversalRequested() {
10354ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            synchronized (mSyncRoot) {
103665d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner                scheduleTraversalLocked(false);
10374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            }
10384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
1039bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
1040bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1041bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private final class CallbackRecord implements DeathRecipient {
1042bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final int mPid;
1043bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final IDisplayManagerCallback mCallback;
1044bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1045bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        public CallbackRecord(int pid, IDisplayManagerCallback callback) {
1046bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mPid = pid;
1047bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mCallback = callback;
1048bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
1049bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1050bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        @Override
1051bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        public void binderDied() {
1052bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            if (DEBUG) {
1053bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                Slog.d(TAG, "Display listener for pid " + mPid + " died.");
1054bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
1055bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            onCallbackDied(mPid);
1056bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
1057bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1058bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        public void notifyDisplayEventAsync(int displayId, int event) {
1059bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            try {
1060bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mCallback.onDisplayEvent(displayId, event);
1061bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            } catch (RemoteException ex) {
1062bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                Slog.w(TAG, "Failed to notify process "
1063bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                        + mPid + " that displays changed, assuming it died.", ex);
1064bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                binderDied();
1065bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
1066bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
1067bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
1068fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown}
1069