Bug 794981 - Part 6: Refactor AndroidBridge to make use of generated code. r=kats
authorChris Kitching <ckitching@mozilla.com>
Mon, 09 Sep 2013 08:57:37 -0400
changeset 146184 6e49ee30a8e11f673f9e25972473b7575f15749d
parent 146183 78aa104740c16f54551b1ba7a918bdb7a193020f
child 146185 130635e9a2c1003ecc34098758cde63004bd31d1
push id25244
push userryanvm@gmail.com
push dateMon, 09 Sep 2013 20:03:14 +0000
treeherdermozilla-central@f320b8c034bd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs794981
milestone26.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 794981 - Part 6: Refactor AndroidBridge to make use of generated code. r=kats
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
widget/android/moz.build
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -168,122 +168,23 @@ AndroidBridge::Init(JNIEnv *jEnv)
     mThread = nullptr;
     mGLControllerObj = nullptr;
     mOpenedGraphicsLibraries = false;
     mHasNativeBitmapAccess = false;
     mHasNativeWindowAccess = false;
     mHasNativeWindowFallback = false;
 
     initInit();
-    mGeckoAppShellClass = getClassGlobalRef("org/mozilla/gecko/GeckoAppShell");
-
-    jNotifyIME = getStaticMethod("notifyIME", "(I)V");
-    jNotifyIMEContext = getStaticMethod("notifyIMEContext", "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
-    jNotifyIMEChange = getStaticMethod("notifyIMEChange", "(Ljava/lang/String;III)V");
-    jAcknowledgeEvent = getStaticMethod("acknowledgeEvent", "()V");
-
-    jEnableLocation = getStaticMethod("enableLocation", "(Z)V");
-    jEnableLocationHighAccuracy = getStaticMethod("enableLocationHighAccuracy", "(Z)V");
-    jEnableSensor = getStaticMethod("enableSensor", "(I)V");
-    jDisableSensor = getStaticMethod("disableSensor", "(I)V");
-    jScheduleRestart = getStaticMethod("scheduleRestart", "()V");
-    jNotifyXreExit = getStaticMethod("onXreExit", "()V");
-    jGetHandlersForMimeType = getStaticMethod("getHandlersForMimeType", "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;");
-    jGetHandlersForURL = getStaticMethod("getHandlersForURL", "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;");
-    jOpenUriExternal = getStaticMethod("openUriExternal", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z");
-    jGetMimeTypeFromExtensions = getStaticMethod("getMimeTypeFromExtensions", "(Ljava/lang/String;)Ljava/lang/String;");
-    jGetExtensionFromMimeType = getStaticMethod("getExtensionFromMimeType", "(Ljava/lang/String;)Ljava/lang/String;");
-    jMoveTaskToBack = getStaticMethod("moveTaskToBack", "()V");
-    jShowAlertNotification = getStaticMethod("showAlertNotification", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
-    jShowFilePickerForExtensions = getStaticMethod("showFilePickerForExtensions", "(Ljava/lang/String;)Ljava/lang/String;");
-    jShowFilePickerForMimeType = getStaticMethod("showFilePickerForMimeType", "(Ljava/lang/String;)Ljava/lang/String;");
-    jShowFilePickerAsync = getStaticMethod("showFilePickerAsync", "(Ljava/lang/String;J)V");
-    jUnlockProfile = getStaticMethod("unlockProfile", "()Z");
-    jKillAnyZombies = getStaticMethod("killAnyZombies", "()V");
-    jAlertsProgressListener_OnProgress = getStaticMethod("alertsProgressListener_OnProgress", "(Ljava/lang/String;JJLjava/lang/String;)V");
-    jCloseNotification = getStaticMethod("closeNotification", "(Ljava/lang/String;)V");
-    jGetDpi = getStaticMethod("getDpi", "()I");
-    jGetScreenDepth = getStaticMethod("getScreenDepth", "()I");
-    jSetFullScreen = getStaticMethod("setFullScreen", "(Z)V");
-    jShowInputMethodPicker = getStaticMethod("showInputMethodPicker", "()V");
-    jNotifyDefaultPrevented = getStaticMethod("notifyDefaultPrevented", "(Z)V");
-    jHideProgressDialog = getStaticMethod("hideProgressDialog", "()V");
-    jPerformHapticFeedback = getStaticMethod("performHapticFeedback", "(Z)V");
-    jVibrate1 = getStaticMethod("vibrate", "(J)V");
-    jVibrateA = getStaticMethod("vibrate", "([JI)V");
-    jCancelVibrate = getStaticMethod("cancelVibrate", "()V");
-    jSetKeepScreenOn = getStaticMethod("setKeepScreenOn", "(Z)V");
-    jIsNetworkLinkUp = getStaticMethod("isNetworkLinkUp", "()Z");
-    jIsNetworkLinkKnown = getStaticMethod("isNetworkLinkKnown", "()Z");
-    jSetSelectedLocale = getStaticMethod("setSelectedLocale", "(Ljava/lang/String;)V");
-    jScanMedia = getStaticMethod("scanMedia", "(Ljava/lang/String;Ljava/lang/String;)V");
-    jGetSystemColors = getStaticMethod("getSystemColors", "()[I");
-    jGetIconForExtension = getStaticMethod("getIconForExtension", "(Ljava/lang/String;I)[B");
-    jCreateShortcut = getStaticMethod("createShortcut", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
-    jGetShowPasswordSetting = getStaticMethod("getShowPasswordSetting", "()Z");
-    jInitCamera = getStaticMethod("initCamera", "(Ljava/lang/String;III)[I");
-    jCloseCamera = getStaticMethod("closeCamera", "()V");
-    jIsTablet = getStaticMethod("isTablet", "()Z");
-    jEnableBatteryNotifications = getStaticMethod("enableBatteryNotifications", "()V");
-    jDisableBatteryNotifications = getStaticMethod("disableBatteryNotifications", "()V");
-    jGetCurrentBatteryInformation = getStaticMethod("getCurrentBatteryInformation", "()[D");
-
-    jHandleGeckoMessage = getStaticMethod("handleGeckoMessage", "(Ljava/lang/String;)Ljava/lang/String;");
-    jCheckUriVisited = getStaticMethod("checkUriVisited", "(Ljava/lang/String;)V");
-    jMarkUriVisited = getStaticMethod("markUriVisited", "(Ljava/lang/String;)V");
-    jSetUriTitle = getStaticMethod("setUriTitle", "(Ljava/lang/String;Ljava/lang/String;)V");
-
-    jSendMessage = getStaticMethod("sendMessage", "(Ljava/lang/String;Ljava/lang/String;I)V");
-    jGetMessage = getStaticMethod("getMessage", "(II)V");
-    jDeleteMessage = getStaticMethod("deleteMessage", "(II)V");
-    jCreateMessageList = getStaticMethod("createMessageList", "(JJ[Ljava/lang/String;IIZI)V");
-    jGetNextMessageinList = getStaticMethod("getNextMessageInList", "(II)V");
-    jClearMessageList = getStaticMethod("clearMessageList", "(I)V");
-
-    jGetCurrentNetworkInformation = getStaticMethod("getCurrentNetworkInformation", "()[D");
-    jEnableNetworkNotifications = getStaticMethod("enableNetworkNotifications", "()V");
-    jDisableNetworkNotifications = getStaticMethod("disableNetworkNotifications", "()V");
-
-    jGetScreenOrientation = getStaticMethod("getScreenOrientation", "()S");
-    jEnableScreenOrientationNotifications = getStaticMethod("enableScreenOrientationNotifications", "()V");
-    jDisableScreenOrientationNotifications = getStaticMethod("disableScreenOrientationNotifications", "()V");
-    jLockScreenOrientation = getStaticMethod("lockScreenOrientation", "(I)V");
-    jUnlockScreenOrientation = getStaticMethod("unlockScreenOrientation", "()V");
-
-    jNotifyWakeLockChanged = getStaticMethod("notifyWakeLockChanged", "(Ljava/lang/String;Ljava/lang/String;)V");
-
-    jGetGfxInfoData = getStaticMethod("getGfxInfoData", "()Ljava/lang/String;");
-    jGetProxyForURI = getStaticMethod("getProxyForURI", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)Ljava/lang/String;");
-    jRegisterSurfaceTextureFrameListener = getStaticMethod("registerSurfaceTextureFrameListener", "(Ljava/lang/Object;I)V");
-    jUnregisterSurfaceTextureFrameListener = getStaticMethod("unregisterSurfaceTextureFrameListener", "(Ljava/lang/Object;)V");
-
-    jPumpMessageLoop = getStaticMethod("pumpMessageLoop", "()Z");
-
-    jAddPluginView = getStaticMethod("addPluginView", "(Landroid/view/View;FFFFZ)V");
-    jRemovePluginView = getStaticMethod("removePluginView", "(Landroid/view/View;Z)V");
-    jGetContext = getStaticMethod("getContext", "()Landroid/content/Context;");
-
+    InitStubs(jEnv);
 
 #ifdef MOZ_WEBSMS_BACKEND
     mAndroidSmsMessageClass = getClassGlobalRef("android/telephony/SmsMessage");
     jCalculateLength = getStaticMethod("calculateLength", "(Ljava/lang/CharSequence;Z)[I");
 #endif
 
-    jGeckoJavaSamplerClass = getClassGlobalRef("org/mozilla/gecko/GeckoJavaSampler");
-    jStart = getStaticMethod("start", "(II)V");
-    jStop = getStaticMethod("stop", "()V");
-    jPause = getStaticMethod("pause", "()V");
-    jUnpause = getStaticMethod("unpause", "()V");
-    jGetThreadName = getStaticMethod("getThreadName", "(I)Ljava/lang/String;");
-    jGetFrameName = getStaticMethod("getFrameName", "(III)Ljava/lang/String;");
-    jGetSampleTime = getStaticMethod("getSampleTime", "(II)D");
-
-    jThumbnailHelperClass = getClassGlobalRef("org/mozilla/gecko/ThumbnailHelper");
-    jNotifyThumbnail = getStaticMethod("notifyThumbnail", "(Ljava/nio/ByteBuffer;IZ)V");
-
     jStringClass = getClassGlobalRef("java/lang/String");
 
     if (!GetStaticIntField("android/os/Build$VERSION", "SDK_INT", &mAPIVersion, jEnv)) {
         ALOG_BRIDGE("Failed to find API version");
     }
 
     jSurfaceClass = getClassGlobalRef("android/view/Surface");
     if (mAPIVersion <= 8 /* Froyo */) {
@@ -293,37 +194,23 @@ AndroidBridge::Init(JNIEnv *jEnv)
 
         // Apparently mNativeSurface doesn't exist in Key Lime Pie, so just clear the
         // exception if we have one and move on.
         if (jEnv->ExceptionCheck()) {
             jEnv->ExceptionClear();
         }
     }
 
-
-    jLayerView = getClassGlobalRef("org/mozilla/gecko/gfx/LayerView");
-
-    getClassGlobalRef("org/mozilla/gecko/gfx/GLController");
-    jProvideEGLSurfaceMethod = getMethod("provideEGLSurface", "()Ljavax/microedition/khronos/egl/EGLSurface;");
-
-    getClassGlobalRef("org/mozilla/gecko/gfx/NativePanZoomController");
-    jRequestContentRepaint = getMethod("requestContentRepaint", "(FFFFF)V");
-    jPostDelayedCallback = getMethod("postDelayedCallback", "(J)V");
-
     jclass eglClass = getClassGlobalRef("com/google/android/gles_jni/EGLSurfaceImpl");
     if (eglClass) {
         jEGLSurfacePointerField = getField("mEGLSurface", "I");
     } else {
         jEGLSurfacePointerField = 0;
     }
 
-    jClipboardClass = getClassGlobalRef("org/mozilla/gecko/util/Clipboard");
-    jClipboardGetText = getStaticMethod("getText", "()Ljava/lang/String;");
-    jClipboardSetText = getStaticMethod("setText", "(Ljava/lang/CharSequence;)V");
-
     InitAndroidJavaWrappers(jEnv);
 
     // jEnv should NOT be cached here by anything -- the jEnv here
     // is not valid for the real gecko main thread, which is set
     // at SetMainThread time.
 
     return true;
 }
@@ -338,180 +225,55 @@ AndroidBridge::SetMainThread(void *thr)
         return (bool) mJNIEnv;
     }
 
     mJNIEnv = nullptr;
     mThread = nullptr;
     return true;
 }
 
-void
-AndroidBridge::NotifyIME(int aType)
-{
-    ALOG_BRIDGE("AndroidBridge::NotifyIME");
-
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(sBridge->mGeckoAppShellClass,
-                              sBridge->jNotifyIME, aType);
-}
-
-jstring NewJavaString(AutoLocalJNIFrame* frame, const PRUnichar* string, uint32_t len) {
-    jstring ret = frame->GetEnv()->NewString(string, len);
-    if (frame->CheckForException())
-        return NULL;
+// Raw JNIEnv variants.
+jstring AndroidBridge::NewJavaString(JNIEnv* env, const PRUnichar* string, uint32_t len) {
+   jstring ret = env->NewString(string, len);
+   if (env->ExceptionCheck()) {
+       ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__);
+       env->ExceptionDescribe();
+       env->ExceptionClear();
+       return NULL;
+    }
     return ret;
 }
 
-jstring NewJavaString(AutoLocalJNIFrame* frame, const nsAString& string) {
+jstring AndroidBridge::NewJavaString(JNIEnv* env, const nsAString& string) {
+    return NewJavaString(env, string.BeginReading(), string.Length());
+}
+
+jstring AndroidBridge::NewJavaString(JNIEnv* env, const char* string) {
+    return NewJavaString(env, NS_ConvertUTF8toUTF16(string));
+}
+
+jstring AndroidBridge::NewJavaString(JNIEnv* env, const nsACString& string) {
+    return NewJavaString(env, NS_ConvertUTF8toUTF16(string));
+}
+
+// AutoLocalJNIFrame variants..
+jstring AndroidBridge::NewJavaString(AutoLocalJNIFrame* frame, const PRUnichar* string, uint32_t len) {
+    return NewJavaString(frame->GetEnv(), string, len);
+}
+
+jstring AndroidBridge::NewJavaString(AutoLocalJNIFrame* frame, const nsAString& string) {
     return NewJavaString(frame, string.BeginReading(), string.Length());
 }
 
-jstring NewJavaString(AutoLocalJNIFrame* frame, const char* string) {
-    return NewJavaString(frame, NS_ConvertUTF8toUTF16(string));
-}
-
-jstring NewJavaString(AutoLocalJNIFrame* frame, const nsACString& string) {
+jstring AndroidBridge::NewJavaString(AutoLocalJNIFrame* frame, const char* string) {
     return NewJavaString(frame, NS_ConvertUTF8toUTF16(string));
 }
 
-void
-AndroidBridge::NotifyIMEContext(int aState, const nsAString& aTypeHint,
-                                const nsAString& aModeHint, const nsAString& aActionHint)
-{
-    ALOG_BRIDGE("AndroidBridge::NotifyIMEContext");
-    if (!sBridge)
-        return;
-
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env);
-
-    jvalue args[4];
-    args[0].i = aState;
-    args[1].l = NewJavaString(&jniFrame, aTypeHint);
-    args[2].l = NewJavaString(&jniFrame, aModeHint);
-    args[3].l = NewJavaString(&jniFrame, aActionHint);
-
-    env->CallStaticVoidMethodA(sBridge->mGeckoAppShellClass,
-                               sBridge->jNotifyIMEContext, args);
-}
-
-void
-AndroidBridge::NotifyIMEChange(const nsAString& aText,
-                               int aStart, int aEnd, int aNewEnd)
-{
-    ALOG_BRIDGE("AndroidBridge::NotifyIMEChange");
-    if (!sBridge)
-        return;
-
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-    AutoLocalJNIFrame jniFrame(env);
-
-    jvalue args[4];
-    args[0].l = NewJavaString(&jniFrame, aText);
-    args[1].i = aStart;
-    args[2].i = aEnd;
-    args[3].i = aNewEnd;
-    env->CallStaticVoidMethodA(sBridge->mGeckoAppShellClass,
-                               sBridge->jNotifyIMEChange, args);
-}
-
-void
-AndroidBridge::AcknowledgeEvent()
-{
-    ALOG_BRIDGE("AndroidBridge::AcknowledgeEvent");
-
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jAcknowledgeEvent);
-}
-
-void
-AndroidBridge::EnableLocation(bool aEnable)
-{
-    ALOG_BRIDGE("AndroidBridge::EnableLocation");
-
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jEnableLocation, aEnable);
-}
-
-void
-AndroidBridge::EnableLocationHighAccuracy(bool aEnable)
-{
-    ALOG_BRIDGE("AndroidBridge::EnableLocationHighAccuracy");
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jEnableLocationHighAccuracy, aEnable);
-}
-
-void
-AndroidBridge::EnableSensor(int aSensorType)
-{
-    ALOG_BRIDGE("AndroidBridge::EnableSensor");
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jEnableSensor, aSensorType);
-}
-
-void
-AndroidBridge::DisableSensor(int aSensorType)
-{
-    ALOG_BRIDGE("AndroidBridge::DisableSensor");
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jDisableSensor, aSensorType);
-}
-
-void
-AndroidBridge::ScheduleRestart()
-{
-    ALOG_BRIDGE("scheduling reboot");
-
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jScheduleRestart);
-}
-
-void
-AndroidBridge::NotifyXreExit()
-{
-    ALOG_BRIDGE("xre exiting");
-
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jNotifyXreExit);
+jstring AndroidBridge::NewJavaString(AutoLocalJNIFrame* frame, const nsACString& string) {
+    return NewJavaString(frame, NS_ConvertUTF8toUTF16(string));
 }
 
 static void
 getHandlersFromStringArray(JNIEnv *aJNIEnv, jobjectArray jArr, jsize aLen,
                            nsIMutableArray *aHandlersArray,
                            nsIHandlerApp **aDefaultApp,
                            const nsAString& aAction = EmptyString(),
                            const nsACString& aMimeType = EmptyCString())
