SurfaceView.java revision e36d6e277e49475076b7872d36ea6a5c5b996e9d
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;
2338ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshimaimport android.content.res.Resources;
2464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshimaimport android.content.res.CompatibilityInfo.Translator;
2554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.Canvas;
2654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.PixelFormat;
2754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.PorterDuff;
2854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.Rect;
2954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.Region;
3054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.os.Handler;
3154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.os.Message;
3254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.os.RemoteException;
3354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.os.SystemClock;
3454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.os.ParcelFileDescriptor;
3554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.util.AttributeSet;
3654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.util.Config;
3754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.util.Log;
3854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
399bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimerimport java.lang.ref.WeakReference;
409bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimerimport java.util.ArrayList;
4154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport java.util.concurrent.locks.ReentrantLock;
42b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Projectimport java.lang.ref.WeakReference;
4354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
4454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project/**
4554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Provides a dedicated drawing surface embedded inside of a view hierarchy.
4654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * You can control the format of this surface and, if you like, its size; the
4754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * SurfaceView takes care of placing the surface at the correct location on the
4854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * screen
4954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project *
5054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p>The surface is Z ordered so that it is behind the window holding its
5154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * SurfaceView; the SurfaceView punches a hole in its window to allow its
5254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * surface to be displayed.  The view hierarchy will take care of correctly
5354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * compositing with the Surface any siblings of the SurfaceView that would
5454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * normally appear on top of it.  This can be used to place overlays such as
5554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * buttons on top of the Surface, though note however that it can have an
5654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * impact on performance since a full alpha-blended composite will be performed
5754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * each time the Surface changes.
5854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project *
5954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p>Access to the underlying surface is provided via the SurfaceHolder interface,
6054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * which can be retrieved by calling {@link #getHolder}.
6154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project *
6254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p>The Surface will be created for you while the SurfaceView's window is
6354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * visible; you should implement {@link SurfaceHolder.Callback#surfaceCreated}
6454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * and {@link SurfaceHolder.Callback#surfaceDestroyed} to discover when the
6554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Surface is created and destroyed as the window is shown and hidden.
6654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project *
6754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p>One of the purposes of this class is to provide a surface in which a
6854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * secondary thread can render in to the screen.  If you are going to use it
6954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * this way, you need to be aware of some threading semantics:
7054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project *
7154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <ul>
7254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <li> All SurfaceView and
7354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * {@link SurfaceHolder.Callback SurfaceHolder.Callback} methods will be called
7454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * from the thread running the SurfaceView's window (typically the main thread
7554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * of the application).  They thus need to correctly synchronize with any
7654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * state that is also touched by the drawing thread.
7754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <li> You must ensure that the drawing thread only touches the underlying
7854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Surface while it is valid -- between
7954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * {@link SurfaceHolder.Callback#surfaceCreated SurfaceHolder.Callback.surfaceCreated()}
8054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * and
8154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * {@link SurfaceHolder.Callback#surfaceDestroyed SurfaceHolder.Callback.surfaceDestroyed()}.
8254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * </ul>
8354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */
8454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectpublic class SurfaceView extends View {
8554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    static private final String TAG = "SurfaceView";
8654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    static private final boolean DEBUG = false;
8754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    static private final boolean localLOGV = DEBUG ? true : Config.LOGV;
8854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
8954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    final ArrayList<SurfaceHolder.Callback> mCallbacks
9054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            = new ArrayList<SurfaceHolder.Callback>();
9154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
92f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    final int[] mLocation = new int[2];
93f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project
9454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    final ReentrantLock mSurfaceLock = new ReentrantLock();
9554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    final Surface mSurface = new Surface();
9654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    boolean mDrawingStopped = true;
9754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
9854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    final WindowManager.LayoutParams mLayout
9954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            = new WindowManager.LayoutParams();
10054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    IWindowSession mSession;
10154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    MyWindow mWindow;
102f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    final Rect mVisibleInsets = new Rect();
10354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    final Rect mWinFrame = new Rect();
104f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    final Rect mContentInsets = new Rect();
10554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
10654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    static final int KEEP_SCREEN_ON_MSG = 1;
10754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    static final int GET_NEW_SURFACE_MSG = 2;
10854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
109c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn    int mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
110c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn
11154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    boolean mIsCreating = false;
11254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
11354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    final Handler mHandler = new Handler() {
11454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        @Override
11554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void handleMessage(Message msg) {
11654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            switch (msg.what) {
11754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                case KEEP_SCREEN_ON_MSG: {
11854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    setKeepScreenOn(msg.arg1 != 0);
11954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                } break;
12054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                case GET_NEW_SURFACE_MSG: {
12154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    handleGetNewSurface();
12254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                } break;
12354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
12454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
12554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    };
12654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
12754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    boolean mRequestedVisible = false;
1286b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian    boolean mWindowVisibility = false;
1296b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian    boolean mViewVisibility = false;
13054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mRequestedWidth = -1;
13154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mRequestedHeight = -1;
13254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mRequestedFormat = PixelFormat.OPAQUE;
13354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mRequestedType = -1;
13454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
13554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    boolean mHaveFrame = false;
13654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    boolean mDestroyReportNeeded = false;
13754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    boolean mNewSurfaceNeeded = false;
13854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    long mLastLockTime = 0;
13954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
14054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    boolean mVisible = false;
14154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mLeft = -1;
14254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mTop = -1;
14354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mWidth = -1;
14454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mHeight = -1;
14554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mFormat = -1;
14654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mType = -1;
14754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    final Rect mSurfaceFrame = new Rect();
14864f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima    private Translator mTranslator;
149424f668545c8b1423f46ed1286146393a8e4bc1aMitsuru Oshima
15054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public SurfaceView(Context context) {
15154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super(context);
15254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        setWillNotDraw(true);
15354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
15454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
15554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public SurfaceView(Context context, AttributeSet attrs) {
15654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super(context, attrs);
15754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        setWillNotDraw(true);
15854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
15954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
16054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public SurfaceView(Context context, AttributeSet attrs, int defStyle) {
16154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super(context, attrs, defStyle);
16254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        setWillNotDraw(true);
16354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
16454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
16554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    /**
16654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     * Return the SurfaceHolder providing access and control over this
16754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     * SurfaceView's underlying surface.
16854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     *
16954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     * @return SurfaceHolder The holder of the surface.
17054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     */
17154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public SurfaceHolder getHolder() {
17254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return mSurfaceHolder;
17354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
17454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
17554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
17654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    protected void onAttachedToWindow() {
17754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super.onAttachedToWindow();
17854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mParent.requestTransparentRegion(this);
17954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mSession = getWindowSession();
18054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mLayout.token = getWindowToken();
18154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mLayout.setTitle("SurfaceView");
1826b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian        mViewVisibility = getVisibility() == VISIBLE;
18354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
18454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
18554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
18654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    protected void onWindowVisibilityChanged(int visibility) {
18754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super.onWindowVisibilityChanged(visibility);
1886b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian        mWindowVisibility = visibility == VISIBLE;
1896b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian        mRequestedVisible = mWindowVisibility && mViewVisibility;
1906b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian        updateWindow(false);
1916b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian    }
1926b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian
1936b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian    @Override
1946b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian    public void setVisibility(int visibility) {
1956b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian        super.setVisibility(visibility);
1966b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian        mViewVisibility = visibility == VISIBLE;
1976b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian        mRequestedVisible = mWindowVisibility && mViewVisibility;
19854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        updateWindow(false);
19954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
20054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
20154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
20254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    protected void onDetachedFromWindow() {
20354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mRequestedVisible = false;
20454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        updateWindow(false);
20554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mHaveFrame = false;
20654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (mWindow != null) {
20754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            try {
20854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mSession.remove(mWindow);
20954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            } catch (RemoteException ex) {
21054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
21154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mWindow = null;
21254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
21354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mSession = null;
21454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mLayout.token = null;
21554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
21654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super.onDetachedFromWindow();
21754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
21854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
21954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
22054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
22154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int width = getDefaultSize(mRequestedWidth, widthMeasureSpec);
22254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int height = getDefaultSize(mRequestedHeight, heightMeasureSpec);
22354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        setMeasuredDimension(width, height);
22454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
22554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
22654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
22754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
22854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super.onScrollChanged(l, t, oldl, oldt);
22954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        updateWindow(false);
23054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
23154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
23254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
23354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
23454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super.onSizeChanged(w, h, oldw, oldh);
23554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        updateWindow(false);
23654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
23754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
23854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
23954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public boolean gatherTransparentRegion(Region region) {
2401cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn        if (mWindowType == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
2411cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn            return super.gatherTransparentRegion(region);
2421cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn        }
2431cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn
24454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        boolean opaque = true;
24554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if ((mPrivateFlags & SKIP_DRAW) == 0) {
24654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // this view draws, remove it from the transparent region
24754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            opaque = super.gatherTransparentRegion(region);
24854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        } else if (region != null) {
24954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            int w = getWidth();
25054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            int h = getHeight();
25154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (w>0 && h>0) {
25254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                getLocationInWindow(mLocation);
25354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                // otherwise, punch a hole in the whole hierarchy
25454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                int l = mLocation[0];
25554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                int t = mLocation[1];
25654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                region.op(l, t, l+w, t+h, Region.Op.UNION);
25754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
25854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
25954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (PixelFormat.formatHasAlpha(mRequestedFormat)) {
26054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            opaque = false;
26154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
26254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return opaque;
26354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
26454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
26554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
26654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public void draw(Canvas canvas) {
2671cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn        if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
2681cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn            // draw() is not called when SKIP_DRAW is set
2691cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn            if ((mPrivateFlags & SKIP_DRAW) == 0) {
2701cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn                // punch a whole in the view-hierarchy below us
2711cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn                canvas.drawColor(0, PorterDuff.Mode.CLEAR);
2721cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn            }
27354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
27454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super.draw(canvas);
27554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
27654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
27754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
27854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    protected void dispatchDraw(Canvas canvas) {
2791cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn        if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
2801cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn            // if SKIP_DRAW is cleared, draw() has already punched a hole
2811cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn            if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
2821cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn                // punch a whole in the view-hierarchy below us
2831cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn                canvas.drawColor(0, PorterDuff.Mode.CLEAR);
2841cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn            }
28554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
28654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // reposition ourselves where the surface is
28754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mHaveFrame = true;
28854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        updateWindow(false);
28954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super.dispatchDraw(canvas);
29054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
29154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
292c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn    /**
29329e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * Control whether the surface view's surface is placed on top of another
29429e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * regular surface view in the window (but still behind the window itself).
29529e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * This is typically used to place overlays on top of an underlying media
29629e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * surface view.
29729e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     *
29829e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * <p>Note that this must be set before the surface view's containing
29929e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * window is attached to the window manager.
30029e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     *
30129e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * <p>Calling this overrides any previous call to {@link #setZOrderOnTop}.
30229e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     */
30329e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn    public void setZOrderMediaOverlay(boolean isMediaOverlay) {
30429e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn        mWindowType = isMediaOverlay
30529e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn                ? WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY
30629e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn                : WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
30729e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn    }
30829e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn
30929e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn    /**
3101cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * Control whether the surface view's surface is placed on top of its
3111cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * window.  Normally it is placed behind the window, to allow it to
3121cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * (for the most part) appear to composite with the views in the
3131cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * hierarchy.  By setting this, you cause it to be placed above the
3141cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * window.  This means that none of the contents of the window this
3151cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * SurfaceView is in will be visible on top of its surface.
3161cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     *
3171cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * <p>Note that this must be set before the surface view's containing
3181cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * window is attached to the window manager.
31929e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     *
32029e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * <p>Calling this overrides any previous call to {@link #setZOrderMediaOverlay}.
3211cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     */
32229e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn    public void setZOrderOnTop(boolean onTop) {
3231cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn        mWindowType = onTop ? WindowManager.LayoutParams.TYPE_APPLICATION_PANEL
3241cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn                : WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
3251cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn    }
3261cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn
3271cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn    /**
328c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn     * Hack to allow special layering of windows.  The type is one of the
329c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn     * types in WindowManager.LayoutParams.  This is a hack so:
330c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn     * @hide
331c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn     */
332c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn    public void setWindowType(int type) {
333c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn        mWindowType = type;
334c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn    }
33534bf2ee9e695c620e0a4b9a790f1f6ccb8a77234Mitsuru Oshima
33654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    private void updateWindow(boolean force) {
33754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (!mHaveFrame) {
33854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return;
33954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
340841f13c8e9ff3f7695b6c18a8abcec3c947983ffMitsuru Oshima        ViewRoot viewRoot = (ViewRoot) getRootView().getParent();
341168173a698e820ceb1ebf54b4910888891be2056Joe Onorato        if (viewRoot != null) {
342168173a698e820ceb1ebf54b4910888891be2056Joe Onorato            mTranslator = viewRoot.mTranslator;
343168173a698e820ceb1ebf54b4910888891be2056Joe Onorato        }
34464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima
34538ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima        Resources res = getContext().getResources();
34638ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima        if (mTranslator != null || !res.getCompatibilityInfo().supportsScreen()) {
347240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima            mSurface.setCompatibleDisplayMetrics(res.getDisplayMetrics(), mTranslator);
34838ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima        }
34938ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima
35054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int myWidth = mRequestedWidth;
35154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (myWidth <= 0) myWidth = getWidth();
35254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int myHeight = mRequestedHeight;
35354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (myHeight <= 0) myHeight = getHeight();
354001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima
35554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        getLocationInWindow(mLocation);
35654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        final boolean creating = mWindow == null;
35754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        final boolean formatChanged = mFormat != mRequestedFormat;
35854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        final boolean sizeChanged = mWidth != myWidth || mHeight != myHeight;
35954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        final boolean visibleChanged = mVisible != mRequestedVisible
36054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                || mNewSurfaceNeeded;
36154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        final boolean typeChanged = mType != mRequestedType;
36254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (force || creating || formatChanged || sizeChanged || visibleChanged
36354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            || typeChanged || mLeft != mLocation[0] || mTop != mLocation[1]) {
36454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
36554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (localLOGV) Log.i(TAG, "Changes: creating=" + creating
36654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    + " format=" + formatChanged + " size=" + sizeChanged
36754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    + " visible=" + visibleChanged
36854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    + " left=" + (mLeft != mLocation[0])
36954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    + " top=" + (mTop != mLocation[1]));
37064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima
37154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            try {
37254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                final boolean visible = mVisible = mRequestedVisible;
37354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mLeft = mLocation[0];
37454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mTop = mLocation[1];
37554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mWidth = myWidth;
37654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mHeight = myHeight;
37754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mFormat = mRequestedFormat;
37854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mType = mRequestedType;
37954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
38064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                // Scaling/Translate window's layout here because mLayout is not used elsewhere.
38164f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima
38264f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                // Places the window relative
38364f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                mLayout.x = mLeft;
38464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                mLayout.y = mTop;
38564f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                mLayout.width = getWidth();
38664f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                mLayout.height = getHeight();
38764f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                if (mTranslator != null) {
38864f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                    mTranslator.translateLayoutParamsInAppWindowToScreen(mLayout);
38964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                }
39064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima
39154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mLayout.format = mRequestedFormat;
3921cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn                mLayout.flags |=WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
3931cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn                              | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
3941cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn                              | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
39554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                              | WindowManager.LayoutParams.FLAG_SCALED
39654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                              | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
39754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                              | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
39854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                              ;
399841f13c8e9ff3f7695b6c18a8abcec3c947983ffMitsuru Oshima                if (!getContext().getResources().getCompatibilityInfo().supportsScreen()) {
400841f13c8e9ff3f7695b6c18a8abcec3c947983ffMitsuru Oshima                    mLayout.flags |= WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
401841f13c8e9ff3f7695b6c18a8abcec3c947983ffMitsuru Oshima                }
40254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
40354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mLayout.memoryType = mRequestedType;
40454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
40554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                if (mWindow == null) {
4069bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                    mWindow = new MyWindow(this);
407c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn                    mLayout.type = mWindowType;
40854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    mLayout.gravity = Gravity.LEFT|Gravity.TOP;
40954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    mSession.add(mWindow, mLayout,
410f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project                            mVisible ? VISIBLE : GONE, mContentInsets);
41154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
41254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
41354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                if (visibleChanged && (!visible || mNewSurfaceNeeded)) {
41454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    reportSurfaceDestroyed();
41554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
41654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
41754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mNewSurfaceNeeded = false;
41854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
41954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mSurfaceLock.lock();
42054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mDrawingStopped = !visible;
4219189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima
42254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                final int relayoutResult = mSession.relayout(
423001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima                    mWindow, mLayout, mWidth, mHeight,
424f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project                        visible ? VISIBLE : GONE, false, mWinFrame, mContentInsets,
425f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project                        mVisibleInsets, mSurface);
4268169daed2f7a8731d478b884b1f455c747b88478Mitsuru Oshima
42754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                if (localLOGV) Log.i(TAG, "New surface: " + mSurface
42854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        + ", vis=" + visible + ", frame=" + mWinFrame);
429589cebe2d58591403de4a77077941c0454bc91bcMitsuru Oshima
43054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mSurfaceFrame.left = 0;
43154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mSurfaceFrame.top = 0;
432589cebe2d58591403de4a77077941c0454bc91bcMitsuru Oshima                if (mTranslator == null) {
433589cebe2d58591403de4a77077941c0454bc91bcMitsuru Oshima                    mSurfaceFrame.right = mWinFrame.width();
434589cebe2d58591403de4a77077941c0454bc91bcMitsuru Oshima                    mSurfaceFrame.bottom = mWinFrame.height();
435589cebe2d58591403de4a77077941c0454bc91bcMitsuru Oshima                } else {
436589cebe2d58591403de4a77077941c0454bc91bcMitsuru Oshima                    float appInvertedScale = mTranslator.applicationInvertedScale;
437589cebe2d58591403de4a77077941c0454bc91bcMitsuru Oshima                    mSurfaceFrame.right = (int) (mWinFrame.width() * appInvertedScale + 0.5f);
438589cebe2d58591403de4a77077941c0454bc91bcMitsuru Oshima                    mSurfaceFrame.bottom = (int) (mWinFrame.height() * appInvertedScale + 0.5f);
439589cebe2d58591403de4a77077941c0454bc91bcMitsuru Oshima                }
44054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mSurfaceLock.unlock();
44154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
44254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                try {
44354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    if (visible) {
44454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        mDestroyReportNeeded = true;
44554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
44654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        SurfaceHolder.Callback callbacks[];
44754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        synchronized (mCallbacks) {
44854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            callbacks = new SurfaceHolder.Callback[mCallbacks.size()];
44954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            mCallbacks.toArray(callbacks);
4503d91492d694cf00474fec792134e496be6ee0313Mitsuru Oshima                        }
45154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
45254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        if (visibleChanged) {
45354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            mIsCreating = true;
45454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            for (SurfaceHolder.Callback c : callbacks) {
45554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                c.surfaceCreated(mSurfaceHolder);
45654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            }
45754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        }
45854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        if (creating || formatChanged || sizeChanged
45954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                || visibleChanged) {
46054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            for (SurfaceHolder.Callback c : callbacks) {
46154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                c.surfaceChanged(mSurfaceHolder, mFormat, mWidth, mHeight);
46254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            }
46354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        }
46454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    }
46554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                } finally {
46654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    mIsCreating = false;
46754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    if (creating || (relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) {
46854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        mSession.finishDrawing(mWindow);
46954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    }
47054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
47154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            } catch (RemoteException ex) {
47254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
47354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (localLOGV) Log.v(
47454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y +
47554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                " w=" + mLayout.width + " h=" + mLayout.height +
47654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                ", frame=" + mSurfaceFrame);
47754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
47854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
47954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
48054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    private void reportSurfaceDestroyed() {
48154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (mDestroyReportNeeded) {
48254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mDestroyReportNeeded = false;
48354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            SurfaceHolder.Callback callbacks[];
48454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            synchronized (mCallbacks) {
48554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                callbacks = new SurfaceHolder.Callback[mCallbacks.size()];
48654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mCallbacks.toArray(callbacks);
48754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
48854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            for (SurfaceHolder.Callback c : callbacks) {
48954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                c.surfaceDestroyed(mSurfaceHolder);
49054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
49154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
49254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super.onDetachedFromWindow();
49354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
49454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
49554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    void handleGetNewSurface() {
49654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mNewSurfaceNeeded = true;
49754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        updateWindow(false);
49854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
499b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project
50072c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn    private static class MyWindow extends BaseIWindow {
5018169daed2f7a8731d478b884b1f455c747b88478Mitsuru Oshima        private final WeakReference<SurfaceView> mSurfaceView;
5029bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer
5039bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer        public MyWindow(SurfaceView surfaceView) {
5049bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer            mSurfaceView = new WeakReference<SurfaceView>(surfaceView);
5059bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer        }
5069bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer
507f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project        public void resized(int w, int h, Rect coveredInsets,
508e36d6e277e49475076b7872d36ea6a5c5b996e9dDianne Hackborn                Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
5099bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer            SurfaceView surfaceView = mSurfaceView.get();
5109bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer            if (surfaceView != null) {
5119bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                if (localLOGV) Log.v(
5129bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                        "SurfaceView", surfaceView + " got resized: w=" +
513b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project                                w + " h=" + h + ", cur w=" + mCurWidth + " h=" + mCurHeight);
5149bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                synchronized (this) {
5159bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                    if (mCurWidth != w || mCurHeight != h) {
5169bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                        mCurWidth = w;
5179bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                        mCurHeight = h;
5189bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                    }
5199bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                    if (reportDraw) {
5209bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                        try {
521b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project                            surfaceView.mSession.finishDrawing(surfaceView.mWindow);
5229bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                        } catch (RemoteException e) {
5239bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                        }
52454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    }
52554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
52654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
52754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
52854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
52954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void dispatchKey(KeyEvent event) {
5309bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer            SurfaceView surfaceView = mSurfaceView.get();
5319bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer            if (surfaceView != null) {
532b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project                //Log.w("SurfaceView", "Unexpected key event in surface: " + event);
533b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project                if (surfaceView.mSession != null && surfaceView.mSurface != null) {
5349bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                    try {
5359bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                        surfaceView.mSession.finishKey(surfaceView.mWindow);
5369bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                    } catch (RemoteException ex) {
5379bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                    }
53854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
53954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
54054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
54154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
5428df8b2b405c60cacf7a66c4e2ca078dd3d7ec7bdDianne Hackborn        public void dispatchPointer(MotionEvent event, long eventTime,
5438df8b2b405c60cacf7a66c4e2ca078dd3d7ec7bdDianne Hackborn                boolean callWhenDone) {
54454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            Log.w("SurfaceView", "Unexpected pointer event in surface: " + event);
54554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //if (mSession != null && mSurface != null) {
54654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //    try {
54754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //        //mSession.finishKey(mWindow);
54854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //    } catch (RemoteException ex) {
54954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //    }
55054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //}
55154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
55254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
5538df8b2b405c60cacf7a66c4e2ca078dd3d7ec7bdDianne Hackborn        public void dispatchTrackball(MotionEvent event, long eventTime,
5548df8b2b405c60cacf7a66c4e2ca078dd3d7ec7bdDianne Hackborn                boolean callWhenDone) {
55554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            Log.w("SurfaceView", "Unexpected trackball event in surface: " + event);
55654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //if (mSession != null && mSurface != null) {
55754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //    try {
55854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //        //mSession.finishKey(mWindow);
55954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //    } catch (RemoteException ex) {
56054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //    }
56154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //}
56254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
56354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
56454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void dispatchAppVisibility(boolean visible) {
56554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // The point of SurfaceView is to let the app control the surface.
56654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
567b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project
56854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void dispatchGetNewSurface() {
5699bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer            SurfaceView surfaceView = mSurfaceView.get();
5709bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer            if (surfaceView != null) {
571b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project                Message msg = surfaceView.mHandler.obtainMessage(GET_NEW_SURFACE_MSG);
572b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project                surfaceView.mHandler.sendMessage(msg);
5739bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer            }
57454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
57554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
57654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void windowFocusChanged(boolean hasFocus, boolean touchEnabled) {
57754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            Log.w("SurfaceView", "Unexpected focus in surface: focus=" + hasFocus + ", touchEnabled=" + touchEnabled);
57854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
57954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
58054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
58154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
58254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
58354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int mCurWidth = -1;
58454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int mCurHeight = -1;
58554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
58654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
58754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
58854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
58954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        private static final String LOG_TAG = "SurfaceHolder";
59034bf2ee9e695c620e0a4b9a790f1f6ccb8a77234Mitsuru Oshima        private int mSaveCount;
59154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
59254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public boolean isCreating() {
59354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return mIsCreating;
59454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
59554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
59654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void addCallback(Callback callback) {
59754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            synchronized (mCallbacks) {
59854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                // This is a linear search, but in practice we'll
59954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                // have only a couple callbacks, so it doesn't matter.
60054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                if (mCallbacks.contains(callback) == false) {
60154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    mCallbacks.add(callback);
60254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
60354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
60454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
60554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
60654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void removeCallback(Callback callback) {
60754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            synchronized (mCallbacks) {
60854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mCallbacks.remove(callback);
60954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
61054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
61154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
61254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void setFixedSize(int width, int height) {
61354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (mRequestedWidth != width || mRequestedHeight != height) {
61454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mRequestedWidth = width;
61554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mRequestedHeight = height;
61654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                requestLayout();
61754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
61854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
61954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
62054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void setSizeFromLayout() {
62154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (mRequestedWidth != -1 || mRequestedHeight != -1) {
62254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mRequestedWidth = mRequestedHeight = -1;
62354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                requestLayout();
62454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
62554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
62654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
62754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void setFormat(int format) {
62854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mRequestedFormat = format;
62954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (mWindow != null) {
63054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                updateWindow(false);
63154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
63254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
63354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
63454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void setType(int type) {
63554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            switch (type) {
63654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            case SURFACE_TYPE_HARDWARE:
63754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            case SURFACE_TYPE_GPU:
638317a6280cc109e873646e4652be1582d870eedfdMathias Agopian                // these are deprecated, treat as "NORMAL"
639317a6280cc109e873646e4652be1582d870eedfdMathias Agopian                type = SURFACE_TYPE_NORMAL;
640317a6280cc109e873646e4652be1582d870eedfdMathias Agopian                break;
641317a6280cc109e873646e4652be1582d870eedfdMathias Agopian            }
642317a6280cc109e873646e4652be1582d870eedfdMathias Agopian            switch (type) {
643317a6280cc109e873646e4652be1582d870eedfdMathias Agopian            case SURFACE_TYPE_NORMAL:
64454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            case SURFACE_TYPE_PUSH_BUFFERS:
64554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mRequestedType = type;
64654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                if (mWindow != null) {
64754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    updateWindow(false);
64854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
64954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                break;
65054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
65154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
65254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
65354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void setKeepScreenOn(boolean screenOn) {
65454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            Message msg = mHandler.obtainMessage(KEEP_SCREEN_ON_MSG);
65554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            msg.arg1 = screenOn ? 1 : 0;
65654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mHandler.sendMessage(msg);
65754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
65854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
65954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public Canvas lockCanvas() {
66054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return internalLockCanvas(null);
66154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
66254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
66354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public Canvas lockCanvas(Rect dirty) {
66454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return internalLockCanvas(dirty);
66554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
66654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
66754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        private final Canvas internalLockCanvas(Rect dirty) {
66854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (mType == SURFACE_TYPE_PUSH_BUFFERS) {
66954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                throw new BadSurfaceTypeException(
67054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        "Surface type is SURFACE_TYPE_PUSH_BUFFERS");
67154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
67254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mSurfaceLock.lock();
67354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
67454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (localLOGV) Log.i(TAG, "Locking canvas... stopped="
67554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    + mDrawingStopped + ", win=" + mWindow);
67654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
67754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            Canvas c = null;
67854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (!mDrawingStopped && mWindow != null) {
67954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                Rect frame = dirty != null ? dirty : mSurfaceFrame;
68054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                try {
68154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    c = mSurface.lockCanvas(frame);
68254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                } catch (Exception e) {
68354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    Log.e(LOG_TAG, "Exception locking surface", e);
68454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
68554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
68654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
68754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (localLOGV) Log.i(TAG, "Returned canvas: " + c);
68854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (c != null) {
68954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mLastLockTime = SystemClock.uptimeMillis();
69054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                return c;
69154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
69254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
69354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // If the Surface is not ready to be drawn, then return null,
69454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // but throttle calls to this function so it isn't called more
69554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // than every 100ms.
69654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            long now = SystemClock.uptimeMillis();
69754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            long nextTime = mLastLockTime + 100;
69854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (nextTime > now) {
69954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                try {
70054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    Thread.sleep(nextTime-now);
70154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                } catch (InterruptedException e) {
70254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
70354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                now = SystemClock.uptimeMillis();
70454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
70554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mLastLockTime = now;
70654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mSurfaceLock.unlock();
70754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
70854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return null;
70954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
71054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
71154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void unlockCanvasAndPost(Canvas canvas) {
71254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mSurface.unlockCanvasAndPost(canvas);
71354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mSurfaceLock.unlock();
71454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
71554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
71654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public Surface getSurface() {
71754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return mSurface;
71854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
71954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
72054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public Rect getSurfaceFrame() {
72154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return mSurfaceFrame;
72254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
72354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    };
72454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
725