Fix static analyzer warnings.

This patch fixes multiple static analyzer warnings:

frameworks/base/media/mca/filterfw/jni/jni_gl_environment.cpp:66:10:
warning: Potential memory leak
frameworks/base/media/mca/filterfw/jni/jni_native_frame.cpp:38:10:
warning: Potential memory leak
frameworks/base/media/mca/filterfw/jni/jni_native_program.cpp:31:10:
warning: Potential memory leak
frameworks/base/media/mca/filterfw/jni/jni_shader_program.cpp:50:12:
warning: Potential memory leak
frameworks/base/media/mca/filterfw/jni/jni_shader_program.cpp:57:12:
warning: Potential memory leak
frameworks/base/media/mca/filterfw/jni/jni_vertex_frame.cpp:27:10:
warning: Potential memory leak

Note that the changes in jni_gl_frame are purely cosmetic; those aren't
fixing any warnings. I'm happy to back them out if anyone wants.

Bug: None.
Test: All of the static analyzer warnings mentioned above are now gone.
Change-Id: I49dc6d7c789233d6497f8bcc766ca66aec72b27b
diff --git a/media/mca/filterfw/jni/jni_gl_environment.cpp b/media/mca/filterfw/jni/jni_gl_environment.cpp
index 096120e..823e88a 100644
--- a/media/mca/filterfw/jni/jni_gl_environment.cpp
+++ b/media/mca/filterfw/jni/jni_gl_environment.cpp
@@ -63,7 +63,8 @@
 };
 
 jboolean Java_android_filterfw_core_GLEnvironment_nativeAllocate(JNIEnv* env, jobject thiz) {
-  return ToJBool(WrapObjectInJava(new GLEnv(), env, thiz, true));
+  std::unique_ptr<GLEnv> glEnv(new GLEnv());
+  return ToJBool(WrapOwnedObjectInJava(std::move(glEnv), env, thiz, true));
 }
 
 jboolean Java_android_filterfw_core_GLEnvironment_nativeDeallocate(JNIEnv* env, jobject thiz) {
diff --git a/media/mca/filterfw/jni/jni_gl_frame.cpp b/media/mca/filterfw/jni/jni_gl_frame.cpp
index b55bc5d..27b4cd2 100644
--- a/media/mca/filterfw/jni/jni_gl_frame.cpp
+++ b/media/mca/filterfw/jni/jni_gl_frame.cpp
@@ -48,13 +48,11 @@
                                                            jint height) {
   GLEnv* gl_env_ptr = ConvertFromJava<GLEnv>(env, gl_env);
   if (!gl_env_ptr) return JNI_FALSE;
-  GLFrame* frame = new GLFrame(gl_env_ptr);
+  std::unique_ptr<GLFrame> frame(new GLFrame(gl_env_ptr));
   if (frame->Init(width, height)) {
-    return ToJBool(WrapObjectInJava(frame, env, thiz, true));
-  } else {
-    delete frame;
-    return JNI_FALSE;
+    return ToJBool(WrapOwnedObjectInJava(std::move(frame), env, thiz, true));
   }
+  return JNI_FALSE;
 }
 
 jboolean Java_android_filterfw_core_GLFrame_nativeAllocateWithTexture(JNIEnv* env,
@@ -65,13 +63,11 @@
                                                                       jint height) {
   GLEnv* gl_env_ptr = ConvertFromJava<GLEnv>(env, gl_env);
   if (!gl_env_ptr) return JNI_FALSE;
-  GLFrame* frame = new GLFrame(gl_env_ptr);
+  std::unique_ptr<GLFrame> frame(new GLFrame(gl_env_ptr));
   if (frame->InitWithTexture(tex_id, width, height)) {
-    return ToJBool(WrapObjectInJava(frame, env, thiz, true));
-  } else {
-    delete frame;
-    return JNI_FALSE;
+    return ToJBool(WrapOwnedObjectInJava(std::move(frame), env, thiz, true));
   }
+  return JNI_FALSE;
 }
 
 jboolean Java_android_filterfw_core_GLFrame_nativeAllocateWithFbo(JNIEnv* env,
@@ -82,13 +78,11 @@
                                                                   jint height) {
   GLEnv* gl_env_ptr = ConvertFromJava<GLEnv>(env, gl_env);
   if (!gl_env_ptr) return JNI_FALSE;
-  GLFrame* frame = new GLFrame(gl_env_ptr);
+  std::unique_ptr<GLFrame> frame(new GLFrame(gl_env_ptr));
   if (frame->InitWithFbo(fbo_id, width, height)) {
-    return ToJBool(WrapObjectInJava(frame, env, thiz, true));
-  } else {
-    delete frame;
-    return JNI_FALSE;
+    return ToJBool(WrapOwnedObjectInJava(std::move(frame), env, thiz, true));
   }
+  return JNI_FALSE;
 }
 
 jboolean Java_android_filterfw_core_GLFrame_nativeAllocateExternal(JNIEnv* env,
@@ -96,13 +90,11 @@
                                                                    jobject gl_env) {
   GLEnv* gl_env_ptr = ConvertFromJava<GLEnv>(env, gl_env);
   if (!gl_env_ptr) return JNI_FALSE;
-  GLFrame* frame = new GLFrame(gl_env_ptr);
+  std::unique_ptr<GLFrame> frame(new GLFrame(gl_env_ptr));
   if (frame->InitWithExternalTexture()) {
-    return ToJBool(WrapObjectInJava(frame, env, thiz, true));
-  } else {
-    delete frame;
-    return JNI_FALSE;
+    return ToJBool(WrapOwnedObjectInJava(std::move(frame), env, thiz, true));
   }
+  return JNI_FALSE;
 }
 
 jboolean Java_android_filterfw_core_GLFrame_nativeDeallocate(JNIEnv* env, jobject thiz) {
diff --git a/media/mca/filterfw/jni/jni_native_frame.cpp b/media/mca/filterfw/jni/jni_native_frame.cpp
index c8f2352..1a11a19 100644
--- a/media/mca/filterfw/jni/jni_native_frame.cpp
+++ b/media/mca/filterfw/jni/jni_native_frame.cpp
@@ -35,7 +35,8 @@
 jboolean Java_android_filterfw_core_NativeFrame_nativeAllocate(JNIEnv* env,
                                                                jobject thiz,
                                                                jint size) {
-  return ToJBool(WrapObjectInJava(new NativeFrame(size), env, thiz, true));
+  std::unique_ptr<NativeFrame> frame(new NativeFrame(size));
+  return ToJBool(WrapOwnedObjectInJava(std::move(frame), env, thiz, true));
 }
 
 jboolean Java_android_filterfw_core_NativeFrame_nativeDeallocate(JNIEnv* env, jobject thiz) {
diff --git a/media/mca/filterfw/jni/jni_native_program.cpp b/media/mca/filterfw/jni/jni_native_program.cpp
index b30b769..1424607 100644
--- a/media/mca/filterfw/jni/jni_native_program.cpp
+++ b/media/mca/filterfw/jni/jni_native_program.cpp
@@ -28,7 +28,8 @@
 using android::filterfw::NativeProgram;
 
 jboolean Java_android_filterfw_core_NativeProgram_allocate(JNIEnv* env, jobject thiz) {
-  return ToJBool(WrapObjectInJava(new NativeProgram(), env, thiz, true));
+  std::unique_ptr<NativeProgram> program(new NativeProgram());
+  return ToJBool(WrapOwnedObjectInJava(std::move(program), env, thiz, true));
 }
 
 jboolean Java_android_filterfw_core_NativeProgram_deallocate(JNIEnv* env, jobject thiz) {
diff --git a/media/mca/filterfw/jni/jni_shader_program.cpp b/media/mca/filterfw/jni/jni_shader_program.cpp
index 19f43cd..98be04c 100644
--- a/media/mca/filterfw/jni/jni_shader_program.cpp
+++ b/media/mca/filterfw/jni/jni_shader_program.cpp
@@ -46,21 +46,14 @@
   // Create the shader
   if (!fragment_shader || !gl_env_ptr)
     return false;
-  else if (!vertex_shader)
-    return ToJBool(WrapObjectInJava(new ShaderProgram(
-      gl_env_ptr,
-      ToCppString(env, fragment_shader)),
-      env,
-      thiz,
-      true));
+
+  std::unique_ptr<ShaderProgram> shader;
+  if (!vertex_shader)
+    shader.reset(new ShaderProgram(gl_env_ptr, ToCppString(env, fragment_shader)));
   else
-    return ToJBool(WrapObjectInJava(new ShaderProgram(
-      gl_env_ptr,
-      ToCppString(env, vertex_shader),
-      ToCppString(env, fragment_shader)),
-      env,
-      thiz,
-      true));
+    shader.reset(new ShaderProgram(gl_env_ptr, ToCppString(env, vertex_shader),
+                                   ToCppString(env, fragment_shader)));
+  return ToJBool(WrapOwnedObjectInJava(std::move(shader), env, thiz, true));
 }
 
 jboolean Java_android_filterfw_core_ShaderProgram_deallocate(JNIEnv* env, jobject thiz) {
diff --git a/media/mca/filterfw/jni/jni_util.h b/media/mca/filterfw/jni/jni_util.h
index 11c0871..803ed29 100644
--- a/media/mca/filterfw/jni/jni_util.h
+++ b/media/mca/filterfw/jni/jni_util.h
@@ -16,6 +16,7 @@
 
 #include <jni.h>
 
+#include <memory>
 #include <unordered_map>
 #include <string>
 
@@ -214,6 +215,17 @@
   return pool ? pool->WrapObject(c_object, env, j_object, owns) : false;
 }
 
+// Calls WrapObjectInJava, safely freeing c_object if object creation fails.
+template<typename T>
+bool WrapOwnedObjectInJava(std::unique_ptr<T> c_object, JNIEnv* env,
+                           jobject j_object, bool owns) {
+  if (!WrapObjectInJava<T>(c_object.get(), env, j_object, owns))
+    return false;
+  // If we succeeded, a Java object now owns our c object; don't free it.
+  c_object.release();
+  return true;
+}
+
 // Creates a new Java instance, which wraps the passed C++ instance. Returns
 // the wrapped object or JNI_NULL if there was an error. Pass true to owns, if
 // the Java layer should own the object.
diff --git a/media/mca/filterfw/jni/jni_vertex_frame.cpp b/media/mca/filterfw/jni/jni_vertex_frame.cpp
index caae938..d0439fe 100644
--- a/media/mca/filterfw/jni/jni_vertex_frame.cpp
+++ b/media/mca/filterfw/jni/jni_vertex_frame.cpp
@@ -24,7 +24,8 @@
 jboolean Java_android_filterfw_core_VertexFrame_nativeAllocate(JNIEnv* env,
                                                                jobject thiz,
                                                                jint size) {
-  return ToJBool(WrapObjectInJava(new VertexFrame(size), env, thiz, true));
+  std::unique_ptr<VertexFrame> frame(new VertexFrame(size));
+  return ToJBool(WrapOwnedObjectInJava(std::move(frame), env, thiz, true));
 }
 
 jboolean Java_android_filterfw_core_VertexFrame_nativeDeallocate(JNIEnv* env, jobject thiz) {