@@ -543,467 +305,277 @@ AndroidBridge::GetHandlersForMimeType(co
                                       const nsAString& aAction)
 {
     ALOG_BRIDGE("AndroidBridge::GetHandlersForMimeType");
 
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return false;
 
-    AutoLocalJNIFrame jniFrame(env);
-    jstring jstrMimeType = NewJavaString(&jniFrame, aMimeType);
-
-    jstring jstrAction = NewJavaString(&jniFrame, aAction);
-
-    jobject obj = env->CallStaticObjectMethod(mGeckoAppShellClass,
-                                              jGetHandlersForMimeType,
-                                              jstrMimeType, jstrAction);
-    if (jniFrame.CheckForException())
-        return false;
-
-    jobjectArray arr = static_cast<jobjectArray>(obj);
+    jobjectArray arr = GetHandlersForMimeTypeWrapper(aMimeType, aAction);
     if (!arr)
         return false;
 
     jsize len = env->GetArrayLength(arr);
 
     if (!aHandlersArray)
         return len > 0;
 
     getHandlersFromStringArray(env, arr, len, aHandlersArray,
                                aDefaultApp, aAction,
                                NS_ConvertUTF16toUTF8(aMimeType));
+
+    env->DeleteLocalRef(arr);
     return true;
 }
 
 bool
 AndroidBridge::GetHandlersForURL(const nsAString& aURL,
                                  nsIMutableArray* aHandlersArray,
                                  nsIHandlerApp **aDefaultApp,
                                  const nsAString& aAction)
 {
     ALOG_BRIDGE("AndroidBridge::GetHandlersForURL");
 
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return false;
 
-    AutoLocalJNIFrame jniFrame(env);
-    jstring jstrScheme = NewJavaString(&jniFrame, aURL);
-    jstring jstrAction = NewJavaString(&jniFrame, aAction);
-
-    jobject obj = env->CallStaticObjectMethod(mGeckoAppShellClass,
-                                              jGetHandlersForURL,
-                                              jstrScheme, jstrAction);
-    if (jniFrame.CheckForException())
-        return false;
-
-    jobjectArray arr = static_cast<jobjectArray>(obj);
+    jobjectArray arr = GetHandlersForURLWrapper(aURL, aAction);
     if (!arr)
         return false;
 
     jsize len = env->GetArrayLength(arr);
 
     if (!aHandlersArray)
         return len > 0;
 
     getHandlersFromStringArray(env, arr, len, aHandlersArray,
                                aDefaultApp, aAction);
+
+    env->DeleteLocalRef(arr);
     return true;
 }
 
-bool
-AndroidBridge::OpenUriExternal(const nsAString& aUriSpec, const nsAString& aMimeType,
-                               const nsAString& aPackageName, const nsAString& aClassName,
-                               const nsAString& aAction, const nsAString& aTitle)
-{
-    ALOG_BRIDGE("AndroidBridge::OpenUriExternal");
-
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return false;
-
-    AutoLocalJNIFrame jniFrame(env);
-
-    jstring jstrUri = NewJavaString(&jniFrame, aUriSpec);
-    jstring jstrType = NewJavaString(&jniFrame, aMimeType);
-
-    jstring jstrPackage = NewJavaString(&jniFrame, aPackageName);
-    jstring jstrClass = NewJavaString(&jniFrame, aClassName);
-    jstring jstrAction = NewJavaString(&jniFrame, aAction);
-    jstring jstrTitle = NewJavaString(&jniFrame, aTitle);
-
-    bool ret = env->CallStaticBooleanMethod(mGeckoAppShellClass,
-                                            jOpenUriExternal,
-                                            jstrUri, jstrType, jstrPackage,
-                                            jstrClass, jstrAction, jstrTitle);
-    if (jniFrame.CheckForException())
-        return false;
-
-    return ret;
-}
-
 void
 AndroidBridge::GetMimeTypeFromExtensions(const nsACString& aFileExt, nsCString& aMimeType)
 {
     ALOG_BRIDGE("AndroidBridge::GetMimeTypeFromExtensions");
 
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
 
-    AutoLocalJNIFrame jniFrame(env);
-    jstring jstrExt = NewJavaString(&jniFrame, aFileExt);
-    jstring jstrType =  static_cast<jstring>(
-        env->CallStaticObjectMethod(mGeckoAppShellClass,
-                                    jGetMimeTypeFromExtensions,
-                                    jstrExt));
-    if (jniFrame.CheckForException())
+    jstring jstrType = GetMimeTypeFromExtensionsWrapper(NS_ConvertUTF8toUTF16(aFileExt));
+    if (!jstrType) {
         return;
-
+    }
     nsJNIString jniStr(jstrType, env);
     CopyUTF16toUTF8(jniStr.get(), aMimeType);
+
+    env->DeleteLocalRef(jstrType);
 }
 
 void
 AndroidBridge::GetExtensionFromMimeType(const nsACString& aMimeType, nsACString& aFileExt)
 {
     ALOG_BRIDGE("AndroidBridge::GetExtensionFromMimeType");
 
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
 
-    AutoLocalJNIFrame jniFrame(env);
-    jstring jstrType = NewJavaString(&jniFrame, aMimeType);
-    jstring jstrExt = static_cast<jstring>(
-        env->CallStaticObjectMethod(mGeckoAppShellClass,
-                                    jGetExtensionFromMimeType,
-                                    jstrType));
-    if (jniFrame.CheckForException())
+    jstring jstrExt = GetExtensionFromMimeTypeWrapper(NS_ConvertUTF8toUTF16(aMimeType));
+    if (!jstrExt) {
         return;
-
+    }
     nsJNIString jniStr(jstrExt, env);
     CopyUTF16toUTF8(jniStr.get(), aFileExt);
-}
 
