14ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown/* 24ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * Copyright (C) 2012 The Android Open Source Project 34ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * 44ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 54ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * you may not use this file except in compliance with the License. 64ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * You may obtain a copy of the License at 74ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * 84ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 94ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * 104ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * Unless required by applicable law or agreed to in writing, software 114ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 124ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * See the License for the specific language governing permissions and 144ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * limitations under the License. 154ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown */ 164ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 174ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownpackage com.android.server.display; 184ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 19cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brownimport com.android.internal.util.DumpUtils; 20cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 214ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.content.Context; 224ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.graphics.SurfaceTexture; 234ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.hardware.display.DisplayManager; 244ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.util.Slog; 254ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.view.Display; 264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.view.DisplayInfo; 274ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.view.GestureDetector; 284ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.view.Gravity; 294ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.view.LayoutInflater; 304ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.view.MotionEvent; 314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.view.ScaleGestureDetector; 324ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.view.TextureView; 33a896306c38c4d11c43b967a21db6d74c251b2520John Reckimport android.view.ThreadedRenderer; 344ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.view.View; 354ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.view.WindowManager; 364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.view.TextureView.SurfaceTextureListener; 374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.widget.TextView; 384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 394ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport java.io.PrintWriter; 404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 414ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown/** 424ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * Manages an overlay window on behalf of {@link OverlayDisplayAdapter}. 434ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * <p> 444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * This object must only be accessed on the UI thread. 454ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * No locks are held by this object and locks must not be held while making called into it. 464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * </p> 474ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown */ 48cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brownfinal class OverlayDisplayWindow implements DumpUtils.Dump { 494ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private static final String TAG = "OverlayDisplayWindow"; 504ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private static final boolean DEBUG = false; 514ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 524ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final float INITIAL_SCALE = 0.5f; 534ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final float MIN_SCALE = 0.3f; 544ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final float MAX_SCALE = 1.0f; 554ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final float WINDOW_ALPHA = 0.8f; 564ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 574ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // When true, disables support for moving and resizing the overlay. 584ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // The window is made non-touchable, which makes it possible to 594ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // directly interact with the content underneath. 604ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final boolean DISABLE_MOVE_AND_RESIZE = false; 614ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 624ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final Context mContext; 634ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final String mName; 64af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand private int mWidth; 65af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand private int mHeight; 66af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand private int mDensityDpi; 674ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final int mGravity; 68040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown private final boolean mSecure; 694ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final Listener mListener; 70040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown private String mTitle; 714ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 724ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final DisplayManager mDisplayManager; 734ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final WindowManager mWindowManager; 744ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 754ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 764ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final Display mDefaultDisplay; 774ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final DisplayInfo mDefaultDisplayInfo = new DisplayInfo(); 784ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 794ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private View mWindowContent; 804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private WindowManager.LayoutParams mWindowParams; 814ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private TextureView mTextureView; 824ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private TextView mTitleTextView; 834ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 844ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private GestureDetector mGestureDetector; 854ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private ScaleGestureDetector mScaleGestureDetector; 864ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 874ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private boolean mWindowVisible; 884ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private int mWindowX; 894ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private int mWindowY; 904ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private float mWindowScale; 914ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 924ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private float mLiveTranslationX; 934ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private float mLiveTranslationY; 944ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private float mLiveScale = 1.0f; 954ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 964ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public OverlayDisplayWindow(Context context, String name, 97040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown int width, int height, int densityDpi, int gravity, boolean secure, 98040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown Listener listener) { 99a896306c38c4d11c43b967a21db6d74c251b2520John Reck // Workaround device freeze (b/38372997) 100a896306c38c4d11c43b967a21db6d74c251b2520John Reck ThreadedRenderer.disableVsync(); 1014ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mContext = context; 1024ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mName = name; 1034ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mGravity = gravity; 104040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown mSecure = secure; 1054ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mListener = listener; 1064ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1074ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mDisplayManager = (DisplayManager)context.getSystemService( 1084ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown Context.DISPLAY_SERVICE); 1094ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowManager = (WindowManager)context.getSystemService( 1104ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown Context.WINDOW_SERVICE); 1114ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1124ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mDefaultDisplay = mWindowManager.getDefaultDisplay(); 1134ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown updateDefaultDisplayInfo(); 1144ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 115af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand resize(width, height, densityDpi, false /* doLayout */); 116af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand 1174ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown createWindow(); 1184ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1194ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1204ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void show() { 1214ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (!mWindowVisible) { 1224ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mDisplayManager.registerDisplayListener(mDisplayListener, null); 1234ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (!updateDefaultDisplayInfo()) { 1244ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mDisplayManager.unregisterDisplayListener(mDisplayListener); 1254ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return; 1264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1274ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1284ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown clearLiveState(); 1294ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown updateWindowParams(); 1304ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowManager.addView(mWindowContent, mWindowParams); 1314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowVisible = true; 1324ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1334ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1344ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1354ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void dismiss() { 1364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (mWindowVisible) { 1374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mDisplayManager.unregisterDisplayListener(mDisplayListener); 1384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowManager.removeView(mWindowContent); 1394ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowVisible = false; 1404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1414ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1424ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 143af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand public void resize(int width, int height, int densityDpi) { 144af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand resize(width, height, densityDpi, true /* doLayout */); 145af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand } 146af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand 147af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand private void resize(int width, int height, int densityDpi, boolean doLayout) { 148af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand mWidth = width; 149af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand mHeight = height; 150af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand mDensityDpi = densityDpi; 151af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand mTitle = mContext.getResources().getString( 152af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand com.android.internal.R.string.display_manager_overlay_display_title, 153af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand mName, mWidth, mHeight, mDensityDpi); 154af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand if (mSecure) { 155af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand mTitle += mContext.getResources().getString( 156af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand com.android.internal.R.string.display_manager_overlay_display_secure_suffix); 157af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand } 158af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand if (doLayout) { 159af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand relayout(); 160af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand } 161af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand } 162af9c52eb45d772301bf96dd6c54455ffa954ead5P.Y. Laligand 1634ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void relayout() { 1644ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (mWindowVisible) { 1654ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown updateWindowParams(); 1664ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowManager.updateViewLayout(mWindowContent, mWindowParams); 1674ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1684ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1694ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 170d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner @Override 171ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn public void dump(PrintWriter pw, String prefix) { 172cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mWindowVisible=" + mWindowVisible); 173cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mWindowX=" + mWindowX); 174cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mWindowY=" + mWindowY); 175cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mWindowScale=" + mWindowScale); 176cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mWindowParams=" + mWindowParams); 1774ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (mTextureView != null) { 178cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mTextureView.getScaleX()=" + mTextureView.getScaleX()); 179cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mTextureView.getScaleY()=" + mTextureView.getScaleY()); 1804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 181cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mLiveTranslationX=" + mLiveTranslationX); 182cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mLiveTranslationY=" + mLiveTranslationY); 183cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mLiveScale=" + mLiveScale); 1844ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1854ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1864ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private boolean updateDefaultDisplayInfo() { 1874ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (!mDefaultDisplay.getDisplayInfo(mDefaultDisplayInfo)) { 1884ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown Slog.w(TAG, "Cannot show overlay display because there is no " 1894ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown + "default display upon which to show it."); 1904ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return false; 1914ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1924ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return true; 1934ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1944ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1954ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private void createWindow() { 1964ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown LayoutInflater inflater = LayoutInflater.from(mContext); 1974ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1984ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowContent = inflater.inflate( 1994ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown com.android.internal.R.layout.overlay_display_window, null); 2004ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowContent.setOnTouchListener(mOnTouchListener); 2014ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2024ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView = (TextureView)mWindowContent.findViewById( 2034ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown com.android.internal.R.id.overlay_display_window_texture); 2044ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.setPivotX(0); 2054ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.setPivotY(0); 2064ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.getLayoutParams().width = mWidth; 2074ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.getLayoutParams().height = mHeight; 2084ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.setOpaque(false); 2094ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.setSurfaceTextureListener(mSurfaceTextureListener); 2104ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2114ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTitleTextView = (TextView)mWindowContent.findViewById( 2124ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown com.android.internal.R.id.overlay_display_window_title); 2134ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTitleTextView.setText(mTitle); 2144ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2154ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams = new WindowManager.LayoutParams( 2164ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY); 2174ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 2184ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS 2194ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 2204ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL 2214ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; 222040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown if (mSecure) { 223040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown mWindowParams.flags |= WindowManager.LayoutParams.FLAG_SECURE; 224040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown } 2254ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (DISABLE_MOVE_AND_RESIZE) { 2264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 2274ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2284ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.privateFlags |= 2294ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED; 2304ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.alpha = WINDOW_ALPHA; 2314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.gravity = Gravity.TOP | Gravity.LEFT; 2324ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.setTitle(mTitle); 2334ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2344ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mGestureDetector = new GestureDetector(mContext, mOnGestureListener); 2354ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mScaleGestureDetector = new ScaleGestureDetector(mContext, mOnScaleGestureListener); 2364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // Set the initial position and scale. 2384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // The position and scale will be clamped when the display is first shown. 2394ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowX = (mGravity & Gravity.LEFT) == Gravity.LEFT ? 2404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 0 : mDefaultDisplayInfo.logicalWidth; 2414ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowY = (mGravity & Gravity.TOP) == Gravity.TOP ? 2424ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 0 : mDefaultDisplayInfo.logicalHeight; 2434ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowScale = INITIAL_SCALE; 2444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2454ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private void updateWindowParams() { 2474ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown float scale = mWindowScale * mLiveScale; 2484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown scale = Math.min(scale, (float)mDefaultDisplayInfo.logicalWidth / mWidth); 2494ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown scale = Math.min(scale, (float)mDefaultDisplayInfo.logicalHeight / mHeight); 2504ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown scale = Math.max(MIN_SCALE, Math.min(MAX_SCALE, scale)); 2514ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2524ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown float offsetScale = (scale / mWindowScale - 1.0f) * 0.5f; 2534ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown int width = (int)(mWidth * scale); 2544ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown int height = (int)(mHeight * scale); 2554ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown int x = (int)(mWindowX + mLiveTranslationX - width * offsetScale); 2564ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown int y = (int)(mWindowY + mLiveTranslationY - height * offsetScale); 2574ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown x = Math.max(0, Math.min(x, mDefaultDisplayInfo.logicalWidth - width)); 2584ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown y = Math.max(0, Math.min(y, mDefaultDisplayInfo.logicalHeight - height)); 2594ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2604ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (DEBUG) { 2614ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown Slog.d(TAG, "updateWindowParams: scale=" + scale 2624ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown + ", offsetScale=" + offsetScale 2634ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown + ", x=" + x + ", y=" + y 2644ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown + ", width=" + width + ", height=" + height); 2654ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2664ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2674ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.setScaleX(scale); 2684ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.setScaleY(scale); 2694ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2704ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.x = x; 2714ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.y = y; 2724ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.width = width; 2734ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.height = height; 2744ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2754ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2764ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private void saveWindowParams() { 2774ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowX = mWindowParams.x; 2784ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowY = mWindowParams.y; 2794ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowScale = mTextureView.getScaleX(); 2804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown clearLiveState(); 2814ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2824ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2834ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private void clearLiveState() { 2844ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mLiveTranslationX = 0f; 2854ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mLiveTranslationY = 0f; 2864ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mLiveScale = 1.0f; 2874ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2884ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2894ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final DisplayManager.DisplayListener mDisplayListener = 2904ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown new DisplayManager.DisplayListener() { 2914ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 2924ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void onDisplayAdded(int displayId) { 2934ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2944ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2954ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 2964ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void onDisplayChanged(int displayId) { 2974ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (displayId == mDefaultDisplay.getDisplayId()) { 2984ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (updateDefaultDisplayInfo()) { 2994ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown relayout(); 300037c33eae74bee2774897d969d48947f9abe254fJeff Brown mListener.onStateChanged(mDefaultDisplayInfo.state); 3014ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } else { 3024ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown dismiss(); 3034ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3044ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3054ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3064ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3074ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 3084ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void onDisplayRemoved(int displayId) { 3094ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (displayId == mDefaultDisplay.getDisplayId()) { 3104ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown dismiss(); 3114ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3124ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3134ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown }; 3144ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3154ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final SurfaceTextureListener mSurfaceTextureListener = 3164ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown new SurfaceTextureListener() { 3174ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 318cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, 319cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown int width, int height) { 3205c7773d86484aac5737667c604bd8fe8150c2136P.Y. Laligand mListener.onWindowCreated(surfaceTexture, 3215c7773d86484aac5737667c604bd8fe8150c2136P.Y. Laligand mDefaultDisplayInfo.getMode().getRefreshRate(), 322e8b1aeb51e1e5da64f1d4fd40f2ee1e815886fe5Andy McFadden mDefaultDisplayInfo.presentationDeadlineNanos, mDefaultDisplayInfo.state); 3234ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3244ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3254ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 326cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) { 3274ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mListener.onWindowDestroyed(); 3284ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return true; 3294ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3304ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 332cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, 333cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown int width, int height) { 3344ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3354ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 337cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { 3384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3394ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown }; 3404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3414ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final View.OnTouchListener mOnTouchListener = new View.OnTouchListener() { 3424ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 3434ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public boolean onTouch(View view, MotionEvent event) { 3444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // Work in screen coordinates. 3454ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown final float oldX = event.getX(); 3464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown final float oldY = event.getY(); 3474ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown event.setLocation(event.getRawX(), event.getRawY()); 3484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3494ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mGestureDetector.onTouchEvent(event); 3504ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mScaleGestureDetector.onTouchEvent(event); 3514ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3524ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown switch (event.getActionMasked()) { 3534ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown case MotionEvent.ACTION_UP: 3544ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown case MotionEvent.ACTION_CANCEL: 3554ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown saveWindowParams(); 3564ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown break; 3574ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3584ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3594ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // Revert to window coordinates. 3604ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown event.setLocation(oldX, oldY); 3614ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return true; 3624ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3634ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown }; 3644ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3654ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final GestureDetector.OnGestureListener mOnGestureListener = 3664ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown new GestureDetector.SimpleOnGestureListener() { 3674ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 3684ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public boolean onScroll(MotionEvent e1, MotionEvent e2, 3694ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown float distanceX, float distanceY) { 3704ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mLiveTranslationX -= distanceX; 3714ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mLiveTranslationY -= distanceY; 3724ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown relayout(); 3734ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return true; 3744ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3754ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown }; 3764ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3774ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final ScaleGestureDetector.OnScaleGestureListener mOnScaleGestureListener = 3784ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown new ScaleGestureDetector.SimpleOnScaleGestureListener() { 3794ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 3804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public boolean onScale(ScaleGestureDetector detector) { 3814ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mLiveScale *= detector.getScaleFactor(); 3824ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown relayout(); 3834ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return true; 3844ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3854ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown }; 3864ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3874ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown /** 3884ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * Watches for significant changes in the overlay display window lifecycle. 3894ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown */ 3904ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public interface Listener { 391037c33eae74bee2774897d969d48947f9abe254fJeff Brown public void onWindowCreated(SurfaceTexture surfaceTexture, 392e8b1aeb51e1e5da64f1d4fd40f2ee1e815886fe5Andy McFadden float refreshRate, long presentationDeadlineNanos, int state); 3934ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void onWindowDestroyed(); 394037c33eae74bee2774897d969d48947f9abe254fJeff Brown public void onStateChanged(int state); 3954ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3965c7773d86484aac5737667c604bd8fe8150c2136P.Y. Laligand} 397