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