-void
-AndroidBridge::MoveTaskToBack()
-{
-    ALOG_BRIDGE("AndroidBridge::MoveTaskToBack");
-
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jMoveTaskToBack);
+    env->DeleteLocalRef(jstrExt);
 }
 
 bool
 AndroidBridge::GetClipboardText(nsAString& aText)
 {
     ALOG_BRIDGE("AndroidBridge::GetClipboardText");
 
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return false;
 
-    AutoLocalJNIFrame jniFrame(env);
-    jstring jstrType = static_cast<jstring>(
-        env->CallStaticObjectMethod(jClipboardClass,
-                                    jClipboardGetText));
-    if (jniFrame.CheckForException() || !jstrType)
+    jstring result = GetClipboardTextWrapper();
+    if (!result)
         return false;
 
-    nsJNIString jniStr(jstrType, env);
+    nsJNIString jniStr(result, env);
     aText.Assign(jniStr);
-    return true;
-}
 
-void
-AndroidBridge::SetClipboardText(const nsAString& aText)
-{
-    ALOG_BRIDGE("AndroidBridge::SetClipboardText");
-
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env);
-    jstring jstr = NewJavaString(&jniFrame, aText);
-    env->CallStaticVoidMethod(jClipboardClass, jClipboardSetText, jstr);
+    env->DeleteLocalRef(result);
+    return true;
 }
 
 bool
 AndroidBridge::ClipboardHasText()
 {
     ALOG_BRIDGE("AndroidBridge::ClipboardHasText");
 
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return false;
 
     AutoLocalJNIFrame jniFrame(env);
-    jstring jstrType = static_cast<jstring>(
-        env->CallStaticObjectMethod(jClipboardClass,
-                                    jClipboardGetText));
-    if (jniFrame.CheckForException() || !jstrType)
-        return false;
 
-    return true;
+    jstring jStr = GetClipboardTextWrapper();
+    bool ret = jStr;
+
+    return ret;
 }
 
 void
 AndroidBridge::EmptyClipboard()
 {
     ALOG_BRIDGE("AndroidBridge::EmptyClipboard");
 
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
 
     AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(jClipboardClass, jClipboardSetText, nullptr);
+    env->CallStaticVoidMethod(mClipboardClass, jSetClipboardText, nullptr);
 }
 
 void
 AndroidBridge::ShowAlertNotification(const nsAString& aImageUrl,
                                      const nsAString& aAlertTitle,
                                      const nsAString& aAlertText,
                                      const nsAString& aAlertCookie,
                                      nsIObserver *aAlertListener,
                                      const nsAString& aAlertName)
 {
-    ALOG_BRIDGE("ShowAlertNotification");
-
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env);
-
     if (nsAppShell::gAppShell && aAlertListener) {
         // This will remove any observers already registered for this id
         nsAppShell::gAppShell->PostEvent(AndroidGeckoEvent::MakeAddObserver(aAlertName, aAlertListener));
     }
 
-    jvalue args[5];
-    args[0].l = NewJavaString(&jniFrame, aImageUrl);
-    args[1].l = NewJavaString(&jniFrame, aAlertTitle);
-    args[2].l = NewJavaString(&jniFrame, aAlertText);
-    args[3].l = NewJavaString(&jniFrame, aAlertCookie);
-    args[4].l = NewJavaString(&jniFrame, aAlertName);
-    env->CallStaticVoidMethodA(mGeckoAppShellClass, jShowAlertNotification, args);
+    ShowAlertNotificationWrapper(aImageUrl, aAlertTitle, aAlertText, aAlertCookie, aAlertName);
 }
 
-void
-AndroidBridge::AlertsProgressListener_OnProgress(const nsAString& aAlertName,
-                                                 int64_t aProgress,
-                                                 int64_t aProgressMax,
-                                                 const nsAString& aAlertText)
-{
-    ALOG_BRIDGE("AlertsProgressListener_OnProgress");
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env);
-
-    jstring jstrName = NewJavaString(&jniFrame, aAlertName);
-    jstring jstrText = NewJavaString(&jniFrame, aAlertText);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jAlertsProgressListener_OnProgress,
-                              jstrName, aProgress, aProgressMax, jstrText);
-}
-
-void
-AndroidBridge::CloseNotification(const nsAString& aAlertName)
-{
-    ALOG_BRIDGE("CloseNotification");
-
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env);
-
-    jstring jstrName = NewJavaString(&jniFrame, aAlertName);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jCloseNotification, jstrName);
-}
-
-
 int
 AndroidBridge::GetDPI()
 {
     static int sDPI = 0;
     if (sDPI)
         return sDPI;
 
-    ALOG_BRIDGE("AndroidBridge::GetDPI");
     const int DEFAULT_DPI = 160;
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return DEFAULT_DPI;
-    AutoLocalJNIFrame jniFrame(env);
 
-    sDPI = (int)env->CallStaticIntMethod(mGeckoAppShellClass, jGetDpi);
-    if (jniFrame.CheckForException()) {
-        sDPI = 0;
+    sDPI = GetDpiWrapper();
+    if (!sDPI) {
         return DEFAULT_DPI;
     }
 
     return sDPI;
 }
 
 int
 AndroidBridge::GetScreenDepth()
 {
+    ALOG_BRIDGE("%s", __PRETTY_FUNCTION__);
+
     static int sDepth = 0;
     if (sDepth)
         return sDepth;
 
-    ALOG_BRIDGE("AndroidBridge::GetScreenDepth");
     const int DEFAULT_DEPTH = 16;
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
+
+    sDepth = GetScreenDepthWrapper();
+    if (!sDepth)
         return DEFAULT_DEPTH;
-    AutoLocalJNIFrame jniFrame(env);
-
-    sDepth = (int)env->CallStaticIntMethod(mGeckoAppShellClass, jGetScreenDepth);
-    if (jniFrame.CheckForException()) {
-        sDepth = 0;
-        return DEFAULT_DEPTH;
-    }
 
     return sDepth;
 }
 
 void
 AndroidBridge::ShowFilePickerForExtensions(nsAString& aFilePath, const nsAString& aExtensions)
 {
-    ALOG_BRIDGE("AndroidBridge::ShowFilePickerForExtensions");
-
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
 
-    AutoLocalJNIFrame jniFrame(env);
-    jstring jstrFilers = NewJavaString(&jniFrame, aExtensions);
-    jstring jstr = static_cast<jstring>(env->CallStaticObjectMethod(
-                                            mGeckoAppShellClass,
-                                            jShowFilePickerForExtensions, jstrFilers));
-    if (jniFrame.CheckForException())
+    jstring jstr = ShowFilePickerForExtensionsWrapper(aExtensions);
+    if (jstr == nullptr) {
         return;
+    }
 
     aFilePath.Assign(nsJNIString(jstr, env));
+    env->DeleteLocalRef(jstr);
 }
 
 void
 AndroidBridge::ShowFilePickerForMimeType(nsAString& aFilePath, const nsAString& aMimeType)
 {
-    ALOG_BRIDGE("AndroidBridge::ShowFilePickerForMimeType");
-
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
 
-    AutoLocalJNIFrame jniFrame(env);
-    jstring jstrFilers = NewJavaString(&jniFrame, aMimeType);
-    jstring jstr = static_cast<jstring>(env->CallStaticObjectMethod(
-                                            mGeckoAppShellClass,
-                                            jShowFilePickerForMimeType, jstrFilers));
-    if (jniFrame.CheckForException())
+    jstring jstr = ShowFilePickerForMimeTypeWrapper(aMimeType);
+    if (jstr == nullptr) {
         return;
+    }
 
     aFilePath.Assign(nsJNIString(jstr, env));
+    env->DeleteLocalRef(jstr);
 }
 
 void
 AndroidBridge::ShowFilePickerAsync(const nsAString& aMimeType, nsFilePickerCallback* callback)
 {
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env);
-    jstring jMimeType = NewJavaString(&jniFrame, aMimeType);
     callback->AddRef();
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jShowFilePickerAsync, jMimeType, (jlong) callback);
-}
-
-void
-AndroidBridge::SetFullScreen(bool aFullScreen)
-{
-    ALOG_BRIDGE("AndroidBridge::SetFullScreen");
-
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jSetFullScreen, aFullScreen);
+    ShowFilePickerAsyncWrapper(aMimeType, (int64_t) callback);
 }
 
 void
 AndroidBridge::HideProgressDialogOnce()
 {
     static bool once = false;
     if (once)
         return;
 
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jHideProgressDialog);
-    if (jniFrame.CheckForException())
-        return;
+    HideProgressDialog();
 
     once = true;
 }
 
 void
