Merge "Media JNI code cleanup"
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index 27b37b7..a219623 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -34,11 +34,11 @@
 
 struct fields_t {
     jfieldID context;
-    jclass bitmapClazz;
+    jclass bitmapClazz;  // Must be a global ref
     jfieldID nativeBitmap;
     jmethodID createBitmapMethod;
     jmethodID createScaledBitmapMethod;
-    jclass configClazz;
+    jclass configClazz;  // Must be a global ref
     jmethodID createConfigMethod;
 };
 
@@ -120,33 +120,71 @@
     if (headers) {
         // Get the Map's entry Set.
         jclass mapClass = env->FindClass("java/util/Map");
+        if (mapClass == NULL) {
+            return;
+        }
 
         jmethodID entrySet =
             env->GetMethodID(mapClass, "entrySet", "()Ljava/util/Set;");
+        if (entrySet == NULL) {
+            return;
+        }
 
         jobject set = env->CallObjectMethod(headers, entrySet);
+        if (set == NULL) {
+            return;
+        }
+
         // Obtain an iterator over the Set
         jclass setClass = env->FindClass("java/util/Set");
+        if (setClass == NULL) {
+            return;
+        }
 
         jmethodID iterator =
             env->GetMethodID(setClass, "iterator", "()Ljava/util/Iterator;");
+        if (iterator == NULL) {
+            return;
+        }
 
         jobject iter = env->CallObjectMethod(set, iterator);
+        if (iter == NULL) {
+            return;
+        }
+
         // Get the Iterator method IDs
         jclass iteratorClass = env->FindClass("java/util/Iterator");
+        if (iteratorClass == NULL) {
+            return;
+        }
         jmethodID hasNext = env->GetMethodID(iteratorClass, "hasNext", "()Z");
+        if (hasNext == NULL) {
+            return;
+        }
 
         jmethodID next =
             env->GetMethodID(iteratorClass, "next", "()Ljava/lang/Object;");
+        if (next == NULL) {
+            return;
+        }
 
         // Get the Entry class method IDs
         jclass entryClass = env->FindClass("java/util/Map$Entry");
+        if (entryClass == NULL) {
+            return;
+        }
 
         jmethodID getKey =
             env->GetMethodID(entryClass, "getKey", "()Ljava/lang/Object;");
+        if (getKey == NULL) {
+            return;
+        }
 
         jmethodID getValue =
             env->GetMethodID(entryClass, "getValue", "()Ljava/lang/Object;");
+        if (getValue == NULL) {
+            return;
+        }
 
         // Iterate over the entry Set
         while (env->CallBooleanMethod(iter, hasNext)) {
@@ -161,6 +199,7 @@
 
             const char* valueStr = env->GetStringUTFChars(value, NULL);
             if (!valueStr) {  // Out of memory
+                env->ReleaseStringUTFChars(key, keyStr);
                 return;
             }
 
@@ -171,14 +210,8 @@
             env->DeleteLocalRef(key);
             env->ReleaseStringUTFChars(value, valueStr);
             env->DeleteLocalRef(value);
-      }
+        }
 
