SurfaceView.java revision 841f13c8e9ff3f7695b6c18a8abcec3c947983ff
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.view;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
2064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshimaimport android.content.res.CompatibilityInfo.Translator;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Canvas;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PixelFormat;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PorterDuff;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Region;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ParcelFileDescriptor;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Config;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.locks.ReentrantLock;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.ref.WeakReference;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Provides a dedicated drawing surface embedded inside of a view hierarchy.
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You can control the format of this surface and, if you like, its size; the
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SurfaceView takes care of placing the surface at the correct location on the
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * screen
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The surface is Z ordered so that it is behind the window holding its
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SurfaceView; the SurfaceView punches a hole in its window to allow its
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * surface to be displayed.  The view hierarchy will take care of correctly
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * compositing with the Surface any siblings of the SurfaceView that would
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * normally appear on top of it.  This can be used to place overlays such as
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * buttons on top of the Surface, though note however that it can have an
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * impact on performance since a full alpha-blended composite will be performed
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * each time the Surface changes.
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Access to the underlying surface is provided via the SurfaceHolder interface,
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * which can be retrieved by calling {@link #getHolder}.
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The Surface will be created for you while the SurfaceView's window is
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * visible; you should implement {@link SurfaceHolder.Callback#surfaceCreated}
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and {@link SurfaceHolder.Callback#surfaceDestroyed} to discover when the
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Surface is created and destroyed as the window is shown and hidden.
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>One of the purposes of this class is to provide a surface in which a
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * secondary thread can render in to the screen.  If you are going to use it
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this way, you need to be aware of some threading semantics:
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul>
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> All SurfaceView and
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link SurfaceHolder.Callback SurfaceHolder.Callback} methods will be called
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * from the thread running the SurfaceView's window (typically the main thread
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the application).  They thus need to correctly synchronize with any
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * state that is also touched by the drawing thread.
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> You must ensure that the drawing thread only touches the underlying
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Surface while it is valid -- between
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link SurfaceHolder.Callback#surfaceCreated SurfaceHolder.Callback.surfaceCreated()}
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link SurfaceHolder.Callback#surfaceDestroyed SurfaceHolder.Callback.surfaceDestroyed()}.
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul>
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class SurfaceView extends View {
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static private final String TAG = "SurfaceView";
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static private final boolean DEBUG = false;
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static private final boolean localLOGV = DEBUG ? true : Config.LOGV;
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final ArrayList<SurfaceHolder.Callback> mCallbacks
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            = new ArrayList<SurfaceHolder.Callback>();
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final int[] mLocation = new int[2];
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final ReentrantLock mSurfaceLock = new ReentrantLock();
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final Surface mSurface = new Surface();
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mDrawingStopped = true;
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final WindowManager.LayoutParams mLayout
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            = new WindowManager.LayoutParams();
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IWindowSession mSession;
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    MyWindow mWindow;
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final Rect mVisibleInsets = new Rect();
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final Rect mWinFrame = new Rect();
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final Rect mContentInsets = new Rect();
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int KEEP_SCREEN_ON_MSG = 1;
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int GET_NEW_SURFACE_MSG = 2;
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
104c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn    int mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
105c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mIsCreating = false;
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final Handler mHandler = new Handler() {
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void handleMessage(Message msg) {
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (msg.what) {
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case KEEP_SCREEN_ON_MSG: {
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    setKeepScreenOn(msg.arg1 != 0);
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } break;
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case GET_NEW_SURFACE_MSG: {
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    handleGetNewSurface();
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } break;
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mRequestedVisible = false;
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mRequestedWidth = -1;
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mRequestedHeight = -1;
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mRequestedFormat = PixelFormat.OPAQUE;
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mRequestedType = -1;
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mHaveFrame = false;
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mDestroyReportNeeded = false;
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mNewSurfaceNeeded = false;
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long mLastLockTime = 0;
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mVisible = false;
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mLeft = -1;
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mTop = -1;
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mWidth = -1;
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mHeight = -1;
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mFormat = -1;
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mType = -1;
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final Rect mSurfaceFrame = new Rect();
14164f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima    private Translator mTranslator;
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public SurfaceView(Context context) {
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super(context);
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setWillNotDraw(true);
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public SurfaceView(Context context, AttributeSet attrs) {
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super(context, attrs);
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setWillNotDraw(true);
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public SurfaceView(Context context, AttributeSet attrs, int defStyle) {
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super(context, attrs, defStyle);
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setWillNotDraw(true);
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the SurfaceHolder providing access and control over this
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * SurfaceView's underlying surface.
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return SurfaceHolder The holder of the surface.
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public SurfaceHolder getHolder() {
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mSurfaceHolder;
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onAttachedToWindow() {
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onAttachedToWindow();
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mParent.requestTransparentRegion(this);
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mSession = getWindowSession();
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLayout.token = getWindowToken();
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLayout.setTitle("SurfaceView");
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onWindowVisibilityChanged(int visibility) {
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onWindowVisibilityChanged(visibility);
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mRequestedVisible = visibility == VISIBLE;
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        updateWindow(false);
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onDetachedFromWindow() {
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mRequestedVisible = false;
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        updateWindow(false);
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHaveFrame = false;
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mWindow != null) {
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mSession.remove(mWindow);
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (RemoteException ex) {
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mWindow = null;
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mSession = null;
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLayout.token = null;
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onDetachedFromWindow();
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int width = getDefaultSize(mRequestedWidth, widthMeasureSpec);
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int height = getDefaultSize(mRequestedHeight, heightMeasureSpec);
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setMeasuredDimension(width, height);
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onScrollChanged(l, t, oldl, oldt);
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        updateWindow(false);
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onSizeChanged(w, h, oldw, oldh);
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        updateWindow(false);
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean gatherTransparentRegion(Region region) {
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean opaque = true;
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((mPrivateFlags & SKIP_DRAW) == 0) {
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // this view draws, remove it from the transparent region
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            opaque = super.gatherTransparentRegion(region);
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (region != null) {
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int w = getWidth();
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int h = getHeight();
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (w>0 && h>0) {
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                getLocationInWindow(mLocation);
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // otherwise, punch a hole in the whole hierarchy
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int l = mLocation[0];
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int t = mLocation[1];
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                region.op(l, t, l+w, t+h, Region.Op.UNION);
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (PixelFormat.formatHasAlpha(mRequestedFormat)) {
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            opaque = false;
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return opaque;
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void draw(Canvas canvas) {
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // draw() is not called when SKIP_DRAW is set
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((mPrivateFlags & SKIP_DRAW) == 0) {
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // punch a whole in the view-hierarchy below us
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            canvas.drawColor(0, PorterDuff.Mode.CLEAR);
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.draw(canvas);
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
255001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima    public boolean dispatchTouchEvent(MotionEvent event) {
256001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima        // SurfaceView uses pre-scaled size unless fixed size is requested. This hook
257001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima        // scales the event back to the pre-scaled coordinates for such surface.
25834bf2ee9e695c620e0a4b9a790f1f6ccb8a77234Mitsuru Oshima        if (mScaled) {
259001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima            MotionEvent scaledBack = MotionEvent.obtain(event);
260841f13c8e9ff3f7695b6c18a8abcec3c947983ffMitsuru Oshima            mTranslator.translateEventInScreenToAppWindow(event);
261001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima            try {
262001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima                return super.dispatchTouchEvent(scaledBack);
263001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima            } finally {
264001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima                scaledBack.recycle();
265001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima            }
266001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima        } else {
267001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima            return super.dispatchTouchEvent(event);
268001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima        }
269001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima    }
270001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima
271001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima    @Override
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void dispatchDraw(Canvas canvas) {
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // if SKIP_DRAW is cleared, draw() has already punched a hole
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // punch a whole in the view-hierarchy below us
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            canvas.drawColor(0, PorterDuff.Mode.CLEAR);
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // reposition ourselves where the surface is
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHaveFrame = true;
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        updateWindow(false);
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.dispatchDraw(canvas);
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
284c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn    /**
285c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn     * Hack to allow special layering of windows.  The type is one of the
286c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn     * types in WindowManager.LayoutParams.  This is a hack so:
287c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn     * @hide
288c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn     */
289c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn    public void setWindowType(int type) {
290c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn        mWindowType = type;
291c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn    }
29234bf2ee9e695c620e0a4b9a790f1f6ccb8a77234Mitsuru Oshima
29334bf2ee9e695c620e0a4b9a790f1f6ccb8a77234Mitsuru Oshima    boolean mScaled = false;
294c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void updateWindow(boolean force) {
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mHaveFrame) {
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
299841f13c8e9ff3f7695b6c18a8abcec3c947983ffMitsuru Oshima        ViewRoot viewRoot = (ViewRoot) getRootView().getParent();
300841f13c8e9ff3f7695b6c18a8abcec3c947983ffMitsuru Oshima        mTranslator = viewRoot.mTranslator;
30164f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima
30264f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima        float appScale = mTranslator == null ? 1.0f : mTranslator.applicationScale;
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int myWidth = mRequestedWidth;
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (myWidth <= 0) myWidth = getWidth();
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int myHeight = mRequestedHeight;
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (myHeight <= 0) myHeight = getHeight();
308001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima
30964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima        // Use original size if the app specified the size of the view,
31064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima        // and let the flinger to scale up.
3111ecf5d28817f0a051e77488380dcd5bc622ea169Mitsuru Oshima        if (mRequestedWidth <= 0 && mTranslator != null) {
3129189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima            myWidth *= appScale;
3139189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima            myHeight *= appScale;
31434bf2ee9e695c620e0a4b9a790f1f6ccb8a77234Mitsuru Oshima            mScaled = true;
31534bf2ee9e695c620e0a4b9a790f1f6ccb8a77234Mitsuru Oshima        } else {
31634bf2ee9e695c620e0a4b9a790f1f6ccb8a77234Mitsuru Oshima            mScaled = false;
317001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima        }
318001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        getLocationInWindow(mLocation);
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final boolean creating = mWindow == null;
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final boolean formatChanged = mFormat != mRequestedFormat;
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final boolean sizeChanged = mWidth != myWidth || mHeight != myHeight;
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final boolean visibleChanged = mVisible != mRequestedVisible
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                || mNewSurfaceNeeded;
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final boolean typeChanged = mType != mRequestedType;
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (force || creating || formatChanged || sizeChanged || visibleChanged
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            || typeChanged || mLeft != mLocation[0] || mTop != mLocation[1]) {
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (localLOGV) Log.i(TAG, "Changes: creating=" + creating
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " format=" + formatChanged + " size=" + sizeChanged
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " visible=" + visibleChanged
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " left=" + (mLeft != mLocation[0])
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " top=" + (mTop != mLocation[1]));
33464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final boolean visible = mVisible = mRequestedVisible;
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mLeft = mLocation[0];
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mTop = mLocation[1];
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mWidth = myWidth;
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mHeight = myHeight;
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mFormat = mRequestedFormat;
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mType = mRequestedType;
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                // Scaling/Translate window's layout here because mLayout is not used elsewhere.
34564f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima
34664f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                // Places the window relative
34764f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                mLayout.x = mLeft;
34864f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                mLayout.y = mTop;
34964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                mLayout.width = getWidth();
35064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                mLayout.height = getHeight();
35164f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                if (mTranslator != null) {
35264f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                    mTranslator.translateLayoutParamsInAppWindowToScreen(mLayout);
35364f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                }
35464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mLayout.format = mRequestedFormat;
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mLayout.flags |=WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                              | WindowManager.LayoutParams.FLAG_SCALED
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                              | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                              | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                              ;
361841f13c8e9ff3f7695b6c18a8abcec3c947983ffMitsuru Oshima                if (!getContext().getResources().getCompatibilityInfo().supportsScreen()) {
362841f13c8e9ff3f7695b6c18a8abcec3c947983ffMitsuru Oshima                    mLayout.flags |= WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
363841f13c8e9ff3f7695b6c18a8abcec3c947983ffMitsuru Oshima                }
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mLayout.memoryType = mRequestedType;
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mWindow == null) {
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mWindow = new MyWindow(this);
369c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn                    mLayout.type = mWindowType;
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mLayout.gravity = Gravity.LEFT|Gravity.TOP;
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mSession.add(mWindow, mLayout,
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            mVisible ? VISIBLE : GONE, mContentInsets);
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (visibleChanged && (!visible || mNewSurfaceNeeded)) {
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    reportSurfaceDestroyed();
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mNewSurfaceNeeded = false;
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mSurfaceLock.lock();
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mDrawingStopped = !visible;
3839189cabb0b6c6c28232fe6f412b7ba7a37352a6aMitsuru Oshima
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final int relayoutResult = mSession.relayout(
385001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima                    mWindow, mLayout, mWidth, mHeight,
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        visible ? VISIBLE : GONE, false, mWinFrame, mContentInsets,
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mVisibleInsets, mSurface);
3888169daed2f7a8731d478b884b1f455c747b88478Mitsuru Oshima
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (localLOGV) Log.i(TAG, "New surface: " + mSurface
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + ", vis=" + visible + ", frame=" + mWinFrame);
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mSurfaceFrame.left = 0;
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mSurfaceFrame.top = 0;
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mSurfaceFrame.right = mWinFrame.width();
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mSurfaceFrame.bottom = mWinFrame.height();
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mSurfaceLock.unlock();
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (visible) {
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mDestroyReportNeeded = true;
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        SurfaceHolder.Callback callbacks[];
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        synchronized (mCallbacks) {
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            callbacks = new SurfaceHolder.Callback[mCallbacks.size()];
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            mCallbacks.toArray(callbacks);
4053d91492d694cf00474fec792134e496be6ee0313Mitsuru Oshima                        }
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (visibleChanged) {
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            mIsCreating = true;
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            for (SurfaceHolder.Callback c : callbacks) {
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                c.surfaceCreated(mSurfaceHolder);
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (creating || formatChanged || sizeChanged
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                || visibleChanged) {
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            for (SurfaceHolder.Callback c : callbacks) {
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                c.surfaceChanged(mSurfaceHolder, mFormat, mWidth, mHeight);
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } finally {
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mIsCreating = false;
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (creating || (relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) {
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mSession.finishDrawing(mWindow);
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (RemoteException ex) {
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (localLOGV) Log.v(
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y +
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                " w=" + mLayout.width + " h=" + mLayout.height +
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ", frame=" + mSurfaceFrame);
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void reportSurfaceDestroyed() {
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDestroyReportNeeded) {
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDestroyReportNeeded = false;
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SurfaceHolder.Callback callbacks[];
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (mCallbacks) {
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                callbacks = new SurfaceHolder.Callback[mCallbacks.size()];
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mCallbacks.toArray(callbacks);
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (SurfaceHolder.Callback c : callbacks) {
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                c.surfaceDestroyed(mSurfaceHolder);
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onDetachedFromWindow();
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void handleGetNewSurface() {
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mNewSurfaceNeeded = true;
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        updateWindow(false);
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static class MyWindow extends IWindow.Stub {
4568169daed2f7a8731d478b884b1f455c747b88478Mitsuru Oshima        private final WeakReference<SurfaceView> mSurfaceView;
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public MyWindow(SurfaceView surfaceView) {
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mSurfaceView = new WeakReference<SurfaceView>(surfaceView);
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void resized(int w, int h, Rect coveredInsets,
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Rect visibleInsets, boolean reportDraw) {
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SurfaceView surfaceView = mSurfaceView.get();
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (surfaceView != null) {
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (localLOGV) Log.v(
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "SurfaceView", surfaceView + " got resized: w=" +
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                w + " h=" + h + ", cur w=" + mCurWidth + " h=" + mCurHeight);
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                synchronized (this) {
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (mCurWidth != w || mCurHeight != h) {
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mCurWidth = w;
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mCurHeight = h;
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (reportDraw) {
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        try {
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            surfaceView.mSession.finishDrawing(surfaceView.mWindow);
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } catch (RemoteException e) {
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void dispatchKey(KeyEvent event) {
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SurfaceView surfaceView = mSurfaceView.get();
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (surfaceView != null) {
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                //Log.w("SurfaceView", "Unexpected key event in surface: " + event);
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (surfaceView.mSession != null && surfaceView.mSurface != null) {
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    try {
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        surfaceView.mSession.finishKey(surfaceView.mWindow);
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } catch (RemoteException ex) {
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void dispatchPointer(MotionEvent event, long eventTime) {
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.w("SurfaceView", "Unexpected pointer event in surface: " + event);
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //if (mSession != null && mSurface != null) {
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //    try {
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //        //mSession.finishKey(mWindow);
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //    } catch (RemoteException ex) {
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //    }
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //}
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void dispatchTrackball(MotionEvent event, long eventTime) {
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.w("SurfaceView", "Unexpected trackball event in surface: " + event);
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //if (mSession != null && mSurface != null) {
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //    try {
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //        //mSession.finishKey(mWindow);
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //    } catch (RemoteException ex) {
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //    }
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //}
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void dispatchAppVisibility(boolean visible) {
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // The point of SurfaceView is to let the app control the surface.
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void dispatchGetNewSurface() {
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            SurfaceView surfaceView = mSurfaceView.get();
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (surfaceView != null) {
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Message msg = surfaceView.mHandler.obtainMessage(GET_NEW_SURFACE_MSG);
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                surfaceView.mHandler.sendMessage(msg);
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void windowFocusChanged(boolean hasFocus, boolean touchEnabled) {
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.w("SurfaceView", "Unexpected focus in surface: focus=" + hasFocus + ", touchEnabled=" + touchEnabled);
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int mCurWidth = -1;
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int mCurHeight = -1;
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private static final String LOG_TAG = "SurfaceHolder";
54334bf2ee9e695c620e0a4b9a790f1f6ccb8a77234Mitsuru Oshima        private int mSaveCount;
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean isCreating() {
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mIsCreating;
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void addCallback(Callback callback) {
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (mCallbacks) {
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // This is a linear search, but in practice we'll
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // have only a couple callbacks, so it doesn't matter.
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mCallbacks.contains(callback) == false) {
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mCallbacks.add(callback);
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void removeCallback(Callback callback) {
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (mCallbacks) {
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mCallbacks.remove(callback);
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setFixedSize(int width, int height) {
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mRequestedWidth != width || mRequestedHeight != height) {
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mRequestedWidth = width;
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mRequestedHeight = height;
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                requestLayout();
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setSizeFromLayout() {
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mRequestedWidth != -1 || mRequestedHeight != -1) {
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mRequestedWidth = mRequestedHeight = -1;
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                requestLayout();
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setFormat(int format) {
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mRequestedFormat = format;
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mWindow != null) {
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                updateWindow(false);
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setType(int type) {
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (type) {
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case SURFACE_TYPE_NORMAL:
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case SURFACE_TYPE_HARDWARE:
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case SURFACE_TYPE_GPU:
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case SURFACE_TYPE_PUSH_BUFFERS:
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mRequestedType = type;
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mWindow != null) {
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    updateWindow(false);
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void setKeepScreenOn(boolean screenOn) {
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Message msg = mHandler.obtainMessage(KEEP_SCREEN_ON_MSG);
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            msg.arg1 = screenOn ? 1 : 0;
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mHandler.sendMessage(msg);
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Canvas lockCanvas() {
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return internalLockCanvas(null);
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Canvas lockCanvas(Rect dirty) {
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return internalLockCanvas(dirty);
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private final Canvas internalLockCanvas(Rect dirty) {
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mType == SURFACE_TYPE_PUSH_BUFFERS) {
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new BadSurfaceTypeException(
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "Surface type is SURFACE_TYPE_PUSH_BUFFERS");
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mSurfaceLock.lock();
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (localLOGV) Log.i(TAG, "Locking canvas... stopped="
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + mDrawingStopped + ", win=" + mWindow);
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Canvas c = null;
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mDrawingStopped && mWindow != null) {
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Rect frame = dirty != null ? dirty : mSurfaceFrame;
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    c = mSurface.lockCanvas(frame);
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (Exception e) {
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Log.e(LOG_TAG, "Exception locking surface", e);
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (localLOGV) Log.i(TAG, "Returned canvas: " + c);
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (c != null) {
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mLastLockTime = SystemClock.uptimeMillis();
63834bf2ee9e695c620e0a4b9a790f1f6ccb8a77234Mitsuru Oshima                if (mScaled) {
63934bf2ee9e695c620e0a4b9a790f1f6ccb8a77234Mitsuru Oshima                    mSaveCount = c.save();
64034bf2ee9e695c620e0a4b9a790f1f6ccb8a77234Mitsuru Oshima                    mTranslator.translateCanvas(c);
64134bf2ee9e695c620e0a4b9a790f1f6ccb8a77234Mitsuru Oshima                }
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return c;
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If the Surface is not ready to be drawn, then return null,
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // but throttle calls to this function so it isn't called more
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // than every 100ms.
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            long now = SystemClock.uptimeMillis();
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            long nextTime = mLastLockTime + 100;
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (nextTime > now) {
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Thread.sleep(nextTime-now);
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (InterruptedException e) {
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                now = SystemClock.uptimeMillis();
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mLastLockTime = now;
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mSurfaceLock.unlock();
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void unlockCanvasAndPost(Canvas canvas) {
66434bf2ee9e695c620e0a4b9a790f1f6ccb8a77234Mitsuru Oshima            if (mScaled) {
66534bf2ee9e695c620e0a4b9a790f1f6ccb8a77234Mitsuru Oshima                canvas.restoreToCount(mSaveCount);
66634bf2ee9e695c620e0a4b9a790f1f6ccb8a77234Mitsuru Oshima            }
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mSurface.unlockCanvasAndPost(canvas);
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mSurfaceLock.unlock();
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Surface getSurface() {
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mSurface;
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Rect getSurfaceFrame() {
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mSurfaceFrame;
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
680