blob: e65637f049752df75d789d763a10a7d6ccdc422a [file] [log] [blame]
Jeff Brownbd6e1502012-08-28 03:27:37 -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 Browncbad9762012-09-04 21:57:59 -070019import com.android.internal.util.DumpUtils;
20import com.android.internal.util.IndentingPrintWriter;
21
Jeff Brownbd6e1502012-08-28 03:27:37 -070022import android.content.Context;
23import android.database.ContentObserver;
Craig Mautnerd5523dc2012-10-02 13:49:22 -070024import android.graphics.SurfaceTexture;
Jeff Brown4ed8fe72012-08-30 18:18:29 -070025import android.os.Handler;
Jeff Brownbd6e1502012-08-28 03:27:37 -070026import android.os.IBinder;
27import android.provider.Settings;
28import android.util.DisplayMetrics;
29import android.util.Slog;
Jeff Brown92130f62012-10-24 21:28:33 -070030import android.view.Display;
Jeff Brownbd6e1502012-08-28 03:27:37 -070031import android.view.Gravity;
Jeff Brownbd6e1502012-08-28 03:27:37 -070032import android.view.Surface;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080033import android.view.SurfaceControl;
Jeff Brownbd6e1502012-08-28 03:27:37 -070034
35import java.io.PrintWriter;
36import java.util.ArrayList;
P.Y. Laligand10188812015-05-06 14:50:52 -070037import java.util.Arrays;
38import java.util.List;
Jeff Brownbd6e1502012-08-28 03:27:37 -070039import java.util.regex.Matcher;
40import java.util.regex.Pattern;
41
42/**
43 * A display adapter that uses overlay windows to simulate secondary displays
44 * for development purposes. Use Development Settings to enable one or more
45 * overlay displays.
46 * <p>
Jeff Brown4ed8fe72012-08-30 18:18:29 -070047 * This object has two different handlers (which may be the same) which must not
48 * get confused. The main handler is used to posting messages to the display manager
49 * service as usual. The UI handler is only used by the {@link OverlayDisplayWindow}.
50 * </p><p>
51 * Display adapters are guarded by the {@link DisplayManagerService.SyncRoot} lock.
P.Y. Laligand10188812015-05-06 14:50:52 -070052 * </p><p>
53 * This adapter is configured via the
54 * {@link android.provider.Settings.Global#OVERLAY_DISPLAY_DEVICES} setting. This setting should be
55 * formatted as follows:
56 * <pre>
57 * [mode1]|[mode2]|...,[flag1],[flag2],...
58 * </pre>
59 * with each mode specified as:
60 * <pre>
61 * [width]x[height]/[densityDpi]
62 * </pre>
63 * Supported flags:
64 * <ul>
65 * <li><pre>secure</pre>: creates a secure display</li>
66 * </ul>
Jeff Brownbd6e1502012-08-28 03:27:37 -070067 * </p>
68 */
Jeff Brown4ed8fe72012-08-30 18:18:29 -070069final class OverlayDisplayAdapter extends DisplayAdapter {
70 static final String TAG = "OverlayDisplayAdapter";
71 static final boolean DEBUG = false;
Jeff Brownbd6e1502012-08-28 03:27:37 -070072
73 private static final int MIN_WIDTH = 100;
74 private static final int MIN_HEIGHT = 100;
75 private static final int MAX_WIDTH = 4096;
76 private static final int MAX_HEIGHT = 4096;
77
P.Y. Laligand10188812015-05-06 14:50:52 -070078 private static final Pattern DISPLAY_PATTERN =
79 Pattern.compile("([^,]+)(,[a-z]+)*");
80 private static final Pattern MODE_PATTERN =
81 Pattern.compile("(\\d+)x(\\d+)/(\\d+)");
Jeff Brownbd6e1502012-08-28 03:27:37 -070082
Wale Ogunwale361ca212014-11-20 11:42:38 -080083 // Unique id prefix for overlay displays.
84 private static final String UNIQUE_ID_PREFIX = "overlay:";
85
Jeff Brown4ed8fe72012-08-30 18:18:29 -070086 private final Handler mUiHandler;
87 private final ArrayList<OverlayDisplayHandle> mOverlays =
88 new ArrayList<OverlayDisplayHandle>();
Jeff Brownbd6e1502012-08-28 03:27:37 -070089 private String mCurrentOverlaySetting = "";
90
Jeff Brown66692502012-10-18 16:13:44 -070091 // Called with SyncRoot lock held.
Jeff Brown4ed8fe72012-08-30 18:18:29 -070092 public OverlayDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
93 Context context, Handler handler, Listener listener, Handler uiHandler) {
94 super(syncRoot, context, handler, listener, TAG);
95 mUiHandler = uiHandler;
Jeff Brownbd6e1502012-08-28 03:27:37 -070096 }
97
98 @Override
Jeff Brown4ed8fe72012-08-30 18:18:29 -070099 public void dumpLocked(PrintWriter pw) {
100 super.dumpLocked(pw);
Jeff Browncbad9762012-09-04 21:57:59 -0700101
Jeff Brownbd6e1502012-08-28 03:27:37 -0700102 pw.println("mCurrentOverlaySetting=" + mCurrentOverlaySetting);
103 pw.println("mOverlays: size=" + mOverlays.size());
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700104 for (OverlayDisplayHandle overlay : mOverlays) {
105 overlay.dumpLocked(pw);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700106 }
107 }
108
109 @Override
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700110 public void registerLocked() {
111 super.registerLocked();
Jeff Browncbad9762012-09-04 21:57:59 -0700112
113 getHandler().post(new Runnable() {
114 @Override
115 public void run() {
116 getContext().getContentResolver().registerContentObserver(
Jeff Brownd4935962012-09-25 13:27:20 -0700117 Settings.Global.getUriFor(Settings.Global.OVERLAY_DISPLAY_DEVICES),
118 true, new ContentObserver(getHandler()) {
119 @Override
120 public void onChange(boolean selfChange) {
121 updateOverlayDisplayDevices();
122 }
123 });
Jeff Browncbad9762012-09-04 21:57:59 -0700124
Jeff Brownd4935962012-09-25 13:27:20 -0700125 updateOverlayDisplayDevices();
Jeff Browncbad9762012-09-04 21:57:59 -0700126 }
127 });
Jeff Brownbd6e1502012-08-28 03:27:37 -0700128 }
129
Jeff Brownd4935962012-09-25 13:27:20 -0700130 private void updateOverlayDisplayDevices() {
131 synchronized (getSyncRoot()) {
132 updateOverlayDisplayDevicesLocked();
133 }
134 }
135
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700136 private void updateOverlayDisplayDevicesLocked() {
Jeff Brownd4935962012-09-25 13:27:20 -0700137 String value = Settings.Global.getString(getContext().getContentResolver(),
138 Settings.Global.OVERLAY_DISPLAY_DEVICES);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700139 if (value == null) {
140 value = "";
141 }
142
143 if (value.equals(mCurrentOverlaySetting)) {
144 return;
145 }
146 mCurrentOverlaySetting = value;
147
148 if (!mOverlays.isEmpty()) {
149 Slog.i(TAG, "Dismissing all overlay display devices.");
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700150 for (OverlayDisplayHandle overlay : mOverlays) {
151 overlay.dismissLocked();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700152 }
153 mOverlays.clear();
154 }
155
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700156 int count = 0;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700157 for (String part : value.split(";")) {
P.Y. Laligand10188812015-05-06 14:50:52 -0700158 Matcher displayMatcher = DISPLAY_PATTERN.matcher(part);
159 if (displayMatcher.matches()) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700160 if (count >= 4) {
161 Slog.w(TAG, "Too many overlay display devices specified: " + value);
162 break;
163 }
P.Y. Laligand10188812015-05-06 14:50:52 -0700164 String modeString = displayMatcher.group(1);
165 String flagString = displayMatcher.group(2);
166 ArrayList<OverlayMode> modes = new ArrayList<>();
167 for (String mode : modeString.split("\\|")) {
168 Matcher modeMatcher = MODE_PATTERN.matcher(mode);
169 if (modeMatcher.matches()) {
170 try {
171 int width = Integer.parseInt(modeMatcher.group(1), 10);
172 int height = Integer.parseInt(modeMatcher.group(2), 10);
173 int densityDpi = Integer.parseInt(modeMatcher.group(3), 10);
174 if (width >= MIN_WIDTH && width <= MAX_WIDTH
175 && height >= MIN_HEIGHT && height <= MAX_HEIGHT
176 && densityDpi >= DisplayMetrics.DENSITY_LOW
Jeff Brownfe4ad332015-06-09 18:26:31 -0700177 && densityDpi <= DisplayMetrics.DENSITY_XXXHIGH) {
P.Y. Laligand10188812015-05-06 14:50:52 -0700178 modes.add(new OverlayMode(width, height, densityDpi));
179 continue;
Jeff Brownfe4ad332015-06-09 18:26:31 -0700180 } else {
181 Slog.w(TAG, "Ignoring out-of-range overlay display mode: " + mode);
P.Y. Laligand10188812015-05-06 14:50:52 -0700182 }
183 } catch (NumberFormatException ex) {
184 }
185 } else if (mode.isEmpty()) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700186 continue;
187 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700188 }
P.Y. Laligand10188812015-05-06 14:50:52 -0700189 if (!modes.isEmpty()) {
190 int number = ++count;
191 String name = getContext().getResources().getString(
192 com.android.internal.R.string.display_manager_overlay_display_name,
193 number);
194 int gravity = chooseOverlayGravity(number);
195 boolean secure = flagString != null && flagString.contains(",secure");
196
197 Slog.i(TAG, "Showing overlay display device #" + number
198 + ": name=" + name + ", modes=" + Arrays.toString(modes.toArray()));
199
200 mOverlays.add(new OverlayDisplayHandle(name, modes, gravity, secure, number));
201 continue;
202 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700203 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700204 Slog.w(TAG, "Malformed overlay display devices setting: " + value);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700205 }
206 }
207
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700208 private static int chooseOverlayGravity(int overlayNumber) {
209 switch (overlayNumber) {
210 case 1:
211 return Gravity.TOP | Gravity.LEFT;
212 case 2:
213 return Gravity.BOTTOM | Gravity.RIGHT;
214 case 3:
215 return Gravity.TOP | Gravity.RIGHT;
216 case 4:
217 default:
218 return Gravity.BOTTOM | Gravity.LEFT;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700219 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700220 }
221
P.Y. Laligand10188812015-05-06 14:50:52 -0700222 private abstract class OverlayDisplayDevice extends DisplayDevice {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700223 private final String mName;
224 private final float mRefreshRate;
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700225 private final long mDisplayPresentationDeadlineNanos;
Jeff Brown040f44d2013-08-02 18:14:46 -0700226 private final boolean mSecure;
P.Y. Laligand10188812015-05-06 14:50:52 -0700227 private final List<OverlayMode> mRawModes;
228 private final Display.Mode[] mModes;
229 private final int mDefaultMode;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700230
Jeff Brown037c33e2014-04-09 00:31:55 -0700231 private int mState;
Craig Mautnerd5523dc2012-10-02 13:49:22 -0700232 private SurfaceTexture mSurfaceTexture;
Jeff Brown037c33e2014-04-09 00:31:55 -0700233 private Surface mSurface;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700234 private DisplayDeviceInfo mInfo;
P.Y. Laligand10188812015-05-06 14:50:52 -0700235 private int mActiveMode;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700236
237 public OverlayDisplayDevice(IBinder displayToken, String name,
P.Y. Laligand10188812015-05-06 14:50:52 -0700238 List<OverlayMode> modes, int activeMode, int defaultMode,
239 float refreshRate, long presentationDeadlineNanos,
240 boolean secure, int state,
Wale Ogunwale361ca212014-11-20 11:42:38 -0800241 SurfaceTexture surfaceTexture, int number) {
242 super(OverlayDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + number);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700243 mName = name;
244 mRefreshRate = refreshRate;
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700245 mDisplayPresentationDeadlineNanos = presentationDeadlineNanos;
Jeff Brown040f44d2013-08-02 18:14:46 -0700246 mSecure = secure;
Jeff Brown037c33e2014-04-09 00:31:55 -0700247 mState = state;
Craig Mautnerd5523dc2012-10-02 13:49:22 -0700248 mSurfaceTexture = surfaceTexture;
P.Y. Laligand10188812015-05-06 14:50:52 -0700249 mRawModes = modes;
250 mModes = new Display.Mode[modes.size()];
251 for (int i = 0; i < modes.size(); i++) {
252 OverlayMode mode = modes.get(i);
253 mModes[i] = createMode(mode.mWidth, mode.mHeight, refreshRate);
254 }
255 mActiveMode = activeMode;
256 mDefaultMode = defaultMode;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700257 }
258
Jesse Hall6a6bc212013-08-08 12:15:03 -0700259 public void destroyLocked() {
260 mSurfaceTexture = null;
261 if (mSurface != null) {
262 mSurface.release();
263 mSurface = null;
Craig Mautnerd5523dc2012-10-02 13:49:22 -0700264 }
Jesse Hall6a6bc212013-08-08 12:15:03 -0700265 SurfaceControl.destroyDisplay(getDisplayTokenLocked());
Jeff Brownbd6e1502012-08-28 03:27:37 -0700266 }
267
268 @Override
Michael Wright1c9977b2016-07-12 13:30:10 -0700269 public boolean hasStableUniqueId() {
270 return false;
271 }
272
273 @Override
Robert Carrae606b42018-02-15 15:36:23 -0800274 public void performTraversalLocked(SurfaceControl.Transaction t) {
Craig Mautnerd5523dc2012-10-02 13:49:22 -0700275 if (mSurfaceTexture != null) {
276 if (mSurface == null) {
277 mSurface = new Surface(mSurfaceTexture);
278 }
Robert Carrae606b42018-02-15 15:36:23 -0800279 setSurfaceLocked(t, mSurface);
Craig Mautnerd5523dc2012-10-02 13:49:22 -0700280 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700281 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700282
Jeff Brown037c33e2014-04-09 00:31:55 -0700283 public void setStateLocked(int state) {
284 mState = state;
285 mInfo = null;
286 }
287
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700288 @Override
289 public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
290 if (mInfo == null) {
P.Y. Laligand10188812015-05-06 14:50:52 -0700291 Display.Mode mode = mModes[mActiveMode];
292 OverlayMode rawMode = mRawModes.get(mActiveMode);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700293 mInfo = new DisplayDeviceInfo();
294 mInfo.name = mName;
Wale Ogunwale361ca212014-11-20 11:42:38 -0800295 mInfo.uniqueId = getUniqueId();
P.Y. Laligand10188812015-05-06 14:50:52 -0700296 mInfo.width = mode.getPhysicalWidth();
297 mInfo.height = mode.getPhysicalHeight();
298 mInfo.modeId = mode.getModeId();
299 mInfo.defaultModeId = mModes[0].getModeId();
300 mInfo.supportedModes = mModes;
301 mInfo.densityDpi = rawMode.mDensityDpi;
302 mInfo.xDpi = rawMode.mDensityDpi;
303 mInfo.yDpi = rawMode.mDensityDpi;
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700304 mInfo.presentationDeadlineNanos = mDisplayPresentationDeadlineNanos +
305 1000000000L / (int) mRefreshRate; // display's deadline + 1 frame
Jeff Brown7d00aff2013-08-02 19:03:49 -0700306 mInfo.flags = DisplayDeviceInfo.FLAG_PRESENTATION;
Jeff Brown040f44d2013-08-02 18:14:46 -0700307 if (mSecure) {
308 mInfo.flags |= DisplayDeviceInfo.FLAG_SECURE;
309 }
Jeff Brown92130f62012-10-24 21:28:33 -0700310 mInfo.type = Display.TYPE_OVERLAY;
Jeff Brownd728bf52012-09-08 18:05:28 -0700311 mInfo.touch = DisplayDeviceInfo.TOUCH_NONE;
Jeff Brown037c33e2014-04-09 00:31:55 -0700312 mInfo.state = mState;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700313 }
314 return mInfo;
315 }
P.Y. Laligand10188812015-05-06 14:50:52 -0700316
317 @Override
Robert Carrae606b42018-02-15 15:36:23 -0800318 public void requestDisplayModesLocked(int color, int id) {
P.Y. Laligand10188812015-05-06 14:50:52 -0700319 int index = -1;
320 if (id == 0) {
321 // Use the default.
322 index = 0;
323 } else {
324 for (int i = 0; i < mModes.length; i++) {
325 if (mModes[i].getModeId() == id) {
326 index = i;
327 break;
328 }
329 }
330 }
331 if (index == -1) {
332 Slog.w(TAG, "Unable to locate mode " + id + ", reverting to default.");
333 index = mDefaultMode;
334 }
335 if (mActiveMode == index) {
336 return;
337 }
338 mActiveMode = index;
339 mInfo = null;
340 sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED);
341 onModeChangedLocked(index);
342 }
343
344 /**
345 * Called when the device switched to a new mode.
346 *
347 * @param index index of the mode in the list of modes
348 */
349 public abstract void onModeChangedLocked(int index);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700350 }
351
352 /**
353 * Functions as a handle for overlay display devices which are created and
354 * destroyed asynchronously.
355 *
356 * Guarded by the {@link DisplayManagerService.SyncRoot} lock.
357 */
358 private final class OverlayDisplayHandle implements OverlayDisplayWindow.Listener {
P.Y. Laligand10188812015-05-06 14:50:52 -0700359 private static final int DEFAULT_MODE_INDEX = 0;
360
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700361 private final String mName;
P.Y. Laligand10188812015-05-06 14:50:52 -0700362 private final List<OverlayMode> mModes;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700363 private final int mGravity;
Jeff Brown040f44d2013-08-02 18:14:46 -0700364 private final boolean mSecure;
Wale Ogunwale361ca212014-11-20 11:42:38 -0800365 private final int mNumber;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700366
367 private OverlayDisplayWindow mWindow;
368 private OverlayDisplayDevice mDevice;
P.Y. Laligand10188812015-05-06 14:50:52 -0700369 private int mActiveMode;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700370
P.Y. Laligand10188812015-05-06 14:50:52 -0700371 public OverlayDisplayHandle(String name, List<OverlayMode> modes, int gravity,
372 boolean secure, int number) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700373 mName = name;
P.Y. Laligand10188812015-05-06 14:50:52 -0700374 mModes = modes;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700375 mGravity = gravity;
Jeff Brown040f44d2013-08-02 18:14:46 -0700376 mSecure = secure;
Wale Ogunwale361ca212014-11-20 11:42:38 -0800377 mNumber = number;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700378
P.Y. Laligand10188812015-05-06 14:50:52 -0700379 mActiveMode = 0;
380
381 showLocked();
382 }
383
384 private void showLocked() {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700385 mUiHandler.post(mShowRunnable);
386 }
387
388 public void dismissLocked() {
389 mUiHandler.removeCallbacks(mShowRunnable);
390 mUiHandler.post(mDismissRunnable);
391 }
392
P.Y. Laligand10188812015-05-06 14:50:52 -0700393 private void onActiveModeChangedLocked(int index) {
394 mUiHandler.removeCallbacks(mResizeRunnable);
395 mActiveMode = index;
396 if (mWindow != null) {
397 mUiHandler.post(mResizeRunnable);
398 }
399 }
400
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700401 // Called on the UI thread.
402 @Override
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700403 public void onWindowCreated(SurfaceTexture surfaceTexture, float refreshRate,
404 long presentationDeadlineNanos, int state) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700405 synchronized (getSyncRoot()) {
Jeff Brown040f44d2013-08-02 18:14:46 -0700406 IBinder displayToken = SurfaceControl.createDisplay(mName, mSecure);
P.Y. Laligand10188812015-05-06 14:50:52 -0700407 mDevice = new OverlayDisplayDevice(displayToken, mName, mModes, mActiveMode,
408 DEFAULT_MODE_INDEX, refreshRate, presentationDeadlineNanos,
409 mSecure, state, surfaceTexture, mNumber) {
410 @Override
411 public void onModeChangedLocked(int index) {
412 onActiveModeChangedLocked(index);
413 }
414 };
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700415
416 sendDisplayDeviceEventLocked(mDevice, DISPLAY_DEVICE_EVENT_ADDED);
417 }
418 }
419
420 // Called on the UI thread.
421 @Override
422 public void onWindowDestroyed() {
423 synchronized (getSyncRoot()) {
424 if (mDevice != null) {
Jesse Hall6a6bc212013-08-08 12:15:03 -0700425 mDevice.destroyLocked();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700426 sendDisplayDeviceEventLocked(mDevice, DISPLAY_DEVICE_EVENT_REMOVED);
427 }
428 }
429 }
430
Jeff Brown037c33e2014-04-09 00:31:55 -0700431 // Called on the UI thread.
432 @Override
433 public void onStateChanged(int state) {
434 synchronized (getSyncRoot()) {
435 if (mDevice != null) {
436 mDevice.setStateLocked(state);
437 sendDisplayDeviceEventLocked(mDevice, DISPLAY_DEVICE_EVENT_CHANGED);
438 }
439 }
440 }
441
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700442 public void dumpLocked(PrintWriter pw) {
Jeff Browncbad9762012-09-04 21:57:59 -0700443 pw.println(" " + mName + ":");
P.Y. Laligand10188812015-05-06 14:50:52 -0700444 pw.println(" mModes=" + Arrays.toString(mModes.toArray()));
445 pw.println(" mActiveMode=" + mActiveMode);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700446 pw.println(" mGravity=" + mGravity);
Jeff Brown040f44d2013-08-02 18:14:46 -0700447 pw.println(" mSecure=" + mSecure);
Wale Ogunwale361ca212014-11-20 11:42:38 -0800448 pw.println(" mNumber=" + mNumber);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700449
450 // Try to dump the window state.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700451 if (mWindow != null) {
Jeff Browncbad9762012-09-04 21:57:59 -0700452 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
453 ipw.increaseIndent();
Dianne Hackbornae6688b2015-02-11 17:02:41 -0800454 DumpUtils.dumpAsync(mUiHandler, mWindow, ipw, "", 200);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700455 }
456 }
457
458 // Runs on the UI thread.
459 private final Runnable mShowRunnable = new Runnable() {
460 @Override
461 public void run() {
P.Y. Laligand10188812015-05-06 14:50:52 -0700462 OverlayMode mode = mModes.get(mActiveMode);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700463 OverlayDisplayWindow window = new OverlayDisplayWindow(getContext(),
P.Y. Laligand10188812015-05-06 14:50:52 -0700464 mName, mode.mWidth, mode.mHeight, mode.mDensityDpi, mGravity, mSecure,
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700465 OverlayDisplayHandle.this);
466 window.show();
467
468 synchronized (getSyncRoot()) {
469 mWindow = window;
470 }
471 }
472 };
473
474 // Runs on the UI thread.
475 private final Runnable mDismissRunnable = new Runnable() {
476 @Override
477 public void run() {
478 OverlayDisplayWindow window;
479 synchronized (getSyncRoot()) {
480 window = mWindow;
481 mWindow = null;
482 }
483
484 if (window != null) {
485 window.dismiss();
486 }
487 }
488 };
P.Y. Laligand10188812015-05-06 14:50:52 -0700489
490 // Runs on the UI thread.
491 private final Runnable mResizeRunnable = new Runnable() {
492 @Override
493 public void run() {
494 OverlayMode mode;
495 OverlayDisplayWindow window;
496 synchronized (getSyncRoot()) {
497 if (mWindow == null) {
498 return;
499 }
500 mode = mModes.get(mActiveMode);
501 window = mWindow;
502 }
503 window.resize(mode.mWidth, mode.mHeight, mode.mDensityDpi);
504 }
505 };
506 }
507
508 /**
509 * A display mode for an overlay display.
510 */
511 private static final class OverlayMode {
512 final int mWidth;
513 final int mHeight;
514 final int mDensityDpi;
515
516 OverlayMode(int width, int height, int densityDpi) {
517 mWidth = width;
518 mHeight = height;
519 mDensityDpi = densityDpi;
520 }
521
522 @Override
523 public String toString() {
524 return new StringBuilder("{")
525 .append("width=").append(mWidth)
526 .append(", height=").append(mHeight)
527 .append(", densityDpi=").append(mDensityDpi)
528 .append("}")
529 .toString();
530 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700531 }
532}