Surface.java revision 29479ebe1007361222bf6ab4d5e2a27927d4b8e8
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
19240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshimaimport android.content.res.CompatibilityInfo.Translator;
200b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brownimport android.graphics.Canvas;
210b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brownimport android.graphics.Matrix;
220b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brownimport android.graphics.Rect;
230b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brownimport android.graphics.SurfaceTexture;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel;
253866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopianimport android.os.Parcelable;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
273866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopianimport dalvik.system.CloseGuard;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
30334031cd07c3bd09d23fce0ebaf946fc6ecfee26Glenn Kasten * Handle onto a raw buffer that is being managed by the screen compositor.
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Surface implements Parcelable {
3364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private static final String TAG = "Surface";
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3529479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    private native int nativeCreateFromSurfaceTexture(SurfaceTexture surfaceTexture)
3629479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian            throws OutOfResourcesException;
3729479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    private native Canvas nativeLockCanvas(int nativeObject, Rect dirty);
3829479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    private native void nativeUnlockCanvasAndPost(int nativeObject, Canvas canvas);
3929479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
4029479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    private static native void nativeRelease(int nativeObject);
4129479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    private static native void nativeDestroy(int nativeObject);
4229479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    private static native boolean nativeIsValid(int nativeObject);
4329479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    private static native boolean nativeIsConsumerRunningBehind(int nativeObject);
4429479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    private static native int nativeCopyFrom(int nativeObject, int surfaceControlNativeObject);
4529479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    private static native int nativeReadFromParcel(int nativeObject, Parcel source);
4629479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    private static native void nativeWriteToParcel(int nativeObject, Parcel dest);
4729479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
4864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public static final Parcelable.Creator<Surface> CREATOR =
4964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            new Parcelable.Creator<Surface>() {
5064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public Surface createFromParcel(Parcel source) {
5164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            try {
5264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                Surface s = new Surface();
5364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                s.readFromParcel(source);
5464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                return s;
5564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            } catch (Exception e) {
5664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                Log.e(TAG, "Exception creating surface from parcel", e);
5764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                return null;
5864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
59b85c933d850286874005f97a9764c9b22e49a597Kevin Hester        }
6064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public Surface[] newArray(int size) {
6164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            return new Surface[size];
62df0c84f90894c677c50bdc967a0598f516ac86d7Jamie Gennis        }
6364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    };
64df0c84f90894c677c50bdc967a0598f516ac86d7Jamie Gennis
6564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private final CloseGuard mCloseGuard = CloseGuard.get();
6664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private String mName;
67c87c4a3e3b3c3949ae3c6f8fd245b71691d5ca3bMathias Agopian
6864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    // Note: These fields are accessed by native code.
690de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg    // The mSurfaceControl will only be present for Surfaces used by the window
700de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg    // server or system processes. When this class is parceled we defer to the
71b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    // mSurfaceControl to do the parceling. Otherwise we parcel the
72b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    // mNativeSurface.
733866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    int mNativeObject; // package scope only for SurfaceControl access
743866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian
7564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private int mGenerationId; // incremented each time mNativeSurface changes
7664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private final Canvas mCanvas = new CompatibleCanvas();
777c1a49f5f5ed6613d736464bf5001b777e89ced2Chris Craik    private int mCanvasSaveCount; // Canvas save count at time of lockCanvas()
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
795be8de3420ba4c9d816b98e29bdec11715f6b626Dianne Hackborn    // The Translator for density compatibility mode.  This is used for scaling
805be8de3420ba4c9d816b98e29bdec11715f6b626Dianne Hackborn    // the canvas to perform the appropriate density transformation.
815be8de3420ba4c9d816b98e29bdec11715f6b626Dianne Hackborn    private Translator mCompatibilityTranslator;
82240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima
83240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    // A matrix to scale the matrix set by application. This is set to null for
84240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    // non compatibility mode.
85240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    private Matrix mCompatibleMatrix;
8638ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
8929479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     * Rotation constant: 0 degree rotation (natural orientation)
9029479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     */
9129479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    public static final int ROTATION_0 = 0;
9229479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
9329479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    /**
9429479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     * Rotation constant: 90 degree rotation.
9529479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     */
9629479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    public static final int ROTATION_90 = 1;
9729479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
9829479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    /**
9929479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     * Rotation constant: 180 degree rotation.
10029479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     */
10129479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    public static final int ROTATION_180 = 2;
10229479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
10329479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    /**
10429479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     * Rotation constant: 270 degree rotation.
10529479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian     */
10629479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    public static final int ROTATION_270 = 3;
10729479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
10829479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
10929479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian
11029479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    /**
11164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Create an empty surface, which will later be filled in by readFromParcel().
11264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @hide
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public Surface() {
11564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        mCloseGuard.open("release");
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Create Surface from a {@link SurfaceTexture}.
12064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
12164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Images drawn to the Surface will be made available to the {@link
12264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * SurfaceTexture}, which can attach them to an OpenGL ES texture via {@link
12364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * SurfaceTexture#updateTexImage}.
12464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
12564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @param surfaceTexture The {@link SurfaceTexture} that is updated by this
12664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Surface.
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public Surface(SurfaceTexture surfaceTexture) {
12964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (surfaceTexture == null) {
13064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("surfaceTexture must not be null");
13164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
13264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
13364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        mName = surfaceTexture.toString();
13464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        try {
1353866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            mNativeObject = nativeCreateFromSurfaceTexture(surfaceTexture);
13664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        } catch (OutOfResourcesException ex) {
13764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            // We can't throw OutOfResourcesException because it would be an API change.
13864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new RuntimeException(ex);
139f5e32f33eddc6e22edee1df486b38294ddc76cc3Mathias Agopian        }
14064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
14164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        mCloseGuard.open("release");
142240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima    }
143240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima
1443866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    private Surface(int nativeObject) {
1453866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        mNativeObject = nativeObject;
1463866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        mCloseGuard.open("release");
1473866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    }
1483866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian
14964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    @Override
15064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    protected void finalize() throws Throwable {
15164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        try {
15264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            if (mCloseGuard != null) {
15364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                mCloseGuard.warnIfOpen();
15464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
1553866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            if (mNativeObject != 0) {
1563866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian                nativeRelease(mNativeObject);
1573866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            }
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() {
1693866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        if (mNativeObject != 0) {
1703866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            nativeRelease(mNativeObject);
1713866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            mNativeObject = 0;
1723866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        }
17364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        mCloseGuard.close();
17464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
17564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
17664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
17764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Free all server-side state associated with this surface and
17864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * release this object's reference.  This method can only be
17964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * called from the process that created the service.
180b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian     * @hide
181b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian     */
18264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void destroy() {
1833866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        if (mNativeObject != 0) {
1843866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            nativeDestroy(mNativeObject);
1853866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            mNativeObject = 0;
1863866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        }
18764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        mCloseGuard.close();
18864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
18961566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn
19061566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn    /**
19164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Returns true if this object holds a valid surface.
19264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
19364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @return True if it holds a physical surface, so lockCanvas() will succeed.
19464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Otherwise returns false.
19561566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn     */
19664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public boolean isValid() {
1973866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        if (mNativeObject == 0) return false;
1983866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        return nativeIsValid(mNativeObject);
19964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
20061566cc1932468720a831ad5cbc68ee080d613c9Dianne Hackborn
20164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
20264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Gets the generation number of this surface, incremented each time
20364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * the native surface contained within this object changes.
20464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
20564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @return The current generation number.
20664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @hide
20764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
208b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    public int getGenerationId() {
20964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        return mGenerationId;
210b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    }
211b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian
212c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian    /**
21364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Returns true if the consumer of this Surface is running behind the producer.
21464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
21564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @return True if the consumer is more than one buffer ahead of the producer.
216c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian     * @hide
217c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian     */
21864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public boolean isConsumerRunningBehind() {
2193866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        checkNotReleased();
2203866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        return nativeIsConsumerRunningBehind(mNativeObject);
22164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
222c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian
223b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian    /**
22464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Gets a {@link Canvas} for drawing into this surface.
22564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
22664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * After drawing into the provided {@link Canvas}, the caller should
22764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface.
22864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
22930d7ab9a10fcde397bae7bed5f16d1094fded8b2Mathias Agopian     * @param inOutDirty A rectangle that represents the dirty region that the caller wants
23064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * to redraw.  This function may choose to expand the dirty rectangle if for example
23164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * the surface has been resized or if the previous contents of the surface were
23264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * not available.  The caller should redraw the entire dirty region as represented
23364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * by the contents of the dirty rect upon return from this function.
23464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * The caller may also pass <code>null</code> instead, in the case where the
23564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * entire surface should be redrawn.
23664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @return A canvas for drawing into the surface.
237240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima     */
2383866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    public Canvas lockCanvas(Rect inOutDirty)
23964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throws OutOfResourcesException, IllegalArgumentException {
2403866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        checkNotReleased();
2413866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        return nativeLockCanvas(mNativeObject, inOutDirty);
24264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
243240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima
24464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
24564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Posts the new contents of the {@link Canvas} to the surface and
24664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * releases the {@link Canvas}.
24764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     *
24864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @param canvas The canvas previously obtained from {@link #lockCanvas}.
24964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
25064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void unlockCanvasAndPost(Canvas canvas) {
2513866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        checkNotReleased();
2523866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        nativeUnlockCanvasAndPost(mNativeObject, canvas);
25364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
254240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima
25564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
25664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @deprecated This API has been removed and is not supported.  Do not use.
25764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
25864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    @Deprecated
25964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void unlockCanvas(Canvas canvas) {
26064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        throw new UnsupportedOperationException();
261d10cd5765a2b706fc174f16b951d6b0a5d3740d3Romain Guy    }
26238ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima
26338ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima    /**
264b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian     * Sets the translator used to scale canvas's width/height in compatibility
265b923066deeffbbaad14a117bd56259bd6ee20a08Mathias Agopian     * mode.
26638ed7d7701514ee7127d0430e952930854608c4fMitsuru Oshima     */
2675be8de3420ba4c9d816b98e29bdec11715f6b626Dianne Hackborn    void setCompatibilityTranslator(Translator translator) {
268240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima        if (translator != null) {
269240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima            float appScale = translator.applicationScale;
270240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima            mCompatibleMatrix = new Matrix();
271240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima            mCompatibleMatrix.setScale(appScale, appScale);
272240f8a7532a024e36998bdbe87cff2ef080d75deMitsuru Oshima        }
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2759e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown
27664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
27764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Copy another surface to this one.  This surface now holds a reference
27864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * to the same data as the original surface, and is -not- the owner.
27964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * This is for use by the window manager when returning a window surface
28064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * back from a client, converting it from the representation being managed
28164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * by the window manager to the representation the client uses to draw
28264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * in to it.
28364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @hide
28464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
2853866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    public void copyFrom(SurfaceControl other) {
28664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (other == null) {
28764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("other must not be null");
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2893866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        if (other.mNativeObject == 0) {
2903866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            throw new NullPointerException(
2913866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian                    "SurfaceControl native object is null. Are you using a released SurfaceControl?");
29264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
2933866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        mNativeObject = nativeCopyFrom(mNativeObject, other.mNativeObject);
29464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
29564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
29664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
29764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Transfer the native state from 'other' to this surface, releasing it
29864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * from 'other'.  This is for use in the client side for drawing into a
29964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * surface; not guaranteed to work on the window manager side.
30064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * This is for use by the client to move the underlying surface from
30164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * one Surface object to another, in particular in SurfaceFlinger.
30264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * @hide.
30364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
30464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void transferFrom(Surface other) {
30564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (other == null) {
30664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("other must not be null");
30764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
30864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (other != this) {
3093866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            if (mNativeObject != 0) {
3103866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian                // release our reference to our native object
3113866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian                nativeRelease(mNativeObject);
3123866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            }
3133866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            // transfer the reference from other to us
3143866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            mNativeObject = other.mNativeObject;
3153866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            other.mNativeObject = 0;
31664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
31764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
32064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public int describeContents() {
32164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        return 0;
32264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
32364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
32464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void readFromParcel(Parcel source) {
32564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (source == null) {
32664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("source must not be null");
327f5e32f33eddc6e22edee1df486b38294ddc76cc3Mathias Agopian        }
32864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        mName = source.readString();
3293866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        mNativeObject = nativeReadFromParcel(mNativeObject, source);
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    @Override
33364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public void writeToParcel(Parcel dest, int flags) {
33464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (dest == null) {
33564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            throw new IllegalArgumentException("dest must not be null");
33664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
33764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        dest.writeString(mName);
3383866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        nativeWriteToParcel(mNativeObject, dest);
33964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
34064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            release();
34164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
34264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
3430de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg
34464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    @Override
34564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public String toString() {
346f9136fd9692158574d187af8d4031fa4b1e2b6e6Mathias Agopian        return "Surface(name=" + mName + ")";
34764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
34864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
34964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
35064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * Exception thrown when a surface couldn't be created or resized.
35164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
35264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    public static class OutOfResourcesException extends Exception {
35364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public OutOfResourcesException() {
35464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
35564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public OutOfResourcesException(String name) {
35664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            super(name);
35764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
35864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
35964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
36064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    /**
361152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     * Returns a human readable representation of a rotation.
362152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     *
363152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     * @param rotation The rotation.
364152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     * @return The rotation symbolic name.
365545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov     *
366545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov     * @hide
367152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov     */
368152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov    public static String rotationToString(int rotation) {
369152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov        switch (rotation) {
370152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            case Surface.ROTATION_0: {
371152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                return "ROTATION_0";
372152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
373152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            case Surface.ROTATION_90: {
374152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                return "ROATATION_90";
375152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
376152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            case Surface.ROTATION_180: {
377152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                return "ROATATION_180";
378152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
379152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            case Surface.ROTATION_270: {
380152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                return "ROATATION_270";
381152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
382152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            default: {
383152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov                throw new IllegalArgumentException("Invalid rotation: " + rotation);
384152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov            }
385152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov        }
386152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov    }
387152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov
388152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov    /**
38964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * A Canvas class that can handle the compatibility mode.
39064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * This does two things differently.
39164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * <ul>
39264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * <li>Returns the width and height of the target metrics, rather than
39364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * native. For example, the canvas returns 320x480 even if an app is running
39464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * in WVGA high density.
39564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * <li>Scales the matrix in setMatrix by the application scale, except if
39664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * the matrix looks like obtained from getMatrix. This is a hack to handle
39764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * the case that an application uses getMatrix to keep the original matrix,
39864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * set matrix of its own, then set the original matrix back. There is no
39964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * perfect solution that works for all cases, and there are a lot of cases
40064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * that this model does not work, but we hope this works for many apps.
40164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     * </ul>
40264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown     */
40364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    private final class CompatibleCanvas extends Canvas {
40464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        // A temp matrix to remember what an application obtained via {@link getMatrix}
40564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        private Matrix mOrigMatrix = null;
40664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
40764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        @Override
40864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public int getWidth() {
40964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            int w = super.getWidth();
41064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            if (mCompatibilityTranslator != null) {
41164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                w = (int)(w * mCompatibilityTranslator.applicationInvertedScale + .5f);
41264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
41364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            return w;
41464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
41564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
41664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        @Override
41764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public int getHeight() {
41864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            int h = super.getHeight();
41964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            if (mCompatibilityTranslator != null) {
42064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                h = (int)(h * mCompatibilityTranslator.applicationInvertedScale + .5f);
42164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
42264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            return h;
42364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
42464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
42564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        @Override
42664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public void setMatrix(Matrix matrix) {
42764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            if (mCompatibleMatrix == null || mOrigMatrix == null || mOrigMatrix.equals(matrix)) {
42864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                // don't scale the matrix if it's not compatibility mode, or
42964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                // the matrix was obtained from getMatrix.
43064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                super.setMatrix(matrix);
43164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            } else {
43264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                Matrix m = new Matrix(mCompatibleMatrix);
43364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                m.preConcat(matrix);
43464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                super.setMatrix(m);
43564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
43664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
43764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
43864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        @Override
43964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        public void getMatrix(Matrix m) {
44064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            super.getMatrix(m);
44164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            if (mOrigMatrix == null) {
44264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                mOrigMatrix = new Matrix();
44364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            }
44464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            mOrigMatrix.set(m);
44564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
44664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
4473866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian
4483866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    private void checkNotReleased() {
4493866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        if (mNativeObject == 0) throw new NullPointerException(
4503866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian                "mNativeObject is null. Have you called release() already?");
4513866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    }
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
453