SurfaceView.java revision f013e1afd1e68af5e3b868c26a653bbfb39538f8
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 1954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.content.Context; 2054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.Canvas; 2154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.PixelFormat; 2254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.PorterDuff; 2354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.Rect; 2454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.Region; 2554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.os.Handler; 2654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.os.Message; 2754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.os.RemoteException; 2854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.os.SystemClock; 2954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.os.ParcelFileDescriptor; 3054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.util.AttributeSet; 3154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.util.Config; 3254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.util.Log; 3354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport java.util.ArrayList; 3454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 3554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport java.util.concurrent.locks.ReentrantLock; 3654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 3754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project/** 3854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Provides a dedicated drawing surface embedded inside of a view hierarchy. 3954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * You can control the format of this surface and, if you like, its size; the 4054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * SurfaceView takes care of placing the surface at the correct location on the 4154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * screen 4254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * 4354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p>The surface is Z ordered so that it is behind the window holding its 4454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * SurfaceView; the SurfaceView punches a hole in its window to allow its 4554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * surface to be displayed. The view hierarchy will take care of correctly 4654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * compositing with the Surface any siblings of the SurfaceView that would 4754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * normally appear on top of it. This can be used to place overlays such as 4854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * buttons on top of the Surface, though note however that it can have an 4954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * impact on performance since a full alpha-blended composite will be performed 5054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * each time the Surface changes. 5154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * 5254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p>Access to the underlying surface is provided via the SurfaceHolder interface, 5354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * which can be retrieved by calling {@link #getHolder}. 5454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * 5554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p>The Surface will be created for you while the SurfaceView's window is 5654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * visible; you should implement {@link SurfaceHolder.Callback#surfaceCreated} 5754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * and {@link SurfaceHolder.Callback#surfaceDestroyed} to discover when the 5854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Surface is created and destroyed as the window is shown and hidden. 5954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * 6054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p>One of the purposes of this class is to provide a surface in which a 6154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * secondary thread can render in to the screen. If you are going to use it 6254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * this way, you need to be aware of some threading semantics: 6354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * 6454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <ul> 6554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <li> All SurfaceView and 6654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * {@link SurfaceHolder.Callback SurfaceHolder.Callback} methods will be called 6754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * from the thread running the SurfaceView's window (typically the main thread 6854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * of the application). They thus need to correctly synchronize with any 6954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * state that is also touched by the drawing thread. 7054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <li> You must ensure that the drawing thread only touches the underlying 7154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Surface while it is valid -- between 7254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * {@link SurfaceHolder.Callback#surfaceCreated SurfaceHolder.Callback.surfaceCreated()} 7354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * and 7454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * {@link SurfaceHolder.Callback#surfaceDestroyed SurfaceHolder.Callback.surfaceDestroyed()}. 7554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * </ul> 7654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */ 7754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectpublic class SurfaceView extends View { 7854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project static private final String TAG = "SurfaceView"; 7954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project static private final boolean DEBUG = false; 8054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project static private final boolean localLOGV = DEBUG ? true : Config.LOGV; 8154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 8254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final ArrayList<SurfaceHolder.Callback> mCallbacks 8354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project = new ArrayList<SurfaceHolder.Callback>(); 8454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 85f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project final int[] mLocation = new int[2]; 86f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project 8754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final ReentrantLock mSurfaceLock = new ReentrantLock(); 8854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final Surface mSurface = new Surface(); 8954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project boolean mDrawingStopped = true; 9054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 9154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final WindowManager.LayoutParams mLayout 9254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project = new WindowManager.LayoutParams(); 9354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project IWindowSession mSession; 9454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project MyWindow mWindow; 95f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project final Rect mVisibleInsets = new Rect(); 9654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final Rect mWinFrame = new Rect(); 97f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project final Rect mContentInsets = new Rect(); 9854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 9954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project static final int KEEP_SCREEN_ON_MSG = 1; 10054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project static final int GET_NEW_SURFACE_MSG = 2; 10154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 10254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project boolean mIsCreating = false; 10354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 10454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final Handler mHandler = new Handler() { 10554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 10654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void handleMessage(Message msg) { 10754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project switch (msg.what) { 10854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project case KEEP_SCREEN_ON_MSG: { 10954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project setKeepScreenOn(msg.arg1 != 0); 11054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } break; 11154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project case GET_NEW_SURFACE_MSG: { 11254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project handleGetNewSurface(); 11354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } break; 11454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 11554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 11654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project }; 11754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 11854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project boolean mRequestedVisible = false; 11954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int mRequestedWidth = -1; 12054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int mRequestedHeight = -1; 12154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int mRequestedFormat = PixelFormat.OPAQUE; 12254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int mRequestedType = -1; 12354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 12454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project boolean mHaveFrame = false; 12554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project boolean mDestroyReportNeeded = false; 12654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project boolean mNewSurfaceNeeded = false; 12754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project long mLastLockTime = 0; 12854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 12954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project boolean mVisible = false; 13054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int mLeft = -1; 13154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int mTop = -1; 13254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int mWidth = -1; 13354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int mHeight = -1; 13454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int mFormat = -1; 13554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int mType = -1; 13654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final Rect mSurfaceFrame = new Rect(); 13754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 13854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public SurfaceView(Context context) { 13954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super(context); 14054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project setWillNotDraw(true); 14154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 14254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 14354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public SurfaceView(Context context, AttributeSet attrs) { 14454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super(context, attrs); 14554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project setWillNotDraw(true); 14654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 14754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 14854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public SurfaceView(Context context, AttributeSet attrs, int defStyle) { 14954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super(context, attrs, defStyle); 15054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project setWillNotDraw(true); 15154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 15254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 15354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project /** 15454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Return the SurfaceHolder providing access and control over this 15554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * SurfaceView's underlying surface. 15654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * 15754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * @return SurfaceHolder The holder of the surface. 15854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */ 15954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public SurfaceHolder getHolder() { 16054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return mSurfaceHolder; 16154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 16254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 16354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 16454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project protected void onAttachedToWindow() { 16554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super.onAttachedToWindow(); 16654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mParent.requestTransparentRegion(this); 16754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSession = getWindowSession(); 16854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLayout.token = getWindowToken(); 16954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLayout.setTitle("SurfaceView"); 17054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 17154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 17254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 17354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project protected void onWindowVisibilityChanged(int visibility) { 17454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super.onWindowVisibilityChanged(visibility); 17554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mRequestedVisible = visibility == VISIBLE; 17654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project updateWindow(false); 17754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 17854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 17954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 18054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project protected void onDetachedFromWindow() { 18154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mRequestedVisible = false; 18254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project updateWindow(false); 18354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mHaveFrame = false; 18454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (mWindow != null) { 18554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project try { 18654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSession.remove(mWindow); 18754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } catch (RemoteException ex) { 18854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 18954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mWindow = null; 19054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 19154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSession = null; 19254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLayout.token = null; 19354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 19454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super.onDetachedFromWindow(); 19554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 19654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 19754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 19854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 19954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int width = getDefaultSize(mRequestedWidth, widthMeasureSpec); 20054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int height = getDefaultSize(mRequestedHeight, heightMeasureSpec); 20154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project setMeasuredDimension(width, height); 20254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 20354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 20454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 20554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project protected void onScrollChanged(int l, int t, int oldl, int oldt) { 20654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super.onScrollChanged(l, t, oldl, oldt); 20754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project updateWindow(false); 20854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 20954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 21054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 21154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project protected void onSizeChanged(int w, int h, int oldw, int oldh) { 21254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super.onSizeChanged(w, h, oldw, oldh); 21354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project updateWindow(false); 21454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 21554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 21654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 21754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public boolean gatherTransparentRegion(Region region) { 21854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project boolean opaque = true; 21954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if ((mPrivateFlags & SKIP_DRAW) == 0) { 22054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // this view draws, remove it from the transparent region 22154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project opaque = super.gatherTransparentRegion(region); 22254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } else if (region != null) { 22354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int w = getWidth(); 22454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int h = getHeight(); 22554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (w>0 && h>0) { 22654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project getLocationInWindow(mLocation); 22754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // otherwise, punch a hole in the whole hierarchy 22854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int l = mLocation[0]; 22954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int t = mLocation[1]; 23054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project region.op(l, t, l+w, t+h, Region.Op.UNION); 23154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 23254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 23354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (PixelFormat.formatHasAlpha(mRequestedFormat)) { 23454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project opaque = false; 23554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 23654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return opaque; 23754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 23854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 23954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 24054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void draw(Canvas canvas) { 24154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // draw() is not called when SKIP_DRAW is set 24254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if ((mPrivateFlags & SKIP_DRAW) == 0) { 24354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // punch a whole in the view-hierarchy below us 24454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project canvas.drawColor(0, PorterDuff.Mode.CLEAR); 24554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 24654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super.draw(canvas); 24754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 24854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 24954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 25054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project protected void dispatchDraw(Canvas canvas) { 25154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // if SKIP_DRAW is cleared, draw() has already punched a hole 25254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) { 25354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // punch a whole in the view-hierarchy below us 25454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project canvas.drawColor(0, PorterDuff.Mode.CLEAR); 25554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 25654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // reposition ourselves where the surface is 25754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mHaveFrame = true; 25854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project updateWindow(false); 25954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super.dispatchDraw(canvas); 26054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 26154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 26254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project private void updateWindow(boolean force) { 26354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (!mHaveFrame) { 26454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return; 26554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 26654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 26754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int myWidth = mRequestedWidth; 26854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (myWidth <= 0) myWidth = getWidth(); 26954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int myHeight = mRequestedHeight; 27054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (myHeight <= 0) myHeight = getHeight(); 27154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 27254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project getLocationInWindow(mLocation); 27354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final boolean creating = mWindow == null; 27454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final boolean formatChanged = mFormat != mRequestedFormat; 27554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final boolean sizeChanged = mWidth != myWidth || mHeight != myHeight; 27654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final boolean visibleChanged = mVisible != mRequestedVisible 27754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project || mNewSurfaceNeeded; 27854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final boolean typeChanged = mType != mRequestedType; 27954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (force || creating || formatChanged || sizeChanged || visibleChanged 28054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project || typeChanged || mLeft != mLocation[0] || mTop != mLocation[1]) { 28154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 28254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (localLOGV) Log.i(TAG, "Changes: creating=" + creating 28354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project + " format=" + formatChanged + " size=" + sizeChanged 28454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project + " visible=" + visibleChanged 28554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project + " left=" + (mLeft != mLocation[0]) 28654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project + " top=" + (mTop != mLocation[1])); 28754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 28854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project try { 28954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final boolean visible = mVisible = mRequestedVisible; 29054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLeft = mLocation[0]; 29154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mTop = mLocation[1]; 29254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mWidth = myWidth; 29354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mHeight = myHeight; 29454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mFormat = mRequestedFormat; 29554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mType = mRequestedType; 29654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 29754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLayout.x = mLeft; 29854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLayout.y = mTop; 29954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLayout.width = getWidth(); 30054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLayout.height = getHeight(); 30154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLayout.format = mRequestedFormat; 30254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLayout.flags |=WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS 30354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project | WindowManager.LayoutParams.FLAG_SCALED 30454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 30554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE 30654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project ; 30754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 30854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLayout.memoryType = mRequestedType; 30954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 31054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (mWindow == null) { 31154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mWindow = new MyWindow(); 31254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLayout.type = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA; 31354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLayout.gravity = Gravity.LEFT|Gravity.TOP; 31454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSession.add(mWindow, mLayout, 315f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project mVisible ? VISIBLE : GONE, mContentInsets); 31654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 31754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 31854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (visibleChanged && (!visible || mNewSurfaceNeeded)) { 31954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project reportSurfaceDestroyed(); 32054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 32154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 32254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mNewSurfaceNeeded = false; 32354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 32454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSurfaceLock.lock(); 32554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mDrawingStopped = !visible; 32654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final int relayoutResult = mSession.relayout( 327f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project mWindow, mLayout, mWidth, mHeight, 328f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project visible ? VISIBLE : GONE, false, mWinFrame, mContentInsets, 329f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project mVisibleInsets, mSurface); 33054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (localLOGV) Log.i(TAG, "New surface: " + mSurface 33154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project + ", vis=" + visible + ", frame=" + mWinFrame); 33254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSurfaceFrame.left = 0; 33354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSurfaceFrame.top = 0; 33454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSurfaceFrame.right = mWinFrame.width(); 33554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSurfaceFrame.bottom = mWinFrame.height(); 33654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSurfaceLock.unlock(); 33754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 33854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project try { 33954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (visible) { 34054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mDestroyReportNeeded = true; 34154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 34254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project SurfaceHolder.Callback callbacks[]; 34354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project synchronized (mCallbacks) { 34454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project callbacks = new SurfaceHolder.Callback[mCallbacks.size()]; 34554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mCallbacks.toArray(callbacks); 34654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 34754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 34854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (visibleChanged) { 34954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mIsCreating = true; 35054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project for (SurfaceHolder.Callback c : callbacks) { 35154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project c.surfaceCreated(mSurfaceHolder); 35254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 35354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 35454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (creating || formatChanged || sizeChanged 35554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project || visibleChanged) { 35654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project for (SurfaceHolder.Callback c : callbacks) { 35754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project c.surfaceChanged(mSurfaceHolder, mFormat, mWidth, mHeight); 35854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 35954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 36054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 36154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } finally { 36254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mIsCreating = false; 36354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (creating || (relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) { 36454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSession.finishDrawing(mWindow); 36554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 36654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 36754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } catch (RemoteException ex) { 36854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 36954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (localLOGV) Log.v( 37054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y + 37154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project " w=" + mLayout.width + " h=" + mLayout.height + 37254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project ", frame=" + mSurfaceFrame); 37354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 37454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 37554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 37654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project private void reportSurfaceDestroyed() { 37754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (mDestroyReportNeeded) { 37854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mDestroyReportNeeded = false; 37954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project SurfaceHolder.Callback callbacks[]; 38054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project synchronized (mCallbacks) { 38154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project callbacks = new SurfaceHolder.Callback[mCallbacks.size()]; 38254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mCallbacks.toArray(callbacks); 38354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 38454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project for (SurfaceHolder.Callback c : callbacks) { 38554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project c.surfaceDestroyed(mSurfaceHolder); 38654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 38754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 38854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super.onDetachedFromWindow(); 38954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 39054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 39154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project void handleGetNewSurface() { 39254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mNewSurfaceNeeded = true; 39354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project updateWindow(false); 39454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 39554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 39654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project private class MyWindow extends IWindow.Stub { 397f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project public void resized(int w, int h, Rect coveredInsets, 398f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project Rect visibleInsets, boolean reportDraw) { 39954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (localLOGV) Log.v( 40054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project "SurfaceView", SurfaceView.this + " got resized: w=" + 40154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project w + " h=" + h + ", cur w=" + mCurWidth + " h=" + mCurHeight); 40254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project synchronized (this) { 40354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (mCurWidth != w || mCurHeight != h) { 40454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mCurWidth = w; 40554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mCurHeight = h; 40654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 40754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (reportDraw) { 40854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project try { 40954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSession.finishDrawing(mWindow); 41054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } catch (RemoteException e) { 41154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 41254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 41354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 41454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 41554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 41654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void dispatchKey(KeyEvent event) { 41754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project //Log.w("SurfaceView", "Unexpected key event in surface: " + event); 41854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (mSession != null && mSurface != null) { 41954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project try { 42054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSession.finishKey(mWindow); 42154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } catch (RemoteException ex) { 42254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 42354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 42454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 42554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 42654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void dispatchPointer(MotionEvent event, long eventTime) { 42754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Log.w("SurfaceView", "Unexpected pointer event in surface: " + event); 42854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project //if (mSession != null && mSurface != null) { 42954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // try { 43054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // //mSession.finishKey(mWindow); 43154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // } catch (RemoteException ex) { 43254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // } 43354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project //} 43454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 43554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 43654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void dispatchTrackball(MotionEvent event, long eventTime) { 43754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Log.w("SurfaceView", "Unexpected trackball event in surface: " + event); 43854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project //if (mSession != null && mSurface != null) { 43954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // try { 44054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // //mSession.finishKey(mWindow); 44154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // } catch (RemoteException ex) { 44254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // } 44354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project //} 44454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 44554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 44654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void dispatchAppVisibility(boolean visible) { 44754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // The point of SurfaceView is to let the app control the surface. 44854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 44954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 45054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void dispatchGetNewSurface() { 45154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Message msg = mHandler.obtainMessage(GET_NEW_SURFACE_MSG); 45254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mHandler.sendMessage(msg); 45354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 45454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 45554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void windowFocusChanged(boolean hasFocus, boolean touchEnabled) { 45654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Log.w("SurfaceView", "Unexpected focus in surface: focus=" + hasFocus + ", touchEnabled=" + touchEnabled); 45754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 45854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 45954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void executeCommand(String command, String parameters, ParcelFileDescriptor out) { 46054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 46154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 46254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int mCurWidth = -1; 46354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int mCurHeight = -1; 46454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 46554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 46654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project private SurfaceHolder mSurfaceHolder = new SurfaceHolder() { 46754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 46854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project private static final String LOG_TAG = "SurfaceHolder"; 46954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 47054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public boolean isCreating() { 47154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return mIsCreating; 47254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 47354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 47454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void addCallback(Callback callback) { 47554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project synchronized (mCallbacks) { 47654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // This is a linear search, but in practice we'll 47754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // have only a couple callbacks, so it doesn't matter. 47854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (mCallbacks.contains(callback) == false) { 47954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mCallbacks.add(callback); 48054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 48154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 48254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 48354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 48454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void removeCallback(Callback callback) { 48554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project synchronized (mCallbacks) { 48654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mCallbacks.remove(callback); 48754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 48854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 48954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 49054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void setFixedSize(int width, int height) { 49154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (mRequestedWidth != width || mRequestedHeight != height) { 49254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mRequestedWidth = width; 49354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mRequestedHeight = height; 49454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project requestLayout(); 49554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 49654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 49754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 49854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void setSizeFromLayout() { 49954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (mRequestedWidth != -1 || mRequestedHeight != -1) { 50054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mRequestedWidth = mRequestedHeight = -1; 50154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project requestLayout(); 50254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 50354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 50454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 50554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void setFormat(int format) { 50654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mRequestedFormat = format; 50754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (mWindow != null) { 50854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project updateWindow(false); 50954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 51054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 51154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 51254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void setType(int type) { 51354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project switch (type) { 51454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project case SURFACE_TYPE_NORMAL: 51554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project case SURFACE_TYPE_HARDWARE: 51654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project case SURFACE_TYPE_GPU: 51754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project case SURFACE_TYPE_PUSH_BUFFERS: 51854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mRequestedType = type; 51954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (mWindow != null) { 52054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project updateWindow(false); 52154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 52254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project break; 52354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 52454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 52554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 52654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void setKeepScreenOn(boolean screenOn) { 52754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Message msg = mHandler.obtainMessage(KEEP_SCREEN_ON_MSG); 52854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project msg.arg1 = screenOn ? 1 : 0; 52954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mHandler.sendMessage(msg); 53054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 53154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 53254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public Canvas lockCanvas() { 53354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return internalLockCanvas(null); 53454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 53554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 53654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public Canvas lockCanvas(Rect dirty) { 53754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return internalLockCanvas(dirty); 53854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 53954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 54054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project private final Canvas internalLockCanvas(Rect dirty) { 54154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (mType == SURFACE_TYPE_PUSH_BUFFERS) { 54254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project throw new BadSurfaceTypeException( 54354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project "Surface type is SURFACE_TYPE_PUSH_BUFFERS"); 54454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 54554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSurfaceLock.lock(); 54654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 54754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (localLOGV) Log.i(TAG, "Locking canvas... stopped=" 54854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project + mDrawingStopped + ", win=" + mWindow); 54954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 55054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Canvas c = null; 55154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (!mDrawingStopped && mWindow != null) { 55254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Rect frame = dirty != null ? dirty : mSurfaceFrame; 55354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project try { 55454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project c = mSurface.lockCanvas(frame); 55554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } catch (Exception e) { 55654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Log.e(LOG_TAG, "Exception locking surface", e); 55754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 55854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 55954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 56054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (localLOGV) Log.i(TAG, "Returned canvas: " + c); 56154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (c != null) { 56254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLastLockTime = SystemClock.uptimeMillis(); 56354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return c; 56454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 56554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 56654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // If the Surface is not ready to be drawn, then return null, 56754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // but throttle calls to this function so it isn't called more 56854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // than every 100ms. 56954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project long now = SystemClock.uptimeMillis(); 57054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project long nextTime = mLastLockTime + 100; 57154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (nextTime > now) { 57254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project try { 57354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Thread.sleep(nextTime-now); 57454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } catch (InterruptedException e) { 57554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 57654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project now = SystemClock.uptimeMillis(); 57754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 57854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mLastLockTime = now; 57954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSurfaceLock.unlock(); 58054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 58154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return null; 58254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 58354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 58454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void unlockCanvasAndPost(Canvas canvas) { 58554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSurface.unlockCanvasAndPost(canvas); 58654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mSurfaceLock.unlock(); 58754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 58854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 58954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public Surface getSurface() { 59054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return mSurface; 59154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 59254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 59354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public Rect getSurfaceFrame() { 59454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return mSurfaceFrame; 59554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 59654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project }; 59754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project} 59854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 599