blob: e09970e93ae895510133b77941469ad592e45656 [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;
Jeff Brown7f3994e2012-12-04 14:04:28 -080044import java.util.concurrent.CopyOnWriteArrayList;
Jeff Brownfa25bf52012-07-23 19:26:30 -070045
46/**
Jeff Brownbd6e1502012-08-28 03:27:37 -070047 * Manages attached displays.
Jeff Brownfa25bf52012-07-23 19:26:30 -070048 * <p>
Jeff Brownbd6e1502012-08-28 03:27:37 -070049 * The {@link DisplayManagerService} manages the global lifecycle of displays,
50 * decides how to configure logical displays based on the physical display devices currently
51 * attached, sends notifications to the system and to applications when the state
52 * changes, and so on.
53 * </p><p>
54 * The display manager service relies on a collection of {@link DisplayAdapter} components,
55 * for discovering and configuring physical display devices attached to the system.
56 * There are separate display adapters for each manner that devices are attached:
57 * one display adapter for built-in local displays, one for simulated non-functional
58 * displays when the system is headless, one for simulated overlay displays used for
59 * development, one for wifi displays, etc.
60 * </p><p>
61 * Display adapters are only weakly coupled to the display manager service.
62 * Display adapters communicate changes in display device state to the display manager
Craig Mautner722285e2012-09-07 13:55:58 -070063 * service asynchronously via a {@link DisplayAdapter.Listener} registered
Jeff Brownbd6e1502012-08-28 03:27:37 -070064 * by the display manager service. This separation of concerns is important for
65 * two main reasons. First, it neatly encapsulates the responsibilities of these
66 * two classes: display adapters handle individual display devices whereas
67 * the display manager service handles the global state. Second, it eliminates
68 * the potential for deadlocks resulting from asynchronous display device discovery.
Jeff Brown4ed8fe72012-08-30 18:18:29 -070069 * </p>
70 *
71 * <h3>Synchronization</h3>
72 * <p>
73 * Because the display manager may be accessed by multiple threads, the synchronization
74 * story gets a little complicated. In particular, the window manager may call into
75 * the display manager while holding a surface transaction with the expectation that
76 * it can apply changes immediately. Unfortunately, that means we can't just do
77 * everything asynchronously (*grump*).
Jeff Brownbd6e1502012-08-28 03:27:37 -070078 * </p><p>
Jeff Brown4ed8fe72012-08-30 18:18:29 -070079 * To make this work, all of the objects that belong to the display manager must
80 * use the same lock. We call this lock the synchronization root and it has a unique
81 * type {@link DisplayManagerService.SyncRoot}. Methods that require this lock are
82 * named with the "Locked" suffix.
83 * </p><p>
84 * Where things get tricky is that the display manager is not allowed to make
85 * any potentially reentrant calls, especially into the window manager. We generally
86 * avoid this by making all potentially reentrant out-calls asynchronous.
Jeff Brownfa25bf52012-07-23 19:26:30 -070087 * </p>
88 */
89public final class DisplayManagerService extends IDisplayManager.Stub {
90 private static final String TAG = "DisplayManagerService";
Jeff Brownbd6e1502012-08-28 03:27:37 -070091 private static final boolean DEBUG = false;
Jeff Brownfa25bf52012-07-23 19:26:30 -070092
Jeff Brownbbd28a22012-09-20 16:47:15 -070093 // When this system property is set to 0, WFD is forcibly disabled on boot.
94 // When this system property is set to 1, WFD is forcibly enabled on boot.
95 // Otherwise WFD is enabled according to the value of config_enableWifiDisplay.
96 private static final String FORCE_WIFI_DISPLAY_ENABLE = "persist.debug.wfd.enable";
97
Jeff Brownfa25bf52012-07-23 19:26:30 -070098 private static final String SYSTEM_HEADLESS = "ro.config.headless";
Jeff Brownbd6e1502012-08-28 03:27:37 -070099 private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000;
100
101 private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER = 1;
102 private static final int MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS = 2;
103 private static final int MSG_DELIVER_DISPLAY_EVENT = 3;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700104 private static final int MSG_REQUEST_TRAVERSAL = 4;
Jeff Brownd728bf52012-09-08 18:05:28 -0700105 private static final int MSG_UPDATE_VIEWPORT = 5;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700106
Jeff Brown9e316a12012-10-08 19:17:06 -0700107 private static final int DISPLAY_BLANK_STATE_UNKNOWN = 0;
108 private static final int DISPLAY_BLANK_STATE_BLANKED = 1;
109 private static final int DISPLAY_BLANK_STATE_UNBLANKED = 2;
110
Jeff Brown848c2dc2012-08-19 20:18:08 -0700111 private final Context mContext;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700112 private final boolean mHeadless;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700113 private final DisplayManagerHandler mHandler;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700114 private final Handler mUiHandler;
115 private final DisplayAdapterListener mDisplayAdapterListener;
116 private WindowManagerFuncs mWindowManagerFuncs;
Jeff Brownd728bf52012-09-08 18:05:28 -0700117 private InputManagerFuncs mInputManagerFuncs;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700118
119 // The synchronization root for the display manager.
120 // This lock guards most of the display manager's state.
121 private final SyncRoot mSyncRoot = new SyncRoot();
122
123 // True if in safe mode.
124 // This option may disable certain display adapters.
125 public boolean mSafeMode;
126
127 // True if we are in a special boot mode where only core applications and
128 // services should be started. This option may disable certain display adapters.
129 public boolean mOnlyCore;
130
Jeff Brown27f1d672012-10-17 18:32:34 -0700131 // True if the display manager service should pretend there is only one display
132 // and only tell applications about the existence of the default logical display.
133 // The display manager can still mirror content to secondary displays but applications
134 // cannot present unique content on those displays.
135 // Used for demonstration purposes only.
136 private final boolean mSingleDisplayDemoMode;
137
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700138 // All callback records indexed by calling process id.
139 public final SparseArray<CallbackRecord> mCallbacks =
Jeff Brownbd6e1502012-08-28 03:27:37 -0700140 new SparseArray<CallbackRecord>();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700141
Jeff Brownbd6e1502012-08-28 03:27:37 -0700142 // List of all currently registered display adapters.
143 private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
144
145 // List of all currently connected display devices.
146 private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>();
147
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700148 // List of all removed display devices.
149 private final ArrayList<DisplayDevice> mRemovedDisplayDevices = new ArrayList<DisplayDevice>();
150
151 // List of all logical displays indexed by logical display id.
152 private final SparseArray<LogicalDisplay> mLogicalDisplays =
153 new SparseArray<LogicalDisplay>();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700154 private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1;
155
Jeff Brown7f3994e2012-12-04 14:04:28 -0800156 // List of all display transaction listeners.
157 private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners =
158 new CopyOnWriteArrayList<DisplayTransactionListener>();
159
Jeff Brown9e316a12012-10-08 19:17:06 -0700160 // Set to true if all displays have been blanked by the power manager.
161 private int mAllDisplayBlankStateFromPowerManager;
162
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700163 // Set to true when there are pending display changes that have yet to be applied
164 // to the surface flinger state.
165 private boolean mPendingTraversal;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700166
Jeff Browne08ae382012-09-07 20:36:36 -0700167 // The Wifi display adapter, or null if not registered.
168 private WifiDisplayAdapter mWifiDisplayAdapter;
169
Jeff Brownd728bf52012-09-08 18:05:28 -0700170 // Viewports of the default display and the display that should receive touch
171 // input from an external source. Used by the input system.
172 private final DisplayViewport mDefaultViewport = new DisplayViewport();
173 private final DisplayViewport mExternalTouchViewport = new DisplayViewport();
174
Jeff Brown89d55462012-09-19 11:33:42 -0700175 // Persistent data store for all internal settings maintained by the display manager service.
176 private final PersistentDataStore mPersistentDataStore = new PersistentDataStore();
177
Jeff Brownbd6e1502012-08-28 03:27:37 -0700178 // Temporary callback list, used when sending display events to applications.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700179 // May be used outside of the lock but only on the handler thread.
180 private final ArrayList<CallbackRecord> mTempCallbacks = new ArrayList<CallbackRecord>();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700181
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700182 // Temporary display info, used for comparing display configurations.
183 private final DisplayInfo mTempDisplayInfo = new DisplayInfo();
184
Jeff Brownd728bf52012-09-08 18:05:28 -0700185 // Temporary viewports, used when sending new viewport information to the
186 // input system. May be used outside of the lock but only on the handler thread.
187 private final DisplayViewport mTempDefaultViewport = new DisplayViewport();
188 private final DisplayViewport mTempExternalTouchViewport = new DisplayViewport();
189
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700190 public DisplayManagerService(Context context, Handler mainHandler, Handler uiHandler) {
Jeff Brown848c2dc2012-08-19 20:18:08 -0700191 mContext = context;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700192 mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1");
Jeff Brown848c2dc2012-08-19 20:18:08 -0700193
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700194 mHandler = new DisplayManagerHandler(mainHandler.getLooper());
195 mUiHandler = uiHandler;
196 mDisplayAdapterListener = new DisplayAdapterListener();
Jeff Brown27f1d672012-10-17 18:32:34 -0700197 mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700198
Jeff Brownbd6e1502012-08-28 03:27:37 -0700199 mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER);
Craig Mautner4f67ba62012-08-02 11:23:00 -0700200 }
201
Jeff Brownbd6e1502012-08-28 03:27:37 -0700202 /**
203 * Pauses the boot process to wait for the first display to be initialized.
204 */
205 public boolean waitForDefaultDisplay() {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700206 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700207 long timeout = SystemClock.uptimeMillis() + WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
208 while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null) {
209 long delay = timeout - SystemClock.uptimeMillis();
210 if (delay <= 0) {
211 return false;
212 }
213 if (DEBUG) {
214 Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay);
215 }
216 try {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700217 mSyncRoot.wait(delay);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700218 } catch (InterruptedException ex) {
219 }
220 }
221 }
222 return true;
223 }
224
225 /**
Jeff Brownd728bf52012-09-08 18:05:28 -0700226 * Called during initialization to associate the display manager with the
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700227 * window manager.
228 */
229 public void setWindowManager(WindowManagerFuncs windowManagerFuncs) {
230 synchronized (mSyncRoot) {
231 mWindowManagerFuncs = windowManagerFuncs;
Craig Mautner65d11b32012-10-01 13:59:52 -0700232 scheduleTraversalLocked(false);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700233 }
234 }
235
236 /**
Jeff Brownd728bf52012-09-08 18:05:28 -0700237 * Called during initialization to associate the display manager with the
238 * input manager.
239 */
240 public void setInputManager(InputManagerFuncs inputManagerFuncs) {
241 synchronized (mSyncRoot) {
242 mInputManagerFuncs = inputManagerFuncs;
Craig Mautner65d11b32012-10-01 13:59:52 -0700243 scheduleTraversalLocked(false);
Jeff Brownd728bf52012-09-08 18:05:28 -0700244 }
245 }
246
247 /**
Jeff Brownbd6e1502012-08-28 03:27:37 -0700248 * Called when the system is ready to go.
249 */
250 public void systemReady(boolean safeMode, boolean onlyCore) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700251 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700252 mSafeMode = safeMode;
253 mOnlyCore = onlyCore;
254 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700255
Jeff Brownbd6e1502012-08-28 03:27:37 -0700256 mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
257 }
258
Jeff Brown848c2dc2012-08-19 20:18:08 -0700259 /**
260 * Returns true if the device is headless.
261 *
262 * @return True if the device is headless.
263 */
Jeff Brownfa25bf52012-07-23 19:26:30 -0700264 public boolean isHeadless() {
265 return mHeadless;
266 }
267
Craig Mautner4f67ba62012-08-02 11:23:00 -0700268 /**
Jeff Brown7f3994e2012-12-04 14:04:28 -0800269 * Registers a display transaction listener to provide the client a chance to
270 * update its surfaces within the same transaction as any display layout updates.
271 *
272 * @param listener The listener to register.
273 */
274 public void registerDisplayTransactionListener(DisplayTransactionListener listener) {
275 if (listener == null) {
276 throw new IllegalArgumentException("listener must not be null");
277 }
278
279 // List is self-synchronized copy-on-write.
280 mDisplayTransactionListeners.add(listener);
281 }
282
283 /**
284 * Unregisters a display transaction listener to provide the client a chance to
285 * update its surfaces within the same transaction as any display layout updates.
286 *
287 * @param listener The listener to unregister.
288 */
289 public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) {
290 if (listener == null) {
291 throw new IllegalArgumentException("listener must not be null");
292 }
293
294 // List is self-synchronized copy-on-write.
295 mDisplayTransactionListeners.remove(listener);
296 }
297
298 /**
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700299 * Overrides the display information of a particular logical display.
300 * This is used by the window manager to control the size and characteristics
301 * of the default display. It is expected to apply the requested change
302 * to the display information synchronously so that applications will immediately
303 * observe the new state.
Jeff Brownbd6e1502012-08-28 03:27:37 -0700304 *
Jeff Brown64a55af2012-08-26 02:47:39 -0700305 * @param displayId The logical display id.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700306 * @param info The new data to be stored.
Jeff Brown64a55af2012-08-26 02:47:39 -0700307 */
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700308 public void setDisplayInfoOverrideFromWindowManager(
309 int displayId, DisplayInfo info) {
310 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700311 LogicalDisplay display = mLogicalDisplays.get(displayId);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700312 if (display != null) {
313 mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
314 display.setDisplayInfoOverrideFromWindowManagerLocked(info);
315 if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
316 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
Craig Mautner65d11b32012-10-01 13:59:52 -0700317 scheduleTraversalLocked(false);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700318 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700319 }
320 }
321 }
322
323 /**
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700324 * Called by the window manager to perform traversals while holding a
325 * surface flinger transaction.
Jeff Brownbd6e1502012-08-28 03:27:37 -0700326 */
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700327 public void performTraversalInTransactionFromWindowManager() {
328 synchronized (mSyncRoot) {
329 if (!mPendingTraversal) {
330 return;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700331 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700332 mPendingTraversal = false;
333
334 performTraversalInTransactionLocked();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700335 }
Jeff Brown7f3994e2012-12-04 14:04:28 -0800336
337 // List is self-synchronized copy-on-write.
338 for (DisplayTransactionListener listener : mDisplayTransactionListeners) {
339 listener.onDisplayTransaction();
340 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700341 }
342
343 /**
Jeff Brown9e316a12012-10-08 19:17:06 -0700344 * Called by the power manager to blank all displays.
345 */
346 public void blankAllDisplaysFromPowerManager() {
347 synchronized (mSyncRoot) {
348 if (mAllDisplayBlankStateFromPowerManager != DISPLAY_BLANK_STATE_BLANKED) {
349 mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_BLANKED;
350
351 final int count = mDisplayDevices.size();
352 for (int i = 0; i < count; i++) {
353 DisplayDevice device = mDisplayDevices.get(i);
354 device.blankLocked();
355 }
Jeff Brown8ec09432012-10-16 16:19:23 -0700356
357 scheduleTraversalLocked(false);
Jeff Brown9e316a12012-10-08 19:17:06 -0700358 }
359 }
360 }
361
362 /**
363 * Called by the power manager to unblank all displays.
364 */
365 public void unblankAllDisplaysFromPowerManager() {
366 synchronized (mSyncRoot) {
367 if (mAllDisplayBlankStateFromPowerManager != DISPLAY_BLANK_STATE_UNBLANKED) {
368 mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_UNBLANKED;
369
370 final int count = mDisplayDevices.size();
371 for (int i = 0; i < count; i++) {
372 DisplayDevice device = mDisplayDevices.get(i);
373 device.unblankLocked();
374 }
Jeff Brown8ec09432012-10-16 16:19:23 -0700375
376 scheduleTraversalLocked(false);
Jeff Brown9e316a12012-10-08 19:17:06 -0700377 }
378 }
379 }
380
381 /**
Jeff Brownbd6e1502012-08-28 03:27:37 -0700382 * Returns information about the specified logical display.
383 *
384 * @param displayId The logical display id.
Craig Mautner722285e2012-09-07 13:55:58 -0700385 * @return The logical display info, or null if the display does not exist. The
386 * returned object must be treated as immutable.
Jeff Brownbd6e1502012-08-28 03:27:37 -0700387 */
388 @Override // Binder call
389 public DisplayInfo getDisplayInfo(int displayId) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700390 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700391 LogicalDisplay display = mLogicalDisplays.get(displayId);
392 if (display != null) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700393 return display.getDisplayInfoLocked();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700394 }
395 return null;
396 }
397 }
398
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700399 /**
400 * Returns the list of all display ids.
401 */
Jeff Brownbd6e1502012-08-28 03:27:37 -0700402 @Override // Binder call
403 public int[] getDisplayIds() {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700404 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700405 final int count = mLogicalDisplays.size();
406 int[] displayIds = new int[count];
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700407 for (int i = 0; i < count; i++) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700408 displayIds[i] = mLogicalDisplays.keyAt(i);
409 }
410 return displayIds;
411 }
412 }
413
414 @Override // Binder call
415 public void registerCallback(IDisplayManagerCallback callback) {
416 if (callback == null) {
417 throw new IllegalArgumentException("listener must not be null");
418 }
419
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700420 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700421 int callingPid = Binder.getCallingPid();
422 if (mCallbacks.get(callingPid) != null) {
423 throw new SecurityException("The calling process has already "
424 + "registered an IDisplayManagerCallback.");
Jeff Brown64a55af2012-08-26 02:47:39 -0700425 }
426
Jeff Brownbd6e1502012-08-28 03:27:37 -0700427 CallbackRecord record = new CallbackRecord(callingPid, callback);
428 try {
429 IBinder binder = callback.asBinder();
430 binder.linkToDeath(record, 0);
431 } catch (RemoteException ex) {
432 // give up
433 throw new RuntimeException(ex);
434 }
435
436 mCallbacks.put(callingPid, record);
437 }
438 }
439
440 private void onCallbackDied(int pid) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700441 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700442 mCallbacks.remove(pid);
443 }
444 }
445
Jeff Browne08ae382012-09-07 20:36:36 -0700446 @Override // Binder call
447 public void scanWifiDisplays() {
Jeff Browne08ae382012-09-07 20:36:36 -0700448 final long token = Binder.clearCallingIdentity();
449 try {
450 synchronized (mSyncRoot) {
Jeff Brown21c71532012-09-09 13:26:55 -0700451 if (mWifiDisplayAdapter != null) {
452 mWifiDisplayAdapter.requestScanLocked();
453 }
Jeff Browne08ae382012-09-07 20:36:36 -0700454 }
455 } finally {
456 Binder.restoreCallingIdentity(token);
457 }
458 }
459
460 @Override // Binder call
461 public void connectWifiDisplay(String address) {
Jeff Browne08ae382012-09-07 20:36:36 -0700462 if (address == null) {
463 throw new IllegalArgumentException("address must not be null");
464 }
465
Jeff Brownbc335452012-09-26 18:34:47 -0700466 final boolean trusted = canCallerConfigureWifiDisplay();
Jeff Browne08ae382012-09-07 20:36:36 -0700467 final long token = Binder.clearCallingIdentity();
468 try {
469 synchronized (mSyncRoot) {
Jeff Brown21c71532012-09-09 13:26:55 -0700470 if (mWifiDisplayAdapter != null) {
Jeff Brownbc335452012-09-26 18:34:47 -0700471 mWifiDisplayAdapter.requestConnectLocked(address, trusted);
Jeff Brown21c71532012-09-09 13:26:55 -0700472 }
Jeff Browne08ae382012-09-07 20:36:36 -0700473 }
474 } finally {
475 Binder.restoreCallingIdentity(token);
476 }
477 }
478
479 @Override // Binder call
480 public void disconnectWifiDisplay() {
Jeff Browne08ae382012-09-07 20:36:36 -0700481 final long token = Binder.clearCallingIdentity();
482 try {
483 synchronized (mSyncRoot) {
Jeff Brown21c71532012-09-09 13:26:55 -0700484 if (mWifiDisplayAdapter != null) {
485 mWifiDisplayAdapter.requestDisconnectLocked();
486 }
Jeff Browne08ae382012-09-07 20:36:36 -0700487 }
488 } finally {
489 Binder.restoreCallingIdentity(token);
490 }
491 }
492
493 @Override // Binder call
Jeff Brown89d55462012-09-19 11:33:42 -0700494 public void renameWifiDisplay(String address, String alias) {
Jeff Brown89d55462012-09-19 11:33:42 -0700495 if (address == null) {
496 throw new IllegalArgumentException("address must not be null");
497 }
Jeff Brownbc335452012-09-26 18:34:47 -0700498 if (!canCallerConfigureWifiDisplay()) {
499 throw new SecurityException("Requires CONFIGURE_WIFI_DISPLAY permission to "
500 + "rename a wifi display.");
501 }
Jeff Brown89d55462012-09-19 11:33:42 -0700502
503 final long token = Binder.clearCallingIdentity();
504 try {
505 synchronized (mSyncRoot) {
506 if (mWifiDisplayAdapter != null) {
507 mWifiDisplayAdapter.requestRenameLocked(address, alias);
508 }
509 }
510 } finally {
511 Binder.restoreCallingIdentity(token);
512 }
513 }
514
515 @Override // Binder call
516 public void forgetWifiDisplay(String address) {
Jeff Brown89d55462012-09-19 11:33:42 -0700517 if (address == null) {
518 throw new IllegalArgumentException("address must not be null");
519 }
Jeff Brownbc335452012-09-26 18:34:47 -0700520 if (!canCallerConfigureWifiDisplay()) {
521 throw new SecurityException("Requires CONFIGURE_WIFI_DISPLAY permission to "
522 + "forget a wifi display.");
523 }
Jeff Brown89d55462012-09-19 11:33:42 -0700524
525 final long token = Binder.clearCallingIdentity();
526 try {
527 synchronized (mSyncRoot) {
528 if (mWifiDisplayAdapter != null) {
529 mWifiDisplayAdapter.requestForgetLocked(address);
530 }
531 }
532 } finally {
533 Binder.restoreCallingIdentity(token);
534 }
535 }
536
537 @Override // Binder call
Jeff Browne08ae382012-09-07 20:36:36 -0700538 public WifiDisplayStatus getWifiDisplayStatus() {
Jeff Browne08ae382012-09-07 20:36:36 -0700539 final long token = Binder.clearCallingIdentity();
540 try {
541 synchronized (mSyncRoot) {
Jeff Brown21c71532012-09-09 13:26:55 -0700542 if (mWifiDisplayAdapter != null) {
543 return mWifiDisplayAdapter.getWifiDisplayStatusLocked();
544 } else {
545 return new WifiDisplayStatus();
546 }
Jeff Browne08ae382012-09-07 20:36:36 -0700547 }
548 } finally {
549 Binder.restoreCallingIdentity(token);
550 }
551 }
552
Jeff Brownbc335452012-09-26 18:34:47 -0700553 private boolean canCallerConfigureWifiDisplay() {
554 return mContext.checkCallingPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
555 == PackageManager.PERMISSION_GRANTED;
556 }
557
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700558 private void registerDefaultDisplayAdapter() {
559 // Register default display adapter.
560 synchronized (mSyncRoot) {
561 if (mHeadless) {
562 registerDisplayAdapterLocked(new HeadlessDisplayAdapter(
563 mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
564 } else {
565 registerDisplayAdapterLocked(new LocalDisplayAdapter(
566 mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
567 }
568 }
569 }
570
571 private void registerAdditionalDisplayAdapters() {
572 synchronized (mSyncRoot) {
573 if (shouldRegisterNonEssentialDisplayAdaptersLocked()) {
Jeff Brown89d55462012-09-19 11:33:42 -0700574 registerOverlayDisplayAdapterLocked();
575 registerWifiDisplayAdapterLocked();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700576 }
577 }
578 }
579
Jeff Brown89d55462012-09-19 11:33:42 -0700580 private void registerOverlayDisplayAdapterLocked() {
581 registerDisplayAdapterLocked(new OverlayDisplayAdapter(
582 mSyncRoot, mContext, mHandler, mDisplayAdapterListener, mUiHandler));
583 }
584
585 private void registerWifiDisplayAdapterLocked() {
586 if (mContext.getResources().getBoolean(
Jeff Brownbbd28a22012-09-20 16:47:15 -0700587 com.android.internal.R.bool.config_enableWifiDisplay)
588 || SystemProperties.getInt(FORCE_WIFI_DISPLAY_ENABLE, -1) == 1) {
Jeff Brown89d55462012-09-19 11:33:42 -0700589 mWifiDisplayAdapter = new WifiDisplayAdapter(
590 mSyncRoot, mContext, mHandler, mDisplayAdapterListener,
591 mPersistentDataStore);
592 registerDisplayAdapterLocked(mWifiDisplayAdapter);
593 }
594 }
595
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700596 private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() {
597 // In safe mode, we disable non-essential display adapters to give the user
598 // an opportunity to fix broken settings or other problems that might affect
599 // system stability.
600 // In only-core mode, we disable non-essential display adapters to minimize
601 // the number of dependencies that are started while in this mode and to
602 // prevent problems that might occur due to the device being encrypted.
603 return !mSafeMode && !mOnlyCore;
604 }
605
606 private void registerDisplayAdapterLocked(DisplayAdapter adapter) {
607 mDisplayAdapters.add(adapter);
608 adapter.registerLocked();
609 }
610
Jeff Brownbd6e1502012-08-28 03:27:37 -0700611 private void handleDisplayDeviceAdded(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700612 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700613 if (mDisplayDevices.contains(device)) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700614 Slog.w(TAG, "Attempted to add already added display device: "
615 + device.getDisplayDeviceInfoLocked());
Jeff Brownbd6e1502012-08-28 03:27:37 -0700616 return;
617 }
618
Jeff Browne87bf032012-09-20 18:30:13 -0700619 Slog.i(TAG, "Display device added: " + device.getDisplayDeviceInfoLocked());
620
Jeff Brownbd6e1502012-08-28 03:27:37 -0700621 mDisplayDevices.add(device);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700622 addLogicalDisplayLocked(device);
Craig Mautner65d11b32012-10-01 13:59:52 -0700623 scheduleTraversalLocked(false);
Jeff Brown9e316a12012-10-08 19:17:06 -0700624
625 // Blank or unblank the display immediately to match the state requested
626 // by the power manager (if known).
627 switch (mAllDisplayBlankStateFromPowerManager) {
628 case DISPLAY_BLANK_STATE_BLANKED:
629 device.blankLocked();
630 break;
631 case DISPLAY_BLANK_STATE_UNBLANKED:
632 device.unblankLocked();
633 break;
634 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700635 }
636 }
637
Jeff Brownbd6e1502012-08-28 03:27:37 -0700638 private void handleDisplayDeviceChanged(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700639 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700640 if (!mDisplayDevices.contains(device)) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700641 Slog.w(TAG, "Attempted to change non-existent display device: "
642 + device.getDisplayDeviceInfoLocked());
Jeff Brownbd6e1502012-08-28 03:27:37 -0700643 return;
644 }
645
Jeff Browne87bf032012-09-20 18:30:13 -0700646 Slog.i(TAG, "Display device changed: " + device.getDisplayDeviceInfoLocked());
647
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700648 device.applyPendingDisplayDeviceInfoChangesLocked();
649 if (updateLogicalDisplaysLocked()) {
Craig Mautner65d11b32012-10-01 13:59:52 -0700650 scheduleTraversalLocked(false);
Jeff Brown64a55af2012-08-26 02:47:39 -0700651 }
652 }
653 }
654
Jeff Brownbd6e1502012-08-28 03:27:37 -0700655 private void handleDisplayDeviceRemoved(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700656 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700657 if (!mDisplayDevices.remove(device)) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700658 Slog.w(TAG, "Attempted to remove non-existent display device: "
659 + device.getDisplayDeviceInfoLocked());
Jeff Brownbd6e1502012-08-28 03:27:37 -0700660 return;
Craig Mautner4f67ba62012-08-02 11:23:00 -0700661 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700662
Jeff Browne87bf032012-09-20 18:30:13 -0700663 Slog.i(TAG, "Display device removed: " + device.getDisplayDeviceInfoLocked());
664
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700665 mRemovedDisplayDevices.add(device);
666 updateLogicalDisplaysLocked();
Craig Mautner65d11b32012-10-01 13:59:52 -0700667 scheduleTraversalLocked(false);
Craig Mautner4f67ba62012-08-02 11:23:00 -0700668 }
669 }
670
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700671 // Adds a new logical display based on the given display device.
672 // Sends notifications if needed.
673 private void addLogicalDisplayLocked(DisplayDevice device) {
674 DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
675 boolean isDefault = (deviceInfo.flags
676 & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0;
677 if (isDefault && mLogicalDisplays.get(Display.DEFAULT_DISPLAY) != null) {
678 Slog.w(TAG, "Ignoring attempt to add a second default display: " + deviceInfo);
679 isDefault = false;
680 }
681
Jeff Brown27f1d672012-10-17 18:32:34 -0700682 if (!isDefault && mSingleDisplayDemoMode) {
683 Slog.i(TAG, "Not creating a logical display for a secondary display "
684 + " because single display demo mode is enabled: " + deviceInfo);
685 return;
686 }
687
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700688 final int displayId = assignDisplayIdLocked(isDefault);
689 final int layerStack = assignLayerStackLocked(displayId);
690
Jeff Brownd728bf52012-09-08 18:05:28 -0700691 LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700692 display.updateLocked(mDisplayDevices);
693 if (!display.isValidLocked()) {
694 // This should never happen currently.
695 Slog.w(TAG, "Ignoring display device because the logical display "
696 + "created from it was not considered valid: " + deviceInfo);
697 return;
698 }
699
700 mLogicalDisplays.put(displayId, display);
701
702 // Wake up waitForDefaultDisplay.
703 if (isDefault) {
704 mSyncRoot.notifyAll();
705 }
706
707 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED);
708 }
709
710 private int assignDisplayIdLocked(boolean isDefault) {
711 return isDefault ? Display.DEFAULT_DISPLAY : mNextNonDefaultDisplayId++;
712 }
713
714 private int assignLayerStackLocked(int displayId) {
715 // Currently layer stacks and display ids are the same.
716 // This need not be the case.
717 return displayId;
718 }
719
720 // Updates all existing logical displays given the current set of display devices.
721 // Removes invalid logical displays.
722 // Sends notifications if needed.
723 private boolean updateLogicalDisplaysLocked() {
724 boolean changed = false;
725 for (int i = mLogicalDisplays.size(); i-- > 0; ) {
726 final int displayId = mLogicalDisplays.keyAt(i);
727 LogicalDisplay display = mLogicalDisplays.valueAt(i);
728
729 mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
730 display.updateLocked(mDisplayDevices);
731 if (!display.isValidLocked()) {
732 mLogicalDisplays.removeAt(i);
733 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED);
734 changed = true;
735 } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
736 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
737 changed = true;
738 }
739 }
740 return changed;
741 }
742
743 private void performTraversalInTransactionLocked() {
744 // Perform one last traversal for each removed display device.
745 final int removedCount = mRemovedDisplayDevices.size();
746 for (int i = 0; i < removedCount; i++) {
747 DisplayDevice device = mRemovedDisplayDevices.get(i);
748 device.performTraversalInTransactionLocked();
749 }
750 mRemovedDisplayDevices.clear();
751
Jeff Brownd728bf52012-09-08 18:05:28 -0700752 // Clear all viewports before configuring displays so that we can keep
753 // track of which ones we have configured.
754 clearViewportsLocked();
755
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700756 // Configure each display device.
757 final int count = mDisplayDevices.size();
758 for (int i = 0; i < count; i++) {
759 DisplayDevice device = mDisplayDevices.get(i);
760 configureDisplayInTransactionLocked(device);
761 device.performTraversalInTransactionLocked();
762 }
Jeff Brownd728bf52012-09-08 18:05:28 -0700763
764 // Tell the input system about these new viewports.
765 if (mInputManagerFuncs != null) {
766 mHandler.sendEmptyMessage(MSG_UPDATE_VIEWPORT);
767 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700768 }
769
Craig Mautner722285e2012-09-07 13:55:58 -0700770 /**
771 * Tells the display manager whether there is interesting unique content on the
772 * specified logical display. This is used to control automatic mirroring.
773 * <p>
774 * If the display has unique content, then the display manager arranges for it
775 * to be presented on a physical display if appropriate. Otherwise, the display manager
776 * may choose to make the physical display mirror some other logical display.
777 * </p>
778 *
779 * @param displayId The logical display id to update.
780 * @param hasContent True if the logical display has content.
Craig Mautner65d11b32012-10-01 13:59:52 -0700781 * @param inTraversal True if called from WindowManagerService during a window traversal prior
782 * to call to performTraversalInTransactionFromWindowManager.
Craig Mautner722285e2012-09-07 13:55:58 -0700783 */
Craig Mautner65d11b32012-10-01 13:59:52 -0700784 public void setDisplayHasContent(int displayId, boolean hasContent, boolean inTraversal) {
Craig Mautner722285e2012-09-07 13:55:58 -0700785 synchronized (mSyncRoot) {
786 LogicalDisplay display = mLogicalDisplays.get(displayId);
787 if (display != null && display.hasContentLocked() != hasContent) {
788 display.setHasContentLocked(hasContent);
Craig Mautner65d11b32012-10-01 13:59:52 -0700789 scheduleTraversalLocked(inTraversal);
Craig Mautner722285e2012-09-07 13:55:58 -0700790 }
791 }
Jeff Brownd728bf52012-09-08 18:05:28 -0700792 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700793
Jeff Brownd728bf52012-09-08 18:05:28 -0700794 private void clearViewportsLocked() {
795 mDefaultViewport.valid = false;
796 mExternalTouchViewport.valid = false;
Craig Mautner722285e2012-09-07 13:55:58 -0700797 }
798
799 private void configureDisplayInTransactionLocked(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700800 // Find the logical display that the display device is showing.
Craig Mautner722285e2012-09-07 13:55:58 -0700801 LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
802 if (display != null && !display.hasContentLocked()) {
803 display = null;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700804 }
805 if (display == null) {
806 display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY);
807 }
808
809 // Apply the logical display configuration to the display device.
810 if (display == null) {
811 // TODO: no logical display for the device, blank it
Jeff Brownd728bf52012-09-08 18:05:28 -0700812 Slog.w(TAG, "Missing logical display to use for physical display device: "
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700813 + device.getDisplayDeviceInfoLocked());
Jeff Brownd728bf52012-09-08 18:05:28 -0700814 return;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700815 } else {
Jeff Brown8ec09432012-10-16 16:19:23 -0700816 boolean isBlanked = (mAllDisplayBlankStateFromPowerManager
817 == DISPLAY_BLANK_STATE_BLANKED);
818 display.configureDisplayInTransactionLocked(device, isBlanked);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700819 }
Jeff Brownd728bf52012-09-08 18:05:28 -0700820
821 // Update the viewports if needed.
822 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
823 if (!mDefaultViewport.valid
824 && (info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
825 setViewportLocked(mDefaultViewport, display, device);
826 }
827 if (!mExternalTouchViewport.valid
828 && info.touch == DisplayDeviceInfo.TOUCH_EXTERNAL) {
829 setViewportLocked(mExternalTouchViewport, display, device);
830 }
831 }
832
833 private static void setViewportLocked(DisplayViewport viewport,
834 LogicalDisplay display, DisplayDevice device) {
835 viewport.valid = true;
836 viewport.displayId = display.getDisplayIdLocked();
837 device.populateViewportLocked(viewport);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700838 }
839
840 private LogicalDisplay findLogicalDisplayForDeviceLocked(DisplayDevice device) {
841 final int count = mLogicalDisplays.size();
842 for (int i = 0; i < count; i++) {
843 LogicalDisplay display = mLogicalDisplays.valueAt(i);
844 if (display.getPrimaryDisplayDeviceLocked() == device) {
845 return display;
846 }
847 }
848 return null;
849 }
850
Jeff Brownbd6e1502012-08-28 03:27:37 -0700851 private void sendDisplayEventLocked(int displayId, int event) {
852 Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT, displayId, event);
853 mHandler.sendMessage(msg);
854 }
855
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700856 // Requests that performTraversalsInTransactionFromWindowManager be called at a
857 // later time to apply changes to surfaces and displays.
Craig Mautner65d11b32012-10-01 13:59:52 -0700858 private void scheduleTraversalLocked(boolean inTraversal) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700859 if (!mPendingTraversal && mWindowManagerFuncs != null) {
860 mPendingTraversal = true;
Craig Mautner65d11b32012-10-01 13:59:52 -0700861 if (!inTraversal) {
862 mHandler.sendEmptyMessage(MSG_REQUEST_TRAVERSAL);
863 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700864 }
865 }
866
867 // Runs on Handler thread.
868 // Delivers display event notifications to callbacks.
Jeff Brownbd6e1502012-08-28 03:27:37 -0700869 private void deliverDisplayEvent(int displayId, int event) {
870 if (DEBUG) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700871 Slog.d(TAG, "Delivering display event: displayId="
872 + displayId + ", event=" + event);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700873 }
Jeff Brownfa25bf52012-07-23 19:26:30 -0700874
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700875 // Grab the lock and copy the callbacks.
Jeff Brownbd6e1502012-08-28 03:27:37 -0700876 final int count;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700877 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700878 count = mCallbacks.size();
879 mTempCallbacks.clear();
880 for (int i = 0; i < count; i++) {
881 mTempCallbacks.add(mCallbacks.valueAt(i));
Craig Mautner4f67ba62012-08-02 11:23:00 -0700882 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700883 }
Craig Mautner4f67ba62012-08-02 11:23:00 -0700884
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700885 // After releasing the lock, send the notifications out.
Jeff Brownbd6e1502012-08-28 03:27:37 -0700886 for (int i = 0; i < count; i++) {
887 mTempCallbacks.get(i).notifyDisplayEventAsync(displayId, event);
888 }
889 mTempCallbacks.clear();
Craig Mautner4f67ba62012-08-02 11:23:00 -0700890 }
891
Jeff Brownfa25bf52012-07-23 19:26:30 -0700892 @Override // Binder call
Jeff Brownbd6e1502012-08-28 03:27:37 -0700893 public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
Jeff Brownfa25bf52012-07-23 19:26:30 -0700894 if (mContext == null
895 || mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
896 != PackageManager.PERMISSION_GRANTED) {
897 pw.println("Permission Denial: can't dump DisplayManager from from pid="
898 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
899 return;
900 }
901
Jeff Brownbd6e1502012-08-28 03:27:37 -0700902 pw.println("DISPLAY MANAGER (dumpsys display)");
Jeff Brownfa25bf52012-07-23 19:26:30 -0700903
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700904 synchronized (mSyncRoot) {
Jeff Brown9e316a12012-10-08 19:17:06 -0700905 pw.println(" mHeadless=" + mHeadless);
906 pw.println(" mOnlyCode=" + mOnlyCore);
907 pw.println(" mSafeMode=" + mSafeMode);
908 pw.println(" mPendingTraversal=" + mPendingTraversal);
909 pw.println(" mAllDisplayBlankStateFromPowerManager="
910 + mAllDisplayBlankStateFromPowerManager);
911 pw.println(" mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId);
912 pw.println(" mDefaultViewport=" + mDefaultViewport);
913 pw.println(" mExternalTouchViewport=" + mExternalTouchViewport);
Jeff Brown27f1d672012-10-17 18:32:34 -0700914 pw.println(" mSingleDisplayDemoMode=" + mSingleDisplayDemoMode);
Jeff Brown9e316a12012-10-08 19:17:06 -0700915
Jeff Brownbd6e1502012-08-28 03:27:37 -0700916 IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700917 ipw.increaseIndent();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700918
919 pw.println();
920 pw.println("Display Adapters: size=" + mDisplayAdapters.size());
Jeff Brown848c2dc2012-08-19 20:18:08 -0700921 for (DisplayAdapter adapter : mDisplayAdapters) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700922 pw.println(" " + adapter.getName());
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700923 adapter.dumpLocked(ipw);
Jeff Brown848c2dc2012-08-19 20:18:08 -0700924 }
Craig Mautner9de49362012-08-02 14:30:30 -0700925
Jeff Brownbd6e1502012-08-28 03:27:37 -0700926 pw.println();
927 pw.println("Display Devices: size=" + mDisplayDevices.size());
928 for (DisplayDevice device : mDisplayDevices) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700929 pw.println(" " + device.getDisplayDeviceInfoLocked());
930 device.dumpLocked(ipw);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700931 }
932
933 final int logicalDisplayCount = mLogicalDisplays.size();
934 pw.println();
935 pw.println("Logical Displays: size=" + logicalDisplayCount);
936 for (int i = 0; i < logicalDisplayCount; i++) {
937 int displayId = mLogicalDisplays.keyAt(i);
938 LogicalDisplay display = mLogicalDisplays.valueAt(i);
939 pw.println(" Display " + displayId + ":");
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700940 display.dumpLocked(ipw);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700941 }
942 }
943 }
944
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700945 /**
946 * This is the object that everything in the display manager locks on.
947 * We make it an inner class within the {@link DisplayManagerService} to so that it is
948 * clear that the object belongs to the display manager service and that it is
949 * a unique object with a special purpose.
950 */
951 public static final class SyncRoot {
952 }
953
954 /**
955 * Private interface to the window manager.
956 */
957 public interface WindowManagerFuncs {
958 /**
Craig Mautner722285e2012-09-07 13:55:58 -0700959 * Request that the window manager call
960 * {@link #performTraversalInTransactionFromWindowManager} within a surface
961 * transaction at a later time.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700962 */
963 void requestTraversal();
964 }
965
Jeff Brownd728bf52012-09-08 18:05:28 -0700966 /**
967 * Private interface to the input manager.
968 */
969 public interface InputManagerFuncs {
970 /**
971 * Sets information about the displays as needed by the input system.
972 * The input system should copy this information if required.
973 */
974 void setDisplayViewports(DisplayViewport defaultViewport,
975 DisplayViewport externalTouchViewport);
976 }
977
Jeff Brownbd6e1502012-08-28 03:27:37 -0700978 private final class DisplayManagerHandler extends Handler {
979 public DisplayManagerHandler(Looper looper) {
980 super(looper, null, true /*async*/);
Jeff Brown848c2dc2012-08-19 20:18:08 -0700981 }
Jeff Brownbf5740e2012-08-19 23:20:02 -0700982
Jeff Brownbd6e1502012-08-28 03:27:37 -0700983 @Override
984 public void handleMessage(Message msg) {
985 switch (msg.what) {
986 case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER:
987 registerDefaultDisplayAdapter();
988 break;
989
990 case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS:
991 registerAdditionalDisplayAdapters();
992 break;
993
994 case MSG_DELIVER_DISPLAY_EVENT:
995 deliverDisplayEvent(msg.arg1, msg.arg2);
996 break;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700997
998 case MSG_REQUEST_TRAVERSAL:
999 mWindowManagerFuncs.requestTraversal();
1000 break;
Jeff Brownd728bf52012-09-08 18:05:28 -07001001
1002 case MSG_UPDATE_VIEWPORT: {
1003 synchronized (mSyncRoot) {
1004 mTempDefaultViewport.copyFrom(mDefaultViewport);
1005 mTempExternalTouchViewport.copyFrom(mExternalTouchViewport);
1006 }
1007 mInputManagerFuncs.setDisplayViewports(
1008 mTempDefaultViewport, mTempExternalTouchViewport);
1009 break;
1010 }
Jeff Brownbd6e1502012-08-28 03:27:37 -07001011 }
1012 }
1013 }
1014
1015 private final class DisplayAdapterListener implements DisplayAdapter.Listener {
1016 @Override
1017 public void onDisplayDeviceEvent(DisplayDevice device, int event) {
1018 switch (event) {
1019 case DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED:
1020 handleDisplayDeviceAdded(device);
1021 break;
1022
1023 case DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED:
1024 handleDisplayDeviceChanged(device);
1025 break;
1026
1027 case DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED:
1028 handleDisplayDeviceRemoved(device);
1029 break;
1030 }
1031 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001032
1033 @Override
1034 public void onTraversalRequested() {
1035 synchronized (mSyncRoot) {
Craig Mautner65d11b32012-10-01 13:59:52 -07001036 scheduleTraversalLocked(false);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001037 }
1038 }
Jeff Brownbd6e1502012-08-28 03:27:37 -07001039 }
1040
1041 private final class CallbackRecord implements DeathRecipient {
1042 private final int mPid;
1043 private final IDisplayManagerCallback mCallback;
1044
1045 public CallbackRecord(int pid, IDisplayManagerCallback callback) {
1046 mPid = pid;
1047 mCallback = callback;
1048 }
1049
1050 @Override
1051 public void binderDied() {
1052 if (DEBUG) {
1053 Slog.d(TAG, "Display listener for pid " + mPid + " died.");
1054 }
1055 onCallbackDied(mPid);
1056 }
1057
1058 public void notifyDisplayEventAsync(int displayId, int event) {
1059 try {
1060 mCallback.onDisplayEvent(displayId, event);
1061 } catch (RemoteException ex) {
1062 Slog.w(TAG, "Failed to notify process "
1063 + mPid + " that displays changed, assuming it died.", ex);
1064 binderDied();
1065 }
1066 }
1067 }
Jeff Brownfa25bf52012-07-23 19:26:30 -07001068}