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; 67040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown private final boolean mSecure; 684ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final Listener mListener; 69040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown private String mTitle; 704ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 714ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final DisplayManager mDisplayManager; 724ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final WindowManager mWindowManager; 734ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 744ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 754ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final Display mDefaultDisplay; 764ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final DisplayInfo mDefaultDisplayInfo = new DisplayInfo(); 774ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 784ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private View mWindowContent; 794ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private WindowManager.LayoutParams mWindowParams; 804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private TextureView mTextureView; 814ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private TextView mTitleTextView; 824ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 834ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private GestureDetector mGestureDetector; 844ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private ScaleGestureDetector mScaleGestureDetector; 854ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 864ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private boolean mWindowVisible; 874ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private int mWindowX; 884ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private int mWindowY; 894ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private float mWindowScale; 904ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 914ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private float mLiveTranslationX; 924ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private float mLiveTranslationY; 934ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private float mLiveScale = 1.0f; 944ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 954ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public OverlayDisplayWindow(Context context, String name, 96040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown int width, int height, int densityDpi, int gravity, boolean secure, 97040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown Listener listener) { 984ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mContext = context; 994ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mName = name; 1004ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWidth = width; 1014ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mHeight = height; 1024ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mDensityDpi = densityDpi; 1034ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mGravity = gravity; 104040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown mSecure = secure; 1054ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mListener = listener; 1064ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTitle = context.getResources().getString( 1074ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown com.android.internal.R.string.display_manager_overlay_display_title, 1084ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mName, mWidth, mHeight, mDensityDpi); 109040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown if (secure) { 110040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown mTitle += context.getResources().getString( 111040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown com.android.internal.R.string.display_manager_overlay_display_secure_suffix); 112040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown } 1134ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1144ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mDisplayManager = (DisplayManager)context.getSystemService( 1154ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown Context.DISPLAY_SERVICE); 1164ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowManager = (WindowManager)context.getSystemService( 1174ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown Context.WINDOW_SERVICE); 1184ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1194ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mDefaultDisplay = mWindowManager.getDefaultDisplay(); 1204ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown updateDefaultDisplayInfo(); 1214ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1224ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown createWindow(); 1234ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1244ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1254ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void show() { 1264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (!mWindowVisible) { 1274ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mDisplayManager.registerDisplayListener(mDisplayListener, null); 1284ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (!updateDefaultDisplayInfo()) { 1294ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mDisplayManager.unregisterDisplayListener(mDisplayListener); 1304ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return; 1314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1324ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1334ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown clearLiveState(); 1344ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown updateWindowParams(); 1354ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowManager.addView(mWindowContent, mWindowParams); 1364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowVisible = true; 1374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1394ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void dismiss() { 1414ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (mWindowVisible) { 1424ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mDisplayManager.unregisterDisplayListener(mDisplayListener); 1434ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowManager.removeView(mWindowContent); 1444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowVisible = false; 1454ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1474ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void relayout() { 1494ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (mWindowVisible) { 1504ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown updateWindowParams(); 1514ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowManager.updateViewLayout(mWindowContent, mWindowParams); 1524ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1534ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1544ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 155d5523dc7b7318f2774109dd30716ff7b74560e61Craig Mautner @Override 1564ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void dump(PrintWriter pw) { 157cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mWindowVisible=" + mWindowVisible); 158cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mWindowX=" + mWindowX); 159cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mWindowY=" + mWindowY); 160cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mWindowScale=" + mWindowScale); 161cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mWindowParams=" + mWindowParams); 1624ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (mTextureView != null) { 163cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mTextureView.getScaleX()=" + mTextureView.getScaleX()); 164cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mTextureView.getScaleY()=" + mTextureView.getScaleY()); 1654ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 166cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mLiveTranslationX=" + mLiveTranslationX); 167cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mLiveTranslationY=" + mLiveTranslationY); 168cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown pw.println("mLiveScale=" + mLiveScale); 1694ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1704ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1714ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private boolean updateDefaultDisplayInfo() { 1724ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (!mDefaultDisplay.getDisplayInfo(mDefaultDisplayInfo)) { 1734ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown Slog.w(TAG, "Cannot show overlay display because there is no " 1744ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown + "default display upon which to show it."); 1754ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return false; 1764ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1774ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return true; 1784ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 1794ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private void createWindow() { 1814ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown LayoutInflater inflater = LayoutInflater.from(mContext); 1824ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1834ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowContent = inflater.inflate( 1844ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown com.android.internal.R.layout.overlay_display_window, null); 1854ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowContent.setOnTouchListener(mOnTouchListener); 1864ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1874ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView = (TextureView)mWindowContent.findViewById( 1884ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown com.android.internal.R.id.overlay_display_window_texture); 1894ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.setPivotX(0); 1904ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.setPivotY(0); 1914ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.getLayoutParams().width = mWidth; 1924ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.getLayoutParams().height = mHeight; 1934ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.setOpaque(false); 1944ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.setSurfaceTextureListener(mSurfaceTextureListener); 1954ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 1964ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTitleTextView = (TextView)mWindowContent.findViewById( 1974ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown com.android.internal.R.id.overlay_display_window_title); 1984ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTitleTextView.setText(mTitle); 1994ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2004ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams = new WindowManager.LayoutParams( 2014ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY); 2024ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 2034ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS 2044ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 2054ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL 2064ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; 207040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown if (mSecure) { 208040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown mWindowParams.flags |= WindowManager.LayoutParams.FLAG_SECURE; 209040f44d0ebdd3a50c59ba0cbc0b023fd2d71039dJeff Brown } 2104ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (DISABLE_MOVE_AND_RESIZE) { 2114ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 2124ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2134ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.privateFlags |= 2144ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED; 2154ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.alpha = WINDOW_ALPHA; 2164ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.gravity = Gravity.TOP | Gravity.LEFT; 2174ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.setTitle(mTitle); 2184ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2194ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mGestureDetector = new GestureDetector(mContext, mOnGestureListener); 2204ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mScaleGestureDetector = new ScaleGestureDetector(mContext, mOnScaleGestureListener); 2214ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2224ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // Set the initial position and scale. 2234ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // The position and scale will be clamped when the display is first shown. 2244ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowX = (mGravity & Gravity.LEFT) == Gravity.LEFT ? 2254ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 0 : mDefaultDisplayInfo.logicalWidth; 2264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowY = (mGravity & Gravity.TOP) == Gravity.TOP ? 2274ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 0 : mDefaultDisplayInfo.logicalHeight; 2284ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowScale = INITIAL_SCALE; 2294ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2304ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private void updateWindowParams() { 2324ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown float scale = mWindowScale * mLiveScale; 2334ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown scale = Math.min(scale, (float)mDefaultDisplayInfo.logicalWidth / mWidth); 2344ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown scale = Math.min(scale, (float)mDefaultDisplayInfo.logicalHeight / mHeight); 2354ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown scale = Math.max(MIN_SCALE, Math.min(MAX_SCALE, scale)); 2364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown float offsetScale = (scale / mWindowScale - 1.0f) * 0.5f; 2384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown int width = (int)(mWidth * scale); 2394ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown int height = (int)(mHeight * scale); 2404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown int x = (int)(mWindowX + mLiveTranslationX - width * offsetScale); 2414ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown int y = (int)(mWindowY + mLiveTranslationY - height * offsetScale); 2424ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown x = Math.max(0, Math.min(x, mDefaultDisplayInfo.logicalWidth - width)); 2434ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown y = Math.max(0, Math.min(y, mDefaultDisplayInfo.logicalHeight - height)); 2444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2454ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (DEBUG) { 2464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown Slog.d(TAG, "updateWindowParams: scale=" + scale 2474ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown + ", offsetScale=" + offsetScale 2484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown + ", x=" + x + ", y=" + y 2494ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown + ", width=" + width + ", height=" + height); 2504ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2514ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2524ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.setScaleX(scale); 2534ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mTextureView.setScaleY(scale); 2544ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2554ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.x = x; 2564ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.y = y; 2574ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.width = width; 2584ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowParams.height = height; 2594ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2604ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2614ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private void saveWindowParams() { 2624ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowX = mWindowParams.x; 2634ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowY = mWindowParams.y; 2644ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mWindowScale = mTextureView.getScaleX(); 2654ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown clearLiveState(); 2664ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2674ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2684ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private void clearLiveState() { 2694ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mLiveTranslationX = 0f; 2704ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mLiveTranslationY = 0f; 2714ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mLiveScale = 1.0f; 2724ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2734ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2744ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final DisplayManager.DisplayListener mDisplayListener = 2754ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown new DisplayManager.DisplayListener() { 2764ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 2774ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void onDisplayAdded(int displayId) { 2784ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2794ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 2814ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void onDisplayChanged(int displayId) { 2824ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (displayId == mDefaultDisplay.getDisplayId()) { 2834ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (updateDefaultDisplayInfo()) { 2844ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown relayout(); 285037c33eae74bee2774897d969d48947f9abe254fJeff Brown mListener.onStateChanged(mDefaultDisplayInfo.state); 2864ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } else { 2874ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown dismiss(); 2884ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2894ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2904ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2914ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2924ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 2934ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void onDisplayRemoved(int displayId) { 2944ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown if (displayId == mDefaultDisplay.getDisplayId()) { 2954ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown dismiss(); 2964ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2974ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2984ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown }; 2994ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3004ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final SurfaceTextureListener mSurfaceTextureListener = 3014ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown new SurfaceTextureListener() { 3024ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 303cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, 304cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown int width, int height) { 305037c33eae74bee2774897d969d48947f9abe254fJeff Brown mListener.onWindowCreated(surfaceTexture, mDefaultDisplayInfo.refreshRate, 306e8b1aeb51e1e5da64f1d4fd40f2ee1e815886fe5Andy McFadden mDefaultDisplayInfo.presentationDeadlineNanos, mDefaultDisplayInfo.state); 3074ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3084ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3094ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 310cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) { 3114ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mListener.onWindowDestroyed(); 3124ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return true; 3134ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3144ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3154ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 316cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, 317cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown int width, int height) { 3184ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3194ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3204ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 321cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { 3224ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3234ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown }; 3244ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3254ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final View.OnTouchListener mOnTouchListener = new View.OnTouchListener() { 3264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 3274ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public boolean onTouch(View view, MotionEvent event) { 3284ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // Work in screen coordinates. 3294ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown final float oldX = event.getX(); 3304ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown final float oldY = event.getY(); 3314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown event.setLocation(event.getRawX(), event.getRawY()); 3324ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3334ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mGestureDetector.onTouchEvent(event); 3344ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mScaleGestureDetector.onTouchEvent(event); 3354ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3364ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown switch (event.getActionMasked()) { 3374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown case MotionEvent.ACTION_UP: 3384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown case MotionEvent.ACTION_CANCEL: 3394ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown saveWindowParams(); 3404ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown break; 3414ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3424ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3434ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown // Revert to window coordinates. 3444ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown event.setLocation(oldX, oldY); 3454ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return true; 3464ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3474ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown }; 3484ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3494ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final GestureDetector.OnGestureListener mOnGestureListener = 3504ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown new GestureDetector.SimpleOnGestureListener() { 3514ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 3524ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public boolean onScroll(MotionEvent e1, MotionEvent e2, 3534ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown float distanceX, float distanceY) { 3544ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mLiveTranslationX -= distanceX; 3554ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mLiveTranslationY -= distanceY; 3564ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown relayout(); 3574ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return true; 3584ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3594ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown }; 3604ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3614ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown private final ScaleGestureDetector.OnScaleGestureListener mOnScaleGestureListener = 3624ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown new ScaleGestureDetector.SimpleOnScaleGestureListener() { 3634ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 3644ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public boolean onScale(ScaleGestureDetector detector) { 3654ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown mLiveScale *= detector.getScaleFactor(); 3664ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown relayout(); 3674ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return true; 3684ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3694ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown }; 3704ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3714ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown /** 3724ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * Watches for significant changes in the overlay display window lifecycle. 3734ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown */ 3744ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public interface Listener { 375037c33eae74bee2774897d969d48947f9abe254fJeff Brown public void onWindowCreated(SurfaceTexture surfaceTexture, 376e8b1aeb51e1e5da64f1d4fd40f2ee1e815886fe5Andy McFadden float refreshRate, long presentationDeadlineNanos, int state); 3774ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public void onWindowDestroyed(); 378037c33eae74bee2774897d969d48947f9abe254fJeff Brown public void onStateChanged(int state); 3794ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3804ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown}