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;
247d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brownimport android.hardware.display.DisplayManager;
25bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.hardware.display.DisplayManagerGlobal;
26fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownimport android.hardware.display.IDisplayManager;
27bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.hardware.display.IDisplayManagerCallback;
28e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brownimport android.hardware.display.WifiDisplayStatus;
29fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownimport android.os.Binder;
30bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.os.Handler;
3164a55af0ac700baecb0877235eb42caac59a3560Jeff Brownimport android.os.IBinder;
32bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.os.Looper;
33bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.os.Message;
34bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.os.RemoteException;
35bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.os.SystemClock;
36fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownimport android.os.SystemProperties;
37a506a6ec94863a35acca9feb165db76ddac3892cJeff Brownimport android.text.TextUtils;
38feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brownimport android.util.Log;
39bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.util.Slog;
40bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.util.SparseArray;
41fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownimport android.view.Display;
42fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownimport android.view.DisplayInfo;
43a506a6ec94863a35acca9feb165db76ddac3892cJeff Brownimport android.view.Surface;
44a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown
458d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackbornimport com.android.server.UiThread;
46fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown
47fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownimport java.io.FileDescriptor;
48fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownimport java.io.PrintWriter;
49fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownimport java.util.ArrayList;
50a506a6ec94863a35acca9feb165db76ddac3892cJeff Brownimport java.util.Arrays;
517f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brownimport java.util.concurrent.CopyOnWriteArrayList;
52fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown
53fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown/**
54bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * Manages attached displays.
55fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * <p>
56bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * The {@link DisplayManagerService} manages the global lifecycle of displays,
57bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * decides how to configure logical displays based on the physical display devices currently
58bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * attached, sends notifications to the system and to applications when the state
59bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * changes, and so on.
60bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * </p><p>
61bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * The display manager service relies on a collection of {@link DisplayAdapter} components,
62bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * for discovering and configuring physical display devices attached to the system.
63bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * There are separate display adapters for each manner that devices are attached:
64bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * one display adapter for built-in local displays, one for simulated non-functional
65bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * displays when the system is headless, one for simulated overlay displays used for
66bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * development, one for wifi displays, etc.
67bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * </p><p>
68bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * Display adapters are only weakly coupled to the display manager service.
69bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * Display adapters communicate changes in display device state to the display manager
70722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner * service asynchronously via a {@link DisplayAdapter.Listener} registered
71bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * by the display manager service.  This separation of concerns is important for
72bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * two main reasons.  First, it neatly encapsulates the responsibilities of these
73bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * two classes: display adapters handle individual display devices whereas
74bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * the display manager service handles the global state.  Second, it eliminates
75bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * the potential for deadlocks resulting from asynchronous display device discovery.
764ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * </p>
774ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown *
784ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * <h3>Synchronization</h3>
794ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * <p>
804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * Because the display manager may be accessed by multiple threads, the synchronization
814ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * story gets a little complicated.  In particular, the window manager may call into
824ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * the display manager while holding a surface transaction with the expectation that
834ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * it can apply changes immediately.  Unfortunately, that means we can't just do
844ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * everything asynchronously (*grump*).
85bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * </p><p>
864ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * To make this work, all of the objects that belong to the display manager must
874ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * use the same lock.  We call this lock the synchronization root and it has a unique
884ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * type {@link DisplayManagerService.SyncRoot}.  Methods that require this lock are
894ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * named with the "Locked" suffix.
904ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * </p><p>
914ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * Where things get tricky is that the display manager is not allowed to make
924ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * any potentially reentrant calls, especially into the window manager.  We generally
934ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * avoid this by making all potentially reentrant out-calls asynchronous.
94fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * </p>
95fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown */
96fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownpublic final class DisplayManagerService extends IDisplayManager.Stub {
97fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown    private static final String TAG = "DisplayManagerService";
98bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final boolean DEBUG = false;
99fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown
100bbd28a293f84baeafed469c5e223eff82c1117c0Jeff Brown    // When this system property is set to 0, WFD is forcibly disabled on boot.
101bbd28a293f84baeafed469c5e223eff82c1117c0Jeff Brown    // When this system property is set to 1, WFD is forcibly enabled on boot.
102bbd28a293f84baeafed469c5e223eff82c1117c0Jeff Brown    // Otherwise WFD is enabled according to the value of config_enableWifiDisplay.
103bbd28a293f84baeafed469c5e223eff82c1117c0Jeff Brown    private static final String FORCE_WIFI_DISPLAY_ENABLE = "persist.debug.wfd.enable";
104bbd28a293f84baeafed469c5e223eff82c1117c0Jeff Brown
105fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown    private static final String SYSTEM_HEADLESS = "ro.config.headless";
106bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000;
107bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
108bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER = 1;
109bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final int MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS = 2;
110bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final int MSG_DELIVER_DISPLAY_EVENT = 3;
1114ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private static final int MSG_REQUEST_TRAVERSAL = 4;
112d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    private static final int MSG_UPDATE_VIEWPORT = 5;
113fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown
1149e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    private static final int DISPLAY_BLANK_STATE_UNKNOWN = 0;
1159e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    private static final int DISPLAY_BLANK_STATE_BLANKED = 1;
1169e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    private static final int DISPLAY_BLANK_STATE_UNBLANKED = 2;
1179e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown
118848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown    private final Context mContext;
119fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown    private final boolean mHeadless;
120bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private final DisplayManagerHandler mHandler;
1214ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private final Handler mUiHandler;
1224ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private final DisplayAdapterListener mDisplayAdapterListener;
1234ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private WindowManagerFuncs mWindowManagerFuncs;
124d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    private InputManagerFuncs mInputManagerFuncs;
1254ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
1264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // The synchronization root for the display manager.
1274ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // This lock guards most of the display manager's state.
1280bf6ec9e377f9fafb67a36f7fb54d3f6676634fcCraig Mautner    // NOTE: This is synchronized on while holding WindowManagerService.mWindowMap so never call
1290bf6ec9e377f9fafb67a36f7fb54d3f6676634fcCraig Mautner    // into WindowManagerService methods that require mWindowMap while holding this unless you are
1300bf6ec9e377f9fafb67a36f7fb54d3f6676634fcCraig Mautner    // very very sure that no deadlock can occur.
1314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private final SyncRoot mSyncRoot = new SyncRoot();
1324ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
1334ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // True if in safe mode.
1344ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // This option may disable certain display adapters.
1354ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public boolean mSafeMode;
1364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
1374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // True if we are in a special boot mode where only core applications and
1384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // services should be started.  This option may disable certain display adapters.
1394ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public boolean mOnlyCore;
1404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
14127f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown    // True if the display manager service should pretend there is only one display
14227f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown    // and only tell applications about the existence of the default logical display.
14327f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown    // The display manager can still mirror content to secondary displays but applications
14427f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown    // cannot present unique content on those displays.
14527f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown    // Used for demonstration purposes only.
14627f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown    private final boolean mSingleDisplayDemoMode;
14727f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown
1484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // All callback records indexed by calling process id.
1494ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public final SparseArray<CallbackRecord> mCallbacks =
150bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            new SparseArray<CallbackRecord>();
151bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
152bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    // List of all currently registered display adapters.
153fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown    private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
154fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown
155bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    // List of all currently connected display devices.
156bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>();
157bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1584ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // List of all logical displays indexed by logical display id.
1594ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private final SparseArray<LogicalDisplay> mLogicalDisplays =
1604ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            new SparseArray<LogicalDisplay>();
1614ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1;
162bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1637f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown    // List of all display transaction listeners.
1647f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown    private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners =
1657f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown            new CopyOnWriteArrayList<DisplayTransactionListener>();
1667f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown
1679e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    // Set to true if all displays have been blanked by the power manager.
1680bf6ec9e377f9fafb67a36f7fb54d3f6676634fcCraig Mautner    private int mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_UNKNOWN;
1699e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown
1704ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // Set to true when there are pending display changes that have yet to be applied
1714ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // to the surface flinger state.
1724ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private boolean mPendingTraversal;
173bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
174e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    // The Wifi display adapter, or null if not registered.
175e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    private WifiDisplayAdapter mWifiDisplayAdapter;
176e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown
177feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown    // The number of active wifi display scan requests.
178feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown    private int mWifiDisplayScanRequestCount;
179feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown
180a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown    // The virtual display adapter, or null if not registered.
181a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown    private VirtualDisplayAdapter mVirtualDisplayAdapter;
182a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown
183d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    // Viewports of the default display and the display that should receive touch
184d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    // input from an external source.  Used by the input system.
185d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    private final DisplayViewport mDefaultViewport = new DisplayViewport();
186d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    private final DisplayViewport mExternalTouchViewport = new DisplayViewport();
187d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown
18889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    // Persistent data store for all internal settings maintained by the display manager service.
18989d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    private final PersistentDataStore mPersistentDataStore = new PersistentDataStore();
19089d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown
191bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    // Temporary callback list, used when sending display events to applications.
1924ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // May be used outside of the lock but only on the handler thread.
1934ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private final ArrayList<CallbackRecord> mTempCallbacks = new ArrayList<CallbackRecord>();
194bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1954ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // Temporary display info, used for comparing display configurations.
1964ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private final DisplayInfo mTempDisplayInfo = new DisplayInfo();
1974ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
198d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    // Temporary viewports, used when sending new viewport information to the
199d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    // input system.  May be used outside of the lock but only on the handler thread.
200d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    private final DisplayViewport mTempDefaultViewport = new DisplayViewport();
201d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    private final DisplayViewport mTempExternalTouchViewport = new DisplayViewport();
202d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown
2038d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn    public DisplayManagerService(Context context, Handler mainHandler) {
204848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown        mContext = context;
205fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown        mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1");
206848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown
2074ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        mHandler = new DisplayManagerHandler(mainHandler.getLooper());
2088d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        mUiHandler = UiThread.getHandler();
2094ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        mDisplayAdapterListener = new DisplayAdapterListener();
21027f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown        mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
2114ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
212bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER);
213bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
214bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
215bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    /**
216bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown     * Pauses the boot process to wait for the first display to be initialized.
217bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown     */
218bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    public boolean waitForDefaultDisplay() {
2194ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
220bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            long timeout = SystemClock.uptimeMillis() + WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
221bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null) {
222bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                long delay = timeout - SystemClock.uptimeMillis();
223bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                if (delay <= 0) {
224bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    return false;
225bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                }
226bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                if (DEBUG) {
227bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay);
228bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                }
229bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                try {
2304ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    mSyncRoot.wait(delay);
231bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                } catch (InterruptedException ex) {
232bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                }
233bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
234bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
235bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        return true;
236bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
237bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
238bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    /**
239d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown     * Called during initialization to associate the display manager with the
2404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * window manager.
2414ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     */
2424ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public void setWindowManager(WindowManagerFuncs windowManagerFuncs) {
2434ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
2444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mWindowManagerFuncs = windowManagerFuncs;
24565d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner            scheduleTraversalLocked(false);
2464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
2474ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
2484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
2494ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    /**
250d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown     * Called during initialization to associate the display manager with the
251d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown     * input manager.
252d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown     */
253d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    public void setInputManager(InputManagerFuncs inputManagerFuncs) {
254d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        synchronized (mSyncRoot) {
255d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            mInputManagerFuncs = inputManagerFuncs;
25665d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner            scheduleTraversalLocked(false);
257d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        }
258d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    }
259d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown
260d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    /**
261bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown     * Called when the system is ready to go.
262bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown     */
263bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    public void systemReady(boolean safeMode, boolean onlyCore) {
2644ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
265bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mSafeMode = safeMode;
266bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mOnlyCore = onlyCore;
267bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
268bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
2694ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
270fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown    }
271fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown
272848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown    /**
273848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown     * Returns true if the device is headless.
274848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown     *
275848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown     * @return True if the device is headless.
276848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown     */
277fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown    public boolean isHeadless() {
278fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown        return mHeadless;
279fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown    }
280fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown
2814f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner    /**
2827f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown     * Registers a display transaction listener to provide the client a chance to
2837f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown     * update its surfaces within the same transaction as any display layout updates.
2847f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown     *
2857f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown     * @param listener The listener to register.
2867f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown     */
2877f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown    public void registerDisplayTransactionListener(DisplayTransactionListener listener) {
2887f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown        if (listener == null) {
2897f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown            throw new IllegalArgumentException("listener must not be null");
2907f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown        }
2917f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown
2927f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown        // List is self-synchronized copy-on-write.
2937f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown        mDisplayTransactionListeners.add(listener);
2947f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown    }
2957f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown
2967f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown    /**
2977f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown     * Unregisters a display transaction listener to provide the client a chance to
2987f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown     * update its surfaces within the same transaction as any display layout updates.
2997f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown     *
3007f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown     * @param listener The listener to unregister.
3017f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown     */
3027f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown    public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) {
3037f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown        if (listener == null) {
3047f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown            throw new IllegalArgumentException("listener must not be null");
3057f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown        }
3067f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown
3077f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown        // List is self-synchronized copy-on-write.
3087f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown        mDisplayTransactionListeners.remove(listener);
3097f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown    }
3107f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown
3117f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown    /**
3124ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * Overrides the display information of a particular logical display.
3134ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * This is used by the window manager to control the size and characteristics
3144ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * of the default display.  It is expected to apply the requested change
3154ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * to the display information synchronously so that applications will immediately
3164ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * observe the new state.
317bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown     *
318ef981a40aa63069dc115b216ce38d1dd939dc64cJeff Brown     * NOTE: This method must be the only entry point by which the window manager
319ef981a40aa63069dc115b216ce38d1dd939dc64cJeff Brown     * influences the logical configuration of displays.
320ef981a40aa63069dc115b216ce38d1dd939dc64cJeff Brown     *
32164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @param displayId The logical display id.
3224ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * @param info The new data to be stored.
32364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
3244ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public void setDisplayInfoOverrideFromWindowManager(
3254ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            int displayId, DisplayInfo info) {
3264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
327bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            LogicalDisplay display = mLogicalDisplays.get(displayId);
3284ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            if (display != null) {
329ef981a40aa63069dc115b216ce38d1dd939dc64cJeff Brown                if (display.setDisplayInfoOverrideFromWindowManagerLocked(info)) {
3304ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
33165d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner                    scheduleTraversalLocked(false);
33264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                }
33364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
33464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
33564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
33664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
33764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
3384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * Called by the window manager to perform traversals while holding a
3394ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * surface flinger transaction.
3404f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner     */
3414ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public void performTraversalInTransactionFromWindowManager() {
3424ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
3434ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            if (!mPendingTraversal) {
3444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                return;
3454f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner            }
3464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mPendingTraversal = false;
3474ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
3484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            performTraversalInTransactionLocked();
3494f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner        }
3507f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown
3517f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown        // List is self-synchronized copy-on-write.
3527f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown        for (DisplayTransactionListener listener : mDisplayTransactionListeners) {
3537f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown            listener.onDisplayTransaction();
3547f3994ec2a5dce1a037f04714b1f25cab85affb6Jeff Brown        }
3554f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner    }
3564f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner
3574f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner    /**
3589e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown     * Called by the power manager to blank all displays.
3599e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown     */
3609e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    public void blankAllDisplaysFromPowerManager() {
3619e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown        synchronized (mSyncRoot) {
3629e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            if (mAllDisplayBlankStateFromPowerManager != DISPLAY_BLANK_STATE_BLANKED) {
3639e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown                mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_BLANKED;
364a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                updateAllDisplayBlankingLocked();
3658ec0943a7963178da838e4b6b842ec1109707b35Jeff Brown                scheduleTraversalLocked(false);
3669e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            }
3679e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown        }
3689e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    }
3699e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown
3709e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    /**
3719e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown     * Called by the power manager to unblank all displays.
3729e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown     */
3739e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    public void unblankAllDisplaysFromPowerManager() {
3749e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown        synchronized (mSyncRoot) {
3759e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            if (mAllDisplayBlankStateFromPowerManager != DISPLAY_BLANK_STATE_UNBLANKED) {
3769e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown                mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_UNBLANKED;
377a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                updateAllDisplayBlankingLocked();
3788ec0943a7963178da838e4b6b842ec1109707b35Jeff Brown                scheduleTraversalLocked(false);
3799e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            }
3809e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown        }
3819e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    }
3829e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown
3839e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    /**
384bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown     * Returns information about the specified logical display.
385bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown     *
386bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown     * @param displayId The logical display id.
387722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     * @return The logical display info, or null if the display does not exist.  The
388722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     * returned object must be treated as immutable.
3894f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner     */
390fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown    @Override // Binder call
391bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    public DisplayInfo getDisplayInfo(int displayId) {
392a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        final int callingUid = Binder.getCallingUid();
393a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        final long token = Binder.clearCallingIdentity();
394a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        try {
395a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            synchronized (mSyncRoot) {
396a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                LogicalDisplay display = mLogicalDisplays.get(displayId);
397a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                if (display != null) {
398a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    DisplayInfo info = display.getDisplayInfoLocked();
399a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    if (info.hasAccess(callingUid)) {
400a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                        return info;
401a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    }
402a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                }
403a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                return null;
4044f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner            }
405a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        } finally {
406a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            Binder.restoreCallingIdentity(token);
4074f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner        }
4084f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner    }
4094f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner
4104ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    /**
4114ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * Returns the list of all display ids.
4124ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     */
413bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    @Override // Binder call
414bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    public int[] getDisplayIds() {
415a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        final int callingUid = Binder.getCallingUid();
416a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        final long token = Binder.clearCallingIdentity();
417a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        try {
418a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            synchronized (mSyncRoot) {
419a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                final int count = mLogicalDisplays.size();
420a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                int[] displayIds = new int[count];
421a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                int n = 0;
422a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                for (int i = 0; i < count; i++) {
423a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    LogicalDisplay display = mLogicalDisplays.valueAt(i);
424a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    DisplayInfo info = display.getDisplayInfoLocked();
425a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    if (info.hasAccess(callingUid)) {
426a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                        displayIds[n++] = mLogicalDisplays.keyAt(i);
427a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    }
428a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                }
429a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                if (n != count) {
430a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    displayIds = Arrays.copyOfRange(displayIds, 0, n);
431a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                }
432a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                return displayIds;
4334f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner            }
434a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        } finally {
435a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            Binder.restoreCallingIdentity(token);
436bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
437bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
4384f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner
439bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    @Override // Binder call
440bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    public void registerCallback(IDisplayManagerCallback callback) {
441bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        if (callback == null) {
442bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            throw new IllegalArgumentException("listener must not be null");
443bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
444bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
4454ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
446bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            int callingPid = Binder.getCallingPid();
447bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            if (mCallbacks.get(callingPid) != null) {
448bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                throw new SecurityException("The calling process has already "
449bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                        + "registered an IDisplayManagerCallback.");
4504f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner            }
451bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
452bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            CallbackRecord record = new CallbackRecord(callingPid, callback);
453bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            try {
454bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                IBinder binder = callback.asBinder();
455bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                binder.linkToDeath(record, 0);
456bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            } catch (RemoteException ex) {
457bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                // give up
458bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                throw new RuntimeException(ex);
459bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
460bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
461bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mCallbacks.put(callingPid, record);
462bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
4639de4936c99b979f6010440b043edc6d6142d1980Craig Mautner    }
4649de4936c99b979f6010440b043edc6d6142d1980Craig Mautner
465feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown    private void onCallbackDied(CallbackRecord record) {
4664ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
467feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown            mCallbacks.remove(record.mPid);
468feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown            stopWifiDisplayScanLocked(record);
469bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
470bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
471bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
472e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    @Override // Binder call
473feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown    public void startWifiDisplayScan() {
474af574183c274f51d04487a9c8355e9f34a1150f2Jeff Brown        mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
475feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                "Permission required to start wifi display scans");
476af574183c274f51d04487a9c8355e9f34a1150f2Jeff Brown
477feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown        final int callingPid = Binder.getCallingPid();
478e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        final long token = Binder.clearCallingIdentity();
479e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        try {
480e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            synchronized (mSyncRoot) {
481feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                CallbackRecord record = mCallbacks.get(callingPid);
482feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                if (record == null) {
483feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                    throw new IllegalStateException("The calling process has not "
484feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                            + "registered an IDisplayManagerCallback.");
485feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                }
486feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                startWifiDisplayScanLocked(record);
487feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown            }
488feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown        } finally {
489feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown            Binder.restoreCallingIdentity(token);
490feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown        }
491feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown    }
492feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown
493feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown    private void startWifiDisplayScanLocked(CallbackRecord record) {
494feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown        if (!record.mWifiDisplayScanRequested) {
495feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown            record.mWifiDisplayScanRequested = true;
496feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown            if (mWifiDisplayScanRequestCount++ == 0) {
49721c7153d30071dcbeb92daa1fd48ed181e42aef3Jeff Brown                if (mWifiDisplayAdapter != null) {
498feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                    mWifiDisplayAdapter.requestStartScanLocked();
49921c7153d30071dcbeb92daa1fd48ed181e42aef3Jeff Brown                }
500e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            }
501feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown        }
502feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown    }
503feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown
504feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown    @Override // Binder call
505feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown    public void stopWifiDisplayScan() {
506feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown        mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
507feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                "Permission required to stop wifi display scans");
508feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown
509feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown        final int callingPid = Binder.getCallingPid();
510feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown        final long token = Binder.clearCallingIdentity();
511feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown        try {
512feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown            synchronized (mSyncRoot) {
513feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                CallbackRecord record = mCallbacks.get(callingPid);
514feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                if (record == null) {
515feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                    throw new IllegalStateException("The calling process has not "
516feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                            + "registered an IDisplayManagerCallback.");
517feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                }
518feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                stopWifiDisplayScanLocked(record);
519feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown            }
520e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        } finally {
521e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            Binder.restoreCallingIdentity(token);
522e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        }
523e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    }
524e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown
525feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown    private void stopWifiDisplayScanLocked(CallbackRecord record) {
526feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown        if (record.mWifiDisplayScanRequested) {
527feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown            record.mWifiDisplayScanRequested = false;
528feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown            if (--mWifiDisplayScanRequestCount == 0) {
529feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                if (mWifiDisplayAdapter != null) {
530feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                    mWifiDisplayAdapter.requestStopScanLocked();
531feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                }
532feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown            } else if (mWifiDisplayScanRequestCount < 0) {
533feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                Log.wtf(TAG, "mWifiDisplayScanRequestCount became negative: "
534feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                        + mWifiDisplayScanRequestCount);
535feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                mWifiDisplayScanRequestCount = 0;
536feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown            }
537feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown        }
538feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown    }
539feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown
540e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    @Override // Binder call
541e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    public void connectWifiDisplay(String address) {
542e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        if (address == null) {
543e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            throw new IllegalArgumentException("address must not be null");
544e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        }
545af574183c274f51d04487a9c8355e9f34a1150f2Jeff Brown        mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
546af574183c274f51d04487a9c8355e9f34a1150f2Jeff Brown                "Permission required to connect to a wifi display");
547e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown
548e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        final long token = Binder.clearCallingIdentity();
549e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        try {
550e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            synchronized (mSyncRoot) {
55121c7153d30071dcbeb92daa1fd48ed181e42aef3Jeff Brown                if (mWifiDisplayAdapter != null) {
552af574183c274f51d04487a9c8355e9f34a1150f2Jeff Brown                    mWifiDisplayAdapter.requestConnectLocked(address);
55321c7153d30071dcbeb92daa1fd48ed181e42aef3Jeff Brown                }
554e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            }
555e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        } finally {
556e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            Binder.restoreCallingIdentity(token);
557e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        }
5581f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang    }
5591f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang
5601f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang    @Override
5611f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang    public void pauseWifiDisplay() {
562af574183c274f51d04487a9c8355e9f34a1150f2Jeff Brown        mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
563af574183c274f51d04487a9c8355e9f34a1150f2Jeff Brown                "Permission required to pause a wifi display session");
5641f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang
5651f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang        final long token = Binder.clearCallingIdentity();
5661f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang        try {
5671f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang            synchronized (mSyncRoot) {
5681f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang                if (mWifiDisplayAdapter != null) {
5691f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang                    mWifiDisplayAdapter.requestPauseLocked();
5701f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang                }
5711f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang            }
5721f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang        } finally {
5731f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang            Binder.restoreCallingIdentity(token);
5741f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang        }
5751f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang    }
5761f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang
5771f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang    @Override
5781f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang    public void resumeWifiDisplay() {
579af574183c274f51d04487a9c8355e9f34a1150f2Jeff Brown        mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
580af574183c274f51d04487a9c8355e9f34a1150f2Jeff Brown                "Permission required to resume a wifi display session");
5811f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang
5821f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang        final long token = Binder.clearCallingIdentity();
5831f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang        try {
5841f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang            synchronized (mSyncRoot) {
5851f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang                if (mWifiDisplayAdapter != null) {
5861f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang                    mWifiDisplayAdapter.requestResumeLocked();
5871f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang                }
5881f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang            }
5891f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang        } finally {
5901f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang            Binder.restoreCallingIdentity(token);
5911f3ecaae6303d5ee6c5ca8499262c9962f036365Chong Zhang        }
592e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    }
593e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown
594e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    @Override // Binder call
595e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    public void disconnectWifiDisplay() {
596af574183c274f51d04487a9c8355e9f34a1150f2Jeff Brown        // This request does not require special permissions.
597af574183c274f51d04487a9c8355e9f34a1150f2Jeff Brown        // Any app can request disconnection from the currently active wifi display.
598af574183c274f51d04487a9c8355e9f34a1150f2Jeff Brown        // This exception should no longer be needed once wifi display control moves
599af574183c274f51d04487a9c8355e9f34a1150f2Jeff Brown        // to the media router service.
600af574183c274f51d04487a9c8355e9f34a1150f2Jeff Brown
601e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        final long token = Binder.clearCallingIdentity();
602e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        try {
603e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            synchronized (mSyncRoot) {
60421c7153d30071dcbeb92daa1fd48ed181e42aef3Jeff Brown                if (mWifiDisplayAdapter != null) {
60521c7153d30071dcbeb92daa1fd48ed181e42aef3Jeff Brown                    mWifiDisplayAdapter.requestDisconnectLocked();
60621c7153d30071dcbeb92daa1fd48ed181e42aef3Jeff Brown                }
607e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            }
608e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        } finally {
609e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            Binder.restoreCallingIdentity(token);
610e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        }
611e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    }
612e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown
613e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    @Override // Binder call
61489d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    public void renameWifiDisplay(String address, String alias) {
61589d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        if (address == null) {
61689d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown            throw new IllegalArgumentException("address must not be null");
61789d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        }
618af574183c274f51d04487a9c8355e9f34a1150f2Jeff Brown        mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
619af574183c274f51d04487a9c8355e9f34a1150f2Jeff Brown                "Permission required to rename to a wifi display");
62089d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown
62189d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        final long token = Binder.clearCallingIdentity();
62289d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        try {
62389d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown            synchronized (mSyncRoot) {
62489d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown                if (mWifiDisplayAdapter != null) {
62589d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown                    mWifiDisplayAdapter.requestRenameLocked(address, alias);
62689d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown                }
62789d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown            }
62889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        } finally {
62989d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown            Binder.restoreCallingIdentity(token);
63089d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        }
63189d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    }
63289d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown
63389d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    @Override // Binder call
63489d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    public void forgetWifiDisplay(String address) {
63589d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        if (address == null) {
63689d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown            throw new IllegalArgumentException("address must not be null");
63789d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        }
638af574183c274f51d04487a9c8355e9f34a1150f2Jeff Brown        mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
639af574183c274f51d04487a9c8355e9f34a1150f2Jeff Brown                "Permission required to forget to a wifi display");
64089d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown
64189d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        final long token = Binder.clearCallingIdentity();
64289d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        try {
64389d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown            synchronized (mSyncRoot) {
64489d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown                if (mWifiDisplayAdapter != null) {
64589d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown                    mWifiDisplayAdapter.requestForgetLocked(address);
64689d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown                }
64789d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown            }
64889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        } finally {
64989d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown            Binder.restoreCallingIdentity(token);
65089d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        }
65189d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    }
65289d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown
65389d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    @Override // Binder call
654e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    public WifiDisplayStatus getWifiDisplayStatus() {
655af574183c274f51d04487a9c8355e9f34a1150f2Jeff Brown        // This request does not require special permissions.
656af574183c274f51d04487a9c8355e9f34a1150f2Jeff Brown        // Any app can get information about available wifi displays.
657af574183c274f51d04487a9c8355e9f34a1150f2Jeff Brown
658e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        final long token = Binder.clearCallingIdentity();
659e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        try {
660e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            synchronized (mSyncRoot) {
66121c7153d30071dcbeb92daa1fd48ed181e42aef3Jeff Brown                if (mWifiDisplayAdapter != null) {
66221c7153d30071dcbeb92daa1fd48ed181e42aef3Jeff Brown                    return mWifiDisplayAdapter.getWifiDisplayStatusLocked();
66321c7153d30071dcbeb92daa1fd48ed181e42aef3Jeff Brown                }
6640bf6ec9e377f9fafb67a36f7fb54d3f6676634fcCraig Mautner                return new WifiDisplayStatus();
665e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            }
666e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        } finally {
667e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown            Binder.restoreCallingIdentity(token);
668e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown        }
669e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown    }
670e08ae388d63c4db8f9d9a7ecd634f9a51f6e91b9Jeff Brown
671a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown    @Override // Binder call
6727d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown    public int createVirtualDisplay(IBinder appToken, String packageName,
6737d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown            String name, int width, int height, int densityDpi, Surface surface, int flags) {
674a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        final int callingUid = Binder.getCallingUid();
675a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        if (!validatePackageName(callingUid, packageName)) {
676a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            throw new SecurityException("packageName must match the calling uid");
677a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        }
678a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        if (appToken == null) {
679a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            throw new IllegalArgumentException("appToken must not be null");
680a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        }
681a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        if (TextUtils.isEmpty(name)) {
682a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            throw new IllegalArgumentException("name must be non-null and non-empty");
683a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        }
684a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        if (width <= 0 || height <= 0 || densityDpi <= 0) {
685a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            throw new IllegalArgumentException("width, height, and densityDpi must be "
686a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    + "greater than 0");
687a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        }
688a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        if (surface == null) {
689a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            throw new IllegalArgumentException("surface must not be null");
690a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        }
6917d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown        if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
6927d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown            if (mContext.checkCallingPermission(android.Manifest.permission.CAPTURE_VIDEO_OUTPUT)
6937d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown                    != PackageManager.PERMISSION_GRANTED
6947d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown                    && mContext.checkCallingPermission(
6957d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown                            android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT)
6967d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown                            != PackageManager.PERMISSION_GRANTED) {
6977d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown                throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or "
6987d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown                        + "CAPTURE_SECURE_VIDEO_OUTPUT permission to create a "
6997d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown                        + "public virtual display.");
7007d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown            }
7017d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown        }
7027d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown        if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE) != 0) {
7037d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown            if (mContext.checkCallingPermission(
7047d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown                    android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT)
7057d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown                    != PackageManager.PERMISSION_GRANTED) {
7067d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown                throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT "
7077d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown                        + "to create a secure virtual display.");
7087d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown            }
7097d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown        }
710a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown
711a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        final long token = Binder.clearCallingIdentity();
712a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        try {
713a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            synchronized (mSyncRoot) {
714a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                if (mVirtualDisplayAdapter == null) {
715a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    Slog.w(TAG, "Rejecting request to create private virtual display "
716a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                            + "because the virtual display adapter is not available.");
717a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    return -1;
718a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                }
719a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown
7207d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown                DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked(
721a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                        appToken, callingUid, packageName, name, width, height, densityDpi,
7227d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown                        surface, flags);
723a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                if (device == null) {
724a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    return -1;
725a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                }
726a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown
727a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                handleDisplayDeviceAddedLocked(device);
728a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
729a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                if (display != null) {
730a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    return display.getDisplayIdLocked();
731a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                }
732a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown
733a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                // Something weird happened and the logical display was not created.
7347d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown                Slog.w(TAG, "Rejecting request to create virtual display "
735a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                        + "because the logical display was not created.");
736a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken);
737a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                handleDisplayDeviceRemovedLocked(device);
738a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            }
739a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        } finally {
740a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            Binder.restoreCallingIdentity(token);
741a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        }
742a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        return -1;
743a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown    }
744a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown
745a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown    @Override // Binder call
746a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown    public void releaseVirtualDisplay(IBinder appToken) {
747a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        final long token = Binder.clearCallingIdentity();
748a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        try {
749a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            synchronized (mSyncRoot) {
750a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                if (mVirtualDisplayAdapter == null) {
751a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    return;
752a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                }
753a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown
754a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                DisplayDevice device =
755a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                        mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken);
756a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                if (device != null) {
757a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    handleDisplayDeviceRemovedLocked(device);
758a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                }
759a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            }
760a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        } finally {
761a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            Binder.restoreCallingIdentity(token);
762a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        }
763a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown    }
764a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown
765a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown    private boolean validatePackageName(int uid, String packageName) {
766a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        if (packageName != null) {
767a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
768a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            if (packageNames != null) {
769a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                for (String n : packageNames) {
770a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    if (n.equals(packageName)) {
771a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                        return true;
772a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    }
773a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                }
774a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            }
775a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        }
776a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        return false;
777a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown    }
778a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown
7794ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private void registerDefaultDisplayAdapter() {
7804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Register default display adapter.
7814ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
7824ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            if (mHeadless) {
7834ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                registerDisplayAdapterLocked(new HeadlessDisplayAdapter(
7844ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                        mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
7854ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            } else {
7864ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                registerDisplayAdapterLocked(new LocalDisplayAdapter(
7874ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                        mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
788bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
7894ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
7904ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
791bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
7924ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private void registerAdditionalDisplayAdapters() {
7934ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
7944ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            if (shouldRegisterNonEssentialDisplayAdaptersLocked()) {
79589d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown                registerOverlayDisplayAdapterLocked();
79689d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown                registerWifiDisplayAdapterLocked();
797a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                registerVirtualDisplayAdapterLocked();
798bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
7994ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
8004ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
801bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
80289d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    private void registerOverlayDisplayAdapterLocked() {
80389d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        registerDisplayAdapterLocked(new OverlayDisplayAdapter(
80489d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown                mSyncRoot, mContext, mHandler, mDisplayAdapterListener, mUiHandler));
80589d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    }
80689d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown
80789d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    private void registerWifiDisplayAdapterLocked() {
80889d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        if (mContext.getResources().getBoolean(
809bbd28a293f84baeafed469c5e223eff82c1117c0Jeff Brown                com.android.internal.R.bool.config_enableWifiDisplay)
810bbd28a293f84baeafed469c5e223eff82c1117c0Jeff Brown                || SystemProperties.getInt(FORCE_WIFI_DISPLAY_ENABLE, -1) == 1) {
81189d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown            mWifiDisplayAdapter = new WifiDisplayAdapter(
81289d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown                    mSyncRoot, mContext, mHandler, mDisplayAdapterListener,
81389d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown                    mPersistentDataStore);
81489d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown            registerDisplayAdapterLocked(mWifiDisplayAdapter);
81589d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown        }
81689d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown    }
81789d5546d7fd3a3bb19820c42e8b4527013dd6545Jeff Brown
818a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown    private void registerVirtualDisplayAdapterLocked() {
819a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        mVirtualDisplayAdapter = new VirtualDisplayAdapter(
820a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                mSyncRoot, mContext, mHandler, mDisplayAdapterListener);
821a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        registerDisplayAdapterLocked(mVirtualDisplayAdapter);
822a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown    }
823a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown
8244ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() {
8254ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // In safe mode, we disable non-essential display adapters to give the user
8264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // an opportunity to fix broken settings or other problems that might affect
8274ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // system stability.
8284ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // In only-core mode, we disable non-essential display adapters to minimize
8294ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // the number of dependencies that are started while in this mode and to
8304ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // prevent problems that might occur due to the device being encrypted.
8314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        return !mSafeMode && !mOnlyCore;
8324ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
833bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
8344ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private void registerDisplayAdapterLocked(DisplayAdapter adapter) {
8354ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        mDisplayAdapters.add(adapter);
8364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        adapter.registerLocked();
8374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
838bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
8394ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private void handleDisplayDeviceAdded(DisplayDevice device) {
8404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
841a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            handleDisplayDeviceAddedLocked(device);
842a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        }
843a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown    }
8444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
845a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown    private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
846a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        if (mDisplayDevices.contains(device)) {
847a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            Slog.w(TAG, "Attempted to add already added display device: "
848a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    + device.getDisplayDeviceInfoLocked());
849a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            return;
850a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        }
851e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown
852a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        Slog.i(TAG, "Display device added: " + device.getDisplayDeviceInfoLocked());
8539e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown
854a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        mDisplayDevices.add(device);
855a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        addLogicalDisplayLocked(device);
856a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        updateDisplayBlankingLocked(device);
857a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        scheduleTraversalLocked(false);
858bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
859bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
860bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private void handleDisplayDeviceChanged(DisplayDevice device) {
8614ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
862bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            if (!mDisplayDevices.contains(device)) {
8634ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                Slog.w(TAG, "Attempted to change non-existent display device: "
8644ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                        + device.getDisplayDeviceInfoLocked());
865bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                return;
866bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
867bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
868e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown            Slog.i(TAG, "Display device changed: " + device.getDisplayDeviceInfoLocked());
869e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown
8704ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            device.applyPendingDisplayDeviceInfoChangesLocked();
8714ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            if (updateLogicalDisplaysLocked()) {
87265d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner                scheduleTraversalLocked(false);
873bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
874bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
875bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
876bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
877bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private void handleDisplayDeviceRemoved(DisplayDevice device) {
8784ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
879a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            handleDisplayDeviceRemovedLocked(device);
880a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        }
881a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown    }
882a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown    private void handleDisplayDeviceRemovedLocked(DisplayDevice device) {
883a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        if (!mDisplayDevices.remove(device)) {
884a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            Slog.w(TAG, "Attempted to remove non-existent display device: "
885a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    + device.getDisplayDeviceInfoLocked());
886a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            return;
887a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        }
888bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
889a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        Slog.i(TAG, "Display device removed: " + device.getDisplayDeviceInfoLocked());
890e87bf030766198bf5e1fe846167dba766e27fb3fJeff Brown
891a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        updateLogicalDisplaysLocked();
892a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        scheduleTraversalLocked(false);
893a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown    }
894a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown
895a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown    private void updateAllDisplayBlankingLocked() {
896a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        final int count = mDisplayDevices.size();
897a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        for (int i = 0; i < count; i++) {
898a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            DisplayDevice device = mDisplayDevices.get(i);
899a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            updateDisplayBlankingLocked(device);
900a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        }
901a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown    }
902a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown
903a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown    private void updateDisplayBlankingLocked(DisplayDevice device) {
904a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        // Blank or unblank the display immediately to match the state requested
905a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        // by the power manager (if known).
906a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
907a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
908a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            switch (mAllDisplayBlankStateFromPowerManager) {
909a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                case DISPLAY_BLANK_STATE_BLANKED:
910a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    device.blankLocked();
911a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    break;
912a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                case DISPLAY_BLANK_STATE_UNBLANKED:
913a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    device.unblankLocked();
914a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                    break;
915a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            }
9164ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
9174ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
9184ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
9194ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // Adds a new logical display based on the given display device.
9204ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // Sends notifications if needed.
9214ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private void addLogicalDisplayLocked(DisplayDevice device) {
9224ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
9234ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        boolean isDefault = (deviceInfo.flags
9244ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0;
9254ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        if (isDefault && mLogicalDisplays.get(Display.DEFAULT_DISPLAY) != null) {
9264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            Slog.w(TAG, "Ignoring attempt to add a second default display: " + deviceInfo);
9274ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            isDefault = false;
9284ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
9294ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
93027f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown        if (!isDefault && mSingleDisplayDemoMode) {
93127f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown            Slog.i(TAG, "Not creating a logical display for a secondary display "
93227f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown                    + " because single display demo mode is enabled: " + deviceInfo);
93327f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown            return;
93427f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown        }
93527f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown
9364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        final int displayId = assignDisplayIdLocked(isDefault);
9374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        final int layerStack = assignLayerStackLocked(displayId);
9384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
939d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
9404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        display.updateLocked(mDisplayDevices);
9414ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        if (!display.isValidLocked()) {
9424ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            // This should never happen currently.
9434ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            Slog.w(TAG, "Ignoring display device because the logical display "
9444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    + "created from it was not considered valid: " + deviceInfo);
9454ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            return;
9464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
9474ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
9484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        mLogicalDisplays.put(displayId, display);
9494ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
9504ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Wake up waitForDefaultDisplay.
9514ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        if (isDefault) {
9524ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mSyncRoot.notifyAll();
9534ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
9544ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
9554ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED);
9564ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
9574ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
9584ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private int assignDisplayIdLocked(boolean isDefault) {
9594ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        return isDefault ? Display.DEFAULT_DISPLAY : mNextNonDefaultDisplayId++;
9604ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
9614ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
9624ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private int assignLayerStackLocked(int displayId) {
9634ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Currently layer stacks and display ids are the same.
9644ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // This need not be the case.
9654ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        return displayId;
9664ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
9674ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
9684ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // Updates all existing logical displays given the current set of display devices.
9694ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // Removes invalid logical displays.
9704ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // Sends notifications if needed.
9714ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private boolean updateLogicalDisplaysLocked() {
9724ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        boolean changed = false;
9734ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        for (int i = mLogicalDisplays.size(); i-- > 0; ) {
9744ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            final int displayId = mLogicalDisplays.keyAt(i);
9754ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            LogicalDisplay display = mLogicalDisplays.valueAt(i);
9764ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
9774ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
9784ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            display.updateLocked(mDisplayDevices);
9794ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            if (!display.isValidLocked()) {
9804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                mLogicalDisplays.removeAt(i);
9814ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED);
9824ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                changed = true;
9834ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
9844ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
9854ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                changed = true;
986bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
987bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
9884ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        return changed;
9894ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
9904ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
9914ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private void performTraversalInTransactionLocked() {
992d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        // Clear all viewports before configuring displays so that we can keep
993d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        // track of which ones we have configured.
994d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        clearViewportsLocked();
995d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown
9964ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Configure each display device.
9974ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        final int count = mDisplayDevices.size();
9984ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        for (int i = 0; i < count; i++) {
9994ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            DisplayDevice device = mDisplayDevices.get(i);
10004ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            configureDisplayInTransactionLocked(device);
10014ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            device.performTraversalInTransactionLocked();
10024ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
1003d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown
1004d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        // Tell the input system about these new viewports.
1005d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        if (mInputManagerFuncs != null) {
1006d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            mHandler.sendEmptyMessage(MSG_UPDATE_VIEWPORT);
1007d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        }
10084ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
10094ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
1010722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner    /**
1011722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     * Tells the display manager whether there is interesting unique content on the
1012722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     * specified logical display.  This is used to control automatic mirroring.
1013722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     * <p>
1014722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     * If the display has unique content, then the display manager arranges for it
1015722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     * to be presented on a physical display if appropriate.  Otherwise, the display manager
1016722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     * may choose to make the physical display mirror some other logical display.
1017722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     * </p>
1018722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     *
1019722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     * @param displayId The logical display id to update.
1020722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     * @param hasContent True if the logical display has content.
102165d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner     * @param inTraversal True if called from WindowManagerService during a window traversal prior
102265d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner     * to call to performTraversalInTransactionFromWindowManager.
1023722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner     */
102465d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner    public void setDisplayHasContent(int displayId, boolean hasContent, boolean inTraversal) {
1025722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner        synchronized (mSyncRoot) {
1026722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner            LogicalDisplay display = mLogicalDisplays.get(displayId);
1027722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner            if (display != null && display.hasContentLocked() != hasContent) {
102833041bd90301d50c61e6375bbd9bb6da2f1c8cbaJeff Brown                if (DEBUG) {
102933041bd90301d50c61e6375bbd9bb6da2f1c8cbaJeff Brown                    Slog.d(TAG, "Display " + displayId + " hasContent flag changed: "
103033041bd90301d50c61e6375bbd9bb6da2f1c8cbaJeff Brown                            + "hasContent=" + hasContent + ", inTraversal=" + inTraversal);
103133041bd90301d50c61e6375bbd9bb6da2f1c8cbaJeff Brown                }
103233041bd90301d50c61e6375bbd9bb6da2f1c8cbaJeff Brown
1033722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner                display.setHasContentLocked(hasContent);
103465d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner                scheduleTraversalLocked(inTraversal);
1035722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner            }
1036722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner        }
1037d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    }
10384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
1039d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    private void clearViewportsLocked() {
1040d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        mDefaultViewport.valid = false;
1041d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        mExternalTouchViewport.valid = false;
1042722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner    }
1043722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner
1044722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner    private void configureDisplayInTransactionLocked(DisplayDevice device) {
1045a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
1046a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        boolean isPrivate = (info.flags & DisplayDeviceInfo.FLAG_PRIVATE) != 0;
1047a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown
10484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Find the logical display that the display device is showing.
1049a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        // Private displays never mirror other displays.
1050722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner        LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
1051a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        if (!isPrivate) {
1052a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            if (display != null && !display.hasContentLocked()) {
1053a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                // If the display does not have any content of its own, then
1054a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                // automatically mirror the default logical display contents.
1055a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                display = null;
1056a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            }
1057a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            if (display == null) {
1058a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY);
1059a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown            }
10604ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
10614ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
10624ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Apply the logical display configuration to the display device.
10634ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        if (display == null) {
10644ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            // TODO: no logical display for the device, blank it
1065d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            Slog.w(TAG, "Missing logical display to use for physical display device: "
10664ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    + device.getDisplayDeviceInfoLocked());
1067d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            return;
10684ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
1069a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown        boolean isBlanked = (mAllDisplayBlankStateFromPowerManager == DISPLAY_BLANK_STATE_BLANKED)
1070a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown                && (info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0;
10710bf6ec9e377f9fafb67a36f7fb54d3f6676634fcCraig Mautner        display.configureDisplayInTransactionLocked(device, isBlanked);
1072d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown
1073d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        // Update the viewports if needed.
1074d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        if (!mDefaultViewport.valid
1075d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                && (info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
1076d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            setViewportLocked(mDefaultViewport, display, device);
1077d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        }
1078d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        if (!mExternalTouchViewport.valid
1079d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                && info.touch == DisplayDeviceInfo.TOUCH_EXTERNAL) {
1080d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            setViewportLocked(mExternalTouchViewport, display, device);
1081d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        }
1082d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    }
1083d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown
1084d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    private static void setViewportLocked(DisplayViewport viewport,
1085d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            LogicalDisplay display, DisplayDevice device) {
1086d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        viewport.valid = true;
1087d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        viewport.displayId = display.getDisplayIdLocked();
1088d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        device.populateViewportLocked(viewport);
10894ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
10904ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
10914ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private LogicalDisplay findLogicalDisplayForDeviceLocked(DisplayDevice device) {
10924ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        final int count = mLogicalDisplays.size();
10934ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        for (int i = 0; i < count; i++) {
10944ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            LogicalDisplay display = mLogicalDisplays.valueAt(i);
10954ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            if (display.getPrimaryDisplayDeviceLocked() == device) {
10964ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                return display;
10974ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            }
10984ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
10994ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        return null;
1100bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
1101bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1102bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private void sendDisplayEventLocked(int displayId, int event) {
1103bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT, displayId, event);
1104bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        mHandler.sendMessage(msg);
1105bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
1106bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
11074ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // Requests that performTraversalsInTransactionFromWindowManager be called at a
11084ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // later time to apply changes to surfaces and displays.
110965d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner    private void scheduleTraversalLocked(boolean inTraversal) {
11104ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        if (!mPendingTraversal && mWindowManagerFuncs != null) {
11114ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mPendingTraversal = true;
111265d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner            if (!inTraversal) {
111365d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner                mHandler.sendEmptyMessage(MSG_REQUEST_TRAVERSAL);
111465d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner            }
11154ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
11164ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
11174ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
11184ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // Runs on Handler thread.
11194ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    // Delivers display event notifications to callbacks.
1120bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private void deliverDisplayEvent(int displayId, int event) {
1121bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        if (DEBUG) {
11224ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            Slog.d(TAG, "Delivering display event: displayId="
11234ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    + displayId + ", event=" + event);
1124bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
1125bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
11264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Grab the lock and copy the callbacks.
1127bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        final int count;
11284ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
1129bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            count = mCallbacks.size();
1130bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mTempCallbacks.clear();
1131bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            for (int i = 0; i < count; i++) {
1132bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mTempCallbacks.add(mCallbacks.valueAt(i));
1133bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
1134bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
1135bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
11364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // After releasing the lock, send the notifications out.
1137bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        for (int i = 0; i < count; i++) {
1138bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mTempCallbacks.get(i).notifyDisplayEventAsync(displayId, event);
1139bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
1140bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        mTempCallbacks.clear();
11414f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner    }
11424f67ba6ba4e861b287a3ff0323c107aa77f66264Craig Mautner
1143fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown    @Override // Binder call
1144bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
1145fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown        if (mContext == null
1146fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown                || mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
1147fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown                        != PackageManager.PERMISSION_GRANTED) {
1148fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown            pw.println("Permission Denial: can't dump DisplayManager from from pid="
1149fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
1150fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown            return;
1151fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown        }
1152fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown
1153bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        pw.println("DISPLAY MANAGER (dumpsys display)");
1154fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown
11554ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        synchronized (mSyncRoot) {
11569e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            pw.println("  mHeadless=" + mHeadless);
11579e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            pw.println("  mOnlyCode=" + mOnlyCore);
11589e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            pw.println("  mSafeMode=" + mSafeMode);
11599e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            pw.println("  mPendingTraversal=" + mPendingTraversal);
11609e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            pw.println("  mAllDisplayBlankStateFromPowerManager="
11619e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown                    + mAllDisplayBlankStateFromPowerManager);
11629e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            pw.println("  mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId);
11639e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            pw.println("  mDefaultViewport=" + mDefaultViewport);
11649e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown            pw.println("  mExternalTouchViewport=" + mExternalTouchViewport);
116527f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown            pw.println("  mSingleDisplayDemoMode=" + mSingleDisplayDemoMode);
1166feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown            pw.println("  mWifiDisplayScanRequestCount=" + mWifiDisplayScanRequestCount);
11679e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown
1168bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "    ");
11694ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            ipw.increaseIndent();
1170bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1171bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            pw.println();
1172bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            pw.println("Display Adapters: size=" + mDisplayAdapters.size());
1173848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown            for (DisplayAdapter adapter : mDisplayAdapters) {
1174bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                pw.println("  " + adapter.getName());
11754ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                adapter.dumpLocked(ipw);
1176848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown            }
11779de4936c99b979f6010440b043edc6d6142d1980Craig Mautner
1178bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            pw.println();
1179bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            pw.println("Display Devices: size=" + mDisplayDevices.size());
1180bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            for (DisplayDevice device : mDisplayDevices) {
11814ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                pw.println("  " + device.getDisplayDeviceInfoLocked());
11824ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                device.dumpLocked(ipw);
1183bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
1184bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1185bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            final int logicalDisplayCount = mLogicalDisplays.size();
1186bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            pw.println();
1187bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            pw.println("Logical Displays: size=" + logicalDisplayCount);
1188bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            for (int i = 0; i < logicalDisplayCount; i++) {
1189bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                int displayId = mLogicalDisplays.keyAt(i);
1190bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                LogicalDisplay display = mLogicalDisplays.valueAt(i);
1191bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                pw.println("  Display " + displayId + ":");
11924ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                display.dumpLocked(ipw);
1193bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
1194feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown
1195feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown            final int callbackCount = mCallbacks.size();
1196feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown            pw.println();
1197feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown            pw.println("Callbacks: size=" + callbackCount);
1198feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown            for (int i = 0; i < callbackCount; i++) {
1199feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                CallbackRecord callback = mCallbacks.valueAt(i);
1200feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                pw.println("  " + i + ": mPid=" + callback.mPid
1201feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown                        + ", mWifiDisplayScanRequested=" + callback.mWifiDisplayScanRequested);
1202feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown            }
1203bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
1204bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
1205bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
12064ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    /**
12074ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * This is the object that everything in the display manager locks on.
12084ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * We make it an inner class within the {@link DisplayManagerService} to so that it is
12094ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * clear that the object belongs to the display manager service and that it is
12104ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * a unique object with a special purpose.
12114ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     */
12124ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public static final class SyncRoot {
12134ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
12144ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
12154ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    /**
12164ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * Private interface to the window manager.
12174ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     */
12184ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public interface WindowManagerFuncs {
12194ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        /**
1220722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner         * Request that the window manager call
1221722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner         * {@link #performTraversalInTransactionFromWindowManager} within a surface
1222722285e199a9fc74b9b3343b7505c00666848c88Craig Mautner         * transaction at a later time.
12234ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown         */
12244ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        void requestTraversal();
12254ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
12264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
1227d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    /**
1228d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown     * Private interface to the input manager.
1229d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown     */
1230d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    public interface InputManagerFuncs {
1231d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        /**
1232d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown         * Sets information about the displays as needed by the input system.
1233d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown         * The input system should copy this information if required.
1234d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown         */
1235d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        void setDisplayViewports(DisplayViewport defaultViewport,
1236d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                DisplayViewport externalTouchViewport);
1237d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    }
1238d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown
1239bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private final class DisplayManagerHandler extends Handler {
1240bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        public DisplayManagerHandler(Looper looper) {
1241bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            super(looper, null, true /*async*/);
1242848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown        }
1243bf5740e75efd87ae0213486e78e029403804c6f0Jeff Brown
1244bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        @Override
1245bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        public void handleMessage(Message msg) {
1246bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            switch (msg.what) {
1247bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER:
1248bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    registerDefaultDisplayAdapter();
1249bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    break;
1250bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1251bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS:
1252bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    registerAdditionalDisplayAdapters();
1253bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    break;
1254bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1255bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                case MSG_DELIVER_DISPLAY_EVENT:
1256bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    deliverDisplayEvent(msg.arg1, msg.arg2);
1257bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    break;
12584ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
12594ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                case MSG_REQUEST_TRAVERSAL:
12604ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    mWindowManagerFuncs.requestTraversal();
12614ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    break;
1262d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown
1263d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                case MSG_UPDATE_VIEWPORT: {
1264d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                    synchronized (mSyncRoot) {
1265d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                        mTempDefaultViewport.copyFrom(mDefaultViewport);
1266d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                        mTempExternalTouchViewport.copyFrom(mExternalTouchViewport);
1267d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                    }
1268d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                    mInputManagerFuncs.setDisplayViewports(
1269d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                            mTempDefaultViewport, mTempExternalTouchViewport);
1270d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                    break;
1271d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                }
1272bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
1273bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
1274bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
1275bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1276bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private final class DisplayAdapterListener implements DisplayAdapter.Listener {
1277bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        @Override
1278bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        public void onDisplayDeviceEvent(DisplayDevice device, int event) {
1279bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            switch (event) {
1280bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                case DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED:
1281bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    handleDisplayDeviceAdded(device);
1282bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    break;
1283bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1284bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                case DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED:
1285bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    handleDisplayDeviceChanged(device);
1286bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    break;
1287bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1288bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                case DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED:
1289bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    handleDisplayDeviceRemoved(device);
1290bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    break;
1291bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
1292bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
12934ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
12944ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        @Override
12954ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        public void onTraversalRequested() {
12964ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            synchronized (mSyncRoot) {
129765d11b3eeff395011a2c6b56eb117fd3c4881c1aCraig Mautner                scheduleTraversalLocked(false);
12984ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            }
12994ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
1300bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
1301bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1302bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private final class CallbackRecord implements DeathRecipient {
1303feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown        public final int mPid;
1304bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final IDisplayManagerCallback mCallback;
1305bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1306feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown        public boolean mWifiDisplayScanRequested;
1307feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown
1308bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        public CallbackRecord(int pid, IDisplayManagerCallback callback) {
1309bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mPid = pid;
1310bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mCallback = callback;
1311bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
1312bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1313bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        @Override
1314bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        public void binderDied() {
1315bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            if (DEBUG) {
1316bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                Slog.d(TAG, "Display listener for pid " + mPid + " died.");
1317bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
1318feef9887e8f8eb6f64fc1b4552c02efb5755cdc1Jeff Brown            onCallbackDied(this);
1319bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
1320bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1321bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        public void notifyDisplayEventAsync(int displayId, int event) {
1322bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            try {
1323bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mCallback.onDisplayEvent(displayId, event);
1324bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            } catch (RemoteException ex) {
1325bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                Slog.w(TAG, "Failed to notify process "
1326bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                        + mPid + " that displays changed, assuming it died.", ex);
1327bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                binderDied();
1328bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
1329bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
1330bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
1331fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown}
1332