-AndroidBridge::PerformHapticFeedback(bool aIsLongPress)
+AndroidBridge::Vibrate(const nsTArray<uint32_t>& aPattern)
 {
-    ALOG_BRIDGE("AndroidBridge::PerformHapticFeedback");
+    ALOG_BRIDGE("%s", __PRETTY_FUNCTION__);
+
+    uint32_t len = aPattern.Length();
+    if (!len) {
+        ALOG_BRIDGE("  invalid 0-length array");
+        return;
+    }
 
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
 
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass,
-                              jPerformHapticFeedback, aIsLongPress);
-}
-
-void
-AndroidBridge::Vibrate(const nsTArray<uint32_t>& aPattern)
-{
-    ALOG_BRIDGE("AndroidBridge::Vibrate");
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
     AutoLocalJNIFrame jniFrame(env);
-    uint32_t len = aPattern.Length();
-    if (!len) {
-        ALOG_BRIDGE("  invalid 0-length array");
-        return;
-    }
 
     // It's clear if this worth special-casing, but it creates less
     // java junk, so dodges the GC.
     if (len == 1) {
         jlong d = aPattern[0];
         if (d < 0) {
             ALOG_BRIDGE("  invalid vibration duration < 0");
             return;
         }
-        env->CallStaticVoidMethod(mGeckoAppShellClass, jVibrate1, d);
+        Vibrate1(d);
         return;
     }
 
     // First element of the array vibrate() expects is how long to wait
     // *before* vibrating.  For us, this is always 0.
 
     jlongArray array = env->NewLongArray(len + 1);
     if (!array) {
@@ -1019,100 +591,34 @@ AndroidBridge::Vibrate(const nsTArray<ui
             ALOG_BRIDGE("  invalid vibration duration < 0");
             env->ReleaseLongArrayElements(array, elts, JNI_ABORT);
             return;
         }
         elts[i + 1] = d;
     }
     env->ReleaseLongArrayElements(array, elts, 0);
 
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jVibrateA,
-                              array, -1/*don't repeat*/);
-    // GC owns |array| now?
-}
-
-void
-AndroidBridge::CancelVibrate()
-{
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jCancelVibrate);
-}
-
-bool
-AndroidBridge::IsNetworkLinkUp()
-{
-    ALOG_BRIDGE("AndroidBridge::IsNetworkLinkUp");
-
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return false;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    bool ret = !!env->CallStaticBooleanMethod(mGeckoAppShellClass, jIsNetworkLinkUp);
-    if (jniFrame.CheckForException())
-        return false;
-
-    return ret;
-}
-
-bool
-AndroidBridge::IsNetworkLinkKnown()
-{
-    ALOG_BRIDGE("AndroidBridge::IsNetworkLinkKnown");
-
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return false;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    bool ret = !!env->CallStaticBooleanMethod(mGeckoAppShellClass, jIsNetworkLinkKnown);
-    if (jniFrame.CheckForException())
-        return false;
-
-    return ret;
-}
-
-void
-AndroidBridge::SetSelectedLocale(const nsAString& aLocale)
-{
-    ALOG_BRIDGE("AndroidBridge::SetSelectedLocale");
-
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env);
-    jstring jLocale = NewJavaString(&jniFrame, aLocale);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jSetSelectedLocale, jLocale);
+    VibrateA(array, -1/*don't repeat*/);
 }
 
 void
 AndroidBridge::GetSystemColors(AndroidSystemColors *aColors)
 {
-    ALOG_BRIDGE("AndroidBridge::GetSystemColors");
 
     NS_ASSERTION(aColors != nullptr, "AndroidBridge::GetSystemColors: aColors is null!");
     if (!aColors)
         return;
 
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
 
     AutoLocalJNIFrame jniFrame(env);
 
-    jobject obj = env->CallStaticObjectMethod(mGeckoAppShellClass, jGetSystemColors);
-    if (jniFrame.CheckForException())
-        return;
-
-    jintArray arr = static_cast<jintArray>(obj);
+    jintArray arr = GetSystemColoursWrapper();
     if (!arr)
         return;
 
     uint32_t len = static_cast<uint32_t>(env->GetArrayLength(arr));
     jint *elements = env->GetIntArrayElements(arr, 0);
 
     uint32_t colorsCount = sizeof(AndroidSystemColors) / sizeof(nscolor);
     if (len < colorsCount)
@@ -1140,55 +646,33 @@ AndroidBridge::GetIconForExtension(const
         return;
 
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
 
     AutoLocalJNIFrame jniFrame(env);
 
-    jstring jstrFileExt = NewJavaString(&jniFrame, aFileExt);
+    jbyteArray arr = GetIconForExtensionWrapper(NS_ConvertUTF8toUTF16(aFileExt), aIconSize);
 
-    jobject obj = env->CallStaticObjectMethod(mGeckoAppShellClass, jGetIconForExtension, jstrFileExt, aIconSize);
-    if (jniFrame.CheckForException())
-        return;
-
-    jbyteArray arr = static_cast<jbyteArray>(obj);
     NS_ASSERTION(arr != nullptr, "AndroidBridge::GetIconForExtension: Returned pixels array is null!");
     if (!arr)
         return;
 
     uint32_t len = static_cast<uint32_t>(env->GetArrayLength(arr));
     jbyte *elements = env->GetByteArrayElements(arr, 0);
 
     uint32_t bufSize = aIconSize * aIconSize * 4;
     NS_ASSERTION(len == bufSize, "AndroidBridge::GetIconForExtension: Pixels array is incomplete!");
     if (len == bufSize)
         memcpy(aBuf, elements, bufSize);
 
     env->ReleaseByteArrayElements(arr, elements, 0);
 }
 
-bool
-AndroidBridge::GetShowPasswordSetting()
-{
-    ALOG_BRIDGE("AndroidBridge::GetShowPasswordSetting");
-
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return false;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    bool ret = env->CallStaticBooleanMethod(mGeckoAppShellClass, jGetShowPasswordSetting);
-    if (jniFrame.CheckForException())
-        return false;
-
-    return ret;
-}
-
 void
 AndroidBridge::SetLayerClient(JNIEnv* env, jobject jobj)
 {
     // if resetting is true, that means Android destroyed our GeckoApp activity
     // and we had to recreate it, but all the Gecko-side things were not destroyed.
     // We therefore need to link up the new java objects to Gecko, and that's what
     // we do here.
     bool resetting = (mLayerClient != NULL);
@@ -1208,70 +692,60 @@ AndroidBridge::SetLayerClient(JNIEnv* en
         // since we are re-linking the new java objects to Gecko, we need to get
         // the viewport from the compositor (since the Java copy was thrown away)
         // and we do that by setting the first-paint flag.
         nsWindow::ForceIsFirstPaint();
     }
 }
 
 void
-AndroidBridge::ShowInputMethodPicker()
-{
-    ALOG_BRIDGE("AndroidBridge::ShowInputMethodPicker");
-
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jShowInputMethodPicker);
-}
-
-void
 AndroidBridge::RegisterCompositor(JNIEnv *env)
 {
     ALOG_BRIDGE("AndroidBridge::RegisterCompositor");
     if (mGLControllerObj) {
         // we already have this set up, no need to do it again
         return;
     }
 
     if (!env) {
         env = GetJNIForThread();    // called on the compositor thread
     }
     if (!env) {
         return;
     }
 
-    AutoLocalJNIFrame jniFrame(env);
-
-    jmethodID registerCompositor = env->GetStaticMethodID(jLayerView, "registerCxxCompositor", "()Lorg/mozilla/gecko/gfx/GLController;");
-
-    jobject glController = env->CallStaticObjectMethod(jLayerView, registerCompositor);
-    if (jniFrame.CheckForException())
+    jobject glController = RegisterCompositorWrapper();
+    if (!glController) {
         return;
+    }
 
     mGLControllerObj = env->NewGlobalRef(glController);
+    env->DeleteLocalRef(glController);
 }
 
 EGLSurface
 AndroidBridge::ProvideEGLSurface()
 {
     if (!jEGLSurfacePointerField) {
         return NULL;
     }
     MOZ_ASSERT(mGLControllerObj, "AndroidBridge::ProvideEGLSurface called with a null GL controller ref");
 
     JNIEnv* env = GetJNIForThread(); // called on the compositor thread
-    AutoLocalJNIFrame jniFrame(env);
-    jobject eglSurface = env->CallObjectMethod(mGLControllerObj, jProvideEGLSurfaceMethod);
-    if (jniFrame.CheckForException() || !eglSurface)
+    if (!env) {
+        return NULL;
+    }
+
+    jobject eglSurface = ProvideEGLSurfaceWrapper(mGLControllerObj);
+    if (!eglSurface)
         return NULL;
 
-    return reinterpret_cast<EGLSurface>(env->GetIntField(eglSurface, jEGLSurfacePointerField));
+    EGLSurface ret = reinterpret_cast<EGLSurface>(env->GetIntField(eglSurface, jEGLSurfacePointerField));
+    env->DeleteLocalRef(eglSurface);
+    return ret;
 }
 
 bool
 AndroidBridge::GetStaticIntField(const char *className, const char *fieldName, int32_t* aInt, JNIEnv* jEnv /* = nullptr */)
 {
     ALOG_BRIDGE("AndroidBridge::GetStaticIntField %s", fieldName);
 
     if (!jEnv) {
@@ -1316,79 +790,32 @@ AndroidBridge::GetStaticStringField(cons
     }
 
     jstring jstr = (jstring) jEnv->GetStaticObjectField(jClass, field);
     jEnv->DeleteGlobalRef(jClass);
     if (!jstr)
         return false;
 
     result.Assign(nsJNIString(jstr, jEnv));
+    jEnv->DeleteLocalRef(jstr);
     return true;
 }
 
-void
-AndroidBridge::SetKeepScreenOn(bool on)
-{
-    ALOG_BRIDGE("AndroidBridge::SetKeepScreenOn");
-
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(sBridge->mGeckoAppShellClass,
-                              sBridge->jSetKeepScreenOn, on);
-}
-
 // Available for places elsewhere in the code to link to.
 bool
 mozilla_AndroidBridge_SetMainThread(void *thr)
 {
     return AndroidBridge::Bridge()->SetMainThread(thr);
 }
 
 jclass GetGeckoAppShellClass()
 {
     return mozilla::AndroidBridge::GetGeckoAppShellClass();
 }
 
-void
-AndroidBridge::ScanMedia(const nsAString& aFile, const nsAString& aMimeType)
-{
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env);
-    jstring jstrFile = NewJavaString(&jniFrame, aFile);
-
-    jstring jstrMimeTypes = NewJavaString(&jniFrame, aMimeType);
-
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jScanMedia, jstrFile, jstrMimeTypes);
-}
-
-void
-AndroidBridge::CreateShortcut(const nsAString& aTitle, const nsAString& aURI, const nsAString& aIconData, const nsAString& aIntent)
-{
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env);
-    jstring jstrTitle = NewJavaString(&jniFrame, aTitle);
-    jstring jstrURI = NewJavaString(&jniFrame, aURI);
-    jstring jstrIconData = NewJavaString(&jniFrame, aIconData);
-    jstring jstrIntent = NewJavaString(&jniFrame, aIntent);
-
-    if (!jstrURI || !jstrTitle || !jstrIconData)
-        return;
-
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jCreateShortcut, jstrTitle, jstrURI, jstrIconData, jstrIntent);
-}
-
 void*
 AndroidBridge::GetNativeSurface(JNIEnv* env, jobject surface) {
     if (!env || !mHasNativeWindowFallback || !jSurfacePointerField)
         return nullptr;
 
     return (void*)env->GetIntField(surface, jSurfacePointerField);
 }
 
