blob: e58a0a5cb04d489a753e594ea847a037bac78c0d [file] [log] [blame]
Jeff Brownfa25bf52012-07-23 19:26:30 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.display;
18
Jeff Brownbd6e1502012-08-28 03:27:37 -070019import com.android.internal.util.IndentingPrintWriter;
20
Jeff Brownfa25bf52012-07-23 19:26:30 -070021import android.Manifest;
22import android.content.Context;
23import android.content.pm.PackageManager;
Jeff Brownbd6e1502012-08-28 03:27:37 -070024import android.hardware.display.DisplayManagerGlobal;
Jeff Brownfa25bf52012-07-23 19:26:30 -070025import android.hardware.display.IDisplayManager;
Jeff Brownbd6e1502012-08-28 03:27:37 -070026import android.hardware.display.IDisplayManagerCallback;
Jeff Browne08ae382012-09-07 20:36:36 -070027import android.hardware.display.WifiDisplayStatus;
Jeff Brownfa25bf52012-07-23 19:26:30 -070028import android.os.Binder;
Jeff Brownbd6e1502012-08-28 03:27:37 -070029import android.os.Handler;
Jeff Brown64a55af2012-08-26 02:47:39 -070030import android.os.IBinder;
Jeff Brownbd6e1502012-08-28 03:27:37 -070031import android.os.Looper;
32import android.os.Message;
33import android.os.RemoteException;
34import android.os.SystemClock;
Jeff Brownfa25bf52012-07-23 19:26:30 -070035import android.os.SystemProperties;
Jeff Brownbd6e1502012-08-28 03:27:37 -070036import android.util.Slog;
37import android.util.SparseArray;
Jeff Brownfa25bf52012-07-23 19:26:30 -070038import android.view.Display;
39import android.view.DisplayInfo;
Jeff Brownfa25bf52012-07-23 19:26:30 -070040
41import java.io.FileDescriptor;
42import java.io.PrintWriter;
43import java.util.ArrayList;
44
45/**
Jeff Brownbd6e1502012-08-28 03:27:37 -070046 * Manages attached displays.
Jeff Brownfa25bf52012-07-23 19:26:30 -070047 * <p>
Jeff Brownbd6e1502012-08-28 03:27:37 -070048 * The {@link DisplayManagerService} manages the global lifecycle of displays,
49 * decides how to configure logical displays based on the physical display devices currently
50 * attached, sends notifications to the system and to applications when the state
51 * changes, and so on.
52 * </p><p>
53 * The display manager service relies on a collection of {@link DisplayAdapter} components,
54 * for discovering and configuring physical display devices attached to the system.
55 * There are separate display adapters for each manner that devices are attached:
56 * one display adapter for built-in local displays, one for simulated non-functional
57 * displays when the system is headless, one for simulated overlay displays used for
58 * development, one for wifi displays, etc.
59 * </p><p>
60 * Display adapters are only weakly coupled to the display manager service.
61 * Display adapters communicate changes in display device state to the display manager
Craig Mautner722285e2012-09-07 13:55:58 -070062 * service asynchronously via a {@link DisplayAdapter.Listener} registered
Jeff Brownbd6e1502012-08-28 03:27:37 -070063 * by the display manager service. This separation of concerns is important for
64 * two main reasons. First, it neatly encapsulates the responsibilities of these
65 * two classes: display adapters handle individual display devices whereas
66 * the display manager service handles the global state. Second, it eliminates
67 * the potential for deadlocks resulting from asynchronous display device discovery.
Jeff Brown4ed8fe72012-08-30 18:18:29 -070068 * </p>
69 *
70 * <h3>Synchronization</h3>
71 * <p>
72 * Because the display manager may be accessed by multiple threads, the synchronization
73 * story gets a little complicated. In particular, the window manager may call into
74 * the display manager while holding a surface transaction with the expectation that
75 * it can apply changes immediately. Unfortunately, that means we can't just do
76 * everything asynchronously (*grump*).
Jeff Brownbd6e1502012-08-28 03:27:37 -070077 * </p><p>
Jeff Brown4ed8fe72012-08-30 18:18:29 -070078 * To make this work, all of the objects that belong to the display manager must
79 * use the same lock. We call this lock the synchronization root and it has a unique
80 * type {@link DisplayManagerService.SyncRoot}. Methods that require this lock are
81 * named with the "Locked" suffix.
82 * </p><p>
83 * Where things get tricky is that the display manager is not allowed to make
84 * any potentially reentrant calls, especially into the window manager. We generally
85 * avoid this by making all potentially reentrant out-calls asynchronous.
Jeff Brownfa25bf52012-07-23 19:26:30 -070086 * </p>
87 */
88public final class DisplayManagerService extends IDisplayManager.Stub {
89 private static final String TAG = "DisplayManagerService";
Jeff Brownbd6e1502012-08-28 03:27:37 -070090 private static final boolean DEBUG = false;
Jeff Brownfa25bf52012-07-23 19:26:30 -070091
Jeff Brownbbd28a22012-09-20 16:47:15 -070092 // When this system property is set to 0, WFD is forcibly disabled on boot.
93 // When this system property is set to 1, WFD is forcibly enabled on boot.
94 // Otherwise WFD is enabled according to the value of config_enableWifiDisplay.
95 private static final String FORCE_WIFI_DISPLAY_ENABLE = "persist.debug.wfd.enable";
96
Jeff Brownfa25bf52012-07-23 19:26:30 -070097 private static final String SYSTEM_HEADLESS = "ro.config.headless";
Jeff Brownbd6e1502012-08-28 03:27:37 -070098 private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000;
99
100 private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER = 1;
101 private static final int MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS = 2;
102 private static final int MSG_DELIVER_DISPLAY_EVENT = 3;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700103 private static final int MSG_REQUEST_TRAVERSAL = 4;
Jeff Brownd728bf52012-09-08 18:05:28 -0700104 private static final int MSG_UPDATE_VIEWPORT = 5;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700105
Jeff Brown9e316a12012-10-08 19:17:06 -0700106 private static final int DISPLAY_BLANK_STATE_UNKNOWN = 0;
107 private static final int DISPLAY_BLANK_STATE_BLANKED = 1;
108 private static final int DISPLAY_BLANK_STATE_UNBLANKED = 2;
109
Jeff Brown848c2dc2012-08-19 20:18:08 -0700110 private final Context mContext;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700111 private final boolean mHeadless;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700112 private final DisplayManagerHandler mHandler;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700113 private final Handler mUiHandler;
114 private final DisplayAdapterListener mDisplayAdapterListener;
115 private WindowManagerFuncs mWindowManagerFuncs;
Jeff Brownd728bf52012-09-08 18:05:28 -0700116 private InputManagerFuncs mInputManagerFuncs;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700117
118 // The synchronization root for the display manager.
119 // This lock guards most of the display manager's state.
120 private final SyncRoot mSyncRoot = new SyncRoot();
121
122 // True if in safe mode.
123 // This option may disable certain display adapters.
124 public boolean mSafeMode;
125
126 // True if we are in a special boot mode where only core applications and
127 // services should be started. This option may disable certain display adapters.
128 public boolean mOnlyCore;
129
Jeff Brown27f1d672012-10-17 18:32:34 -0700130 // True if the display manager service should pretend there is only one display
131 // and only tell applications about the existence of the default logical display.
132 // The display manager can still mirror content to secondary displays but applications
133 // cannot present unique content on those displays.
134 // Used for demonstration purposes only.
135 private final boolean mSingleDisplayDemoMode;
136
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700137 // All callback records indexed by calling process id.
138 public final SparseArray<CallbackRecord> mCallbacks =
Jeff Brownbd6e1502012-08-28 03:27:37 -0700139 new SparseArray<CallbackRecord>();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700140
Jeff Brownbd6e1502012-08-28 03:27:37 -0700141 // List of all currently registered display adapters.
142 private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
143
144 // List of all currently connected display devices.
145 private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>();
146
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700147 // List of all removed display devices.
148 private final ArrayList<DisplayDevice> mRemovedDisplayDevices = new ArrayList<DisplayDevice>();
149
150 // List of all logical displays indexed by logical display id.
151 private final SparseArray<LogicalDisplay> mLogicalDisplays =
152 new SparseArray<LogicalDisplay>();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700153 private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1;
154
Jeff Brown9e316a12012-10-08 19:17:06 -0700155 // Set to true if all displays have been blanked by the power manager.
156 private int mAllDisplayBlankStateFromPowerManager;
157
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700158 // Set to true when there are pending display changes that have yet to be applied
159 // to the surface flinger state.
160 private boolean mPendingTraversal;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700161
Jeff Browne08ae382012-09-07 20:36:36 -0700162 // The Wifi display adapter, or null if not registered.
163 private WifiDisplayAdapter mWifiDisplayAdapter;
164
Jeff Brownd728bf52012-09-08 18:05:28 -0700165 // Viewports of the default display and the display that should receive touch
166 // input from an external source. Used by the input system.
167 private final DisplayViewport mDefaultViewport = new DisplayViewport();
168 private final DisplayViewport mExternalTouchViewport = new DisplayViewport();
169
Jeff Brown89d55462012-09-19 11:33:42 -0700170 // Persistent data store for all internal settings maintained by the display manager service.
171 private final PersistentDataStore mPersistentDataStore = new PersistentDataStore();
172
Jeff Brownbd6e1502012-08-28 03:27:37 -0700173 // Temporary callback list, used when sending display events to applications.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700174 // May be used outside of the lock but only on the handler thread.
175 private final ArrayList<CallbackRecord> mTempCallbacks = new ArrayList<CallbackRecord>();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700176
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700177 // Temporary display info, used for comparing display configurations.
178 private final DisplayInfo mTempDisplayInfo = new DisplayInfo();
179
Jeff Brownd728bf52012-09-08 18:05:28 -0700180 // Temporary viewports, used when sending new viewport information to the
181 // input system. May be used outside of the lock but only on the handler thread.
182 private final DisplayViewport mTempDefaultViewport = new DisplayViewport();
183 private final DisplayViewport mTempExternalTouchViewport = new DisplayViewport();
184
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700185 public DisplayManagerService(Context context, Handler mainHandler, Handler uiHandler) {
Jeff Brown848c2dc2012-08-19 20:18:08 -0700186 mContext = context;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700187 mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1");
Jeff Brown848c2dc2012-08-19 20:18:08 -0700188
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700189 mHandler = new DisplayManagerHandler(mainHandler.getLooper());
190 mUiHandler = uiHandler;
191 mDisplayAdapterListener = new DisplayAdapterListener();
Jeff Brown27f1d672012-10-17 18:32:34 -0700192 mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700193
Jeff Brownbd6e1502012-08-28 03:27:37 -0700194 mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER);
Craig Mautner4f67ba62012-08-02 11:23:00 -0700195 }
196
Jeff Brownbd6e1502012-08-28 03:27:37 -0700197 /**
198 * Pauses the boot process to wait for the first display to be initialized.
199 */
200 public boolean waitForDefaultDisplay() {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700201 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700202 long timeout = SystemClock.uptimeMillis() + WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
203 while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null) {
204 long delay = timeout - SystemClock.uptimeMillis();
205 if (delay <= 0) {
206 return false;
207 }
208 if (DEBUG) {
209 Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay);
210 }
211 try {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700212 mSyncRoot.wait(delay);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700213 } catch (InterruptedException ex) {
214 }
215 }
216 }
217 return true;
218 }
219
220 /**
Jeff Brownd728bf52012-09-08 18:05:28 -0700221 * Called during initialization to associate the display manager with the
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700222 * window manager.
223 */
224 public void setWindowManager(WindowManagerFuncs windowManagerFuncs) {
225 synchronized (mSyncRoot) {
226 mWindowManagerFuncs = windowManagerFuncs;
Craig Mautner65d11b32012-10-01 13:59:52 -0700227 scheduleTraversalLocked(false);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700228 }
229 }
230
231 /**
Jeff Brownd728bf52012-09-08 18:05:28 -0700232 * Called during initialization to associate the display manager with the
233 * input manager.
234 */
235 public void setInputManager(InputManagerFuncs inputManagerFuncs) {
236 synchronized (mSyncRoot) {
237 mInputManagerFuncs = inputManagerFuncs;
Craig Mautner65d11b32012-10-01 13:59:52 -0700238 scheduleTraversalLocked(false);
Jeff Brownd728bf52012-09-08 18:05:28 -0700239 }
240 }
241
242 /**
Jeff Brownbd6e1502012-08-28 03:27:37 -0700243 * Called when the system is ready to go.
244 */
245 public void systemReady(boolean safeMode, boolean onlyCore) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700246 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700247 mSafeMode = safeMode;
248 mOnlyCore = onlyCore;
249 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700250
Jeff Brownbd6e1502012-08-28 03:27:37 -0700251 mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
252 }
253
Jeff Brown848c2dc2012-08-19 20:18:08 -0700254 /**
255 * Returns true if the device is headless.
256 *
257 * @return True if the device is headless.
258 */
Jeff Brownfa25bf52012-07-23 19:26:30 -0700259 public boolean isHeadless() {
260 return mHeadless;
261 }
262
Craig Mautner4f67ba62012-08-02 11:23:00 -0700263 /**
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700264 * Overrides the display information of a particular logical display.
265 * This is used by the window manager to control the size and characteristics
266 * of the default display. It is expected to apply the requested change
267 * to the display information synchronously so that applications will immediately
268 * observe the new state.
Jeff Brownbd6e1502012-08-28 03:27:37 -0700269 *
Jeff Brown64a55af2012-08-26 02:47:39 -0700270 * @param displayId The logical display id.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700271 * @param info The new data to be stored.
Jeff Brown64a55af2012-08-26 02:47:39 -0700272 */
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700273 public void setDisplayInfoOverrideFromWindowManager(
274 int displayId, DisplayInfo info) {
275 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700276 LogicalDisplay display = mLogicalDisplays.get(displayId);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700277 if (display != null) {
278 mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
279 display.setDisplayInfoOverrideFromWindowManagerLocked(info);
280 if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
281 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
Craig Mautner65d11b32012-10-01 13:59:52 -0700282 scheduleTraversalLocked(false);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700283 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700284 }
285 }
286 }
287
288 /**
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700289 * Called by the window manager to perform traversals while holding a
290 * surface flinger transaction.
Jeff Brownbd6e1502012-08-28 03:27:37 -0700291 */
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700292 public void performTraversalInTransactionFromWindowManager() {
293 synchronized (mSyncRoot) {
294 if (!mPendingTraversal) {
295 return;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700296 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700297 mPendingTraversal = false;
298
299 performTraversalInTransactionLocked();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700300 }
301 }
302
303 /**
Jeff Brown9e316a12012-10-08 19:17:06 -0700304 * Called by the power manager to blank all displays.
305 */
306 public void blankAllDisplaysFromPowerManager() {
307 synchronized (mSyncRoot) {
308 if (mAllDisplayBlankStateFromPowerManager != DISPLAY_BLANK_STATE_BLANKED) {
309 mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_BLANKED;
310
311 final int count = mDisplayDevices.size();
312 for (int i = 0; i < count; i++) {
313 DisplayDevice device = mDisplayDevices.get(i);
314 device.blankLocked();
315 }
Jeff Brown8ec09432012-10-16 16:19:23 -0700316
317 scheduleTraversalLocked(false);
Jeff Brown9e316a12012-10-08 19:17:06 -0700318 }
319 }
320 }
321
322 /**
323 * Called by the power manager to unblank all displays.
324 */
325 public void unblankAllDisplaysFromPowerManager() {
326 synchronized (mSyncRoot) {
327 if (mAllDisplayBlankStateFromPowerManager != DISPLAY_BLANK_STATE_UNBLANKED) {
328 mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_UNBLANKED;
329
330 final int count = mDisplayDevices.size();
331 for (int i = 0; i < count; i++) {
332 DisplayDevice device = mDisplayDevices.get(i);
333 device.unblankLocked();
334 }
Jeff Brown8ec09432012-10-16 16:19:23 -0700335
336 scheduleTraversalLocked(false);
Jeff Brown9e316a12012-10-08 19:17:06 -0700337 }
338 }
339 }
340
341 /**
Jeff Brownbd6e1502012-08-28 03:27:37 -0700342 * Returns information about the specified logical display.
343 *
344 * @param displayId The logical display id.
Craig Mautner722285e2012-09-07 13:55:58 -0700345 * @return The logical display info, or null if the display does not exist. The
346 * returned object must be treated as immutable.
Jeff Brownbd6e1502012-08-28 03:27:37 -0700347 */
348 @Override // Binder call
349 public DisplayInfo getDisplayInfo(int displayId) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700350 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700351 LogicalDisplay display = mLogicalDisplays.get(displayId);
352 if (display != null) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700353 return display.getDisplayInfoLocked();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700354 }
355 return null;
356 }
357 }
358
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700359 /**
360 * Returns the list of all display ids.
361 */
Jeff Brownbd6e1502012-08-28 03:27:37 -0700362 @Override // Binder call
363 public int[] getDisplayIds() {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700364 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700365 final int count = mLogicalDisplays.size();
366 int[] displayIds = new int[count];
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700367 for (int i = 0; i < count; i++) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700368 displayIds[i] = mLogicalDisplays.keyAt(i);
369 }
370 return displayIds;
371 }
372 }
373
374 @Override // Binder call
375 public void registerCallback(IDisplayManagerCallback callback) {
376 if (callback == null) {
377 throw new IllegalArgumentException("listener must not be null");
378 }
379
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700380 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700381 int callingPid = Binder.getCallingPid();
382 if (mCallbacks.get(callingPid) != null) {
383 throw new SecurityException("The calling process has already "
384 + "registered an IDisplayManagerCallback.");
Jeff Brown64a55af2012-08-26 02:47:39 -0700385 }
386
Jeff Brownbd6e1502012-08-28 03:27:37 -0700387 CallbackRecord record = new CallbackRecord(callingPid, callback);
388 try {
389 IBinder binder = callback.asBinder();
390 binder.linkToDeath(record, 0);
391 } catch (RemoteException ex) {
392 // give up
393 throw new RuntimeException(ex);
394 }
395
396 mCallbacks.put(callingPid, record);
397 }
398 }
399
400 private void onCallbackDied(int pid) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700401 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700402 mCallbacks.remove(pid);
403 }
404 }
405
Jeff Browne08ae382012-09-07 20:36:36 -0700406 @Override // Binder call
407 public void scanWifiDisplays() {
Jeff Browne08ae382012-09-07 20:36:36 -0700408 final long token = Binder.clearCallingIdentity();
409 try {
410 synchronized (mSyncRoot) {
Jeff Brown21c71532012-09-09 13:26:55 -0700411 if (mWifiDisplayAdapter != null) {
412 mWifiDisplayAdapter.requestScanLocked();
413 }
Jeff Browne08ae382012-09-07 20:36:36 -0700414 }
415 } finally {
416 Binder.restoreCallingIdentity(token);
417 }
418 }
419
420 @Override // Binder call
421 public void connectWifiDisplay(String address) {
Jeff Browne08ae382012-09-07 20:36:36 -0700422 if (address == null) {
423 throw new IllegalArgumentException("address must not be null");
424 }
425
Jeff Brownbc335452012-09-26 18:34:47 -0700426 final boolean trusted = canCallerConfigureWifiDisplay();
Jeff Browne08ae382012-09-07 20:36:36 -0700427 final long token = Binder.clearCallingIdentity();
428 try {
429 synchronized (mSyncRoot) {
Jeff Brown21c71532012-09-09 13:26:55 -0700430 if (mWifiDisplayAdapter != null) {
Jeff Brownbc335452012-09-26 18:34:47 -0700431 mWifiDisplayAdapter.requestConnectLocked(address, trusted);
Jeff Brown21c71532012-09-09 13:26:55 -0700432 }
Jeff Browne08ae382012-09-07 20:36:36 -0700433 }
434 } finally {
435 Binder.restoreCallingIdentity(token);
436 }
437 }
438
439 @Override // Binder call
440 public void disconnectWifiDisplay() {
Jeff Browne08ae382012-09-07 20:36:36 -0700441 final long token = Binder.clearCallingIdentity();
442 try {
443 synchronized (mSyncRoot) {
Jeff Brown21c71532012-09-09 13:26:55 -0700444 if (mWifiDisplayAdapter != null) {
445 mWifiDisplayAdapter.requestDisconnectLocked();
446 }
Jeff Browne08ae382012-09-07 20:36:36 -0700447 }
448 } finally {
449 Binder.restoreCallingIdentity(token);
450 }
451 }
452
453 @Override // Binder call
Jeff Brown89d55462012-09-19 11:33:42 -0700454 public void renameWifiDisplay(String address, String alias) {
Jeff Brown89d55462012-09-19 11:33:42 -0700455 if (address == null) {
456 throw new IllegalArgumentException("address must not be null");
457 }
Jeff Brownbc335452012-09-26 18:34:47 -0700458 if (!canCallerConfigureWifiDisplay()) {
459 throw new SecurityException("Requires CONFIGURE_WIFI_DISPLAY permission to "
460 + "rename a wifi display.");
461 }
Jeff Brown89d55462012-09-19 11:33:42 -0700462
463 final long token = Binder.clearCallingIdentity();
464 try {
465 synchronized (mSyncRoot) {
466 if (mWifiDisplayAdapter != null) {
467 mWifiDisplayAdapter.requestRenameLocked(address, alias);
468 }
469 }
470 } finally {
471 Binder.restoreCallingIdentity(token);
472 }
473 }
474
475 @Override // Binder call
476 public void forgetWifiDisplay(String address) {
Jeff Brown89d55462012-09-19 11:33:42 -0700477 if (address == null) {
478 throw new IllegalArgumentException("address must not be null");
479 }
Jeff Brownbc335452012-09-26 18:34:47 -0700480 if (!canCallerConfigureWifiDisplay()) {
481 throw new SecurityException("Requires CONFIGURE_WIFI_DISPLAY permission to "
482 + "forget a wifi display.");
483 }
Jeff Brown89d55462012-09-19 11:33:42 -0700484
485 final long token = Binder.clearCallingIdentity();
486 try {
487 synchronized (mSyncRoot) {
488 if (mWifiDisplayAdapter != null) {
489 mWifiDisplayAdapter.requestForgetLocked(address);
490 }
491 }
492 } finally {
493 Binder.restoreCallingIdentity(token);
494 }
495 }
496
497 @Override // Binder call
Jeff Browne08ae382012-09-07 20:36:36 -0700498 public WifiDisplayStatus getWifiDisplayStatus() {
Jeff Browne08ae382012-09-07 20:36:36 -0700499 final long token = Binder.clearCallingIdentity();
500 try {
501 synchronized (mSyncRoot) {
Jeff Brown21c71532012-09-09 13:26:55 -0700502 if (mWifiDisplayAdapter != null) {
503 return mWifiDisplayAdapter.getWifiDisplayStatusLocked();
504 } else {
505 return new WifiDisplayStatus();
506 }
Jeff Browne08ae382012-09-07 20:36:36 -0700507 }
508 } finally {
509 Binder.restoreCallingIdentity(token);
510 }
511 }
512
Jeff Brownbc335452012-09-26 18:34:47 -0700513 private boolean canCallerConfigureWifiDisplay() {
514 return mContext.checkCallingPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
515 == PackageManager.PERMISSION_GRANTED;
516 }
517
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700518 private void registerDefaultDisplayAdapter() {
519 // Register default display adapter.
520 synchronized (mSyncRoot) {
521 if (mHeadless) {
522 registerDisplayAdapterLocked(new HeadlessDisplayAdapter(
523 mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
524 } else {
525 registerDisplayAdapterLocked(new LocalDisplayAdapter(
526 mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
527 }
528 }
529 }
530
531 private void registerAdditionalDisplayAdapters() {
532 synchronized (mSyncRoot) {
533 if (shouldRegisterNonEssentialDisplayAdaptersLocked()) {
Jeff Brown89d55462012-09-19 11:33:42 -0700534 registerOverlayDisplayAdapterLocked();
535 registerWifiDisplayAdapterLocked();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700536 }
537 }
538 }
539
Jeff Brown89d55462012-09-19 11:33:42 -0700540 private void registerOverlayDisplayAdapterLocked() {
541 registerDisplayAdapterLocked(new OverlayDisplayAdapter(
542 mSyncRoot, mContext, mHandler, mDisplayAdapterListener, mUiHandler));
543 }
544
545 private void registerWifiDisplayAdapterLocked() {
546 if (mContext.getResources().getBoolean(
Jeff Brownbbd28a22012-09-20 16:47:15 -0700547 com.android.internal.R.bool.config_enableWifiDisplay)
548 || SystemProperties.getInt(FORCE_WIFI_DISPLAY_ENABLE, -1) == 1) {
Jeff Brown89d55462012-09-19 11:33:42 -0700549 mWifiDisplayAdapter = new WifiDisplayAdapter(
550 mSyncRoot, mContext, mHandler, mDisplayAdapterListener,
551 mPersistentDataStore);
552 registerDisplayAdapterLocked(mWifiDisplayAdapter);
553 }
554 }
555
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700556 private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() {
557 // In safe mode, we disable non-essential display adapters to give the user
558 // an opportunity to fix broken settings or other problems that might affect
559 // system stability.
560 // In only-core mode, we disable non-essential display adapters to minimize
561 // the number of dependencies that are started while in this mode and to
562 // prevent problems that might occur due to the device being encrypted.
563 return !mSafeMode && !mOnlyCore;
564 }
565
566 private void registerDisplayAdapterLocked(DisplayAdapter adapter) {
567 mDisplayAdapters.add(adapter);
568 adapter.registerLocked();
569 }
570
Jeff Brownbd6e1502012-08-28 03:27:37 -0700571 private void handleDisplayDeviceAdded(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700572 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700573 if (mDisplayDevices.contains(device)) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700574 Slog.w(TAG, "Attempted to add already added display device: "
575 + device.getDisplayDeviceInfoLocked());
Jeff Brownbd6e1502012-08-28 03:27:37 -0700576 return;
577 }
578
Jeff Browne87bf032012-09-20 18:30:13 -0700579 Slog.i(TAG, "Display device added: " + device.getDisplayDeviceInfoLocked());
580
Jeff Brownbd6e1502012-08-28 03:27:37 -0700581 mDisplayDevices.add(device);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700582 addLogicalDisplayLocked(device);
Craig Mautner65d11b32012-10-01 13:59:52 -0700583 scheduleTraversalLocked(false);
Jeff Brown9e316a12012-10-08 19:17:06 -0700584
585 // Blank or unblank the display immediately to match the state requested
586 // by the power manager (if known).
587 switch (mAllDisplayBlankStateFromPowerManager) {
588 case DISPLAY_BLANK_STATE_BLANKED:
589 device.blankLocked();
590 break;
591 case DISPLAY_BLANK_STATE_UNBLANKED:
592 device.unblankLocked();
593 break;
594 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700595 }
596 }
597
Jeff Brownbd6e1502012-08-28 03:27:37 -0700598 private void handleDisplayDeviceChanged(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700599 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700600 if (!mDisplayDevices.contains(device)) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700601 Slog.w(TAG, "Attempted to change non-existent display device: "
602 + device.getDisplayDeviceInfoLocked());
Jeff Brownbd6e1502012-08-28 03:27:37 -0700603 return;
604 }
605
Jeff Browne87bf032012-09-20 18:30:13 -0700606 Slog.i(TAG, "Display device changed: " + device.getDisplayDeviceInfoLocked());
607
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700608 device.applyPendingDisplayDeviceInfoChangesLocked();
609 if (updateLogicalDisplaysLocked()) {
Craig Mautner65d11b32012-10-01 13:59:52 -0700610 scheduleTraversalLocked(false);
Jeff Brown64a55af2012-08-26 02:47:39 -0700611 }
612 }
613 }
614
Jeff Brownbd6e1502012-08-28 03:27:37 -0700615 private void handleDisplayDeviceRemoved(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700616 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700617 if (!mDisplayDevices.remove(device)) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700618 Slog.w(TAG, "Attempted to remove non-existent display device: "
619 + device.getDisplayDeviceInfoLocked());
Jeff Brownbd6e1502012-08-28 03:27:37 -0700620 return;
Craig Mautner4f67ba62012-08-02 11:23:00 -0700621 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700622
Jeff Browne87bf032012-09-20 18:30:13 -0700623 Slog.i(TAG, "Display device removed: " + device.getDisplayDeviceInfoLocked());
624
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700625 mRemovedDisplayDevices.add(device);
626 updateLogicalDisplaysLocked();
Craig Mautner65d11b32012-10-01 13:59:52 -0700627 scheduleTraversalLocked(false);
Craig Mautner4f67ba62012-08-02 11:23:00 -0700628 }
629 }
630
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700631 // Adds a new logical display based on the given display device.
632 // Sends notifications if needed.
633 private void addLogicalDisplayLocked(DisplayDevice device) {
634 DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
635 boolean isDefault = (deviceInfo.flags
636 & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0;
637 if (isDefault && mLogicalDisplays.get(Display.DEFAULT_DISPLAY) != null) {
638 Slog.w(TAG, "Ignoring attempt to add a second default display: " + deviceInfo);
639 isDefault = false;
640 }
641
Jeff Brown27f1d672012-10-17 18:32:34 -0700642 if (!isDefault && mSingleDisplayDemoMode) {
643 Slog.i(TAG, "Not creating a logical display for a secondary display "
644 + " because single display demo mode is enabled: " + deviceInfo);
645 return;
646 }
647
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700648 final int displayId = assignDisplayIdLocked(isDefault);
649 final int layerStack = assignLayerStackLocked(displayId);
650
Jeff Brownd728bf52012-09-08 18:05:28 -0700651 LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700652 display.updateLocked(mDisplayDevices);
653 if (!display.isValidLocked()) {
654 // This should never happen currently.
655 Slog.w(TAG, "Ignoring display device because the logical display "
656 + "created from it was not considered valid: " + deviceInfo);
657 return;
658 }
659
660 mLogicalDisplays.put(displayId, display);
661
662 // Wake up waitForDefaultDisplay.
663 if (isDefault) {
664 mSyncRoot.notifyAll();
665 }
666
667 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED);
668 }
669
670 private int assignDisplayIdLocked(boolean isDefault) {
671 return isDefault ? Display.DEFAULT_DISPLAY : mNextNonDefaultDisplayId++;
672 }
673
674 private int assignLayerStackLocked(int displayId) {
675 // Currently layer stacks and display ids are the same.
676 // This need not be the case.
677 return displayId;
678 }
679
680 // Updates all existing logical displays given the current set of display devices.
681 // Removes invalid logical displays.
682 // Sends notifications if needed.
683 private boolean updateLogicalDisplaysLocked() {
684 boolean changed = false;
685 for (int i = mLogicalDisplays.size(); i-- > 0; ) {
686 final int displayId = mLogicalDisplays.keyAt(i);
687 LogicalDisplay display = mLogicalDisplays.valueAt(i);
688
689 mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
690 display.updateLocked(mDisplayDevices);
691 if (!display.isValidLocked()) {
692 mLogicalDisplays.removeAt(i);
693 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED);
694 changed = true;
695 } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
696 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
697 changed = true;
698 }
699 }
700 return changed;
701 }
702
703 private void performTraversalInTransactionLocked() {
704 // Perform one last traversal for each removed display device.
705 final int removedCount = mRemovedDisplayDevices.size();
706 for (int i = 0; i < removedCount; i++) {
707 DisplayDevice device = mRemovedDisplayDevices.get(i);
708 device.performTraversalInTransactionLocked();
709 }
710 mRemovedDisplayDevices.clear();
711
Jeff Brownd728bf52012-09-08 18:05:28 -0700712 // Clear all viewports before configuring displays so that we can keep
713 // track of which ones we have configured.
714 clearViewportsLocked();
715
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700716 // Configure each display device.
717 final int count = mDisplayDevices.size();
718 for (int i = 0; i < count; i++) {
719 DisplayDevice device = mDisplayDevices.get(i);
720 configureDisplayInTransactionLocked(device);
721 device.performTraversalInTransactionLocked();
722 }
Jeff Brownd728bf52012-09-08 18:05:28 -0700723
724 // Tell the input system about these new viewports.
725 if (mInputManagerFuncs != null) {
726 mHandler.sendEmptyMessage(MSG_UPDATE_VIEWPORT);
727 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700728 }
729
Craig Mautner722285e2012-09-07 13:55:58 -0700730 /**
731 * Tells the display manager whether there is interesting unique content on the
732 * specified logical display. This is used to control automatic mirroring.
733 * <p>
734 * If the display has unique content, then the display manager arranges for it
735 * to be presented on a physical display if appropriate. Otherwise, the display manager
736 * may choose to make the physical display mirror some other logical display.
737 * </p>
738 *
739 * @param displayId The logical display id to update.
740 * @param hasContent True if the logical display has content.
Craig Mautner65d11b32012-10-01 13:59:52 -0700741 * @param inTraversal True if called from WindowManagerService during a window traversal prior
742 * to call to performTraversalInTransactionFromWindowManager.
Craig Mautner722285e2012-09-07 13:55:58 -0700743 */
Craig Mautner65d11b32012-10-01 13:59:52 -0700744 public void setDisplayHasContent(int displayId, boolean hasContent, boolean inTraversal) {
Craig Mautner722285e2012-09-07 13:55:58 -0700745 synchronized (mSyncRoot) {
746 LogicalDisplay display = mLogicalDisplays.get(displayId);
747 if (display != null && display.hasContentLocked() != hasContent) {
748 display.setHasContentLocked(hasContent);
Craig Mautner65d11b32012-10-01 13:59:52 -0700749 scheduleTraversalLocked(inTraversal);
Craig Mautner722285e2012-09-07 13:55:58 -0700750 }
751 }
Jeff Brownd728bf52012-09-08 18:05:28 -0700752 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700753
Jeff Brownd728bf52012-09-08 18:05:28 -0700754 private void clearViewportsLocked() {
755 mDefaultViewport.valid = false;
756 mExternalTouchViewport.valid = false;
Craig Mautner722285e2012-09-07 13:55:58 -0700757 }
758
759 private void configureDisplayInTransactionLocked(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700760 // Find the logical display that the display device is showing.
Craig Mautner722285e2012-09-07 13:55:58 -0700761 LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
762 if (display != null && !display.hasContentLocked()) {
763 display = null;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700764 }
765 if (display == null) {
766 display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY);
767 }
768
769 // Apply the logical display configuration to the display device.
770 if (display == null) {
771 // TODO: no logical display for the device, blank it
Jeff Brownd728bf52012-09-08 18:05:28 -0700772 Slog.w(TAG, "Missing logical display to use for physical display device: "
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700773 + device.getDisplayDeviceInfoLocked());
Jeff Brownd728bf52012-09-08 18:05:28 -0700774 return;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700775 } else {
Jeff Brown8ec09432012-10-16 16:19:23 -0700776 boolean isBlanked = (mAllDisplayBlankStateFromPowerManager
777 == DISPLAY_BLANK_STATE_BLANKED);
778 display.configureDisplayInTransactionLocked(device, isBlanked);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700779 }
Jeff Brownd728bf52012-09-08 18:05:28 -0700780
781 // Update the viewports if needed.
782 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
783 if (!mDefaultViewport.valid
784 && (info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
785 setViewportLocked(mDefaultViewport, display, device);
786 }
787 if (!mExternalTouchViewport.valid
788 && info.touch == DisplayDeviceInfo.TOUCH_EXTERNAL) {
789 setViewportLocked(mExternalTouchViewport, display, device);
790 }
791 }
792
793 private static void setViewportLocked(DisplayViewport viewport,
794 LogicalDisplay display, DisplayDevice device) {
795 viewport.valid = true;
796 viewport.displayId = display.getDisplayIdLocked();
797 device.populateViewportLocked(viewport);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700798 }
799
800 private LogicalDisplay findLogicalDisplayForDeviceLocked(DisplayDevice device) {
801 final int count = mLogicalDisplays.size();
802 for (int i = 0; i < count; i++) {
803 LogicalDisplay display = mLogicalDisplays.valueAt(i);
804 if (display.getPrimaryDisplayDeviceLocked() == device) {
805 return display;
806 }
807 }
808 return null;
809 }
810
Jeff Brownbd6e1502012-08-28 03:27:37 -0700811 private void sendDisplayEventLocked(int displayId, int event) {
812 Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT, displayId, event);
813 mHandler.sendMessage(msg);
814 }
815
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700816 // Requests that performTraversalsInTransactionFromWindowManager be called at a
817 // later time to apply changes to surfaces and displays.
Craig Mautner65d11b32012-10-01 13:59:52 -0700818 private void scheduleTraversalLocked(boolean inTraversal) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700819 if (!mPendingTraversal && mWindowManagerFuncs != null) {
820 mPendingTraversal = true;
Craig Mautner65d11b32012-10-01 13:59:52 -0700821 if (!inTraversal) {
822 mHandler.sendEmptyMessage(MSG_REQUEST_TRAVERSAL);
823 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700824 }
825 }
826
827 // Runs on Handler thread.
828 // Delivers display event notifications to callbacks.
Jeff Brownbd6e1502012-08-28 03:27:37 -0700829 private void deliverDisplayEvent(int displayId, int event) {
830 if (DEBUG) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700831 Slog.d(TAG, "Delivering display event: displayId="
832 + displayId + ", event=" + event);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700833 }
Jeff Brownfa25bf52012-07-23 19:26:30 -0700834
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700835 // Grab the lock and copy the callbacks.
Jeff Brownbd6e1502012-08-28 03:27:37 -0700836 final int count;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700837 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700838 count = mCallbacks.size();
839 mTempCallbacks.clear();
840 for (int i = 0; i < count; i++) {
841 mTempCallbacks.add(mCallbacks.valueAt(i));
Craig Mautner4f67ba62012-08-02 11:23:00 -0700842 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700843 }
Craig Mautner4f67ba62012-08-02 11:23:00 -0700844
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700845 // After releasing the lock, send the notifications out.
Jeff Brownbd6e1502012-08-28 03:27:37 -0700846 for (int i = 0; i < count; i++) {
847 mTempCallbacks.get(i).notifyDisplayEventAsync(displayId, event);
848 }
849 mTempCallbacks.clear();
Craig Mautner4f67ba62012-08-02 11:23:00 -0700850 }
851
Jeff Brownfa25bf52012-07-23 19:26:30 -0700852 @Override // Binder call
Jeff Brownbd6e1502012-08-28 03:27:37 -0700853 public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
Jeff Brownfa25bf52012-07-23 19:26:30 -0700854 if (mContext == null
855 || mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
856 != PackageManager.PERMISSION_GRANTED) {
857 pw.println("Permission Denial: can't dump DisplayManager from from pid="
858 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
859 return;
860 }
861
Jeff Brownbd6e1502012-08-28 03:27:37 -0700862 pw.println("DISPLAY MANAGER (dumpsys display)");
Jeff Brownfa25bf52012-07-23 19:26:30 -0700863
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700864 synchronized (mSyncRoot) {
Jeff Brown9e316a12012-10-08 19:17:06 -0700865 pw.println(" mHeadless=" + mHeadless);
866 pw.println(" mOnlyCode=" + mOnlyCore);
867 pw.println(" mSafeMode=" + mSafeMode);
868 pw.println(" mPendingTraversal=" + mPendingTraversal);
869 pw.println(" mAllDisplayBlankStateFromPowerManager="
870 + mAllDisplayBlankStateFromPowerManager);
871 pw.println(" mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId);
872 pw.println(" mDefaultViewport=" + mDefaultViewport);
873 pw.println(" mExternalTouchViewport=" + mExternalTouchViewport);
Jeff Brown27f1d672012-10-17 18:32:34 -0700874 pw.println(" mSingleDisplayDemoMode=" + mSingleDisplayDemoMode);
Jeff Brown9e316a12012-10-08 19:17:06 -0700875
Jeff Brownbd6e1502012-08-28 03:27:37 -0700876 IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700877 ipw.increaseIndent();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700878
879 pw.println();
880 pw.println("Display Adapters: size=" + mDisplayAdapters.size());
Jeff Brown848c2dc2012-08-19 20:18:08 -0700881 for (DisplayAdapter adapter : mDisplayAdapters) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700882 pw.println(" " + adapter.getName());
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700883 adapter.dumpLocked(ipw);
Jeff Brown848c2dc2012-08-19 20:18:08 -0700884 }
Craig Mautner9de49362012-08-02 14:30:30 -0700885
Jeff Brownbd6e1502012-08-28 03:27:37 -0700886 pw.println();
887 pw.println("Display Devices: size=" + mDisplayDevices.size());
888 for (DisplayDevice device : mDisplayDevices) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700889 pw.println(" " + device.getDisplayDeviceInfoLocked());
890 device.dumpLocked(ipw);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700891 }
892
893 final int logicalDisplayCount = mLogicalDisplays.size();
894 pw.println();
895 pw.println("Logical Displays: size=" + logicalDisplayCount);
896 for (int i = 0; i < logicalDisplayCount; i++) {
897 int displayId = mLogicalDisplays.keyAt(i);
898 LogicalDisplay display = mLogicalDisplays.valueAt(i);
899 pw.println(" Display " + displayId + ":");
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700900 display.dumpLocked(ipw);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700901 }
902 }
903 }
904
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700905 /**
906 * This is the object that everything in the display manager locks on.
907 * We make it an inner class within the {@link DisplayManagerService} to so that it is
908 * clear that the object belongs to the display manager service and that it is
909 * a unique object with a special purpose.
910 */
911 public static final class SyncRoot {
912 }
913
914 /**
915 * Private interface to the window manager.
916 */
917 public interface WindowManagerFuncs {
918 /**
Craig Mautner722285e2012-09-07 13:55:58 -0700919 * Request that the window manager call
920 * {@link #performTraversalInTransactionFromWindowManager} within a surface
921 * transaction at a later time.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700922 */
923 void requestTraversal();
924 }
925
Jeff Brownd728bf52012-09-08 18:05:28 -0700926 /**
927 * Private interface to the input manager.
928 */
929 public interface InputManagerFuncs {
930 /**
931 * Sets information about the displays as needed by the input system.
932 * The input system should copy this information if required.
933 */
934 void setDisplayViewports(DisplayViewport defaultViewport,
935 DisplayViewport externalTouchViewport);
936 }
937
Jeff Brownbd6e1502012-08-28 03:27:37 -0700938 private final class DisplayManagerHandler extends Handler {
939 public DisplayManagerHandler(Looper looper) {
940 super(looper, null, true /*async*/);
Jeff Brown848c2dc2012-08-19 20:18:08 -0700941 }
Jeff Brownbf5740e2012-08-19 23:20:02 -0700942
Jeff Brownbd6e1502012-08-28 03:27:37 -0700943 @Override
944 public void handleMessage(Message msg) {
945 switch (msg.what) {
946 case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER:
947 registerDefaultDisplayAdapter();
948 break;
949
950 case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS:
951 registerAdditionalDisplayAdapters();
952 break;
953
954 case MSG_DELIVER_DISPLAY_EVENT:
955 deliverDisplayEvent(msg.arg1, msg.arg2);
956 break;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700957
958 case MSG_REQUEST_TRAVERSAL:
959 mWindowManagerFuncs.requestTraversal();
960 break;
Jeff Brownd728bf52012-09-08 18:05:28 -0700961
962 case MSG_UPDATE_VIEWPORT: {
963 synchronized (mSyncRoot) {
964 mTempDefaultViewport.copyFrom(mDefaultViewport);
965 mTempExternalTouchViewport.copyFrom(mExternalTouchViewport);
966 }
967 mInputManagerFuncs.setDisplayViewports(
968 mTempDefaultViewport, mTempExternalTouchViewport);
969 break;
970 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700971 }
972 }
973 }
974
975 private final class DisplayAdapterListener implements DisplayAdapter.Listener {
976 @Override
977 public void onDisplayDeviceEvent(DisplayDevice device, int event) {
978 switch (event) {
979 case DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED:
980 handleDisplayDeviceAdded(device);
981 break;
982
983 case DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED:
984 handleDisplayDeviceChanged(device);
985 break;
986
987 case DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED:
988 handleDisplayDeviceRemoved(device);
989 break;
990 }
991 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700992
993 @Override
994 public void onTraversalRequested() {
995 synchronized (mSyncRoot) {
Craig Mautner65d11b32012-10-01 13:59:52 -0700996 scheduleTraversalLocked(false);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700997 }
998 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700999 }
1000
1001 private final class CallbackRecord implements DeathRecipient {
1002 private final int mPid;
1003 private final IDisplayManagerCallback mCallback;
1004
1005 public CallbackRecord(int pid, IDisplayManagerCallback callback) {
1006 mPid = pid;
1007 mCallback = callback;
1008 }
1009
1010 @Override
1011 public void binderDied() {
1012 if (DEBUG) {
1013 Slog.d(TAG, "Display listener for pid " + mPid + " died.");
1014 }
1015 onCallbackDied(mPid);
1016 }
1017
1018 public void notifyDisplayEventAsync(int displayId, int event) {
1019 try {
1020 mCallback.onDisplayEvent(displayId, event);
1021 } catch (RemoteException ex) {
1022 Slog.w(TAG, "Failed to notify process "
1023 + mPid + " that displays changed, assuming it died.", ex);
1024 binderDied();
1025 }
1026 }
1027 }
Jeff Brownfa25bf52012-07-23 19:26:30 -07001028}