Merge "Update HardwareBuffer API." into oc-dev am: 649040c7f6
am: d5fcb3a45f

Change-Id: I14b0606c3d7866f68f7b0e7a7458bb4af4236d0e
diff --git a/api/current.txt b/api/current.txt
index 016da25..4a72fd9 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -14754,16 +14754,16 @@
     method public float getZ();
   }
 
-  public final class HardwareBuffer implements android.os.Parcelable {
+  public final class HardwareBuffer implements java.lang.AutoCloseable android.os.Parcelable {
+    method public void close();
     method public static android.hardware.HardwareBuffer create(int, int, int, int, long);
     method public int describeContents();
-    method public void destroy();
     method public int getFormat();
     method public int getHeight();
     method public int getLayers();
     method public long getUsage();
     method public int getWidth();
-    method public boolean isDestroyed();
+    method public boolean isClosed();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int BLOB = 33; // 0x21
     field public static final android.os.Parcelable.Creator<android.hardware.HardwareBuffer> CREATOR;
diff --git a/api/removed.txt b/api/removed.txt
index 189536d..dc9c54e 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -126,6 +126,11 @@
 
 package android.hardware {
 
+  public final class HardwareBuffer implements java.lang.AutoCloseable android.os.Parcelable {
+    method public deprecated void destroy();
+    method public deprecated boolean isDestroyed();
+  }
+
   public final class SensorDirectChannel implements java.nio.channels.Channel {
     method public deprecated boolean isValid();
   }
diff --git a/api/system-current.txt b/api/system-current.txt
index d14c0d9..f954a78 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -15528,16 +15528,16 @@
     method public float getZ();
   }
 
-  public final class HardwareBuffer implements android.os.Parcelable {
+  public final class HardwareBuffer implements java.lang.AutoCloseable android.os.Parcelable {
+    method public void close();
     method public static android.hardware.HardwareBuffer create(int, int, int, int, long);
     method public int describeContents();
-    method public void destroy();
     method public int getFormat();
     method public int getHeight();
     method public int getLayers();
     method public long getUsage();
     method public int getWidth();
-    method public boolean isDestroyed();
+    method public boolean isClosed();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int BLOB = 33; // 0x21
     field public static final android.os.Parcelable.Creator<android.hardware.HardwareBuffer> CREATOR;
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 559ce12..4862bb7 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -124,6 +124,11 @@
 
 package android.hardware {
 
+  public final class HardwareBuffer implements java.lang.AutoCloseable android.os.Parcelable {
+    method public deprecated void destroy();
+    method public deprecated boolean isDestroyed();
+  }
+
   public final class SensorDirectChannel implements java.nio.channels.Channel {
     method public deprecated boolean isValid();
   }
diff --git a/api/test-current.txt b/api/test-current.txt
index a241be6..e780d83 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -14799,16 +14799,16 @@
     method public float getZ();
   }
 
-  public final class HardwareBuffer implements android.os.Parcelable {
+  public final class HardwareBuffer implements java.lang.AutoCloseable android.os.Parcelable {
+    method public void close();
     method public static android.hardware.HardwareBuffer create(int, int, int, int, long);
     method public int describeContents();
-    method public void destroy();
     method public int getFormat();
     method public int getHeight();
     method public int getLayers();
     method public long getUsage();
     method public int getWidth();
-    method public boolean isDestroyed();
+    method public boolean isClosed();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int BLOB = 33; // 0x21
     field public static final android.os.Parcelable.Creator<android.hardware.HardwareBuffer> CREATOR;
diff --git a/api/test-removed.txt b/api/test-removed.txt
index 189536d..dc9c54e 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -126,6 +126,11 @@
 
 package android.hardware {
 
+  public final class HardwareBuffer implements java.lang.AutoCloseable android.os.Parcelable {
+    method public deprecated void destroy();
+    method public deprecated boolean isDestroyed();
+  }
+
   public final class SensorDirectChannel implements java.nio.channels.Channel {
     method public deprecated boolean isValid();
   }
diff --git a/core/java/android/hardware/HardwareBuffer.java b/core/java/android/hardware/HardwareBuffer.java
index 7b09e26..9d217d3 100644
--- a/core/java/android/hardware/HardwareBuffer.java
+++ b/core/java/android/hardware/HardwareBuffer.java
@@ -22,6 +22,7 @@
 import android.os.Parcelable;
 
 import dalvik.annotation.optimization.FastNative;
+import dalvik.system.CloseGuard;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -37,7 +38,7 @@
  *
  * For more information, see the NDK documentation for <code>AHardwareBuffer</code>.
  */
-public final class HardwareBuffer implements Parcelable {
+public final class HardwareBuffer implements Parcelable, AutoCloseable {
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({RGBA_8888, RGBA_FP16, RGBA_1010102, RGBX_8888, RGB_888, RGB_565, BLOB})
@@ -65,6 +66,8 @@
     // Invoked on destruction
     private Runnable mCleaner;
 
+    private final CloseGuard mCloseGuard = CloseGuard.get();
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(flag = true, value = {USAGE0_CPU_READ, USAGE0_CPU_READ_OFTEN, USAGE0_CPU_WRITE,
@@ -163,14 +166,25 @@
         NativeAllocationRegistry registry = new NativeAllocationRegistry(
                 loader, nGetNativeFinalizer(), NATIVE_HARDWARE_BUFFER_SIZE);
         mCleaner = registry.registerNativeAllocation(this, mNativeObject);
+        mCloseGuard.open("close");
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            mCloseGuard.warnIfOpen();
+            close();
+        } finally {
+            super.finalize();
+        }
     }
 
     /**
      * Returns the width of this buffer in pixels.
      */
     public int getWidth() {
-        if (mNativeObject == 0) {
-            throw new IllegalStateException("This HardwareBuffer has been destroyed and its width "
+        if (isClosed()) {
+            throw new IllegalStateException("This HardwareBuffer has been closed and its width "
                     + "cannot be obtained.");
         }
         return nGetWidth(mNativeObject);
@@ -180,8 +194,8 @@
      * Returns the height of this buffer in pixels.
      */
     public int getHeight() {
-        if (mNativeObject == 0) {
-            throw new IllegalStateException("This HardwareBuffer has been destroyed and its height "
+        if (isClosed()) {
+            throw new IllegalStateException("This HardwareBuffer has been closed and its height "
                     + "cannot be obtained.");
         }
         return nGetHeight(mNativeObject);
@@ -193,8 +207,8 @@
      */
     @Format
     public int getFormat() {
-        if (mNativeObject == 0) {
-            throw new IllegalStateException("This HardwareBuffer has been destroyed and its format "
+        if (isClosed()) {
+            throw new IllegalStateException("This HardwareBuffer has been closed and its format "
                     + "cannot be obtained.");
         }
         return nGetFormat(mNativeObject);
@@ -204,8 +218,8 @@
      * Returns the number of layers in this buffer.
      */
     public int getLayers() {
-        if (mNativeObject == 0) {
-            throw new IllegalStateException("This HardwareBuffer has been destroyed and its layer "
+        if (isClosed()) {
+            throw new IllegalStateException("This HardwareBuffer has been closed and its layer "
                     + "count cannot be obtained.");
         }
         return nGetLayers(mNativeObject);
@@ -215,22 +229,36 @@
      * Returns the usage flags of the usage hints set on this buffer.
      */
     public long getUsage() {
-        if (mNativeObject == 0) {
-            throw new IllegalStateException("This HardwareBuffer has been destroyed and its usage "
+        if (isClosed()) {
+            throw new IllegalStateException("This HardwareBuffer has been closed and its usage "
                     + "cannot be obtained.");
         }
         return nGetUsage(mNativeObject);
     }
 
+    /** @removed replaced by {@link #close()} */
+    @Deprecated
+    public void destroy() {
+        close();
+    }
+
+    /** @removed replaced by {@link #isClosed()} */
+    @Deprecated
+    public boolean isDestroyed() {
+        return isClosed();
+    }
+
     /**
      * Destroys this buffer immediately. Calling this method frees up any
      * underlying native resources. After calling this method, this buffer
      * must not be used in any way.
      *
-     * @see #isDestroyed()
+     * @see #isClosed()
      */
-    public void destroy() {
-        if (mNativeObject != 0) {
+    @Override
+    public void close() {
+        if (!isClosed()) {
+            mCloseGuard.close();
             mNativeObject = 0;
             mCleaner.run();
             mCleaner = null;
@@ -238,15 +266,15 @@
     }
 
     /**
-     * Indicates whether this buffer has been destroyed. A destroyed buffer
-     * cannot be used in any way: the buffer cannot be written to a parcel, etc.
+     * Indicates whether this buffer has been closed. A closed buffer cannot
+     * be used in any way: the buffer cannot be written to a parcel, etc.
      *
-     * @return True if this <code>HardwareBuffer</code> is in a destroyed state,
+     * @return True if this <code>HardwareBuffer</code> is in a closed state,
      *         false otherwise.
      *
-     * @see #destroy()
+     * @see #close()
      */
-    public boolean isDestroyed() {
+    public boolean isClosed() {
         return mNativeObject == 0;
     }
 
@@ -259,7 +287,7 @@
      * Flatten this object in to a Parcel.
      *
      * <p>Calling this method will throw an <code>IllegalStateException</code> if
-     * {@link #destroy()} has been previously called.</p>
+     * {@link #close()} has been previously called.</p>
      *
      * @param dest The Parcel in which the object should be written.
      * @param flags Additional flags about how the object should be written.
@@ -267,8 +295,8 @@
      */
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-        if (mNativeObject == 0) {
-            throw new IllegalStateException("This HardwareBuffer has been destroyed and cannot be "
+        if (isClosed()) {
+            throw new IllegalStateException("This HardwareBuffer has been closed and cannot be "
                     + "written to a parcel.");
         }
         nWriteHardwareBufferToParcel(mNativeObject, dest);