blob: 17b066272262acde83cde241c6a0c3e59848d90d [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.
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800121 // NOTE: This is synchronized on while holding WindowManagerService.mWindowMap so never call
122 // into WindowManagerService methods that require mWindowMap while holding this unless you are
123 // very very sure that no deadlock can occur.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700124 private final SyncRoot mSyncRoot = new SyncRoot();
125
126 // True if in safe mode.
127 // This option may disable certain display adapters.
128 public boolean mSafeMode;
129
130 // True if we are in a special boot mode where only core applications and
131 // services should be started. This option may disable certain display adapters.
132 public boolean mOnlyCore;
133
Jeff Brown27f1d672012-10-17 18:32:34 -0700134 // True if the display manager service should pretend there is only one display
135 // and only tell applications about the existence of the default logical display.
136 // The display manager can still mirror content to secondary displays but applications
137 // cannot present unique content on those displays.
138 // Used for demonstration purposes only.
139 private final boolean mSingleDisplayDemoMode;
140
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700141 // All callback records indexed by calling process id.
142 public final SparseArray<CallbackRecord> mCallbacks =
Jeff Brownbd6e1502012-08-28 03:27:37 -0700143 new SparseArray<CallbackRecord>();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700144
Jeff Brownbd6e1502012-08-28 03:27:37 -0700145 // List of all currently registered display adapters.
146 private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
147
148 // List of all currently connected display devices.
149 private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>();
150
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700151 // List of all removed display devices.
152 private final ArrayList<DisplayDevice> mRemovedDisplayDevices = new ArrayList<DisplayDevice>();
153
154 // List of all logical displays indexed by logical display id.
155 private final SparseArray<LogicalDisplay> mLogicalDisplays =
156 new SparseArray<LogicalDisplay>();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700157 private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1;
158
Jeff Brown7f3994e2012-12-04 14:04:28 -0800159 // List of all display transaction listeners.
160 private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners =
161 new CopyOnWriteArrayList<DisplayTransactionListener>();
162
Jeff Brown9e316a12012-10-08 19:17:06 -0700163 // Set to true if all displays have been blanked by the power manager.
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800164 private int mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_UNKNOWN;
Jeff Brown9e316a12012-10-08 19:17:06 -0700165
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700166 // Set to true when there are pending display changes that have yet to be applied
167 // to the surface flinger state.
168 private boolean mPendingTraversal;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700169
Jeff Browne08ae382012-09-07 20:36:36 -0700170 // The Wifi display adapter, or null if not registered.
171 private WifiDisplayAdapter mWifiDisplayAdapter;
172
Jeff Brownd728bf52012-09-08 18:05:28 -0700173 // Viewports of the default display and the display that should receive touch
174 // input from an external source. Used by the input system.
175 private final DisplayViewport mDefaultViewport = new DisplayViewport();
176 private final DisplayViewport mExternalTouchViewport = new DisplayViewport();
177
Jeff Brown89d55462012-09-19 11:33:42 -0700178 // Persistent data store for all internal settings maintained by the display manager service.
179 private final PersistentDataStore mPersistentDataStore = new PersistentDataStore();
180
Jeff Brownbd6e1502012-08-28 03:27:37 -0700181 // Temporary callback list, used when sending display events to applications.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700182 // May be used outside of the lock but only on the handler thread.
183 private final ArrayList<CallbackRecord> mTempCallbacks = new ArrayList<CallbackRecord>();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700184
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700185 // Temporary display info, used for comparing display configurations.
186 private final DisplayInfo mTempDisplayInfo = new DisplayInfo();
187
Jeff Brownd728bf52012-09-08 18:05:28 -0700188 // Temporary viewports, used when sending new viewport information to the
189 // input system. May be used outside of the lock but only on the handler thread.
190 private final DisplayViewport mTempDefaultViewport = new DisplayViewport();
191 private final DisplayViewport mTempExternalTouchViewport = new DisplayViewport();
192
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700193 public DisplayManagerService(Context context, Handler mainHandler, Handler uiHandler) {
Jeff Brown848c2dc2012-08-19 20:18:08 -0700194 mContext = context;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700195 mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1");
Jeff Brown848c2dc2012-08-19 20:18:08 -0700196
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700197 mHandler = new DisplayManagerHandler(mainHandler.getLooper());
198 mUiHandler = uiHandler;
199 mDisplayAdapterListener = new DisplayAdapterListener();
Jeff Brown27f1d672012-10-17 18:32:34 -0700200 mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700201
Jeff Brownbd6e1502012-08-28 03:27:37 -0700202 mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER);
Craig Mautner4f67ba62012-08-02 11:23:00 -0700203 }
204
Jeff Brownbd6e1502012-08-28 03:27:37 -0700205 /**
206 * Pauses the boot process to wait for the first display to be initialized.
207 */
208 public boolean waitForDefaultDisplay() {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700209 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700210 long timeout = SystemClock.uptimeMillis() + WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
211 while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null) {
212 long delay = timeout - SystemClock.uptimeMillis();
213 if (delay <= 0) {
214 return false;
215 }
216 if (DEBUG) {
217 Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay);
218 }
219 try {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700220 mSyncRoot.wait(delay);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700221 } catch (InterruptedException ex) {
222 }
223 }
224 }
225 return true;
226 }
227
228 /**
Jeff Brownd728bf52012-09-08 18:05:28 -0700229 * Called during initialization to associate the display manager with the
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700230 * window manager.
231 */
232 public void setWindowManager(WindowManagerFuncs windowManagerFuncs) {
233 synchronized (mSyncRoot) {
234 mWindowManagerFuncs = windowManagerFuncs;
Craig Mautner65d11b32012-10-01 13:59:52 -0700235 scheduleTraversalLocked(false);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700236 }
237 }
238
239 /**
Jeff Brownd728bf52012-09-08 18:05:28 -0700240 * Called during initialization to associate the display manager with the
241 * input manager.
242 */
243 public void setInputManager(InputManagerFuncs inputManagerFuncs) {
244 synchronized (mSyncRoot) {
245 mInputManagerFuncs = inputManagerFuncs;
Craig Mautner65d11b32012-10-01 13:59:52 -0700246 scheduleTraversalLocked(false);
Jeff Brownd728bf52012-09-08 18:05:28 -0700247 }
248 }
249
250 /**
Jeff Brownbd6e1502012-08-28 03:27:37 -0700251 * Called when the system is ready to go.
252 */
253 public void systemReady(boolean safeMode, boolean onlyCore) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700254 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700255 mSafeMode = safeMode;
256 mOnlyCore = onlyCore;
257 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700258
Jeff Brownbd6e1502012-08-28 03:27:37 -0700259 mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
260 }
261
Jeff Brown848c2dc2012-08-19 20:18:08 -0700262 /**
263 * Returns true if the device is headless.
264 *
265 * @return True if the device is headless.
266 */
Jeff Brownfa25bf52012-07-23 19:26:30 -0700267 public boolean isHeadless() {
268 return mHeadless;
269 }
270
Craig Mautner4f67ba62012-08-02 11:23:00 -0700271 /**
Jeff Brown7f3994e2012-12-04 14:04:28 -0800272 * Registers a display transaction listener to provide the client a chance to
273 * update its surfaces within the same transaction as any display layout updates.
274 *
275 * @param listener The listener to register.
276 */
277 public void registerDisplayTransactionListener(DisplayTransactionListener listener) {
278 if (listener == null) {
279 throw new IllegalArgumentException("listener must not be null");
280 }
281
282 // List is self-synchronized copy-on-write.
283 mDisplayTransactionListeners.add(listener);
284 }
285
286 /**
287 * Unregisters a display transaction listener to provide the client a chance to
288 * update its surfaces within the same transaction as any display layout updates.
289 *
290 * @param listener The listener to unregister.
291 */
292 public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) {
293 if (listener == null) {
294 throw new IllegalArgumentException("listener must not be null");
295 }
296
297 // List is self-synchronized copy-on-write.
298 mDisplayTransactionListeners.remove(listener);
299 }
300
301 /**
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700302 * Overrides the display information of a particular logical display.
303 * This is used by the window manager to control the size and characteristics
304 * of the default display. It is expected to apply the requested change
305 * to the display information synchronously so that applications will immediately
306 * observe the new state.
Jeff Brownbd6e1502012-08-28 03:27:37 -0700307 *
Jeff Brown64a55af2012-08-26 02:47:39 -0700308 * @param displayId The logical display id.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700309 * @param info The new data to be stored.
Jeff Brown64a55af2012-08-26 02:47:39 -0700310 */
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700311 public void setDisplayInfoOverrideFromWindowManager(
312 int displayId, DisplayInfo info) {
313 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700314 LogicalDisplay display = mLogicalDisplays.get(displayId);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700315 if (display != null) {
316 mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
317 display.setDisplayInfoOverrideFromWindowManagerLocked(info);
318 if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
319 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
Craig Mautner65d11b32012-10-01 13:59:52 -0700320 scheduleTraversalLocked(false);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700321 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700322 }
323 }
324 }
325
326 /**
Dianne Hackbornc652de82013-02-15 16:32:56 -0800327 * Sets the overscan insets for a particular display.
328 */
329 public void setOverscan(int displayId, int left, int top, int right, int bottom) {
330 synchronized (mSyncRoot) {
331 LogicalDisplay display = mLogicalDisplays.get(displayId);
332 if (display != null) {
333 display.setOverscan(left, top, right, bottom);
334 }
335 }
336 }
337
338 /**
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700339 * Called by the window manager to perform traversals while holding a
340 * surface flinger transaction.
Jeff Brownbd6e1502012-08-28 03:27:37 -0700341 */
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700342 public void performTraversalInTransactionFromWindowManager() {
343 synchronized (mSyncRoot) {
344 if (!mPendingTraversal) {
345 return;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700346 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700347 mPendingTraversal = false;
348
349 performTraversalInTransactionLocked();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700350 }
Jeff Brown7f3994e2012-12-04 14:04:28 -0800351
352 // List is self-synchronized copy-on-write.
353 for (DisplayTransactionListener listener : mDisplayTransactionListeners) {
354 listener.onDisplayTransaction();
355 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700356 }
357
358 /**
Jeff Brown9e316a12012-10-08 19:17:06 -0700359 * Called by the power manager to blank all displays.
360 */
361 public void blankAllDisplaysFromPowerManager() {
362 synchronized (mSyncRoot) {
363 if (mAllDisplayBlankStateFromPowerManager != DISPLAY_BLANK_STATE_BLANKED) {
364 mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_BLANKED;
365
366 final int count = mDisplayDevices.size();
367 for (int i = 0; i < count; i++) {
368 DisplayDevice device = mDisplayDevices.get(i);
369 device.blankLocked();
370 }
Jeff Brown8ec09432012-10-16 16:19:23 -0700371
372 scheduleTraversalLocked(false);
Jeff Brown9e316a12012-10-08 19:17:06 -0700373 }
374 }
375 }
376
377 /**
378 * Called by the power manager to unblank all displays.
379 */
380 public void unblankAllDisplaysFromPowerManager() {
381 synchronized (mSyncRoot) {
382 if (mAllDisplayBlankStateFromPowerManager != DISPLAY_BLANK_STATE_UNBLANKED) {
383 mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_UNBLANKED;
384
385 final int count = mDisplayDevices.size();
386 for (int i = 0; i < count; i++) {
387 DisplayDevice device = mDisplayDevices.get(i);
388 device.unblankLocked();
389 }
Jeff Brown8ec09432012-10-16 16:19:23 -0700390
391 scheduleTraversalLocked(false);
Jeff Brown9e316a12012-10-08 19:17:06 -0700392 }
393 }
394 }
395
396 /**
Jeff Brownbd6e1502012-08-28 03:27:37 -0700397 * Returns information about the specified logical display.
398 *
399 * @param displayId The logical display id.
Craig Mautner722285e2012-09-07 13:55:58 -0700400 * @return The logical display info, or null if the display does not exist. The
401 * returned object must be treated as immutable.
Jeff Brownbd6e1502012-08-28 03:27:37 -0700402 */
403 @Override // Binder call
404 public DisplayInfo getDisplayInfo(int displayId) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700405 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700406 LogicalDisplay display = mLogicalDisplays.get(displayId);
407 if (display != null) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700408 return display.getDisplayInfoLocked();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700409 }
410 return null;
411 }
412 }
413
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700414 /**
415 * Returns the list of all display ids.
416 */
Jeff Brownbd6e1502012-08-28 03:27:37 -0700417 @Override // Binder call
418 public int[] getDisplayIds() {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700419 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700420 final int count = mLogicalDisplays.size();
421 int[] displayIds = new int[count];
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700422 for (int i = 0; i < count; i++) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700423 displayIds[i] = mLogicalDisplays.keyAt(i);
424 }
425 return displayIds;
426 }
427 }
428
429 @Override // Binder call
430 public void registerCallback(IDisplayManagerCallback callback) {
431 if (callback == null) {
432 throw new IllegalArgumentException("listener must not be null");
433 }
434
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700435 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700436 int callingPid = Binder.getCallingPid();
437 if (mCallbacks.get(callingPid) != null) {
438 throw new SecurityException("The calling process has already "
439 + "registered an IDisplayManagerCallback.");
Jeff Brown64a55af2012-08-26 02:47:39 -0700440 }
441
Jeff Brownbd6e1502012-08-28 03:27:37 -0700442 CallbackRecord record = new CallbackRecord(callingPid, callback);
443 try {
444 IBinder binder = callback.asBinder();
445 binder.linkToDeath(record, 0);
446 } catch (RemoteException ex) {
447 // give up
448 throw new RuntimeException(ex);
449 }
450
451 mCallbacks.put(callingPid, record);
452 }
453 }
454
455 private void onCallbackDied(int pid) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700456 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700457 mCallbacks.remove(pid);
458 }
459 }
460
Jeff Browne08ae382012-09-07 20:36:36 -0700461 @Override // Binder call
462 public void scanWifiDisplays() {
Jeff Browne08ae382012-09-07 20:36:36 -0700463 final long token = Binder.clearCallingIdentity();
464 try {
465 synchronized (mSyncRoot) {
Jeff Brown21c71532012-09-09 13:26:55 -0700466 if (mWifiDisplayAdapter != null) {
467 mWifiDisplayAdapter.requestScanLocked();
468 }
Jeff Browne08ae382012-09-07 20:36:36 -0700469 }
470 } finally {
471 Binder.restoreCallingIdentity(token);
472 }
473 }
474
475 @Override // Binder call
476 public void connectWifiDisplay(String address) {
Jeff Browne08ae382012-09-07 20:36:36 -0700477 if (address == null) {
478 throw new IllegalArgumentException("address must not be null");
479 }
480
Jeff Brownbc335452012-09-26 18:34:47 -0700481 final boolean trusted = canCallerConfigureWifiDisplay();
Jeff Browne08ae382012-09-07 20:36:36 -0700482 final long token = Binder.clearCallingIdentity();
483 try {
484 synchronized (mSyncRoot) {
Jeff Brown21c71532012-09-09 13:26:55 -0700485 if (mWifiDisplayAdapter != null) {
Jeff Brownbc335452012-09-26 18:34:47 -0700486 mWifiDisplayAdapter.requestConnectLocked(address, trusted);
Jeff Brown21c71532012-09-09 13:26:55 -0700487 }
Jeff Browne08ae382012-09-07 20:36:36 -0700488 }
489 } finally {
490 Binder.restoreCallingIdentity(token);
491 }
492 }
493
494 @Override // Binder call
495 public void disconnectWifiDisplay() {
Jeff Browne08ae382012-09-07 20:36:36 -0700496 final long token = Binder.clearCallingIdentity();
497 try {
498 synchronized (mSyncRoot) {
Jeff Brown21c71532012-09-09 13:26:55 -0700499 if (mWifiDisplayAdapter != null) {
500 mWifiDisplayAdapter.requestDisconnectLocked();
501 }
Jeff Browne08ae382012-09-07 20:36:36 -0700502 }
503 } finally {
504 Binder.restoreCallingIdentity(token);
505 }
506 }
507
508 @Override // Binder call
Jeff Brown89d55462012-09-19 11:33:42 -0700509 public void renameWifiDisplay(String address, String alias) {
Jeff Brown89d55462012-09-19 11:33:42 -0700510 if (address == null) {
511 throw new IllegalArgumentException("address must not be null");
512 }
Jeff Brownbc335452012-09-26 18:34:47 -0700513 if (!canCallerConfigureWifiDisplay()) {
514 throw new SecurityException("Requires CONFIGURE_WIFI_DISPLAY permission to "
515 + "rename a wifi display.");
516 }
Jeff Brown89d55462012-09-19 11:33:42 -0700517
518 final long token = Binder.clearCallingIdentity();
519 try {
520 synchronized (mSyncRoot) {
521 if (mWifiDisplayAdapter != null) {
522 mWifiDisplayAdapter.requestRenameLocked(address, alias);
523 }
524 }
525 } finally {
526 Binder.restoreCallingIdentity(token);
527 }
528 }
529
530 @Override // Binder call
531 public void forgetWifiDisplay(String address) {
Jeff Brown89d55462012-09-19 11:33:42 -0700532 if (address == null) {
533 throw new IllegalArgumentException("address must not be null");
534 }
Jeff Brownbc335452012-09-26 18:34:47 -0700535 if (!canCallerConfigureWifiDisplay()) {
536 throw new SecurityException("Requires CONFIGURE_WIFI_DISPLAY permission to "
537 + "forget a wifi display.");
538 }
Jeff Brown89d55462012-09-19 11:33:42 -0700539
540 final long token = Binder.clearCallingIdentity();
541 try {
542 synchronized (mSyncRoot) {
543 if (mWifiDisplayAdapter != null) {
544 mWifiDisplayAdapter.requestForgetLocked(address);
545 }
546 }
547 } finally {
548 Binder.restoreCallingIdentity(token);
549 }
550 }
551
552 @Override // Binder call
Jeff Browne08ae382012-09-07 20:36:36 -0700553 public WifiDisplayStatus getWifiDisplayStatus() {
Jeff Browne08ae382012-09-07 20:36:36 -0700554 final long token = Binder.clearCallingIdentity();
555 try {
556 synchronized (mSyncRoot) {
Jeff Brown21c71532012-09-09 13:26:55 -0700557 if (mWifiDisplayAdapter != null) {
558 return mWifiDisplayAdapter.getWifiDisplayStatusLocked();
Jeff Brown21c71532012-09-09 13:26:55 -0700559 }
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800560 return new WifiDisplayStatus();
Jeff Browne08ae382012-09-07 20:36:36 -0700561 }
562 } finally {
563 Binder.restoreCallingIdentity(token);
564 }
565 }
566
Jeff Brownbc335452012-09-26 18:34:47 -0700567 private boolean canCallerConfigureWifiDisplay() {
568 return mContext.checkCallingPermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
569 == PackageManager.PERMISSION_GRANTED;
570 }
571
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700572 private void registerDefaultDisplayAdapter() {
573 // Register default display adapter.
574 synchronized (mSyncRoot) {
575 if (mHeadless) {
576 registerDisplayAdapterLocked(new HeadlessDisplayAdapter(
577 mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
578 } else {
579 registerDisplayAdapterLocked(new LocalDisplayAdapter(
580 mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
581 }
582 }
583 }
584
585 private void registerAdditionalDisplayAdapters() {
586 synchronized (mSyncRoot) {
587 if (shouldRegisterNonEssentialDisplayAdaptersLocked()) {
Jeff Brown89d55462012-09-19 11:33:42 -0700588 registerOverlayDisplayAdapterLocked();
589 registerWifiDisplayAdapterLocked();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700590 }
591 }
592 }
593
Jeff Brown89d55462012-09-19 11:33:42 -0700594 private void registerOverlayDisplayAdapterLocked() {
595 registerDisplayAdapterLocked(new OverlayDisplayAdapter(
596 mSyncRoot, mContext, mHandler, mDisplayAdapterListener, mUiHandler));
597 }
598
599 private void registerWifiDisplayAdapterLocked() {
600 if (mContext.getResources().getBoolean(
Jeff Brownbbd28a22012-09-20 16:47:15 -0700601 com.android.internal.R.bool.config_enableWifiDisplay)
602 || SystemProperties.getInt(FORCE_WIFI_DISPLAY_ENABLE, -1) == 1) {
Jeff Brown89d55462012-09-19 11:33:42 -0700603 mWifiDisplayAdapter = new WifiDisplayAdapter(
604 mSyncRoot, mContext, mHandler, mDisplayAdapterListener,
605 mPersistentDataStore);
606 registerDisplayAdapterLocked(mWifiDisplayAdapter);
607 }
608 }
609
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700610 private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() {
611 // In safe mode, we disable non-essential display adapters to give the user
612 // an opportunity to fix broken settings or other problems that might affect
613 // system stability.
614 // In only-core mode, we disable non-essential display adapters to minimize
615 // the number of dependencies that are started while in this mode and to
616 // prevent problems that might occur due to the device being encrypted.
617 return !mSafeMode && !mOnlyCore;
618 }
619
620 private void registerDisplayAdapterLocked(DisplayAdapter adapter) {
621 mDisplayAdapters.add(adapter);
622 adapter.registerLocked();
623 }
624
Jeff Brownbd6e1502012-08-28 03:27:37 -0700625 private void handleDisplayDeviceAdded(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700626 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700627 if (mDisplayDevices.contains(device)) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700628 Slog.w(TAG, "Attempted to add already added display device: "
629 + device.getDisplayDeviceInfoLocked());
Jeff Brownbd6e1502012-08-28 03:27:37 -0700630 return;
631 }
632
Jeff Browne87bf032012-09-20 18:30:13 -0700633 Slog.i(TAG, "Display device added: " + device.getDisplayDeviceInfoLocked());
634
Jeff Brownbd6e1502012-08-28 03:27:37 -0700635 mDisplayDevices.add(device);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700636 addLogicalDisplayLocked(device);
Craig Mautner65d11b32012-10-01 13:59:52 -0700637 scheduleTraversalLocked(false);
Jeff Brown9e316a12012-10-08 19:17:06 -0700638
639 // Blank or unblank the display immediately to match the state requested
640 // by the power manager (if known).
641 switch (mAllDisplayBlankStateFromPowerManager) {
642 case DISPLAY_BLANK_STATE_BLANKED:
643 device.blankLocked();
644 break;
645 case DISPLAY_BLANK_STATE_UNBLANKED:
646 device.unblankLocked();
647 break;
648 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700649 }
650 }
651
Jeff Brownbd6e1502012-08-28 03:27:37 -0700652 private void handleDisplayDeviceChanged(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700653 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700654 if (!mDisplayDevices.contains(device)) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700655 Slog.w(TAG, "Attempted to change non-existent display device: "
656 + device.getDisplayDeviceInfoLocked());
Jeff Brownbd6e1502012-08-28 03:27:37 -0700657 return;
658 }
659
Jeff Browne87bf032012-09-20 18:30:13 -0700660 Slog.i(TAG, "Display device changed: " + device.getDisplayDeviceInfoLocked());
661
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700662 device.applyPendingDisplayDeviceInfoChangesLocked();
663 if (updateLogicalDisplaysLocked()) {
Craig Mautner65d11b32012-10-01 13:59:52 -0700664 scheduleTraversalLocked(false);
Jeff Brown64a55af2012-08-26 02:47:39 -0700665 }
666 }
667 }
668
Jeff Brownbd6e1502012-08-28 03:27:37 -0700669 private void handleDisplayDeviceRemoved(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700670 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700671 if (!mDisplayDevices.remove(device)) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700672 Slog.w(TAG, "Attempted to remove non-existent display device: "
673 + device.getDisplayDeviceInfoLocked());
Jeff Brownbd6e1502012-08-28 03:27:37 -0700674 return;
Craig Mautner4f67ba62012-08-02 11:23:00 -0700675 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700676
Jeff Browne87bf032012-09-20 18:30:13 -0700677 Slog.i(TAG, "Display device removed: " + device.getDisplayDeviceInfoLocked());
678
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700679 mRemovedDisplayDevices.add(device);
680 updateLogicalDisplaysLocked();
Craig Mautner65d11b32012-10-01 13:59:52 -0700681 scheduleTraversalLocked(false);
Craig Mautner4f67ba62012-08-02 11:23:00 -0700682 }
683 }
684
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700685 // Adds a new logical display based on the given display device.
686 // Sends notifications if needed.
687 private void addLogicalDisplayLocked(DisplayDevice device) {
688 DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
689 boolean isDefault = (deviceInfo.flags
690 & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0;
691 if (isDefault && mLogicalDisplays.get(Display.DEFAULT_DISPLAY) != null) {
692 Slog.w(TAG, "Ignoring attempt to add a second default display: " + deviceInfo);
693 isDefault = false;
694 }
695
Jeff Brown27f1d672012-10-17 18:32:34 -0700696 if (!isDefault && mSingleDisplayDemoMode) {
697 Slog.i(TAG, "Not creating a logical display for a secondary display "
698 + " because single display demo mode is enabled: " + deviceInfo);
699 return;
700 }
701
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700702 final int displayId = assignDisplayIdLocked(isDefault);
703 final int layerStack = assignLayerStackLocked(displayId);
704
Jeff Brownd728bf52012-09-08 18:05:28 -0700705 LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700706 display.updateLocked(mDisplayDevices);
707 if (!display.isValidLocked()) {
708 // This should never happen currently.
709 Slog.w(TAG, "Ignoring display device because the logical display "
710 + "created from it was not considered valid: " + deviceInfo);
711 return;
712 }
713
714 mLogicalDisplays.put(displayId, display);
715
716 // Wake up waitForDefaultDisplay.
717 if (isDefault) {
718 mSyncRoot.notifyAll();
719 }
720
721 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED);
722 }
723
724 private int assignDisplayIdLocked(boolean isDefault) {
725 return isDefault ? Display.DEFAULT_DISPLAY : mNextNonDefaultDisplayId++;
726 }
727
728 private int assignLayerStackLocked(int displayId) {
729 // Currently layer stacks and display ids are the same.
730 // This need not be the case.
731 return displayId;
732 }
733
734 // Updates all existing logical displays given the current set of display devices.
735 // Removes invalid logical displays.
736 // Sends notifications if needed.
737 private boolean updateLogicalDisplaysLocked() {
738 boolean changed = false;
739 for (int i = mLogicalDisplays.size(); i-- > 0; ) {
740 final int displayId = mLogicalDisplays.keyAt(i);
741 LogicalDisplay display = mLogicalDisplays.valueAt(i);
742
743 mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
744 display.updateLocked(mDisplayDevices);
745 if (!display.isValidLocked()) {
746 mLogicalDisplays.removeAt(i);
747 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED);
748 changed = true;
749 } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
750 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
751 changed = true;
752 }
753 }
754 return changed;
755 }
756
757 private void performTraversalInTransactionLocked() {
758 // Perform one last traversal for each removed display device.
759 final int removedCount = mRemovedDisplayDevices.size();
760 for (int i = 0; i < removedCount; i++) {
761 DisplayDevice device = mRemovedDisplayDevices.get(i);
762 device.performTraversalInTransactionLocked();
763 }
764 mRemovedDisplayDevices.clear();
765
Jeff Brownd728bf52012-09-08 18:05:28 -0700766 // Clear all viewports before configuring displays so that we can keep
767 // track of which ones we have configured.
768 clearViewportsLocked();
769
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700770 // Configure each display device.
771 final int count = mDisplayDevices.size();
772 for (int i = 0; i < count; i++) {
773 DisplayDevice device = mDisplayDevices.get(i);
774 configureDisplayInTransactionLocked(device);
775 device.performTraversalInTransactionLocked();
776 }
Jeff Brownd728bf52012-09-08 18:05:28 -0700777
778 // Tell the input system about these new viewports.
779 if (mInputManagerFuncs != null) {
780 mHandler.sendEmptyMessage(MSG_UPDATE_VIEWPORT);
781 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700782 }
783
Craig Mautner722285e2012-09-07 13:55:58 -0700784 /**
785 * Tells the display manager whether there is interesting unique content on the
786 * specified logical display. This is used to control automatic mirroring.
787 * <p>
788 * If the display has unique content, then the display manager arranges for it
789 * to be presented on a physical display if appropriate. Otherwise, the display manager
790 * may choose to make the physical display mirror some other logical display.
791 * </p>
792 *
793 * @param displayId The logical display id to update.
794 * @param hasContent True if the logical display has content.
Craig Mautner65d11b32012-10-01 13:59:52 -0700795 * @param inTraversal True if called from WindowManagerService during a window traversal prior
796 * to call to performTraversalInTransactionFromWindowManager.
Craig Mautner722285e2012-09-07 13:55:58 -0700797 */
Craig Mautner65d11b32012-10-01 13:59:52 -0700798 public void setDisplayHasContent(int displayId, boolean hasContent, boolean inTraversal) {
Craig Mautner722285e2012-09-07 13:55:58 -0700799 synchronized (mSyncRoot) {
800 LogicalDisplay display = mLogicalDisplays.get(displayId);
801 if (display != null && display.hasContentLocked() != hasContent) {
802 display.setHasContentLocked(hasContent);
Craig Mautner65d11b32012-10-01 13:59:52 -0700803 scheduleTraversalLocked(inTraversal);
Craig Mautner722285e2012-09-07 13:55:58 -0700804 }
805 }
Jeff Brownd728bf52012-09-08 18:05:28 -0700806 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700807
Jeff Brownd728bf52012-09-08 18:05:28 -0700808 private void clearViewportsLocked() {
809 mDefaultViewport.valid = false;
810 mExternalTouchViewport.valid = false;
Craig Mautner722285e2012-09-07 13:55:58 -0700811 }
812
813 private void configureDisplayInTransactionLocked(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700814 // Find the logical display that the display device is showing.
Craig Mautner722285e2012-09-07 13:55:58 -0700815 LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
816 if (display != null && !display.hasContentLocked()) {
817 display = null;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700818 }
819 if (display == null) {
820 display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY);
821 }
822
823 // Apply the logical display configuration to the display device.
824 if (display == null) {
825 // TODO: no logical display for the device, blank it
Jeff Brownd728bf52012-09-08 18:05:28 -0700826 Slog.w(TAG, "Missing logical display to use for physical display device: "
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700827 + device.getDisplayDeviceInfoLocked());
Jeff Brownd728bf52012-09-08 18:05:28 -0700828 return;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700829 }
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800830 boolean isBlanked = (mAllDisplayBlankStateFromPowerManager == DISPLAY_BLANK_STATE_BLANKED);
831 display.configureDisplayInTransactionLocked(device, isBlanked);
Jeff Brownd728bf52012-09-08 18:05:28 -0700832
833 // Update the viewports if needed.
834 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
835 if (!mDefaultViewport.valid
836 && (info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
837 setViewportLocked(mDefaultViewport, display, device);
838 }
839 if (!mExternalTouchViewport.valid
840 && info.touch == DisplayDeviceInfo.TOUCH_EXTERNAL) {
841 setViewportLocked(mExternalTouchViewport, display, device);
842 }
843 }
844
845 private static void setViewportLocked(DisplayViewport viewport,
846 LogicalDisplay display, DisplayDevice device) {
847 viewport.valid = true;
848 viewport.displayId = display.getDisplayIdLocked();
849 device.populateViewportLocked(viewport);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700850 }
851
852 private LogicalDisplay findLogicalDisplayForDeviceLocked(DisplayDevice device) {
853 final int count = mLogicalDisplays.size();
854 for (int i = 0; i < count; i++) {
855 LogicalDisplay display = mLogicalDisplays.valueAt(i);
856 if (display.getPrimaryDisplayDeviceLocked() == device) {
857 return display;
858 }
859 }
860 return null;
861 }
862
Jeff Brownbd6e1502012-08-28 03:27:37 -0700863 private void sendDisplayEventLocked(int displayId, int event) {
864 Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT, displayId, event);
865 mHandler.sendMessage(msg);
866 }
867
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700868 // Requests that performTraversalsInTransactionFromWindowManager be called at a
869 // later time to apply changes to surfaces and displays.
Craig Mautner65d11b32012-10-01 13:59:52 -0700870 private void scheduleTraversalLocked(boolean inTraversal) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700871 if (!mPendingTraversal && mWindowManagerFuncs != null) {
872 mPendingTraversal = true;
Craig Mautner65d11b32012-10-01 13:59:52 -0700873 if (!inTraversal) {
874 mHandler.sendEmptyMessage(MSG_REQUEST_TRAVERSAL);
875 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700876 }
877 }
878
879 // Runs on Handler thread.
880 // Delivers display event notifications to callbacks.
Jeff Brownbd6e1502012-08-28 03:27:37 -0700881 private void deliverDisplayEvent(int displayId, int event) {
882 if (DEBUG) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700883 Slog.d(TAG, "Delivering display event: displayId="
884 + displayId + ", event=" + event);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700885 }
Jeff Brownfa25bf52012-07-23 19:26:30 -0700886
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700887 // Grab the lock and copy the callbacks.
Jeff Brownbd6e1502012-08-28 03:27:37 -0700888 final int count;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700889 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700890 count = mCallbacks.size();
891 mTempCallbacks.clear();
892 for (int i = 0; i < count; i++) {
893 mTempCallbacks.add(mCallbacks.valueAt(i));
Craig Mautner4f67ba62012-08-02 11:23:00 -0700894 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700895 }
Craig Mautner4f67ba62012-08-02 11:23:00 -0700896
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700897 // After releasing the lock, send the notifications out.
Jeff Brownbd6e1502012-08-28 03:27:37 -0700898 for (int i = 0; i < count; i++) {
899 mTempCallbacks.get(i).notifyDisplayEventAsync(displayId, event);
900 }
901 mTempCallbacks.clear();
Craig Mautner4f67ba62012-08-02 11:23:00 -0700902 }
903
Jeff Brownfa25bf52012-07-23 19:26:30 -0700904 @Override // Binder call
Jeff Brownbd6e1502012-08-28 03:27:37 -0700905 public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
Jeff Brownfa25bf52012-07-23 19:26:30 -0700906 if (mContext == null
907 || mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
908 != PackageManager.PERMISSION_GRANTED) {
909 pw.println("Permission Denial: can't dump DisplayManager from from pid="
910 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
911 return;
912 }
913
Jeff Brownbd6e1502012-08-28 03:27:37 -0700914 pw.println("DISPLAY MANAGER (dumpsys display)");
Jeff Brownfa25bf52012-07-23 19:26:30 -0700915
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700916 synchronized (mSyncRoot) {
Jeff Brown9e316a12012-10-08 19:17:06 -0700917 pw.println(" mHeadless=" + mHeadless);
918 pw.println(" mOnlyCode=" + mOnlyCore);
919 pw.println(" mSafeMode=" + mSafeMode);
920 pw.println(" mPendingTraversal=" + mPendingTraversal);
921 pw.println(" mAllDisplayBlankStateFromPowerManager="
922 + mAllDisplayBlankStateFromPowerManager);
923 pw.println(" mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId);
924 pw.println(" mDefaultViewport=" + mDefaultViewport);
925 pw.println(" mExternalTouchViewport=" + mExternalTouchViewport);
Jeff Brown27f1d672012-10-17 18:32:34 -0700926 pw.println(" mSingleDisplayDemoMode=" + mSingleDisplayDemoMode);
Jeff Brown9e316a12012-10-08 19:17:06 -0700927
Jeff Brownbd6e1502012-08-28 03:27:37 -0700928 IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700929 ipw.increaseIndent();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700930
931 pw.println();
932 pw.println("Display Adapters: size=" + mDisplayAdapters.size());
Jeff Brown848c2dc2012-08-19 20:18:08 -0700933 for (DisplayAdapter adapter : mDisplayAdapters) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700934 pw.println(" " + adapter.getName());
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700935 adapter.dumpLocked(ipw);
Jeff Brown848c2dc2012-08-19 20:18:08 -0700936 }
Craig Mautner9de49362012-08-02 14:30:30 -0700937
Jeff Brownbd6e1502012-08-28 03:27:37 -0700938 pw.println();
939 pw.println("Display Devices: size=" + mDisplayDevices.size());
940 for (DisplayDevice device : mDisplayDevices) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700941 pw.println(" " + device.getDisplayDeviceInfoLocked());
942 device.dumpLocked(ipw);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700943 }
944
945 final int logicalDisplayCount = mLogicalDisplays.size();
946 pw.println();
947 pw.println("Logical Displays: size=" + logicalDisplayCount);
948 for (int i = 0; i < logicalDisplayCount; i++) {
949 int displayId = mLogicalDisplays.keyAt(i);
950 LogicalDisplay display = mLogicalDisplays.valueAt(i);
951 pw.println(" Display " + displayId + ":");
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700952 display.dumpLocked(ipw);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700953 }
954 }
955 }
956
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700957 /**
958 * This is the object that everything in the display manager locks on.
959 * We make it an inner class within the {@link DisplayManagerService} to so that it is
960 * clear that the object belongs to the display manager service and that it is
961 * a unique object with a special purpose.
962 */
963 public static final class SyncRoot {
964 }
965
966 /**
967 * Private interface to the window manager.
968 */
969 public interface WindowManagerFuncs {
970 /**
Craig Mautner722285e2012-09-07 13:55:58 -0700971 * Request that the window manager call
972 * {@link #performTraversalInTransactionFromWindowManager} within a surface
973 * transaction at a later time.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700974 */
975 void requestTraversal();
976 }
977
Jeff Brownd728bf52012-09-08 18:05:28 -0700978 /**
979 * Private interface to the input manager.
980 */
981 public interface InputManagerFuncs {
982 /**
983 * Sets information about the displays as needed by the input system.
984 * The input system should copy this information if required.
985 */
986 void setDisplayViewports(DisplayViewport defaultViewport,
987 DisplayViewport externalTouchViewport);
988 }
989
Jeff Brownbd6e1502012-08-28 03:27:37 -0700990 private final class DisplayManagerHandler extends Handler {
991 public DisplayManagerHandler(Looper looper) {
992 super(looper, null, true /*async*/);
Jeff Brown848c2dc2012-08-19 20:18:08 -0700993 }
Jeff Brownbf5740e2012-08-19 23:20:02 -0700994
Jeff Brownbd6e1502012-08-28 03:27:37 -0700995 @Override
996 public void handleMessage(Message msg) {
997 switch (msg.what) {
998 case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER:
999 registerDefaultDisplayAdapter();
1000 break;
1001
1002 case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS:
1003 registerAdditionalDisplayAdapters();
1004 break;
1005
1006 case MSG_DELIVER_DISPLAY_EVENT:
1007 deliverDisplayEvent(msg.arg1, msg.arg2);
1008 break;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001009
1010 case MSG_REQUEST_TRAVERSAL:
1011 mWindowManagerFuncs.requestTraversal();
1012 break;
Jeff Brownd728bf52012-09-08 18:05:28 -07001013
1014 case MSG_UPDATE_VIEWPORT: {
1015 synchronized (mSyncRoot) {
1016 mTempDefaultViewport.copyFrom(mDefaultViewport);
1017 mTempExternalTouchViewport.copyFrom(mExternalTouchViewport);
1018 }
1019 mInputManagerFuncs.setDisplayViewports(
1020 mTempDefaultViewport, mTempExternalTouchViewport);
1021 break;
1022 }
Jeff Brownbd6e1502012-08-28 03:27:37 -07001023 }
1024 }
1025 }
1026
1027 private final class DisplayAdapterListener implements DisplayAdapter.Listener {
1028 @Override
1029 public void onDisplayDeviceEvent(DisplayDevice device, int event) {
1030 switch (event) {
1031 case DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED:
1032 handleDisplayDeviceAdded(device);
1033 break;
1034
1035 case DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED:
1036 handleDisplayDeviceChanged(device);
1037 break;
1038
1039 case DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED:
1040 handleDisplayDeviceRemoved(device);
1041 break;
1042 }
1043 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001044
1045 @Override
1046 public void onTraversalRequested() {
1047 synchronized (mSyncRoot) {
Craig Mautner65d11b32012-10-01 13:59:52 -07001048 scheduleTraversalLocked(false);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001049 }
1050 }
Jeff Brownbd6e1502012-08-28 03:27:37 -07001051 }
1052
1053 private final class CallbackRecord implements DeathRecipient {
1054 private final int mPid;
1055 private final IDisplayManagerCallback mCallback;
1056
1057 public CallbackRecord(int pid, IDisplayManagerCallback callback) {
1058 mPid = pid;
1059 mCallback = callback;
1060 }
1061
1062 @Override
1063 public void binderDied() {
1064 if (DEBUG) {
1065 Slog.d(TAG, "Display listener for pid " + mPid + " died.");
1066 }
1067 onCallbackDied(mPid);
1068 }
1069
1070 public void notifyDisplayEventAsync(int displayId, int event) {
1071 try {
1072 mCallback.onDisplayEvent(displayId, event);
1073 } catch (RemoteException ex) {
1074 Slog.w(TAG, "Failed to notify process "
1075 + mPid + " that displays changed, assuming it died.", ex);
1076 binderDied();
1077 }
1078 }
1079 }
Jeff Brownfa25bf52012-07-23 19:26:30 -07001080}