Surface.java revision d7e559675c96071b6ee46c3b45aa3c9e7216a9c4
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 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
19d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbyeimport android.annotation.IntDef;
20240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshimaimport android.content.res.CompatibilityInfo.Translator;
210b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brownimport android.graphics.Canvas;
220b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brownimport android.graphics.Matrix;
230b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brownimport android.graphics.Rect;
240b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brownimport android.graphics.SurfaceTexture;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel;
263866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopianimport android.os.Parcelable;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
28d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye
29d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbyeimport java.lang.annotation.Retention;
30d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbyeimport java.lang.annotation.RetentionPolicy;
31d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye
323866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopianimport dalvik.system.CloseGuard;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
35334031cd07c3bd09d23fce0ebaf946fc6ecfee26Glenn Kasten * Handle onto a raw buffer that is being managed by the screen compositor.
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Surface implements Parcelable {
3864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private static final String TAG = "Surface";
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native long nativeCreateFromSurfaceTexture(SurfaceTexture surfaceTexture)
4129479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian            throws OutOfResourcesException;
4236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native long nativeCreateFromSurfaceControl(long surfaceControlNativeObject);
4352800617946c456e78ed010c82d0ec4358368164Mathias Agopian
4436bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native long nativeLockCanvas(long nativeObject, Canvas canvas, Rect dirty)
45fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            throws OutOfResourcesException;
4636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeUnlockCanvasAndPost(long nativeObject, Canvas canvas);
4729479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
4836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeRelease(long nativeObject);
4936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native boolean nativeIsValid(long nativeObject);
5036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native boolean nativeIsConsumerRunningBehind(long nativeObject);
5136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native long nativeReadFromParcel(long nativeObject, Parcel source);
5236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private static native void nativeWriteToParcel(long nativeObject, Parcel dest);
5329479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
545795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza    private static native void nativeAllocateBuffers(long nativeObject);
555795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza
5664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public static final Parcelable.Creator<Surface> CREATOR =
5764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            new Parcelable.Creator<Surface>() {
58fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        @Override
5964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public Surface createFromParcel(Parcel source) {
6064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            try {
6164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                Surface s = new Surface();
6264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                s.readFromParcel(source);
6364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                return s;
6464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            } catch (Exception e) {
6564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                Log.e(TAG, "Exception creating surface from parcel", e);
6664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                return null;
6764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
68b85c933d850286874005f97a9764c9b22e49a597Kevin Hester        }
69fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
70fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        @Override
7164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public Surface[] newArray(int size) {
7264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            return new Surface[size];
73df0c84f90894c677c50bdc967a0598f516ac86d7Jamie Gennis        }
7464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    };
75df0c84f90894c677c50bdc967a0598f516ac86d7Jamie Gennis
7664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private final CloseGuard mCloseGuard = CloseGuard.get();
77c87c4a3e3b3c3949ae3c6f8fd245b71691d5ca3bMathias Agopian
78fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown    // Guarded state.
79fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown    final Object mLock = new Object(); // protects the native state
80fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown    private String mName;
8136bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    long mNativeObject; // package scope only for SurfaceControl access
8236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private long mLockedObject;
83fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown    private int mGenerationId; // incremented each time mNativeObject changes
8464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private final Canvas mCanvas = new CompatibleCanvas();
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
86240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    // A matrix to scale the matrix set by application. This is set to null for
87240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    // non compatibility mode.
88240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    private Matrix mCompatibleMatrix;
8938ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima
90d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye    /** @hide */
91d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye    @IntDef({ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270})
92d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye    @Retention(RetentionPolicy.SOURCE)
93d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye    public @interface Rotation {}
94d9273d6f289d9b55da3fd0db2f659fdfb48106a8Tor Norbye
9564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
9629479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     * Rotation constant: 0 degree rotation (natural orientation)
9729479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     */
9829479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    public static final int ROTATION_0 = 0;
9929479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
10029479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    /**
10129479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     * Rotation constant: 90 degree rotation.
10229479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     */
10329479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    public static final int ROTATION_90 = 1;
10429479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
10529479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    /**
10629479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     * Rotation constant: 180 degree rotation.
10729479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     */
10829479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    public static final int ROTATION_180 = 2;
10929479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
11029479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    /**
11129479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     * Rotation constant: 270 degree rotation.
11229479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     */
11329479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    public static final int ROTATION_270 = 3;
11429479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
11529479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    /**
11664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Create an empty surface, which will later be filled in by readFromParcel().
11764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @hide
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public Surface() {
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Create Surface from a {@link SurfaceTexture}.
12464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
12564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Images drawn to the Surface will be made available to the {@link
12664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * SurfaceTexture}, which can attach them to an OpenGL ES texture via {@link
12764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * SurfaceTexture#updateTexImage}.
12864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
12964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @param surfaceTexture The {@link SurfaceTexture} that is updated by this
13064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Surface.
131a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     * @throws OutOfResourcesException if the surface could not be created.
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public Surface(SurfaceTexture surfaceTexture) {
13464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (surfaceTexture == null) {
13564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("surfaceTexture must not be null");
13664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
13764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
138fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
139fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            mName = surfaceTexture.toString();
140a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin            setNativeObjectLocked(nativeCreateFromSurfaceTexture(surfaceTexture));
141f5e32f33eddc6e22edee1df486b38294ddc76cc3Mathias Agopian        }
142240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    }
143240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima
14486e1bc730570765355dc8789b5c6de6962a053ccMathias Agopian    /* called from android_view_Surface_createFromIGraphicBufferProducer() */
14536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private Surface(long nativeObject) {
146fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
147fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            setNativeObjectLocked(nativeObject);
148fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        }
1493866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    }
1503866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian
15164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    @Override
15264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    protected void finalize() throws Throwable {
15364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        try {
15464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            if (mCloseGuard != null) {
15564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                mCloseGuard.warnIfOpen();
15664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
15786e1bc730570765355dc8789b5c6de6962a053ccMathias Agopian            release();
15864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        } finally {
15964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            super.finalize();
16064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
161b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    }
162b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian
163240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    /**
16464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Release the local reference to the server-side surface.
16564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Always call release() when you're done with a Surface.
16664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * This will make the surface invalid.
16764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
16864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void release() {
169fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
1707c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            if (mNativeObject != 0) {
1717c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian                nativeRelease(mNativeObject);
172fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                setNativeObjectLocked(0);
1737c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            }
1743866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        }
17564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
17664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
17764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
17864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Free all server-side state associated with this surface and
17964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * release this object's reference.  This method can only be
18064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * called from the process that created the service.
181b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian     * @hide
182b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian     */
18364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void destroy() {
18486e1bc730570765355dc8789b5c6de6962a053ccMathias Agopian        release();
18564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
18661566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn
18761566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn    /**
18864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Returns true if this object holds a valid surface.
18964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
19064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @return True if it holds a physical surface, so lockCanvas() will succeed.
19164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Otherwise returns false.
19261566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn     */
19364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public boolean isValid() {
194fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
1957c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            if (mNativeObject == 0) return false;
1967c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            return nativeIsValid(mNativeObject);
1977c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian        }
19864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
19961566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn
20064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
20164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Gets the generation number of this surface, incremented each time
20264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * the native surface contained within this object changes.
20364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
20464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @return The current generation number.
20564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @hide
20664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
207b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    public int getGenerationId() {
208fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
209fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            return mGenerationId;
210fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        }
211b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    }
212b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian
213c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian    /**
21464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Returns true if the consumer of this Surface is running behind the producer.
21564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
21664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @return True if the consumer is more than one buffer ahead of the producer.
217c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian     * @hide
218c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian     */
21964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public boolean isConsumerRunningBehind() {
220fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
2217c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            checkNotReleasedLocked();
2227c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            return nativeIsConsumerRunningBehind(mNativeObject);
2237c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian        }
22464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
225c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian
226b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    /**
22764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Gets a {@link Canvas} for drawing into this surface.
22864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
2299ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian     * After drawing into the provided {@link Canvas}, the caller must
23064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface.
23164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
23230d7ab9a10fcde397bae7bed5f16d1094fded8b2Mathias Agopian     * @param inOutDirty A rectangle that represents the dirty region that the caller wants
23364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * to redraw.  This function may choose to expand the dirty rectangle if for example
23464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * the surface has been resized or if the previous contents of the surface were
2359ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian     * not available.  The caller must redraw the entire dirty region as represented
2369ddf32aa8ac5aa8c29a8063f0528838f1436e5ddMathias Agopian     * by the contents of the inOutDirty rectangle upon return from this function.
23764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * The caller may also pass <code>null</code> instead, in the case where the
23864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * entire surface should be redrawn.
23964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @return A canvas for drawing into the surface.
240a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     *
241a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     * @throws IllegalArgumentException If the inOutDirty rectangle is not valid.
242a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     * @throws OutOfResourcesException If the canvas cannot be locked.
243240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima     */
2443866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    public Canvas lockCanvas(Rect inOutDirty)
245a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin            throws Surface.OutOfResourcesException, IllegalArgumentException {
246fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
2477c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            checkNotReleasedLocked();
248ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            if (mLockedObject != 0) {
249ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden                // Ideally, nativeLockCanvas() would throw in this situation and prevent the
250ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden                // double-lock, but that won't happen if mNativeObject was updated.  We can't
251ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden                // abandon the old mLockedObject because it might still be in use, so instead
252ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden                // we just refuse to re-lock the Surface.
253d7e559675c96071b6ee46c3b45aa3c9e7216a9c4Jesse Hall                throw new IllegalArgumentException("Surface was already locked");
254ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            }
255ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
256fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            return mCanvas;
2577c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian        }
25864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
259240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima
26064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
26164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Posts the new contents of the {@link Canvas} to the surface and
26264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * releases the {@link Canvas}.
26364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
26464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @param canvas The canvas previously obtained from {@link #lockCanvas}.
26564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
26664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void unlockCanvasAndPost(Canvas canvas) {
267fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        if (canvas != mCanvas) {
268fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            throw new IllegalArgumentException("canvas object must be the same instance that "
269fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                    + "was previously returned by lockCanvas");
270fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        }
271fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
272fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
2737c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            checkNotReleasedLocked();
274ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            if (mNativeObject != mLockedObject) {
275ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden                Log.w(TAG, "WARNING: Surface's mNativeObject (0x" +
27636bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                        Long.toHexString(mNativeObject) + ") != mLockedObject (0x" +
27736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                        Long.toHexString(mLockedObject) +")");
278ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            }
279ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            if (mLockedObject == 0) {
280a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin                throw new IllegalStateException("Surface was not locked");
281ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            }
282d7e559675c96071b6ee46c3b45aa3c9e7216a9c4Jesse Hall            try {
283d7e559675c96071b6ee46c3b45aa3c9e7216a9c4Jesse Hall                nativeUnlockCanvasAndPost(mLockedObject, canvas);
284d7e559675c96071b6ee46c3b45aa3c9e7216a9c4Jesse Hall            } finally {
285d7e559675c96071b6ee46c3b45aa3c9e7216a9c4Jesse Hall                nativeRelease(mLockedObject);
286d7e559675c96071b6ee46c3b45aa3c9e7216a9c4Jesse Hall                mLockedObject = 0;
287d7e559675c96071b6ee46c3b45aa3c9e7216a9c4Jesse Hall            }
2887c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian        }
28964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
290240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima
291ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden    /**
29264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @deprecated This API has been removed and is not supported.  Do not use.
29364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
29464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    @Deprecated
29564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void unlockCanvas(Canvas canvas) {
29664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        throw new UnsupportedOperationException();
297d10cd5765a2b706fc174f16b951d6b0a5d3740d3Romain Guy    }
29838ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima
29938ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima    /**
300b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian     * Sets the translator used to scale canvas's width/height in compatibility
301b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian     * mode.
30238ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima     */
3035be8de3420ba4c9d816b98e29bdec11715f6b626Dianne Hackborn    void setCompatibilityTranslator(Translator translator) {
304240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima        if (translator != null) {
305240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima            float appScale = translator.applicationScale;
306240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima            mCompatibleMatrix = new Matrix();
307240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima            mCompatibleMatrix.setScale(appScale, appScale);
308240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima        }
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
31264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Copy another surface to this one.  This surface now holds a reference
31364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * to the same data as the original surface, and is -not- the owner.
31464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * This is for use by the window manager when returning a window surface
31564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * back from a client, converting it from the representation being managed
31664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * by the window manager to the representation the client uses to draw
31764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * in to it.
31864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @hide
31964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
3203866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    public void copyFrom(SurfaceControl other) {
32164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (other == null) {
32264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("other must not be null");
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
324fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
32536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        long surfaceControlPtr = other.mNativeObject;
326fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        if (surfaceControlPtr == 0) {
3273866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            throw new NullPointerException(
3283866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian                    "SurfaceControl native object is null. Are you using a released SurfaceControl?");
32964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
33036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat        long newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);
331fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
332fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
333fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            if (mNativeObject != 0) {
334fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                nativeRelease(mNativeObject);
3357c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            }
336fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            setNativeObjectLocked(newNativeObject);
33786e1bc730570765355dc8789b5c6de6962a053ccMathias Agopian        }
33864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
33964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
34064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
341fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown     * This is intended to be used by {@link SurfaceView#updateWindow} only.
3427c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian     * @param other access is not thread safe
3437c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian     * @hide
3447c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian     * @deprecated
34564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
3467c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian    @Deprecated
34764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void transferFrom(Surface other) {
34864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (other == null) {
34964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("other must not be null");
35064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
35164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (other != this) {
35236bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat            final long newPtr;
353fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            synchronized (other.mLock) {
354fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                newPtr = other.mNativeObject;
355fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                other.setNativeObjectLocked(0);
356fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            }
357fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
358fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            synchronized (mLock) {
3597c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian                if (mNativeObject != 0) {
3607c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian                    nativeRelease(mNativeObject);
3617c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian                }
362fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                setNativeObjectLocked(newPtr);
3633866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            }
36464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
36564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
36864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public int describeContents() {
36964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        return 0;
37064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
37164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
37264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void readFromParcel(Parcel source) {
37364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (source == null) {
37464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("source must not be null");
375f5e32f33eddc6e22edee1df486b38294ddc76cc3Mathias Agopian        }
376fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
377fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
378ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            // nativeReadFromParcel() will either return mNativeObject, or
379ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            // create a new native Surface and return it after reducing
380ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            // the reference count on mNativeObject.  Either way, it is
381ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            // not necessary to call nativeRelease() here.
3827c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            mName = source.readString();
383fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source));
38486e1bc730570765355dc8789b5c6de6962a053ccMathias Agopian        }
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
38764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    @Override
38864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void writeToParcel(Parcel dest, int flags) {
38964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (dest == null) {
39064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("dest must not be null");
39164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
392fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
3937c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            dest.writeString(mName);
3947c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian            nativeWriteToParcel(mNativeObject, dest);
3957c116b54b743cc3e92ac42abdbbe324d63b50a81Mathias Agopian        }
39664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
39764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            release();
39864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
39964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
4000de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg
40164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    @Override
40264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public String toString() {
403fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        synchronized (mLock) {
404ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden            return "Surface(name=" + mName + ")/@0x" +
405ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden                    Integer.toHexString(System.identityHashCode(this));
406fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        }
407fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown    }
408fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
40936bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    private void setNativeObjectLocked(long ptr) {
410fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        if (mNativeObject != ptr) {
411fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            if (mNativeObject == 0 && ptr != 0) {
412fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                mCloseGuard.open("release");
413fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            } else if (mNativeObject != 0 && ptr == 0) {
414fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown                mCloseGuard.close();
415fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            }
416fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            mNativeObject = ptr;
417fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            mGenerationId += 1;
418fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        }
419fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown    }
420fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown
421fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown    private void checkNotReleasedLocked() {
422fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        if (mNativeObject == 0) {
423fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown            throw new IllegalStateException("Surface has already been released.");
424fc0ebd7d379ff63c00ebf78ca252fab5070213daJeff Brown        }
42564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
42664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
42764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
4285795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza     * Allocate buffers ahead of time to avoid allocation delays during rendering
4295795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza     * @hide
4305795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza     */
4315795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza    public void allocateBuffers() {
4325795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza        synchronized (mLock) {
4335795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza            checkNotReleasedLocked();
4345795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza            nativeAllocateBuffers(mNativeObject);
4355795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza        }
4365795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza    }
4375795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza
4385795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza    /**
439a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     * Exception thrown when a Canvas couldn't be locked with {@link Surface#lockCanvas}, or
440a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin     * when a SurfaceTexture could not successfully be allocated.
44164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
442a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin    @SuppressWarnings("serial")
443a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin    public static class OutOfResourcesException extends RuntimeException {
44464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public OutOfResourcesException() {
44564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
44664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public OutOfResourcesException(String name) {
44764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            super(name);
44864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
44964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
45064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
45164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
452152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     * Returns a human readable representation of a rotation.
453152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     *
454152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     * @param rotation The rotation.
455152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     * @return The rotation symbolic name.
456545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov     *
457545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov     * @hide
458152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     */
459152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov    public static String rotationToString(int rotation) {
460152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov        switch (rotation) {
461152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            case Surface.ROTATION_0: {
462152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                return "ROTATION_0";
463152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
464152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            case Surface.ROTATION_90: {
465152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                return "ROATATION_90";
466152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
467152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            case Surface.ROTATION_180: {
468152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                return "ROATATION_180";
469152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
470152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            case Surface.ROTATION_270: {
471152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                return "ROATATION_270";
472152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
473152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            default: {
474152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                throw new IllegalArgumentException("Invalid rotation: " + rotation);
475152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
476152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov        }
477152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov    }
478152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov
479152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov    /**
48064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * A Canvas class that can handle the compatibility mode.
48164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * This does two things differently.
48264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * <ul>
48364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * <li>Returns the width and height of the target metrics, rather than
48464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * native. For example, the canvas returns 320x480 even if an app is running
48564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * in WVGA high density.
48664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * <li>Scales the matrix in setMatrix by the application scale, except if
48764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * the matrix looks like obtained from getMatrix. This is a hack to handle
48864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * the case that an application uses getMatrix to keep the original matrix,
48964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * set matrix of its own, then set the original matrix back. There is no
49064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * perfect solution that works for all cases, and there are a lot of cases
49164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * that this model does not work, but we hope this works for many apps.
49264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * </ul>
49364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
49464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private final class CompatibleCanvas extends Canvas {
49564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        // A temp matrix to remember what an application obtained via {@link getMatrix}
49664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        private Matrix mOrigMatrix = null;
49764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
49864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        @Override
49964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public void setMatrix(Matrix matrix) {
50064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            if (mCompatibleMatrix == null || mOrigMatrix == null || mOrigMatrix.equals(matrix)) {
50164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                // don't scale the matrix if it's not compatibility mode, or
50264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                // the matrix was obtained from getMatrix.
50364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                super.setMatrix(matrix);
50464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            } else {
50564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                Matrix m = new Matrix(mCompatibleMatrix);
50664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                m.preConcat(matrix);
50764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                super.setMatrix(m);
50864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
50964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
51064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
5118b5aa4846939975adacd6ea1d2a57a2493ac0216Romain Guy        @SuppressWarnings("deprecation")
51264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        @Override
51364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public void getMatrix(Matrix m) {
51464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            super.getMatrix(m);
51564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            if (mOrigMatrix == null) {
516ed55c8db1c0d47492423fc54f4b0dd5cd585e593Andy McFadden                mOrigMatrix = new Matrix();
51764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
51864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            mOrigMatrix.set(m);
51964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
52064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
522