154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project/*
254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project *
454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * you may not use this file except in compliance with the License.
654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * You may obtain a copy of the License at
754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project *
854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project *
1054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * See the License for the specific language governing permissions and
1454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * limitations under the License.
1554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */
1654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
1754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectpackage android.view;
1854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
1972c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackbornimport com.android.internal.view.BaseIWindow;
2072c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn
2154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.content.Context;
22e36d6e277e49475076b7872d36ea6a5c5b996e9dDianne Hackbornimport android.content.res.Configuration;
2364f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshimaimport android.content.res.CompatibilityInfo.Translator;
2454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.Canvas;
2554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.PixelFormat;
2654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.PorterDuff;
2754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.Rect;
2854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.Region;
2954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.os.Handler;
3054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.os.Message;
3154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.os.RemoteException;
3254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.os.SystemClock;
3354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.os.ParcelFileDescriptor;
3454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.util.AttributeSet;
3554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.util.Log;
3654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
379bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimerimport java.lang.ref.WeakReference;
389bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimerimport java.util.ArrayList;
3954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport java.util.concurrent.locks.ReentrantLock;
4054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
4154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project/**
4254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Provides a dedicated drawing surface embedded inside of a view hierarchy.
4354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * You can control the format of this surface and, if you like, its size; the
4454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * SurfaceView takes care of placing the surface at the correct location on the
4554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * screen
46a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin *
4754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p>The surface is Z ordered so that it is behind the window holding its
4854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * SurfaceView; the SurfaceView punches a hole in its window to allow its
49c9f345ff7bc59916d5168d49d9312b2ff7a07daaJesse Hall * surface to be displayed. The view hierarchy will take care of correctly
5054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * compositing with the Surface any siblings of the SurfaceView that would
51c9f345ff7bc59916d5168d49d9312b2ff7a07daaJesse Hall * normally appear on top of it. This can be used to place overlays such as
5254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * buttons on top of the Surface, though note however that it can have an
5354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * impact on performance since a full alpha-blended composite will be performed
5454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * each time the Surface changes.
55a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin *
56c9f345ff7bc59916d5168d49d9312b2ff7a07daaJesse Hall * <p> The transparent region that makes the surface visible is based on the
57c9f345ff7bc59916d5168d49d9312b2ff7a07daaJesse Hall * layout positions in the view hierarchy. If the post-layout transform
58c9f345ff7bc59916d5168d49d9312b2ff7a07daaJesse Hall * properties are used to draw a sibling view on top of the SurfaceView, the
59c9f345ff7bc59916d5168d49d9312b2ff7a07daaJesse Hall * view may not be properly composited with the surface.
60c9f345ff7bc59916d5168d49d9312b2ff7a07daaJesse Hall *
6154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p>Access to the underlying surface is provided via the SurfaceHolder interface,
6254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * which can be retrieved by calling {@link #getHolder}.
63a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin *
6454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p>The Surface will be created for you while the SurfaceView's window is
6554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * visible; you should implement {@link SurfaceHolder.Callback#surfaceCreated}
6654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * and {@link SurfaceHolder.Callback#surfaceDestroyed} to discover when the
6754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Surface is created and destroyed as the window is shown and hidden.
68a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin *
6954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p>One of the purposes of this class is to provide a surface in which a
70c9f345ff7bc59916d5168d49d9312b2ff7a07daaJesse Hall * secondary thread can render into the screen. If you are going to use it
7154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * this way, you need to be aware of some threading semantics:
72a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin *
7354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <ul>
7454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <li> All SurfaceView and
7554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * {@link SurfaceHolder.Callback SurfaceHolder.Callback} methods will be called
7654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * from the thread running the SurfaceView's window (typically the main thread
77c9f345ff7bc59916d5168d49d9312b2ff7a07daaJesse Hall * of the application). They thus need to correctly synchronize with any
7854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * state that is also touched by the drawing thread.
7954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <li> You must ensure that the drawing thread only touches the underlying
8054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Surface while it is valid -- between
8154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * {@link SurfaceHolder.Callback#surfaceCreated SurfaceHolder.Callback.surfaceCreated()}
8254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * and
8354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * {@link SurfaceHolder.Callback#surfaceDestroyed SurfaceHolder.Callback.surfaceDestroyed()}.
8454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * </ul>
8554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */
8654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectpublic class SurfaceView extends View {
8754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    static private final String TAG = "SurfaceView";
8854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    static private final boolean DEBUG = false;
8954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
9054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    final ArrayList<SurfaceHolder.Callback> mCallbacks
9154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            = new ArrayList<SurfaceHolder.Callback>();
9254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
93f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    final int[] mLocation = new int[2];
94a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
9554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    final ReentrantLock mSurfaceLock = new ReentrantLock();
9661566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn    final Surface mSurface = new Surface();       // Current surface in use
9761566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn    final Surface mNewSurface = new Surface();    // New surface we are switching to
9854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    boolean mDrawingStopped = true;
9954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
10054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    final WindowManager.LayoutParams mLayout
10154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            = new WindowManager.LayoutParams();
10254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    IWindowSession mSession;
10354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    MyWindow mWindow;
104f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    final Rect mVisibleInsets = new Rect();
10554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    final Rect mWinFrame = new Rect();
106c4aad01cbbb69c916ef323693e1fd0560b0eccbaDianne Hackborn    final Rect mOverscanInsets = new Rect();
107f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    final Rect mContentInsets = new Rect();
108fa10423fa00f3495e451016acba9b6848eb995c9Adrian Roos    final Rect mStableInsets = new Rect();
109694f79b5d1196640d1beb680b7d1fc68e6e77cbdDianne Hackborn    final Configuration mConfiguration = new Configuration();
110a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
11154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    static final int KEEP_SCREEN_ON_MSG = 1;
11254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    static final int GET_NEW_SURFACE_MSG = 2;
113726426ee736929e605742bfa52bca4b20095921dDianne Hackborn    static final int UPDATE_WINDOW_MSG = 3;
114a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
115c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn    int mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
116a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
11754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    boolean mIsCreating = false;
11854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
11954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    final Handler mHandler = new Handler() {
12054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        @Override
12154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void handleMessage(Message msg) {
12254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            switch (msg.what) {
12354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                case KEEP_SCREEN_ON_MSG: {
12454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    setKeepScreenOn(msg.arg1 != 0);
12554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                } break;
12654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                case GET_NEW_SURFACE_MSG: {
12754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    handleGetNewSurface();
12854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                } break;
129726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                case UPDATE_WINDOW_MSG: {
130d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    updateWindow(false, false);
131726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                } break;
13254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
13354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
13454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    };
135a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
136e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn    final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener
137e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn            = new ViewTreeObserver.OnScrollChangedListener() {
138a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin                    @Override
139e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn                    public void onScrollChanged() {
140d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                        updateWindow(false, false);
141e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn                    }
142e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn            };
143a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
14454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    boolean mRequestedVisible = false;
1456b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian    boolean mWindowVisibility = false;
1466b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian    boolean mViewVisibility = false;
14754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mRequestedWidth = -1;
14854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mRequestedHeight = -1;
149d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian    /* Set SurfaceView's format to 565 by default to maintain backward
150d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian     * compatibility with applications assuming this format.
151d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian     */
152d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian    int mRequestedFormat = PixelFormat.RGB_565;
15354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
15454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    boolean mHaveFrame = false;
1556d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn    boolean mSurfaceCreated = false;
15654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    long mLastLockTime = 0;
157a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
15854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    boolean mVisible = false;
15954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mLeft = -1;
16054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mTop = -1;
16154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mWidth = -1;
16254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mHeight = -1;
16354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mFormat = -1;
16454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    final Rect mSurfaceFrame = new Rect();
165726426ee736929e605742bfa52bca4b20095921dDianne Hackborn    int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1;
166726426ee736929e605742bfa52bca4b20095921dDianne Hackborn    boolean mUpdateWindowNeeded;
167726426ee736929e605742bfa52bca4b20095921dDianne Hackborn    boolean mReportDrawNeeded;
16864f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima    private Translator mTranslator;
169f2499fa434521a8948387afe8f0acd4f39620500Romain Guy
170f2499fa434521a8948387afe8f0acd4f39620500Romain Guy    private final ViewTreeObserver.OnPreDrawListener mDrawListener =
171f2499fa434521a8948387afe8f0acd4f39620500Romain Guy            new ViewTreeObserver.OnPreDrawListener() {
172f2499fa434521a8948387afe8f0acd4f39620500Romain Guy                @Override
173f2499fa434521a8948387afe8f0acd4f39620500Romain Guy                public boolean onPreDraw() {
174a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin                    // reposition ourselves where the surface is
1750c75622cf80e53c13d079bfe1f3df0b185c4f02dRomain Guy                    mHaveFrame = getWidth() > 0 && getHeight() > 0;
176f2499fa434521a8948387afe8f0acd4f39620500Romain Guy                    updateWindow(false, false);
177f2499fa434521a8948387afe8f0acd4f39620500Romain Guy                    return true;
178f2499fa434521a8948387afe8f0acd4f39620500Romain Guy                }
179f2499fa434521a8948387afe8f0acd4f39620500Romain Guy            };
18001d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy    private boolean mGlobalListenersAdded;
181f2499fa434521a8948387afe8f0acd4f39620500Romain Guy
18254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public SurfaceView(Context context) {
18354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super(context);
184d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian        init();
18554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
186a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
18754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public SurfaceView(Context context, AttributeSet attrs) {
18854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super(context, attrs);
189d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian        init();
19054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
19154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
192617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    public SurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
193617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        super(context, attrs, defStyleAttr);
194617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        init();
195617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    }
196617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette
197617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette    public SurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
198617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette        super(context, attrs, defStyleAttr, defStyleRes);
199d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian        init();
200d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian    }
201d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian
202d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian    private void init() {
20354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        setWillNotDraw(true);
20454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
205a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
20654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    /**
20754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     * Return the SurfaceHolder providing access and control over this
20854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     * SurfaceView's underlying surface.
209a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     *
21054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     * @return SurfaceHolder The holder of the surface.
21154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     */
21254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public SurfaceHolder getHolder() {
21354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return mSurfaceHolder;
21454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
21554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
21654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
21754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    protected void onAttachedToWindow() {
21854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super.onAttachedToWindow();
21954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mParent.requestTransparentRegion(this);
22054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mSession = getWindowSession();
22154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mLayout.token = getWindowToken();
22254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mLayout.setTitle("SurfaceView");
2236b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian        mViewVisibility = getVisibility() == VISIBLE;
22401d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy
22501d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy        if (!mGlobalListenersAdded) {
22601d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy            ViewTreeObserver observer = getViewTreeObserver();
22701d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy            observer.addOnScrollChangedListener(mScrollChangedListener);
22801d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy            observer.addOnPreDrawListener(mDrawListener);
22901d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy            mGlobalListenersAdded = true;
23001d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy        }
23154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
23254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
23354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
23454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    protected void onWindowVisibilityChanged(int visibility) {
23554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super.onWindowVisibilityChanged(visibility);
2366b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian        mWindowVisibility = visibility == VISIBLE;
2376b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian        mRequestedVisible = mWindowVisibility && mViewVisibility;
238d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        updateWindow(false, false);
2396b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian    }
2406b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian
2416b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian    @Override
2426b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian    public void setVisibility(int visibility) {
2436b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian        super.setVisibility(visibility);
2446b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian        mViewVisibility = visibility == VISIBLE;
245cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian        boolean newRequestedVisible = mWindowVisibility && mViewVisibility;
246cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian        if (newRequestedVisible != mRequestedVisible) {
247cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian            // our base class (View) invalidates the layout only when
248cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian            // we go from/to the GONE state. However, SurfaceView needs
249cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian            // to request a re-layout when the visibility changes at all.
250cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian            // This is needed because the transparent region is computed
251cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian            // as part of the layout phase, and it changes (obviously) when
252cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian            // the visibility changes.
253cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian            requestLayout();
254cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian        }
255cbeb33249d5beec7903f18269c991a5515c5d981Mathias Agopian        mRequestedVisible = newRequestedVisible;
256d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        updateWindow(false, false);
25754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
258afc3e11f10828e113331eb24b65e4f9759f67747Romain Guy
25954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
26077e4a5250fc6df451999efe508f57968a44b603fJohn Reck    protected void onDetachedFromWindow() {
26101d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy        if (mGlobalListenersAdded) {
26201d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy            ViewTreeObserver observer = getViewTreeObserver();
26301d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy            observer.removeOnScrollChangedListener(mScrollChangedListener);
26401d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy            observer.removeOnPreDrawListener(mDrawListener);
26501d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy            mGlobalListenersAdded = false;
26601d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy        }
26701d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy
26854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mRequestedVisible = false;
269d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        updateWindow(false, false);
27054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mHaveFrame = false;
27154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (mWindow != null) {
27254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            try {
27354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mSession.remove(mWindow);
27454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            } catch (RemoteException ex) {
27501d5edc49ae8995aabffe1a30bfd966faaf70bd6Romain Guy                // Not much we can do here...
27654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
27754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mWindow = null;
27854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
27954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mSession = null;
28054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mLayout.token = null;
28154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
28277e4a5250fc6df451999efe508f57968a44b603fJohn Reck        super.onDetachedFromWindow();
28354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
28454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
28554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
28654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
287189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn        int width = mRequestedWidth >= 0
288189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn                ? resolveSizeAndState(mRequestedWidth, widthMeasureSpec, 0)
289189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn                : getDefaultSize(0, widthMeasureSpec);
290189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn        int height = mRequestedHeight >= 0
291189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn                ? resolveSizeAndState(mRequestedHeight, heightMeasureSpec, 0)
292189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn                : getDefaultSize(0, heightMeasureSpec);
29354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        setMeasuredDimension(width, height);
29454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
295a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
296ef11530874f86570aa04a10c16a416b274b3fdf5Mathias Agopian    /** @hide */
29754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
298995bb9d24d3b278939a01e1d05c2b7f337ab0565Mathias Agopian    protected boolean setFrame(int left, int top, int right, int bottom) {
299995bb9d24d3b278939a01e1d05c2b7f337ab0565Mathias Agopian        boolean result = super.setFrame(left, top, right, bottom);
300d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        updateWindow(false, false);
301995bb9d24d3b278939a01e1d05c2b7f337ab0565Mathias Agopian        return result;
30254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
30354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
30454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
30554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public boolean gatherTransparentRegion(Region region) {
3061cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn        if (mWindowType == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
3071cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn            return super.gatherTransparentRegion(region);
3081cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn        }
309a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
31054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        boolean opaque = true;
3114702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn        if ((mPrivateFlags & PFLAG_SKIP_DRAW) == 0) {
31254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // this view draws, remove it from the transparent region
31354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            opaque = super.gatherTransparentRegion(region);
31454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        } else if (region != null) {
31554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            int w = getWidth();
31654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            int h = getHeight();
31754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (w>0 && h>0) {
31854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                getLocationInWindow(mLocation);
31954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                // otherwise, punch a hole in the whole hierarchy
32054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                int l = mLocation[0];
32154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                int t = mLocation[1];
32254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                region.op(l, t, l+w, t+h, Region.Op.UNION);
32354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
32454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
32554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (PixelFormat.formatHasAlpha(mRequestedFormat)) {
32654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            opaque = false;
32754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
32854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return opaque;
32954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
33054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
33154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
33254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public void draw(Canvas canvas) {
3331cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn        if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
3341cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn            // draw() is not called when SKIP_DRAW is set
3354702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn            if ((mPrivateFlags & PFLAG_SKIP_DRAW) == 0) {
3361cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn                // punch a whole in the view-hierarchy below us
3371cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn                canvas.drawColor(0, PorterDuff.Mode.CLEAR);
3381cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn            }
33954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
34054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super.draw(canvas);
34154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
34254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
34354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
34454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    protected void dispatchDraw(Canvas canvas) {
3451cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn        if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
3461cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn            // if SKIP_DRAW is cleared, draw() has already punched a hole
3474702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn            if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
3481cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn                // punch a whole in the view-hierarchy below us
3491cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn                canvas.drawColor(0, PorterDuff.Mode.CLEAR);
3501cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn            }
35154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
35254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super.dispatchDraw(canvas);
35354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
35454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
355c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn    /**
35629e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * Control whether the surface view's surface is placed on top of another
35729e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * regular surface view in the window (but still behind the window itself).
35829e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * This is typically used to place overlays on top of an underlying media
35929e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * surface view.
360a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     *
36129e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * <p>Note that this must be set before the surface view's containing
36229e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * window is attached to the window manager.
363a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     *
36429e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * <p>Calling this overrides any previous call to {@link #setZOrderOnTop}.
36529e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     */
36629e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn    public void setZOrderMediaOverlay(boolean isMediaOverlay) {
36729e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn        mWindowType = isMediaOverlay
36829e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn                ? WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY
36929e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn                : WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
37029e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn    }
371a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
37229e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn    /**
3731cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * Control whether the surface view's surface is placed on top of its
3741cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * window.  Normally it is placed behind the window, to allow it to
3751cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * (for the most part) appear to composite with the views in the
3761cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * hierarchy.  By setting this, you cause it to be placed above the
3771cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * window.  This means that none of the contents of the window this
3781cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * SurfaceView is in will be visible on top of its surface.
379a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     *
3801cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * <p>Note that this must be set before the surface view's containing
3811cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * window is attached to the window manager.
382a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     *
38329e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * <p>Calling this overrides any previous call to {@link #setZOrderMediaOverlay}.
3841cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     */
38529e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn    public void setZOrderOnTop(boolean onTop) {
386ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger        if (onTop) {
387ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger            mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
388ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger            // ensures the surface is placed below the IME
389ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger            mLayout.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
390ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger        } else {
391ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger            mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
392ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger            mLayout.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
393ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger        }
3941cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn    }
395f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown
396f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown    /**
397f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown     * Control whether the surface view's content should be treated as secure,
398f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown     * preventing it from appearing in screenshots or from being viewed on
399f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown     * non-secure displays.
400f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown     *
401f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown     * <p>Note that this must be set before the surface view's containing
402f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown     * window is attached to the window manager.
403f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown     *
404f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown     * <p>See {@link android.view.Display#FLAG_SECURE} for details.
405f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown     *
406f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown     * @param isSecure True if the surface view is secure.
407f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown     */
408f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown    public void setSecure(boolean isSecure) {
409f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown        if (isSecure) {
410f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown            mLayout.flags |= WindowManager.LayoutParams.FLAG_SECURE;
411f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown        } else {
412f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown            mLayout.flags &= ~WindowManager.LayoutParams.FLAG_SECURE;
413f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown        }
414f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown    }
415f0681b34dffc1510cbd9c3da5c3a7e695553fa8dJeff Brown
4161cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn    /**
417c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn     * Hack to allow special layering of windows.  The type is one of the
418c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn     * types in WindowManager.LayoutParams.  This is a hack so:
419c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn     * @hide
420c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn     */
421c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn    public void setWindowType(int type) {
422c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn        mWindowType = type;
423c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn    }
42434bf2ee9e695c620e0a4b9a790f1f6ccb8a77234Mitsuru Oshima
4259a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho    /** @hide */
4269a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho    protected void updateWindow(boolean force, boolean redrawNeeded) {
42754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (!mHaveFrame) {
42854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return;
42954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
430a175a5b7ea3682cb58cca7f9726d0b8171cd549dJeff Brown        ViewRootImpl viewRoot = getViewRootImpl();
431168173a698e820ceb1ebf54b4910888891be2056Joe Onorato        if (viewRoot != null) {
432168173a698e820ceb1ebf54b4910888891be2056Joe Onorato            mTranslator = viewRoot.mTranslator;
433168173a698e820ceb1ebf54b4910888891be2056Joe Onorato        }
43464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima
4355be8de3420ba4c9d816b98e29bdec11715f6b626Dianne Hackborn        if (mTranslator != null) {
4365be8de3420ba4c9d816b98e29bdec11715f6b626Dianne Hackborn            mSurface.setCompatibilityTranslator(mTranslator);
43738ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima        }
438a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
43954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int myWidth = mRequestedWidth;
44054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (myWidth <= 0) myWidth = getWidth();
44154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int myHeight = mRequestedHeight;
44254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (myHeight <= 0) myHeight = getHeight();
443001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima
44454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        getLocationInWindow(mLocation);
44554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        final boolean creating = mWindow == null;
44654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        final boolean formatChanged = mFormat != mRequestedFormat;
44754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        final boolean sizeChanged = mWidth != myWidth || mHeight != myHeight;
4486d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn        final boolean visibleChanged = mVisible != mRequestedVisible;
449d2112306330ce0c162bee4b864991962ca2b655aMathias Agopian
45054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (force || creating || formatChanged || sizeChanged || visibleChanged
451d2112306330ce0c162bee4b864991962ca2b655aMathias Agopian            || mLeft != mLocation[0] || mTop != mLocation[1]
452d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn            || mUpdateWindowNeeded || mReportDrawNeeded || redrawNeeded) {
45354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
4546d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn            if (DEBUG) Log.i(TAG, "Changes: creating=" + creating
45554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    + " format=" + formatChanged + " size=" + sizeChanged
45654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    + " visible=" + visibleChanged
45754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    + " left=" + (mLeft != mLocation[0])
45854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    + " top=" + (mTop != mLocation[1]));
45964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima
46054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            try {
46154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                final boolean visible = mVisible = mRequestedVisible;
46254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mLeft = mLocation[0];
46354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mTop = mLocation[1];
46454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mWidth = myWidth;
46554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mHeight = myHeight;
46654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mFormat = mRequestedFormat;
46754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
46864f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                // Scaling/Translate window's layout here because mLayout is not used elsewhere.
469a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
47064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                // Places the window relative
47164f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                mLayout.x = mLeft;
47264f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                mLayout.y = mTop;
47364f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                mLayout.width = getWidth();
47464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                mLayout.height = getHeight();
47564f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                if (mTranslator != null) {
47664f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                    mTranslator.translateLayoutParamsInAppWindowToScreen(mLayout);
47764f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                }
478a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
47954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mLayout.format = mRequestedFormat;
4801cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn                mLayout.flags |=WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
4811cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn                              | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
4821cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn                              | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
48354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                              | WindowManager.LayoutParams.FLAG_SCALED
48454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                              | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
48554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                              | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
48654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                              ;
487841f13c8e9ff3f7695b6c18a8abcec3c947983ffMitsuru Oshima                if (!getContext().getResources().getCompatibilityInfo().supportsScreen()) {
48895c42974f719d1fac90fc0438eac778e9795681fAdam Lesinski                    mLayout.privateFlags |=
48995c42974f719d1fac90fc0438eac778e9795681fAdam Lesinski                            WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
490841f13c8e9ff3f7695b6c18a8abcec3c947983ffMitsuru Oshima                }
4911c5383ce0b4e162ebc9ac7e29c8c39377724d45bDianne Hackborn                mLayout.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
49254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
49354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                if (mWindow == null) {
4948d0243a3d0269d3a57d90eb2e7b12b41f53b27d9Jeff Brown                    Display display = getDisplay();
4959bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                    mWindow = new MyWindow(this);
496c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn                    mLayout.type = mWindowType;
497aac0d4ed026d1cfbcf3fa81c6e4eb96f4347ca17Fabrice Di Meglio                    mLayout.gravity = Gravity.START|Gravity.TOP;
4986881a10557acf3b0270de54799d6f19437acf584Craig Mautner                    mSession.addToDisplayWithoutInputChannel(mWindow, mWindow.mSeq, mLayout,
49937d7a68de7e353c31a3a4736054cd86f0e002eafAdrian Roos                            mVisible ? VISIBLE : GONE, display.getDisplayId(), mContentInsets,
50037d7a68de7e353c31a3a4736054cd86f0e002eafAdrian Roos                            mStableInsets);
50154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
502a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
503726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                boolean realSizeChanged;
504726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                boolean reportDrawNeeded;
5056d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn
5066d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                int relayoutResult;
5076d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn
508726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                mSurfaceLock.lock();
509726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                try {
510726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    mUpdateWindowNeeded = false;
511726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    reportDrawNeeded = mReportDrawNeeded;
512726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    mReportDrawNeeded = false;
513726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    mDrawingStopped = !visible;
514a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
5156d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                    if (DEBUG) Log.i(TAG, "Cur surface: " + mSurface);
5166d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn
5176d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                    relayoutResult = mSession.relayout(
5189a230e01a1237749a8a19a5de8d46531b0c8ca6aDianne Hackborn                        mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
5196d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                            visible ? VISIBLE : GONE,
52098365d7663cbd82979a5700faf0050220b01084dJeff Brown                            WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY,
521c4aad01cbbb69c916ef323693e1fd0560b0eccbaDianne Hackborn                            mWinFrame, mOverscanInsets, mContentInsets,
522fa10423fa00f3495e451016acba9b6848eb995c9Adrian Roos                            mVisibleInsets, mStableInsets, mConfiguration, mNewSurface);
52398365d7663cbd82979a5700faf0050220b01084dJeff Brown                    if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
524726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        mReportDrawNeeded = true;
525726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    }
5266d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn
5276d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                    if (DEBUG) Log.i(TAG, "New surface: " + mNewSurface
528726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                            + ", vis=" + visible + ", frame=" + mWinFrame);
5296d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn
530726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    mSurfaceFrame.left = 0;
531726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    mSurfaceFrame.top = 0;
532726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    if (mTranslator == null) {
533726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        mSurfaceFrame.right = mWinFrame.width();
534726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        mSurfaceFrame.bottom = mWinFrame.height();
535726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    } else {
536726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        float appInvertedScale = mTranslator.applicationInvertedScale;
537726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        mSurfaceFrame.right = (int) (mWinFrame.width() * appInvertedScale + 0.5f);
538726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        mSurfaceFrame.bottom = (int) (mWinFrame.height() * appInvertedScale + 0.5f);
539726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    }
540a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
541726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    final int surfaceWidth = mSurfaceFrame.right;
542726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    final int surfaceHeight = mSurfaceFrame.bottom;
543726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    realSizeChanged = mLastSurfaceWidth != surfaceWidth
544726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                            || mLastSurfaceHeight != surfaceHeight;
545726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    mLastSurfaceWidth = surfaceWidth;
546726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    mLastSurfaceHeight = surfaceHeight;
547726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                } finally {
548726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    mSurfaceLock.unlock();
549589cebe2d58591403de4a77077941c0454bc91bcMitsuru Oshima                }
55054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
55154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                try {
552d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    redrawNeeded |= creating | reportDrawNeeded;
553d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn
5546d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                    SurfaceHolder.Callback callbacks[] = null;
55554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
55698365d7663cbd82979a5700faf0050220b01084dJeff Brown                    final boolean surfaceChanged = (relayoutResult
55798365d7663cbd82979a5700faf0050220b01084dJeff Brown                            & WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED) != 0;
5586d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                    if (mSurfaceCreated && (surfaceChanged || (!visible && visibleChanged))) {
5596d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                        mSurfaceCreated = false;
5606d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                        if (mSurface.isValid()) {
5616d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                            if (DEBUG) Log.i(TAG, "visibleChanged -- surfaceDestroyed");
5626d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                            callbacks = getSurfaceCallbacks();
5636d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                            for (SurfaceHolder.Callback c : callbacks) {
5646d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                                c.surfaceDestroyed(mSurfaceHolder);
5656d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                            }
5663d91492d694cf00474fec792134e496be6ee0313Mitsuru Oshima                        }
5676d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                    }
5686d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn
56961566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn                    mSurface.transferFrom(mNewSurface);
57054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
571f750b8ce3c8cb30bcbc5fe53087c7e9035078ebaAndreas Röhl                    if (visible && mSurface.isValid()) {
5726d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                        if (!mSurfaceCreated && (surfaceChanged || visibleChanged)) {
5736d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                            mSurfaceCreated = true;
57454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            mIsCreating = true;
5756d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                            if (DEBUG) Log.i(TAG, "visibleChanged -- surfaceCreated");
5766d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                            if (callbacks == null) {
5776d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                                callbacks = getSurfaceCallbacks();
5786d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                            }
57954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            for (SurfaceHolder.Callback c : callbacks) {
58054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                c.surfaceCreated(mSurfaceHolder);
58154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            }
58254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        }
58354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        if (creating || formatChanged || sizeChanged
584726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                                || visibleChanged || realSizeChanged) {
5856d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                            if (DEBUG) Log.i(TAG, "surfaceChanged -- format=" + mFormat
5866d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                                    + " w=" + myWidth + " h=" + myHeight);
5876d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                            if (callbacks == null) {
5886d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                                callbacks = getSurfaceCallbacks();
5896d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                            }
590251fd430c7e355ad440202c83b0c6d91f5bf93e5Dianne Hackborn                            for (SurfaceHolder.Callback c : callbacks) {
591251fd430c7e355ad440202c83b0c6d91f5bf93e5Dianne Hackborn                                c.surfaceChanged(mSurfaceHolder, mFormat, myWidth, myHeight);
592251fd430c7e355ad440202c83b0c6d91f5bf93e5Dianne Hackborn                            }
593d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                        }
594d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                        if (redrawNeeded) {
5956d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                            if (DEBUG) Log.i(TAG, "surfaceRedrawNeeded");
5966d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                            if (callbacks == null) {
5976d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                                callbacks = getSurfaceCallbacks();
5986d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                            }
59954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            for (SurfaceHolder.Callback c : callbacks) {
600d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                                if (c instanceof SurfaceHolder.Callback2) {
601d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                                    ((SurfaceHolder.Callback2)c).surfaceRedrawNeeded(
602d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                                            mSurfaceHolder);
603d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                                }
60454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            }
60554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        }
60654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    }
60754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                } finally {
60854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    mIsCreating = false;
609d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                    if (redrawNeeded) {
6106d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                        if (DEBUG) Log.i(TAG, "finishedDrawing");
61154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        mSession.finishDrawing(mWindow);
61254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    }
6136d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                    mSession.performDeferredDestroy(mWindow);
61454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
61554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            } catch (RemoteException ex) {
61654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
6176d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn            if (DEBUG) Log.v(
61854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y +
61954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                " w=" + mLayout.width + " h=" + mLayout.height +
62054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                ", frame=" + mSurfaceFrame);
62154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
62254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
62354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
6246d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn    private SurfaceHolder.Callback[] getSurfaceCallbacks() {
6256d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn        SurfaceHolder.Callback callbacks[];
6266d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn        synchronized (mCallbacks) {
6276d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn            callbacks = new SurfaceHolder.Callback[mCallbacks.size()];
6286d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn            mCallbacks.toArray(callbacks);
62954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
6306d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn        return callbacks;
63154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
63254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
63354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    void handleGetNewSurface() {
634d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn        updateWindow(false, false);
63554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
636b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project
6377179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger    /**
6387179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger     * Check to see if the surface has fixed size dimensions or if the surface's
6397179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger     * dimensions are dimensions are dependent on its current layout.
6407179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger     *
6417179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger     * @return true if the surface has dimensions that are fixed in size
6427179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger     * @hide
6437179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger     */
6447179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger    public boolean isFixedSize() {
6457179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger        return (mRequestedWidth != -1 || mRequestedHeight != -1);
6467179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger    }
6477179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger
64872c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn    private static class MyWindow extends BaseIWindow {
6498169daed2f7a8731d478b884b1f455c747b88478Mitsuru Oshima        private final WeakReference<SurfaceView> mSurfaceView;
6509bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer
6519bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer        public MyWindow(SurfaceView surfaceView) {
6529bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer            mSurfaceView = new WeakReference<SurfaceView>(surfaceView);
6539bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer        }
6549bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer
655656e3af44432be6a2ba60289b8e787fad2506cebCraig Mautner        @Override
656c4aad01cbbb69c916ef323693e1fd0560b0eccbaDianne Hackborn        public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
657fa10423fa00f3495e451016acba9b6848eb995c9Adrian Roos                Rect visibleInsets, Rect stableInsets, boolean reportDraw,
658fa10423fa00f3495e451016acba9b6848eb995c9Adrian Roos                Configuration newConfig) {
6599bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer            SurfaceView surfaceView = mSurfaceView.get();
6609bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer            if (surfaceView != null) {
6616d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn                if (DEBUG) Log.v(
662656e3af44432be6a2ba60289b8e787fad2506cebCraig Mautner                        "SurfaceView", surfaceView + " got resized: w=" + frame.width()
663656e3af44432be6a2ba60289b8e787fad2506cebCraig Mautner                        + " h=" + frame.height() + ", cur w=" + mCurWidth + " h=" + mCurHeight);
664726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                surfaceView.mSurfaceLock.lock();
665726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                try {
6669bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                    if (reportDraw) {
667726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        surfaceView.mUpdateWindowNeeded = true;
668726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        surfaceView.mReportDrawNeeded = true;
669726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        surfaceView.mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG);
670656e3af44432be6a2ba60289b8e787fad2506cebCraig Mautner                    } else if (surfaceView.mWinFrame.width() != frame.width()
671656e3af44432be6a2ba60289b8e787fad2506cebCraig Mautner                            || surfaceView.mWinFrame.height() != frame.height()) {
672726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        surfaceView.mUpdateWindowNeeded = true;
673726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        surfaceView.mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG);
67454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    }
675726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                } finally {
676726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    surfaceView.mSurfaceLock.unlock();
67754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
67854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
67954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
68054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
681a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin        @Override
68254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void dispatchAppVisibility(boolean visible) {
68354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // The point of SurfaceView is to let the app control the surface.
68454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
685b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project
686a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin        @Override
68754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void dispatchGetNewSurface() {
6889bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer            SurfaceView surfaceView = mSurfaceView.get();
6899bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer            if (surfaceView != null) {
690b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project                Message msg = surfaceView.mHandler.obtainMessage(GET_NEW_SURFACE_MSG);
691b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project                surfaceView.mHandler.sendMessage(msg);
6929bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer            }
69354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
69454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
695a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin        @Override
69654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void windowFocusChanged(boolean hasFocus, boolean touchEnabled) {
69754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            Log.w("SurfaceView", "Unexpected focus in surface: focus=" + hasFocus + ", touchEnabled=" + touchEnabled);
69854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
69954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
700a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin        @Override
70154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
70254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
70354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
70454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int mCurWidth = -1;
70554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int mCurHeight = -1;
70654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
70754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
708a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin    private final SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
709a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
71054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        private static final String LOG_TAG = "SurfaceHolder";
711a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
712a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin        @Override
71354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public boolean isCreating() {
71454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return mIsCreating;
71554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
71654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
717a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin        @Override
71854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void addCallback(Callback callback) {
71954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            synchronized (mCallbacks) {
720a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin                // This is a linear search, but in practice we'll
72154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                // have only a couple callbacks, so it doesn't matter.
722a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin                if (mCallbacks.contains(callback) == false) {
72354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    mCallbacks.add(callback);
72454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
72554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
72654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
72754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
728a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin        @Override
72954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void removeCallback(Callback callback) {
73054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            synchronized (mCallbacks) {
73154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mCallbacks.remove(callback);
73254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
73354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
734a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
735a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin        @Override
73654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void setFixedSize(int width, int height) {
73754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (mRequestedWidth != width || mRequestedHeight != height) {
73854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mRequestedWidth = width;
73954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mRequestedHeight = height;
74054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                requestLayout();
74154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
74254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
74354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
744a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin        @Override
74554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void setSizeFromLayout() {
74654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (mRequestedWidth != -1 || mRequestedHeight != -1) {
74754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mRequestedWidth = mRequestedHeight = -1;
74854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                requestLayout();
74954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
75054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
75154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
752a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin        @Override
75354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void setFormat(int format) {
7542d468c5d73cc1cefbcfa8d98e30622c54756918cMathias Agopian
7552d468c5d73cc1cefbcfa8d98e30622c54756918cMathias Agopian            // for backward compatibility reason, OPAQUE always
7562d468c5d73cc1cefbcfa8d98e30622c54756918cMathias Agopian            // means 565 for SurfaceView
7572d468c5d73cc1cefbcfa8d98e30622c54756918cMathias Agopian            if (format == PixelFormat.OPAQUE)
7582d468c5d73cc1cefbcfa8d98e30622c54756918cMathias Agopian                format = PixelFormat.RGB_565;
7592d468c5d73cc1cefbcfa8d98e30622c54756918cMathias Agopian
76054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mRequestedFormat = format;
76154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (mWindow != null) {
762d76b67c340d1564abf8d14d976fdaf83bf2b3320Dianne Hackborn                updateWindow(false, false);
76354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
76454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
76554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
766d2112306330ce0c162bee4b864991962ca2b655aMathias Agopian        /**
767d2112306330ce0c162bee4b864991962ca2b655aMathias Agopian         * @deprecated setType is now ignored.
768d2112306330ce0c162bee4b864991962ca2b655aMathias Agopian         */
769a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin        @Override
770d2112306330ce0c162bee4b864991962ca2b655aMathias Agopian        @Deprecated
771d2112306330ce0c162bee4b864991962ca2b655aMathias Agopian        public void setType(int type) { }
77254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
773a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin        @Override
77454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void setKeepScreenOn(boolean screenOn) {
77554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            Message msg = mHandler.obtainMessage(KEEP_SCREEN_ON_MSG);
77654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            msg.arg1 = screenOn ? 1 : 0;
77754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mHandler.sendMessage(msg);
77854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
779a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
7809ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian        /**
7819ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         * Gets a {@link Canvas} for drawing into the SurfaceView's Surface
7829ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         *
7839ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         * After drawing into the provided {@link Canvas}, the caller must
7849ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface.
7859ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         *
7869ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         * The caller must redraw the entire surface.
7879ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         * @return A canvas for drawing into the surface.
7889ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         */
789a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin        @Override
79054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public Canvas lockCanvas() {
79154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return internalLockCanvas(null);
79254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
79354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
7949ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian        /**
7959ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         * Gets a {@link Canvas} for drawing into the SurfaceView's Surface
7969ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         *
7979ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         * After drawing into the provided {@link Canvas}, the caller must
7989ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface.
7999ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         *
8009ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         * @param inOutDirty A rectangle that represents the dirty region that the caller wants
8019ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         * to redraw.  This function may choose to expand the dirty rectangle if for example
8029ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         * the surface has been resized or if the previous contents of the surface were
8039ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         * not available.  The caller must redraw the entire dirty region as represented
8049ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         * by the contents of the inOutDirty rectangle upon return from this function.
8059ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         * The caller may also pass <code>null</code> instead, in the case where the
8069ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         * entire surface should be redrawn.
8079ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         * @return A canvas for drawing into the surface.
8089ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         */
809a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin        @Override
8109ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian        public Canvas lockCanvas(Rect inOutDirty) {
8119ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian            return internalLockCanvas(inOutDirty);
81254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
81354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
81454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        private final Canvas internalLockCanvas(Rect dirty) {
81554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mSurfaceLock.lock();
81654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
8176d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn            if (DEBUG) Log.i(TAG, "Locking canvas... stopped="
81854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    + mDrawingStopped + ", win=" + mWindow);
81954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
82054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            Canvas c = null;
82154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (!mDrawingStopped && mWindow != null) {
82254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                try {
82330bc34f191ca8a009af313fc751e5b4bff6e39a1Jeff Brown                    c = mSurface.lockCanvas(dirty);
82454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                } catch (Exception e) {
82554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    Log.e(LOG_TAG, "Exception locking surface", e);
82654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
82754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
82854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
8296d05fd3c795088ac60f86382df5a66d631e8a0cbDianne Hackborn            if (DEBUG) Log.i(TAG, "Returned canvas: " + c);
83054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (c != null) {
83154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mLastLockTime = SystemClock.uptimeMillis();
83254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                return c;
83354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
834a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
83554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // If the Surface is not ready to be drawn, then return null,
83654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // but throttle calls to this function so it isn't called more
83754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // than every 100ms.
83854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            long now = SystemClock.uptimeMillis();
83954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            long nextTime = mLastLockTime + 100;
84054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (nextTime > now) {
84154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                try {
84254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    Thread.sleep(nextTime-now);
84354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                } catch (InterruptedException e) {
84454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
84554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                now = SystemClock.uptimeMillis();
84654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
84754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mLastLockTime = now;
84854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mSurfaceLock.unlock();
849a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin
85054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return null;
85154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
85254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
8539ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian        /**
8549ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         * Posts the new contents of the {@link Canvas} to the surface and
8559ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         * releases the {@link Canvas}.
8569ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         *
8579ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         * @param canvas The canvas previously obtained from {@link #lockCanvas}.
8589ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian         */
859a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin        @Override
86054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void unlockCanvasAndPost(Canvas canvas) {
86154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mSurface.unlockCanvasAndPost(canvas);
86254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mSurfaceLock.unlock();
86354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
86454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
865a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin        @Override
86654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public Surface getSurface() {
86754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return mSurface;
86854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
86954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
870a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin        @Override
87154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public Rect getSurfaceFrame() {
87254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return mSurfaceFrame;
87354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
87454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    };
87554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
876