SurfaceView.java revision 2e95a488e0a12d4263d101e888fdd89fd123aec3
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> 8554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */ 8654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectpublic class SurfaceView extends View { 8754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project static private final String TAG = "SurfaceView"; 8854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project static private final boolean DEBUG = false; 8954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 9054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final ArrayList<SurfaceHolder.Callback> mCallbacks 9154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project = new ArrayList<SurfaceHolder.Callback>(); 9254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 93f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project final int[] mLocation = new int[2]; 94a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 9554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final ReentrantLock mSurfaceLock = new ReentrantLock(); 9661566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn final Surface mSurface = new Surface(); // Current surface in use 9761566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn final Surface mNewSurface = new Surface(); // New surface we are switching to 9854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project boolean mDrawingStopped = true; 9954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 10054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final WindowManager.LayoutParams mLayout 10154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project = new WindowManager.LayoutParams(); 10254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project IWindowSession mSession; 10354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project MyWindow mWindow; 104f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project final Rect mVisibleInsets = new Rect(); 10554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final Rect mWinFrame = new Rect(); 106c4aad01cbbb69c916ef323693e1fd0560b0eccbaDianne Hackborn final Rect mOverscanInsets = new Rect(); 107f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project final Rect mContentInsets = new Rect(); 108fa10423fa00f3495e451016acba9b6848eb995c9Adrian Roos final Rect mStableInsets = new Rect(); 1092217f61e51ba4b19c56b19297c1e9cf74d7d860fFilip Gruszczynski final Rect mOutsets = new Rect(); 1102e95a488e0a12d4263d101e888fdd89fd123aec3Jorim Jaggi final Rect mBackdropFrame = new Rect(); 111694f79b5d1196640d1beb680b7d1fc68e6e77cbdDianne Hackborn final Configuration mConfiguration = new Configuration(); 112a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 11354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project static final int KEEP_SCREEN_ON_MSG = 1; 11454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project static final int GET_NEW_SURFACE_MSG = 2; 115726426ee736929e605742bfa52bca4b20095921dDianne Hackborn static final int UPDATE_WINDOW_MSG = 3; 116a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 117c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn int mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA; 118a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 11954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project boolean mIsCreating = false; 12054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 12154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final Handler mHandler = new Handler() { 12254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 12354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void handleMessage(Message msg) { 12454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project switch (msg.what) { 12554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project case KEEP_SCREEN_ON_MSG: { 12654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project setKeepScreenOn(msg.arg1 != 0); 12754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } break; 12854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project case GET_NEW_SURFACE_MSG: { 12954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project handleGetNewSurface(); 13054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } break; 131726426ee736929e605742bfa52bca4b20095921dDianne Hackborn case UPDATE_WINDOW_MSG: { 132d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn updateWindow(false, false); 133726426ee736929e605742bfa52bca4b20095921dDianne Hackborn } break; 13454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 13554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 13654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project }; 137a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 138e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener 139e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn = new ViewTreeObserver.OnScrollChangedListener() { 140a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 141e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn public void onScrollChanged() { 142d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn updateWindow(false, false); 143e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn } 144e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn }; 145a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 14654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project boolean mRequestedVisible = false; 1476b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian boolean mWindowVisibility = false; 1486b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian boolean mViewVisibility = false; 14954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int mRequestedWidth = -1; 15054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int mRequestedHeight = -1; 151d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian /* Set SurfaceView's format to 565 by default to maintain backward 152d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian * compatibility with applications assuming this format. 153d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian */ 154d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian int mRequestedFormat = PixelFormat.RGB_565; 15554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 15654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project boolean mHaveFrame = false; 1576d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn boolean mSurfaceCreated = false; 15854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project long mLastLockTime = 0; 159a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 16054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project boolean mVisible = false; 16164aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr int mWindowSpaceLeft = -1; 16264aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr int mWindowSpaceTop = -1; 16364aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr int mWindowSpaceWidth = -1; 16464aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr int mWindowSpaceHeight = -1; 16554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int mFormat = -1; 16654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final Rect mSurfaceFrame = new Rect(); 167726426ee736929e605742bfa52bca4b20095921dDianne Hackborn int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1; 168726426ee736929e605742bfa52bca4b20095921dDianne Hackborn boolean mUpdateWindowNeeded; 169726426ee736929e605742bfa52bca4b20095921dDianne Hackborn boolean mReportDrawNeeded; 17064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima private Translator mTranslator; 171f2499fa434521a8948387afe8f0acd4f39620500Romain Guy 172f2499fa434521a8948387afe8f0acd4f39620500Romain Guy private final ViewTreeObserver.OnPreDrawListener mDrawListener = 173f2499fa434521a8948387afe8f0acd4f39620500Romain Guy new ViewTreeObserver.OnPreDrawListener() { 174f2499fa434521a8948387afe8f0acd4f39620500Romain Guy @Override 175f2499fa434521a8948387afe8f0acd4f39620500Romain Guy public boolean onPreDraw() { 176a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin // reposition ourselves where the surface is 1770c75622cf80e53c13d079bfe1f3df0b185c4f02dRomain Guy mHaveFrame = getWidth() > 0 && getHeight() > 0; 178f2499fa434521a8948387afe8f0acd4f39620500Romain Guy updateWindow(false, false); 179f2499fa434521a8948387afe8f0acd4f39620500Romain Guy return true; 180f2499fa434521a8948387afe8f0acd4f39620500Romain Guy } 181f2499fa434521a8948387afe8f0acd4f39620500Romain Guy }; 18201d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy private boolean mGlobalListenersAdded; 183f2499fa434521a8948387afe8f0acd4f39620500Romain Guy 18454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public SurfaceView(Context context) { 18554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super(context); 186d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian init(); 18754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 188a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 18954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public SurfaceView(Context context, AttributeSet attrs) { 19054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super(context, attrs); 191d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian init(); 19254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 19354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 194617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public SurfaceView(Context context, AttributeSet attrs, int defStyleAttr) { 195617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette super(context, attrs, defStyleAttr); 196617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette init(); 197617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette } 198617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette 199617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public SurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 200617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette super(context, attrs, defStyleAttr, defStyleRes); 201d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian init(); 202d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian } 203d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian 204d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian private void init() { 20554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project setWillNotDraw(true); 20654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 207a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 20854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project /** 20954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Return the SurfaceHolder providing access and control over this 21054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * SurfaceView's underlying surface. 211a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin * 21254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * @return SurfaceHolder The holder of the surface. 21354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */ 21454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public SurfaceHolder getHolder() { 21554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return mSurfaceHolder; 21654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 21754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 21854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 21954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project protected void onAttachedToWindow() { 22054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super.onAttachedToWindow(); 22154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mParent.requestTransparentRegion(this); 22254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSession = getWindowSession(); 22354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLayout.token = getWindowToken(); 22454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLayout.setTitle("SurfaceView"); 2256b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian mViewVisibility = getVisibility() == VISIBLE; 22601d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy 22701d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy if (!mGlobalListenersAdded) { 22801d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy ViewTreeObserver observer = getViewTreeObserver(); 22901d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy observer.addOnScrollChangedListener(mScrollChangedListener); 23001d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy observer.addOnPreDrawListener(mDrawListener); 23101d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy mGlobalListenersAdded = true; 23201d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy } 23354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 23454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 23554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 23654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project protected void onWindowVisibilityChanged(int visibility) { 23754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super.onWindowVisibilityChanged(visibility); 2386b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian mWindowVisibility = visibility == VISIBLE; 2396b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian mRequestedVisible = mWindowVisibility && mViewVisibility; 240d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn updateWindow(false, false); 2416b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian } 2426b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian 2436b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian @Override 2446b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian public void setVisibility(int visibility) { 2456b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian super.setVisibility(visibility); 2466b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian mViewVisibility = visibility == VISIBLE; 247cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian boolean newRequestedVisible = mWindowVisibility && mViewVisibility; 248cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian if (newRequestedVisible != mRequestedVisible) { 249cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian // our base class (View) invalidates the layout only when 250cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian // we go from/to the GONE state. However, SurfaceView needs 251cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian // to request a re-layout when the visibility changes at all. 252cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian // This is needed because the transparent region is computed 253cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian // as part of the layout phase, and it changes (obviously) when 254cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian // the visibility changes. 255cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian requestLayout(); 256cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian } 257cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian mRequestedVisible = newRequestedVisible; 258d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn updateWindow(false, false); 25954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 260afc3e11f10828e113331eb24b65e4f9759f67747Romain Guy 26154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 26277e4a5250fc6df451999efe508f57968a44b603fJohn Reck protected void onDetachedFromWindow() { 26301d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy if (mGlobalListenersAdded) { 26401d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy ViewTreeObserver observer = getViewTreeObserver(); 26501d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy observer.removeOnScrollChangedListener(mScrollChangedListener); 26601d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy observer.removeOnPreDrawListener(mDrawListener); 26701d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy mGlobalListenersAdded = false; 26801d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy } 26901d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy 27054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mRequestedVisible = false; 271d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn updateWindow(false, false); 27254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mHaveFrame = false; 27354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (mWindow != null) { 27454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project try { 27554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSession.remove(mWindow); 27654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } catch (RemoteException ex) { 27701d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy // Not much we can do here... 27854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 27954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mWindow = null; 28054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 28154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSession = null; 28254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLayout.token = null; 28354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 28477e4a5250fc6df451999efe508f57968a44b603fJohn Reck super.onDetachedFromWindow(); 28554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 28654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 28754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 28854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 289189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn int width = mRequestedWidth >= 0 290189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn ? resolveSizeAndState(mRequestedWidth, widthMeasureSpec, 0) 291189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn : getDefaultSize(0, widthMeasureSpec); 292189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn int height = mRequestedHeight >= 0 293189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn ? resolveSizeAndState(mRequestedHeight, heightMeasureSpec, 0) 294189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn : getDefaultSize(0, heightMeasureSpec); 29554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project setMeasuredDimension(width, height); 29654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 297a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 298ef11530874f86570aa04a10c16a416b274b3fdf5Mathias Agopian /** @hide */ 29954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 300995bb9d24d3b278939a01e1d05c2b7f337ab0565Mathias Agopian protected boolean setFrame(int left, int top, int right, int bottom) { 301995bb9d24d3b278939a01e1d05c2b7f337ab0565Mathias Agopian boolean result = super.setFrame(left, top, right, bottom); 302d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn updateWindow(false, false); 303995bb9d24d3b278939a01e1d05c2b7f337ab0565Mathias Agopian return result; 30454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 30554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 30654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 30754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public boolean gatherTransparentRegion(Region region) { 3081cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn if (mWindowType == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) { 3091cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn return super.gatherTransparentRegion(region); 3101cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn } 311a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 31254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project boolean opaque = true; 3134702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn if ((mPrivateFlags & PFLAG_SKIP_DRAW) == 0) { 31454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // this view draws, remove it from the transparent region 31554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project opaque = super.gatherTransparentRegion(region); 31654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } else if (region != null) { 31754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int w = getWidth(); 31854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int h = getHeight(); 31954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (w>0 && h>0) { 32054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project getLocationInWindow(mLocation); 32154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // otherwise, punch a hole in the whole hierarchy 32254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int l = mLocation[0]; 32354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int t = mLocation[1]; 32454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project region.op(l, t, l+w, t+h, Region.Op.UNION); 32554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 32654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 32754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (PixelFormat.formatHasAlpha(mRequestedFormat)) { 32854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project opaque = false; 32954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 33054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return opaque; 33154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 33254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 33354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 33454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void draw(Canvas canvas) { 3351cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) { 3361cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn // draw() is not called when SKIP_DRAW is set 3374702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn if ((mPrivateFlags & PFLAG_SKIP_DRAW) == 0) { 3381cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn // punch a whole in the view-hierarchy below us 3391cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn canvas.drawColor(0, PorterDuff.Mode.CLEAR); 3401cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn } 34154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 34254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super.draw(canvas); 34354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 34454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 34554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 34654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project protected void dispatchDraw(Canvas canvas) { 3471cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) { 3481cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn // if SKIP_DRAW is cleared, draw() has already punched a hole 3494702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) { 3501cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn // punch a whole in the view-hierarchy below us 3511cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn canvas.drawColor(0, PorterDuff.Mode.CLEAR); 3521cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn } 35354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 35454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super.dispatchDraw(canvas); 35554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 35654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 357c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn /** 35829e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn * Control whether the surface view's surface is placed on top of another 35929e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn * regular surface view in the window (but still behind the window itself). 36029e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn * This is typically used to place overlays on top of an underlying media 36129e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn * surface view. 362a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin * 36329e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn * <p>Note that this must be set before the surface view's containing 36429e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn * window is attached to the window manager. 365a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin * 36629e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn * <p>Calling this overrides any previous call to {@link #setZOrderOnTop}. 36729e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn */ 36829e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn public void setZOrderMediaOverlay(boolean isMediaOverlay) { 36929e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn mWindowType = isMediaOverlay 37029e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn ? WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY 37129e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn : WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA; 37229e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn } 373a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 37429e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn /** 3751cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn * Control whether the surface view's surface is placed on top of its 3761cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn * window. Normally it is placed behind the window, to allow it to 3771cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn * (for the most part) appear to composite with the views in the 3781cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn * hierarchy. By setting this, you cause it to be placed above the 3791cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn * window. This means that none of the contents of the window this 3801cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn * SurfaceView is in will be visible on top of its surface. 381a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin * 3821cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn * <p>Note that this must be set before the surface view's containing 3831cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn * window is attached to the window manager. 384a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin * 38529e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn * <p>Calling this overrides any previous call to {@link #setZOrderMediaOverlay}. 3861cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn */ 38729e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn public void setZOrderOnTop(boolean onTop) { 388ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger if (onTop) { 389ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; 390ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger // ensures the surface is placed below the IME 391ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger mLayout.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 392ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger } else { 393ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA; 394ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger mLayout.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 395ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger } 3961cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn } 397f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown 398f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown /** 399f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown * Control whether the surface view's content should be treated as secure, 400f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown * preventing it from appearing in screenshots or from being viewed on 401f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown * non-secure displays. 402f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown * 403f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown * <p>Note that this must be set before the surface view's containing 404f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown * window is attached to the window manager. 405f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown * 406f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown * <p>See {@link android.view.Display#FLAG_SECURE} for details. 407f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown * 408f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown * @param isSecure True if the surface view is secure. 409f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown */ 410f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown public void setSecure(boolean isSecure) { 411f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown if (isSecure) { 412f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown mLayout.flags |= WindowManager.LayoutParams.FLAG_SECURE; 413f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown } else { 414f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown mLayout.flags &= ~WindowManager.LayoutParams.FLAG_SECURE; 415f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown } 416f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown } 417f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown 4181cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn /** 419c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn * Hack to allow special layering of windows. The type is one of the 420c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn * types in WindowManager.LayoutParams. This is a hack so: 421c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn * @hide 422c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn */ 423c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn public void setWindowType(int type) { 424c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn mWindowType = type; 425c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn } 42634bf2ee9e695c620e0a4b9a790f1f6ccb8a77234Mitsuru Oshima 4279a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho /** @hide */ 4289a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho protected void updateWindow(boolean force, boolean redrawNeeded) { 42954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (!mHaveFrame) { 43054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return; 43154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 432a175a5b7ea3682cb58cca7f9726d0b8171cd549dJeff Brown ViewRootImpl viewRoot = getViewRootImpl(); 433168173a698e820ceb1ebf54b4910888891be2056Joe Onorato if (viewRoot != null) { 434168173a698e820ceb1ebf54b4910888891be2056Joe Onorato mTranslator = viewRoot.mTranslator; 435168173a698e820ceb1ebf54b4910888891be2056Joe Onorato } 43664f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 4375be8de3420ba4c9d816b98e29bdec11715f6b626Dianne Hackborn if (mTranslator != null) { 4385be8de3420ba4c9d816b98e29bdec11715f6b626Dianne Hackborn mSurface.setCompatibilityTranslator(mTranslator); 43938ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima } 440a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 44154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int myWidth = mRequestedWidth; 44254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (myWidth <= 0) myWidth = getWidth(); 44354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int myHeight = mRequestedHeight; 44454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (myHeight <= 0) myHeight = getHeight(); 445001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima 44654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project getLocationInWindow(mLocation); 44754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final boolean creating = mWindow == null; 44854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final boolean formatChanged = mFormat != mRequestedFormat; 44964aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr final boolean sizeChanged = mWindowSpaceWidth != myWidth || mWindowSpaceHeight != myHeight; 4506d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn final boolean visibleChanged = mVisible != mRequestedVisible; 45164aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr final boolean layoutSizeChanged = getWidth() != mLayout.width 45264aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr || getHeight() != mLayout.height; 45364aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr final boolean positionChanged = mWindowSpaceLeft != mLocation[0] || mWindowSpaceTop != mLocation[1]; 454d2112306330ce0c162bee4b864991962ca2b655aMathias Agopian 45554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (force || creating || formatChanged || sizeChanged || visibleChanged 45664aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr || mUpdateWindowNeeded || mReportDrawNeeded || redrawNeeded) { 4576d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (DEBUG) Log.i(TAG, "Changes: creating=" + creating 45854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project + " format=" + formatChanged + " size=" + sizeChanged 45954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project + " visible=" + visibleChanged 46064aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr + " left=" + (mWindowSpaceLeft != mLocation[0]) 46164aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr + " top=" + (mWindowSpaceTop != mLocation[1])); 46264f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima 46354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project try { 46454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final boolean visible = mVisible = mRequestedVisible; 46564aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mWindowSpaceLeft = mLocation[0]; 46664aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mWindowSpaceTop = mLocation[1]; 46764aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mWindowSpaceWidth = myWidth; 46864aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mWindowSpaceHeight = myHeight; 46954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mFormat = mRequestedFormat; 47054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 47164f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima // Scaling/Translate window's layout here because mLayout is not used elsewhere. 472a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 47364f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima // Places the window relative 47464aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mLayout.x = mWindowSpaceLeft; 47564aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mLayout.y = mWindowSpaceTop; 47664f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima mLayout.width = getWidth(); 47764f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima mLayout.height = getHeight(); 47864f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima if (mTranslator != null) { 47964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima mTranslator.translateLayoutParamsInAppWindowToScreen(mLayout); 48064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima } 481a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 48254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLayout.format = mRequestedFormat; 4831cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn mLayout.flags |=WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE 4841cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 4851cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS 48654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project | WindowManager.LayoutParams.FLAG_SCALED 48754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 48854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE 48954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project ; 49064aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr if (!creating && !force && !mUpdateWindowNeeded) { 49164aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mLayout.privateFlags |= 49264aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY; 49364aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr } else { 49464aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mLayout.privateFlags &= 49564aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr ~WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY; 49664aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr } 49764aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr 498841f13c8e9ff3f7695b6c18a8abcec3c947983ffMitsuru Oshima if (!getContext().getResources().getCompatibilityInfo().supportsScreen()) { 49995c42974f719d1fac90fc0438eac778e9795681fAdam Lesinski mLayout.privateFlags |= 50095c42974f719d1fac90fc0438eac778e9795681fAdam Lesinski WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; 501841f13c8e9ff3f7695b6c18a8abcec3c947983ffMitsuru Oshima } 5021c5383ce0b4e162ebc9ac7e29c8c39377724d45bDianne Hackborn mLayout.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION; 50354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 50454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (mWindow == null) { 5058d0243a3d0269d3a57d90eb2e7b12b41f53b27d9Jeff Brown Display display = getDisplay(); 5069bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer mWindow = new MyWindow(this); 507c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn mLayout.type = mWindowType; 508aac0d4ed026d1cfbcf3fa81c6e4eb96f4347ca17Fabrice Di Meglio mLayout.gravity = Gravity.START|Gravity.TOP; 5096881a10557acf3b0270de54799d6f19437acf584Craig Mautner mSession.addToDisplayWithoutInputChannel(mWindow, mWindow.mSeq, mLayout, 51037d7a68de7e353c31a3a4736054cd86f0e002eafAdrian Roos mVisible ? VISIBLE : GONE, display.getDisplayId(), mContentInsets, 51137d7a68de7e353c31a3a4736054cd86f0e002eafAdrian Roos mStableInsets); 51254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 513a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 514726426ee736929e605742bfa52bca4b20095921dDianne Hackborn boolean realSizeChanged; 515726426ee736929e605742bfa52bca4b20095921dDianne Hackborn boolean reportDrawNeeded; 5166d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn 5176d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn int relayoutResult; 5186d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn 519726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mSurfaceLock.lock(); 520726426ee736929e605742bfa52bca4b20095921dDianne Hackborn try { 521726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mUpdateWindowNeeded = false; 522726426ee736929e605742bfa52bca4b20095921dDianne Hackborn reportDrawNeeded = mReportDrawNeeded; 523726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mReportDrawNeeded = false; 524726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mDrawingStopped = !visible; 525a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 5266d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (DEBUG) Log.i(TAG, "Cur surface: " + mSurface); 5276d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn 5286d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn relayoutResult = mSession.relayout( 52964aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mWindow, mWindow.mSeq, mLayout, mWindowSpaceWidth, mWindowSpaceHeight, 5306d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn visible ? VISIBLE : GONE, 53198365d7663cbd82979a5700faf0050220b01084dJeff Brown WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY, 532c4aad01cbbb69c916ef323693e1fd0560b0eccbaDianne Hackborn mWinFrame, mOverscanInsets, mContentInsets, 5332e95a488e0a12d4263d101e888fdd89fd123aec3Jorim Jaggi mVisibleInsets, mStableInsets, mOutsets, mBackdropFrame, 5342e95a488e0a12d4263d101e888fdd89fd123aec3Jorim Jaggi mConfiguration, mNewSurface); 53598365d7663cbd82979a5700faf0050220b01084dJeff Brown if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) { 5366fa9512e349ef1efbf4558da9e8418a842ab6201John Reck reportDrawNeeded = true; 537726426ee736929e605742bfa52bca4b20095921dDianne Hackborn } 5386d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn 5396d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (DEBUG) Log.i(TAG, "New surface: " + mNewSurface 540726426ee736929e605742bfa52bca4b20095921dDianne Hackborn + ", vis=" + visible + ", frame=" + mWinFrame); 5416d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn 542726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mSurfaceFrame.left = 0; 543726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mSurfaceFrame.top = 0; 544726426ee736929e605742bfa52bca4b20095921dDianne Hackborn if (mTranslator == null) { 545726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mSurfaceFrame.right = mWinFrame.width(); 546726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mSurfaceFrame.bottom = mWinFrame.height(); 547726426ee736929e605742bfa52bca4b20095921dDianne Hackborn } else { 548726426ee736929e605742bfa52bca4b20095921dDianne Hackborn float appInvertedScale = mTranslator.applicationInvertedScale; 549726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mSurfaceFrame.right = (int) (mWinFrame.width() * appInvertedScale + 0.5f); 550726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mSurfaceFrame.bottom = (int) (mWinFrame.height() * appInvertedScale + 0.5f); 551726426ee736929e605742bfa52bca4b20095921dDianne Hackborn } 552a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 553726426ee736929e605742bfa52bca4b20095921dDianne Hackborn final int surfaceWidth = mSurfaceFrame.right; 554726426ee736929e605742bfa52bca4b20095921dDianne Hackborn final int surfaceHeight = mSurfaceFrame.bottom; 555726426ee736929e605742bfa52bca4b20095921dDianne Hackborn realSizeChanged = mLastSurfaceWidth != surfaceWidth 556726426ee736929e605742bfa52bca4b20095921dDianne Hackborn || mLastSurfaceHeight != surfaceHeight; 557726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mLastSurfaceWidth = surfaceWidth; 558726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mLastSurfaceHeight = surfaceHeight; 559726426ee736929e605742bfa52bca4b20095921dDianne Hackborn } finally { 560726426ee736929e605742bfa52bca4b20095921dDianne Hackborn mSurfaceLock.unlock(); 561589cebe2d58591403de4a77077941c0454bc91bcMitsuru Oshima } 56254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 56354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project try { 564d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn redrawNeeded |= creating | reportDrawNeeded; 565d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn 5666d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn SurfaceHolder.Callback callbacks[] = null; 56754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 56898365d7663cbd82979a5700faf0050220b01084dJeff Brown final boolean surfaceChanged = (relayoutResult 56998365d7663cbd82979a5700faf0050220b01084dJeff Brown & WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED) != 0; 5706d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (mSurfaceCreated && (surfaceChanged || (!visible && visibleChanged))) { 5716d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn mSurfaceCreated = false; 5726d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (mSurface.isValid()) { 5736d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (DEBUG) Log.i(TAG, "visibleChanged -- surfaceDestroyed"); 5746d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn callbacks = getSurfaceCallbacks(); 5756d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn for (SurfaceHolder.Callback c : callbacks) { 5766d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn c.surfaceDestroyed(mSurfaceHolder); 5776d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn } 5783d91492d694cf00474fec792134e496be6ee0313Mitsuru Oshima } 5796d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn } 5806d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn 58161566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn mSurface.transferFrom(mNewSurface); 582f750b8ce3c8cb30bcbc5fe53087c7e9035078ebaAndreas Röhl if (visible && mSurface.isValid()) { 583cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr // We set SCALING_MODE_NO_SCALE_CROP to allow the WindowManager 584cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr // to update our Surface crop without requiring a new buffer from 585cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr // us. In the default mode of SCALING_MODE_FREEZE, surface geometry 586cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr // state (which includes crop) is only applied when a buffer 587cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr // with appropriate geometry is available. During drag resize 588cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr // it is quite frequent that a matching buffer will not be available 589cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr // (because we are constantly being resized and have fallen behind). 590cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr // However in such situations the WindowManager still needs to be able 591cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr // to update our crop to ensure we stay within the bounds of the containing 592cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr // window. 593cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr mSurface.setScalingMode(Surface.SCALING_MODE_NO_SCALE_CROP); 594cd9a18c7f864901400c6017c892bfd3bc48c3a4bRobert Carr 5956d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (!mSurfaceCreated && (surfaceChanged || visibleChanged)) { 5966d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn mSurfaceCreated = true; 59754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mIsCreating = true; 5986d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (DEBUG) Log.i(TAG, "visibleChanged -- surfaceCreated"); 5996d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (callbacks == null) { 6006d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn callbacks = getSurfaceCallbacks(); 6016d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn } 60254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project for (SurfaceHolder.Callback c : callbacks) { 60354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project c.surfaceCreated(mSurfaceHolder); 60454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 60554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 60654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (creating || formatChanged || sizeChanged 607726426ee736929e605742bfa52bca4b20095921dDianne Hackborn || visibleChanged || realSizeChanged) { 6086d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (DEBUG) Log.i(TAG, "surfaceChanged -- format=" + mFormat 6096d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn + " w=" + myWidth + " h=" + myHeight); 6106d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (callbacks == null) { 6116d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn callbacks = getSurfaceCallbacks(); 6126d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn } 613251fd430c7e355ad440202c83b0c6d91f5bf93e5Dianne Hackborn for (SurfaceHolder.Callback c : callbacks) { 614251fd430c7e355ad440202c83b0c6d91f5bf93e5Dianne Hackborn c.surfaceChanged(mSurfaceHolder, mFormat, myWidth, myHeight); 615251fd430c7e355ad440202c83b0c6d91f5bf93e5Dianne Hackborn } 616d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn } 617d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn if (redrawNeeded) { 6186d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (DEBUG) Log.i(TAG, "surfaceRedrawNeeded"); 6196d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (callbacks == null) { 6206d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn callbacks = getSurfaceCallbacks(); 6216d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn } 62254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project for (SurfaceHolder.Callback c : callbacks) { 623d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn if (c instanceof SurfaceHolder.Callback2) { 624d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn ((SurfaceHolder.Callback2)c).surfaceRedrawNeeded( 625d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn mSurfaceHolder); 626d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn } 62754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 62854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 62954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 63054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } finally { 63154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mIsCreating = false; 632d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn if (redrawNeeded) { 6336d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (DEBUG) Log.i(TAG, "finishedDrawing"); 63454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSession.finishDrawing(mWindow); 63554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 6366d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn mSession.performDeferredDestroy(mWindow); 63754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 63854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } catch (RemoteException ex) { 63964e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr Log.e(TAG, "Exception from relayout", ex); 64054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 6416d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (DEBUG) Log.v( 64254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y + 64354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project " w=" + mLayout.width + " h=" + mLayout.height + 64454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project ", frame=" + mSurfaceFrame); 64564aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr } else if (positionChanged || layoutSizeChanged) { // Only the position has changed 64664aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mWindowSpaceLeft = mLocation[0]; 64764aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mWindowSpaceTop = mLocation[1]; 64864aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr // For our size changed check, we keep mLayout.width and mLayout.height 64964aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr // in view local space. 65064aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mLocation[0] = mLayout.width = getWidth(); 65164aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mLocation[1] = mLayout.height = getHeight(); 65264aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr 65364aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr transformFromViewToWindowSpace(mLocation); 65464aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr 65564e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr try { 65664aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mSession.repositionChild(mWindow, mWindowSpaceLeft, mWindowSpaceTop, 65764aadd08491172e90f6d6512d8affc9a4cfa04ccRobert Carr mLocation[0], mLocation[1], 65864e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr viewRoot != null ? viewRoot.getNextFrameNumber() : -1, 65964e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr mWinFrame); 66064e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr } catch (RemoteException ex) { 66164e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr Log.e(TAG, "Exception from relayout", ex); 66264e516f5fa56d71bf6b5076e5620c30dc5810ba1Rob Carr } 66354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 66454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 66554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 6666d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn private SurfaceHolder.Callback[] getSurfaceCallbacks() { 6676d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn SurfaceHolder.Callback callbacks[]; 6686d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn synchronized (mCallbacks) { 6696d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn callbacks = new SurfaceHolder.Callback[mCallbacks.size()]; 6706d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn mCallbacks.toArray(callbacks); 67154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 6726d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn return callbacks; 67354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 67454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 67554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project void handleGetNewSurface() { 676d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn updateWindow(false, false); 67754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 678b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project 6797179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger /** 6807179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger * Check to see if the surface has fixed size dimensions or if the surface's 6817179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger * dimensions are dimensions are dependent on its current layout. 6827179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger * 6837179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger * @return true if the surface has dimensions that are fixed in size 6847179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger * @hide 6857179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger */ 6867179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger public boolean isFixedSize() { 6877179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger return (mRequestedWidth != -1 || mRequestedHeight != -1); 6887179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger } 6897179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger 69072c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn private static class MyWindow extends BaseIWindow { 6918169daed2f7a8731d478b884b1f455c747b88478Mitsuru Oshima private final WeakReference<SurfaceView> mSurfaceView; 6929bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer 6939bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer public MyWindow(SurfaceView surfaceView) { 6949bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer mSurfaceView = new WeakReference<SurfaceView>(surfaceView); 6959bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer } 6969bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer 697656e3af44432be6a2ba60289b8e787fad2506cebCraig Mautner @Override 698c4aad01cbbb69c916ef323693e1fd0560b0eccbaDianne Hackborn public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, 6992217f61e51ba4b19c56b19297c1e9cf74d7d860fFilip Gruszczynski Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, 700253a20fad8703e21c7298fe66e0f3f53d4e63c14Jorim Jaggi Configuration newConfig, Rect backDropRect) { 7019bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer SurfaceView surfaceView = mSurfaceView.get(); 7029bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer if (surfaceView != null) { 7036d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (DEBUG) Log.v( 704656e3af44432be6a2ba60289b8e787fad2506cebCraig Mautner "SurfaceView", surfaceView + " got resized: w=" + frame.width() 705656e3af44432be6a2ba60289b8e787fad2506cebCraig Mautner + " h=" + frame.height() + ", cur w=" + mCurWidth + " h=" + mCurHeight); 706726426ee736929e605742bfa52bca4b20095921dDianne Hackborn surfaceView.mSurfaceLock.lock(); 707726426ee736929e605742bfa52bca4b20095921dDianne Hackborn try { 7089bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer if (reportDraw) { 709726426ee736929e605742bfa52bca4b20095921dDianne Hackborn surfaceView.mUpdateWindowNeeded = true; 710726426ee736929e605742bfa52bca4b20095921dDianne Hackborn surfaceView.mReportDrawNeeded = true; 711726426ee736929e605742bfa52bca4b20095921dDianne Hackborn surfaceView.mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG); 712656e3af44432be6a2ba60289b8e787fad2506cebCraig Mautner } else if (surfaceView.mWinFrame.width() != frame.width() 713656e3af44432be6a2ba60289b8e787fad2506cebCraig Mautner || surfaceView.mWinFrame.height() != frame.height()) { 714726426ee736929e605742bfa52bca4b20095921dDianne Hackborn surfaceView.mUpdateWindowNeeded = true; 715726426ee736929e605742bfa52bca4b20095921dDianne Hackborn surfaceView.mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG); 71654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 717726426ee736929e605742bfa52bca4b20095921dDianne Hackborn } finally { 718726426ee736929e605742bfa52bca4b20095921dDianne Hackborn surfaceView.mSurfaceLock.unlock(); 71954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 72054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 72154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 72254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 723a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 72454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void dispatchAppVisibility(boolean visible) { 72554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // The point of SurfaceView is to let the app control the surface. 72654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 727b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project 728a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 72954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void dispatchGetNewSurface() { 7309bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer SurfaceView surfaceView = mSurfaceView.get(); 7319bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer if (surfaceView != null) { 732b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project Message msg = surfaceView.mHandler.obtainMessage(GET_NEW_SURFACE_MSG); 733b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project surfaceView.mHandler.sendMessage(msg); 7349bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer } 73554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 73654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 737a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 73854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void windowFocusChanged(boolean hasFocus, boolean touchEnabled) { 73954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Log.w("SurfaceView", "Unexpected focus in surface: focus=" + hasFocus + ", touchEnabled=" + touchEnabled); 74054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 74154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 742a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 74354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void executeCommand(String command, String parameters, ParcelFileDescriptor out) { 74454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 74554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 74654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int mCurWidth = -1; 74754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int mCurHeight = -1; 74854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 74954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 750a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin private final SurfaceHolder mSurfaceHolder = new SurfaceHolder() { 751a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 75254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project private static final String LOG_TAG = "SurfaceHolder"; 753a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 754a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 75554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public boolean isCreating() { 75654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return mIsCreating; 75754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 75854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 759a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 76054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void addCallback(Callback callback) { 76154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project synchronized (mCallbacks) { 762a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin // This is a linear search, but in practice we'll 76354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // have only a couple callbacks, so it doesn't matter. 764a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin if (mCallbacks.contains(callback) == false) { 76554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mCallbacks.add(callback); 76654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 76754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 76854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 76954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 770a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 77154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void removeCallback(Callback callback) { 77254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project synchronized (mCallbacks) { 77354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mCallbacks.remove(callback); 77454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 77554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 776a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 777a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 77854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void setFixedSize(int width, int height) { 77954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (mRequestedWidth != width || mRequestedHeight != height) { 78054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mRequestedWidth = width; 78154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mRequestedHeight = height; 78254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project requestLayout(); 78354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 78454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 78554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 786a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 78754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void setSizeFromLayout() { 78854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (mRequestedWidth != -1 || mRequestedHeight != -1) { 78954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mRequestedWidth = mRequestedHeight = -1; 79054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project requestLayout(); 79154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 79254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 79354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 794a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 79554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void setFormat(int format) { 7962d468c5d73cc1cefbcfa8d98e30622c54756918cMathias Agopian 7972d468c5d73cc1cefbcfa8d98e30622c54756918cMathias Agopian // for backward compatibility reason, OPAQUE always 7982d468c5d73cc1cefbcfa8d98e30622c54756918cMathias Agopian // means 565 for SurfaceView 7992d468c5d73cc1cefbcfa8d98e30622c54756918cMathias Agopian if (format == PixelFormat.OPAQUE) 8002d468c5d73cc1cefbcfa8d98e30622c54756918cMathias Agopian format = PixelFormat.RGB_565; 8012d468c5d73cc1cefbcfa8d98e30622c54756918cMathias Agopian 80254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mRequestedFormat = format; 80354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (mWindow != null) { 804d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn updateWindow(false, false); 80554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 80654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 80754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 808d2112306330ce0c162bee4b864991962ca2b655aMathias Agopian /** 809d2112306330ce0c162bee4b864991962ca2b655aMathias Agopian * @deprecated setType is now ignored. 810d2112306330ce0c162bee4b864991962ca2b655aMathias Agopian */ 811a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 812d2112306330ce0c162bee4b864991962ca2b655aMathias Agopian @Deprecated 813d2112306330ce0c162bee4b864991962ca2b655aMathias Agopian public void setType(int type) { } 81454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 815a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 81654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void setKeepScreenOn(boolean screenOn) { 81754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Message msg = mHandler.obtainMessage(KEEP_SCREEN_ON_MSG); 81854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project msg.arg1 = screenOn ? 1 : 0; 81954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mHandler.sendMessage(msg); 82054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 821a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 8229ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian /** 8239ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * Gets a {@link Canvas} for drawing into the SurfaceView's Surface 8249ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * 8259ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * After drawing into the provided {@link Canvas}, the caller must 8269ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface. 8279ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * 8289ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * The caller must redraw the entire surface. 8299ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * @return A canvas for drawing into the surface. 8309ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian */ 831a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 83254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public Canvas lockCanvas() { 83354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return internalLockCanvas(null); 83454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 83554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 8369ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian /** 8379ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * Gets a {@link Canvas} for drawing into the SurfaceView's Surface 8389ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * 8399ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * After drawing into the provided {@link Canvas}, the caller must 8409ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface. 8419ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * 8429ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * @param inOutDirty A rectangle that represents the dirty region that the caller wants 8439ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * to redraw. This function may choose to expand the dirty rectangle if for example 8449ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * the surface has been resized or if the previous contents of the surface were 8459ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * not available. The caller must redraw the entire dirty region as represented 8469ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * by the contents of the inOutDirty rectangle upon return from this function. 8479ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * The caller may also pass <code>null</code> instead, in the case where the 8489ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * entire surface should be redrawn. 8499ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * @return A canvas for drawing into the surface. 8509ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian */ 851a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 8529ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian public Canvas lockCanvas(Rect inOutDirty) { 8539ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian return internalLockCanvas(inOutDirty); 85454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 85554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 85654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project private final Canvas internalLockCanvas(Rect dirty) { 85754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSurfaceLock.lock(); 85854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 8596d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (DEBUG) Log.i(TAG, "Locking canvas... stopped=" 86054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project + mDrawingStopped + ", win=" + mWindow); 86154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 86254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Canvas c = null; 86354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (!mDrawingStopped && mWindow != null) { 86454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project try { 86530bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown c = mSurface.lockCanvas(dirty); 86654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } catch (Exception e) { 86754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Log.e(LOG_TAG, "Exception locking surface", e); 86854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 86954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 87054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 8716d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn if (DEBUG) Log.i(TAG, "Returned canvas: " + c); 87254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (c != null) { 87354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLastLockTime = SystemClock.uptimeMillis(); 87454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return c; 87554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 876a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 87754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // If the Surface is not ready to be drawn, then return null, 87854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // but throttle calls to this function so it isn't called more 87954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // than every 100ms. 88054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project long now = SystemClock.uptimeMillis(); 88154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project long nextTime = mLastLockTime + 100; 88254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (nextTime > now) { 88354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project try { 88454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Thread.sleep(nextTime-now); 88554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } catch (InterruptedException e) { 88654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 88754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project now = SystemClock.uptimeMillis(); 88854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 88954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLastLockTime = now; 89054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSurfaceLock.unlock(); 891a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin 89254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return null; 89354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 89454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 8959ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian /** 8969ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * Posts the new contents of the {@link Canvas} to the surface and 8979ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * releases the {@link Canvas}. 8989ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * 8999ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian * @param canvas The canvas previously obtained from {@link #lockCanvas}. 9009ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian */ 901a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 90254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void unlockCanvasAndPost(Canvas canvas) { 90354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSurface.unlockCanvasAndPost(canvas); 90454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSurfaceLock.unlock(); 90554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 90654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 907a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 90854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public Surface getSurface() { 90954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return mSurface; 91054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 91154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 912a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin @Override 91354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public Rect getSurfaceFrame() { 91454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return mSurfaceFrame; 91554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 91654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project }; 91754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project} 918