@@ -1575,24 +1002,18 @@ AndroidBridge::ValidateBitmap(jobject bi
 bool
 AndroidBridge::InitCamera(const nsCString& contentType, uint32_t camera, uint32_t *width, uint32_t *height, uint32_t *fps)
 {
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return false;
 
     AutoLocalJNIFrame jniFrame(env);
-
-    jstring jstrContentType = NewJavaString(&jniFrame, contentType);
+    jintArray arr = InitCameraWrapper(NS_ConvertUTF8toUTF16(contentType), (int32_t) camera, (int32_t) width, (int32_t) height);
 
-    jobject obj = env->CallStaticObjectMethod(mGeckoAppShellClass, jInitCamera, jstrContentType, camera, *width, *height);
-    if (jniFrame.CheckForException())
-        return false;
-
-    jintArray arr = static_cast<jintArray>(obj);
     if (!arr)
         return false;
 
     jint *elements = env->GetIntArrayElements(arr, 0);
 
     *width = elements[1];
     *height = elements[2];
     *fps = elements[3];
@@ -1600,71 +1021,29 @@ AndroidBridge::InitCamera(const nsCStrin
     bool res = elements[0] == 1;
 
     env->ReleaseIntArrayElements(arr, elements, 0);
 
     return res;
 }
 
 void
-AndroidBridge::CloseCamera()
-{
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jCloseCamera);
-}
-
-void
-AndroidBridge::EnableBatteryNotifications()
-{
-    ALOG_BRIDGE("AndroidBridge::EnableBatteryObserver");
-
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jEnableBatteryNotifications);
-}
-
-void
-AndroidBridge::DisableBatteryNotifications()
-{
-    ALOG_BRIDGE("AndroidBridge::DisableBatteryNotifications");
-
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jDisableBatteryNotifications);
-}
-
-void
 AndroidBridge::GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo)
 {
     ALOG_BRIDGE("AndroidBridge::GetCurrentBatteryInformation");
 
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
 
     AutoLocalJNIFrame jniFrame(env);
 
     // To prevent calling too many methods through JNI, the Java method returns
     // an array of double even if we actually want a double and a boolean.
-    jobject obj = env->CallStaticObjectMethod(mGeckoAppShellClass, jGetCurrentBatteryInformation);
-    if (jniFrame.CheckForException())
-        return;
-
-    jdoubleArray arr = static_cast<jdoubleArray>(obj);
+    jdoubleArray arr = GetCurrentBatteryInformationWrapper();
     if (!arr || env->GetArrayLength(arr) != 3) {
         return;
     }
 
     jdouble* info = env->GetDoubleArrayElements(arr, 0);
 
     aBatteryInfo->level() = info[0];
     aBatteryInfo->charging() = info[1] == 1.0f;
@@ -1678,65 +1057,26 @@ AndroidBridge::HandleGeckoMessage(const 
 {
     ALOG_BRIDGE("%s", __PRETTY_FUNCTION__);
 
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
 
     AutoLocalJNIFrame jniFrame(env);
-    jstring jMessage = NewJavaString(&jniFrame, aMessage);
-    jstring returnMessage =  static_cast<jstring>(env->CallStaticObjectMethod(mGeckoAppShellClass, jHandleGeckoMessage, jMessage));
-    if (jniFrame.CheckForException())
+    jstring returnMessage = HandleGeckoMessageWrapper(aMessage);
+
+    if (!returnMessage)
         return;
 
     nsJNIString jniStr(returnMessage, env);
     aRet.Assign(jniStr);
     ALOG_BRIDGE("leaving %s", __PRETTY_FUNCTION__);
 }
 
-void
-AndroidBridge::CheckURIVisited(const nsAString& aURI)
-{
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 1);
-    jstring jstrURI = NewJavaString(&jniFrame, aURI);
-    // If creating the string fails, just bail
-    if (jstrURI)
-        env->CallStaticVoidMethod(mGeckoAppShellClass, jCheckUriVisited, jstrURI);
-}
-
-void
-AndroidBridge::MarkURIVisited(const nsAString& aURI)
-{
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env);
-    jstring jstrURI = NewJavaString(&jniFrame, aURI);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jMarkUriVisited, jstrURI);
-}
-
-void
-AndroidBridge::SetURITitle(const nsAString& aURI, const nsAString& aTitle)
-{
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env);
-    jstring jstrURI = NewJavaString(&jniFrame, aURI);
-    jstring jstrTitle = NewJavaString(&jniFrame, aTitle);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jSetUriTitle, jstrURI, jstrTitle);
-}
-
 nsresult
 AndroidBridge::GetSegmentInfoForText(const nsAString& aText,
                                      nsIMobileMessageCallback* aRequest)
 {
 #ifndef MOZ_WEBSMS_BACKEND
     return NS_ERROR_FAILURE;
 #else
     ALOG_BRIDGE("AndroidBridge::GetSegmentInfoForText");
@@ -1780,63 +1120,45 @@ AndroidBridge::GetSegmentInfoForText(con
 
 void
 AndroidBridge::SendMessage(const nsAString& aNumber,
                            const nsAString& aMessage,
                            nsIMobileMessageCallback* aRequest)
 {
     ALOG_BRIDGE("AndroidBridge::SendMessage");
 
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
     uint32_t requestId;
     if (!QueueSmsRequest(aRequest, &requestId))
         return;
 
-    AutoLocalJNIFrame jniFrame(env);
-    jstring jNumber = NewJavaString(&jniFrame, aNumber);
-    jstring jMessage = NewJavaString(&jniFrame, aMessage);
-
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jSendMessage, jNumber, jMessage, requestId);
+    SendMessageWrapper(aNumber, aMessage, requestId);
 }
 
 void
 AndroidBridge::GetMessage(int32_t aMessageId, nsIMobileMessageCallback* aRequest)
 {
     ALOG_BRIDGE("AndroidBridge::GetMessage");
 
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
     uint32_t requestId;
     if (!QueueSmsRequest(aRequest, &requestId))
         return;
 
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jGetMessage, aMessageId, requestId);
+    GetMessageWrapper(aMessageId, requestId);
 }
 
 void
 AndroidBridge::DeleteMessage(int32_t aMessageId, nsIMobileMessageCallback* aRequest)
 {
     ALOG_BRIDGE("AndroidBridge::DeleteMessage");
 
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
     uint32_t requestId;
     if (!QueueSmsRequest(aRequest, &requestId))
         return;
 
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jDeleteMessage, aMessageId, requestId);
+    DeleteMessageWrapper(aMessageId, requestId);
 }
 
 void
 AndroidBridge::CreateMessageList(const dom::mobilemessage::SmsFilterData& aFilter, bool aReverse,
                                  nsIMobileMessageCallback* aRequest)
 {
     ALOG_BRIDGE("AndroidBridge::CreateMessageList");
 
@@ -1855,50 +1177,31 @@ AndroidBridge::CreateMessageList(const d
                                           jStringClass,
                                           NewJavaString(&jniFrame, EmptyString()));
 
     for (uint32_t i = 0; i < aFilter.numbers().Length(); ++i) {
         env->SetObjectArrayElement(numbers, i,
                                    NewJavaString(&jniFrame, aFilter.numbers()[i]));
     }
 
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jCreateMessageList,
-                              aFilter.startDate(), aFilter.endDate(),
-                              numbers, aFilter.numbers().Length(),
-                              aFilter.delivery(), aReverse, requestId);
+    CreateMessageListWrapper(aFilter.startDate(), aFilter.endDate(),
+                             numbers, aFilter.numbers().Length(),
+                             aFilter.delivery(), aReverse, requestId);
 }
 
 void
 AndroidBridge::GetNextMessageInList(int32_t aListId, nsIMobileMessageCallback* aRequest)
 {
     ALOG_BRIDGE("AndroidBridge::GetNextMessageInList");
 
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
     uint32_t requestId;
     if (!QueueSmsRequest(aRequest, &requestId))
         return;
 
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jGetNextMessageinList, aListId, requestId);
-}
-
-void
-AndroidBridge::ClearMessageList(int32_t aListId)
-{
-    ALOG_BRIDGE("AndroidBridge::ClearMessageList");
-
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jClearMessageList, aListId);
+    GetNextMessageInListWrapper(aListId, requestId);
 }
 
 bool
 AndroidBridge::QueueSmsRequest(nsIMobileMessageCallback* aRequest, uint32_t* aRequestIdOut)
 {
     MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
     MOZ_ASSERT(aRequest && aRequestIdOut);
 
@@ -1939,59 +1242,32 @@ AndroidBridge::GetCurrentNetworkInformat
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return;
 
     AutoLocalJNIFrame jniFrame(env);
 
     // To prevent calling too many methods through JNI, the Java method returns
     // an array of double even if we actually want a double, two booleans, and an integer.
-    jobject obj = env->CallStaticObjectMethod(mGeckoAppShellClass, jGetCurrentNetworkInformation);
-    if (jniFrame.CheckForException())
-        return;
 
-    jdoubleArray arr = static_cast<jdoubleArray>(obj);
+    jdoubleArray arr = GetCurrentNetworkInformationWrapper();
     if (!arr || env->GetArrayLength(arr) != 4) {
         return;
     }
 
     jdouble* info = env->GetDoubleArrayElements(arr, 0);
 
     aNetworkInfo->bandwidth() = info[0];
     aNetworkInfo->canBeMetered() = info[1] == 1.0f;
     aNetworkInfo->isWifi() = info[2] == 1.0f;
     aNetworkInfo->dhcpGateway() = info[3];
 
     env->ReleaseDoubleArrayElements(arr, info, 0);
 }
 
-void
-AndroidBridge::EnableNetworkNotifications()
-{
-    ALOG_BRIDGE("AndroidBridge::EnableNetworkNotifications");
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jEnableNetworkNotifications);
-}
-
-void
-AndroidBridge::DisableNetworkNotifications()
-{
-    ALOG_BRIDGE("AndroidBridge::DisableNetworkNotifications");
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jDisableNetworkNotifications);
-}
-
 void *
 AndroidBridge::LockBitmap(jobject bitmap)
 {
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return nullptr;
 
     AutoLocalJNIFrame jniFrame(env);
@@ -2152,38 +1428,22 @@ AndroidBridge::LockWindow(void *window, 
         *format = info.format;
         *stride = info.s;
     } else return false;
 
     return true;
 }
 
 jobject
-AndroidBridge::GetContext() {
-    JNIEnv *env = GetJNIForThread();
-    if (!env)
-        return 0;
-
-    jobject context = env->CallStaticObjectMethod(mGeckoAppShellClass, jGetContext);
-    if (env->ExceptionCheck()) {
-        env->ExceptionDescribe();
-        env->ExceptionClear();
-        return 0;
-    }
-
-    return context;
-}
-
-jobject
 AndroidBridge::GetGlobalContextRef() {
     JNIEnv *env = GetJNIForThread();
     if (!env)
         return 0;
 
-    AutoLocalJNIFrame jniFrame(env, 0);
+    AutoLocalJNIFrame jniFrame(env, 2);
 
     jobject context = GetContext();
 
     jobject globalRef = env->NewGlobalRef(context);
     MOZ_ASSERT(globalRef);
 
     return globalRef;
 }
@@ -2202,32 +1462,16 @@ AndroidBridge::UnlockWindow(void* window
     } else if (mHasNativeWindowFallback && (err = Surface_unlockAndPost(window)) != 0) {
         ALOG_BRIDGE("Surface_unlockAndPost failed! (error %d)", err);
         return false;
     }
 
     return true;
 }
 
-bool
-AndroidBridge::IsTablet()
-{
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return false;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-
-    bool ret = env->CallStaticBooleanMethod(mGeckoAppShellClass, jIsTablet);
-    if (jniFrame.CheckForException())
-        return false;
-
-    return ret;
-}
-
 void
 AndroidBridge::SetFirstPaintViewport(const LayerIntPoint& aOffset, const CSSToLayerScale& aZoom, const CSSRect& aCssPageRect)
 {
     AndroidGeckoLayerClient *client = mLayerClient;
     if (!client)
         return;
 
     client->SetFirstPaintViewport(aOffset, aZoom, aCssPageRect);
@@ -2314,28 +1558,16 @@ NS_IMETHODIMP nsAndroidBridge::ContentDo
 
 /* boolean isContentDocumentDisplayed(); */
 NS_IMETHODIMP nsAndroidBridge::IsContentDocumentDisplayed(bool *aRet)
 {
     *aRet = AndroidBridge::Bridge()->IsContentDocumentDisplayed();
     return NS_OK;
 }
 
-void
-AndroidBridge::NotifyDefaultPrevented(bool aDefaultPrevented)
-{
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jNotifyDefaultPrevented, (jboolean)aDefaultPrevented);
-}
-
-
 // DO NOT USE THIS unless you need to access JNI from
 // non-main threads.  This is probably not what you want.
 // Questions, ask blassey or dougt.
 
 static void
 JavaThreadDetachFunc(void *arg)
 {
     JNIEnv *env = (JNIEnv*) arg;
@@ -2376,151 +1608,44 @@ extern "C" {
         return jEnv;
     }
 }
 
 uint32_t
 AndroidBridge::GetScreenOrientation()
 {
     ALOG_BRIDGE("AndroidBridge::GetScreenOrientation");
-    JNIEnv* env = GetJNIEnv();
-    if (!env)
-        return dom::eScreenOrientation_None;
 
-    AutoLocalJNIFrame jniFrame(env, 0);
+    int16_t orientation = GetScreenOrientationWrapper();
 
-    jshort orientation = env->CallStaticShortMethod(mGeckoAppShellClass, jGetScreenOrientation);
-    if (jniFrame.CheckForException())
+    if (!orientation)
         return dom::eScreenOrientation_None;
 
     return static_cast<dom::ScreenOrientation>(orientation);
 }
 
 void
