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;
3092130f6407dc51c58b3b941d28a6daf4e04b8d62Jeff Brownimport android.view.Display;
31bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.view.Gravity;
32bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.view.Surface;
333866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopianimport android.view.SurfaceControl;
34bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
35bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport java.io.PrintWriter;
36bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport java.util.ArrayList;
37bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport java.util.regex.Matcher;
38bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport java.util.regex.Pattern;
39bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
40bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown/**
41bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * A display adapter that uses overlay windows to simulate secondary displays
42bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * for development purposes.  Use Development Settings to enable one or more
43bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * overlay displays.
44bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * <p>
454ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * This object has two different handlers (which may be the same) which must not
464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * get confused.  The main handler is used to posting messages to the display manager
474ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * service as usual.  The UI handler is only used by the {@link OverlayDisplayWindow}.
484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * </p><p>
494ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * Display adapters are guarded by the {@link DisplayManagerService.SyncRoot} lock.
50bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * </p>
51bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown */
524ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownfinal class OverlayDisplayAdapter extends DisplayAdapter {
534ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    static final String TAG = "OverlayDisplayAdapter";
544ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    static final boolean DEBUG = false;
55bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
56bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final int MIN_WIDTH = 100;
57bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final int MIN_HEIGHT = 100;
58bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final int MAX_WIDTH = 4096;
59bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final int MAX_HEIGHT = 4096;
60bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
61bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final Pattern SETTING_PATTERN =
62040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown            Pattern.compile("(\\d+)x(\\d+)/(\\d+)(,[a-z]+)*");
63bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
644ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private final Handler mUiHandler;
654ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private final ArrayList<OverlayDisplayHandle> mOverlays =
664ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            new ArrayList<OverlayDisplayHandle>();
67bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private String mCurrentOverlaySetting = "";
68bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
6966692500344cab2f53cdb6ee1545c567fff7cb16Jeff Brown    // Called with SyncRoot lock held.
704ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public OverlayDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
714ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            Context context, Handler handler, Listener listener, Handler uiHandler) {
724ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        super(syncRoot, context, handler, listener, TAG);
734ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        mUiHandler = uiHandler;
74bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
75bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
76bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    @Override
774ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public void dumpLocked(PrintWriter pw) {
784ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        super.dumpLocked(pw);
79cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
80bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        pw.println("mCurrentOverlaySetting=" + mCurrentOverlaySetting);
81bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        pw.println("mOverlays: size=" + mOverlays.size());
824ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        for (OverlayDisplayHandle overlay : mOverlays) {
834ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            overlay.dumpLocked(pw);
84bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
85bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
86bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
87bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    @Override
884ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    public void registerLocked() {
894ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        super.registerLocked();
90cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
91cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        getHandler().post(new Runnable() {
92cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            @Override
93cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            public void run() {
94cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown                getContext().getContentResolver().registerContentObserver(
95d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown                        Settings.Global.getUriFor(Settings.Global.OVERLAY_DISPLAY_DEVICES),
96d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown                        true, new ContentObserver(getHandler()) {
97d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown                            @Override
98d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown                            public void onChange(boolean selfChange) {
99d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown                                updateOverlayDisplayDevices();
100d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown                            }
101d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown                        });
102d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown
103d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown                updateOverlayDisplayDevices();
104cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            }
105cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        });
106bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
107bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
108d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown    private void updateOverlayDisplayDevices() {
109d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown        synchronized (getSyncRoot()) {
110d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown            updateOverlayDisplayDevicesLocked();
111d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown        }
112d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown    }
113d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown
1144ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private void updateOverlayDisplayDevicesLocked() {
115d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown        String value = Settings.Global.getString(getContext().getContentResolver(),
116d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown                Settings.Global.OVERLAY_DISPLAY_DEVICES);
117bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        if (value == null) {
118bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            value = "";
119bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
120bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
121bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        if (value.equals(mCurrentOverlaySetting)) {
122bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            return;
123bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
124bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        mCurrentOverlaySetting = value;
125bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
126bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        if (!mOverlays.isEmpty()) {
127bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            Slog.i(TAG, "Dismissing all overlay display devices.");
1284ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            for (OverlayDisplayHandle overlay : mOverlays) {
1294ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                overlay.dismissLocked();
130bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
131bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mOverlays.clear();
132bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
133bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1344ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        int count = 0;
135bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        for (String part : value.split(";")) {
136bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            Matcher matcher = SETTING_PATTERN.matcher(part);
137bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            if (matcher.matches()) {
1384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                if (count >= 4) {
1394ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    Slog.w(TAG, "Too many overlay display devices specified: " + value);
1404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    break;
1414ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                }
142bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                try {
143bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    int width = Integer.parseInt(matcher.group(1), 10);
144bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    int height = Integer.parseInt(matcher.group(2), 10);
145bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    int densityDpi = Integer.parseInt(matcher.group(3), 10);
146040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown                    String flagString = matcher.group(4);
147bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    if (width >= MIN_WIDTH && width <= MAX_WIDTH
148bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                            && height >= MIN_HEIGHT && height <= MAX_HEIGHT
149bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                            && densityDpi >= DisplayMetrics.DENSITY_LOW
150bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                            && densityDpi <= DisplayMetrics.DENSITY_XXHIGH) {
1514ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                        int number = ++count;
1524ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                        String name = getContext().getResources().getString(
1534ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                                com.android.internal.R.string.display_manager_overlay_display_name,
1544ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                                number);
1554ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                        int gravity = chooseOverlayGravity(number);
156040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown                        boolean secure = flagString != null && flagString.contains(",secure");
1574ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
158bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                        Slog.i(TAG, "Showing overlay display device #" + number
1594ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                                + ": name=" + name + ", width=" + width + ", height=" + height
160040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown                                + ", densityDpi=" + densityDpi + ", secure=" + secure);
1614ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
1624ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                        mOverlays.add(new OverlayDisplayHandle(name,
163040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown                                width, height, densityDpi, gravity, secure));
164bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                        continue;
165bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    }
166bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                } catch (NumberFormatException ex) {
167bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                }
168bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            } else if (part.isEmpty()) {
169bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                continue;
170bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
1714ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            Slog.w(TAG, "Malformed overlay display devices setting: " + value);
172bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
1734ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
174bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1754ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private static int chooseOverlayGravity(int overlayNumber) {
1764ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        switch (overlayNumber) {
1774ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            case 1:
1784ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                return Gravity.TOP | Gravity.LEFT;
1794ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            case 2:
1804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                return Gravity.BOTTOM | Gravity.RIGHT;
1814ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            case 3:
1824ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                return Gravity.TOP | Gravity.RIGHT;
1834ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            case 4:
1844ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            default:
1854ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                return Gravity.BOTTOM | Gravity.LEFT;
186bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
187bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
188bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
1894ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private final class OverlayDisplayDevice extends DisplayDevice {
1904ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private final String mName;
191bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final int mWidth;
192bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final int mHeight;
1934ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private final float mRefreshRate;
194bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final int mDensityDpi;
195040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown        private final boolean mSecure;
196bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
197cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        private Surface mSurface;
198d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner        private SurfaceTexture mSurfaceTexture;
1994ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private DisplayDeviceInfo mInfo;
2004ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
2014ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        public OverlayDisplayDevice(IBinder displayToken, String name,
202040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown                int width, int height, float refreshRate, int densityDpi, boolean secure,
203d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner                SurfaceTexture surfaceTexture) {
2044ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            super(OverlayDisplayAdapter.this, displayToken);
2054ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mName = name;
206bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mWidth = width;
207bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mHeight = height;
2084ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mRefreshRate = refreshRate;
209bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mDensityDpi = densityDpi;
210040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown            mSecure = secure;
211d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner            mSurfaceTexture = surfaceTexture;
212bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
213bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
2146a6bc216d15293886ad088bb0ca99aadb7df85dcJesse Hall        public void destroyLocked() {
2156a6bc216d15293886ad088bb0ca99aadb7df85dcJesse Hall            mSurfaceTexture = null;
2166a6bc216d15293886ad088bb0ca99aadb7df85dcJesse Hall            if (mSurface != null) {
2176a6bc216d15293886ad088bb0ca99aadb7df85dcJesse Hall                mSurface.release();
2186a6bc216d15293886ad088bb0ca99aadb7df85dcJesse Hall                mSurface = null;
219d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner            }
2206a6bc216d15293886ad088bb0ca99aadb7df85dcJesse Hall            SurfaceControl.destroyDisplay(getDisplayTokenLocked());
221bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
222bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
2234ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        @Override
2244ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        public void performTraversalInTransactionLocked() {
225d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner            if (mSurfaceTexture != null) {
226d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner                if (mSurface == null) {
227d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner                    mSurface = new Surface(mSurfaceTexture);
228d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner                }
229d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner                setSurfaceInTransactionLocked(mSurface);
230d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner            }
231bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
232bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
2334ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        @Override
2344ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
2354ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            if (mInfo == null) {
2364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                mInfo = new DisplayDeviceInfo();
2374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                mInfo.name = mName;
2384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                mInfo.width = mWidth;
2394ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                mInfo.height = mHeight;
2404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                mInfo.refreshRate = mRefreshRate;
2414ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                mInfo.densityDpi = mDensityDpi;
2424ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                mInfo.xDpi = mDensityDpi;
2434ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                mInfo.yDpi = mDensityDpi;
2447d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown                mInfo.flags = DisplayDeviceInfo.FLAG_PRESENTATION;
245040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown                if (mSecure) {
246040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown                    mInfo.flags |= DisplayDeviceInfo.FLAG_SECURE;
247040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown                }
24892130f6407dc51c58b3b941d28a6daf4e04b8d62Jeff Brown                mInfo.type = Display.TYPE_OVERLAY;
249d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                mInfo.touch = DisplayDeviceInfo.TOUCH_NONE;
250bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
2514ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            return mInfo;
252bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
2534ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    }
254bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
2554ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    /**
2564ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * Functions as a handle for overlay display devices which are created and
2574ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * destroyed asynchronously.
2584ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     *
2594ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     * Guarded by the {@link DisplayManagerService.SyncRoot} lock.
2604ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown     */
2614ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown    private final class OverlayDisplayHandle implements OverlayDisplayWindow.Listener {
2624ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private final String mName;
2634ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private final int mWidth;
2644ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private final int mHeight;
2654ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private final int mDensityDpi;
2664ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private final int mGravity;
267040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown        private final boolean mSecure;
268d0dd63dcaed8f63009c03907f38269feb798f305Jeff Brown
2694ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private OverlayDisplayWindow mWindow;
2704ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private OverlayDisplayDevice mDevice;
271bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
2724ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        public OverlayDisplayHandle(String name,
273040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown                int width, int height, int densityDpi, int gravity, boolean secure) {
2744ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mName = name;
2754ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mWidth = width;
2764ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mHeight = height;
2774ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mDensityDpi = densityDpi;
2784ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mGravity = gravity;
279040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown            mSecure = secure;
280bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
2814ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mUiHandler.post(mShowRunnable);
282bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
283bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
2844ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        public void dismissLocked() {
2854ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mUiHandler.removeCallbacks(mShowRunnable);
2864ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            mUiHandler.post(mDismissRunnable);
287bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
288bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
2894ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Called on the UI thread.
2904ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        @Override
291d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner        public void onWindowCreated(SurfaceTexture surfaceTexture, float refreshRate) {
2924ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            synchronized (getSyncRoot()) {
293040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown                IBinder displayToken = SurfaceControl.createDisplay(mName, mSecure);
2944ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                mDevice = new OverlayDisplayDevice(displayToken, mName,
295040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown                        mWidth, mHeight, refreshRate, mDensityDpi, mSecure, surfaceTexture);
2964ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
2974ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                sendDisplayDeviceEventLocked(mDevice, DISPLAY_DEVICE_EVENT_ADDED);
298bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
2994ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
300bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
3014ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Called on the UI thread.
3024ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        @Override
3034ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        public void onWindowDestroyed() {
3044ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            synchronized (getSyncRoot()) {
3054ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                if (mDevice != null) {
3066a6bc216d15293886ad088bb0ca99aadb7df85dcJesse Hall                    mDevice.destroyLocked();
3074ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    sendDisplayDeviceEventLocked(mDevice, DISPLAY_DEVICE_EVENT_REMOVED);
308bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                }
309bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
3104ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
311bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
3124ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        public void dumpLocked(PrintWriter pw) {
313cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            pw.println("  " + mName + ":");
3144ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            pw.println("    mWidth=" + mWidth);
3154ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            pw.println("    mHeight=" + mHeight);
3164ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            pw.println("    mDensityDpi=" + mDensityDpi);
3174ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            pw.println("    mGravity=" + mGravity);
318040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown            pw.println("    mSecure=" + mSecure);
3194ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
3204ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            // Try to dump the window state.
3214ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            if (mWindow != null) {
322cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "    ");
323cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown                ipw.increaseIndent();
324cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown                DumpUtils.dumpAsync(mUiHandler, mWindow, ipw, 200);
325bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
3264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        }
327bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
3284ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Runs on the UI thread.
3294ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private final Runnable mShowRunnable = new Runnable() {
330bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            @Override
3314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            public void run() {
3324ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                OverlayDisplayWindow window = new OverlayDisplayWindow(getContext(),
333040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown                        mName, mWidth, mHeight, mDensityDpi, mGravity, mSecure,
3344ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                        OverlayDisplayHandle.this);
3354ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                window.show();
3364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown
3374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                synchronized (getSyncRoot()) {
3384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    mWindow = window;
339bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                }
340bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
341bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        };
342bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
3434ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        // Runs on the UI thread.
3444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown        private final Runnable mDismissRunnable = new Runnable() {
345bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            @Override
3464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown            public void run() {
3474ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                OverlayDisplayWindow window;
3484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                synchronized (getSyncRoot()) {
3494ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    window = mWindow;
3504ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    mWindow = null;
351bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                }
352bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
3534ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                if (window != null) {
3544ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                    window.dismiss();
3554ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown                }
356bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
357bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        };
358bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
359bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown}
360