154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project/* 254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * 454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * you may not use this file except in compliance with the License. 654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * You may obtain a copy of the License at 754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * 854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * 1054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * See the License for the specific language governing permissions and 1454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * limitations under the License. 1554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */ 1654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 1754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectpackage android.view; 1854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 1972c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackbornimport com.android.internal.view.BaseIWindow; 2072c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn 2154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.content.Context; 22e36d6e277e49475076b7872d36ea6a5c5b996e9dDianne Hackbornimport android.content.res.Configuration; 2364f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshimaimport android.content.res.CompatibilityInfo.Translator; 2454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.Canvas; 2554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.PixelFormat; 2654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.PorterDuff; 2754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.Rect; 2854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.Region; 2954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.os.Handler; 3054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.os.Message; 3154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.os.RemoteException; 3254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.os.SystemClock; 3354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.os.ParcelFileDescriptor; 3454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.util.AttributeSet; 3554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.util.Log; 3654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 379bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimerimport java.lang.ref.WeakReference; 389bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimerimport java.util.ArrayList; 3954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport java.util.concurrent.locks.ReentrantLock; 4054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 4154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project/** 4254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Provides a dedicated drawing surface embedded inside of a view hierarchy. 4354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * You can control the format of this surface and, if you like, its size; the 4454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * SurfaceView takes care of placing the surface at the correct location on the 4554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * screen 46a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin * 4754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p>The surface is Z ordered so that it is behind the window holding its 4854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * SurfaceView; the SurfaceView punches a hole in its window to allow its 49c9f345ff7bc59916d5168d49d9312b2ff7a07daaJesse Hall * surface to be displayed. The view hierarchy will take care of correctly 5054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * compositing with the Surface any siblings of the SurfaceView that would 51c9f345ff7bc59916d5168d49d9312b2ff7a07daaJesse Hall * normally appear on top of it. This can be used to place overlays such as 5254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * buttons on top of the Surface, though note however that it can have an 5354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * impact on performance since a full alpha-blended composite will be performed 5454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * each time the Surface changes. 55a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin * 56c9f345ff7bc59916d5168d49d9312b2ff7a07daaJesse Hall * <p> The transparent region that makes the surface visible is based on the 57c9f345ff7bc59916d5168d49d9312b2ff7a07daaJesse Hall * layout positions in the view hierarchy. If the post-layout transform 58c9f345ff7bc59916d5168d49d9312b2ff7a07daaJesse Hall * properties are used to draw a sibling view on top of the SurfaceView, the 59c9f345ff7bc59916d5168d49d9312b2ff7a07daaJesse Hall * view may not be properly composited with the surface. 60c9f345ff7bc59916d5168d49d9312b2ff7a07daaJesse Hall * 6154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p>Access to the underlying surface is provided via the SurfaceHolder interface, 6254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * which can be retrieved by calling {@link #getHolder}. 63a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin * 6454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p>The Surface will be created for you while the SurfaceView's window is 6554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * visible; you should implement {@link SurfaceHolder.Callback#surfaceCreated} 6654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * and {@link SurfaceHolder.Callback#surfaceDestroyed} to discover when the 6754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Surface is created and destroyed as the window is shown and hidden. 68a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin * 6954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p>One of the purposes of this class is to provide a surface in which a 70c9f345ff7bc59916d5168d49d9312b2ff7a07daaJesse Hall * secondary thread can render into the screen. If you are going to use it 7154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * this way, you need to be aware of some threading semantics: 72a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin * 7354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <ul> 7454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <li> All SurfaceView and 7554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * {@link SurfaceHolder.Callback SurfaceHolder.Callback} methods will be called 7654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * from the thread running the SurfaceView's window (typically the main thread 77c9f345ff7bc59916d5168d49d9312b2ff7a07daaJesse Hall * of the application). They thus need to correctly synchronize with any 7854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * state that is also touched by the drawing thread. 7954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <li> You must ensure that the drawing thread only touches the underlying 8054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Surface while it is valid -- between 8154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * {@link SurfaceHolder.Callback#surfaceCreated SurfaceHolder.Callback.surfaceCreated()} 8254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * and 8354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * {@link SurfaceHolder.Callback#surfaceDestroyed SurfaceHolder.Callback.surfaceDestroyed()}. 8454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * </ul> 856ee192f4e981845db5fdff127bf2ee990cd05dbfChris Craik * 866ee192f4e981845db5fdff127bf2ee990cd05dbfChris Craik * <p class="note"><strong>Note:</strong> Starting in platform version 876ee192f4e981845db5fdff127bf2ee990cd05dbfChris Craik * {@link android.os.Build.VERSION_CODES#N}, SurfaceView's window position is 886ee192f4e981845db5fdff127bf2ee990cd05dbfChris Craik * updated synchronously with other View rendering. This means that translating 896ee192f4e981845db5fdff127bf2ee990cd05dbfChris Craik * and scaling a SurfaceView on screen will not cause rendering artifacts. Such 906ee192f4e981845db5fdff127bf2ee990cd05dbfChris Craik * artifacts may occur on previous versions of the platform when its window is 916ee192f4e981845db5fdff127bf2ee990cd05dbfChris Craik * positioned asynchronously.</p> 9254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */ 9354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectpublic class SurfaceView extends View { 9454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project static private final String TAG = "SurfaceView"; 9554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project static private final boolean DEBUG = false; 9654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 9754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final ArrayList<SurfaceHolder.Callback> mCallbacks 9854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project = new ArrayList<SurfaceHolder.Callback>(); 9954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 100f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project final int[] mLocation = new int[2]; 101a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 10254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final ReentrantLock mSurfaceLock = new ReentrantLock(); 10361566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn final Surface mSurface = new Surface(); // Current surface in use 10461566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn final Surface mNewSurface = new Surface(); // New surface we are switching to 10554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project boolean mDrawingStopped = true; 10654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 10754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final WindowManager.LayoutParams mLayout 10854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project = new WindowManager.LayoutParams(); 10954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project IWindowSession mSession; 11054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project MyWindow mWindow; 111f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project final Rect mVisibleInsets = new Rect(); 11254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final Rect mWinFrame = new Rect(); 113c4aad01cbbb69c916ef323693e1fd0560b0eccbaDianne Hackborn final Rect mOverscanInsets = new Rect(); 114f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project final Rect mContentInsets = new Rect(); 115fa10423fa00f3495e451016acba9b6848eb995c9Adrian Roos final Rect mStableInsets = new Rect(); 1162217f61e51ba4b19c56b19297c1e9cf74d7d860fFilip Gruszczynski final Rect mOutsets = new Rect(); 1172e95a488e0a12d4263d101e888fdd89fd123aec3Jorim Jaggi final Rect mBackdropFrame = new Rect(); 118694f79b5d1196640d1beb680b7d1fc68e6e77cbdDianne Hackborn final Configuration mConfiguration = new Configuration(); 119a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 12054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project static final int KEEP_SCREEN_ON_MSG = 1; 12154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project static final int GET_NEW_SURFACE_MSG = 2; 122726426ee736929e605742bfa52bca4b20095921dDianne Hackborn static final int UPDATE_WINDOW_MSG = 3; 123a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 124c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn int mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA; 125a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 12654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project boolean mIsCreating = false; 127f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck private volatile boolean mRtHandlingPositionUpdates = false; 12854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 12954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final Handler mHandler = new Handler() { 13054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 13154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void handleMessage(Message msg) { 13254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project switch (msg.what) { 13354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project case KEEP_SCREEN_ON_MSG: { 13454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project setKeepScreenOn(msg.arg1 != 0); 13554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } break; 13654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project case GET_NEW_SURFACE_MSG: { 13754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project handleGetNewSurface(); 13854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } break; 139726426ee736929e605742bfa52bca4b20095921dDianne Hackborn case UPDATE_WINDOW_MSG: { 140d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn updateWindow(false, false); 141726426ee736929e605742bfa52bca4b20095921dDianne Hackborn } break; 14254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 14354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 14454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project }; 145a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 146f648108f83d4e74811919e9811efb8fcc184b8a3John Reck private final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener 147e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn = new ViewTreeObserver.OnScrollChangedListener() { 148a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 149e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn public void onScrollChanged() { 150d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn updateWindow(false, false); 151e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn } 152e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn }; 153a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 154f648108f83d4e74811919e9811efb8fcc184b8a3John Reck private final ViewTreeObserver.OnPreDrawListener mDrawListener = 155f648108f83d4e74811919e9811efb8fcc184b8a3John Reck new ViewTreeObserver.OnPreDrawListener() { 156f648108f83d4e74811919e9811efb8fcc184b8a3John Reck @Override 157f648108f83d4e74811919e9811efb8fcc184b8a3John Reck public boolean onPreDraw() { 158f648108f83d4e74811919e9811efb8fcc184b8a3John Reck // reposition ourselves where the surface is 159f648108f83d4e74811919e9811efb8fcc184b8a3John Reck mHaveFrame = getWidth() > 0 && getHeight() > 0; 160f648108f83d4e74811919e9811efb8fcc184b8a3John Reck updateWindow(false, false); 161f648108f83d4e74811919e9811efb8fcc184b8a3John Reck return true; 162f648108f83d4e74811919e9811efb8fcc184b8a3John Reck } 163f648108f83d4e74811919e9811efb8fcc184b8a3John Reck }; 164f648108f83d4e74811919e9811efb8fcc184b8a3John Reck 16554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project boolean mRequestedVisible = false; 1666b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian boolean mWindowVisibility = false; 1676b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian boolean mViewVisibility = false; 16854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int mRequestedWidth = -1; 16954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int mRequestedHeight = -1; 170d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian /* Set SurfaceView's format to 565 by default to maintain backward 171d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian * compatibility with applications assuming this format. 172d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian */ 173d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian int mRequestedFormat = PixelFormat.RGB_565; 17454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 17554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project boolean mHaveFrame = false; 1766d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn boolean mSurfaceCreated = false; 17754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project long mLastLockTime = 0; 178a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 17954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project boolean mVisible = false; 18064aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr int mWindowSpaceLeft = -1; 18164aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr int mWindowSpaceTop = -1; 18264aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr int mWindowSpaceWidth = -1; 18364aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr int mWindowSpaceHeight = -1; 18454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int mFormat = -1; 18554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final Rect mSurfaceFrame = new Rect(); 186726426ee736929e605742bfa52bca4b20095921dDianne Hackborn int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1; 187726426ee736929e605742bfa52bca4b20095921dDianne Hackborn boolean mUpdateWindowNeeded; 188726426ee736929e605742bfa52bca4b20095921dDianne Hackborn boolean mReportDrawNeeded; 18964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima private Translator mTranslator; 190f648108f83d4e74811919e9811efb8fcc184b8a3John Reck private int mWindowInsetLeft; 191f648108f83d4e74811919e9811efb8fcc184b8a3John Reck private int mWindowInsetTop; 192f2499fa434521a8948387afe8f0acd4f39620500Romain Guy 19301d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy private boolean mGlobalListenersAdded; 194f2499fa434521a8948387afe8f0acd4f39620500Romain Guy 19554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public SurfaceView(Context context) { 19654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super(context); 197d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian init(); 19854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 199a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 20054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public SurfaceView(Context context, AttributeSet attrs) { 20154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super(context, attrs); 202d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian init(); 20354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 20454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 205617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public SurfaceView(Context context, AttributeSet attrs, int defStyleAttr) { 206617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette super(context, attrs, defStyleAttr); 207617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette init(); 208617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette } 209617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette 210617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public SurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 211617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette super(context, attrs, defStyleAttr, defStyleRes); 212d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian init(); 213d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian } 214d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian 215d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian private void init() { 21654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project setWillNotDraw(true); 21754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 218a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 21954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project /** 22054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Return the SurfaceHolder providing access and control over this 22154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * SurfaceView's underlying surface. 222a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin * 22354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * @return SurfaceHolder The holder of the surface. 22454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */ 22554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public SurfaceHolder getHolder() { 22654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return mSurfaceHolder; 22754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 22854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 22954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 23054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project protected void onAttachedToWindow() { 23154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super.onAttachedToWindow(); 23254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mParent.requestTransparentRegion(this); 23354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSession = getWindowSession(); 23454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLayout.token = getWindowToken(); 235afeea9ba50bf2a60ccd9e6fcfb5f2efa880f4079John Reck mLayout.setTitle("SurfaceView - " + getViewRootImpl().getTitle()); 2366b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian mViewVisibility = getVisibility() == VISIBLE; 23701d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy 23801d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy if (!mGlobalListenersAdded) { 23901d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy ViewTreeObserver observer = getViewTreeObserver(); 24001d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy observer.addOnScrollChangedListener(mScrollChangedListener); 24101d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy observer.addOnPreDrawListener(mDrawListener); 24201d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy mGlobalListenersAdded = true; 24301d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy } 24454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 24554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 24654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 24754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project protected void onWindowVisibilityChanged(int visibility) { 24854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super.onWindowVisibilityChanged(visibility); 2496b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian mWindowVisibility = visibility == VISIBLE; 2506b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian mRequestedVisible = mWindowVisibility && mViewVisibility; 251d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn updateWindow(false, false); 2526b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian } 2536b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian 2546b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian @Override 2556b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian public void setVisibility(int visibility) { 2566b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian super.setVisibility(visibility); 2576b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian mViewVisibility = visibility == VISIBLE; 258cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian boolean newRequestedVisible = mWindowVisibility && mViewVisibility; 259cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian if (newRequestedVisible != mRequestedVisible) { 260cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian // our base class (View) invalidates the layout only when 261cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian // we go from/to the GONE state. However, SurfaceView needs 262cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian // to request a re-layout when the visibility changes at all. 263cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian // This is needed because the transparent region is computed 264cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian // as part of the layout phase, and it changes (obviously) when 265cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian // the visibility changes. 266cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian requestLayout(); 267cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian } 268cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian mRequestedVisible = newRequestedVisible; 269d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn updateWindow(false, false); 27054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 271afc3e11f10828e113331eb24b65e4f9759f67747Romain Guy 27254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 27377e4a5250fc6df451999efe508f57968a44b603fJohn Reck protected void onDetachedFromWindow() { 27401d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy if (mGlobalListenersAdded) { 27501d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy ViewTreeObserver observer = getViewTreeObserver(); 27601d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy observer.removeOnScrollChangedListener(mScrollChangedListener); 27701d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy observer.removeOnPreDrawListener(mDrawListener); 27801d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy mGlobalListenersAdded = false; 27901d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy } 28001d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy 28154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mRequestedVisible = false; 282d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn updateWindow(false, false); 28354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mHaveFrame = false; 28454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (mWindow != null) { 28554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project try { 28654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSession.remove(mWindow); 28754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } catch (RemoteException ex) { 28801d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy // Not much we can do here... 28954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 29054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mWindow = null; 29154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 29254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSession = null; 29354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLayout.token = null; 29454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 29577e4a5250fc6df451999efe508f57968a44b603fJohn Reck super.onDetachedFromWindow(); 29654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 29754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 29854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 29954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 300189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn int width = mRequestedWidth >= 0 301189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn ? resolveSizeAndState(mRequestedWidth, widthMeasureSpec, 0) 302189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn : getDefaultSize(0, widthMeasureSpec); 303189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn int height = mRequestedHeight >= 0 304189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn ? resolveSizeAndState(mRequestedHeight, heightMeasureSpec, 0) 305189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn : getDefaultSize(0, heightMeasureSpec); 30654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project setMeasuredDimension(width, height); 30754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 308a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 309ef11530874f86570aa04a10c16a416b274b3fdf5Mathias Agopian /** @hide */ 31054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 311995bb9d24d3b278939a01e1d05c2b7f337ab0565Mathias Agopian protected boolean setFrame(int left, int top, int right, int bottom) { 312995bb9d24d3b278939a01e1d05c2b7f337ab0565Mathias Agopian boolean result = super.setFrame(left, top, right, bottom); 313d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn updateWindow(false, false); 314995bb9d24d3b278939a01e1d05c2b7f337ab0565Mathias Agopian return result; 31554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 31654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 31754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 31854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public boolean gatherTransparentRegion(Region region) { 3191cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn if (mWindowType == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) { 3201cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn return super.gatherTransparentRegion(region); 3211cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn } 322a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 32354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project boolean opaque = true; 3244702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn if ((mPrivateFlags & PFLAG_SKIP_DRAW) == 0) { 32554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // this view draws, remove it from the transparent region 32654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project opaque = super.gatherTransparentRegion(region); 32754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } else if (region != null) { 32854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int w = getWidth(); 32954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int h = getHeight(); 33054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (w>0 && h>0) { 33154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project getLocationInWindow(mLocation); 33254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // otherwise, punch a hole in the whole hierarchy 33354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int l = mLocation[0]; 33454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int t = mLocation[1]; 33554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project region.op(l, t, l+w, t+h, Region.Op.UNION); 33654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 33754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 33854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (PixelFormat.formatHasAlpha(mRequestedFormat)) { 33954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project opaque = false; 34054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 34154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return opaque; 34254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 34354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 34454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 34554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void draw(Canvas canvas) { 3461cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) { 3471cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn // draw() is not called when SKIP_DRAW is set 3484702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn if ((mPrivateFlags & PFLAG_SKIP_DRAW) == 0) { 3491cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn // punch a whole in the view-hierarchy below us 3501cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn canvas.drawColor(0, PorterDuff.Mode.CLEAR); 3511cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn } 35254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 35354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super.draw(canvas); 35454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 35554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 35654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 35754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project protected void dispatchDraw(Canvas canvas) { 3581cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) { 3591cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn // if SKIP_DRAW is cleared, draw() has already punched a hole 3604702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) { 3611cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn // punch a whole in the view-hierarchy below us 3621cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn canvas.drawColor(0, PorterDuff.Mode.CLEAR); 3631cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn } 36454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 36554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super.dispatchDraw(canvas); 36654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 36754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 368c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn /** 36929e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn * Control whether the surface view's surface is placed on top of another 37029e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn * regular surface view in the window (but still behind the window itself). 37129e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn * This is typically used to place overlays on top of an underlying media 37229e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn * surface view. 373a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin * 37429e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn * <p>Note that this must be set before the surface view's containing 37529e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn * window is attached to the window manager. 376a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin * 37729e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn * <p>Calling this overrides any previous call to {@link #setZOrderOnTop}. 37829e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn */ 37929e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn public void setZOrderMediaOverlay(boolean isMediaOverlay) { 38029e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn mWindowType = isMediaOverlay 38129e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn ? WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY 38229e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn : WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA; 38329e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn } 384a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 38529e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn /** 3861cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn * Control whether the surface view's surface is placed on top of its 3871cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn * window. Normally it is placed behind the window, to allow it to 3881cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn * (for the most part) appear to composite with the views in the 3891cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn * hierarchy. By setting this, you cause it to be placed above the 3901cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn * window. This means that none of the contents of the window this 3911cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn * SurfaceView is in will be visible on top of its surface. 392a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin * 3931cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn * <p>Note that this must be set before the surface view's containing 3941cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn * window is attached to the window manager. 395a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin * 39629e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn * <p>Calling this overrides any previous call to {@link #setZOrderMediaOverlay}. 3971cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn */ 39829e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn public void setZOrderOnTop(boolean onTop) { 399ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger if (onTop) { 400ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; 401ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger // ensures the surface is placed below the IME 402ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger mLayout.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 403ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger } else { 404ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA; 405ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger mLayout.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 406ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger } 4071cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn } 408f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown 409f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown /** 410f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown * Control whether the surface view's content should be treated as secure, 411f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown * preventing it from appearing in screenshots or from being viewed on 412f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown * non-secure displays. 413f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown * 414f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown * <p>Note that this must be set before the surface view's containing 415f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown * window is attached to the window manager. 416f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown * 417f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown * <p>See {@link android.view.Display#FLAG_SECURE} for details. 418f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown * 419f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown * @param isSecure True if the surface view is secure. 420f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown */ 421f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown public void setSecure(boolean isSecure) { 422f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown if (isSecure) { 423f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown mLayout.flags |= WindowManager.LayoutParams.FLAG_SECURE; 424f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown } else { 425f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown mLayout.flags &= ~WindowManager.LayoutParams.FLAG_SECURE; 426f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown } 427f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown } 428f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown 4291cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn /** 430c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn * Hack to allow special layering of windows. The type is one of the 431c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn * types in WindowManager.LayoutParams. This is a hack so: 432c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn * @hide 433c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn */ 434c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn public void setWindowType(int type) { 435c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn mWindowType = type; 436c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn } 43734bf2ee9e695c620e0a4b9a790f1f6ccb8a77234Mitsuru Oshima 4389a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho /** @hide */ 4399a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho protected void updateWindow(boolean force, boolean redrawNeeded) { 44054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (!mHaveFrame) { 44154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return; 44254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 443a175a5b7ea3682cb58cca7f9726d0b8171cd549dJeff Brown ViewRootImpl viewRoot = getViewRootImpl(); 444168173a698e820ceb1ebf54b4910888891be2056Joe Onorato if (viewRoot != null) { 445168173a698e820ceb1ebf54b4910888891be2056Joe Onorato mTranslator = viewRoot.mTranslator; 446168173a698e820ceb1ebf54b4910888891be2056Joe Onorato } 44764f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 4485be8de3420ba4c9d816b98e29bdec11715f6b626Dianne Hackborn if (mTranslator != null) { 4495be8de3420ba4c9d816b98e29bdec11715f6b626Dianne Hackborn mSurface.setCompatibilityTranslator(mTranslator); 45038ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima } 451a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 45254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int myWidth = mRequestedWidth; 45354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (myWidth <= 0) myWidth = getWidth(); 45454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int myHeight = mRequestedHeight; 45554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (myHeight <= 0) myHeight = getHeight(); 456001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima 45754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final boolean creating = mWindow == null; 45854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final boolean formatChanged = mFormat != mRequestedFormat; 45964aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr final boolean sizeChanged = mWindowSpaceWidth != myWidth || mWindowSpaceHeight != myHeight; 4606d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn final boolean visibleChanged = mVisible != mRequestedVisible; 46164aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr final boolean layoutSizeChanged = getWidth() != mLayout.width 46264aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr || getHeight() != mLayout.height; 463d2112306330ce0c162bee4b864991962ca2b655aMathias Agopian 46454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (force || creating || formatChanged || sizeChanged || visibleChanged 46564aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr || mUpdateWindowNeeded || mReportDrawNeeded || redrawNeeded) { 466f648108f83d4e74811919e9811efb8fcc184b8a3John Reck getLocationInWindow(mLocation); 467f648108f83d4e74811919e9811efb8fcc184b8a3John Reck 46834bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " 46934bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck + "Changes: creating=" + creating 47054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project + " format=" + formatChanged + " size=" + sizeChanged 47154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project + " visible=" + visibleChanged 47264aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr + " left=" + (mWindowSpaceLeft != mLocation[0]) 47364aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr + " top=" + (mWindowSpaceTop != mLocation[1])); 47464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 47554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project try { 47654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final boolean visible = mVisible = mRequestedVisible; 47764aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mWindowSpaceLeft = mLocation[0]; 47864aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mWindowSpaceTop = mLocation[1]; 47964aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mWindowSpaceWidth = myWidth; 48064aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mWindowSpaceHeight = myHeight; 48154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mFormat = mRequestedFormat; 48254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 48364f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima // Scaling/Translate window's layout here because mLayout is not used elsewhere. 484a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 48564f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima // Places the window relative 48664aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mLayout.x = mWindowSpaceLeft; 48764aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mLayout.y = mWindowSpaceTop; 48864f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima mLayout.width = getWidth(); 48964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima mLayout.height = getHeight(); 49064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima if (mTranslator != null) { 49164f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima mTranslator.translateLayoutParamsInAppWindowToScreen(mLayout); 49264f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima } 493a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 49454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLayout.format = mRequestedFormat; 4951cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn mLayout.flags |=WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE 4961cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 4971cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS 49854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project | WindowManager.LayoutParams.FLAG_SCALED 49954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 50054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE 50154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project ; 5020b10c335c72cb610e71432a61f315e7670b9af41Robert Carr if (!creating && !force && !mUpdateWindowNeeded && !sizeChanged) { 50364aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mLayout.privateFlags |= 50464aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY; 50564aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr } else { 50664aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mLayout.privateFlags &= 50764aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr ~WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY; 50864aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr } 50964aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr 510841f13c8e9ff3f7695b6c18a8abcec3c947983ffMitsuru Oshima if (!getContext().getResources().getCompatibilityInfo().supportsScreen()) { 51195c42974f719d1fac90fc0438eac778e9795681fAdam Lesinski mLayout.privateFlags |= 51295c42974f719d1fac90fc0438eac778e9795681fAdam Lesinski WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; 513841f13c8e9ff3f7695b6c18a8abcec3c947983ffMitsuru Oshima } 514d86c63a25e54e419bcd001f2ea98b0744e8b17d8Robert Carr mLayout.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION 515d86c63a25e54e419bcd001f2ea98b0744e8b17d8Robert Carr | WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME; 51654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 51754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (mWindow == null) { 5188d0243a3d0269d3a57d90eb2e7b12b41f53b27d9Jeff Brown Display display = getDisplay(); 5199bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer mWindow = new MyWindow(this); 520c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn mLayout.type = mWindowType; 521aac0d4ed026d1cfbcf3fa81c6e4eb96f4347ca17Fabrice Di Meglio mLayout.gravity = Gravity.START|Gravity.TOP; 5226881a10557acf3b0270de54799d6f19437acf584Craig Mautner mSession.addToDisplayWithoutInputChannel(mWindow, mWindow.mSeq, mLayout, 52337d7a68de7e353c31a3a4736054cd86f0e002eafAdrian Roos mVisible ? VISIBLE : GONE, display.getDisplayId(), mContentInsets, 52437d7a68de7e353c31a3a4736054cd86f0e002eafAdrian Roos mStableInsets); 52554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 526a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 527726426ee736929e605742bfa52bca4b20095921dDianne Hackborn boolean realSizeChanged; 528726426ee736929e605742bfa52bca4b20095921dDianne Hackborn boolean reportDrawNeeded; 5296d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn 5306d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn int relayoutResult; 5316d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn 532726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mSurfaceLock.lock(); 533726426ee736929e605742bfa52bca4b20095921dDianne Hackborn try { 534726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mUpdateWindowNeeded = false; 535726426ee736929e605742bfa52bca4b20095921dDianne Hackborn reportDrawNeeded = mReportDrawNeeded; 536726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mReportDrawNeeded = false; 537726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mDrawingStopped = !visible; 538a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 53934bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " 54034bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck + "Cur surface: " + mSurface); 5416d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn 5426d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn relayoutResult = mSession.relayout( 54364aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mWindow, mWindow.mSeq, mLayout, mWindowSpaceWidth, mWindowSpaceHeight, 5446d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn visible ? VISIBLE : GONE, 54598365d7663cbd82979a5700faf0050220b01084dJeff Brown WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY, 546c4aad01cbbb69c916ef323693e1fd0560b0eccbaDianne Hackborn mWinFrame, mOverscanInsets, mContentInsets, 5472e95a488e0a12d4263d101e888fdd89fd123aec3Jorim Jaggi mVisibleInsets, mStableInsets, mOutsets, mBackdropFrame, 5482e95a488e0a12d4263d101e888fdd89fd123aec3Jorim Jaggi mConfiguration, mNewSurface); 54998365d7663cbd82979a5700faf0050220b01084dJeff Brown if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) { 5506fa9512e349ef1efbf4558da9e8418a842ab6201John Reck reportDrawNeeded = true; 551726426ee736929e605742bfa52bca4b20095921dDianne Hackborn } 5526d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn 55334bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " 55434bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck + "New surface: " + mNewSurface 555726426ee736929e605742bfa52bca4b20095921dDianne Hackborn + ", vis=" + visible + ", frame=" + mWinFrame); 5566d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn 557726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mSurfaceFrame.left = 0; 558726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mSurfaceFrame.top = 0; 559726426ee736929e605742bfa52bca4b20095921dDianne Hackborn if (mTranslator == null) { 560726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mSurfaceFrame.right = mWinFrame.width(); 561726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mSurfaceFrame.bottom = mWinFrame.height(); 562726426ee736929e605742bfa52bca4b20095921dDianne Hackborn } else { 563726426ee736929e605742bfa52bca4b20095921dDianne Hackborn float appInvertedScale = mTranslator.applicationInvertedScale; 564726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mSurfaceFrame.right = (int) (mWinFrame.width() * appInvertedScale + 0.5f); 565726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mSurfaceFrame.bottom = (int) (mWinFrame.height() * appInvertedScale + 0.5f); 566726426ee736929e605742bfa52bca4b20095921dDianne Hackborn } 567a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 568726426ee736929e605742bfa52bca4b20095921dDianne Hackborn final int surfaceWidth = mSurfaceFrame.right; 569726426ee736929e605742bfa52bca4b20095921dDianne Hackborn final int surfaceHeight = mSurfaceFrame.bottom; 570726426ee736929e605742bfa52bca4b20095921dDianne Hackborn realSizeChanged = mLastSurfaceWidth != surfaceWidth 571726426ee736929e605742bfa52bca4b20095921dDianne Hackborn || mLastSurfaceHeight != surfaceHeight; 572726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mLastSurfaceWidth = surfaceWidth; 573726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mLastSurfaceHeight = surfaceHeight; 574726426ee736929e605742bfa52bca4b20095921dDianne Hackborn } finally { 575726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mSurfaceLock.unlock(); 576589cebe2d58591403de4a77077941c0454bc91bcMitsuru Oshima } 57754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 57854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project try { 579d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn redrawNeeded |= creating | reportDrawNeeded; 580d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn 5816d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn SurfaceHolder.Callback callbacks[] = null; 58254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 58398365d7663cbd82979a5700faf0050220b01084dJeff Brown final boolean surfaceChanged = (relayoutResult 58498365d7663cbd82979a5700faf0050220b01084dJeff Brown & WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED) != 0; 5856d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (mSurfaceCreated && (surfaceChanged || (!visible && visibleChanged))) { 5866d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn mSurfaceCreated = false; 5876d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (mSurface.isValid()) { 58834bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " 58934bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck + "visibleChanged -- surfaceDestroyed"); 5906d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn callbacks = getSurfaceCallbacks(); 5916d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn for (SurfaceHolder.Callback c : callbacks) { 5926d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn c.surfaceDestroyed(mSurfaceHolder); 5936d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn } 5943d91492d694cf00474fec792134e496be6ee0313Mitsuru Oshima } 5956d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn } 5966d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn 59761566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn mSurface.transferFrom(mNewSurface); 598f750b8ce3c8cb30bcbc5fe53087c7e9035078ebaAndreas Röhl if (visible && mSurface.isValid()) { 5996d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (!mSurfaceCreated && (surfaceChanged || visibleChanged)) { 6006d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn mSurfaceCreated = true; 60154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mIsCreating = true; 60234bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " 60334bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck + "visibleChanged -- surfaceCreated"); 6046d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (callbacks == null) { 6056d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn callbacks = getSurfaceCallbacks(); 6066d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn } 60754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project for (SurfaceHolder.Callback c : callbacks) { 60854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project c.surfaceCreated(mSurfaceHolder); 60954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 61054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 61154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (creating || formatChanged || sizeChanged 612726426ee736929e605742bfa52bca4b20095921dDianne Hackborn || visibleChanged || realSizeChanged) { 61334bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " 61434bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck + "surfaceChanged -- format=" + mFormat 6156d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn + " w=" + myWidth + " h=" + myHeight); 6166d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (callbacks == null) { 6176d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn callbacks = getSurfaceCallbacks(); 6186d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn } 619251fd430c7e355ad440202c83b0c6d91f5bf93e5Dianne Hackborn for (SurfaceHolder.Callback c : callbacks) { 620251fd430c7e355ad440202c83b0c6d91f5bf93e5Dianne Hackborn c.surfaceChanged(mSurfaceHolder, mFormat, myWidth, myHeight); 621251fd430c7e355ad440202c83b0c6d91f5bf93e5Dianne Hackborn } 622d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn } 623d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn if (redrawNeeded) { 62434bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " 62534bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck + "surfaceRedrawNeeded"); 6266d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (callbacks == null) { 6276d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn callbacks = getSurfaceCallbacks(); 6286d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn } 62954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project for (SurfaceHolder.Callback c : callbacks) { 630d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn if (c instanceof SurfaceHolder.Callback2) { 631d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn ((SurfaceHolder.Callback2)c).surfaceRedrawNeeded( 632d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn mSurfaceHolder); 633d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn } 63454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 63554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 63654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 63754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } finally { 63854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mIsCreating = false; 639d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn if (redrawNeeded) { 64034bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " 64134bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck + "finishedDrawing"); 64254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSession.finishDrawing(mWindow); 64354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 6446d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn mSession.performDeferredDestroy(mWindow); 64554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 64654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } catch (RemoteException ex) { 64764e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr Log.e(TAG, "Exception from relayout", ex); 64854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 6496d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (DEBUG) Log.v( 65054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y + 65154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project " w=" + mLayout.width + " h=" + mLayout.height + 65254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project ", frame=" + mSurfaceFrame); 653f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck } else { 654f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck // Calculate the window position in case RT loses the window 655f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck // and we need to fallback to a UI-thread driven position update 656f648108f83d4e74811919e9811efb8fcc184b8a3John Reck getLocationInWindow(mLocation); 657f648108f83d4e74811919e9811efb8fcc184b8a3John Reck final boolean positionChanged = mWindowSpaceLeft != mLocation[0] 658f648108f83d4e74811919e9811efb8fcc184b8a3John Reck || mWindowSpaceTop != mLocation[1]; 659f648108f83d4e74811919e9811efb8fcc184b8a3John Reck if (positionChanged || layoutSizeChanged) { // Only the position has changed 660f648108f83d4e74811919e9811efb8fcc184b8a3John Reck mWindowSpaceLeft = mLocation[0]; 661f648108f83d4e74811919e9811efb8fcc184b8a3John Reck mWindowSpaceTop = mLocation[1]; 662f648108f83d4e74811919e9811efb8fcc184b8a3John Reck // For our size changed check, we keep mLayout.width and mLayout.height 663f648108f83d4e74811919e9811efb8fcc184b8a3John Reck // in view local space. 664f648108f83d4e74811919e9811efb8fcc184b8a3John Reck mLocation[0] = mLayout.width = getWidth(); 665f648108f83d4e74811919e9811efb8fcc184b8a3John Reck mLocation[1] = mLayout.height = getHeight(); 66664aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr 667f648108f83d4e74811919e9811efb8fcc184b8a3John Reck transformFromViewToWindowSpace(mLocation); 66864aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr 669f057fb56f69f8cb1bdee086c73f9d4efe8e331c4John Reck mWinFrame.set(mWindowSpaceLeft, mWindowSpaceTop, 670f057fb56f69f8cb1bdee086c73f9d4efe8e331c4John Reck mLocation[0], mLocation[1]); 671f057fb56f69f8cb1bdee086c73f9d4efe8e331c4John Reck 672f057fb56f69f8cb1bdee086c73f9d4efe8e331c4John Reck if (mTranslator != null) { 673f057fb56f69f8cb1bdee086c73f9d4efe8e331c4John Reck mTranslator.translateRectInAppWindowToScreen(mWinFrame); 674f057fb56f69f8cb1bdee086c73f9d4efe8e331c4John Reck } 675f057fb56f69f8cb1bdee086c73f9d4efe8e331c4John Reck 676f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck if (!isHardwareAccelerated() || !mRtHandlingPositionUpdates) { 677f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck try { 678f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck if (DEBUG) Log.d(TAG, String.format("%d updateWindowPosition UI, " + 679f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck "postion = [%d, %d, %d, %d]", System.identityHashCode(this), 680f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck mWinFrame.left, mWinFrame.top, 681f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck mWinFrame.right, mWinFrame.bottom)); 682f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck mSession.repositionChild(mWindow, mWinFrame.left, mWinFrame.top, 683f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck mWinFrame.right, mWinFrame.bottom, -1, mWinFrame); 684f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck } catch (RemoteException ex) { 685f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck Log.e(TAG, "Exception from relayout", ex); 686f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck } 687f648108f83d4e74811919e9811efb8fcc184b8a3John Reck } 688f648108f83d4e74811919e9811efb8fcc184b8a3John Reck } 689f648108f83d4e74811919e9811efb8fcc184b8a3John Reck } 690f648108f83d4e74811919e9811efb8fcc184b8a3John Reck } 691f648108f83d4e74811919e9811efb8fcc184b8a3John Reck 692f648108f83d4e74811919e9811efb8fcc184b8a3John Reck private Rect mRTLastReportedPosition = new Rect(); 693f648108f83d4e74811919e9811efb8fcc184b8a3John Reck 694f648108f83d4e74811919e9811efb8fcc184b8a3John Reck /** 695f648108f83d4e74811919e9811efb8fcc184b8a3John Reck * Called by native on RenderThread to update the window position 696f648108f83d4e74811919e9811efb8fcc184b8a3John Reck * @hide 697f648108f83d4e74811919e9811efb8fcc184b8a3John Reck */ 698f648108f83d4e74811919e9811efb8fcc184b8a3John Reck public final void updateWindowPositionRT(long frameNumber, 699f648108f83d4e74811919e9811efb8fcc184b8a3John Reck int left, int top, int right, int bottom) { 700f648108f83d4e74811919e9811efb8fcc184b8a3John Reck IWindowSession session = mSession; 701f648108f83d4e74811919e9811efb8fcc184b8a3John Reck MyWindow window = mWindow; 702f648108f83d4e74811919e9811efb8fcc184b8a3John Reck if (session == null || window == null) { 703f648108f83d4e74811919e9811efb8fcc184b8a3John Reck // Guess we got detached, that sucks 704f648108f83d4e74811919e9811efb8fcc184b8a3John Reck return; 705f648108f83d4e74811919e9811efb8fcc184b8a3John Reck } 706f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck // TODO: This is teensy bit racey in that a brand new SurfaceView moving on 707f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck // its 2nd frame if RenderThread is running slowly could potentially see 708f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck // this as false, enter the branch, get pre-empted, then this comes along 709f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck // and reports a new position, then the UI thread resumes and reports 710f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck // its position. This could therefore be de-sync'd in that interval, but 711f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck // the synchronization would violate the rule that RT must never block 712f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck // on the UI thread which would open up potential deadlocks. The risk of 713f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck // a single-frame desync is therefore preferable for now. 714f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck mRtHandlingPositionUpdates = true; 715f648108f83d4e74811919e9811efb8fcc184b8a3John Reck if (mRTLastReportedPosition.left == left 716f648108f83d4e74811919e9811efb8fcc184b8a3John Reck && mRTLastReportedPosition.top == top 717f648108f83d4e74811919e9811efb8fcc184b8a3John Reck && mRTLastReportedPosition.right == right 718f648108f83d4e74811919e9811efb8fcc184b8a3John Reck && mRTLastReportedPosition.bottom == bottom) { 719f648108f83d4e74811919e9811efb8fcc184b8a3John Reck return; 720f648108f83d4e74811919e9811efb8fcc184b8a3John Reck } 721f648108f83d4e74811919e9811efb8fcc184b8a3John Reck try { 722f648108f83d4e74811919e9811efb8fcc184b8a3John Reck if (DEBUG) { 72334bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck Log.d(TAG, String.format("%d updateWindowPosition RT, frameNr = %d, " + 72434bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck "postion = [%d, %d, %d, %d]", System.identityHashCode(this), 72534bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck frameNumber, left, top, right, bottom)); 72664e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr } 727f648108f83d4e74811919e9811efb8fcc184b8a3John Reck // Just using mRTLastReportedPosition as a dummy rect here 7286136273888c42faad74dce19ec49904a55affc15Chong Zhang session.repositionChild(window, left, top, right, bottom, 7296136273888c42faad74dce19ec49904a55affc15Chong Zhang frameNumber, 730f648108f83d4e74811919e9811efb8fcc184b8a3John Reck mRTLastReportedPosition); 731f648108f83d4e74811919e9811efb8fcc184b8a3John Reck // Now overwrite mRTLastReportedPosition with our values 732f648108f83d4e74811919e9811efb8fcc184b8a3John Reck mRTLastReportedPosition.set(left, top, right, bottom); 733f648108f83d4e74811919e9811efb8fcc184b8a3John Reck } catch (RemoteException ex) { 734f648108f83d4e74811919e9811efb8fcc184b8a3John Reck Log.e(TAG, "Exception from repositionChild", ex); 73554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 73654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 73754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 73834bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck /** 73934bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck * Called by native on RenderThread to notify that the window is no longer in the 74034bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck * draw tree 74134bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck * @hide 74234bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck */ 74334bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck public final void windowPositionLostRT(long frameNumber) { 74434bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck if (DEBUG) { 74534bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck Log.d(TAG, String.format("%d windowPositionLostRT RT, frameNr = %d", 74634bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck System.identityHashCode(this), frameNumber)); 74734bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck } 748474659ccc421aaacfa49a742891aefed46c6f5d2John Reck IWindowSession session = mSession; 749474659ccc421aaacfa49a742891aefed46c6f5d2John Reck MyWindow window = mWindow; 750474659ccc421aaacfa49a742891aefed46c6f5d2John Reck if (session == null || window == null) { 751474659ccc421aaacfa49a742891aefed46c6f5d2John Reck // We got detached prior to receiving this, abort 752474659ccc421aaacfa49a742891aefed46c6f5d2John Reck return; 753474659ccc421aaacfa49a742891aefed46c6f5d2John Reck } 754f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck if (mRtHandlingPositionUpdates) { 755f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck mRtHandlingPositionUpdates = false; 756f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck // This callback will happen while the UI thread is blocked, so we can 757f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck // safely access other member variables at this time. 758f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck // So do what the UI thread would have done if RT wasn't handling position 759f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck // updates. 760f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck if (!mWinFrame.isEmpty() && !mWinFrame.equals(mRTLastReportedPosition)) { 761f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck try { 762f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck if (DEBUG) Log.d(TAG, String.format("%d updateWindowPosition, " + 763f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck "postion = [%d, %d, %d, %d]", System.identityHashCode(this), 764f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck mWinFrame.left, mWinFrame.top, 765f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck mWinFrame.right, mWinFrame.bottom)); 766474659ccc421aaacfa49a742891aefed46c6f5d2John Reck session.repositionChild(window, mWinFrame.left, mWinFrame.top, 767f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck mWinFrame.right, mWinFrame.bottom, frameNumber, mWinFrame); 768f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck } catch (RemoteException ex) { 769f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck Log.e(TAG, "Exception from relayout", ex); 770f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck } 771f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck } 772f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck mRTLastReportedPosition.setEmpty(); 773f23a1b8e4c5e63d11fe12fb1d51e4f5e3570bbc2John Reck } 77434bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck } 77534bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck 7766d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn private SurfaceHolder.Callback[] getSurfaceCallbacks() { 7776d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn SurfaceHolder.Callback callbacks[]; 7786d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn synchronized (mCallbacks) { 7796d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn callbacks = new SurfaceHolder.Callback[mCallbacks.size()]; 7806d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn mCallbacks.toArray(callbacks); 78154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 7826d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn return callbacks; 78354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 78454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 78554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project void handleGetNewSurface() { 786d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn updateWindow(false, false); 78754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 788b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project 7897179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger /** 7907179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger * Check to see if the surface has fixed size dimensions or if the surface's 7917179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger * dimensions are dimensions are dependent on its current layout. 7927179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger * 7937179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger * @return true if the surface has dimensions that are fixed in size 7947179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger * @hide 7957179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger */ 7967179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger public boolean isFixedSize() { 7977179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger return (mRequestedWidth != -1 || mRequestedHeight != -1); 7987179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger } 7997179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger 80072c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn private static class MyWindow extends BaseIWindow { 8018169daed2f7a8731d478b884b1f455c747b88478Mitsuru Oshima private final WeakReference<SurfaceView> mSurfaceView; 8029bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer 8039bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer public MyWindow(SurfaceView surfaceView) { 8049bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer mSurfaceView = new WeakReference<SurfaceView>(surfaceView); 8059bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer } 8069bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer 807656e3af44432be6a2ba60289b8e787fad2506cebCraig Mautner @Override 808c4aad01cbbb69c916ef323693e1fd0560b0eccbaDianne Hackborn public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, 8092217f61e51ba4b19c56b19297c1e9cf74d7d860fFilip Gruszczynski Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, 8100ffd49cbe0ab4c13fd5528abacade898a8cff481Jorim Jaggi Configuration newConfig, Rect backDropRect, boolean forceLayout, 8110ffd49cbe0ab4c13fd5528abacade898a8cff481Jorim Jaggi boolean alwaysConsumeNavBar) { 8129bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer SurfaceView surfaceView = mSurfaceView.get(); 8139bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer if (surfaceView != null) { 81434bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck if (DEBUG) Log.v(TAG, surfaceView + " got resized: w=" + frame.width() 815656e3af44432be6a2ba60289b8e787fad2506cebCraig Mautner + " h=" + frame.height() + ", cur w=" + mCurWidth + " h=" + mCurHeight); 816726426ee736929e605742bfa52bca4b20095921dDianne Hackborn surfaceView.mSurfaceLock.lock(); 817726426ee736929e605742bfa52bca4b20095921dDianne Hackborn try { 8189bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer if (reportDraw) { 819726426ee736929e605742bfa52bca4b20095921dDianne Hackborn surfaceView.mUpdateWindowNeeded = true; 820726426ee736929e605742bfa52bca4b20095921dDianne Hackborn surfaceView.mReportDrawNeeded = true; 821726426ee736929e605742bfa52bca4b20095921dDianne Hackborn surfaceView.mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG); 822656e3af44432be6a2ba60289b8e787fad2506cebCraig Mautner } else if (surfaceView.mWinFrame.width() != frame.width() 823a4a58efe8203d63a9a6bf78b0fa9f2992b25871bJorim Jaggi || surfaceView.mWinFrame.height() != frame.height() 824a4a58efe8203d63a9a6bf78b0fa9f2992b25871bJorim Jaggi || forceLayout) { 825726426ee736929e605742bfa52bca4b20095921dDianne Hackborn surfaceView.mUpdateWindowNeeded = true; 826726426ee736929e605742bfa52bca4b20095921dDianne Hackborn surfaceView.mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG); 82754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 828726426ee736929e605742bfa52bca4b20095921dDianne Hackborn } finally { 829726426ee736929e605742bfa52bca4b20095921dDianne Hackborn surfaceView.mSurfaceLock.unlock(); 83054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 83154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 83254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 83354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 834a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 83554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void dispatchAppVisibility(boolean visible) { 83654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // The point of SurfaceView is to let the app control the surface. 83754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 838b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project 839a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 84054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void dispatchGetNewSurface() { 8419bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer SurfaceView surfaceView = mSurfaceView.get(); 8429bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer if (surfaceView != null) { 843b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project Message msg = surfaceView.mHandler.obtainMessage(GET_NEW_SURFACE_MSG); 844b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project surfaceView.mHandler.sendMessage(msg); 8459bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer } 84654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 84754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 848a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 84954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void windowFocusChanged(boolean hasFocus, boolean touchEnabled) { 85054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Log.w("SurfaceView", "Unexpected focus in surface: focus=" + hasFocus + ", touchEnabled=" + touchEnabled); 85154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 85254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 853a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 85454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void executeCommand(String command, String parameters, ParcelFileDescriptor out) { 85554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 85654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 85754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int mCurWidth = -1; 85854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int mCurHeight = -1; 85954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 86054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 861a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin private final SurfaceHolder mSurfaceHolder = new SurfaceHolder() { 862a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 86354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project private static final String LOG_TAG = "SurfaceHolder"; 864a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 865a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 86654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public boolean isCreating() { 86754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return mIsCreating; 86854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 86954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 870a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 87154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void addCallback(Callback callback) { 87254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project synchronized (mCallbacks) { 873a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin // This is a linear search, but in practice we'll 87454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // have only a couple callbacks, so it doesn't matter. 875a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin if (mCallbacks.contains(callback) == false) { 87654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mCallbacks.add(callback); 87754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 87854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 87954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 88054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 881a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 88254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void removeCallback(Callback callback) { 88354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project synchronized (mCallbacks) { 88454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mCallbacks.remove(callback); 88554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 88654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 887a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 888a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 88954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void setFixedSize(int width, int height) { 89054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (mRequestedWidth != width || mRequestedHeight != height) { 89154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mRequestedWidth = width; 89254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mRequestedHeight = height; 89354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project requestLayout(); 89454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 89554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 89654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 897a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 89854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void setSizeFromLayout() { 89954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (mRequestedWidth != -1 || mRequestedHeight != -1) { 90054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mRequestedWidth = mRequestedHeight = -1; 90154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project requestLayout(); 90254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 90354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 90454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 905a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 90654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void setFormat(int format) { 9072d468c5d73cc1cefbcfa8d98e30622c54756918cMathias Agopian 9082d468c5d73cc1cefbcfa8d98e30622c54756918cMathias Agopian // for backward compatibility reason, OPAQUE always 9092d468c5d73cc1cefbcfa8d98e30622c54756918cMathias Agopian // means 565 for SurfaceView 9102d468c5d73cc1cefbcfa8d98e30622c54756918cMathias Agopian if (format == PixelFormat.OPAQUE) 9112d468c5d73cc1cefbcfa8d98e30622c54756918cMathias Agopian format = PixelFormat.RGB_565; 9122d468c5d73cc1cefbcfa8d98e30622c54756918cMathias Agopian 91354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mRequestedFormat = format; 91454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (mWindow != null) { 915d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn updateWindow(false, false); 91654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 91754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 91854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 919d2112306330ce0c162bee4b864991962ca2b655aMathias Agopian /** 920d2112306330ce0c162bee4b864991962ca2b655aMathias Agopian * @deprecated setType is now ignored. 921d2112306330ce0c162bee4b864991962ca2b655aMathias Agopian */ 922a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 923d2112306330ce0c162bee4b864991962ca2b655aMathias Agopian @Deprecated 924d2112306330ce0c162bee4b864991962ca2b655aMathias Agopian public void setType(int type) { } 92554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 926a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 92754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void setKeepScreenOn(boolean screenOn) { 92854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Message msg = mHandler.obtainMessage(KEEP_SCREEN_ON_MSG); 92954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project msg.arg1 = screenOn ? 1 : 0; 93054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mHandler.sendMessage(msg); 93154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 932a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 9339ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian /** 9349ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * Gets a {@link Canvas} for drawing into the SurfaceView's Surface 9359ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * 9369ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * After drawing into the provided {@link Canvas}, the caller must 9379ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface. 9389ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * 9399ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * The caller must redraw the entire surface. 9409ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * @return A canvas for drawing into the surface. 9419ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian */ 942a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 94354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public Canvas lockCanvas() { 94454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return internalLockCanvas(null); 94554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 94654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 9479ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian /** 9489ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * Gets a {@link Canvas} for drawing into the SurfaceView's Surface 9499ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * 9509ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * After drawing into the provided {@link Canvas}, the caller must 9519ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface. 9529ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * 9539ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * @param inOutDirty A rectangle that represents the dirty region that the caller wants 9549ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * to redraw. This function may choose to expand the dirty rectangle if for example 9559ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * the surface has been resized or if the previous contents of the surface were 9569ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * not available. The caller must redraw the entire dirty region as represented 9579ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * by the contents of the inOutDirty rectangle upon return from this function. 9589ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * The caller may also pass <code>null</code> instead, in the case where the 9599ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * entire surface should be redrawn. 9609ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * @return A canvas for drawing into the surface. 9619ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian */ 962a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 9639ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian public Canvas lockCanvas(Rect inOutDirty) { 9649ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian return internalLockCanvas(inOutDirty); 96554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 96654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 96754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project private final Canvas internalLockCanvas(Rect dirty) { 96854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSurfaceLock.lock(); 96954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 97034bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " + "Locking canvas... stopped=" 97154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project + mDrawingStopped + ", win=" + mWindow); 97254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 97354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Canvas c = null; 97454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (!mDrawingStopped && mWindow != null) { 97554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project try { 97630bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown c = mSurface.lockCanvas(dirty); 97754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } catch (Exception e) { 97854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Log.e(LOG_TAG, "Exception locking surface", e); 97954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 98054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 98154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 98234bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " + "Returned canvas: " + c); 98354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (c != null) { 98454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLastLockTime = SystemClock.uptimeMillis(); 98554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return c; 98654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 987a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 98854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // If the Surface is not ready to be drawn, then return null, 98954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // but throttle calls to this function so it isn't called more 99054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // than every 100ms. 99154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project long now = SystemClock.uptimeMillis(); 99254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project long nextTime = mLastLockTime + 100; 99354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (nextTime > now) { 99454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project try { 99554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Thread.sleep(nextTime-now); 99654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } catch (InterruptedException e) { 99754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 99854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project now = SystemClock.uptimeMillis(); 99954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 100054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLastLockTime = now; 100154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSurfaceLock.unlock(); 1002a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 100354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return null; 100454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 100554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 10069ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian /** 10079ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * Posts the new contents of the {@link Canvas} to the surface and 10089ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * releases the {@link Canvas}. 10099ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * 10109ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * @param canvas The canvas previously obtained from {@link #lockCanvas}. 10119ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian */ 1012a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 101354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void unlockCanvasAndPost(Canvas canvas) { 101454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSurface.unlockCanvasAndPost(canvas); 101554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSurfaceLock.unlock(); 101654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 101754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 1018a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 101954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public Surface getSurface() { 102054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return mSurface; 102154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 102254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 1023a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 102454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public Rect getSurfaceFrame() { 102554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return mSurfaceFrame; 102654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 102754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project }; 102854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project} 1029