OverlayDisplayWindow.java revision d5523dc7b7318f2774109dd30716ff7b74560e61
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; 334ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.view.View; 344ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.view.WindowManager; 354ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.view.TextureView.SurfaceTextureListener; 364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport android.widget.TextView; 374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport java.io.PrintWriter; 394ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown/** 414ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * Manages an overlay window on behalf of {@link OverlayDisplayAdapter}. 424ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * <p> 434ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * This object must only be accessed on the UI thread. 444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * No locks are held by this object and locks must not be held while making called into it. 454ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * </p> 464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown */ 47cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brownfinal class OverlayDisplayWindow implements DumpUtils.Dump { 484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private static final String TAG = "OverlayDisplayWindow"; 494ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private static final boolean DEBUG = false; 504ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 514ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final float INITIAL_SCALE = 0.5f; 524ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final float MIN_SCALE = 0.3f; 534ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final float MAX_SCALE = 1.0f; 544ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final float WINDOW_ALPHA = 0.8f; 554ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 564ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // When true, disables support for moving and resizing the overlay. 574ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // The window is made non-touchable, which makes it possible to 584ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // directly interact with the content underneath. 594ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final boolean DISABLE_MOVE_AND_RESIZE = false; 604ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 614ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final Context mContext; 624ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final String mName; 634ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final int mWidth; 644ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final int mHeight; 654ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final int mDensityDpi; 664ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final int mGravity; 674ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final Listener mListener; 684ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final String mTitle; 694ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 704ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final DisplayManager mDisplayManager; 714ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final WindowManager mWindowManager; 724ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 734ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 744ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final Display mDefaultDisplay; 754ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final DisplayInfo mDefaultDisplayInfo = new DisplayInfo(); 764ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 774ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private View mWindowContent; 784ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private WindowManager.LayoutParams mWindowParams; 794ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private TextureView mTextureView; 804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private TextView mTitleTextView; 814ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 824ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private GestureDetector mGestureDetector; 834ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private ScaleGestureDetector mScaleGestureDetector; 844ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 854ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private boolean mWindowVisible; 864ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private int mWindowX; 874ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private int mWindowY; 884ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private float mWindowScale; 894ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 904ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private float mLiveTranslationX; 914ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private float mLiveTranslationY; 924ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private float mLiveScale = 1.0f; 934ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 944ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public OverlayDisplayWindow(Context context, String name, 954ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown int width, int height, int densityDpi, int gravity, Listener listener) { 964ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mContext = context; 974ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mName = name; 984ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWidth = width; 994ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mHeight = height; 1004ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mDensityDpi = densityDpi; 1014ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mGravity = gravity; 1024ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mListener = listener; 1034ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTitle = context.getResources().getString( 1044ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown com.android.internal.R.string.display_manager_overlay_display_title, 1054ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mName, mWidth, mHeight, mDensityDpi); 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 1154ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown createWindow(); 1164ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1174ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1184ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void show() { 1194ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (!mWindowVisible) { 1204ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mDisplayManager.registerDisplayListener(mDisplayListener, null); 1214ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (!updateDefaultDisplayInfo()) { 1224ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mDisplayManager.unregisterDisplayListener(mDisplayListener); 1234ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return; 1244ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1254ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown clearLiveState(); 1274ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown updateWindowParams(); 1284ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowManager.addView(mWindowContent, mWindowParams); 1294ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowVisible = true; 1304ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1324ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1334ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void dismiss() { 1344ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (mWindowVisible) { 1354ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mDisplayManager.unregisterDisplayListener(mDisplayListener); 1364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowManager.removeView(mWindowContent); 1374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowVisible = false; 1384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1394ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1414ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void relayout() { 1424ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (mWindowVisible) { 1434ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown updateWindowParams(); 1444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowManager.updateViewLayout(mWindowContent, mWindowParams); 1454ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1474ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 148d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner @Override 1494ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void dump(PrintWriter pw) { 150cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mWindowVisible=" + mWindowVisible); 151cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mWindowX=" + mWindowX); 152cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mWindowY=" + mWindowY); 153cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mWindowScale=" + mWindowScale); 154cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mWindowParams=" + mWindowParams); 1554ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (mTextureView != null) { 156cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mTextureView.getScaleX()=" + mTextureView.getScaleX()); 157cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mTextureView.getScaleY()=" + mTextureView.getScaleY()); 1584ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 159cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mLiveTranslationX=" + mLiveTranslationX); 160cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mLiveTranslationY=" + mLiveTranslationY); 161cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mLiveScale=" + mLiveScale); 1624ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1634ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1644ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private boolean updateDefaultDisplayInfo() { 1654ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (!mDefaultDisplay.getDisplayInfo(mDefaultDisplayInfo)) { 1664ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown Slog.w(TAG, "Cannot show overlay display because there is no " 1674ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown + "default display upon which to show it."); 1684ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return false; 1694ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1704ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return true; 1714ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1724ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1734ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private void createWindow() { 1744ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown LayoutInflater inflater = LayoutInflater.from(mContext); 1754ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1764ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowContent = inflater.inflate( 1774ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown com.android.internal.R.layout.overlay_display_window, null); 1784ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowContent.setOnTouchListener(mOnTouchListener); 1794ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView = (TextureView)mWindowContent.findViewById( 1814ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown com.android.internal.R.id.overlay_display_window_texture); 1824ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.setPivotX(0); 1834ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.setPivotY(0); 1844ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.getLayoutParams().width = mWidth; 1854ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.getLayoutParams().height = mHeight; 1864ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.setOpaque(false); 1874ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.setSurfaceTextureListener(mSurfaceTextureListener); 1884ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1894ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTitleTextView = (TextView)mWindowContent.findViewById( 1904ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown com.android.internal.R.id.overlay_display_window_title); 1914ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTitleTextView.setText(mTitle); 1924ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1934ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams = new WindowManager.LayoutParams( 1944ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY); 1954ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 1964ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS 1974ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 1984ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL 1994ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; 2004ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (DISABLE_MOVE_AND_RESIZE) { 2014ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 2024ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2034ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.privateFlags |= 2044ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED; 2054ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.alpha = WINDOW_ALPHA; 2064ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.gravity = Gravity.TOP | Gravity.LEFT; 2074ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.setTitle(mTitle); 2084ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2094ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mGestureDetector = new GestureDetector(mContext, mOnGestureListener); 2104ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mScaleGestureDetector = new ScaleGestureDetector(mContext, mOnScaleGestureListener); 2114ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2124ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // Set the initial position and scale. 2134ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // The position and scale will be clamped when the display is first shown. 2144ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowX = (mGravity & Gravity.LEFT) == Gravity.LEFT ? 2154ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 0 : mDefaultDisplayInfo.logicalWidth; 2164ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowY = (mGravity & Gravity.TOP) == Gravity.TOP ? 2174ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 0 : mDefaultDisplayInfo.logicalHeight; 2184ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowScale = INITIAL_SCALE; 2194ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2204ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2214ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private void updateWindowParams() { 2224ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown float scale = mWindowScale * mLiveScale; 2234ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown scale = Math.min(scale, (float)mDefaultDisplayInfo.logicalWidth / mWidth); 2244ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown scale = Math.min(scale, (float)mDefaultDisplayInfo.logicalHeight / mHeight); 2254ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown scale = Math.max(MIN_SCALE, Math.min(MAX_SCALE, scale)); 2264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2274ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown float offsetScale = (scale / mWindowScale - 1.0f) * 0.5f; 2284ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown int width = (int)(mWidth * scale); 2294ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown int height = (int)(mHeight * scale); 2304ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown int x = (int)(mWindowX + mLiveTranslationX - width * offsetScale); 2314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown int y = (int)(mWindowY + mLiveTranslationY - height * offsetScale); 2324ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown x = Math.max(0, Math.min(x, mDefaultDisplayInfo.logicalWidth - width)); 2334ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown y = Math.max(0, Math.min(y, mDefaultDisplayInfo.logicalHeight - height)); 2344ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2354ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (DEBUG) { 2364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown Slog.d(TAG, "updateWindowParams: scale=" + scale 2374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown + ", offsetScale=" + offsetScale 2384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown + ", x=" + x + ", y=" + y 2394ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown + ", width=" + width + ", height=" + height); 2404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2414ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2424ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.setScaleX(scale); 2434ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.setScaleY(scale); 2444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2454ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.x = x; 2464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.y = y; 2474ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.width = width; 2484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.height = height; 2494ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2504ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2514ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private void saveWindowParams() { 2524ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowX = mWindowParams.x; 2534ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowY = mWindowParams.y; 2544ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowScale = mTextureView.getScaleX(); 2554ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown clearLiveState(); 2564ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2574ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2584ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private void clearLiveState() { 2594ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mLiveTranslationX = 0f; 2604ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mLiveTranslationY = 0f; 2614ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mLiveScale = 1.0f; 2624ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2634ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2644ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final DisplayManager.DisplayListener mDisplayListener = 2654ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown new DisplayManager.DisplayListener() { 2664ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 2674ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void onDisplayAdded(int displayId) { 2684ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2694ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2704ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 2714ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void onDisplayChanged(int displayId) { 2724ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (displayId == mDefaultDisplay.getDisplayId()) { 2734ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (updateDefaultDisplayInfo()) { 2744ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown relayout(); 2754ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } else { 2764ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown dismiss(); 2774ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2784ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2794ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2814ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 2824ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void onDisplayRemoved(int displayId) { 2834ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (displayId == mDefaultDisplay.getDisplayId()) { 2844ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown dismiss(); 2854ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2864ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2874ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown }; 2884ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2894ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final SurfaceTextureListener mSurfaceTextureListener = 2904ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown new SurfaceTextureListener() { 2914ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 292cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, 293cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown int width, int height) { 294d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner mListener.onWindowCreated(surfaceTexture, mDefaultDisplayInfo.refreshRate); 2954ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2964ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2974ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 298cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) { 2994ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mListener.onWindowDestroyed(); 3004ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return true; 3014ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3024ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3034ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 304cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, 305cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown int width, int height) { 3064ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3074ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3084ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 309cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { 3104ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3114ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown }; 3124ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3134ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final View.OnTouchListener mOnTouchListener = new View.OnTouchListener() { 3144ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 3154ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public boolean onTouch(View view, MotionEvent event) { 3164ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // Work in screen coordinates. 3174ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown final float oldX = event.getX(); 3184ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown final float oldY = event.getY(); 3194ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown event.setLocation(event.getRawX(), event.getRawY()); 3204ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3214ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mGestureDetector.onTouchEvent(event); 3224ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mScaleGestureDetector.onTouchEvent(event); 3234ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3244ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown switch (event.getActionMasked()) { 3254ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown case MotionEvent.ACTION_UP: 3264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown case MotionEvent.ACTION_CANCEL: 3274ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown saveWindowParams(); 3284ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown break; 3294ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3304ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // Revert to window coordinates. 3324ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown event.setLocation(oldX, oldY); 3334ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return true; 3344ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3354ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown }; 3364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final GestureDetector.OnGestureListener mOnGestureListener = 3384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown new GestureDetector.SimpleOnGestureListener() { 3394ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 3404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public boolean onScroll(MotionEvent e1, MotionEvent e2, 3414ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown float distanceX, float distanceY) { 3424ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mLiveTranslationX -= distanceX; 3434ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mLiveTranslationY -= distanceY; 3444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown relayout(); 3454ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return true; 3464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3474ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown }; 3484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3494ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final ScaleGestureDetector.OnScaleGestureListener mOnScaleGestureListener = 3504ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown new ScaleGestureDetector.SimpleOnScaleGestureListener() { 3514ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 3524ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public boolean onScale(ScaleGestureDetector detector) { 3534ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mLiveScale *= detector.getScaleFactor(); 3544ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown relayout(); 3554ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return true; 3564ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3574ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown }; 3584ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3594ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown /** 3604ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * Watches for significant changes in the overlay display window lifecycle. 3614ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown */ 3624ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public interface Listener { 363d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner public void onWindowCreated(SurfaceTexture surfaceTexture, float refreshRate); 3644ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void onWindowDestroyed(); 3654ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3664ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown}