OverlayDisplayAdapter.java revision bd6e1500aedc5461e832f69e76341bff0e55fa2b
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
19bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.content.Context;
20bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.database.ContentObserver;
21bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.graphics.SurfaceTexture;
22bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.hardware.display.DisplayManager;
23bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.os.IBinder;
24bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.provider.Settings;
25bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.util.DisplayMetrics;
26bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.util.Slog;
27bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.view.Display;
28bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.view.DisplayInfo;
29bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.view.Gravity;
30bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.view.LayoutInflater;
31bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.view.MotionEvent;
32bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.view.ScaleGestureDetector;
33bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.view.Surface;
34bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.view.TextureView;
35bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.view.TextureView.SurfaceTextureListener;
36bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.view.View;
37bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.view.WindowManager;
38bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport android.widget.TextView;
39bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
40bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport java.io.PrintWriter;
41bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport java.util.ArrayList;
42bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport java.util.regex.Matcher;
43bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownimport java.util.regex.Pattern;
44bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
45bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown/**
46bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * A display adapter that uses overlay windows to simulate secondary displays
47bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * for development purposes.  Use Development Settings to enable one or more
48bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * overlay displays.
49bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * <p>
50bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * Display adapters are not thread-safe and must only be accessed
51bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * on the display manager service's handler thread.
52bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown * </p>
53bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown */
54bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brownpublic final class OverlayDisplayAdapter extends DisplayAdapter {
55bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final String TAG = "OverlayDisplayAdapter";
56bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
57bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final int MIN_WIDTH = 100;
58bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final int MIN_HEIGHT = 100;
59bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final int MAX_WIDTH = 4096;
60bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final int MAX_HEIGHT = 4096;
61bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
62bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private static final Pattern SETTING_PATTERN =
63bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            Pattern.compile("(\\d+)x(\\d+)/(\\d+)");
64bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
65bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private final ArrayList<Overlay> mOverlays = new ArrayList<Overlay>();
66bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private String mCurrentOverlaySetting = "";
67bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
68bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    public OverlayDisplayAdapter(Context context) {
69bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        super(context, TAG);
70bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
71bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
72bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    @Override
73bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    public void dump(PrintWriter pw) {
74bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        pw.println("mCurrentOverlaySetting=" + mCurrentOverlaySetting);
75bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        pw.println("mOverlays: size=" + mOverlays.size());
76bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        for (Overlay overlay : mOverlays) {
77bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            overlay.dump(pw);
78bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
79bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
80bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
81bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    @Override
82bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    protected void onRegister() {
83bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        getContext().getContentResolver().registerContentObserver(
84bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                Settings.System.getUriFor(Settings.Secure.OVERLAY_DISPLAY_DEVICES), true,
85bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                new ContentObserver(getHandler()) {
86bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    @Override
87bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    public void onChange(boolean selfChange) {
88bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                        updateOverlayDisplayDevices();
89bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    }
90bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                });
91bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        updateOverlayDisplayDevices();
92bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
93bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
94bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private void updateOverlayDisplayDevices() {
95bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        String value = Settings.System.getString(getContext().getContentResolver(),
96bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                Settings.Secure.OVERLAY_DISPLAY_DEVICES);
97bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        if (value == null) {
98bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            value = "";
99bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
100bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
101bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        if (value.equals(mCurrentOverlaySetting)) {
102bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            return;
103bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
104bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        mCurrentOverlaySetting = value;
105bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
106bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        if (!mOverlays.isEmpty()) {
107bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            Slog.i(TAG, "Dismissing all overlay display devices.");
108bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            for (Overlay overlay : mOverlays) {
109bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                overlay.dismiss();
110bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
111bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mOverlays.clear();
112bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
113bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
114bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        int number = 1;
115bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        for (String part : value.split(";")) {
116bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            if (number > 4) {
117bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                Slog.w(TAG, "Too many overlay display devices.");
118bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
119bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            Matcher matcher = SETTING_PATTERN.matcher(part);
120bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            if (matcher.matches()) {
121bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                try {
122bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    int width = Integer.parseInt(matcher.group(1), 10);
123bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    int height = Integer.parseInt(matcher.group(2), 10);
124bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    int densityDpi = Integer.parseInt(matcher.group(3), 10);
125bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    if (width >= MIN_WIDTH && width <= MAX_WIDTH
126bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                            && height >= MIN_HEIGHT && height <= MAX_HEIGHT
127bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                            && densityDpi >= DisplayMetrics.DENSITY_LOW
128bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                            && densityDpi <= DisplayMetrics.DENSITY_XXHIGH) {
129bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                        Slog.i(TAG, "Showing overlay display device #" + number
130bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                                + ": width=" + width + ", height=" + height
131bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                                + ", densityDpi=" + densityDpi);
132bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                        mOverlays.add(new Overlay(number++, width, height, densityDpi));
133bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                        continue;
134bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    }
135bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                } catch (NumberFormatException ex) {
136bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                }
137bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            } else if (part.isEmpty()) {
138bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                continue;
139bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
140bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            Slog.w(TAG, "Malformed overlay display devices setting: \"" + value + "\"");
141bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
142bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
143bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        for (Overlay overlay : mOverlays) {
144bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            overlay.show();
145bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
146bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
147bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
148bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    // Manages an overlay window.
149bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private final class Overlay {
150bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final float INITIAL_SCALE = 0.5f;
151bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final float MIN_SCALE = 0.3f;
152bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final float MAX_SCALE = 1.0f;
153bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final float WINDOW_ALPHA = 0.8f;
154bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
155bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        // When true, disables support for moving and resizing the overlay.
156bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        // The window is made non-touchable, which makes it possible to
157bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        // directly interact with the content underneath.
158bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final boolean DISABLE_MOVE_AND_RESIZE = false;
159bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
160bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final DisplayManager mDisplayManager;
161bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final WindowManager mWindowManager;
162bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
163bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final int mNumber;
164bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final int mWidth;
165bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final int mHeight;
166bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final int mDensityDpi;
167bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
168bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final String mName;
169bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final String mTitle;
170bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
171bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final Display mDefaultDisplay;
172bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final DisplayInfo mDefaultDisplayInfo = new DisplayInfo();
173bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final IBinder mDisplayToken;
174bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final OverlayDisplayDevice mDisplayDevice;
175bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
176bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private View mWindowContent;
177bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private WindowManager.LayoutParams mWindowParams;
178bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private TextureView mTextureView;
179bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private TextView mTitleTextView;
180bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private ScaleGestureDetector mScaleGestureDetector;
181bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
182bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private boolean mWindowVisible;
183bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private int mWindowX;
184bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private int mWindowY;
185bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private float mWindowScale;
186bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
187bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private int mLiveTranslationX;
188bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private int mLiveTranslationY;
189bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private float mLiveScale = 1.0f;
190bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
191bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private int mDragPointerId;
192bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private float mDragTouchX;
193bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private float mDragTouchY;
194bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
195bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        public Overlay(int number, int width, int height, int densityDpi) {
196bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            Context context = getContext();
197bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mDisplayManager = (DisplayManager)context.getSystemService(
198bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    Context.DISPLAY_SERVICE);
199bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mWindowManager = (WindowManager)context.getSystemService(
200bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    Context.WINDOW_SERVICE);
201bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
202bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mNumber = number;
203bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mWidth = width;
204bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mHeight = height;
205bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mDensityDpi = densityDpi;
206bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
207bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mName = context.getResources().getString(
208bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    com.android.internal.R.string.display_manager_overlay_display_name, number);
209bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mTitle = context.getResources().getString(
210bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    com.android.internal.R.string.display_manager_overlay_display_title,
211bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    mNumber, mWidth, mHeight, mDensityDpi);
212bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
213bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mDefaultDisplay = mWindowManager.getDefaultDisplay();
214bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            updateDefaultDisplayInfo();
215bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
216bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mDisplayToken = Surface.createDisplay(mName);
217bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mDisplayDevice = new OverlayDisplayDevice(mDisplayToken, mName,
218bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    mDefaultDisplayInfo.refreshRate, mDensityDpi);
219bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
220bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            createWindow();
221bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
222bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
223bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        public void show() {
224bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            if (!mWindowVisible) {
225bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mDisplayManager.registerDisplayListener(mDisplayListener, null);
226bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                if (!updateDefaultDisplayInfo()) {
227bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    mDisplayManager.unregisterDisplayListener(mDisplayListener);
228bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    return;
229bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                }
230bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
231bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                clearLiveState();
232bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                updateWindowParams();
233bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mWindowManager.addView(mWindowContent, mWindowParams);
234bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mWindowVisible = true;
235bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
236bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
237bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
238bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        public void dismiss() {
239bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            if (mWindowVisible) {
240bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mDisplayManager.unregisterDisplayListener(mDisplayListener);
241bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mWindowManager.removeView(mWindowContent);
242bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mWindowVisible = false;
243bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
244bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
245bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
246bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        public void relayout() {
247bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            if (mWindowVisible) {
248bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                updateWindowParams();
249bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mWindowManager.updateViewLayout(mWindowContent, mWindowParams);
250bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
251bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
252bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
253bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        public void dump(PrintWriter pw) {
254bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            pw.println("  #" + mNumber + ": "
255bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    + mWidth + "x" + mHeight + ", " + mDensityDpi + " dpi");
256bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            pw.println("    mName=" + mName);
257bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            pw.println("    mWindowVisible=" + mWindowVisible);
258bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            pw.println("    mWindowX=" + mWindowX);
259bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            pw.println("    mWindowY=" + mWindowY);
260bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            pw.println("    mWindowScale=" + mWindowScale);
261bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            pw.println("    mWindowParams=" + mWindowParams);
262bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            pw.println("    mLiveTranslationX=" + mLiveTranslationX);
263bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            pw.println("    mLiveTranslationY=" + mLiveTranslationY);
264bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            pw.println("    mLiveScale=" + mLiveScale);
265bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
266bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
267bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private boolean updateDefaultDisplayInfo() {
268bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            if (!mDefaultDisplay.getDisplayInfo(mDefaultDisplayInfo)) {
269bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                Slog.w(TAG, "Cannot show overlay display because there is no "
270bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                        + "default display upon which to show it.");
271bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                return false;
272bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
273bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            return true;
274bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
275bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
276bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private void createWindow() {
277bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            Context context = getContext();
278bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            LayoutInflater inflater = LayoutInflater.from(context);
279bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
280bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mWindowContent = inflater.inflate(
281bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    com.android.internal.R.layout.overlay_display_window, null);
282bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mWindowContent.setOnTouchListener(mOnTouchListener);
283bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
284bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mTextureView = (TextureView)mWindowContent.findViewById(
285bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    com.android.internal.R.id.overlay_display_window_texture);
286bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mTextureView.setPivotX(0);
287bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mTextureView.setPivotY(0);
288bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mTextureView.getLayoutParams().width = mWidth;
289bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mTextureView.getLayoutParams().height = mHeight;
290bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
291bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
292bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mTitleTextView = (TextView)mWindowContent.findViewById(
293bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    com.android.internal.R.id.overlay_display_window_title);
294bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mTitleTextView.setText(mTitle);
295bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
296bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mWindowParams = new WindowManager.LayoutParams(
297bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY);
298bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mWindowParams.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
299bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
300bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
301bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
302bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
303bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            if (DISABLE_MOVE_AND_RESIZE) {
304bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mWindowParams.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
305bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
306bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mWindowParams.privateFlags |=
307bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;
308bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mWindowParams.alpha = WINDOW_ALPHA;
309bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mWindowParams.gravity = Gravity.TOP | Gravity.LEFT;
310bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mWindowParams.setTitle(mTitle);
311bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
312bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mScaleGestureDetector = new ScaleGestureDetector(context, mOnScaleGestureListener);
313bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
314bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            // By default, arrange the displays in the four corners.
315bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mWindowVisible = false;
316bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mWindowScale = INITIAL_SCALE;
317bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            if (mNumber == 2 || mNumber == 3) {
318bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mWindowX = mDefaultDisplayInfo.logicalWidth;
319bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            } else {
320bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mWindowX = 0;
321bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
322bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            if (mNumber == 2 || mNumber == 4) {
323bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mWindowY = mDefaultDisplayInfo.logicalHeight;
324bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            } else {
325bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mWindowY = 0;
326bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
327bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
328bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
329bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private void updateWindowParams() {
330bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            float scale = mWindowScale * mLiveScale;
331bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            if (mWidth * scale > mDefaultDisplayInfo.logicalWidth) {
332bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                scale = mDefaultDisplayInfo.logicalWidth / mWidth;
333bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
334bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            if (mHeight * scale > mDefaultDisplayInfo.logicalHeight) {
335bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                scale = mDefaultDisplayInfo.logicalHeight / mHeight;
336bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
337bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            scale = Math.max(MIN_SCALE, Math.min(MAX_SCALE, scale));
338bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
339bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            float offsetScale = (scale / mWindowScale - 1.0f) * 0.5f;
340bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            int width = (int)(mWidth * scale);
341bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            int height = (int)(mHeight * scale);
342bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            int x = mWindowX + mLiveTranslationX - (int)(width * offsetScale);
343bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            int y = mWindowY + mLiveTranslationY - (int)(height * offsetScale);
344bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            x = Math.max(0, Math.min(x, mDefaultDisplayInfo.logicalWidth - width));
345bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            y = Math.max(0, Math.min(y, mDefaultDisplayInfo.logicalHeight - height));
346bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
347bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mTextureView.setScaleX(scale);
348bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mTextureView.setScaleY(scale);
349bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
350bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mWindowParams.x = x;
351bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mWindowParams.y = y;
352bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mWindowParams.width = width;
353bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mWindowParams.height = height;
354bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
355bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
356bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private void saveWindowParams() {
357bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mWindowX = mWindowParams.x;
358bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mWindowY = mWindowParams.y;
359bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mWindowScale = mTextureView.getScaleX();
360bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            clearLiveState();
361bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
362bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
363bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private void clearLiveState() {
364bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mLiveTranslationX = 0;
365bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mLiveTranslationY = 0;
366bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mLiveScale = 1.0f;
367bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
368bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
369bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final DisplayManager.DisplayListener mDisplayListener =
370bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                new DisplayManager.DisplayListener() {
371bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            @Override
372bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            public void onDisplayAdded(int displayId) {
373bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
374bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
375bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            @Override
376bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            public void onDisplayChanged(int displayId) {
377bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                if (displayId == mDefaultDisplay.getDisplayId()) {
378bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    if (updateDefaultDisplayInfo()) {
379bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                        relayout();
380bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    } else {
381bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                        dismiss();
382bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    }
383bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                }
384bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
385bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
386bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            @Override
387bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            public void onDisplayRemoved(int displayId) {
388bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                if (displayId == mDefaultDisplay.getDisplayId()) {
389bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    dismiss();
390bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                }
391bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
392bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        };
393bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
394bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final SurfaceTextureListener mSurfaceTextureListener =
395bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                new SurfaceTextureListener() {
396bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            @Override
397bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
398bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                Surface.openTransaction();
399bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                try {
400bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    Surface.setDisplaySurface(mDisplayToken, surface);
401bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                } finally {
402bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    Surface.closeTransaction();
403bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                }
404bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
405bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mDisplayDevice.setSize(width, height);
406bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                sendDisplayDeviceEvent(mDisplayDevice, DISPLAY_DEVICE_EVENT_ADDED);
407bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
408bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
409bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            @Override
410bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
411bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                sendDisplayDeviceEvent(mDisplayDevice, DISPLAY_DEVICE_EVENT_REMOVED);
412bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
413bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                Surface.openTransaction();
414bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                try {
415bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    Surface.setDisplaySurface(mDisplayToken, null);
416bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                } finally {
417bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    Surface.closeTransaction();
418bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                }
419bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                return true;
420bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
421bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
422bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            @Override
423bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
424bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mDisplayDevice.setSize(width, height);
425bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                sendDisplayDeviceEvent(mDisplayDevice, DISPLAY_DEVICE_EVENT_CHANGED);
426bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
427bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
428bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            @Override
429bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            public void onSurfaceTextureUpdated(SurfaceTexture surface) {
430bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
431bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        };
432bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
433bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final View.OnTouchListener mOnTouchListener = new View.OnTouchListener() {
434bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            @Override
435bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            public boolean onTouch(View view, MotionEvent event) {
436bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                // Work in screen coordinates.
437bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                final float oldX = event.getX();
438bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                final float oldY = event.getY();
439bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                event.setLocation(event.getRawX(), event.getRawY());
440bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
441bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mScaleGestureDetector.onTouchEvent(event);
442bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
443bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                switch (event.getActionMasked()) {
444bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    case MotionEvent.ACTION_DOWN:
445bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                        resetDrag(event);
446bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                        break;
447bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
448bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    case MotionEvent.ACTION_MOVE:
449bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                        if (event.getPointerCount() == 1) {
450bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                            int index = event.findPointerIndex(mDragPointerId);
451bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                            if (index < 0) {
452bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                                resetDrag(event);
453bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                            } else {
454bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                                mLiveTranslationX = (int)(event.getX(index) - mDragTouchX);
455bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                                mLiveTranslationY = (int)(event.getY(index) - mDragTouchY);
456bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                                relayout();
457bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                            }
458bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                        }
459bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                        break;
460bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
461bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    case MotionEvent.ACTION_UP:
462bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                    case MotionEvent.ACTION_CANCEL:
463bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                        saveWindowParams();
464bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                        break;
465bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                }
466bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
467bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                // Revert to window coordinates.
468bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                event.setLocation(oldX, oldY);
469bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                return true;
470bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
471bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
472bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            private void resetDrag(MotionEvent event) {
473bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                saveWindowParams();
474bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mDragPointerId = event.getPointerId(0);
475bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mDragTouchX = event.getX();
476bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mDragTouchY = event.getY();
477bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
478bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        };
479bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
480bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final ScaleGestureDetector.OnScaleGestureListener mOnScaleGestureListener =
481bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                new ScaleGestureDetector.SimpleOnScaleGestureListener() {
482bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            @Override
483bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            public boolean onScaleBegin(ScaleGestureDetector detector) {
484bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                saveWindowParams();
485bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mDragPointerId = -1; // cause drag to be reset
486bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                return true;
487bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
488bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
489bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            @Override
490bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            public boolean onScale(ScaleGestureDetector detector) {
491bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                mLiveScale = detector.getScaleFactor();
492bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                relayout();
493bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                return false;
494bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            }
495bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        };
496bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
497bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
498bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    private final class OverlayDisplayDevice extends DisplayDevice {
499bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final String mName;
500bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final float mRefreshRate;
501bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private final int mDensityDpi;
502bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private int mWidth;
503bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        private int mHeight;
504bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
505bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        public OverlayDisplayDevice(IBinder displayToken, String name,
506bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown                float refreshRate, int densityDpi) {
507bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            super(OverlayDisplayAdapter.this, displayToken);
508bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mName = name;
509bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mRefreshRate = refreshRate;
510bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mDensityDpi = densityDpi;
511bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
512bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
513bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        public void setSize(int width, int height) {
514bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mWidth = width;
515bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            mHeight = height;
516bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
517bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown
518bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        @Override
519bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        public void getInfo(DisplayDeviceInfo outInfo) {
520bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            outInfo.name = mName;
521bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            outInfo.width = mWidth;
522bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            outInfo.height = mHeight;
523bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            outInfo.refreshRate = mRefreshRate;
524bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            outInfo.densityDpi = mDensityDpi;
525bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            outInfo.xDpi = mDensityDpi;
526bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            outInfo.yDpi = mDensityDpi;
527bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown            outInfo.flags = DisplayDeviceInfo.FLAG_SECURE;
528bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown        }
529bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown    }
530bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown}
531