-AndroidBridge::EnableScreenOrientationNotifications()
-{
-    ALOG_BRIDGE("AndroidBridge::EnableScreenOrientationNotifications");
-    JNIEnv* env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jEnableScreenOrientationNotifications);
-}
-
-void
-AndroidBridge::DisableScreenOrientationNotifications()
-{
-    ALOG_BRIDGE("AndroidBridge::DisableScreenOrientationNotifications");
-    JNIEnv* env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jDisableScreenOrientationNotifications);
-}
-
-void
-AndroidBridge::LockScreenOrientation(uint32_t aOrientation)
-{
-    ALOG_BRIDGE("AndroidBridge::LockScreenOrientation");
-    JNIEnv* env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jLockScreenOrientation, aOrientation);
-}
-
-void
-AndroidBridge::UnlockScreenOrientation()
-{
-    ALOG_BRIDGE("AndroidBridge::UnlockScreenOrientation");
-    JNIEnv* env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jUnlockScreenOrientation);
-}
-
-bool
-AndroidBridge::PumpMessageLoop()
-{
-    JNIEnv* env = GetJNIEnv();
-    if (!env)
-        return false;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-
-    if ((void*)pthread_self() != mThread)
-        return false;
-
-    return env->CallStaticBooleanMethod(mGeckoAppShellClass, jPumpMessageLoop);
-}
-
-void
-AndroidBridge::NotifyWakeLockChanged(const nsAString& topic, const nsAString& state)
-{
-    JNIEnv* env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env);
-
-    jstring jstrTopic = NewJavaString(&jniFrame, topic);
-    jstring jstrState = NewJavaString(&jniFrame, state);
-
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jNotifyWakeLockChanged, jstrTopic, jstrState);
-}
-
-void
 AndroidBridge::ScheduleComposite()
 {
     nsWindow::ScheduleComposite();
 }
 
 void
-AndroidBridge::RegisterSurfaceTextureFrameListener(jobject surfaceTexture, int id)
-{
-    JNIEnv* env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env);
-
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jRegisterSurfaceTextureFrameListener, surfaceTexture, id);
-}
-
-void
-AndroidBridge::UnregisterSurfaceTextureFrameListener(jobject surfaceTexture)
-{
-    // This function is called on a worker thread when the Flash plugin is unloaded.
-    JNIEnv* env = GetJNIForThread();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env);
-
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jUnregisterSurfaceTextureFrameListener, surfaceTexture);
-}
-
-void
 AndroidBridge::GetGfxInfoData(nsACString& aRet)
 {
     ALOG_BRIDGE("AndroidBridge::GetGfxInfoData");
 
     JNIEnv* env = GetJNIEnv();
     if (!env)
         return;
 
     AutoLocalJNIFrame jniFrame(env);
-    jstring jstrRet = static_cast<jstring>
-        (env->CallStaticObjectMethod(mGeckoAppShellClass, jGetGfxInfoData));
-    if (jniFrame.CheckForException())
+    jstring jstrRet = GetGfxInfoDataWrapper();
+
+    if (!jstrRet)
         return;
 
     nsJNIString jniStr(jstrRet, env);
     CopyUTF16toUTF8(jniStr, aRet);
 }
 
 nsresult
 AndroidBridge::GetProxyForURI(const nsACString & aSpec,
@@ -2529,24 +1654,22 @@ AndroidBridge::GetProxyForURI(const nsAC
                               const int32_t      aPort,
                               nsACString & aResult)
 {
     JNIEnv* env = GetJNIEnv();
     if (!env)
         return NS_ERROR_FAILURE;
 
     AutoLocalJNIFrame jniFrame(env);
+    jstring jstrRet = GetProxyForURIWrapper(NS_ConvertUTF8toUTF16(aSpec),
+                                            NS_ConvertUTF8toUTF16(aScheme),
+                                            NS_ConvertUTF8toUTF16(aHost),
+                                            aPort);
 
-    jstring jSpec = NewJavaString(&jniFrame, aSpec);
-    jstring jScheme = NewJavaString(&jniFrame, aScheme);
-    jstring jHost = NewJavaString(&jniFrame, aHost);
-    jstring jstrRet = static_cast<jstring>
-        (env->CallStaticObjectMethod(mGeckoAppShellClass, jGetProxyForURI, jSpec, jScheme, jHost, aPort));
-
-    if (jniFrame.CheckForException())
+    if (!jstrRet)
         return NS_ERROR_FAILURE;
 
     nsJNIString jniStr(jstrRet, env);
     CopyUTF16toUTF8(jniStr, aResult);
     return NS_OK;
 }
 
 
@@ -2562,115 +1685,39 @@ NS_IMETHODIMP nsAndroidBridge::SetBrowse
 {
     if (nsAppShell::gAppShell)
         nsAppShell::gAppShell->SetBrowserApp(aBrowserApp);
     return NS_OK;
 }
 
 void
 AndroidBridge::AddPluginView(jobject view, const LayoutDeviceRect& rect, bool isFullScreen) {
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env);
-
     nsWindow* win = nsWindow::TopWindow();
     if (!win)
         return;
 
     CSSRect cssRect = rect / CSSToLayoutDeviceScale(win->GetDefaultScale());
-    env->CallStaticVoidMethod(sBridge->mGeckoAppShellClass,
-                              sBridge->jAddPluginView, view,
-                              cssRect.x, cssRect.y, cssRect.width, cssRect.height,
-                              isFullScreen);
-}
-
-void
-AndroidBridge::RemovePluginView(jobject view, bool isFullScreen)
-{
-    JNIEnv *env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(mGeckoAppShellClass, jRemovePluginView, view, isFullScreen);
+    AddPluginViewWrapper(view, cssRect.x, cssRect.y, cssRect.width, cssRect.height, isFullScreen);
 }
 
 extern "C"
 __attribute__ ((visibility("default")))
 jobject JNICALL
 Java_org_mozilla_gecko_GeckoAppShell_allocateDirectBuffer(JNIEnv *env, jclass, jlong size);
 
-void
-AndroidBridge::StartJavaProfiling(int aInterval, int aSamples)
-{
-    JNIEnv* env = GetJNIForThread();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env);
-
-    env->CallStaticVoidMethod(AndroidBridge::Bridge()->jGeckoJavaSamplerClass,
-                              AndroidBridge::Bridge()->jStart,
-                              aInterval, aSamples);
-}
-
-void
-AndroidBridge::StopJavaProfiling()
-{
-    JNIEnv* env = GetJNIForThread();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env);
-
-    env->CallStaticVoidMethod(AndroidBridge::Bridge()->jGeckoJavaSamplerClass,
-                              AndroidBridge::Bridge()->jStop);
-}
-
-void
-AndroidBridge::PauseJavaProfiling()
-{
-    JNIEnv* env = GetJNIForThread();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env);
-
-    env->CallStaticVoidMethod(AndroidBridge::Bridge()->jGeckoJavaSamplerClass,
-                              AndroidBridge::Bridge()->jPause);
-}
-
-void
-AndroidBridge::UnpauseJavaProfiling()
-{
-    JNIEnv* env = GetJNIForThread();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env);
-
-    env->CallStaticVoidMethod(AndroidBridge::Bridge()->jGeckoJavaSamplerClass,
-                              AndroidBridge::Bridge()->jUnpause);
-}
-
 bool
 AndroidBridge::GetThreadNameJavaProfiling(uint32_t aThreadId, nsCString & aResult)
 {
     JNIEnv* env = GetJNIForThread();
     if (!env)
         return false;
 
     AutoLocalJNIFrame jniFrame(env);
 
-    jstring jstrThreadName = static_cast<jstring>(
-        env->CallStaticObjectMethod(AndroidBridge::Bridge()->jGeckoJavaSamplerClass,
-                                    AndroidBridge::Bridge()->jGetThreadName,
-                                    aThreadId));
+    jstring jstrThreadName = GetThreadNameJavaProfilingWrapper(aThreadId);
 
     if (!jstrThreadName)
         return false;
 
     nsJNIString jniStr(jstrThreadName, env);
     CopyUTF16toUTF8(jniStr.get(), aResult);
     return true;
 }
@@ -2680,62 +1727,27 @@ AndroidBridge::GetFrameNameJavaProfiling
                                           uint32_t aFrameId, nsCString & aResult)
 {
     JNIEnv* env = GetJNIForThread();
     if (!env)
         return false;
 
     AutoLocalJNIFrame jniFrame(env);
 
-    jstring jstrSampleName = static_cast<jstring>(
-        env->CallStaticObjectMethod(AndroidBridge::Bridge()->jGeckoJavaSamplerClass,
-                                    AndroidBridge::Bridge()->jGetFrameName,
-                                    aThreadId, aSampleId, aFrameId));
+    jstring jstrSampleName = GetFrameNameJavaProfilingWrapper(aThreadId, aSampleId, aFrameId);
 
     if (!jstrSampleName)
         return false;
 
     nsJNIString jniStr(jstrSampleName, env);
     CopyUTF16toUTF8(jniStr.get(), aResult);
+    env->DeleteLocalRef(jstrSampleName);
     return true;
 }
 
