Use jniThrowException for exception throwing from native code.

I'll do media and the generated gl stuff separately. Otherwise, this
cleans up all direct calls of ThrowNew/Throw except the one in the
binder that needs to remain.

Change-Id: I8f95a5f020f53b25926ad31ac0c9477ddf85d04b
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 6fedde2..233167f 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -1,6 +1,7 @@
 #define LOG_TAG "GraphicsJNI"
 
 #include "jni.h"
+#include "JNIHelp.h"
 #include "GraphicsJNI.h"
 
 #include "SkCanvas.h"
@@ -9,44 +10,32 @@
 #include "SkRegion.h"
 #include <android_runtime/AndroidRuntime.h>
 
-void doThrow(JNIEnv* env, const char* exc, const char* msg) {
-    // don't throw a new exception if we already have one pending
-    if (env->ExceptionCheck() == JNI_FALSE) {
-        jclass npeClazz;
-        
-        npeClazz = env->FindClass(exc);
-        LOG_FATAL_IF(npeClazz == NULL, "Unable to find class %s", exc);
-        
-        env->ThrowNew(npeClazz, msg);
-    }
-}
-
 void doThrowNPE(JNIEnv* env) {
-    doThrow(env, "java/lang/NullPointerException");
+    jniThrowException(env, "java/lang/NullPointerException", NULL);
 }
 
 void doThrowAIOOBE(JNIEnv* env) {
-    doThrow(env, "java/lang/ArrayIndexOutOfBoundsException");
+    jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL);
 }
 
 void doThrowRE(JNIEnv* env, const char* msg) {
-    doThrow(env, "java/lang/RuntimeException", msg);
+    jniThrowException(env, "java/lang/RuntimeException", msg);
 }
 
 void doThrowIAE(JNIEnv* env, const char* msg) {
-    doThrow(env, "java/lang/IllegalArgumentException", msg);
+    jniThrowException(env, "java/lang/IllegalArgumentException", msg);
 }
 
 void doThrowISE(JNIEnv* env, const char* msg) {
-    doThrow(env, "java/lang/IllegalStateException", msg);
+    jniThrowException(env, "java/lang/IllegalStateException", msg);
 }
 
 void doThrowOOME(JNIEnv* env, const char* msg) {
-    doThrow(env, "java/lang/OutOfMemoryError", msg);
+    jniThrowException(env, "java/lang/OutOfMemoryError", msg);
 }
 
 void doThrowIOE(JNIEnv* env, const char* msg) {
-    doThrow(env, "java/io/IOException", msg);
+    jniThrowException(env, "java/io/IOException", msg);
 }
 
 bool GraphicsJNI::hasException(JNIEnv *env) {
@@ -229,7 +218,7 @@
 SkRect* GraphicsJNI::jrectf_to_rect(JNIEnv* env, jobject obj, SkRect* r)
 {
     SkASSERT(env->IsInstanceOf(obj, gRectF_class));
-    
+
     r->set(SkFloatToScalar(env->GetFloatField(obj, gRectF_leftFieldID)),
            SkFloatToScalar(env->GetFloatField(obj, gRectF_topFieldID)),
            SkFloatToScalar(env->GetFloatField(obj, gRectF_rightFieldID)),
@@ -240,7 +229,7 @@
 SkRect* GraphicsJNI::jrect_to_rect(JNIEnv* env, jobject obj, SkRect* r)
 {
     SkASSERT(env->IsInstanceOf(obj, gRect_class));
-    
+
     r->set(SkIntToScalar(env->GetIntField(obj, gRect_leftFieldID)),
            SkIntToScalar(env->GetIntField(obj, gRect_topFieldID)),
            SkIntToScalar(env->GetIntField(obj, gRect_rightFieldID)),
@@ -261,7 +250,7 @@
 SkIPoint* GraphicsJNI::jpoint_to_ipoint(JNIEnv* env, jobject obj, SkIPoint* point)
 {
     SkASSERT(env->IsInstanceOf(obj, gPoint_class));
-    
+
     point->set(env->GetIntField(obj, gPoint_xFieldID),
                env->GetIntField(obj, gPoint_yFieldID));
     return point;
@@ -278,7 +267,7 @@
 SkPoint* GraphicsJNI::jpointf_to_point(JNIEnv* env, jobject obj, SkPoint* point)
 {
     SkASSERT(env->IsInstanceOf(obj, gPointF_class));
-        
+
     point->set(SkFloatToScalar(env->GetIntField(obj, gPointF_xFieldID)),
                SkFloatToScalar(env->GetIntField(obj, gPointF_yFieldID)));
     return point;
@@ -360,7 +349,7 @@
 {
     SkASSERT(bitmap);
     SkASSERT(bitmap->pixelRef());
-    
+
     jobject obj = env->AllocObject(gBitmap_class);
     if (obj) {
         env->CallVoidMethod(obj, gBitmap_constructorMethodID,
@@ -438,7 +427,7 @@
 
     // If storageObj is NULL, the memory was NOT allocated on the Java heap
     fOnJavaHeap = (storageObj != NULL);
-    
+
 }
 
 AndroidPixelRef::~AndroidPixelRef() {
@@ -508,11 +497,11 @@
                                              SkColorTable* ctable) {
     Sk64 size64 = bitmap->getSize64();
     if (size64.isNeg() || !size64.is32()) {
-        doThrow(env, "java/lang/IllegalArgumentException",
-                     "bitmap size exceeds 32bits");
+        jniThrowException(env, "java/lang/IllegalArgumentException",
+                          "bitmap size exceeds 32bits");
         return NULL;
     }
-    
+
     size_t size = size64.get32();
     jbyteArray arrayObj = env->NewByteArray(size);
     if (arrayObj) {
@@ -540,7 +529,7 @@
         sk_throw();
     }
 }
-    
+
 bool JavaPixelAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
     JNIEnv* env = vm2env(fVM);
 
@@ -625,14 +614,14 @@
 
     gBitmapConfig_class = make_globalref(env, "android/graphics/Bitmap$Config");
     gBitmapConfig_nativeInstanceID = getFieldIDCheck(env, gBitmapConfig_class,
-                                                     "nativeInt", "I");    
+                                                     "nativeInt", "I");
 
     gCanvas_class = make_globalref(env, "android/graphics/Canvas");
     gCanvas_nativeInstanceID = getFieldIDCheck(env, gCanvas_class, "mNativeCanvas", "I");
 
     gPaint_class = make_globalref(env, "android/graphics/Paint");
     gPaint_nativeInstanceID = getFieldIDCheck(env, gPaint_class, "mNativePaint", "I");
-    
+
     gPicture_class = make_globalref(env, "android/graphics/Picture");
     gPicture_nativeInstanceID = getFieldIDCheck(env, gPicture_class, "mNativePicture", "I");
 
@@ -640,6 +629,6 @@
     gRegion_nativeInstanceID = getFieldIDCheck(env, gRegion_class, "mNativeRegion", "I");
     gRegion_constructorMethodID = env->GetMethodID(gRegion_class, "<init>",
         "(II)V");
-    
+
     return 0;
 }
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index d678a5d..cc32f44 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -29,26 +29,26 @@
     static SkRect* jrectf_to_rect(JNIEnv*, jobject jrectf, SkRect*);
     static SkRect* jrect_to_rect(JNIEnv*, jobject jrect, SkRect*);
     static void rect_to_jrectf(const SkRect&, JNIEnv*, jobject jrectf);
-    
+
     static void set_jpoint(JNIEnv*, jobject jrect, int x, int y);
-    
+
     static SkIPoint* jpoint_to_ipoint(JNIEnv*, jobject jpoint, SkIPoint* point);
     static void ipoint_to_jpoint(const SkIPoint& point, JNIEnv*, jobject jpoint);
-    
+
     static SkPoint* jpointf_to_point(JNIEnv*, jobject jpointf, SkPoint* point);
     static void point_to_jpointf(const SkPoint& point, JNIEnv*, jobject jpointf);
-  
+
     static SkCanvas* getNativeCanvas(JNIEnv*, jobject canvas);
     static SkPaint*  getNativePaint(JNIEnv*, jobject paint);
     static SkBitmap* getNativeBitmap(JNIEnv*, jobject bitmap);
     static SkPicture* getNativePicture(JNIEnv*, jobject picture);
     static SkRegion* getNativeRegion(JNIEnv*, jobject region);
-    
+
     /** Return the corresponding native config from the java Config enum,
         or kNo_Config if the java object is null.
     */
     static SkBitmap::Config getNativeBitmapConfig(JNIEnv*, jobject jconfig);
-    
+
     /** Create a java Bitmap object given the native bitmap (required) and optional
         storage array (may be null).
     */
@@ -57,7 +57,7 @@
 
     static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, bool isMutable,
                                 jbyteArray ninepatch, int density = -1);
-    
+
     static jobject createRegion(JNIEnv* env, SkRegion* region);
 
     static jobject createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap);
@@ -138,7 +138,7 @@
     JavaPixelAllocator(JNIEnv* env);
     // overrides
     virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable);
-    
+
     /** Return the Java array object created for the last allocation.
      *  This returns a local JNI reference which the caller is responsible
      *  for storing appropriately (usually by passing it to the Bitmap
@@ -173,10 +173,10 @@
     AutoJavaFloatArray(JNIEnv* env, jfloatArray array,
                        int minLength = 0, JNIAccess = kRW_JNIAccess);
     ~AutoJavaFloatArray();
-    
+
     float* ptr() const { return fPtr; }
     int    length() const { return fLen; }
-    
+
 private:
     JNIEnv*     fEnv;
     jfloatArray fArray;
@@ -189,10 +189,10 @@
 public:
     AutoJavaIntArray(JNIEnv* env, jintArray array, int minLength = 0);
     ~AutoJavaIntArray();
-    
+
     jint* ptr() const { return fPtr; }
     int    length() const { return fLen; }
-    
+
 private:
     JNIEnv*     fEnv;
     jintArray fArray;
@@ -205,10 +205,10 @@
     AutoJavaShortArray(JNIEnv* env, jshortArray array,
                        int minLength = 0, JNIAccess = kRW_JNIAccess);
     ~AutoJavaShortArray();
-    
+
     jshort* ptr() const { return fPtr; }
     int    length() const { return fLen; }
-    
+
 private:
     JNIEnv*     fEnv;
     jshortArray fArray;
@@ -221,10 +221,10 @@
 public:
     AutoJavaByteArray(JNIEnv* env, jbyteArray array, int minLength = 0);
     ~AutoJavaByteArray();
-    
+
     jbyte* ptr() const { return fPtr; }
     int    length() const { return fLen; }
-    
+
 private:
     JNIEnv*     fEnv;
     jbyteArray fArray;
@@ -232,7 +232,6 @@
     int         fLen;
 };
 
-void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL);
 void doThrowNPE(JNIEnv* env);
 void doThrowAIOOBE(JNIEnv* env); // Array Index Out Of Bounds Exception
 void doThrowIAE(JNIEnv* env, const char* msg = NULL);   // Illegal Argument
diff --git a/core/jni/android/graphics/Movie.cpp b/core/jni/android/graphics/Movie.cpp
index b319a74..7145433 100644
--- a/core/jni/android/graphics/Movie.cpp
+++ b/core/jni/android/graphics/Movie.cpp
@@ -83,7 +83,7 @@
 }
 
 static jobject movie_decodeStream(JNIEnv* env, jobject clazz, jobject istream) {
-                              
+
     NPE_CHECK_RETURN_ZERO(env, istream);
 
     // what is the lifetime of the array? Can the skstream hold onto it?
@@ -101,12 +101,12 @@
 static jobject movie_decodeByteArray(JNIEnv* env, jobject clazz,
                                      jbyteArray byteArray,
                                      int offset, int length) {
-                              
+
     NPE_CHECK_RETURN_ZERO(env, byteArray);
 
     int totalLength = env->GetArrayLength(byteArray);
     if ((offset | length) < 0 || offset + length > totalLength) {
-        doThrow(env, "java/lang/ArrayIndexOutOfBoundsException");
+        doThrowAIOOBE(env);
         return 0;
     }
 
@@ -142,7 +142,7 @@
     gMovie_class = env->FindClass(kClassPathName);
     RETURN_ERR_IF_NULL(gMovie_class);
     gMovie_class = (jclass)env->NewGlobalRef(gMovie_class);
-    
+
     gMovie_constructorMethodID = env->GetMethodID(gMovie_class, "<init>", "(I)V");
     RETURN_ERR_IF_NULL(gMovie_constructorMethodID);
 
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index fbb9cea..04c7fb9 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -2,16 +2,16 @@
 **
 ** Copyright 2006, The Android Open Source Project
 **
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
 **
-**     http://www.apache.org/licenses/LICENSE-2.0 
+**     http://www.apache.org/licenses/LICENSE-2.0
 **
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
 
@@ -76,214 +76,214 @@
         SkPaint* obj = new SkPaint(*paint);
         return obj;
     }
- 
+
     static void reset(JNIEnv* env, jobject clazz, SkPaint* obj) {
         obj->reset();
         defaultSettingsForAndroid(obj);
     }
- 
+
     static void assign(JNIEnv* env, jobject clazz, SkPaint* dst, const SkPaint* src) {
         *dst = *src;
     }
- 
+
     static jint getFlags(JNIEnv* env, jobject paint) {
         NPE_CHECK_RETURN_ZERO(env, paint);
         return GraphicsJNI::getNativePaint(env, paint)->getFlags();
     }
- 
+
     static void setFlags(JNIEnv* env, jobject paint, jint flags) {
         NPE_CHECK_RETURN_VOID(env, paint);
         GraphicsJNI::getNativePaint(env, paint)->setFlags(flags);
     }
- 
+
     static void setAntiAlias(JNIEnv* env, jobject paint, jboolean aa) {
         NPE_CHECK_RETURN_VOID(env, paint);
         GraphicsJNI::getNativePaint(env, paint)->setAntiAlias(aa);
     }
- 
+
     static void setLinearText(JNIEnv* env, jobject paint, jboolean linearText) {
         NPE_CHECK_RETURN_VOID(env, paint);
         GraphicsJNI::getNativePaint(env, paint)->setLinearText(linearText);
     }
-    
+
     static void setSubpixelText(JNIEnv* env, jobject paint, jboolean subpixelText) {
         NPE_CHECK_RETURN_VOID(env, paint);
         GraphicsJNI::getNativePaint(env, paint)->setSubpixelText(subpixelText);
     }
-    
+
     static void setUnderlineText(JNIEnv* env, jobject paint, jboolean underlineText) {
         NPE_CHECK_RETURN_VOID(env, paint);
         GraphicsJNI::getNativePaint(env, paint)->setUnderlineText(underlineText);
     }
- 
+
     static void setStrikeThruText(JNIEnv* env, jobject paint, jboolean strikeThruText) {
         NPE_CHECK_RETURN_VOID(env, paint);
         GraphicsJNI::getNativePaint(env, paint)->setStrikeThruText(strikeThruText);
     }
- 
+
     static void setFakeBoldText(JNIEnv* env, jobject paint, jboolean fakeBoldText) {
         NPE_CHECK_RETURN_VOID(env, paint);
         GraphicsJNI::getNativePaint(env, paint)->setFakeBoldText(fakeBoldText);
     }
-    
+
     static void setFilterBitmap(JNIEnv* env, jobject paint, jboolean filterBitmap) {
         NPE_CHECK_RETURN_VOID(env, paint);
         GraphicsJNI::getNativePaint(env, paint)->setFilterBitmap(filterBitmap);
     }
-    
+
     static void setDither(JNIEnv* env, jobject paint, jboolean dither) {
         NPE_CHECK_RETURN_VOID(env, paint);
         GraphicsJNI::getNativePaint(env, paint)->setDither(dither);
     }
-    
+
     static jint getStyle(JNIEnv* env, jobject clazz, SkPaint* obj) {
         return obj->getStyle();
     }
- 
+
     static void setStyle(JNIEnv* env, jobject clazz, SkPaint* obj, SkPaint::Style style) {
         obj->setStyle(style);
     }
- 
+
     static jint getColor(JNIEnv* env, jobject paint) {
         NPE_CHECK_RETURN_ZERO(env, paint);
         return GraphicsJNI::getNativePaint(env, paint)->getColor();
     }
- 
+
     static jint getAlpha(JNIEnv* env, jobject paint) {
         NPE_CHECK_RETURN_ZERO(env, paint);
         return GraphicsJNI::getNativePaint(env, paint)->getAlpha();
     }
- 
+
     static void setColor(JNIEnv* env, jobject paint, jint color) {
         NPE_CHECK_RETURN_VOID(env, paint);
         GraphicsJNI::getNativePaint(env, paint)->setColor(color);
     }
- 
+
     static void setAlpha(JNIEnv* env, jobject paint, jint a) {
         NPE_CHECK_RETURN_VOID(env, paint);
         GraphicsJNI::getNativePaint(env, paint)->setAlpha(a);
     }
- 
+
     static jfloat getStrokeWidth(JNIEnv* env, jobject paint) {
         NPE_CHECK_RETURN_ZERO(env, paint);
         return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getStrokeWidth());
     }
- 
+
     static void setStrokeWidth(JNIEnv* env, jobject paint, jfloat width) {
         NPE_CHECK_RETURN_VOID(env, paint);
         GraphicsJNI::getNativePaint(env, paint)->setStrokeWidth(SkFloatToScalar(width));
     }
- 
+
     static jfloat getStrokeMiter(JNIEnv* env, jobject paint) {
         NPE_CHECK_RETURN_ZERO(env, paint);
         return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getStrokeMiter());
     }
- 
+
     static void setStrokeMiter(JNIEnv* env, jobject paint, jfloat miter) {
         NPE_CHECK_RETURN_VOID(env, paint);
         GraphicsJNI::getNativePaint(env, paint)->setStrokeMiter(SkFloatToScalar(miter));
     }
- 
+
     static jint getStrokeCap(JNIEnv* env, jobject clazz, SkPaint* obj) {
         return obj->getStrokeCap();
     }
- 
+
     static void setStrokeCap(JNIEnv* env, jobject clazz, SkPaint* obj, SkPaint::Cap cap) {
         obj->setStrokeCap(cap);
     }
- 
+
     static jint getStrokeJoin(JNIEnv* env, jobject clazz, SkPaint* obj) {
         return obj->getStrokeJoin();
     }
- 
+
     static void setStrokeJoin(JNIEnv* env, jobject clazz, SkPaint* obj, SkPaint::Join join) {
         obj->setStrokeJoin(join);
     }
- 
+
     static jboolean getFillPath(JNIEnv* env, jobject clazz, SkPaint* obj, SkPath* src, SkPath* dst) {
         return obj->getFillPath(*src, dst);
     }
- 
+
     static SkShader* setShader(JNIEnv* env, jobject clazz, SkPaint* obj, SkShader* shader) {
         return obj->setShader(shader);
     }
- 
+
     static SkColorFilter* setColorFilter(JNIEnv* env, jobject clazz, SkPaint* obj, SkColorFilter* filter) {
         return obj->setColorFilter(filter);
     }
- 
+
     static SkXfermode* setXfermode(JNIEnv* env, jobject clazz, SkPaint* obj, SkXfermode* xfermode) {
         return obj->setXfermode(xfermode);
     }
- 
+
     static SkPathEffect* setPathEffect(JNIEnv* env, jobject clazz, SkPaint* obj, SkPathEffect* effect) {
         return obj->setPathEffect(effect);
     }
- 
+
     static SkMaskFilter* setMaskFilter(JNIEnv* env, jobject clazz, SkPaint* obj, SkMaskFilter* maskfilter) {
         return obj->setMaskFilter(maskfilter);
     }
- 
+
     static SkTypeface* setTypeface(JNIEnv* env, jobject clazz, SkPaint* obj, SkTypeface* typeface) {
         return obj->setTypeface(typeface);
     }
- 
+
     static SkRasterizer* setRasterizer(JNIEnv* env, jobject clazz, SkPaint* obj, SkRasterizer* rasterizer) {
         return obj->setRasterizer(rasterizer);
     }
- 
+
     static jint getTextAlign(JNIEnv* env, jobject clazz, SkPaint* obj) {
         return obj->getTextAlign();
     }
- 
+
     static void setTextAlign(JNIEnv* env, jobject clazz, SkPaint* obj, SkPaint::Align align) {
         obj->setTextAlign(align);
     }
- 
+
     static jfloat getTextSize(JNIEnv* env, jobject paint) {
         NPE_CHECK_RETURN_ZERO(env, paint);
         return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextSize());
     }
- 
+
     static void setTextSize(JNIEnv* env, jobject paint, jfloat textSize) {
         NPE_CHECK_RETURN_VOID(env, paint);
         GraphicsJNI::getNativePaint(env, paint)->setTextSize(SkFloatToScalar(textSize));
     }
- 
+
     static jfloat getTextScaleX(JNIEnv* env, jobject paint) {
         NPE_CHECK_RETURN_ZERO(env, paint);
         return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextScaleX());
     }
- 
+
     static void setTextScaleX(JNIEnv* env, jobject paint, jfloat scaleX) {
         NPE_CHECK_RETURN_VOID(env, paint);
         GraphicsJNI::getNativePaint(env, paint)->setTextScaleX(SkFloatToScalar(scaleX));
     }
- 
+
     static jfloat getTextSkewX(JNIEnv* env, jobject paint) {
         NPE_CHECK_RETURN_ZERO(env, paint);
         return SkScalarToFloat(GraphicsJNI::getNativePaint(env, paint)->getTextSkewX());
     }
- 
+
     static void setTextSkewX(JNIEnv* env, jobject paint, jfloat skewX) {
         NPE_CHECK_RETURN_VOID(env, paint);
         GraphicsJNI::getNativePaint(env, paint)->setTextSkewX(SkFloatToScalar(skewX));
     }
- 
+
     static jfloat ascent(JNIEnv* env, jobject paint) {
         NPE_CHECK_RETURN_ZERO(env, paint);
         SkPaint::FontMetrics    metrics;
         (void)GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
         return SkScalarToFloat(metrics.fAscent);
     }
- 
+
     static jfloat descent(JNIEnv* env, jobject paint) {
         NPE_CHECK_RETURN_ZERO(env, paint);
         SkPaint::FontMetrics    metrics;
         (void)GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
         return SkScalarToFloat(metrics.fDescent);
     }
- 
+
     static jfloat getFontMetrics(JNIEnv* env, jobject paint, jobject metricsObj) {
         NPE_CHECK_RETURN_ZERO(env, paint);
         SkPaint::FontMetrics metrics;
@@ -299,11 +299,11 @@
         }
         return SkScalarToFloat(spacing);
     }
-    
+
     static jint getFontMetricsInt(JNIEnv* env, jobject paint, jobject metricsObj) {
         NPE_CHECK_RETURN_ZERO(env, paint);
         SkPaint::FontMetrics metrics;
-        
+
         GraphicsJNI::getNativePaint(env, paint)->getFontMetrics(&metrics);
         int ascent = SkScalarRound(metrics.fAscent);
         int descent = SkScalarRound(metrics.fDescent);
@@ -325,13 +325,13 @@
         NPE_CHECK_RETURN_ZERO(env, text);
 
         size_t textLength = env->GetArrayLength(text);
-        
+
         if ((index | count) < 0 || (size_t)(index + count) > textLength) {
-            doThrow(env, "java/lang/ArrayIndexOutOfBoundsException");
+            doThrowAIOOBE(env);
             return 0;
         }
 
-        const SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);        
+        const SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
         const jchar* textArray = env->GetCharArrayElements(text, NULL);
         // we double count, since measureText wants a byteLength
         SkScalar width = paint->measureText(textArray + index, count << 1);
@@ -340,59 +340,59 @@
 
         return SkScalarToFloat(width);
     }
- 
+
     static jfloat measureText_StringII(JNIEnv* env, jobject jpaint, jstring text, int start, int end) {
         NPE_CHECK_RETURN_ZERO(env, jpaint);
         NPE_CHECK_RETURN_ZERO(env, text);
-        
-        SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);        
+
+        SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
         const jchar* textArray = env->GetStringChars(text, NULL);
         size_t textLength = env->GetStringLength(text);
-        
+
         int count = end - start;
         if ((start | count) < 0 || (size_t)count > textLength) {
-            doThrow(env, "java/lang/IndexOutOfBoundsException");
+            doThrowAIOOBE(env);
             return 0;
         }
-        
+
         jfloat width = SkScalarToFloat(paint->measureText(textArray + start, count << 1));
         env->ReleaseStringChars(text, textArray);
         return width;
     }
-    
+
     static jfloat measureText_String(JNIEnv* env, jobject jpaint, jstring text) {
         NPE_CHECK_RETURN_ZERO(env, jpaint);
         NPE_CHECK_RETURN_ZERO(env, text);
-        
-        SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);        
+
+        SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
         const jchar* textArray = env->GetStringChars(text, NULL);
         size_t textLength = env->GetStringLength(text);
-        
+
         jfloat width = SkScalarToFloat(paint->measureText(textArray, textLength << 1));
         env->ReleaseStringChars(text, textArray);
         return width;
     }
-    
+
     static int dotextwidths(JNIEnv* env, SkPaint* paint, const jchar text[], int count, jfloatArray widths) {
         AutoJavaFloatArray autoWidths(env, widths, count);
         jfloat* widthsArray = autoWidths.ptr();
         SkScalar* scalarArray = (SkScalar*)widthsArray;
 
-        count = paint->getTextWidths(text, count << 1, scalarArray);        
+        count = paint->getTextWidths(text, count << 1, scalarArray);
         for (int i = 0; i < count; i++) {
             widthsArray[i] = SkScalarToFloat(scalarArray[i]);
         }
         return count;
     }
-    
+
     static int getTextWidths___CII_F(JNIEnv* env, jobject clazz, SkPaint* paint, jcharArray text, int index, int count, jfloatArray widths) {
         const jchar* textArray = env->GetCharArrayElements(text, NULL);
         count = dotextwidths(env, paint, textArray + index, count, widths);
         env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
-                                      JNI_ABORT);        
+                                      JNI_ABORT);
         return count;
     }
- 
+
     static int getTextWidths__StringII_F(JNIEnv* env, jobject clazz, SkPaint* paint, jstring text,
             int start, int end, jfloatArray widths) {
         const jchar* textArray = env->GetStringChars(text, NULL);
@@ -621,8 +621,8 @@
     static void setShadowLayer(JNIEnv* env, jobject jpaint, jfloat radius,
                                jfloat dx, jfloat dy, int color) {
         NPE_CHECK_RETURN_VOID(env, jpaint);
-        
-        SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);        
+
+        SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
         if (radius <= 0) {
             paint->setLooper(NULL);
         }
@@ -667,7 +667,7 @@
         }
 
         if ((index < 0) || (index + count > env->GetArrayLength(jtext))) {
-            doThrow(env, "java/lang/ArrayIndexOutOfBoundsException");
+            doThrowAIOOBE(env);
             return 0;
         }
 
@@ -703,7 +703,7 @@
     {
         SkRect  r;
         SkIRect ir;
-        
+
         paint.measureText(text, count << 1, &r);
         r.roundOut(&ir);
         GraphicsJNI::irect_to_jrect(ir, env, bounds);
@@ -716,7 +716,7 @@
         doTextBounds(env, textArray + start, end - start, bounds, *paint);
         env->ReleaseStringChars(text, textArray);
     }
-    
+
     static void getCharArrayBounds(JNIEnv* env, jobject, const SkPaint* paint,
                         jcharArray text, int index, int count, jobject bounds)
     {
@@ -725,7 +725,7 @@
         env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
                                       JNI_ABORT);
     }
-    
+
 };
 
 static JNINativeMethod methods[] = {
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index 589b255..6a049e0 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -14,7 +14,9 @@
  ** limitations under the License.
  */
 
-#include <nativehelper/jni.h>
+#include "jni.h"
+#include "JNIHelp.h"
+
 #include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -38,10 +40,6 @@
 
 namespace android {
 
-static jclass gIAEClass;
-static jclass gUOEClass;
-static jclass gAIOOBEClass;
-
 static inline
 void mx4transform(float x, float y, float z, float w, const float* pM, float* pDest) {
     pDest[0] = pM[0 + 4 * 0] * x + pM[0 + 4 * 1] * y + pM[0 + 4 * 2] * z + pM[0 + 4 * 3] * w;
@@ -151,6 +149,10 @@
     return result;
 }
 
+static void doThrowIAE(JNIEnv* env, const char* msg) {
+    jniThrowException(env, "java/lang/IllegalArgumentException", msg);
+}
+
 template<class JArray, class T>
 class ArrayHelper {
 public:
@@ -178,16 +180,16 @@
 
     bool check() {
         if ( ! mRef) {
-            mEnv->ThrowNew(gIAEClass, "array == null");
+            doThrowIAE(mEnv, "array == null");
             return false;
         }
         if ( mOffset < 0) {
-            mEnv->ThrowNew(gIAEClass, "offset < 0");
+            doThrowIAE(mEnv, "offset < 0");
             return false;
         }
         mLength = mEnv->GetArrayLength(mRef) - mOffset;
         if (mLength < mMinSize ) {
-            mEnv->ThrowNew(gIAEClass, "length - offset < n");
+            doThrowIAE(mEnv, "length - offset < n");
             return false;
         }
         return true;
@@ -245,7 +247,7 @@
     sphere.bind();
 
     if ( positionsCount < 1 ) {
-        env->ThrowNew(gIAEClass, "positionsCount < 1");
+        doThrowIAE(env, "positionsCount < 1");
         return;
     }
 
@@ -450,8 +452,7 @@
     }
 
     if (indices.mLength < indexCount) {
-        env->ThrowNew(gIAEClass, "length < offset + indexCount");
-        // Return value will be ignored, because an exception has been thrown.
+        doThrowIAE(env, "length < offset + indexCount");
         return -1;
     }
 
@@ -784,11 +785,11 @@
         if (mBuffer) {
             mData = getPointer(mEnv, mBuffer, &mRemaining);
             if (mData == NULL) {
-                mEnv->ThrowNew(gIAEClass, errorMessage);
+                doThrowIAE(mEnv, errorMessage);
             }
             return mData != NULL;
         } else {
-            mEnv->ThrowNew(gIAEClass, errorMessage);
+            doThrowIAE(mEnv, errorMessage);
             return false;
         }
     }
@@ -824,16 +825,16 @@
 static void etc1_encodeBlock(JNIEnv *env, jclass clazz,
         jobject in, jint validPixelMask, jobject out) {
     if (validPixelMask < 0 || validPixelMask > 15) {
-        env->ThrowNew(gIAEClass, "validPixelMask");
+        doThrowIAE(env, "validPixelMask");
         return;
     }
     BufferHelper inB(env, in);
     BufferHelper outB(env, out);
     if (inB.checkPointer("in") && outB.checkPointer("out")) {
         if (inB.remaining() < ETC1_DECODED_BLOCK_SIZE) {
-            env->ThrowNew(gIAEClass, "in's remaining data < DECODED_BLOCK_SIZE");
+            doThrowIAE(env, "in's remaining data < DECODED_BLOCK_SIZE");
         } else if (outB.remaining() < ETC1_ENCODED_BLOCK_SIZE) {
-            env->ThrowNew(gIAEClass, "out's remaining data < ENCODED_BLOCK_SIZE");
+            doThrowIAE(env, "out's remaining data < ENCODED_BLOCK_SIZE");
         } else {
             etc1_encode_block((etc1_byte*) inB.getData(), validPixelMask,
                     (etc1_byte*) outB.getData());
@@ -856,9 +857,9 @@
     BufferHelper outB(env, out);
     if (inB.checkPointer("in") && outB.checkPointer("out")) {
         if (inB.remaining() < ETC1_ENCODED_BLOCK_SIZE) {
-            env->ThrowNew(gIAEClass, "in's remaining data < ENCODED_BLOCK_SIZE");
+            doThrowIAE(env, "in's remaining data < ENCODED_BLOCK_SIZE");
         } else if (outB.remaining() < ETC1_DECODED_BLOCK_SIZE) {
-            env->ThrowNew(gIAEClass, "out's remaining data < DECODED_BLOCK_SIZE");
+            doThrowIAE(env, "out's remaining data < DECODED_BLOCK_SIZE");
         } else {
             etc1_decode_block((etc1_byte*) inB.getData(),
                     (etc1_byte*) outB.getData());
@@ -884,7 +885,7 @@
         jobject in, jint width, jint height,
         jint pixelSize, jint stride, jobject out) {
     if (pixelSize < 2 || pixelSize > 3) {
-        env->ThrowNew(gIAEClass, "pixelSize must be 2 or 3");
+        doThrowIAE(env, "pixelSize must be 2 or 3");
         return;
     }
     BufferHelper inB(env, in);
@@ -893,9 +894,9 @@
         jint imageSize = stride * height;
         jint encodedImageSize = etc1_get_encoded_data_size(width, height);
         if (inB.remaining() < imageSize) {
-            env->ThrowNew(gIAEClass, "in's remaining data < image size");
+            doThrowIAE(env, "in's remaining data < image size");
         } else if (outB.remaining() < encodedImageSize) {
-            env->ThrowNew(gIAEClass, "out's remaining data < encoded image size");
+            doThrowIAE(env, "out's remaining data < encoded image size");
         } else {
             int result = etc1_encode_image((etc1_byte*) inB.getData(),
                     width, height, pixelSize,
@@ -917,7 +918,7 @@
         jint width, jint height,
         jint pixelSize, jint stride) {
     if (pixelSize < 2 || pixelSize > 3) {
-        env->ThrowNew(gIAEClass, "pixelSize must be 2 or 3");
+        doThrowIAE(env, "pixelSize must be 2 or 3");
         return;
     }
     BufferHelper inB(env, in);
@@ -926,9 +927,9 @@
         jint imageSize = stride * height;
         jint encodedImageSize = etc1_get_encoded_data_size(width, height);
         if (inB.remaining() < encodedImageSize) {
-            env->ThrowNew(gIAEClass, "in's remaining data < encoded image size");
+            doThrowIAE(env, "in's remaining data < encoded image size");
         } else if (outB.remaining() < imageSize) {
-            env->ThrowNew(gIAEClass, "out's remaining data < image size");
+            doThrowIAE(env, "out's remaining data < image size");
         } else {
             int result = etc1_decode_image((etc1_byte*) inB.getData(),
                     (etc1_byte*) outB.getData(),
@@ -946,7 +947,7 @@
     BufferHelper headerB(env, header);
     if (headerB.checkPointer("header") ){
         if (headerB.remaining() < ETC_PKM_HEADER_SIZE) {
-            env->ThrowNew(gIAEClass, "header's remaining data < ETC_PKM_HEADER_SIZE");
+            doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE");
         } else {
             etc1_pkm_format_header((etc1_byte*) headerB.getData(), width, height);
         }
@@ -962,7 +963,7 @@
     BufferHelper headerB(env, header);
     if (headerB.checkPointer("header") ){
         if (headerB.remaining() < ETC_PKM_HEADER_SIZE) {
-            env->ThrowNew(gIAEClass, "header's remaining data < ETC_PKM_HEADER_SIZE");
+            doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE");
         } else {
             result = etc1_pkm_is_valid((etc1_byte*) headerB.getData());
         }
@@ -979,7 +980,7 @@
     BufferHelper headerB(env, header);
     if (headerB.checkPointer("header") ){
         if (headerB.remaining() < ETC_PKM_HEADER_SIZE) {
-            env->ThrowNew(gIAEClass, "header's remaining data < ETC_PKM_HEADER_SIZE");
+            doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE");
         } else {
             result = etc1_pkm_get_width((etc1_byte*) headerB.getData());
         }
@@ -996,7 +997,7 @@
     BufferHelper headerB(env, header);
     if (headerB.checkPointer("header") ){
         if (headerB.remaining() < ETC_PKM_HEADER_SIZE) {
-            env->ThrowNew(gIAEClass, "header's remaining data < ETC_PKM_HEADER_SIZE");
+            doThrowIAE(env, "header's remaining data < ETC_PKM_HEADER_SIZE");
         } else {
             result = etc1_pkm_get_height((etc1_byte*) headerB.getData());
         }
@@ -1008,22 +1009,12 @@
  * JNI registration
  */
 
-static void
-lookupClasses(JNIEnv* env) {
-    gIAEClass = (jclass) env->NewGlobalRef(
-            env->FindClass("java/lang/IllegalArgumentException"));
-    gUOEClass = (jclass) env->NewGlobalRef(
-            env->FindClass("java/lang/UnsupportedOperationException"));
-    gAIOOBEClass = (jclass) env->NewGlobalRef(
-            env->FindClass("java/lang/ArrayIndexOutOfBoundsException"));
-}
-
 static JNINativeMethod gMatrixMethods[] = {
     { "multiplyMM", "([FI[FI[FI)V", (void*)util_multiplyMM },
     { "multiplyMV", "([FI[FI[FI)V", (void*)util_multiplyMV },
 };
 
-static JNINativeMethod gVisiblityMethods[] = {
+static JNINativeMethod gVisibilityMethods[] = {
     { "computeBoundingSphere", "([FII[FI)V", (void*)util_computeBoundingSphere },
     { "frustumCullSpheres", "([FI[FII[III)I", (void*)util_frustumCullSpheres },
     { "visibilityTest", "([FI[FI[CII)I", (void*)util_visibilityTest },
@@ -1056,15 +1047,14 @@
 } ClassRegistrationInfo;
 
 static ClassRegistrationInfo gClasses[] = {
-        {"android/opengl/Matrix", gMatrixMethods, NELEM(gMatrixMethods)},
-        {"android/opengl/Visibility", gVisiblityMethods, NELEM(gVisiblityMethods)},
-        {"android/opengl/GLUtils", gUtilsMethods, NELEM(gUtilsMethods)},
-        {"android/opengl/ETC1", gEtc1Methods, NELEM(gEtc1Methods)},
+    {"android/opengl/Matrix", gMatrixMethods, NELEM(gMatrixMethods)},
+    {"android/opengl/Visibility", gVisibilityMethods, NELEM(gVisibilityMethods)},
+    {"android/opengl/GLUtils", gUtilsMethods, NELEM(gUtilsMethods)},
+    {"android/opengl/ETC1", gEtc1Methods, NELEM(gEtc1Methods)},
 };
 
 int register_android_opengl_classes(JNIEnv* env)
 {
-    lookupClasses(env);
     nativeClassInitBuffer(env);
     int result = 0;
     for (int i = 0; i < NELEM(gClasses); i++) {
@@ -1080,4 +1070,3 @@
 }
 
 } // namespace android
-
diff --git a/core/jni/android_content_res_ObbScanner.cpp b/core/jni/android_content_res_ObbScanner.cpp
index 4759e27..404a87d 100644
--- a/core/jni/android_content_res_ObbScanner.cpp
+++ b/core/jni/android_content_res_ObbScanner.cpp
@@ -21,6 +21,7 @@
 #include <utils/ObbFile.h>
 
 #include "jni.h"
+#include "JNIHelp.h"
 #include "utils/misc.h"
 #include "android_runtime/AndroidRuntime.h"
 
@@ -35,16 +36,6 @@
     jfieldID salt;
 } gObbInfoClassInfo;
 
-static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
-{
-    jclass npeClazz;
-
-    npeClazz = env->FindClass(exc);
-    LOG_FATAL_IF(npeClazz == NULL, "Unable to find class %s", exc);
-
-    env->ThrowNew(npeClazz, msg);
-}
-
 static void android_content_res_ObbScanner_getObbInfo(JNIEnv* env, jobject clazz, jstring file,
         jobject obbInfo)
 {
@@ -53,7 +44,7 @@
     sp<ObbFile> obb = new ObbFile();
     if (!obb->readFrom(filePath)) {
         env->ReleaseStringUTFChars(file, filePath);
-        doThrow(env, "java/io/IOException", "Could not read OBB file");
+        jniThrowException(env, "java/io/IOException", "Could not read OBB file");
         return;
     }
 
@@ -63,7 +54,7 @@
 
     jstring packageName = env->NewStringUTF(packageNameStr);
     if (packageName == NULL) {
-        doThrow(env, "java/io/IOException", "Could not read OBB file");
+        jniThrowException(env, "java/io/IOException", "Could not read OBB file");
         return;
     }
 
diff --git a/core/jni/android_graphics_PixelFormat.cpp b/core/jni/android_graphics_PixelFormat.cpp
index 5b8363c..1fc363b 100644
--- a/core/jni/android_graphics_PixelFormat.cpp
+++ b/core/jni/android_graphics_PixelFormat.cpp
@@ -20,6 +20,7 @@
 #include <ui/PixelFormat.h>
 
 #include "jni.h"
+#include "JNIHelp.h"
 #include <android_runtime/AndroidRuntime.h>
 #include <utils/misc.h>
 
@@ -36,12 +37,6 @@
 
 static offsets_t offsets;
 
-static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
-{
-    jclass npeClazz = env->FindClass(exc);
-    env->ThrowNew(npeClazz, msg);
-}
-
 // ----------------------------------------------------------------------------
 
 static void android_graphics_getPixelFormatInfo(
@@ -72,7 +67,7 @@
 
     err = getPixelFormatInfo(format, &info);
     if (err < 0) {
-        doThrow(env, "java/lang/IllegalArgumentException");
+        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
         return;
     }
 
@@ -97,7 +92,7 @@
 void nativeClassInit(JNIEnv* env, jclass clazz)
 {
     offsets.bytesPerPixel = env->GetFieldID(clazz, "bytesPerPixel", "I");
-    offsets.bitsPerPixel  = env->GetFieldID(clazz, "bitsPerPixel", "I");    
+    offsets.bitsPerPixel  = env->GetFieldID(clazz, "bitsPerPixel", "I");
 }
 
 int register_android_graphics_PixelFormat(JNIEnv* env)
diff --git a/core/jni/android_hardware_UsbDeviceConnection.cpp b/core/jni/android_hardware_UsbDeviceConnection.cpp
index ec36a38..e259514 100644
--- a/core/jni/android_hardware_UsbDeviceConnection.cpp
+++ b/core/jni/android_hardware_UsbDeviceConnection.cpp
@@ -132,7 +132,7 @@
     jbyte* bufferBytes = NULL;
     if (buffer) {
         if (env->GetArrayLength(buffer) < length) {
-            env->ThrowNew(env->FindClass("java/lang/ArrayIndexOutOfBoundsException"), NULL);
+            jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL);
             return -1;
         }
         bufferBytes = env->GetByteArrayElements(buffer, 0);
@@ -160,7 +160,7 @@
     jbyte* bufferBytes = NULL;
     if (buffer) {
         if (env->GetArrayLength(buffer) < length) {
-            env->ThrowNew(env->FindClass("java/lang/ArrayIndexOutOfBoundsException"), NULL);
+            jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL);
             return -1;
         }
         bufferBytes = env->GetByteArrayElements(buffer, 0);
@@ -239,4 +239,3 @@
     return AndroidRuntime::registerNativeMethods(env, "android/hardware/usb/UsbDeviceConnection",
             method_table, NELEM(method_table));
 }
-
diff --git a/core/jni/android_os_Power.cpp b/core/jni/android_os_Power.cpp
index 5cfb9b1..9ae4a63 100644
--- a/core/jni/android_os_Power.cpp
+++ b/core/jni/android_os_Power.cpp
@@ -25,18 +25,11 @@
 namespace android
 {
 
-static void throw_NullPointerException(JNIEnv *env, const char* msg)
-{
-    jclass clazz;
-    clazz = env->FindClass("java/lang/NullPointerException");
-    env->ThrowNew(clazz, msg);
-}
-
 static void
 acquireWakeLock(JNIEnv *env, jobject clazz, jint lock, jstring idObj)
 {
     if (idObj == NULL) {
-        throw_NullPointerException(env, "id is null");
+        jniThrowNullPointerException(env, "id is null");
         return ;
     }
 
@@ -51,7 +44,7 @@
 releaseWakeLock(JNIEnv *env, jobject clazz, jstring idObj)
 {
     if (idObj == NULL) {
-        throw_NullPointerException(env, "id is null");
+        jniThrowNullPointerException(env, "id is null");
         return ;
     }
 
diff --git a/core/jni/android_util_Log.cpp b/core/jni/android_util_Log.cpp
index 6b97951..0fbe0e7 100644
--- a/core/jni/android_util_Log.cpp
+++ b/core/jni/android_util_Log.cpp
@@ -2,16 +2,16 @@
 **
 ** Copyright 2006, The Android Open Source Project
 **
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
 **
-**     http://www.apache.org/licenses/LICENSE-2.0 
+**     http://www.apache.org/licenses/LICENSE-2.0
 **
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
 
@@ -24,6 +24,7 @@
 #include <utils/String8.h>
 
 #include "jni.h"
+#include "JNIHelp.h"
 #include "utils/misc.h"
 #include "android_runtime/AndroidRuntime.h"
 
@@ -41,7 +42,7 @@
 };
 static levels_t levels;
 
-static int toLevel(const char* value) 
+static int toLevel(const char* value)
 {
     switch (value[0]) {
         case 'V': return levels.verbose;
@@ -67,13 +68,12 @@
     if (tag == NULL) {
         return false;
     }
-    
+
     jboolean result = false;
-    
+
     const char* chars = env->GetStringUTFChars(tag, NULL);
 
     if ((strlen(chars)+sizeof(LOG_NAMESPACE)) > PROPERTY_KEY_MAX) {
-        jclass clazz = env->FindClass("java/lang/IllegalArgumentException");
         char buf2[200];
         snprintf(buf2, sizeof(buf2), "Log tag \"%s\" exceeds limit of %d characters\n",
                 chars, PROPERTY_KEY_MAX - sizeof(LOG_NAMESPACE));
@@ -81,13 +81,13 @@
         // release the chars!
         env->ReleaseStringUTFChars(tag, chars);
 
-        env->ThrowNew(clazz, buf2);
+        jniThrowException(env, "java/lang/IllegalArgumentException", buf2);
         return false;
     } else {
         strncpy(key, LOG_NAMESPACE, sizeof(LOG_NAMESPACE)-1);
         strcpy(key + sizeof(LOG_NAMESPACE) - 1, chars);
     }
-    
+
     env->ReleaseStringUTFChars(tag, chars);
 
     len = property_get(key, buf, "");
@@ -107,22 +107,12 @@
     const char* msg = NULL;
 
     if (msgObj == NULL) {
-        jclass npeClazz;
-
-        npeClazz = env->FindClass("java/lang/NullPointerException");
-        assert(npeClazz != NULL);
-
-        env->ThrowNew(npeClazz, "println needs a message");
+        jniThrowNullPointerException(env, "println needs a message");
         return -1;
     }
 
     if (bufID < 0 || bufID >= LOG_ID_MAX) {
-        jclass npeClazz;
-
-        npeClazz = env->FindClass("java/lang/NullPointerException");
-        assert(npeClazz != NULL);
-
-        env->ThrowNew(npeClazz, "bad bufID");
+        jniThrowNullPointerException(env, "bad bufID");
         return -1;
     }
 
@@ -156,16 +146,15 @@
         LOGE("Can't find android/util/Log");
         return -1;
     }
-    
+
     levels.verbose = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "VERBOSE", "I"));
     levels.debug = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "DEBUG", "I"));
     levels.info = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "INFO", "I"));
     levels.warn = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "WARN", "I"));
     levels.error = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "ERROR", "I"));
     levels.assert = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "ASSERT", "I"));
-                
+
     return AndroidRuntime::registerNativeMethods(env, "android/util/Log", gMethods, NELEM(gMethods));
 }
 
 }; // namespace android
-
diff --git a/core/jni/android_util_StringBlock.cpp b/core/jni/android_util_StringBlock.cpp
index a021efd..958ddb2 100644
--- a/core/jni/android_util_StringBlock.cpp
+++ b/core/jni/android_util_StringBlock.cpp
@@ -2,22 +2,23 @@
 **
 ** Copyright 2006, The Android Open Source Project
 **
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
 **
-**     http://www.apache.org/licenses/LICENSE-2.0 
+**     http://www.apache.org/licenses/LICENSE-2.0
 **
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
 
 #define LOG_TAG "StringBlock"
 
 #include "jni.h"
+#include "JNIHelp.h"
 #include <utils/misc.h>
 #include <android_runtime/AndroidRuntime.h>
 #include <utils/Log.h>
@@ -30,28 +31,18 @@
 
 // ----------------------------------------------------------------------------
 
-static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
-{
-    jclass npeClazz;
-
-    npeClazz = env->FindClass(exc);
-    LOG_FATAL_IF(npeClazz == NULL, "Unable to find class %s", exc);
-
-    env->ThrowNew(npeClazz, msg);
-}
-
 static jint android_content_StringBlock_nativeCreate(JNIEnv* env, jobject clazz,
                                                   jbyteArray bArray,
                                                   jint off, jint len)
 {
     if (bArray == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        jniThrowNullPointerException(env, NULL);
         return 0;
     }
 
     jsize bLen = env->GetArrayLength(bArray);
     if (off < 0 || off >= bLen || len < 0 || len > bLen || (off+len) > bLen) {
-        doThrow(env, "java/lang/IndexOutOfBoundsException");
+        jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
         return 0;
     }
 
@@ -60,7 +51,7 @@
     env->ReleaseByteArrayElements(bArray, b, 0);
 
     if (osb == NULL || osb->getError() != NO_ERROR) {
-        doThrow(env, "java/lang/IllegalArgumentException");
+        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
         return 0;
     }
 
@@ -72,7 +63,7 @@
 {
     ResStringPool* osb = (ResStringPool*)token;
     if (osb == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        jniThrowNullPointerException(env, NULL);
         return 0;
     }
 
@@ -84,7 +75,7 @@
 {
     ResStringPool* osb = (ResStringPool*)token;
     if (osb == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        jniThrowNullPointerException(env, NULL);
         return 0;
     }
 
@@ -96,7 +87,7 @@
 
     const char16_t* str = osb->stringAt(idx, &len);
     if (str == NULL) {
-        doThrow(env, "java/lang/IndexOutOfBoundsException");
+        jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
         return 0;
     }
 
@@ -108,7 +99,7 @@
 {
     ResStringPool* osb = (ResStringPool*)token;
     if (osb == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        jniThrowNullPointerException(env, NULL);
         return NULL;
     }
 
@@ -129,8 +120,7 @@
     }
 
     jintArray array = env->NewIntArray((num*sizeof(ResStringPool_span))/sizeof(jint));
-    if (array == NULL) {
-        doThrow(env, "java/lang/OutOfMemoryError");
+    if (array == NULL) { // NewIntArray already threw OutOfMemoryError.
         return NULL;
     }
 
@@ -152,7 +142,7 @@
 {
     ResStringPool* osb = (ResStringPool*)token;
     if (osb == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        jniThrowNullPointerException(env, NULL);
         return;
     }
 
@@ -185,4 +175,3 @@
 }
 
 }; // namespace android
-
diff --git a/core/jni/android_util_XmlBlock.cpp b/core/jni/android_util_XmlBlock.cpp
index 8887fdc..45728db 100644
--- a/core/jni/android_util_XmlBlock.cpp
+++ b/core/jni/android_util_XmlBlock.cpp
@@ -2,22 +2,23 @@
 **
 ** Copyright 2006, The Android Open Source Project
 **
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
 **
-**     http://www.apache.org/licenses/LICENSE-2.0 
+**     http://www.apache.org/licenses/LICENSE-2.0
 **
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
 
 #define LOG_TAG "XmlBlock"
 
 #include "jni.h"
+#include "JNIHelp.h"
 #include <utils/misc.h>
 #include <android_runtime/AndroidRuntime.h>
 #include <utils/AssetManager.h>
@@ -31,28 +32,18 @@
 
 // ----------------------------------------------------------------------------
 
-static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
-{
-    jclass npeClazz;
-
-    npeClazz = env->FindClass(exc);
-    LOG_FATAL_IF(npeClazz == NULL, "Unable to find class %s", exc);
-
-    env->ThrowNew(npeClazz, msg);
-}
-
 static jint android_content_XmlBlock_nativeCreate(JNIEnv* env, jobject clazz,
                                                jbyteArray bArray,
                                                jint off, jint len)
 {
     if (bArray == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        jniThrowNullPointerException(env, NULL);
         return 0;
     }
 
     jsize bLen = env->GetArrayLength(bArray);
     if (off < 0 || off >= bLen || len < 0 || len > bLen || (off+len) > bLen) {
-        doThrow(env, "java/lang/IndexOutOfBoundsException");
+        jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
         return 0;
     }
 
@@ -61,7 +52,7 @@
     env->ReleaseByteArrayElements(bArray, b, 0);
 
     if (osb == NULL || osb->getError() != NO_ERROR) {
-        doThrow(env, "java/lang/IllegalArgumentException");
+        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
         return 0;
     }
 
@@ -73,7 +64,7 @@
 {
     ResXMLTree* osb = (ResXMLTree*)token;
     if (osb == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        jniThrowNullPointerException(env, NULL);
         return 0;
     }
 
@@ -85,13 +76,13 @@
 {
     ResXMLTree* osb = (ResXMLTree*)token;
     if (osb == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        jniThrowNullPointerException(env, NULL);
         return 0;
     }
 
     ResXMLParser* st = new ResXMLParser(*osb);
     if (st == NULL) {
-        doThrow(env, "java/lang/OutOfMemoryError");
+        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
         return 0;
     }
 
@@ -125,9 +116,9 @@
                 goto bad;
         }
     } while (true);
-    
+
 bad:
-    doThrow(env, "org/xmlpull/v1/XmlPullParserException",
+    jniThrowException(env, "org/xmlpull/v1/XmlPullParserException",
             "Corrupt XML binary file");
     return ResXMLParser::BAD_DOCUMENT;
 }
@@ -139,7 +130,7 @@
     if (st == NULL) {
         return -1;
     }
-    
+
     return (jint)st->getElementNamespaceID();
 }
 
@@ -170,7 +161,7 @@
 {
     ResXMLParser* st = (ResXMLParser*)token;
     if (st == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        jniThrowNullPointerException(env, NULL);
         return 0;
     }
 
@@ -182,7 +173,7 @@
 {
     ResXMLParser* st = (ResXMLParser*)token;
     if (st == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        jniThrowNullPointerException(env, NULL);
         return 0;
     }
 
@@ -194,10 +185,10 @@
 {
     ResXMLParser* st = (ResXMLParser*)token;
     if (st == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        jniThrowNullPointerException(env, NULL);
         return 0;
     }
-    
+
     return (jint)st->getAttributeNamespaceID(idx);
 }
 
@@ -206,7 +197,7 @@
 {
     ResXMLParser* st = (ResXMLParser*)token;
     if (st == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        jniThrowNullPointerException(env, NULL);
         return 0;
     }
 
@@ -218,7 +209,7 @@
 {
     ResXMLParser* st = (ResXMLParser*)token;
     if (st == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        jniThrowNullPointerException(env, NULL);
         return 0;
     }
 
@@ -230,7 +221,7 @@
 {
     ResXMLParser* st = (ResXMLParser*)token;
     if (st == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        jniThrowNullPointerException(env, NULL);
         return 0;
     }
 
@@ -242,7 +233,7 @@
 {
     ResXMLParser* st = (ResXMLParser*)token;
     if (st == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        jniThrowNullPointerException(env, NULL);
         return 0;
     }
 
@@ -254,7 +245,7 @@
 {
     ResXMLParser* st = (ResXMLParser*)token;
     if (st == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        jniThrowNullPointerException(env, NULL);
         return 0;
     }
 
@@ -267,7 +258,7 @@
 {
     ResXMLParser* st = (ResXMLParser*)token;
     if (st == NULL || name == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        jniThrowNullPointerException(env, NULL);
         return 0;
     }
 
@@ -277,7 +268,7 @@
         ns16 = env->GetStringChars(ns, NULL);
         nsLen = env->GetStringLength(ns);
     }
-    
+
     const char16_t* name16 = env->GetStringChars(name, NULL);
     jsize nameLen = env->GetStringLength(name);
 
@@ -296,7 +287,7 @@
 {
     ResXMLParser* st = (ResXMLParser*)token;
     if (st == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        jniThrowNullPointerException(env, NULL);
         return 0;
     }
 
@@ -309,10 +300,10 @@
 {
     ResXMLParser* st = (ResXMLParser*)token;
     if (st == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        jniThrowNullPointerException(env, NULL);
         return 0;
     }
-    
+
     ssize_t idx = st->indexOfClass();
     return idx >= 0 ? (jint)st->getAttributeValueStringID(idx) : -1;
 }
@@ -322,7 +313,7 @@
 {
     ResXMLParser* st = (ResXMLParser*)token;
     if (st == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        jniThrowNullPointerException(env, NULL);
         return 0;
     }
 
@@ -336,7 +327,7 @@
         return 0;
     }
 
-    return value.dataType == value.TYPE_REFERENCE 
+    return value.dataType == value.TYPE_REFERENCE
         || value.dataType == value.TYPE_ATTRIBUTE
         ? value.data : 0;
 }
@@ -346,7 +337,7 @@
 {
     ResXMLParser* st = (ResXMLParser*)token;
     if (st == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        jniThrowNullPointerException(env, NULL);
         return;
     }
 
@@ -358,7 +349,7 @@
 {
     ResXMLTree* osb = (ResXMLTree*)token;
     if (osb == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        jniThrowNullPointerException(env, NULL);
         return;
     }
 
@@ -423,4 +414,3 @@
 }
 
 }; // namespace android
-
diff --git a/core/jni/android_view_Display.cpp b/core/jni/android_view_Display.cpp
index 160d654..8feeb9a 100644
--- a/core/jni/android_view_Display.cpp
+++ b/core/jni/android_view_Display.cpp
@@ -24,6 +24,7 @@
 #include <ui/DisplayInfo.h>
 
 #include "jni.h"
+#include "JNIHelp.h"
 #include <android_runtime/AndroidRuntime.h>
 #include <utils/misc.h>
 #include <utils/Log.h>
@@ -49,12 +50,6 @@
 static int gOldSize = -1;
 static int gNewSize = -1;
 
-static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
-{
-    jclass npeClazz = env->FindClass(exc);
-    env->ThrowNew(npeClazz, msg);
-}
-
 // ----------------------------------------------------------------------------
 
 static void android_view_Display_init(
@@ -63,7 +58,7 @@
     DisplayInfo info;
     status_t err = SurfaceComposerClient::getDisplayInfo(DisplayID(dpy), &info);
     if (err < 0) {
-        doThrow(env, "java/lang/IllegalArgumentException");
+        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
         return;
     }
     env->SetIntField(clazz, offsets.pixelFormat,info.pixelFormatInfo.format);
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 9f1b1fd..f172913 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -35,6 +35,7 @@
 #include <SkPixelRef.h>
 
 #include "jni.h"
+#include "JNIHelp.h"
 #include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/android_view_Surface.h>
 #include <utils/misc.h>
@@ -131,15 +132,15 @@
 
 static sp<SurfaceControl> getSurfaceControl(JNIEnv* env, jobject clazz)
 {
-    SurfaceControl* const p = 
+    SurfaceControl* const p =
         (SurfaceControl*)env->GetIntField(clazz, so.surfaceControl);
     return sp<SurfaceControl>(p);
 }
 
-static void setSurfaceControl(JNIEnv* env, jobject clazz, 
+static void setSurfaceControl(JNIEnv* env, jobject clazz,
         const sp<SurfaceControl>& surface)
 {
-    SurfaceControl* const p = 
+    SurfaceControl* const p =
         (SurfaceControl*)env->GetIntField(clazz, so.surfaceControl);
     if (surface.get()) {
         surface->incStrong(clazz);
@@ -157,12 +158,12 @@
         /*
          * if this method is called from the WindowManager's process, it means
          * the client is is not remote, and therefore is allowed to have
-         * a Surface (data), so we create it here. 
+         * a Surface (data), so we create it here.
          * If we don't have a SurfaceControl, it means we're in a different
          * process.
          */
-        
-        SurfaceControl* const control = 
+
+        SurfaceControl* const control =
             (SurfaceControl*)env->GetIntField(clazz, so.surfaceControl);
         if (control) {
             result = control->getSurface();
@@ -201,15 +202,15 @@
 // ----------------------------------------------------------------------------
 
 static void Surface_init(
-        JNIEnv* env, jobject clazz, 
+        JNIEnv* env, jobject clazz,
         jobject session,
         jint pid, jstring jname, jint dpy, jint w, jint h, jint format, jint flags)
 {
     if (session == NULL) {
-        doThrow(env, "java/lang/NullPointerException");
+        doThrowNPE(env);
         return;
     }
-    
+
     SurfaceComposerClient* client =
             (SurfaceComposerClient*)env->GetIntField(session, sso.client);
 
@@ -224,7 +225,7 @@
     }
 
     if (surface == 0) {
-        doThrow(env, OutOfResourcesException);
+        jniThrowException(env, OutOfResourcesException, NULL);
         return;
     }
     setSurfaceControl(env, clazz, surface);
@@ -234,7 +235,7 @@
 {
     Parcel* parcel = (Parcel*)env->GetIntField(argParcel, no.native_parcel);
     if (parcel == NULL) {
-        doThrow(env, "java/lang/NullPointerException", NULL);
+        doThrowNPE(env);
         return;
     }
 
@@ -297,7 +298,7 @@
 {
     const sp<Surface>& surface(getSurface(env, clazz));
     if (!Surface::isValid(surface)) {
-        doThrow(env, "java/lang/IllegalArgumentException", NULL);
+        doThrowIAE(env);
         return 0;
     }
 
@@ -310,7 +311,7 @@
         dirty.right = env->GetIntField(dirtyRect, ro.r);
         dirty.bottom= env->GetIntField(dirtyRect, ro.b);
         if (!dirty.isEmpty()) {
-            dirtyRegion.set(dirty);    
+            dirtyRegion.set(dirty);
         }
     } else {
         dirtyRegion.set(Rect(0x3FFF,0x3FFF));
@@ -322,7 +323,7 @@
         const char* const exception = (err == NO_MEMORY) ?
             OutOfResourcesException :
             "java/lang/IllegalArgumentException";
-        doThrow(env, exception, NULL);
+        jniThrowException(env, exception, NULL);
         return 0;
     }
 
@@ -344,7 +345,7 @@
         bitmap.setPixels(NULL);
     }
     nativeCanvas->setBitmapDevice(bitmap);
-    
+
     SkRegion clipReg;
     if (dirtyRegion.isRect()) { // very common case
         const Rect b(dirtyRegion.getBounds());
@@ -359,7 +360,7 @@
     }
 
     nativeCanvas->clipRegion(clipReg);
-    
+
     int saveCount = nativeCanvas->save();
     env->SetIntField(clazz, so.saveCount, saveCount);
 
@@ -370,7 +371,7 @@
         env->SetIntField(dirtyRect, ro.r, bounds.right);
         env->SetIntField(dirtyRect, ro.b, bounds.bottom);
     }
-    
+
     return canvas;
 }
 
@@ -379,10 +380,10 @@
 {
     jobject canvas = env->GetObjectField(clazz, so.canvas);
     if (env->IsSameObject(canvas, argCanvas) == JNI_FALSE) {
-        doThrow(env, "java/lang/IllegalArgumentException", NULL);
+        doThrowIAE(env);
         return;
     }
-    
+
     const sp<Surface>& surface(getSurface(env, clazz));
     if (!Surface::isValid(surface))
         return;
@@ -397,7 +398,7 @@
     // unlock surface
     status_t err = surface->unlockAndPost();
     if (err < 0) {
-        doThrow(env, "java/lang/IllegalArgumentException", NULL);
+        doThrowIAE(env);
     }
 }
 
@@ -405,7 +406,7 @@
         JNIEnv* env, jobject clazz, jobject argCanvas)
 {
     // XXX: this API has been removed
-    doThrow(env, "java/lang/IllegalArgumentException", NULL);
+    doThrowIAE(env);
 }
 
 static void Surface_openTransaction(
@@ -425,7 +426,7 @@
 {
     int err = SurfaceComposerClient::setOrientation(display, orientation, flags);
     if (err < 0) {
-        doThrow(env, "java/lang/IllegalArgumentException", NULL);
+        doThrowIAE(env);
     }
 }
 
@@ -434,7 +435,7 @@
 {
     int err = SurfaceComposerClient::freezeDisplay(display, 0);
     if (err < 0) {
-        doThrow(env, "java/lang/IllegalArgumentException", NULL);
+        doThrowIAE(env);
     }
 }
 
@@ -443,7 +444,7 @@
 {
     int err = SurfaceComposerClient::unfreezeDisplay(display, 0);
     if (err < 0) {
-        doThrow(env, "java/lang/IllegalArgumentException", NULL);
+        doThrowIAE(env);
     }
 }
 
@@ -554,8 +555,9 @@
     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
     if (surface == 0) return;
     status_t err = surface->setLayer(zorder);
-    if (err<0 && err!=NO_INIT)
-        doThrow(env, "java/lang/IllegalArgumentException", NULL);
+    if (err<0 && err!=NO_INIT) {
+        doThrowIAE(env);
+    }
 }
 
 static void Surface_setPosition(
@@ -564,8 +566,9 @@
     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
     if (surface == 0) return;
     status_t err = surface->setPosition(x, y);
-    if (err<0 && err!=NO_INIT)
-        doThrow(env, "java/lang/IllegalArgumentException", NULL);
+    if (err<0 && err!=NO_INIT) {
+        doThrowIAE(env);
+    }
 }
 
 static void Surface_setSize(
@@ -574,8 +577,9 @@
     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
     if (surface == 0) return;
     status_t err = surface->setSize(w, h);
-    if (err<0 && err!=NO_INIT)
-        doThrow(env, "java/lang/IllegalArgumentException", NULL);
+    if (err<0 && err!=NO_INIT) {
+        doThrowIAE(env);
+    }
 }
 
 static void Surface_hide(
@@ -584,8 +588,9 @@
     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
     if (surface == 0) return;
     status_t err = surface->hide();
-    if (err<0 && err!=NO_INIT)
-        doThrow(env, "java/lang/IllegalArgumentException", NULL);
+    if (err<0 && err!=NO_INIT) {
+        doThrowIAE(env);
+    }
 }
 
 static void Surface_show(
@@ -594,8 +599,9 @@
     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
     if (surface == 0) return;
     status_t err = surface->show();
-    if (err<0 && err!=NO_INIT)
-        doThrow(env, "java/lang/IllegalArgumentException", NULL);
+    if (err<0 && err!=NO_INIT) {
+        doThrowIAE(env);
+    }
 }
 
 static void Surface_freeze(
@@ -604,8 +610,9 @@
     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
     if (surface == 0) return;
     status_t err = surface->freeze();
-    if (err<0 && err!=NO_INIT)
-        doThrow(env, "java/lang/IllegalArgumentException", NULL);
+    if (err<0 && err!=NO_INIT) {
+        doThrowIAE(env);
+    }
 }
 
 static void Surface_unfreeze(
@@ -614,8 +621,9 @@
     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
     if (surface == 0) return;
     status_t err = surface->unfreeze();
-    if (err<0 && err!=NO_INIT)
-        doThrow(env, "java/lang/IllegalArgumentException", NULL);
+    if (err<0 && err!=NO_INIT) {
+        doThrowIAE(env);
+    }
 }
 
 static void Surface_setFlags(
@@ -624,8 +632,9 @@
     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
     if (surface == 0) return;
     status_t err = surface->setFlags(flags, mask);
-    if (err<0 && err!=NO_INIT)
-        doThrow(env, "java/lang/IllegalArgumentException", NULL);
+    if (err<0 && err!=NO_INIT) {
+        doThrowIAE(env);
+    }
 }
 
 static void Surface_setTransparentRegion(
@@ -634,7 +643,7 @@
     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
     if (surface == 0) return;
     SkRegion* nativeRegion = (SkRegion*)env->GetIntField(argRegion, no.native_region);
-    
+
     const SkIRect& b(nativeRegion->getBounds());
     Region reg(Rect(b.fLeft, b.fTop, b.fRight, b.fBottom));
     if (nativeRegion->isComplex()) {
@@ -645,10 +654,11 @@
             it.next();
         }
     }
-    
+
     status_t err = surface->setTransparentRegionHint(reg);
-    if (err<0 && err!=NO_INIT)
-        doThrow(env, "java/lang/IllegalArgumentException", NULL);
+    if (err<0 && err!=NO_INIT) {
+        doThrowIAE(env);
+    }
 }
 
 static void Surface_setAlpha(
@@ -657,8 +667,9 @@
     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
     if (surface == 0) return;
     status_t err = surface->setAlpha(alpha);
-    if (err<0 && err!=NO_INIT)
-        doThrow(env, "java/lang/IllegalArgumentException", NULL);
+    if (err<0 && err!=NO_INIT) {
+        doThrowIAE(env);
+    }
 }
 
 static void Surface_setMatrix(
@@ -668,8 +679,9 @@
     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
     if (surface == 0) return;
     status_t err = surface->setMatrix(dsdx, dtdx, dsdy, dtdy);
-    if (err<0 && err!=NO_INIT)
-        doThrow(env, "java/lang/IllegalArgumentException", NULL);
+    if (err<0 && err!=NO_INIT) {
+        doThrowIAE(env);
+    }
 }
 
 static void Surface_setFreezeTint(
@@ -679,8 +691,9 @@
     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
     if (surface == 0) return;
     status_t err = surface->setFreezeTint(tint);
-    if (err<0 && err!=NO_INIT)
-        doThrow(env, "java/lang/IllegalArgumentException", NULL);
+    if (err<0 && err!=NO_INIT) {
+        doThrowIAE(env);
+    }
 }
 
 // ----------------------------------------------------------------------------
@@ -692,7 +705,7 @@
         return;
 
     if (other == NULL) {
-        doThrow(env, "java/lang/NullPointerException", NULL);
+        doThrowNPE(env);
         return;
     }
 
@@ -716,7 +729,7 @@
 {
     Parcel* parcel = (Parcel*)env->GetIntField( argParcel, no.native_parcel);
     if (parcel == NULL) {
-        doThrow(env, "java/lang/NullPointerException", NULL);
+        doThrowNPE(env);
         return;
     }
 
@@ -731,7 +744,7 @@
             argParcel, no.native_parcel);
 
     if (parcel == NULL) {
-        doThrow(env, "java/lang/NullPointerException", NULL);
+        doThrowNPE(env);
         return;
     }
 
diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
index 3d24bee..61efcf2 100644
--- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
@@ -15,6 +15,7 @@
 ** limitations under the License.
 */
 
+#include "JNIHelp.h"
 #include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/android_view_Surface.h>
 #include <utils/misc.h>
@@ -44,13 +45,6 @@
 static jfieldID gBitmap_NativeBitmapFieldID;
 
 static __attribute__((noinline))
-void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
-{
-    jclass npeClazz = env->FindClass(exc);
-    env->ThrowNew(npeClazz, msg);
-}
-
-static __attribute__((noinline))
 bool hasException(JNIEnv *env) {
     if (env->ExceptionCheck() != 0) {
         env->ExceptionDescribe();
@@ -133,7 +127,7 @@
         jintArray major_minor) {
     if (display == NULL || (major_minor != NULL &&
             _env->GetArrayLength(major_minor) < 2)) {
-        doThrow(_env, "java/lang/IllegalArgumentException");
+        jniThrowException(_env, "java/lang/IllegalArgumentException", NULL);
         return JNI_FALSE;
     }
 
@@ -156,7 +150,7 @@
         jobject context, jint attribute, jintArray value) {
     if (display == NULL || context == NULL || value == NULL
         || _env->GetArrayLength(value) < 1) {
-        doThrow(_env, "java/lang/IllegalArgumentException");
+        jniThrowException(_env, "java/lang/IllegalArgumentException", NULL);
         return JNI_FALSE;
     }
     EGLDisplay dpy = getDisplay(_env, display);
@@ -175,7 +169,7 @@
         jobject surface, jint attribute, jintArray value) {
     if (display == NULL || surface == NULL || value == NULL
         || _env->GetArrayLength(value) < 1) {
-        doThrow(_env, "java/lang/IllegalArgumentException");
+        jniThrowException(_env, "java/lang/IllegalArgumentException", NULL);
         return JNI_FALSE;
     }
     EGLDisplay dpy = getDisplay(_env, display);
@@ -197,7 +191,7 @@
         || !validAttribList(_env, attrib_list)
         || (configs != NULL && _env->GetArrayLength(configs) < config_size)
         || (num_config != NULL && _env->GetArrayLength(num_config) < 1)) {
-        doThrow(_env, "java/lang/IllegalArgumentException");
+        jniThrowException(_env, "java/lang/IllegalArgumentException", NULL);
         return JNI_FALSE;
     }
     EGLDisplay dpy = getDisplay(_env, display);
@@ -230,7 +224,7 @@
         jobject config, jobject share_context, jintArray attrib_list) {
     if (display == NULL || config == NULL || share_context == NULL
         || !validAttribList(_env, attrib_list)) {
-        doThrow(_env, "java/lang/IllegalArgumentException");
+        jniThrowException(_env, "java/lang/IllegalArgumentException", NULL);
         return JNI_FALSE;
     }
     EGLDisplay dpy = getDisplay(_env, display);
@@ -246,7 +240,7 @@
         jobject config, jintArray attrib_list) {
     if (display == NULL || config == NULL
         || !validAttribList(_env, attrib_list)) {
-        doThrow(_env, "java/lang/IllegalArgumentException");
+        jniThrowException(_env, "java/lang/IllegalArgumentException", NULL);
         return JNI_FALSE;
     }
     EGLDisplay dpy = getDisplay(_env, display);
@@ -274,7 +268,7 @@
 {
     if (display == NULL || config == NULL || native_pixmap == NULL
         || !validAttribList(_env, attrib_list)) {
-        doThrow(_env, "java/lang/IllegalArgumentException");
+        jniThrowException(_env, "java/lang/IllegalArgumentException", NULL);
         return;
     }
     EGLDisplay dpy = getDisplay(_env, display);
@@ -286,7 +280,7 @@
                     gBitmap_NativeBitmapFieldID);
     SkPixelRef* ref = nativeBitmap ? nativeBitmap->pixelRef() : 0;
     if (ref == NULL) {
-        doThrow(_env, "java/lang/IllegalArgumentException", "Bitmap has no PixelRef");
+        jniThrowException(_env, "java/lang/IllegalArgumentException", "Bitmap has no PixelRef");
         return;
     }
 
@@ -318,7 +312,7 @@
         jobject config, jobject native_window, jintArray attrib_list) {
     if (display == NULL || config == NULL
         || !validAttribList(_env, attrib_list)) {
-        doThrow(_env, "java/lang/IllegalArgumentException");
+        jniThrowException(_env, "java/lang/IllegalArgumentException", NULL);
         return JNI_FALSE;
     }
     EGLDisplay dpy = getDisplay(_env, display);
@@ -326,7 +320,7 @@
     sp<ANativeWindow> window;
     if (native_window == NULL) {
 not_valid_surface:
-        doThrow(_env, "java/lang/IllegalArgumentException",
+        jniThrowException(_env, "java/lang/IllegalArgumentException",
                 "Make sure the SurfaceView or associated SurfaceHolder has a valid Surface");
         return 0;
     }
@@ -345,7 +339,7 @@
         jobject config, jint attribute, jintArray value) {
     if (display == NULL || config == NULL
         || (value == NULL || _env->GetArrayLength(value) < 1)) {
-        doThrow(_env, "java/lang/IllegalArgumentException");
+        jniThrowException(_env, "java/lang/IllegalArgumentException", NULL);
         return JNI_FALSE;
     }
     EGLDisplay dpy = getDisplay(_env, display);
@@ -363,7 +357,7 @@
         jobjectArray configs, jint config_size, jintArray num_config) {
     if (display == NULL || (configs != NULL && _env->GetArrayLength(configs) < config_size)
         || (num_config != NULL && _env->GetArrayLength(num_config) < 1)) {
-        doThrow(_env, "java/lang/IllegalArgumentException");
+        jniThrowException(_env, "java/lang/IllegalArgumentException", NULL);
         return JNI_FALSE;
     }
     EGLDisplay dpy = getDisplay(_env, display);
@@ -401,7 +395,7 @@
 
 static jint jni_eglGetCurrentSurface(JNIEnv *_env, jobject _this, jint readdraw) {
     if ((readdraw != EGL_READ) && (readdraw != EGL_DRAW)) {
-        doThrow(_env, "java/lang/IllegalArgumentException");
+        jniThrowException(_env, "java/lang/IllegalArgumentException", NULL);
         return 0;
     }
     return (jint)eglGetCurrentSurface(readdraw);
@@ -409,7 +403,7 @@
 
 static jboolean jni_eglDestroyContext(JNIEnv *_env, jobject _this, jobject display, jobject context) {
     if (display == NULL || context == NULL) {
-        doThrow(_env, "java/lang/IllegalArgumentException");
+        jniThrowException(_env, "java/lang/IllegalArgumentException", NULL);
         return JNI_FALSE;
     }
     EGLDisplay dpy = getDisplay(_env, display);
@@ -419,7 +413,7 @@
 
 static jboolean jni_eglDestroySurface(JNIEnv *_env, jobject _this, jobject display, jobject surface) {
     if (display == NULL || surface == NULL) {
-        doThrow(_env, "java/lang/IllegalArgumentException");
+        jniThrowException(_env, "java/lang/IllegalArgumentException", NULL);
         return JNI_FALSE;
     }
     EGLDisplay dpy = getDisplay(_env, display);
@@ -442,7 +436,7 @@
 
 static jboolean jni_eglMakeCurrent(JNIEnv *_env, jobject _this, jobject display, jobject draw, jobject read, jobject context) {
     if (display == NULL || draw == NULL || read == NULL || context == NULL) {
-        doThrow(_env, "java/lang/IllegalArgumentException");
+        jniThrowException(_env, "java/lang/IllegalArgumentException", NULL);
         return JNI_FALSE;
     }
     EGLDisplay dpy = getDisplay(_env, display);
@@ -454,7 +448,7 @@
 
 static jstring jni_eglQueryString(JNIEnv *_env, jobject _this, jobject display, jint name) {
     if (display == NULL) {
-        doThrow(_env, "java/lang/IllegalArgumentException");
+        jniThrowException(_env, "java/lang/IllegalArgumentException", NULL);
         return NULL;
     }
     EGLDisplay dpy = getDisplay(_env, display);
@@ -464,7 +458,7 @@
 
 static jboolean jni_eglSwapBuffers(JNIEnv *_env, jobject _this, jobject display, jobject surface) {
     if (display == NULL || surface == NULL) {
-        doThrow(_env, "java/lang/IllegalArgumentException");
+        jniThrowException(_env, "java/lang/IllegalArgumentException", NULL);
         return JNI_FALSE;
     }
     EGLDisplay dpy = getDisplay(_env, display);
@@ -474,7 +468,7 @@
 
 static jboolean jni_eglTerminate(JNIEnv *_env, jobject _this, jobject display) {
     if (display == NULL) {
-        doThrow(_env, "java/lang/IllegalArgumentException");
+        jniThrowException(_env, "java/lang/IllegalArgumentException", NULL);
         return JNI_FALSE;
     }
     EGLDisplay dpy = getDisplay(_env, display);
@@ -484,7 +478,7 @@
 static jboolean jni_eglCopyBuffers(JNIEnv *_env, jobject _this, jobject display,
         jobject surface, jobject native_pixmap) {
     if (display == NULL || surface == NULL || native_pixmap == NULL) {
-        doThrow(_env, "java/lang/IllegalArgumentException");
+        jniThrowException(_env, "java/lang/IllegalArgumentException", NULL);
         return JNI_FALSE;
     }
     // TODO: Implement this
@@ -546,4 +540,3 @@
             android::classPathName, android::methods, NELEM(android::methods));
     return err;
 }
-
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 12c5940..c6c86b2 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -72,12 +72,6 @@
 
 // ---------------------------------------------------------------------------
 
-static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
-{
-    jclass npeClazz = env->FindClass(exc);
-    env->ThrowNew(npeClazz, msg);
-}
-
 static jfieldID gContextId = 0;
 static jfieldID gNativeBitmapID = 0;
 static jfieldID gTypeNativeCache = 0;
@@ -858,24 +852,24 @@
     AutoJavaStringToUTF8 resNameUTF(_env, resName);
     AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
     jint ret = 0;
-
+    jbyte* script_ptr = NULL;
     jint _exception = 0;
     jint remaining;
-    jbyte* script_ptr;
     if (!scriptRef) {
         _exception = 1;
-        //_env->ThrowNew(IAEClass, "script == null");
+        //jniThrowException(_env, "java/lang/IllegalArgumentException", "script == null");
         goto exit;
     }
     if (length < 0) {
         _exception = 1;
-        //_env->ThrowNew(IAEClass, "length < 0");
+        //jniThrowException(_env, "java/lang/IllegalArgumentException", "length < 0");
         goto exit;
     }
     remaining = _env->GetArrayLength(scriptRef);
     if (remaining < length) {
         _exception = 1;
-        //_env->ThrowNew(IAEClass, "length > script.length - offset");
+        //jniThrowException(_env, "java/lang/IllegalArgumentException",
+        //        "length > script.length - offset");
         goto exit;
     }
     script_ptr = (jbyte *)