OverlayDisplayAdapter.java revision d5523dc7b7318f2774109dd30716ff7b74560e61
1bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown/*
2bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * Copyright (C) 2012 The Android Open Source Project
3bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown *
4bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
5bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * you may not use this file except in compliance with the License.
6bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * You may obtain a copy of the License at
7bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown *
8bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
9bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown *
10bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * Unless required by applicable law or agreed to in writing, software
11bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
12bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * See the License for the specific language governing permissions and
14bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * limitations under the License.
15bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown */
16bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
17bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownpackage com.android.server.display;
18bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
19cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brownimport com.android.internal.util.DumpUtils;
20cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brownimport com.android.internal.util.IndentingPrintWriter;
21cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
22bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.content.Context;
23bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.database.ContentObserver;
24d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautnerimport android.graphics.SurfaceTexture;
254ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.os.Handler;
26bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.os.IBinder;
27bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.provider.Settings;
28bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.util.DisplayMetrics;
29bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.util.Slog;
30bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.view.Gravity;
31bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.view.Surface;
32bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
33bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport java.io.PrintWriter;
34bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport java.util.ArrayList;
35bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport java.util.regex.Matcher;
36bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport java.util.regex.Pattern;
37bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
38bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown/**
39bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * A display adapter that uses overlay windows to simulate secondary displays
40bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * for development purposes.  Use Development Settings to enable one or more
41bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * overlay displays.
42bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * <p>
434ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * This object has two different handlers (which may be the same) which must not
444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * get confused.  The main handler is used to posting messages to the display manager
454ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * service as usual.  The UI handler is only used by the {@link OverlayDisplayWindow}.
464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * </p><p>
474ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * Display adapters are guarded by the {@link DisplayManagerService.SyncRoot} lock.
48bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * </p>
49bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown */
504ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownfinal class OverlayDisplayAdapter extends DisplayAdapter {
514ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    static final String TAG = "OverlayDisplayAdapter";
524ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    static final boolean DEBUG = false;
53bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
54bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final int MIN_WIDTH = 100;
55bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final int MIN_HEIGHT = 100;
56bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final int MAX_WIDTH = 4096;
57bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final int MAX_HEIGHT = 4096;
58bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
59bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final Pattern SETTING_PATTERN =
60bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            Pattern.compile("(\\d+)x(\\d+)/(\\d+)");
61bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
624ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private final Handler mUiHandler;
634ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private final ArrayList<OverlayDisplayHandle> mOverlays =
644ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            new ArrayList<OverlayDisplayHandle>();
65bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private String mCurrentOverlaySetting = "";
66bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
674ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public OverlayDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
684ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            Context context, Handler handler, Listener listener, Handler uiHandler) {
694ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        super(syncRoot, context, handler, listener, TAG);
704ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        mUiHandler = uiHandler;
71bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
72bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
73bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    @Override
744ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public void dumpLocked(PrintWriter pw) {
754ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        super.dumpLocked(pw);
76cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
77bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        pw.println("mCurrentOverlaySetting=" + mCurrentOverlaySetting);
78bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        pw.println("mOverlays: size=" + mOverlays.size());
794ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        for (OverlayDisplayHandle overlay : mOverlays) {
804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            overlay.dumpLocked(pw);
81bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
82bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
83bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
84bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    @Override
854ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public void registerLocked() {
864ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        super.registerLocked();
87cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
88cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        getHandler().post(new Runnable() {
89cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            @Override
90cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            public void run() {
91cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown                getContext().getContentResolver().registerContentObserver(
92d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown                        Settings.Global.getUriFor(Settings.Global.OVERLAY_DISPLAY_DEVICES),
93d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown                        true, new ContentObserver(getHandler()) {
94d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown                            @Override
95d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown                            public void onChange(boolean selfChange) {
96d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown                                updateOverlayDisplayDevices();
97d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown                            }
98d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown                        });
99d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown
100d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown                updateOverlayDisplayDevices();
101cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            }
102cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        });
103bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
104bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
105d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown    private void updateOverlayDisplayDevices() {
106d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown        synchronized (getSyncRoot()) {
107d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown            updateOverlayDisplayDevicesLocked();
108d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown        }
109d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown    }
110d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown
1114ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private void updateOverlayDisplayDevicesLocked() {
112d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown        String value = Settings.Global.getString(getContext().getContentResolver(),
113d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown                Settings.Global.OVERLAY_DISPLAY_DEVICES);
114bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        if (value == null) {
115bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            value = "";
116bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
117bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
118bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        if (value.equals(mCurrentOverlaySetting)) {
119bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            return;
120bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
121bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        mCurrentOverlaySetting = value;
122bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
123bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        if (!mOverlays.isEmpty()) {
124bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            Slog.i(TAG, "Dismissing all overlay display devices.");
1254ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            for (OverlayDisplayHandle overlay : mOverlays) {
1264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                overlay.dismissLocked();
127bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
128bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mOverlays.clear();
129bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
130bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        int count = 0;
132bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        for (String part : value.split(";")) {
133bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            Matcher matcher = SETTING_PATTERN.matcher(part);
134bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            if (matcher.matches()) {
1354ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                if (count >= 4) {
1364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    Slog.w(TAG, "Too many overlay display devices specified: " + value);
1374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    break;
1384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                }
139bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                try {
140bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    int width = Integer.parseInt(matcher.group(1), 10);
141bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    int height = Integer.parseInt(matcher.group(2), 10);
142bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    int densityDpi = Integer.parseInt(matcher.group(3), 10);
143bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    if (width >= MIN_WIDTH && width <= MAX_WIDTH
144bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                            && height >= MIN_HEIGHT && height <= MAX_HEIGHT
145bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                            && densityDpi >= DisplayMetrics.DENSITY_LOW
146bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                            && densityDpi <= DisplayMetrics.DENSITY_XXHIGH) {
1474ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                        int number = ++count;
1484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                        String name = getContext().getResources().getString(
1494ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                                com.android.internal.R.string.display_manager_overlay_display_name,
1504ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                                number);
1514ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                        int gravity = chooseOverlayGravity(number);
1524ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
153bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                        Slog.i(TAG, "Showing overlay display device #" + number
1544ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                                + ": name=" + name + ", width=" + width + ", height=" + height
155bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                                + ", densityDpi=" + densityDpi);
1564ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
1574ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                        mOverlays.add(new OverlayDisplayHandle(name,
1584ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                                width, height, densityDpi, gravity));
159bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                        continue;
160bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    }
161bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                } catch (NumberFormatException ex) {
162bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                }
163bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            } else if (part.isEmpty()) {
164bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                continue;
165bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
1664ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            Slog.w(TAG, "Malformed overlay display devices setting: " + value);
167bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
1684ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
169bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1704ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private static int chooseOverlayGravity(int overlayNumber) {
1714ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        switch (overlayNumber) {
1724ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            case 1:
1734ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                return Gravity.TOP | Gravity.LEFT;
1744ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            case 2:
1754ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                return Gravity.BOTTOM | Gravity.RIGHT;
1764ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            case 3:
1774ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                return Gravity.TOP | Gravity.RIGHT;
1784ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            case 4:
1794ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            default:
1804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                return Gravity.BOTTOM | Gravity.LEFT;
181bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
182bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
183bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1844ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private final class OverlayDisplayDevice extends DisplayDevice {
1854ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private final String mName;
186bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final int mWidth;
187bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final int mHeight;
1884ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private final float mRefreshRate;
189bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final int mDensityDpi;
190bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
191cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        private Surface mSurface;
192d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner        private SurfaceTexture mSurfaceTexture;
1934ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private DisplayDeviceInfo mInfo;
1944ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
1954ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        public OverlayDisplayDevice(IBinder displayToken, String name,
196cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown                int width, int height, float refreshRate, int densityDpi,
197d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner                SurfaceTexture surfaceTexture) {
1984ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            super(OverlayDisplayAdapter.this, displayToken);
1994ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mName = name;
200bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mWidth = width;
201bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mHeight = height;
2024ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mRefreshRate = refreshRate;
203bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mDensityDpi = densityDpi;
204d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner            mSurfaceTexture = surfaceTexture;
205bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
206bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
207d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner        public void clearSurfaceTextureLocked() {
208d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner            if (mSurfaceTexture != null) {
209d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner                mSurfaceTexture = null;
210d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner            }
211cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            sendTraversalRequestLocked();
212bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
213bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
2144ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        @Override
2154ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        public void performTraversalInTransactionLocked() {
216d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner            if (mSurfaceTexture != null) {
217d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner                if (mSurface == null) {
218d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner                    mSurface = new Surface(mSurfaceTexture);
219d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner                }
220d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner                setSurfaceInTransactionLocked(mSurface);
221d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner            } else {
222d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner                setSurfaceInTransactionLocked(null);
223d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner                if (mSurface != null) {
224d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner                    mSurface.destroy();
225d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner                    mSurface = null;
226d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner                }
227d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner            }
228bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
229bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
2304ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        @Override
2314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
2324ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            if (mInfo == null) {
2334ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                mInfo = new DisplayDeviceInfo();
2344ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                mInfo.name = mName;
2354ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                mInfo.width = mWidth;
2364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                mInfo.height = mHeight;
2374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                mInfo.refreshRate = mRefreshRate;
2384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                mInfo.densityDpi = mDensityDpi;
2394ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                mInfo.xDpi = mDensityDpi;
2404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                mInfo.yDpi = mDensityDpi;
241c5df37c285221d0fb113f55b9e78b35632241d3fJeff Brown                mInfo.flags = DisplayDeviceInfo.FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT;
242d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                mInfo.touch = DisplayDeviceInfo.TOUCH_NONE;
243bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
2444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            return mInfo;
245bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
2464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
247bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
2484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    /**
2494ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * Functions as a handle for overlay display devices which are created and
2504ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * destroyed asynchronously.
2514ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     *
2524ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * Guarded by the {@link DisplayManagerService.SyncRoot} lock.
2534ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     */
2544ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private final class OverlayDisplayHandle implements OverlayDisplayWindow.Listener {
2554ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private final String mName;
2564ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private final int mWidth;
2574ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private final int mHeight;
2584ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private final int mDensityDpi;
2594ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private final int mGravity;
260d0dd63dcaed8f63009c03907f38269feb798f305Jeff Brown
2614ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private OverlayDisplayWindow mWindow;
2624ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private OverlayDisplayDevice mDevice;
263bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
2644ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        public OverlayDisplayHandle(String name,
2654ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                int width, int height, int densityDpi, int gravity) {
2664ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mName = name;
2674ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mWidth = width;
2684ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mHeight = height;
2694ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mDensityDpi = densityDpi;
2704ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mGravity = gravity;
271bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
2724ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mUiHandler.post(mShowRunnable);
273bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
274bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
2754ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        public void dismissLocked() {
2764ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mUiHandler.removeCallbacks(mShowRunnable);
2774ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mUiHandler.post(mDismissRunnable);
278bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
279bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
2804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Called on the UI thread.
2814ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        @Override
282d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner        public void onWindowCreated(SurfaceTexture surfaceTexture, float refreshRate) {
2834ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            synchronized (getSyncRoot()) {
2844ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                IBinder displayToken = Surface.createDisplay(mName);
2854ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                mDevice = new OverlayDisplayDevice(displayToken, mName,
286d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner                        mWidth, mHeight, refreshRate, mDensityDpi, surfaceTexture);
2874ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
2884ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                sendDisplayDeviceEventLocked(mDevice, DISPLAY_DEVICE_EVENT_ADDED);
289bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
2904ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
291bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
2924ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Called on the UI thread.
2934ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        @Override
2944ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        public void onWindowDestroyed() {
2954ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            synchronized (getSyncRoot()) {
2964ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                if (mDevice != null) {
297d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner                    mDevice.clearSurfaceTextureLocked();
2984ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    sendDisplayDeviceEventLocked(mDevice, DISPLAY_DEVICE_EVENT_REMOVED);
299bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                }
300bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
3014ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
302bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
3034ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        public void dumpLocked(PrintWriter pw) {
304cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            pw.println("  " + mName + ":");
3054ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            pw.println("    mWidth=" + mWidth);
3064ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            pw.println("    mHeight=" + mHeight);
3074ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            pw.println("    mDensityDpi=" + mDensityDpi);
3084ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            pw.println("    mGravity=" + mGravity);
3094ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
3104ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            // Try to dump the window state.
3114ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            if (mWindow != null) {
312cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "    ");
313cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown                ipw.increaseIndent();
314cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown                DumpUtils.dumpAsync(mUiHandler, mWindow, ipw, 200);
315bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
3164ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
317bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
3184ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Runs on the UI thread.
3194ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private final Runnable mShowRunnable = new Runnable() {
320bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            @Override
3214ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            public void run() {
3224ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                OverlayDisplayWindow window = new OverlayDisplayWindow(getContext(),
3234ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                        mName, mWidth, mHeight, mDensityDpi, mGravity,
3244ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                        OverlayDisplayHandle.this);
3254ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                window.show();
3264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
3274ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                synchronized (getSyncRoot()) {
3284ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    mWindow = window;
329bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                }
330bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
331bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        };
332bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
3334ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Runs on the UI thread.
3344ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private final Runnable mDismissRunnable = new Runnable() {
335bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            @Override
3364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            public void run() {
3374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                OverlayDisplayWindow window;
3384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                synchronized (getSyncRoot()) {
3394ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    window = mWindow;
3404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    mWindow = null;
341bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                }
342bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
3434ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                if (window != null) {
3444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    window.dismiss();
3454ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                }
346bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
347bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        };
348bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
349bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown}
350