-double
-AndroidBridge::GetSampleTimeJavaProfiling(uint32_t aThreadId, uint32_t aSampleId)
-{
-    JNIEnv* env = GetJNIForThread();
-    if (!env)
-        return 0;
-
-    AutoLocalJNIFrame jniFrame(env);
-
-    jdouble jSampleTime =
-        env->CallStaticDoubleMethod(AndroidBridge::Bridge()->jGeckoJavaSamplerClass,
-                                    AndroidBridge::Bridge()->jGetSampleTime,
-                                    aThreadId, aSampleId);
-
-    return jSampleTime;
-}
-
-void
-AndroidBridge::SendThumbnail(jobject buffer, int32_t tabId, bool success) {
-    // Regardless of whether we successfully captured a thumbnail, we need to
-    // send a response to process the remaining entries in the queue. If we
-    // don't get an env here, we'll stall the thumbnail loop, but there isn't
-    // much we can do about it.
-    JNIEnv* env = GetJNIEnv();
-    if (!env)
-        return;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallStaticVoidMethod(AndroidBridge::Bridge()->jThumbnailHelperClass,
-                              AndroidBridge::Bridge()->jNotifyThumbnail,
-                              buffer, tabId, success);
-}
-
 nsresult AndroidBridge::CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int32_t bufH, int32_t tabId, jobject buffer)
 {
     nsresult rv;
     float scale = 1.0;
 
     if (!buffer)
         return NS_ERROR_FAILURE;
 
@@ -2860,62 +1872,33 @@ AndroidBridge::ProgressiveUpdateCallback
 {
     AndroidGeckoLayerClient *client = mLayerClient;
     if (!client)
         return false;
 
     return client->ProgressiveUpdateCallback(aHasPendingNewThebesContent, aDisplayPort, aDisplayResolution, aDrawingCritical, aViewport, aScaleX, aScaleY);
 }
 
-void
-AndroidBridge::KillAnyZombies()
-{
-    JNIEnv* env = GetJNIEnv();
-    if (!env)
-        return;
-    env->CallStaticVoidMethod(mGeckoAppShellClass, AndroidBridge::Bridge()->jKillAnyZombies);
-}
-
-bool
-AndroidBridge::UnlockProfile()
-{
-    JNIEnv* env = GetJNIEnv();
-    if (!env)
-        return false;
-
-    AutoLocalJNIFrame jniFrame(env, 0);
-    bool ret = env->CallStaticBooleanMethod(mGeckoAppShellClass, jUnlockProfile);
-    if (jniFrame.CheckForException())
-        return false;
-
-    return ret;
-}
-
 jobject
 AndroidBridge::SetNativePanZoomController(jobject obj)
 {
     jobject old = mNativePanZoomController;
     mNativePanZoomController = obj;
     return old;
 }
 
 void
 AndroidBridge::RequestContentRepaint(const mozilla::layers::FrameMetrics& aFrameMetrics)
 {
     ALOG_BRIDGE("AndroidBridge::RequestContentRepaint");
-    JNIEnv* env = GetJNIForThread();    // called on the compositor thread
-    if (!env || !mNativePanZoomController) {
-        return;
-    }
 
     CSSToScreenScale resolution = aFrameMetrics.mZoom;
     ScreenRect dp = (aFrameMetrics.mDisplayPort + aFrameMetrics.mScrollOffset) * resolution;
 
-    AutoLocalJNIFrame jniFrame(env, 0);
-    env->CallVoidMethod(mNativePanZoomController, jRequestContentRepaint,
+    RequestContentRepaintWrapper(mNativePanZoomController,
         dp.x, dp.y, dp.width, dp.height, resolution.scale);
 }
 
 void
 AndroidBridge::HandleDoubleTap(const CSSIntPoint& aPoint)
 {
     nsCString data = nsPrintfCString("{ \"x\": %d, \"y\": %d }", aPoint.x, aPoint.y);
     nsAppShell::gAppShell->PostEvent(AndroidGeckoEvent::MakeBroadcastEvent(
@@ -2944,21 +1927,16 @@ AndroidBridge::SendAsyncScrollDOMEvent(m
                                        const CSSSize& aScrollableSize)
 {
     // FIXME implement this
 }
 
 void
 AndroidBridge::PostDelayedTask(Task* aTask, int aDelayMs)
 {
-    JNIEnv* env = GetJNIForThread();
-    if (!env || !mNativePanZoomController) {
-        return;
-    }
-
     // add the new task into the mDelayedTaskQueue, sorted with
     // the earliest task first in the queue
     DelayedTask* newTask = new DelayedTask(aTask, aDelayMs);
     uint32_t i = 0;
     while (i < mDelayedTaskQueue.Length()) {
         if (newTask->IsEarlierThan(mDelayedTaskQueue[i])) {
             mDelayedTaskQueue.InsertElementAt(i, newTask);
             break;
@@ -2968,18 +1946,17 @@ AndroidBridge::PostDelayedTask(Task* aTa
     if (i == mDelayedTaskQueue.Length()) {
         // this new task will run after all the existing tasks in the queue
         mDelayedTaskQueue.AppendElement(newTask);
     }
     if (i == 0) {
         // if we're inserting it at the head of the queue, notify Java because
         // we need to get a callback at an earlier time than the last scheduled
         // callback
-        AutoLocalJNIFrame jniFrame(env, 0);
-        env->CallVoidMethod(mNativePanZoomController, jPostDelayedCallback, (int64_t)aDelayMs);
+        PostDelayedCallbackWrapper(mNativePanZoomController, (int64_t)aDelayMs);
     }
 }
 
 int64_t
 AndroidBridge::RunDelayedTasks()
 {
     while (mDelayedTaskQueue.Length() > 0) {
         DelayedTask* nextTask = mDelayedTaskQueue[0];
--- a/widget/android/AndroidBridge.h
+++ b/widget/android/AndroidBridge.h
@@ -169,165 +169,92 @@ public:
     // The bridge needs to be constructed via ConstructBridge first,
     // and then once the Gecko main thread is spun up (Gecko side),
     // SetMainThread should be called which will create the JNIEnv for
     // us to use.  toolkit/xre/nsAndroidStartup.cpp calls
     // SetMainThread.
     bool SetMainThread(void *thr);
 
     /* These are all implemented in Java */
-    static void NotifyIME(int aType);
-
-    static void NotifyIMEContext(int aState, const nsAString& aTypeHint,
-                                 const nsAString& aModeHint, const nsAString& aActionHint);
-
-    static void NotifyIMEChange(const nsAString& a0, int32_t a1, int32_t a2, int32_t a3);
-
-    void StartJavaProfiling(int aInterval, int aSamples);
-    void StopJavaProfiling();
-    void PauseJavaProfiling();
-    void UnpauseJavaProfiling();
     bool GetThreadNameJavaProfiling(uint32_t aThreadId, nsCString & aResult);
     bool GetFrameNameJavaProfiling(uint32_t aThreadId, uint32_t aSampleId, uint32_t aFrameId, nsCString & aResult);
-    double GetSampleTimeJavaProfiling(uint32_t aThreadId, uint32_t aSampleId);
 
     nsresult CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int32_t bufH, int32_t tabId, jobject buffer);
-    void SendThumbnail(jobject buffer, int32_t tabId, bool success);
     void GetDisplayPort(bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort);
     void ContentDocumentChanged();
     bool IsContentDocumentDisplayed();
 
     bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const LayerRect& aDisplayPort, float aDisplayResolution, bool aDrawingCritical, gfx::Rect& aViewport, float& aScaleX, float& aScaleY);
 
-    void AcknowledgeEvent();
-
-    void EnableLocation(bool aEnable);
-    void EnableLocationHighAccuracy(bool aEnable);
-
-    void EnableSensor(int aSensorType);
-
-    void DisableSensor(int aSensorType);
-
-    void NotifyXreExit();
-
-    void ScheduleRestart();
-
     void SetLayerClient(JNIEnv* env, jobject jobj);
     AndroidGeckoLayerClient &GetLayerClient() { return *mLayerClient; }
 
     bool GetHandlersForURL(const nsAString& aURL,
                            nsIMutableArray* handlersArray = nullptr,
                            nsIHandlerApp **aDefaultApp = nullptr,
                            const nsAString& aAction = EmptyString());
 
     bool GetHandlersForMimeType(const nsAString& aMimeType,
                                 nsIMutableArray* handlersArray = nullptr,
                                 nsIHandlerApp **aDefaultApp = nullptr,
                                 const nsAString& aAction = EmptyString());
 
-    bool OpenUriExternal(const nsAString& aUriSpec, const nsAString& aMimeType,
-                         const nsAString& aPackageName = EmptyString(),
-                         const nsAString& aClassName = EmptyString(),
-                         const nsAString& aAction = EmptyString(),
-                         const nsAString& aTitle = EmptyString());
-
     void GetMimeTypeFromExtensions(const nsACString& aFileExt, nsCString& aMimeType);
     void GetExtensionFromMimeType(const nsACString& aMimeType, nsACString& aFileExt);
 
-    void MoveTaskToBack();
-
     bool GetClipboardText(nsAString& aText);
-
-    void SetClipboardText(const nsAString& aText);
     
     void EmptyClipboard();
 
     bool ClipboardHasText();
 
     void ShowAlertNotification(const nsAString& aImageUrl,
                                const nsAString& aAlertTitle,
                                const nsAString& aAlertText,
                                const nsAString& aAlertData,
                                nsIObserver *aAlertListener,
                                const nsAString& aAlertName);
 
-    void AlertsProgressListener_OnProgress(const nsAString& aAlertName,
-                                           int64_t aProgress,
-                                           int64_t aProgressMax,
-                                           const nsAString& aAlertText);
-
-    void CloseNotification(const nsAString& aAlertName);
-
     int GetDPI();
     int GetScreenDepth();
 
     void ShowFilePickerForExtensions(nsAString& aFilePath, const nsAString& aExtensions);
     void ShowFilePickerForMimeType(nsAString& aFilePath, const nsAString& aMimeType);
     void ShowFilePickerAsync(const nsAString& aMimeType, nsFilePickerCallback* callback);
 
-    void PerformHapticFeedback(bool aIsLongPress);
-
     void Vibrate(const nsTArray<uint32_t>& aPattern);
-    void CancelVibrate();
-
-    void SetFullScreen(bool aFullScreen);
-
-    void ShowInputMethodPicker();
-
-    void NotifyDefaultPrevented(bool aDefaultPrevented);
 
     void HideProgressDialogOnce();
 
-    bool IsNetworkLinkUp();
-
-    bool IsNetworkLinkKnown();
-
-    void SetSelectedLocale(const nsAString&);
-
     void GetSystemColors(AndroidSystemColors *aColors);
 
     void GetIconForExtension(const nsACString& aFileExt, uint32_t aIconSize, uint8_t * const aBuf);
 
-    bool GetShowPasswordSetting();
-
     // Switch Java to composite with the Gecko Compositor thread
     void RegisterCompositor(JNIEnv* env = NULL);
     EGLSurface ProvideEGLSurface();
 
     bool GetStaticStringField(const char *classID, const char *field, nsAString &result, JNIEnv* env = nullptr);
 
     bool GetStaticIntField(const char *className, const char *fieldName, int32_t* aInt, JNIEnv* env = nullptr);
 
-    void SetKeepScreenOn(bool on);
-
-    void ScanMedia(const nsAString& aFile, const nsAString& aMimeType);
-
-    void CreateShortcut(const nsAString& aTitle, const nsAString& aURI, const nsAString& aIconData, const nsAString& aIntent);
-
     // These next four functions are for native Bitmap access in Android 2.2+
     bool HasNativeBitmapAccess();
 
     bool ValidateBitmap(jobject bitmap, int width, int height);
 
     void *LockBitmap(jobject bitmap);
 
     // Returns a global reference to the Context for Fennec's Activity. The
     // caller is responsible for ensuring this doesn't leak by calling
     // DeleteGlobalRef() when the context is no longer needed.
     jobject GetGlobalContextRef(void);
 
-    // Returns a local reference. Caller must manage this reference
-    jobject GetContext(void);
-
     void UnlockBitmap(jobject bitmap);
 
-    bool UnlockProfile();
-
-    void KillAnyZombies();
-
     /* Copied from Android's native_window.h in newer (platform 9) NDK */
     enum {
         WINDOW_FORMAT_RGBA_8888          = 1,
         WINDOW_FORMAT_RGBX_8888          = 2,
         WINDOW_FORMAT_RGB_565            = 4
     };
 
     bool HasNativeWindowAccess();
@@ -338,96 +265,73 @@ public:
     void *AcquireNativeWindowFromSurfaceTexture(JNIEnv* aEnv, jobject aSurface);
     void ReleaseNativeWindowForSurfaceTexture(void *window);
 
     bool LockWindow(void *window, unsigned char **bits, int *width, int *height, int *format, int *stride);
     bool UnlockWindow(void *window);
     
     void HandleGeckoMessage(const nsAString& message, nsAString &aRet);
 
-    void CheckURIVisited(const nsAString& uri);
-    void MarkURIVisited(const nsAString& uri);
-    void SetURITitle(const nsAString& uri, const nsAString& title);
-
     bool InitCamera(const nsCString& contentType, uint32_t camera, uint32_t *width, uint32_t *height, uint32_t *fps);
 
-    void CloseCamera();
-
-    void EnableBatteryNotifications();
-    void DisableBatteryNotifications();
     void GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo);
 
     nsresult GetSegmentInfoForText(const nsAString& aText,
                                    nsIMobileMessageCallback* aRequest);
     void SendMessage(const nsAString& aNumber, const nsAString& aText,
                      nsIMobileMessageCallback* aRequest);
     void GetMessage(int32_t aMessageId, nsIMobileMessageCallback* aRequest);
     void DeleteMessage(int32_t aMessageId, nsIMobileMessageCallback* aRequest);
     void CreateMessageList(const dom::mobilemessage::SmsFilterData& aFilter,
                            bool aReverse, nsIMobileMessageCallback* aRequest);
     void GetNextMessageInList(int32_t aListId, nsIMobileMessageCallback* aRequest);
-    void ClearMessageList(int32_t aListId);
     already_AddRefed<nsIMobileMessageCallback> DequeueSmsRequest(uint32_t aRequestId);
 
-    bool IsTablet();
-
     void GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInfo);
-    void EnableNetworkNotifications();
-    void DisableNetworkNotifications();
 
     void SetFirstPaintViewport(const LayerIntPoint& aOffset, const CSSToLayerScale& aZoom, const CSSRect& aCssPageRect);
     void SetPageRect(const CSSRect& aCssPageRect);
     void SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
                           bool aLayersUpdated, ScreenPoint& aScrollOffset, CSSToScreenScale& aScale,
                           LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset);
     void SyncFrameMetrics(const ScreenPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect,
                           bool aLayersUpdated, const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
                           bool aIsFirstPaint, LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset);
 
     void AddPluginView(jobject view, const LayoutDeviceRect& rect, bool isFullScreen);
-    void RemovePluginView(jobject view, bool isFullScreen);
 
     // These methods don't use a ScreenOrientation because it's an
     // enum and that would require including the header which requires
     // include IPC headers which requires including basictypes.h which
     // requires a lot of changes...
     uint32_t GetScreenOrientation();
-    void EnableScreenOrientationNotifications();
-    void DisableScreenOrientationNotifications();
-    void LockScreenOrientation(uint32_t aOrientation);
-    void UnlockScreenOrientation();
-
-    bool PumpMessageLoop();
-
-    void NotifyWakeLockChanged(const nsAString& topic, const nsAString& state);
 
     int GetAPIVersion() { return mAPIVersion; }
     bool IsHoneycomb() { return mAPIVersion >= 11 && mAPIVersion <= 13; }
 
     void ScheduleComposite();
-    void RegisterSurfaceTextureFrameListener(jobject surfaceTexture, int id);
-    void UnregisterSurfaceTextureFrameListener(jobject surfaceTexture);
-
-    jclass jGeckoJavaSamplerClass;
-    jmethodID jStart;
-    jmethodID jStop;
-    jmethodID jPause;
-    jmethodID jUnpause;
-    jmethodID jGetThreadName;
-    jmethodID jGetFrameName;
-    jmethodID jGetSampleTime;
 
     void GetGfxInfoData(nsACString& aRet);
     nsresult GetProxyForURI(const nsACString & aSpec,
                             const nsACString & aScheme,
                             const nsACString & aHost,
                             const int32_t      aPort,
                             nsACString & aResult);
 
     // Utility methods.
+    static jstring NewJavaString(JNIEnv* env, const PRUnichar* string, uint32_t len);
+    static jstring NewJavaString(JNIEnv* env, const nsAString& string);
+    static jstring NewJavaString(JNIEnv* env, const char* string);
+    static jstring NewJavaString(JNIEnv* env, const nsACString& string);
+
+    static jstring NewJavaString(AutoLocalJNIFrame* frame, const PRUnichar* string, uint32_t len);
+    static jstring NewJavaString(AutoLocalJNIFrame* frame, const nsAString& string);
+    static jstring NewJavaString(AutoLocalJNIFrame* frame, const char* string);
+    static jstring NewJavaString(AutoLocalJNIFrame* frame, const nsACString& string);
+
     static jclass GetClassGlobalRef(JNIEnv* env, const char* className);
     static jfieldID GetFieldID(JNIEnv* env, jclass jClass, const char* fieldName, const char* fieldType);
     static jfieldID GetStaticFieldID(JNIEnv* env, jclass jClass, const char* fieldName, const char* fieldType);
     static jmethodID GetMethodID(JNIEnv* env, jclass jClass, const char* methodName, const char* methodType);
     static jmethodID GetStaticMethodID(JNIEnv* env, jclass jClass, const char* methodName, const char* methodType);
 protected:
     static StaticRefPtr<AndroidBridge> sBridge;
     nsTArray<nsCOMPtr<nsIMobileMessageCallback> > mSmsRequests;
@@ -436,149 +340,57 @@ protected:
     JavaVM *mJavaVM;
 
     // the JNIEnv for the main thread
     JNIEnv *mJNIEnv;
     void *mThread;
 
     AndroidGeckoLayerClient *mLayerClient;
 
-    // the GeckoAppShell java class
-    jclass mGeckoAppShellClass;
     // the android.telephony.SmsMessage class
     jclass mAndroidSmsMessageClass;
 
     AndroidBridge();
     ~AndroidBridge();
 
+    void InitStubs(JNIEnv *jEnv);
     bool Init(JNIEnv *jEnv);
 
     bool mOpenedGraphicsLibraries;
     void OpenGraphicsLibraries();
     void* GetNativeSurface(JNIEnv* env, jobject surface);
 
     bool mHasNativeBitmapAccess;
     bool mHasNativeWindowAccess;
     bool mHasNativeWindowFallback;
 
     int mAPIVersion;
 
     bool QueueSmsRequest(nsIMobileMessageCallback* aRequest, uint32_t* aRequestIdOut);
 
     // other things
-    jmethodID jNotifyIME;
-    jmethodID jNotifyIMEContext;
-    jmethodID jNotifyIMEChange;
-    jmethodID jAcknowledgeEvent;
-    jmethodID jEnableLocation;
-    jmethodID jEnableLocationHighAccuracy;
-    jmethodID jEnableSensor;
-    jmethodID jDisableSensor;
     jmethodID jNotifyAppShellReady;
-    jmethodID jNotifyXreExit;
-    jmethodID jScheduleRestart;
     jmethodID jGetOutstandingDrawEvents;
-    jmethodID jGetHandlersForMimeType;
-    jmethodID jGetHandlersForURL;
-    jmethodID jOpenUriExternal;
-    jmethodID jGetMimeTypeFromExtensions;
-    jmethodID jGetExtensionFromMimeType;
-    jmethodID jMoveTaskToBack;
-    jmethodID jShowAlertNotification;
-    jmethodID jShowFilePickerForExtensions;
-    jmethodID jShowFilePickerForMimeType;
-    jmethodID jShowFilePickerAsync;
-    jmethodID jUnlockProfile;
-    jmethodID jKillAnyZombies;
-    jmethodID jAlertsProgressListener_OnProgress;
-    jmethodID jCloseNotification;
-    jmethodID jGetDpi;
-    jmethodID jGetScreenDepth;
-    jmethodID jSetFullScreen;
-    jmethodID jShowInputMethodPicker;
-    jmethodID jNotifyDefaultPrevented;
-    jmethodID jHideProgressDialog;
-    jmethodID jPerformHapticFeedback;
-    jmethodID jVibrate1;
-    jmethodID jVibrateA;
-    jmethodID jCancelVibrate;
-    jmethodID jSetKeepScreenOn;
-    jmethodID jIsNetworkLinkUp;
-    jmethodID jIsNetworkLinkKnown;
-    jmethodID jSetSelectedLocale;
-    jmethodID jScanMedia;
-    jmethodID jGetSystemColors;
-    jmethodID jGetIconForExtension;
-    jmethodID jCreateShortcut;
-    jmethodID jGetShowPasswordSetting;
     jmethodID jPostToJavaThread;
-    jmethodID jInitCamera;
-    jmethodID jCloseCamera;
-    jmethodID jIsTablet;
-    jmethodID jEnableBatteryNotifications;
-    jmethodID jDisableBatteryNotifications;
-    jmethodID jGetCurrentBatteryInformation;
-    jmethodID jHandleGeckoMessage;
-    jmethodID jCheckUriVisited;
-    jmethodID jMarkUriVisited;
-    jmethodID jSetUriTitle;
-    jmethodID jAddPluginView;
-    jmethodID jRemovePluginView;
     jmethodID jCreateSurface;
     jmethodID jShowSurface;
     jmethodID jHideSurface;
     jmethodID jDestroySurface;
-    jmethodID jGetProxyForURI;
 
     jmethodID jCalculateLength;
-    jmethodID jSendMessage;
-    jmethodID jGetMessage;
-    jmethodID jDeleteMessage;
-    jmethodID jCreateMessageList;
-    jmethodID jGetNextMessageinList;
-    jmethodID jClearMessageList;
-
-    jmethodID jGetCurrentNetworkInformation;
-    jmethodID jEnableNetworkNotifications;
-    jmethodID jDisableNetworkNotifications;
-
-    jmethodID jGetScreenOrientation;
-    jmethodID jEnableScreenOrientationNotifications;
-    jmethodID jDisableScreenOrientationNotifications;
-    jmethodID jLockScreenOrientation;
-    jmethodID jUnlockScreenOrientation;
-    jmethodID jPumpMessageLoop;
-    jmethodID jNotifyWakeLockChanged;
-    jmethodID jRegisterSurfaceTextureFrameListener;
-    jmethodID jUnregisterSurfaceTextureFrameListener;
-
-    jclass jThumbnailHelperClass;
-    jmethodID jNotifyThumbnail;
-
-    jmethodID jGetContext;
-
-    // for GfxInfo (gfx feature detection and blacklisting)
-    jmethodID jGetGfxInfoData;
 
     // For native surface stuff
     jclass jSurfaceClass;
     jfieldID jSurfacePointerField;
 
     jclass jLayerView;
-    jmethodID jProvideEGLSurfaceMethod;
+
     jfieldID jEGLSurfacePointerField;
     jobject mGLControllerObj;
 
-    jmethodID jRequestContentRepaint;
-    jmethodID jPostDelayedCallback;
-
-    jclass jClipboardClass;
-    jmethodID jClipboardGetText;
-    jmethodID jClipboardSetText;
-
     // some convinient types to have around
     jclass jStringClass;
 
     // calls we've dlopened from libjnigraphics.so
     int (* AndroidBitmap_getInfo)(JNIEnv *env, jobject bitmap, void *info);
     int (* AndroidBitmap_lockPixels)(JNIEnv *env, jobject bitmap, void **buffer);
     int (* AndroidBitmap_unlockPixels)(JNIEnv *env, jobject bitmap);
 
@@ -598,16 +410,17 @@ protected:
 private:
     jobject mNativePanZoomController;
     // This will always be accessed from one thread (the APZC "controller"
     // thread, which is the Java UI thread), so we don't need to do locking
     // to touch it
     nsTArray<DelayedTask*> mDelayedTaskQueue;
 
 public:
+    #include "GeneratedJNIWrappers.h"
     jobject SetNativePanZoomController(jobject obj);
     // GeckoContentController methods
     void RequestContentRepaint(const mozilla::layers::FrameMetrics& aFrameMetrics) MOZ_OVERRIDE;
     void HandleDoubleTap(const CSSIntPoint& aPoint) MOZ_OVERRIDE;
     void HandleSingleTap(const CSSIntPoint& aPoint) MOZ_OVERRIDE;
     void HandleLongTap(const CSSIntPoint& aPoint) MOZ_OVERRIDE;
     void SendAsyncScrollDOMEvent(mozilla::layers::FrameMetrics::ViewID aScrollId,
                                  const CSSRect& aContentRect,
--- a/widget/android/moz.build
+++ b/widget/android/moz.build
@@ -11,25 +11,27 @@ XPIDL_SOURCES += [
 XPIDL_MODULE = 'widget_android'
 
 MODULE = 'widget'
 
 EXPORTS += [
     'AndroidBridge.h',
     'AndroidJNIWrapper.h',
     'AndroidJavaWrappers.h',
+    'GeneratedJNIWrappers.h'
 ]
 
 CPP_SOURCES += [
     'AndroidBridge.cpp',
     'AndroidDirectTexture.cpp',
     'AndroidGraphicBuffer.cpp',
     'AndroidJNI.cpp',
     'AndroidJNIWrapper.cpp',
     'AndroidJavaWrappers.cpp',
+    'GeneratedJNIWrappers.cpp',
     'GfxInfo.cpp',
     'nsAppShell.cpp',
     'nsClipboard.cpp',
     'nsDeviceContextAndroid.cpp',
     'nsIMEPicker.cpp',
     'nsIdleServiceAndroid.cpp',
     'nsLookAndFeel.cpp',
     'nsPrintOptionsAndroid.cpp',