SurfaceView.java revision d6ddcb7f00a7af95b452233d965b922632f78f21
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;
4254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
4354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project/**
4454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Provides a dedicated drawing surface embedded inside of a view hierarchy.
4554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * You can control the format of this surface and, if you like, its size; the
4654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * SurfaceView takes care of placing the surface at the correct location on the
4754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * screen
4854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project *
4954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p>The surface is Z ordered so that it is behind the window holding its
5054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * SurfaceView; the SurfaceView punches a hole in its window to allow its
5154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * surface to be displayed.  The view hierarchy will take care of correctly
5254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * compositing with the Surface any siblings of the SurfaceView that would
5354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * normally appear on top of it.  This can be used to place overlays such as
5454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * buttons on top of the Surface, though note however that it can have an
5554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * impact on performance since a full alpha-blended composite will be performed
5654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * each time the Surface changes.
5754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project *
5854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p>Access to the underlying surface is provided via the SurfaceHolder interface,
5954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * which can be retrieved by calling {@link #getHolder}.
6054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project *
6154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p>The Surface will be created for you while the SurfaceView's window is
6254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * visible; you should implement {@link SurfaceHolder.Callback#surfaceCreated}
6354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * and {@link SurfaceHolder.Callback#surfaceDestroyed} to discover when the
6454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Surface is created and destroyed as the window is shown and hidden.
6554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project *
6654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <p>One of the purposes of this class is to provide a surface in which a
6754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * secondary thread can render in to the screen.  If you are going to use it
6854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * this way, you need to be aware of some threading semantics:
6954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project *
7054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <ul>
7154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <li> All SurfaceView and
7254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * {@link SurfaceHolder.Callback SurfaceHolder.Callback} methods will be called
7354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * from the thread running the SurfaceView's window (typically the main thread
7454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * of the application).  They thus need to correctly synchronize with any
7554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * state that is also touched by the drawing thread.
7654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * <li> You must ensure that the drawing thread only touches the underlying
7754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Surface while it is valid -- between
7854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * {@link SurfaceHolder.Callback#surfaceCreated SurfaceHolder.Callback.surfaceCreated()}
7954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * and
8054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * {@link SurfaceHolder.Callback#surfaceDestroyed SurfaceHolder.Callback.surfaceDestroyed()}.
8154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * </ul>
8254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */
8354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectpublic class SurfaceView extends View {
8454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    static private final String TAG = "SurfaceView";
8554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    static private final boolean DEBUG = false;
8654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    static private final boolean localLOGV = DEBUG ? true : Config.LOGV;
8754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
8854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    final ArrayList<SurfaceHolder.Callback> mCallbacks
8954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            = new ArrayList<SurfaceHolder.Callback>();
9054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
91f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    final int[] mLocation = new int[2];
92f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project
9354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    final ReentrantLock mSurfaceLock = new ReentrantLock();
9454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    final Surface mSurface = new Surface();
9554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    boolean mDrawingStopped = true;
9654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
9754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    final WindowManager.LayoutParams mLayout
9854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            = new WindowManager.LayoutParams();
9954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    IWindowSession mSession;
10054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    MyWindow mWindow;
101f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    final Rect mVisibleInsets = new Rect();
10254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    final Rect mWinFrame = new Rect();
103f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    final Rect mContentInsets = new Rect();
104694f79b5d1196640d1beb680b7d1fc68e6e77cbdDianne Hackborn    final Configuration mConfiguration = new Configuration();
105694f79b5d1196640d1beb680b7d1fc68e6e77cbdDianne Hackborn
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;
108726426ee736929e605742bfa52bca4b20095921dDianne Hackborn    static final int UPDATE_WINDOW_MSG = 3;
10954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
110c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn    int mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
111c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn
11254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    boolean mIsCreating = false;
11354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
11454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    final Handler mHandler = new Handler() {
11554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        @Override
11654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void handleMessage(Message msg) {
11754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            switch (msg.what) {
11854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                case KEEP_SCREEN_ON_MSG: {
11954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    setKeepScreenOn(msg.arg1 != 0);
12054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                } break;
12154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                case GET_NEW_SURFACE_MSG: {
12254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    handleGetNewSurface();
12354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                } break;
124726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                case UPDATE_WINDOW_MSG: {
125726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    updateWindow(false);
126726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                } break;
12754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
12854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
12954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    };
13054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
131e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn    final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener
132e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn            = new ViewTreeObserver.OnScrollChangedListener() {
133e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn                    public void onScrollChanged() {
134e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn                        updateWindow(false);
135e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn                    }
136e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn            };
137e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn
13854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    boolean mRequestedVisible = false;
1396b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian    boolean mWindowVisibility = false;
1406b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian    boolean mViewVisibility = false;
14154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mRequestedWidth = -1;
14254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mRequestedHeight = -1;
143d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian    /* Set SurfaceView's format to 565 by default to maintain backward
144d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian     * compatibility with applications assuming this format.
145d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian     */
146d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian    int mRequestedFormat = PixelFormat.RGB_565;
14754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mRequestedType = -1;
14854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
14954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    boolean mHaveFrame = false;
15054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    boolean mDestroyReportNeeded = false;
15154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    boolean mNewSurfaceNeeded = false;
15254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    long mLastLockTime = 0;
15354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
15454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    boolean mVisible = false;
15554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mLeft = -1;
15654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mTop = -1;
15754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mWidth = -1;
15854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mHeight = -1;
15954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mFormat = -1;
16054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int mType = -1;
16154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    final Rect mSurfaceFrame = new Rect();
162726426ee736929e605742bfa52bca4b20095921dDianne Hackborn    int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1;
163726426ee736929e605742bfa52bca4b20095921dDianne Hackborn    boolean mUpdateWindowNeeded;
164726426ee736929e605742bfa52bca4b20095921dDianne Hackborn    boolean mReportDrawNeeded;
16564f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima    private Translator mTranslator;
166424f668545c8b1423f46ed1286146393a8e4bc1aMitsuru Oshima
16754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public SurfaceView(Context context) {
16854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super(context);
169d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian        init();
17054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
17154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
17254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public SurfaceView(Context context, AttributeSet attrs) {
17354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super(context, attrs);
174d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian        init();
17554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
17654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
17754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public SurfaceView(Context context, AttributeSet attrs, int defStyle) {
17854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super(context, attrs, defStyle);
179d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian        init();
180d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian    }
181d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian
182d6ddcb7f00a7af95b452233d965b922632f78f21Mathias Agopian    private void init() {
18354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        setWillNotDraw(true);
18454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
18554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
18654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    /**
18754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     * Return the SurfaceHolder providing access and control over this
18854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     * SurfaceView's underlying surface.
18954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     *
19054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     * @return SurfaceHolder The holder of the surface.
19154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     */
19254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public SurfaceHolder getHolder() {
19354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return mSurfaceHolder;
19454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
19554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
19654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
19754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    protected void onAttachedToWindow() {
19854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super.onAttachedToWindow();
19954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mParent.requestTransparentRegion(this);
20054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mSession = getWindowSession();
20154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mLayout.token = getWindowToken();
20254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mLayout.setTitle("SurfaceView");
2036b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian        mViewVisibility = getVisibility() == VISIBLE;
204e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn        getViewTreeObserver().addOnScrollChangedListener(mScrollChangedListener);
20554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
20654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
20754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
20854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    protected void onWindowVisibilityChanged(int visibility) {
20954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super.onWindowVisibilityChanged(visibility);
2106b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian        mWindowVisibility = visibility == VISIBLE;
2116b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian        mRequestedVisible = mWindowVisibility && mViewVisibility;
2126b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian        updateWindow(false);
2136b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian    }
2146b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian
2156b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian    @Override
2166b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian    public void setVisibility(int visibility) {
2176b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian        super.setVisibility(visibility);
2186b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian        mViewVisibility = visibility == VISIBLE;
2196b7f1a62b5094fc72765a2537ee0760572df0950Mathias Agopian        mRequestedVisible = mWindowVisibility && mViewVisibility;
22054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        updateWindow(false);
22154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
22254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
22354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
22454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    protected void onDetachedFromWindow() {
225e2af5c882b146c3a8c7a37f093d13c8b386e8ebaDianne Hackborn        getViewTreeObserver().removeOnScrollChangedListener(mScrollChangedListener);
22654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mRequestedVisible = false;
22754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        updateWindow(false);
22854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mHaveFrame = false;
22954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (mWindow != null) {
23054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            try {
23154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mSession.remove(mWindow);
23254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            } catch (RemoteException ex) {
23354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
23454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mWindow = null;
23554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
23654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mSession = null;
23754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mLayout.token = null;
23854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
23954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super.onDetachedFromWindow();
24054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
24154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
24254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
24354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
24454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int width = getDefaultSize(mRequestedWidth, widthMeasureSpec);
24554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int height = getDefaultSize(mRequestedHeight, heightMeasureSpec);
24654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        setMeasuredDimension(width, height);
24754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
24854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
24954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
25054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
25154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super.onSizeChanged(w, h, oldw, oldh);
25254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        updateWindow(false);
25354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
25454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
25554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
25654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public boolean gatherTransparentRegion(Region region) {
2571cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn        if (mWindowType == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
2581cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn            return super.gatherTransparentRegion(region);
2591cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn        }
2601cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn
26154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        boolean opaque = true;
26254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if ((mPrivateFlags & SKIP_DRAW) == 0) {
26354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // this view draws, remove it from the transparent region
26454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            opaque = super.gatherTransparentRegion(region);
26554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        } else if (region != null) {
26654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            int w = getWidth();
26754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            int h = getHeight();
26854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (w>0 && h>0) {
26954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                getLocationInWindow(mLocation);
27054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                // otherwise, punch a hole in the whole hierarchy
27154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                int l = mLocation[0];
27254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                int t = mLocation[1];
27354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                region.op(l, t, l+w, t+h, Region.Op.UNION);
27454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
27554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
27654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (PixelFormat.formatHasAlpha(mRequestedFormat)) {
27754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            opaque = false;
27854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
27954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return opaque;
28054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
28154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
28254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
28354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public void draw(Canvas canvas) {
2841cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn        if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
2851cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn            // draw() is not called when SKIP_DRAW is set
2861cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn            if ((mPrivateFlags & SKIP_DRAW) == 0) {
2871cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn                // punch a whole in the view-hierarchy below us
2881cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn                canvas.drawColor(0, PorterDuff.Mode.CLEAR);
2891cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn            }
29054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
29154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super.draw(canvas);
29254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
29354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
29454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
29554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    protected void dispatchDraw(Canvas canvas) {
2961cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn        if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
2971cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn            // if SKIP_DRAW is cleared, draw() has already punched a hole
2981cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn            if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
2991cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn                // punch a whole in the view-hierarchy below us
3001cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn                canvas.drawColor(0, PorterDuff.Mode.CLEAR);
3011cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn            }
30254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
30354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // reposition ourselves where the surface is
30454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mHaveFrame = true;
30554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        updateWindow(false);
30654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super.dispatchDraw(canvas);
30754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
30854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
309c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn    /**
31029e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * Control whether the surface view's surface is placed on top of another
31129e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * regular surface view in the window (but still behind the window itself).
31229e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * This is typically used to place overlays on top of an underlying media
31329e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * surface view.
31429e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     *
31529e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * <p>Note that this must be set before the surface view's containing
31629e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * window is attached to the window manager.
31729e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     *
31829e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * <p>Calling this overrides any previous call to {@link #setZOrderOnTop}.
31929e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     */
32029e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn    public void setZOrderMediaOverlay(boolean isMediaOverlay) {
32129e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn        mWindowType = isMediaOverlay
32229e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn                ? WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY
32329e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn                : WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
32429e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn    }
32529e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn
32629e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn    /**
3271cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * Control whether the surface view's surface is placed on top of its
3281cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * window.  Normally it is placed behind the window, to allow it to
3291cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * (for the most part) appear to composite with the views in the
3301cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * hierarchy.  By setting this, you cause it to be placed above the
3311cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * window.  This means that none of the contents of the window this
3321cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * SurfaceView is in will be visible on top of its surface.
3331cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     *
3341cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * <p>Note that this must be set before the surface view's containing
3351cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     * window is attached to the window manager.
33629e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     *
33729e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn     * <p>Calling this overrides any previous call to {@link #setZOrderMediaOverlay}.
3381cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn     */
33929e4a3c566f435c32f0b95e4ac8e8b33cac6fabaDianne Hackborn    public void setZOrderOnTop(boolean onTop) {
340ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger        if (onTop) {
341ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger            mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
342ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger            // ensures the surface is placed below the IME
343ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger            mLayout.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
344ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger        } else {
345ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger            mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
346ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger            mLayout.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
347ecde72fe411811ca02a2565bf73b86e6e8ddc76bDerek Sollenberger        }
3481cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn    }
3491cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn
3501cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn    /**
351c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn     * Hack to allow special layering of windows.  The type is one of the
352c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn     * types in WindowManager.LayoutParams.  This is a hack so:
353c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn     * @hide
354c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn     */
355c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn    public void setWindowType(int type) {
356c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn        mWindowType = type;
357c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn    }
35834bf2ee9e695c620e0a4b9a790f1f6ccb8a77234Mitsuru Oshima
35954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    private void updateWindow(boolean force) {
36054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (!mHaveFrame) {
36154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return;
36254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
363841f13c8e9ff3f7695b6c18a8abcec3c947983ffMitsuru Oshima        ViewRoot viewRoot = (ViewRoot) getRootView().getParent();
364168173a698e820ceb1ebf54b4910888891be2056Joe Onorato        if (viewRoot != null) {
365168173a698e820ceb1ebf54b4910888891be2056Joe Onorato            mTranslator = viewRoot.mTranslator;
366168173a698e820ceb1ebf54b4910888891be2056Joe Onorato        }
36764f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima
36838ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima        Resources res = getContext().getResources();
36938ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima        if (mTranslator != null || !res.getCompatibilityInfo().supportsScreen()) {
370240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima            mSurface.setCompatibleDisplayMetrics(res.getDisplayMetrics(), mTranslator);
37138ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima        }
37238ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima
37354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int myWidth = mRequestedWidth;
37454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (myWidth <= 0) myWidth = getWidth();
37554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int myHeight = mRequestedHeight;
37654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (myHeight <= 0) myHeight = getHeight();
377001a6e52445b2744b4f2eb00099b98a17f4245c9Mitsuru Oshima
37854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        getLocationInWindow(mLocation);
37954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        final boolean creating = mWindow == null;
38054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        final boolean formatChanged = mFormat != mRequestedFormat;
38154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        final boolean sizeChanged = mWidth != myWidth || mHeight != myHeight;
38254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        final boolean visibleChanged = mVisible != mRequestedVisible
38354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                || mNewSurfaceNeeded;
38454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        final boolean typeChanged = mType != mRequestedType;
38554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (force || creating || formatChanged || sizeChanged || visibleChanged
386726426ee736929e605742bfa52bca4b20095921dDianne Hackborn            || typeChanged || mLeft != mLocation[0] || mTop != mLocation[1]
387726426ee736929e605742bfa52bca4b20095921dDianne Hackborn            || mUpdateWindowNeeded || mReportDrawNeeded) {
38854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
38954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (localLOGV) Log.i(TAG, "Changes: creating=" + creating
39054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    + " format=" + formatChanged + " size=" + sizeChanged
39154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    + " visible=" + visibleChanged
39254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    + " left=" + (mLeft != mLocation[0])
39354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    + " top=" + (mTop != mLocation[1]));
39464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima
39554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            try {
39654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                final boolean visible = mVisible = mRequestedVisible;
39754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mLeft = mLocation[0];
39854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mTop = mLocation[1];
39954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mWidth = myWidth;
40054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mHeight = myHeight;
40154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mFormat = mRequestedFormat;
40254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mType = mRequestedType;
40354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
40464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                // Scaling/Translate window's layout here because mLayout is not used elsewhere.
40564f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima
40664f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                // Places the window relative
40764f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                mLayout.x = mLeft;
40864f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                mLayout.y = mTop;
40964f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                mLayout.width = getWidth();
41064f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                mLayout.height = getHeight();
41164f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                if (mTranslator != null) {
41264f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                    mTranslator.translateLayoutParamsInAppWindowToScreen(mLayout);
41364f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima                }
41464f59342d41849bd365cb43fad7505d5e3daa417Mitsuru Oshima
41554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mLayout.format = mRequestedFormat;
4161cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn                mLayout.flags |=WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
4171cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn                              | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
4181cd403eaac24e0e84619dea07e2d1d60e58e1fd2Dianne Hackborn                              | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
41954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                              | WindowManager.LayoutParams.FLAG_SCALED
42054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                              | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
42154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                              | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
42254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                              ;
423841f13c8e9ff3f7695b6c18a8abcec3c947983ffMitsuru Oshima                if (!getContext().getResources().getCompatibilityInfo().supportsScreen()) {
424841f13c8e9ff3f7695b6c18a8abcec3c947983ffMitsuru Oshima                    mLayout.flags |= WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
425841f13c8e9ff3f7695b6c18a8abcec3c947983ffMitsuru Oshima                }
42654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
42754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mLayout.memoryType = mRequestedType;
42854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
42954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                if (mWindow == null) {
4309bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                    mWindow = new MyWindow(this);
431c4d5d02667af6989a3121072871f6a4b1e68b594Dianne Hackborn                    mLayout.type = mWindowType;
43254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    mLayout.gravity = Gravity.LEFT|Gravity.TOP;
43354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    mSession.add(mWindow, mLayout,
434f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project                            mVisible ? VISIBLE : GONE, mContentInsets);
43554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
43654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
43754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                if (visibleChanged && (!visible || mNewSurfaceNeeded)) {
43854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    reportSurfaceDestroyed();
43954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
440f5e32f33eddc6e22edee1df486b38294ddc76cc3Mathias Agopian
44154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mNewSurfaceNeeded = false;
44254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
443726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                boolean realSizeChanged;
444726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                boolean reportDrawNeeded;
445589cebe2d58591403de4a77077941c0454bc91bcMitsuru Oshima
446726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                mSurfaceLock.lock();
447726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                try {
448726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    mUpdateWindowNeeded = false;
449726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    reportDrawNeeded = mReportDrawNeeded;
450726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    mReportDrawNeeded = false;
451726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    mDrawingStopped = !visible;
452726426ee736929e605742bfa52bca4b20095921dDianne Hackborn
453726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    final int relayoutResult = mSession.relayout(
454726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        mWindow, mLayout, mWidth, mHeight,
455726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                            visible ? VISIBLE : GONE, false, mWinFrame, mContentInsets,
456726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                            mVisibleInsets, mConfiguration, mSurface);
457726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    if ((relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) {
458726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        mReportDrawNeeded = true;
459726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    }
460726426ee736929e605742bfa52bca4b20095921dDianne Hackborn
461726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    if (localLOGV) Log.i(TAG, "New surface: " + mSurface
462726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                            + ", vis=" + visible + ", frame=" + mWinFrame);
463726426ee736929e605742bfa52bca4b20095921dDianne Hackborn
464726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    mSurfaceFrame.left = 0;
465726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    mSurfaceFrame.top = 0;
466726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    if (mTranslator == null) {
467726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        mSurfaceFrame.right = mWinFrame.width();
468726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        mSurfaceFrame.bottom = mWinFrame.height();
469726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    } else {
470726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        float appInvertedScale = mTranslator.applicationInvertedScale;
471726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        mSurfaceFrame.right = (int) (mWinFrame.width() * appInvertedScale + 0.5f);
472726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        mSurfaceFrame.bottom = (int) (mWinFrame.height() * appInvertedScale + 0.5f);
473726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    }
474726426ee736929e605742bfa52bca4b20095921dDianne Hackborn
475726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    final int surfaceWidth = mSurfaceFrame.right;
476726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    final int surfaceHeight = mSurfaceFrame.bottom;
477726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    realSizeChanged = mLastSurfaceWidth != surfaceWidth
478726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                            || mLastSurfaceHeight != surfaceHeight;
479726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    mLastSurfaceWidth = surfaceWidth;
480726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    mLastSurfaceHeight = surfaceHeight;
481726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                } finally {
482726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    mSurfaceLock.unlock();
483589cebe2d58591403de4a77077941c0454bc91bcMitsuru Oshima                }
48454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
48554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                try {
48654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    if (visible) {
48754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        mDestroyReportNeeded = true;
48854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
48954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        SurfaceHolder.Callback callbacks[];
49054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        synchronized (mCallbacks) {
49154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            callbacks = new SurfaceHolder.Callback[mCallbacks.size()];
49254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            mCallbacks.toArray(callbacks);
4933d91492d694cf00474fec792134e496be6ee0313Mitsuru Oshima                        }
49454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
49554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        if (visibleChanged) {
49654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            mIsCreating = true;
49754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            for (SurfaceHolder.Callback c : callbacks) {
49854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                c.surfaceCreated(mSurfaceHolder);
49954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            }
50054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        }
50154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        if (creating || formatChanged || sizeChanged
502726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                                || visibleChanged || realSizeChanged) {
50354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            for (SurfaceHolder.Callback c : callbacks) {
504726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                                c.surfaceChanged(mSurfaceHolder, mFormat, myWidth, myHeight);
50554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            }
50654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        }
507f5e32f33eddc6e22edee1df486b38294ddc76cc3Mathias Agopian                    } else {
508f5e32f33eddc6e22edee1df486b38294ddc76cc3Mathias Agopian                        mSurface.release();
50954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    }
51054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                } finally {
51154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    mIsCreating = false;
512726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    if (creating || reportDrawNeeded) {
51354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        mSession.finishDrawing(mWindow);
51454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    }
51554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
51654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            } catch (RemoteException ex) {
51754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
51854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (localLOGV) Log.v(
51954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y +
52054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                " w=" + mLayout.width + " h=" + mLayout.height +
52154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                ", frame=" + mSurfaceFrame);
52254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
52354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
52454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
52554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    private void reportSurfaceDestroyed() {
52654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (mDestroyReportNeeded) {
52754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mDestroyReportNeeded = false;
52854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            SurfaceHolder.Callback callbacks[];
52954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            synchronized (mCallbacks) {
53054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                callbacks = new SurfaceHolder.Callback[mCallbacks.size()];
53154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mCallbacks.toArray(callbacks);
53254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
53354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            for (SurfaceHolder.Callback c : callbacks) {
53454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                c.surfaceDestroyed(mSurfaceHolder);
53554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
53654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
53754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super.onDetachedFromWindow();
53854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
53954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
54054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    void handleGetNewSurface() {
54154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mNewSurfaceNeeded = true;
54254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        updateWindow(false);
54354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
544b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project
5457179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger    /**
5467179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger     * Check to see if the surface has fixed size dimensions or if the surface's
5477179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger     * dimensions are dimensions are dependent on its current layout.
5487179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger     *
5497179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger     * @return true if the surface has dimensions that are fixed in size
5507179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger     * @hide
5517179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger     */
5527179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger    public boolean isFixedSize() {
5537179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger        return (mRequestedWidth != -1 || mRequestedHeight != -1);
5547179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger    }
5557179b8133d4a1d8e5f26cbe3da6aa978094e75c9Derek Sollenberger
55672c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn    private static class MyWindow extends BaseIWindow {
5578169daed2f7a8731d478b884b1f455c747b88478Mitsuru Oshima        private final WeakReference<SurfaceView> mSurfaceView;
5589bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer
5599bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer        public MyWindow(SurfaceView surfaceView) {
5609bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer            mSurfaceView = new WeakReference<SurfaceView>(surfaceView);
5619bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer        }
5629bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer
563f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project        public void resized(int w, int h, Rect coveredInsets,
564e36d6e277e49475076b7872d36ea6a5c5b996e9dDianne Hackborn                Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
5659bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer            SurfaceView surfaceView = mSurfaceView.get();
5669bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer            if (surfaceView != null) {
5679bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                if (localLOGV) Log.v(
5689bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                        "SurfaceView", surfaceView + " got resized: w=" +
569b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project                                w + " h=" + h + ", cur w=" + mCurWidth + " h=" + mCurHeight);
570726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                surfaceView.mSurfaceLock.lock();
571726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                try {
5729bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                    if (reportDraw) {
573726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        surfaceView.mUpdateWindowNeeded = true;
574726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        surfaceView.mReportDrawNeeded = true;
575726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        surfaceView.mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG);
576726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    } else if (surfaceView.mWinFrame.width() != w
577726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                            || surfaceView.mWinFrame.height() != h) {
578726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        surfaceView.mUpdateWindowNeeded = true;
579726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                        surfaceView.mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG);
58054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    }
581726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                } finally {
582726426ee736929e605742bfa52bca4b20095921dDianne Hackborn                    surfaceView.mSurfaceLock.unlock();
58354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
58454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
58554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
58654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
58754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void dispatchKey(KeyEvent event) {
5889bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer            SurfaceView surfaceView = mSurfaceView.get();
5899bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer            if (surfaceView != null) {
590b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project                //Log.w("SurfaceView", "Unexpected key event in surface: " + event);
591b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project                if (surfaceView.mSession != null && surfaceView.mSurface != null) {
5929bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                    try {
5939bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                        surfaceView.mSession.finishKey(surfaceView.mWindow);
5949bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                    } catch (RemoteException ex) {
5959bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer                    }
59654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
59754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
59854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
59954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
6008df8b2b405c60cacf7a66c4e2ca078dd3d7ec7bdDianne Hackborn        public void dispatchPointer(MotionEvent event, long eventTime,
6018df8b2b405c60cacf7a66c4e2ca078dd3d7ec7bdDianne Hackborn                boolean callWhenDone) {
60254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            Log.w("SurfaceView", "Unexpected pointer event in surface: " + event);
60354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //if (mSession != null && mSurface != null) {
60454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //    try {
60554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //        //mSession.finishKey(mWindow);
60654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //    } catch (RemoteException ex) {
60754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //    }
60854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //}
60954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
61054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
6118df8b2b405c60cacf7a66c4e2ca078dd3d7ec7bdDianne Hackborn        public void dispatchTrackball(MotionEvent event, long eventTime,
6128df8b2b405c60cacf7a66c4e2ca078dd3d7ec7bdDianne Hackborn                boolean callWhenDone) {
61354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            Log.w("SurfaceView", "Unexpected trackball event in surface: " + event);
61454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //if (mSession != null && mSurface != null) {
61554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //    try {
61654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //        //mSession.finishKey(mWindow);
61754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //    } catch (RemoteException ex) {
61854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //    }
61954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            //}
62054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
62154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
62254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void dispatchAppVisibility(boolean visible) {
62354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // The point of SurfaceView is to let the app control the surface.
62454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
625b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project
62654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void dispatchGetNewSurface() {
6279bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer            SurfaceView surfaceView = mSurfaceView.get();
6289bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer            if (surfaceView != null) {
629b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project                Message msg = surfaceView.mHandler.obtainMessage(GET_NEW_SURFACE_MSG);
630b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project                surfaceView.mHandler.sendMessage(msg);
6319bdf576615231e4b9693f08bfe3dc886c2edf49eJon Larimer            }
63254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
63354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
63454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void windowFocusChanged(boolean hasFocus, boolean touchEnabled) {
63554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            Log.w("SurfaceView", "Unexpected focus in surface: focus=" + hasFocus + ", touchEnabled=" + touchEnabled);
63654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
63754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
63854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
63954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
64054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
64154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int mCurWidth = -1;
64254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int mCurHeight = -1;
64354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
64454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
64554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
64654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
64754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        private static final String LOG_TAG = "SurfaceHolder";
64834bf2ee9e695c620e0a4b9a790f1f6ccb8a77234Mitsuru Oshima        private int mSaveCount;
64954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
65054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public boolean isCreating() {
65154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return mIsCreating;
65254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
65354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
65454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void addCallback(Callback callback) {
65554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            synchronized (mCallbacks) {
65654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                // This is a linear search, but in practice we'll
65754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                // have only a couple callbacks, so it doesn't matter.
65854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                if (mCallbacks.contains(callback) == false) {
65954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    mCallbacks.add(callback);
66054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
66154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
66254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
66354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
66454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void removeCallback(Callback callback) {
66554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            synchronized (mCallbacks) {
66654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mCallbacks.remove(callback);
66754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
66854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
66954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
67054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void setFixedSize(int width, int height) {
67154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (mRequestedWidth != width || mRequestedHeight != height) {
67254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mRequestedWidth = width;
67354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mRequestedHeight = height;
67454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                requestLayout();
67554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
67654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
67754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
67854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void setSizeFromLayout() {
67954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (mRequestedWidth != -1 || mRequestedHeight != -1) {
68054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mRequestedWidth = mRequestedHeight = -1;
68154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                requestLayout();
68254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
68354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
68454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
68554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void setFormat(int format) {
68654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mRequestedFormat = format;
68754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (mWindow != null) {
68854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                updateWindow(false);
68954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
69054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
69154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
69254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void setType(int type) {
69354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            switch (type) {
69454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            case SURFACE_TYPE_HARDWARE:
69554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            case SURFACE_TYPE_GPU:
696317a6280cc109e873646e4652be1582d870eedfdMathias Agopian                // these are deprecated, treat as "NORMAL"
697317a6280cc109e873646e4652be1582d870eedfdMathias Agopian                type = SURFACE_TYPE_NORMAL;
698317a6280cc109e873646e4652be1582d870eedfdMathias Agopian                break;
699317a6280cc109e873646e4652be1582d870eedfdMathias Agopian            }
700317a6280cc109e873646e4652be1582d870eedfdMathias Agopian            switch (type) {
701317a6280cc109e873646e4652be1582d870eedfdMathias Agopian            case SURFACE_TYPE_NORMAL:
70254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            case SURFACE_TYPE_PUSH_BUFFERS:
70354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mRequestedType = type;
70454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                if (mWindow != null) {
70554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    updateWindow(false);
70654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
70754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                break;
70854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
70954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
71054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
71154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void setKeepScreenOn(boolean screenOn) {
71254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            Message msg = mHandler.obtainMessage(KEEP_SCREEN_ON_MSG);
71354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            msg.arg1 = screenOn ? 1 : 0;
71454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mHandler.sendMessage(msg);
71554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
71654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
71754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public Canvas lockCanvas() {
71854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return internalLockCanvas(null);
71954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
72054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
72154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public Canvas lockCanvas(Rect dirty) {
72254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return internalLockCanvas(dirty);
72354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
72454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
72554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        private final Canvas internalLockCanvas(Rect dirty) {
72654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (mType == SURFACE_TYPE_PUSH_BUFFERS) {
72754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                throw new BadSurfaceTypeException(
72854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        "Surface type is SURFACE_TYPE_PUSH_BUFFERS");
72954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
73054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mSurfaceLock.lock();
73154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
73254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (localLOGV) Log.i(TAG, "Locking canvas... stopped="
73354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    + mDrawingStopped + ", win=" + mWindow);
73454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
73554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            Canvas c = null;
73654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (!mDrawingStopped && mWindow != null) {
73754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                Rect frame = dirty != null ? dirty : mSurfaceFrame;
73854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                try {
73954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    c = mSurface.lockCanvas(frame);
74054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                } catch (Exception e) {
74154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    Log.e(LOG_TAG, "Exception locking surface", e);
74254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
74354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
74454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
74554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (localLOGV) Log.i(TAG, "Returned canvas: " + c);
74654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (c != null) {
74754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                mLastLockTime = SystemClock.uptimeMillis();
74854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                return c;
74954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
75054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
75154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // If the Surface is not ready to be drawn, then return null,
75254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // but throttle calls to this function so it isn't called more
75354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // than every 100ms.
75454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            long now = SystemClock.uptimeMillis();
75554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            long nextTime = mLastLockTime + 100;
75654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (nextTime > now) {
75754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                try {
75854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    Thread.sleep(nextTime-now);
75954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                } catch (InterruptedException e) {
76054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                }
76154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                now = SystemClock.uptimeMillis();
76254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
76354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mLastLockTime = now;
76454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mSurfaceLock.unlock();
76554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
76654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return null;
76754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
76854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
76954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public void unlockCanvasAndPost(Canvas canvas) {
77054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mSurface.unlockCanvasAndPost(canvas);
77154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mSurfaceLock.unlock();
77254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
77354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
77454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public Surface getSurface() {
77554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return mSurface;
77654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
77754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
77854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        public Rect getSurfaceFrame() {
77954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return mSurfaceFrame;
78054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
78154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    };
78254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
783