-      env->DeleteLocalRef(entryClass);
-      env->DeleteLocalRef(iteratorClass);
-      env->DeleteLocalRef(iter);
-      env->DeleteLocalRef(setClass);
-      env->DeleteLocalRef(set);
-      env->DeleteLocalRef(mapClass);
     }
 
     process_media_retriever_call(
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 0f9cbec..ecbd288 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -1,4 +1,4 @@
-/* //device/libs/android_runtime/android_media_MediaPlayer.cpp
+/*
 **
 ** Copyright 2007, The Android Open Source Project
 **
@@ -185,45 +185,87 @@
         return;
     }
 
-    const char *pathStr = env->GetStringUTFChars(path, NULL);
-    if (pathStr == NULL) {  // Out of memory
-        jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
+    const char *tmp = env->GetStringUTFChars(path, NULL);
+    if (tmp == NULL) {  // Out of memory
         return;
     }
 
+    String8 pathStr(tmp);
+    env->ReleaseStringUTFChars(path, tmp);
+    tmp = NULL;
+
     // headers is a Map<String, String>.
     // We build a similar KeyedVector out of it.
     KeyedVector<String8, String8> headersVector;
     if (headers) {
         // Get the Map's entry Set.
         jclass mapClass = env->FindClass("java/util/Map");
+        if (mapClass == NULL) {
+            return;
+        }
 
         jmethodID entrySet =
             env->GetMethodID(mapClass, "entrySet", "()Ljava/util/Set;");
+        if (entrySet == NULL) {
+            return;
+        }
 
         jobject set = env->CallObjectMethod(headers, entrySet);
+        if (set == NULL) {
+            return;
+        }
+
         // Obtain an iterator over the Set
         jclass setClass = env->FindClass("java/util/Set");
+        if (setClass == NULL) {
+            return;
+        }
 
         jmethodID iterator =
             env->GetMethodID(setClass, "iterator", "()Ljava/util/Iterator;");
+        if (iterator == NULL) {
+            return;
+        }
 
         jobject iter = env->CallObjectMethod(set, iterator);
+        if (iter == NULL) {
+            return;
+        }
+
         // Get the Iterator method IDs
         jclass iteratorClass = env->FindClass("java/util/Iterator");
+        if (iteratorClass == NULL) {
+            return;
+        }
+
         jmethodID hasNext = env->GetMethodID(iteratorClass, "hasNext", "()Z");
+        if (hasNext == NULL) {
+            return;
+        }
 
         jmethodID next =
             env->GetMethodID(iteratorClass, "next", "()Ljava/lang/Object;");
+        if (next == NULL) {
+            return;
+        }
 
         // Get the Entry class method IDs
         jclass entryClass = env->FindClass("java/util/Map$Entry");
+        if (entryClass == NULL) {
+            return;
+        }
 
         jmethodID getKey =
             env->GetMethodID(entryClass, "getKey", "()Ljava/lang/Object;");
+        if (getKey == NULL) {
+            return;
+        }
 
         jmethodID getValue =
             env->GetMethodID(entryClass, "getValue", "()Ljava/lang/Object;");
+        if (getValue == NULL) {
+            return;
+        }
 
         // Iterate over the entry Set
         while (env->CallBooleanMethod(iter, hasNext)) {
@@ -233,15 +275,12 @@
 
             const char* keyStr = env->GetStringUTFChars(key, NULL);
             if (!keyStr) {  // Out of memory
-                jniThrowException(
-                        env, "java/lang/RuntimeException", "Out of memory");
                 return;
             }
 
             const char* valueStr = env->GetStringUTFChars(value, NULL);
             if (!valueStr) {  // Out of memory
-                jniThrowException(
-                        env, "java/lang/RuntimeException", "Out of memory");
+                env->ReleaseStringUTFChars(key, keyStr);
                 return;
             }
 
@@ -252,25 +291,16 @@
             env->DeleteLocalRef(key);
             env->ReleaseStringUTFChars(value, valueStr);
             env->DeleteLocalRef(value);
-      }
+        }
 
-      env->DeleteLocalRef(entryClass);
-      env->DeleteLocalRef(iteratorClass);
-      env->DeleteLocalRef(iter);
-      env->DeleteLocalRef(setClass);
-      env->DeleteLocalRef(set);
-      env->DeleteLocalRef(mapClass);
     }
 
     LOGV("setDataSource: path %s", pathStr);
     status_t opStatus =
         mp->setDataSource(
-                String8(pathStr),
+                pathStr,
                 headers ? &headersVector : NULL);
 
-    // Make sure that local ref is released before a potential exception
-    env->ReleaseStringUTFChars(path, pathStr);
-
     process_media_player_call(
             env, thiz, opStatus, "java/io/IOException",
             "setDataSource failed." );
@@ -628,62 +658,49 @@
 
     clazz = env->FindClass("android/media/MediaPlayer");
     if (clazz == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException", "Can't find android/media/MediaPlayer");
         return;
     }
 
     fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
     if (fields.context == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaPlayer.mNativeContext");
         return;
     }
 
     fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
                                                "(Ljava/lang/Object;IIILjava/lang/Object;)V");
     if (fields.post_event == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaPlayer.postEventFromNative");
         return;
     }
 
     fields.surface = env->GetFieldID(clazz, "mSurface", "Landroid/view/Surface;");
     if (fields.surface == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaPlayer.mSurface");
         return;
     }
 
     jclass surface = env->FindClass("android/view/Surface");
     if (surface == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException", "Can't find android/view/Surface");
         return;
     }
 
     fields.surface_native = env->GetFieldID(surface, ANDROID_VIEW_SURFACE_JNI_ID, "I");
     if (fields.surface_native == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException",
-                "Can't find Surface." ANDROID_VIEW_SURFACE_JNI_ID);
         return;
     }
 
     fields.surfaceTexture = env->GetFieldID(clazz, "mSurfaceTexture",
             "Landroid/graphics/SurfaceTexture;");
     if (fields.surfaceTexture == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException",
-                "Can't find MediaPlayer.mSurfaceTexture");
         return;
     }
 
     jclass surfaceTexture = env->FindClass("android/graphics/SurfaceTexture");
     if (surfaceTexture == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException",
-                "Can't find android/graphics/SurfaceTexture");
         return;
     }
 
     fields.surfaceTexture_native = env->GetFieldID(surfaceTexture,
             ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID, "I");
     if (fields.surfaceTexture_native == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException",
-                "Can't find SurfaceTexture." ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID);
         return;
     }
 
diff --git a/media/jni/android_media_MediaScanner.cpp b/media/jni/android_media_MediaScanner.cpp
index 9d7bf2c..06058dc 100644
--- a/media/jni/android_media_MediaScanner.cpp
+++ b/media/jni/android_media_MediaScanner.cpp
@@ -213,7 +213,6 @@
 
     const char *pathStr = env->GetStringUTFChars(path, NULL);
     if (pathStr == NULL) {  // Out of memory
-        jniThrowException(env, kRunTimeException, "Out of memory");
         return;
     }
 
@@ -243,15 +242,14 @@
 
     const char *pathStr = env->GetStringUTFChars(path, NULL);
     if (pathStr == NULL) {  // Out of memory
-        jniThrowException(env, kRunTimeException, "Out of memory");
         return;
     }
 
     const char *mimeTypeStr =
         (mimeType ? env->GetStringUTFChars(mimeType, NULL) : NULL);
     if (mimeType && mimeTypeStr == NULL) {  // Out of memory
+        // ReleaseStringUTFChars can be called with an exception pending.
         env->ReleaseStringUTFChars(path, pathStr);
-        jniThrowException(env, kRunTimeException, "Out of memory");
         return;
     }
 
@@ -281,7 +279,6 @@
     }
     const char *localeStr = env->GetStringUTFChars(locale, NULL);
     if (localeStr == NULL) {  // Out of memory
-        jniThrowException(env, kRunTimeException, "Out of memory");
         return;
     }
     mp->setLocale(localeStr);