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