Backed out 7 changesets (bug 1086693) for Android bustage on a CLOSED TREE. DONTBUILD
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 11 Nov 2014 16:13:15 -0500
changeset 226467 12c9b418a8fcc0bea197c4ad26de533456e906f8
parent 226466 6eed18d830d2bfd947ff0099fee113ae4ad821c1
child 226468 feba300a5eec8d9e406084473e3990049809aed9
push id53
push userdglastonbury@mozilla.com
push dateWed, 12 Nov 2014 02:04:58 +0000
bugs1086693
milestone36.0a1
backs out6eed18d830d2bfd947ff0099fee113ae4ad821c1
b67a2e48f281b5d88d931cb14e04fdfd73e9f624
2b4b439e7e6ca6b45bb8b3e17ac94a7bd4f6799d
3adfd767a92f06dcca70454af5b68832f9dc2f4b
6ea8b92479154feef7127d3b838434e3a420d566
408af1e3b457143e1cc6daa4f647436b6ade8329
4c759b83892a4c767dc82b56be71fd781f7b28cd
Backed out 7 changesets (bug 1086693) for Android bustage on a CLOSED TREE. DONTBUILD Backed out changeset 6eed18d830d2 (bug 1086693) Backed out changeset b67a2e48f281 (bug 1086693) Backed out changeset 2b4b439e7e6c (bug 1086693) Backed out changeset 3adfd767a92f (bug 1086693) Backed out changeset 6ea8b9247915 (bug 1086693) Backed out changeset 408af1e3b457 (bug 1086693) Backed out changeset 4c759b83892a (bug 1086693)
build/annotationProcessors/AnnotationInfo.java
build/annotationProcessors/AnnotationProcessor.java
build/annotationProcessors/CodeGenerator.java
build/annotationProcessors/Makefile.in
build/annotationProcessors/SDKProcessor.java
build/annotationProcessors/moz.build
build/annotationProcessors/utils/GeneratableElementIterator.java
build/annotationProcessors/utils/Utils.java
config/recurse.mk
dom/media/fmp4/android/AndroidDecoderModule.cpp
dom/media/fmp4/android/AndroidDecoderModule.h
dom/plugins/base/nsNPAPIPluginInstance.cpp
dom/plugins/base/nsNPAPIPluginInstance.h
gfx/gl/AndroidSurfaceTexture.cpp
gfx/gl/AndroidSurfaceTexture.h
gfx/gl/GLBlitHelper.cpp
gfx/layers/opengl/TextureHostOGL.cpp
mobile/android/base/Makefile.in
mobile/android/base/mozglue/generatorannotations/WrapElementForJNI.java
widget/android/AndroidBridge.cpp
widget/android/AndroidJavaWrappers.cpp
widget/android/GeneratedJNIWrappers.cpp
widget/android/GeneratedJNIWrappers.h
widget/android/GeneratedSDKWrappers.cpp
widget/android/GeneratedSDKWrappers.h
widget/android/bindings/Makefile.in
widget/android/bindings/mediacodec-classes.txt
widget/android/bindings/moz.build
widget/android/bindings/surfacetexture-classes.txt
widget/android/moz.build
--- a/build/annotationProcessors/AnnotationInfo.java
+++ b/build/annotationProcessors/AnnotationInfo.java
@@ -7,24 +7,17 @@ package org.mozilla.gecko.annotationProc
 /**
  * Object holding annotation data. Used by GeneratableElementIterator.
  */
 public class AnnotationInfo {
     public final String wrapperName;
     public final boolean isMultithreaded;
     public final boolean noThrow;
     public final boolean narrowChars;
-    public final boolean catchException;
 
     public AnnotationInfo(String aWrapperName, boolean aIsMultithreaded,
-                          boolean aNoThrow, boolean aNarrowChars, boolean aCatchException) {
+                          boolean aNoThrow, boolean aNarrowChars) {
         wrapperName = aWrapperName;
         isMultithreaded = aIsMultithreaded;
         noThrow = aNoThrow;
         narrowChars = aNarrowChars;
-        catchException = aCatchException;
-
-        if (!noThrow && catchException) {
-            // It doesn't make sense to have these together
-            throw new IllegalArgumentException("noThrow and catchException are not allowed together");
-        }
     }
 }
--- a/build/annotationProcessors/AnnotationProcessor.java
+++ b/build/annotationProcessors/AnnotationProcessor.java
@@ -47,46 +47,46 @@ public class AnnotationProcessor {
         headerFile.append("#ifndef GeneratedJNIWrappers_h__\n" +
                           "#define GeneratedJNIWrappers_h__\n\n" +
                           "#include \"nsXPCOMStrings.h\"\n" +
                           "#include \"AndroidJavaWrappers.h\"\n" +
                           "\n" +
                           "namespace mozilla {\n" +
                           "namespace widget {\n" +
                           "namespace android {\n" +
-                          "void InitStubs(JNIEnv *env);\n\n");
+                          "void InitStubs(JNIEnv *jEnv);\n\n");
 
         StringBuilder implementationFile = new StringBuilder(GENERATED_COMMENT);
         implementationFile.append("#include \"GeneratedJNIWrappers.h\"\n" +
                                   "#include \"AndroidBridgeUtilities.h\"\n" +
                                   "#include \"nsXPCOMStrings.h\"\n" +
                                   "#include \"AndroidBridge.h\"\n" +
                                   "\n" +
                                   "namespace mozilla {\n" +
                                   "namespace widget {\n" +
                                   "namespace android {\n");
 
         // Used to track the calls to the various class-specific initialisation functions.
         StringBuilder stubInitialiser = new StringBuilder();
-        stubInitialiser.append("void InitStubs(JNIEnv *env) {\n");
+        stubInitialiser.append("void InitStubs(JNIEnv *jEnv) {\n");
 
         while (jarClassIterator.hasNext()) {
             ClassWithOptions aClassTuple = jarClassIterator.next();
 
             CodeGenerator generatorInstance;
 
             // Get an iterator over the appropriately generated methods of this class
             Iterator<AnnotatableEntity> methodIterator = new GeneratableElementIterator(aClassTuple.wrappedClass);
 
             if (!methodIterator.hasNext()) {
                 continue;
             }
             generatorInstance = new CodeGenerator(aClassTuple.wrappedClass, aClassTuple.generatedName);
 
-            stubInitialiser.append("    ").append(aClassTuple.generatedName).append("::InitStubs(env);\n");
+            stubInitialiser.append("    ").append(aClassTuple.generatedName).append("::InitStubs(jEnv);\n");
 
             // Iterate all annotated members in this class..
             while (methodIterator.hasNext()) {
                 AnnotatableEntity aElementTuple = methodIterator.next();
                 switch (aElementTuple.mEntityType) {
                     case METHOD:
                         generatorInstance.generateMethod(aElementTuple);
                         break;
--- a/build/annotationProcessors/CodeGenerator.java
+++ b/build/annotationProcessors/CodeGenerator.java
@@ -7,17 +7,16 @@ package org.mozilla.gecko.annotationProc
 import org.mozilla.gecko.annotationProcessors.classloader.AnnotatableEntity;
 import org.mozilla.gecko.annotationProcessors.utils.Utils;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Member;
 import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
 import java.util.HashMap;
 import java.util.HashSet;
 
 public class CodeGenerator {
     private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
     private static final Annotation[][] GETTER_ARGUMENT_ANNOTATIONS = new Annotation[0][0];
     private static final Annotation[][] SETTER_ARGUMENT_ANNOTATIONS = new Annotation[1][0];
 
@@ -36,37 +35,31 @@ public class CodeGenerator {
 
     private boolean mHasEncounteredDefaultConstructor;
 
     // Used for creating unique names for method ID fields in the face of
     private final HashMap<Member, String> mMembersToIds = new HashMap<Member, String>();
     private final HashSet<String> mTakenMemberNames = new HashSet<String>();
     private int mNameMunger;
 
-    private final boolean mLazyInit;
-
     public CodeGenerator(Class<?> aClass, String aGeneratedName) {
-        this(aClass, aGeneratedName, false);
-    }
-
-    public CodeGenerator(Class<?> aClass, String aGeneratedName, boolean aLazyInit) {
         mClassToWrap = aClass;
         mCClassName = aGeneratedName;
-        mLazyInit = aLazyInit;
 
         // Write the file header things. Includes and so forth.
         // GeneratedJNIWrappers.cpp is generated as the concatenation of wrapperStartupCode with
         // wrapperMethodBodies. Similarly, GeneratedJNIWrappers.h is the concatenation of headerPublic
         // with headerProtected.
-        wrapperStartupCode.append("void ").append(mCClassName).append("::InitStubs(JNIEnv *env) {\n");
+        wrapperStartupCode.append("void ").append(mCClassName).append("::InitStubs(JNIEnv *jEnv) {\n" +
+                                  "    initInit();\n");
 
         // Now we write the various GetStaticMethodID calls here...
         headerPublic.append("class ").append(mCClassName).append(" : public AutoGlobalWrappedJavaObject {\n" +
                             "public:\n" +
-                            "    static void InitStubs(JNIEnv *env);\n");
+                            "    static void InitStubs(JNIEnv *jEnv);\n");
         headerProtected.append("protected:");
 
         generateWrapperMethod();
     }
 
     /**
      * Emit a static method which takes an instance of the class being wrapped and returns an instance
      * of the C++ wrapper class backed by that object.
@@ -81,20 +74,17 @@ public class CodeGenerator {
                 "    env->DeleteLocalRef(obj);\n" +
                 "    return ret;\n" +
                 "}\n");
     }
 
     private void generateMemberCommon(Member theMethod, String aCMethodName, Class<?> aClass) {
         ensureClassHeaderAndStartup(aClass);
         writeMemberIdField(theMethod, aCMethodName);
-
-        if (!mLazyInit) {
-            writeMemberInit(theMethod, wrapperStartupCode);
-        }
+        writeStartupCode(theMethod);
     }
 
     /**
      * Append the appropriate generated code to the buffers for the method provided.
      *
      * @param aMethodTuple The Java method, plus annotation data.
      */
     public void generateMethod(AnnotatableEntity aMethodTuple) {
@@ -106,64 +96,56 @@ public class CodeGenerator {
         generateMemberCommon(theMethod, CMethodName, mClassToWrap);
 
         boolean isFieldStatic = Utils.isMemberStatic(theMethod);
 
         Class<?>[] parameterTypes = theMethod.getParameterTypes();
         Class<?> returnType = theMethod.getReturnType();
 
         // Get the C++ method signature for this method.
-        String implementationSignature = Utils.getCImplementationMethodSignature(parameterTypes, returnType, CMethodName,
-            mCClassName, aMethodTuple.mAnnotationInfo.narrowChars, aMethodTuple.mAnnotationInfo.catchException);
-        String headerSignature = Utils.getCHeaderMethodSignature(parameterTypes, theMethod.getParameterAnnotations(), returnType,
-            CMethodName, mCClassName, isFieldStatic, aMethodTuple.mAnnotationInfo.narrowChars, aMethodTuple.mAnnotationInfo.catchException);
+        String implementationSignature = Utils.getCImplementationMethodSignature(parameterTypes, returnType, CMethodName, mCClassName, aMethodTuple.mAnnotationInfo.narrowChars);
+        String headerSignature = Utils.getCHeaderMethodSignature(parameterTypes, theMethod.getParameterAnnotations(), returnType, CMethodName, mCClassName, isFieldStatic, aMethodTuple.mAnnotationInfo.narrowChars);
 
         // Add the header signature to the header file.
         writeSignatureToHeader(headerSignature);
 
         // Use the implementation signature to generate the method body...
         writeMethodBody(implementationSignature, theMethod, mClassToWrap,
                         aMethodTuple.mAnnotationInfo.isMultithreaded,
                         aMethodTuple.mAnnotationInfo.noThrow,
-                        aMethodTuple.mAnnotationInfo.narrowChars,
-                        aMethodTuple.mAnnotationInfo.catchException);
+                        aMethodTuple.mAnnotationInfo.narrowChars);
     }
 
-    private void generateGetterOrSetterBody(Field aField, String aFieldName, boolean aIsFieldStatic, boolean isSetter, boolean aNarrowChars) {
+    private void generateGetterOrSetterBody(Class<?> aFieldType, String aFieldName, boolean aIsFieldStatic, boolean isSetter, boolean aNarrowChars) {
         StringBuilder argumentContent = null;
-        Class<?> fieldType = aField.getType();
 
         if (isSetter) {
-            Class<?>[] setterArguments = new Class<?>[]{fieldType};
+            Class<?>[] setterArguments = new Class<?>[]{aFieldType};
             // Marshall the argument..
             argumentContent = getArgumentMarshalling(setterArguments);
         }
 
-        if (mLazyInit) {
-            writeMemberInit(aField, wrapperMethodBodies);
-        }
-
-        boolean isObjectReturningMethod = Utils.isObjectType(fieldType);
+        boolean isObjectReturningMethod = Utils.isObjectType(aFieldType);
         wrapperMethodBodies.append("    ");
         if (isSetter) {
             wrapperMethodBodies.append("env->Set");
         } else {
             wrapperMethodBodies.append("return ");
 
             if (isObjectReturningMethod) {
-                wrapperMethodBodies.append("static_cast<").append(Utils.getCReturnType(fieldType, aNarrowChars)).append(">(");
+                wrapperMethodBodies.append("static_cast<").append(Utils.getCReturnType(aFieldType, aNarrowChars)).append(">(");
             }
 
             wrapperMethodBodies.append("env->Get");
         }
 
         if (aIsFieldStatic) {
             wrapperMethodBodies.append("Static");
         }
-        wrapperMethodBodies.append(Utils.getFieldType(fieldType))
+        wrapperMethodBodies.append(Utils.getFieldType(aFieldType))
                            .append("Field(");
 
         // Static will require the class and the field id. Nonstatic, the object and the field id.
         if (aIsFieldStatic) {
             wrapperMethodBodies.append(Utils.getClassReferenceName(mClassToWrap));
         } else {
             wrapperMethodBodies.append("wrapped_obj");
         }
@@ -194,95 +176,69 @@ public class CodeGenerator {
         Class<?> fieldType = theField.getType();
 
         generateMemberCommon(theField, CFieldName, mClassToWrap);
 
         boolean isFieldStatic = Utils.isMemberStatic(theField);
         boolean isFieldFinal = Utils.isMemberFinal(theField);
 
         String getterName = "get" + CFieldName;
-        String getterSignature = Utils.getCImplementationMethodSignature(EMPTY_CLASS_ARRAY, fieldType, getterName, mCClassName, aFieldTuple.mAnnotationInfo.narrowChars, false);
-        String getterHeaderSignature = Utils.getCHeaderMethodSignature(EMPTY_CLASS_ARRAY, GETTER_ARGUMENT_ANNOTATIONS, fieldType, getterName, mCClassName, isFieldStatic, aFieldTuple.mAnnotationInfo.narrowChars, false);
+        String getterSignature = Utils.getCImplementationMethodSignature(EMPTY_CLASS_ARRAY, fieldType, getterName, mCClassName, aFieldTuple.mAnnotationInfo.narrowChars);
+        String getterHeaderSignature = Utils.getCHeaderMethodSignature(EMPTY_CLASS_ARRAY, GETTER_ARGUMENT_ANNOTATIONS, fieldType, getterName, mCClassName, isFieldStatic, aFieldTuple.mAnnotationInfo.narrowChars);
 
         writeSignatureToHeader(getterHeaderSignature);
 
         writeFunctionStartupBoilerPlate(getterSignature, true);
 
-        generateGetterOrSetterBody(theField, CFieldName, isFieldStatic, false, aFieldTuple.mAnnotationInfo.narrowChars);
+        generateGetterOrSetterBody(fieldType, CFieldName, isFieldStatic, false, aFieldTuple.mAnnotationInfo.narrowChars);
 
         // If field not final, also generate a setter function.
         if (!isFieldFinal) {
             String setterName = "set" + CFieldName;
 
             Class<?>[] setterArguments = new Class<?>[]{fieldType};
 
-            String setterSignature = Utils.getCImplementationMethodSignature(setterArguments, Void.class, setterName, mCClassName, aFieldTuple.mAnnotationInfo.narrowChars, false);
-            String setterHeaderSignature = Utils.getCHeaderMethodSignature(setterArguments, SETTER_ARGUMENT_ANNOTATIONS, Void.class, setterName, mCClassName, isFieldStatic, aFieldTuple.mAnnotationInfo.narrowChars, false);
+            String setterSignature = Utils.getCImplementationMethodSignature(setterArguments, Void.class, setterName, mCClassName, aFieldTuple.mAnnotationInfo.narrowChars);
+            String setterHeaderSignature = Utils.getCHeaderMethodSignature(setterArguments, SETTER_ARGUMENT_ANNOTATIONS, Void.class, setterName, mCClassName, isFieldStatic, aFieldTuple.mAnnotationInfo.narrowChars);
 
             writeSignatureToHeader(setterHeaderSignature);
 
             writeFunctionStartupBoilerPlate(setterSignature, true);
 
-            generateGetterOrSetterBody(theField, CFieldName, isFieldStatic, true, aFieldTuple.mAnnotationInfo.narrowChars);
+            generateGetterOrSetterBody(fieldType, CFieldName, isFieldStatic, true, aFieldTuple.mAnnotationInfo.narrowChars);
         }
     }
 
     public void generateConstructor(AnnotatableEntity aCtorTuple) {
         // Unpack the tuple and extract some useful fields from the Method..
         Constructor<?> theCtor = aCtorTuple.getConstructor();
         String CMethodName = mCClassName;
 
         generateMemberCommon(theCtor, mCClassName, mClassToWrap);
 
-        String implementationSignature = Utils.getCImplementationMethodSignature(theCtor.getParameterTypes(), Void.class, CMethodName,
-            mCClassName, aCtorTuple.mAnnotationInfo.narrowChars, aCtorTuple.mAnnotationInfo.catchException);
-        String headerSignature = Utils.getCHeaderMethodSignature(theCtor.getParameterTypes(), theCtor.getParameterAnnotations(), Void.class, CMethodName,
-            mCClassName, false, aCtorTuple.mAnnotationInfo.narrowChars, aCtorTuple.mAnnotationInfo.catchException);
+        String implementationSignature = Utils.getCImplementationMethodSignature(theCtor.getParameterTypes(), Void.class, CMethodName, mCClassName, aCtorTuple.mAnnotationInfo.narrowChars);
+        String headerSignature = Utils.getCHeaderMethodSignature(theCtor.getParameterTypes(), theCtor.getParameterAnnotations(), Void.class, CMethodName, mCClassName, false, aCtorTuple.mAnnotationInfo.narrowChars);
 
         // Slice off the "void " from the start of the constructor declaration.
         headerSignature = headerSignature.substring(5);
         implementationSignature = implementationSignature.substring(5);
 
         // Add the header signatures to the header file.
         writeSignatureToHeader(headerSignature);
 
         // Use the implementation signature to generate the method body...
         writeCtorBody(implementationSignature, theCtor,
             aCtorTuple.mAnnotationInfo.isMultithreaded,
-            aCtorTuple.mAnnotationInfo.noThrow,
-            aCtorTuple.mAnnotationInfo.catchException);
+            aCtorTuple.mAnnotationInfo.noThrow);
 
         if (theCtor.getParameterTypes().length == 0) {
             mHasEncounteredDefaultConstructor = true;
         }
     }
 
-    public void generateMembers(Member[] members) {
-        for (Member m : members) {
-            if (!Modifier.isPublic(m.getModifiers())) {
-                continue;
-            }
-
-            String name = m.getName();
-            name = name.substring(0, 1).toUpperCase() + name.substring(1);
-
-            AnnotationInfo info = new AnnotationInfo(name, true, true, true, true);
-            AnnotatableEntity entity = new AnnotatableEntity(m, info);
-            if (m instanceof Constructor) {
-                generateConstructor(entity);
-            } else if (m instanceof Method) {
-                generateMethod(entity);
-            } else if (m instanceof Field) {
-                generateField(entity);
-            } else {
-                throw new IllegalArgumentException("expected member to be Constructor, Method, or Field");
-            }
-        }
-    }
-
     /**
      * Writes the appropriate header and startup code to ensure the existence of a reference to the
      * class specified. If this is already done, does nothing.
      *
      * @param aClass The target class.
      */
     private void ensureClassHeaderAndStartup(Class<?> aClass) {
         String className = aClass.getCanonicalName();
@@ -297,17 +253,18 @@ public class CodeGenerator {
                    .append(" = 0;\n");
 
         // Add a field to hold the reference...
         headerProtected.append("\n    static jclass ")
                        .append(Utils.getClassReferenceName(aClass))
                        .append(";\n");
 
         // Add startup code to populate it..
-        wrapperStartupCode.append(Utils.getStartupLineForClass(aClass));
+        wrapperStartupCode.append('\n')
+                          .append(Utils.getStartupLineForClass(aClass));
 
         seenClasses.add(className);
     }
 
     /**
      * Writes code for getting the JNIEnv instance.
      */
     private void writeFunctionStartupBoilerPlate(String methodSignature, boolean aIsThreaded) {
@@ -409,40 +366,24 @@ public class CodeGenerator {
             if (needsNewline) {
                 wrapperMethodBodies.append('\n');
             }
         }
 
         return argumentContent;
     }
 
-    private void writeCatchException() {
-        wrapperMethodBodies.append(
-            "    if (env->ExceptionCheck()) {\n" +
-            "        env->ExceptionClear();\n" +
-            "        if (aResult) {\n" +
-            "            *aResult = NS_ERROR_FAILURE;\n" +
-            "        }\n" +
-            "    } else if (aResult) {\n" +
-            "        *aResult = NS_OK;\n" +
-            "    }\n\n");
-    }
-
     private void writeCtorBody(String implementationSignature, Constructor<?> theCtor,
-            boolean aIsThreaded, boolean aNoThrow, boolean aCatchException) {
+            boolean aIsThreaded, boolean aNoThrow) {
         Class<?>[] argumentTypes = theCtor.getParameterTypes();
 
         writeFunctionStartupBoilerPlate(implementationSignature, aIsThreaded);
 
         writeFramePushBoilerplate(theCtor, false, aNoThrow);
 
-        if (mLazyInit) {
-            writeMemberInit(theCtor, wrapperMethodBodies);
-        }
-
         // Marshall arguments for this constructor, if any...
         boolean hasArguments = argumentTypes.length != 0;
 
         StringBuilder argumentContent = new StringBuilder();
         if (hasArguments) {
             argumentContent = getArgumentMarshalling(argumentTypes);
         }
 
@@ -456,51 +397,41 @@ public class CodeGenerator {
 
 
         // Call takes class id, method id of constructor method, then arguments.
         wrapperMethodBodies.append(Utils.getClassReferenceName(mClassToWrap)).append(", ");
 
         wrapperMethodBodies.append(mMembersToIds.get(theCtor))
         // Tack on the arguments, if any..
                            .append(argumentContent)
-                           .append("), env);\n");
-
-        // Check for exception and set aResult
-        if (aCatchException) {
-            writeCatchException();
-        }
-
-        wrapperMethodBodies.append("    env->PopLocalFrame(nullptr);\n}\n");
+                           .append("), env);\n" +
+                                   "    env->PopLocalFrame(nullptr);\n" +
+                                   "}\n");
     }
 
     /**
      * Generates the method body of the C++ wrapper function for the Java method indicated.
      *
      * @param methodSignature The previously-generated C++ method signature for the method to be
      *                        generated.
      * @param aMethod         The Java method to be wrapped by the C++ method being generated.
      * @param aClass          The Java class to which the method belongs.
      */
     private void writeMethodBody(String methodSignature, Method aMethod,
                                  Class<?> aClass, boolean aIsMultithreaded,
-                                 boolean aNoThrow, boolean aNarrowChars,
-                                 boolean aCatchException) {
+                                 boolean aNoThrow, boolean aNarrowChars) {
         Class<?>[] argumentTypes = aMethod.getParameterTypes();
         Class<?> returnType = aMethod.getReturnType();
 
         writeFunctionStartupBoilerPlate(methodSignature, aIsMultithreaded);
 
         boolean isObjectReturningMethod = !returnType.getCanonicalName().equals("void") && Utils.isObjectType(returnType);
 
         writeFramePushBoilerplate(aMethod, isObjectReturningMethod, aNoThrow);
 
-        if (mLazyInit) {
-            writeMemberInit(aMethod, wrapperMethodBodies);
-        }
-
         // Marshall arguments, if we have any.
         boolean hasArguments = argumentTypes.length != 0;
 
         // We buffer the arguments to the call separately to avoid needing to repeatedly iterate the
         // argument list while building this line. In the coming code block, we simultaneously
         // construct any argument marshalling code (Creation of jstrings, placement of arguments
         // into an argument array, etc. and the actual argument list passed to the function (in
         // argumentContent).
@@ -545,21 +476,16 @@ public class CodeGenerator {
         wrapperMethodBodies.append(argumentContent)
                            .append(");\n");
 
         // Check for exception and crash if any...
         if (!aNoThrow) {
             wrapperMethodBodies.append("    AndroidBridge::HandleUncaughtException(env);\n");
         }
 
-        // Check for exception and set aResult
-        if (aCatchException) {
-            writeCatchException();
-        }
-
         // If we're returning an object, pop the callee's stack frame extracting our ref as the return
         // value.
         if (isObjectReturningMethod) {
             wrapperMethodBodies.append("    ")
                                .append(Utils.getCReturnType(returnType, aNarrowChars))
                                .append(" ret = static_cast<").append(Utils.getCReturnType(returnType, aNarrowChars)).append(">(env->PopLocalFrame(temp));\n" +
                                        "    return ret;\n");
         } else if (!returnType.getCanonicalName().equals("void")) {
@@ -570,51 +496,43 @@ public class CodeGenerator {
         } else {
             // If we don't return anything, just pop the stack frame and move on with life.
             wrapperMethodBodies.append("    env->PopLocalFrame(nullptr);\n");
         }
         wrapperMethodBodies.append("}\n");
     }
 
     /**
-     * Generates the code to get the id of the given member on startup or in the member body if lazy init
-     * is requested.
+     * Generates the code to get the id of the given member on startup.
      *
      * @param aMember         The Java member being wrapped.
      */
-    private void writeMemberInit(Member aMember, StringBuilder aOutput) {
-        if (mLazyInit) {
-            aOutput.append("    if (!" + mMembersToIds.get(aMember) + ") {\n    ");
-        }
-
-        aOutput.append("    " + mMembersToIds.get(aMember)).append(" = AndroidBridge::Get");
+    private void writeStartupCode(Member aMember) {
+        wrapperStartupCode.append("    ")
+                          .append(mMembersToIds.get(aMember))
+                          .append(" = get");
         if (Utils.isMemberStatic(aMember)) {
-            aOutput.append("Static");
+            wrapperStartupCode.append("Static");
         }
 
         boolean isField = aMember instanceof Field;
         if (isField) {
-            aOutput.append("FieldID(env, " + Utils.getClassReferenceName(aMember.getDeclaringClass()) + ", \"");
+            wrapperStartupCode.append("Field(\"");
         } else {
-            aOutput.append("MethodID(env, " + Utils.getClassReferenceName(aMember.getDeclaringClass()) + ", \"");
+            wrapperStartupCode.append("Method(\"");
+        }
+        if (aMember instanceof Constructor) {
+            wrapperStartupCode.append("<init>");
+        } else {
+            wrapperStartupCode.append(aMember.getName());
         }
 
-        if (aMember instanceof Constructor) {
-            aOutput.append("<init>");
-        } else {
-            aOutput.append(aMember.getName());
-        }
-
-        aOutput.append("\", \"")
+        wrapperStartupCode.append("\", \"")
                           .append(Utils.getTypeSignatureStringForMember(aMember))
                           .append("\");\n");
-
-        if (mLazyInit) {
-            aOutput.append("    }\n\n");
-        }
     }
 
     private void writeZeroingFor(Member aMember, final String aMemberName) {
         if (aMember instanceof Field) {
             zeroingCode.append("jfieldID ");
         } else {
             zeroingCode.append("jmethodID ");
         }
--- a/build/annotationProcessors/Makefile.in
+++ b/build/annotationProcessors/Makefile.in
@@ -1,12 +1,12 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 include $(topsrcdir)/config/rules.mk
 
-JAVA_CLASSPATH := $(ANDROID_SDK)/android.jar:$(ANDROID_SDK)/../../tools/lib/lint.jar:$(ANDROID_SDK)/../../tools/lib/lint-checks.jar
+JAVA_CLASSPATH := $(ANDROID_SDK)/android.jar
 
 # Include Android specific java flags, instead of what's in rules.mk.
 include $(topsrcdir)/config/android-common.mk
 
-export:: annotationProcessors.jar
+libs:: annotationProcessors.jar
deleted file mode 100644
--- a/build/annotationProcessors/SDKProcessor.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.annotationProcessors;
-
-import com.android.tools.lint.checks.ApiLookup;
-import com.android.tools.lint.LintCliClient;
-
-import org.mozilla.gecko.annotationProcessors.classloader.AnnotatableEntity;
-import org.mozilla.gecko.annotationProcessors.classloader.ClassWithOptions;
-import org.mozilla.gecko.annotationProcessors.classloader.IterableJarLoadingURLClassLoader;
-import org.mozilla.gecko.annotationProcessors.utils.GeneratableElementIterator;
-import org.mozilla.gecko.annotationProcessors.utils.Utils;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.Properties;
-import java.util.Scanner;
-import java.util.Vector;
-import java.net.URL;
-import java.net.URLClassLoader;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-
-public class SDKProcessor {
-    public static final String GENERATED_COMMENT =
-            "// GENERATED CODE\n" +
-            "// Generated by the Java program at /build/annotationProcessors at compile time from\n" +
-            "// annotations on Java methods. To update, change the annotations on the corresponding Java\n" +
-            "// methods and rerun the build. Manually updating this file will cause your build to fail.\n\n";
-
-    private static ApiLookup sApiLookup;
-    private static int sMaxSdkVersion;
-
-    public static void main(String[] args) {
-        // We expect a list of jars on the commandline. If missing, whinge about it.
-        if (args.length < 5) {
-            System.err.println("Usage: java SDKProcessor sdkjar classlistfile outdir fileprefix max-sdk-version");
-            System.exit(1);
-        }
-
-        System.out.println("Processing platform bindings...");
-
-        String sdkJar = args[0];
-        Vector classes = getClassList(args[1]);
-        String outdir = args[2];
-        String generatedFilePrefix = args[3];
-        sMaxSdkVersion = Integer.parseInt(args[4]);
-
-        Properties props = System.getProperties();
-        props.setProperty("com.android.tools.lint.bindir",
-            new File(new File(sdkJar).getParentFile(), "../../tools").toString());
-
-        LintCliClient lintClient = new LintCliClient();
-        sApiLookup = ApiLookup.get(lintClient);
-
-        // Start the clock!
-        long s = System.currentTimeMillis();
-
-        // Get an iterator over the classes in the jar files given...
-        // Iterator<ClassWithOptions> jarClassIterator = IterableJarLoadingURLClassLoader.getIteratorOverJars(args);
-
-        StringBuilder headerFile = new StringBuilder(GENERATED_COMMENT);
-        headerFile.append("#ifndef " + generatedFilePrefix + "_h__\n" +
-                          "#define " + generatedFilePrefix + "_h__\n" +
-                          "#include \"nsXPCOMStrings.h\"\n" +
-                          "#include \"AndroidJavaWrappers.h\"\n" +
-                          "\n" +
-                          "namespace mozilla {\n" +
-                          "namespace widget {\n" +
-                          "namespace android {\n" +
-                          "namespace sdk {\n" +
-                          "void Init" + generatedFilePrefix + "Stubs(JNIEnv *jEnv);\n\n");
-
-        StringBuilder implementationFile = new StringBuilder(GENERATED_COMMENT);
-        implementationFile.append("#include \"" + generatedFilePrefix + ".h\"\n" +
-                                  "#include \"AndroidBridgeUtilities.h\"\n" +
-                                  "#include \"nsXPCOMStrings.h\"\n" +
-                                  "#include \"AndroidBridge.h\"\n" +
-                                  "\n" +
-                                  "namespace mozilla {\n" +
-                                  "namespace widget {\n" +
-                                  "namespace android {\n" +
-                                  "namespace sdk {\n");
-
-        // Used to track the calls to the various class-specific initialisation functions.
-        StringBuilder stubInitializer = new StringBuilder();
-        stubInitializer.append("void Init" + generatedFilePrefix + "Stubs(JNIEnv *jEnv) {\n");
-
-        ClassLoader loader = null;
-        try {
-            loader = URLClassLoader.newInstance(new URL[] { new URL("file://" + sdkJar) },
-                                                SDKProcessor.class.getClassLoader());
-        } catch (Exception e) {
-            System.out.println(e);
-        }
-
-        for (Iterator<String> i = classes.iterator(); i.hasNext(); ) {
-            String className = i.next();
-            System.out.println("Looking up: " + className);
-
-            try {
-                Class<?> c = Class.forName(className, true, loader);
-
-                generateClass(Class.forName(className, true, loader),
-                              stubInitializer,
-                              implementationFile,
-                              headerFile);
-            } catch (Exception e) {
-                System.out.println("Failed to generate class " + className + ": " + e);
-            }
-        }
-
-        implementationFile.append('\n');
-        stubInitializer.append("}");
-        implementationFile.append(stubInitializer);
-
-        implementationFile.append("\n} /* sdk */\n" +
-                                    "} /* android */\n" +
-                                    "} /* widget */\n" +
-                                    "} /* mozilla */\n");
-
-        headerFile.append("\n} /* sdk */\n" +
-                            "} /* android */\n" +
-                            "} /* widget */\n" +
-                            "} /* mozilla */\n" +
-                            "#endif\n");
-
-        writeOutputFiles(outdir, generatedFilePrefix, headerFile, implementationFile);
-        long e = System.currentTimeMillis();
-        System.out.println("SDK processing complete in " + (e - s) + "ms");
-    }
-
-    private static Member[] sortAndFilterMembers(Member[] members) {
-        Arrays.sort(members, new Comparator<Member>() {
-            @Override
-            public int compare(Member a, Member b) {
-                return a.getName().compareTo(b.getName());
-            }
-        });
-
-        ArrayList<Member> list = new ArrayList<>();
-        for (Member m : members) {
-            int version = 0;
-
-            if (m instanceof Method || m instanceof Constructor) {
-                version = sApiLookup.getCallVersion(Utils.getTypeSignatureStringForClass(m.getDeclaringClass()),
-                                                    m.getName(),
-                                                    Utils.getTypeSignatureStringForMember(m));
-            } else if (m instanceof Field) {
-                version = sApiLookup.getFieldVersion(Utils.getTypeSignatureStringForClass(m.getDeclaringClass()),
-                                                     m.getName());
-            } else {
-                throw new IllegalArgumentException("expected member to be Method, Constructor, or Field");
-            }
-
-            if (version > sMaxSdkVersion) {
-                System.out.println("Skipping " + m.getDeclaringClass().getName() + "." + m.getName() +
-                    ", version " + version + " > " + sMaxSdkVersion);
-                continue;
-            }
-
-            list.add(m);
-        }
-
-        return list.toArray(new Member[list.size()]);
-    }
-
-    private static void generateClass(Class<?> clazz,
-                                      StringBuilder stubInitializer,
-                                      StringBuilder implementationFile,
-                                      StringBuilder headerFile) {
-        String generatedName = clazz.getSimpleName();
-
-        CodeGenerator generator = new CodeGenerator(clazz, generatedName, true);
-        stubInitializer.append("    ").append(generatedName).append("::InitStubs(jEnv);\n");
-
-        generator.generateMembers(sortAndFilterMembers(clazz.getDeclaredConstructors()));
-        generator.generateMembers(sortAndFilterMembers(clazz.getDeclaredMethods()));
-        generator.generateMembers(sortAndFilterMembers(clazz.getDeclaredFields()));
-
-        headerFile.append(generator.getHeaderFileContents());
-        implementationFile.append(generator.getWrapperFileContents());
-    }
-
-    private static Vector<String> getClassList(String path) {
-        Scanner scanner = null;
-        try {
-            scanner = new Scanner(new FileInputStream(path));
-
-            Vector lines = new Vector();
-            while (scanner.hasNextLine()) {
-                lines.add(scanner.nextLine());
-            }
-            return lines;
-        } catch (Exception e) {
-            System.out.println(e.toString());
-            return null;
-        } finally {
-            if (scanner != null) {
-                scanner.close();
-            }
-        }
-    }
-
-    private static void writeOutputFiles(String aOutputDir, String aPrefix, StringBuilder aHeaderFile,
-                                         StringBuilder aImplementationFile) {
-        FileOutputStream implStream = null;
-        try {
-            implStream = new FileOutputStream(new File(aOutputDir, aPrefix + ".cpp"));
-            implStream.write(aImplementationFile.toString().getBytes());
-        } catch (IOException e) {
-            System.err.println("Unable to write " + aOutputDir + ". Perhaps a permissions issue?");
-            e.printStackTrace(System.err);
-        } finally {
-            if (implStream != null) {
-                try {
-                    implStream.close();
-                } catch (IOException e) {
-                    System.err.println("Unable to close implStream due to "+e);
-                    e.printStackTrace(System.err);
-                }
-            }
-        }
-
-        FileOutputStream headerStream = null;
-        try {
-            headerStream = new FileOutputStream(new File(aOutputDir, aPrefix + ".h"));
-            headerStream.write(aHeaderFile.toString().getBytes());
-        } catch (IOException e) {
-            System.err.println("Unable to write " + aOutputDir + ". Perhaps a permissions issue?");
-            e.printStackTrace(System.err);
-        } finally {
-            if (headerStream != null) {
-                try {
-                    headerStream.close();
-                } catch (IOException e) {
-                    System.err.println("Unable to close headerStream due to "+e);
-                    e.printStackTrace(System.err);
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
--- a/build/annotationProcessors/moz.build
+++ b/build/annotationProcessors/moz.build
@@ -8,13 +8,12 @@ jar = add_java_jar('annotationProcessors
 jar.sources += [
     'AnnotationInfo.java',
     'AnnotationProcessor.java',
     'classloader/AnnotatableEntity.java',
     'classloader/ClassWithOptions.java',
     'classloader/IterableJarLoadingURLClassLoader.java',
     'classloader/JarClassIterator.java',
     'CodeGenerator.java',
-    'SDKProcessor.java',
     'utils/AlphabeticAnnotatableEntityComparator.java',
     'utils/GeneratableElementIterator.java',
     'utils/Utils.java',
 ]
--- a/build/annotationProcessors/utils/GeneratableElementIterator.java
+++ b/build/annotationProcessors/utils/GeneratableElementIterator.java
@@ -71,17 +71,16 @@ public class GeneratableElementIterator 
                 // WrappedJNIMethod has parameters. Use Reflection to obtain them.
                 Class<? extends Annotation> annotationType = annotation.annotationType();
                 final String annotationTypeName = annotationType.getName();
                 if (annotationTypeName.equals("org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI")) {
                     String stubName = null;
                     boolean isMultithreadedStub = false;
                     boolean noThrow = false;
                     boolean narrowChars = false;
-                    boolean catchException = false;
                     try {
                         // Determine the explicitly-given name of the stub to generate, if any.
                         final Method stubNameMethod = annotationType.getDeclaredMethod("stubName");
                         stubNameMethod.setAccessible(true);
                         stubName = (String) stubNameMethod.invoke(annotation);
 
                         // Determine if the generated stub is to allow calls from multiple threads.
                         final Method multithreadedStubMethod = annotationType.getDeclaredMethod("allowMultithread");
@@ -93,21 +92,16 @@ public class GeneratableElementIterator 
                         noThrowMethod.setAccessible(true);
                         noThrow = (Boolean) noThrowMethod.invoke(annotation);
 
                         // Determine if strings should be wide or narrow
                         final Method narrowCharsMethod = annotationType.getDeclaredMethod("narrowChars");
                         narrowCharsMethod.setAccessible(true);
                         narrowChars = (Boolean) narrowCharsMethod.invoke(annotation);
 
-                        // Determine if we should catch exceptions
-                        final Method catchExceptionMethod = annotationType.getDeclaredMethod("catchException");
-                        catchExceptionMethod.setAccessible(true);
-                        catchException = (Boolean) catchExceptionMethod.invoke(annotation);
-
                     } catch (NoSuchMethodException e) {
                         System.err.println("Unable to find expected field on WrapElementForJNI annotation. Did the signature change?");
                         e.printStackTrace(System.err);
                         System.exit(3);
                     } catch (IllegalAccessException e) {
                         System.err.println("IllegalAccessException reading fields on WrapElementForJNI annotation. Seems the semantics of Reflection have changed...");
                         e.printStackTrace(System.err);
                         System.exit(4);
@@ -119,27 +113,27 @@ public class GeneratableElementIterator 
 
                     // If the method name was not explicitly given in the annotation generate one...
                     if (stubName.isEmpty()) {
                         String aMethodName = candidateElement.getName();
                         stubName = aMethodName.substring(0, 1).toUpperCase() + aMethodName.substring(1);
                     }
 
                     AnnotationInfo annotationInfo = new AnnotationInfo(
-                        stubName, isMultithreadedStub, noThrow, narrowChars, catchException);
+                        stubName, isMultithreadedStub, noThrow, narrowChars);
                     mNextReturnValue = new AnnotatableEntity(candidateElement, annotationInfo);
                     return;
                 }
             }
 
             // If no annotation found, we might be expected to generate anyway using default arguments,
             // thanks to the "Generate everything" annotation.
             if (mIterateEveryEntry) {
                 AnnotationInfo annotationInfo = new AnnotationInfo(
-                    candidateElement.getName(), false, false, false, false);
+                    candidateElement.getName(), false, false, false);
                 mNextReturnValue = new AnnotatableEntity(candidateElement, annotationInfo);
                 return;
             }
         }
         mNextReturnValue = null;
     }
 
     @Override
--- a/build/annotationProcessors/utils/Utils.java
+++ b/build/annotationProcessors/utils/Utils.java
@@ -313,20 +313,16 @@ public class Utils {
             return getTypeSignatureStringForMethod((Method) aMember);
         } else if (aMember instanceof Field) {
             return getTypeSignatureStringForField((Field) aMember);
         } else {
             return getTypeSignatureStringForConstructor((Constructor<?>) aMember);
         }
     }
 
-    public static String getTypeSignatureStringForClass(Class<?> clazz) {
-        return clazz.getCanonicalName().replace('.', '/');
-    }
-
     public static String getTypeSignatureString(Constructor<?> aConstructor) {
         Class<?>[] arguments = aConstructor.getParameterTypes();
         StringBuilder sb = new StringBuilder();
         sb.append('(');
 
         // For each argument, write its signature component to the buffer..
         for (int i = 0; i < arguments.length; i++) {
             writeTypeSignature(sb, arguments[i]);
@@ -340,17 +336,17 @@ public class Utils {
     /**
      * Helper method used by getTypeSignatureStringForMethod to build the signature. Write the subsignature
      * of a given type into the buffer.
      *
      * @param sb The buffer to write into.
      * @param c  The type of the element to write the subsignature of.
      */
     private static void writeTypeSignature(StringBuilder sb, Class<?> c) {
-        String name = Utils.getTypeSignatureStringForClass(c);
+        String name = c.getCanonicalName().replaceAll("\\.", "/");
 
         // Determine if this is an array type and, if so, peel away the array operators..
         int len = name.length();
         while (name.endsWith("[]")) {
             sb.append('[');
             name = name.substring(0, len - 2);
             len = len - 2;
         }
@@ -383,18 +379,17 @@ public class Utils {
      * generating header files and method bodies.
      *
      * @param aArgumentTypes Argument types of the Java method being wrapped.
      * @param aReturnType Return type of the Java method being wrapped.
      * @param aCMethodName Name of the method to generate in the C++ class.
      * @param aCClassName Name of the C++ class into which the method is declared.
      * @return The C++ method implementation signature for the method described.
      */
-    public static String getCImplementationMethodSignature(Class<?>[] aArgumentTypes, Class<?> aReturnType,
-        String aCMethodName, String aCClassName, boolean aNarrowChars, boolean aCatchException) {
+    public static String getCImplementationMethodSignature(Class<?>[] aArgumentTypes, Class<?> aReturnType, String aCMethodName, String aCClassName, boolean aNarrowChars) {
         StringBuilder retBuffer = new StringBuilder();
 
         retBuffer.append(getCReturnType(aReturnType, aNarrowChars));
         retBuffer.append(' ');
         retBuffer.append(aCClassName);
         retBuffer.append("::");
         retBuffer.append(aCMethodName);
         retBuffer.append('(');
@@ -406,24 +401,16 @@ public class Utils {
             // We, imaginatively, call our arguments a1, a2, a3...
             // The only way to preserve the names from Java would be to parse the
             // Java source, which would be computationally hard.
             retBuffer.append(aT);
             if (aT != aArgumentTypes.length - 1) {
                 retBuffer.append(", ");
             }
         }
-
-        if (aCatchException) {
-            if (aArgumentTypes.length > 0) {
-                retBuffer.append(", ");
-            }
-            retBuffer.append("nsresult* aResult");
-        }
-
         retBuffer.append(')');
         return retBuffer.toString();
     }
 
     /**
      * Produces a C method signature, sans semicolon, for the given Java Method. Useful for both
      * generating header files and method bodies.
      *
@@ -431,18 +418,17 @@ public class Utils {
      * @param aArgumentAnnotations The annotations on the Java method arguments. Used to specify
      *                             default values etc.
      * @param aReturnType Return type of the Java method being wrapped.
      * @param aCMethodName Name of the method to generate in the C++ class.
      * @param aCClassName Name of the C++ class into which the method is declared.e
      * @param aIsStaticStub true if the generated C++ method should be static, false otherwise.
      * @return The generated C++ header method signature for the method described.
      */
-    public static String getCHeaderMethodSignature(Class<?>[] aArgumentTypes, Annotation[][] aArgumentAnnotations, Class<?> aReturnType,
-        String aCMethodName, String aCClassName, boolean aIsStaticStub, boolean aNarrowChars, boolean aCatchException) {
+    public static String getCHeaderMethodSignature(Class<?>[] aArgumentTypes, Annotation[][] aArgumentAnnotations, Class<?> aReturnType, String aCMethodName, String aCClassName, boolean aIsStaticStub, boolean aNarrowChars) {
         StringBuilder retBuffer = new StringBuilder();
 
         // Add the static keyword, if applicable.
         if (aIsStaticStub) {
             retBuffer.append("static ");
         }
 
         // Write return type..
@@ -462,24 +448,16 @@ public class Utils {
 
             // Append the default value, if there is one..
             retBuffer.append(getDefaultValueString(aArgumentTypes[aT], aArgumentAnnotations[aT]));
 
             if (aT != aArgumentTypes.length - 1) {
                 retBuffer.append(", ");
             }
         }
-
-        if (aCatchException) {
-            if (aArgumentTypes.length > 0) {
-                retBuffer.append(", ");
-            }
-            retBuffer.append("nsresult* aResult = nullptr");
-        }
-
         retBuffer.append(')');
         return retBuffer.toString();
     }
 
     /**
      * If the given Annotation[] contains an OptionalGeneratedParameter annotation then return a
      * string assigning an argument of type aArgumentType to the default value for that type.
      * Otherwise, return the empty string.
@@ -604,19 +582,19 @@ public class Utils {
      *
      * @param aClass The target Java class.
      * @return The generated code to populate the reference to the class.
      */
     public static String getStartupLineForClass(Class<?> aClass) {
         StringBuilder sb = new StringBuilder();
         sb.append("    ");
         sb.append(getClassReferenceName(aClass));
-        sb.append(" = AndroidBridge::GetClassGlobalRef(env, \"");
+        sb.append(" = getClassGlobalRef(\"");
 
-        String name = Utils.getTypeSignatureStringForClass(aClass);
+        String name = aClass.getCanonicalName().replaceAll("\\.", "/");
         Class<?> containerClass = aClass.getDeclaringClass();
         if (containerClass != null) {
             // Is an inner class. Add the $ symbol.
             final int lastSlash = name.lastIndexOf('/');
             name = name.substring(0, lastSlash) + '$' + name.substring(lastSlash+1);
         }
 
         sb.append(name);
--- a/config/recurse.mk
+++ b/config/recurse.mk
@@ -136,17 +136,16 @@ endif # ifeq (.,$(DEPTH))
 recurse:
 	@$(RECURSED_COMMAND)
 	$(LOOP_OVER_DIRS)
 
 ifeq (.,$(DEPTH))
 # Interdependencies for parallel export.
 js/xpconnect/src/export: dom/bindings/export xpcom/xpidl/export
 accessible/xpcom/export: xpcom/xpidl/export
-widget/android/bindings/export: build/annotationProcessors/export
 ifdef ENABLE_CLANG_PLUGIN
 $(filter-out build/clang-plugin/%,$(compile_targets)): build/clang-plugin/target build/clang-plugin/tests/target
 build/clang-plugin/tests/target: build/clang-plugin/target
 endif
 
 # Interdependencies that moz.build world don't know about yet for compilation.
 # Note some others are hardcoded or "guessed" in recursivemake.py and emitter.py
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk3)
--- a/dom/media/fmp4/android/AndroidDecoderModule.cpp
+++ b/dom/media/fmp4/android/AndroidDecoderModule.cpp
@@ -1,41 +1,50 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "AndroidDecoderModule.h"
+#include "PlatformDecoderModule.h"
+#include "GeneratedJNIWrappers.h"
+#include "GeneratedSDKWrappers.h"
 #include "AndroidBridge.h"
+#include "MediaTaskQueue.h"
+#include "SharedThreadPool.h"
+#include "TexturePoolOGL.h"
 #include "GLImages.h"
 
 #include "MediaData.h"
 
 #include "mp4_demuxer/Adts.h"
 #include "mp4_demuxer/AnnexB.h"
 #include "mp4_demuxer/DecoderData.h"
 
 #include "nsThreadUtils.h"
 #include "nsAutoPtr.h"
 
 #include <jni.h>
 #include <string.h>
 
 using namespace mozilla;
 using namespace mozilla::gl;
-using namespace mozilla::widget::android::sdk;
+using namespace mozilla::widget::android;
 
 namespace mozilla {
 
 static MediaCodec* CreateDecoder(JNIEnv* aEnv, const char* aMimeType)
 {
   if (!aMimeType) {
     return nullptr;
   }
 
-  jobject decoder = MediaCodec::CreateDecoderByType(nsCString(aMimeType));
+  nsAutoString mimeType;
+  mimeType.AssignASCII(aMimeType);
+
+  jobject decoder = MediaCodec::CreateDecoderByType(mimeType);
 
   return new MediaCodec(decoder, aEnv);
 }
 
 class VideoDataDecoder : public MediaCodecDataDecoder {
 public:
   VideoDataDecoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
                    MediaFormat* aFormat, MediaDataDecoderCallback* aCallback,
@@ -89,50 +98,50 @@ public:
                                                    mConfig.display_width,
                                                    mConfig.display_height)));
     return NS_OK;
   }
 
 protected:
   layers::ImageContainer* mImageContainer;
   const mp4_demuxer::VideoDecoderConfig& mConfig;
-  RefPtr<AndroidSurfaceTexture> mSurfaceTexture;
+  nsRefPtr<AndroidSurfaceTexture> mSurfaceTexture;
 };
 
 class AudioDataDecoder : public MediaCodecDataDecoder {
 public:
   AudioDataDecoder(const char* aMimeType, MediaFormat* aFormat, MediaDataDecoderCallback* aCallback)
   : MediaCodecDataDecoder(MediaData::Type::AUDIO_DATA, aMimeType, aFormat, aCallback)
   {
   }
 
   virtual nsresult Input(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE {
     if (!strcmp(mMimeType, "audio/mp4a-latm")) {
-      uint32_t numChannels = mFormat->GetInteger(NS_LITERAL_CSTRING("channel-count"));
-      uint32_t sampleRate = mFormat->GetInteger(NS_LITERAL_CSTRING("sample-rate"));
+      uint32_t numChannels = mFormat->GetInteger(NS_LITERAL_STRING("channel-count"));
+      uint32_t sampleRate = mFormat->GetInteger(NS_LITERAL_STRING("sample-rate"));
       uint8_t frequencyIndex =
           mp4_demuxer::Adts::GetFrequencyIndex(sampleRate);
-      uint32_t aacProfile = mFormat->GetInteger(NS_LITERAL_CSTRING("aac-profile"));
+      uint32_t aacProfile = mFormat->GetInteger(NS_LITERAL_STRING("aac-profile"));
       bool rv = mp4_demuxer::Adts::ConvertSample(numChannels,
                                                  frequencyIndex,
                                                  aacProfile,
                                                  aSample);
       if (!rv) {
         printf_stderr("Failed to prepend ADTS header\n");
         return NS_ERROR_FAILURE;
       }
     }
     return MediaCodecDataDecoder::Input(aSample);
   }
 
   nsresult Output(BufferInfo* aInfo, void* aBuffer, MediaFormat* aFormat, Microseconds aDuration) {
     // The output on Android is always 16-bit signed
 
-    uint32_t numChannels = aFormat->GetInteger(NS_LITERAL_CSTRING("channel-count"));
-    uint32_t sampleRate = aFormat->GetInteger(NS_LITERAL_CSTRING("sample-rate"));
+    uint32_t numChannels = aFormat->GetInteger(NS_LITERAL_STRING("channel-count"));
+    uint32_t sampleRate = aFormat->GetInteger(NS_LITERAL_STRING("sample-rate"));
     uint32_t numFrames = (aInfo->getSize() / numChannels) / 2;
 
     AudioDataValue* audio = new AudioDataValue[aInfo->getSize()];
     PodCopy(audio, static_cast<AudioDataValue*>(aBuffer), aInfo->getSize());
 
     mCallback->Output(new AudioData(aInfo->getOffset(), aInfo->getPresentationTimeUs(),
                                     aDuration,
                                     numFrames,
@@ -155,17 +164,20 @@ bool AndroidDecoderModule::SupportsAudio
 already_AddRefed<MediaDataDecoder>
 AndroidDecoderModule::CreateH264Decoder(
                                 const mp4_demuxer::VideoDecoderConfig& aConfig,
                                 layers::LayersBackend aLayersBackend,
                                 layers::ImageContainer* aImageContainer,
                                 MediaTaskQueue* aVideoTaskQueue,
                                 MediaDataDecoderCallback* aCallback)
 {
-  jobject jFormat = MediaFormat::CreateVideoFormat(nsCString(aConfig.mime_type),
+  nsAutoString mimeType;
+  mimeType.AssignASCII(aConfig.mime_type);
+
+  jobject jFormat = MediaFormat::CreateVideoFormat(mimeType,
                                                    aConfig.display_width,
                                                    aConfig.display_height);
 
   if (!jFormat) {
     return nullptr;
   }
 
   MediaFormat* format = MediaFormat::Wrap(jFormat);
@@ -182,45 +194,48 @@ AndroidDecoderModule::CreateH264Decoder(
 
 already_AddRefed<MediaDataDecoder>
 AndroidDecoderModule::CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
                                          MediaTaskQueue* aAudioTaskQueue,
                                          MediaDataDecoderCallback* aCallback)
 {
   MOZ_ASSERT(aConfig.bits_per_sample == 16, "We only handle 16-bit audio!");
 
-  jobject jFormat = MediaFormat::CreateAudioFormat(nsCString(aConfig.mime_type),
+  nsAutoString mimeType;
+  mimeType.AssignASCII(aConfig.mime_type);
+
+  jobject jFormat = MediaFormat::CreateAudioFormat(mimeType,
                                                    aConfig.samples_per_second,
                                                    aConfig.channel_count);
 
   if (jFormat == nullptr)
     return nullptr;
 
   MediaFormat* format = MediaFormat::Wrap(jFormat);
 
   if(format == nullptr)
     return nullptr;
 
   JNIEnv* env = GetJNIForThread();
 
-  if (!format->GetByteBuffer(NS_LITERAL_CSTRING("csd-0"))) {
+  if (!format->GetByteBuffer(NS_LITERAL_STRING("csd-0"))) {
     uint8_t* csd0 = new uint8_t[2];
 
     csd0[0] = aConfig.audio_specific_config[0];
     csd0[1] = aConfig.audio_specific_config[1];
 
     jobject buffer = env->NewDirectByteBuffer(csd0, 2);
-    format->SetByteBuffer(NS_LITERAL_CSTRING("csd-0"), buffer);
+    format->SetByteBuffer(NS_LITERAL_STRING("csd-0"), buffer);
 
     env->DeleteLocalRef(buffer);
   }
 
-  if (strcmp(aConfig.mime_type, "audio/mp4a-latm") == 0) {
-    format->SetInteger(NS_LITERAL_CSTRING("is-adts"), 1);
-    format->SetInteger(NS_LITERAL_CSTRING("aac-profile"), aConfig.aac_profile);
+  if (mimeType.EqualsLiteral("audio/mp4a-latm")) {
+    format->SetInteger(NS_LITERAL_STRING("is-adts"), 1);
+    format->SetInteger(NS_LITERAL_STRING("aac-profile"), aConfig.aac_profile);
   }
 
   nsRefPtr<MediaDataDecoder> decoder =
     new AudioDataDecoder(aConfig.mime_type, format, aCallback);
 
   return decoder.forget();
 
 }
@@ -274,36 +289,25 @@ nsresult MediaCodecDataDecoder::InitDeco
 {
   JNIEnv* env = GetJNIForThread();
   mDecoder = CreateDecoder(env, mMimeType);
   if (!mDecoder) {
     mCallback->Error();
     return NS_ERROR_FAILURE;
   }
 
-  nsresult res;
-  mDecoder->Configure(mFormat->wrappedObject(), aSurface, nullptr, 0, &res);
-  if (NS_FAILED(res)) {
-    return res;
+  if (!mDecoder->Configure(mFormat->wrappedObject(), aSurface, nullptr, 0)) {
+    mCallback->Error();
+    return NS_ERROR_FAILURE;
   }
 
-  mDecoder->Start(&res);
-  if (NS_FAILED(res)) {
-    return res;
-  }
+  mDecoder->Start();
 
-  res = ResetInputBuffers();
-  if (NS_FAILED(res)) {
-    return res;
-  }
-
-  res = ResetOutputBuffers();
-  if (NS_FAILED(res)) {
-    return res;
-  }
+  ResetInputBuffers();
+  ResetOutputBuffers();
 
   NS_NewNamedThread("MC Decoder", getter_AddRefs(mThread),
                     NS_NewRunnableMethod(this, &MediaCodecDataDecoder::DecoderLoop));
 
   return NS_OK;
 }
 
 // This is in usec, so that's 10ms
@@ -312,17 +316,16 @@ nsresult MediaCodecDataDecoder::InitDeco
 void MediaCodecDataDecoder::DecoderLoop()
 {
   bool outputDone = false;
 
   JNIEnv* env = GetJNIForThread();
   mp4_demuxer::MP4Sample* sample = nullptr;
 
   nsAutoPtr<MediaFormat> outputFormat;
-  nsresult res;
 
   for (;;) {
     {
       MonitorAutoLock lock(mMonitor);
       while (!mStopping && !mDraining && mQueue.empty()) {
         if (mQueue.empty()) {
           // We could be waiting here forever if we don't signal that we need more input
           mCallback->InputExhausted();
@@ -346,74 +349,51 @@ void MediaCodecDataDecoder::DecoderLoop(
       // We're not stopping or draining, so try to get a sample
       if (!mQueue.empty()) {
         sample = mQueue.front();
       }
     }
 
     if (sample) {
       // We have a sample, try to feed it to the decoder
-      int inputIndex = mDecoder->DequeueInputBuffer(DECODER_TIMEOUT, &res);
-      if (NS_FAILED(res)) {
-        printf_stderr("exiting decoder loop due to exception while dequeuing input\n");
-        mCallback->Error();
-        break;
-      }
-
+      int inputIndex = mDecoder->DequeueInputBuffer(DECODER_TIMEOUT);
       if (inputIndex >= 0) {
         jobject buffer = env->GetObjectArrayElement(mInputBuffers, inputIndex);
         void* directBuffer = env->GetDirectBufferAddress(buffer);
 
         // We're feeding this to the decoder, so remove it from the queue
         mMonitor.Lock();
         mQueue.pop();
         mMonitor.Unlock();
 
         MOZ_ASSERT(env->GetDirectBufferCapacity(buffer) >= sample->size,
           "Decoder buffer is not large enough for sample");
 
         PodCopy((uint8_t*)directBuffer, sample->data, sample->size);
 
-        mDecoder->QueueInputBuffer(inputIndex, 0, sample->size, sample->composition_timestamp, 0, &res);
-        if (NS_FAILED(res)) {
-          printf_stderr("exiting decoder loop due to exception while queuing input\n");
-          mCallback->Error();
-          break;
-        }
-
+        mDecoder->QueueInputBuffer(inputIndex, 0, sample->size, sample->composition_timestamp, 0);
         mDurations.push(sample->duration);
 
         delete sample;
         sample = nullptr;
 
         outputDone = false;
         env->DeleteLocalRef(buffer);
       }
     }
 
     if (!outputDone) {
       BufferInfo bufferInfo;
 
-      int outputStatus = mDecoder->DequeueOutputBuffer(bufferInfo.wrappedObject(), DECODER_TIMEOUT, &res);
-      if (NS_FAILED(res)) {
-        printf_stderr("exiting decoder loop due to exception while dequeuing output\n");
-        mCallback->Error();
-        break;
-      }
-
+      int outputStatus = mDecoder->DequeueOutputBuffer(bufferInfo.wrappedObject(), DECODER_TIMEOUT);
       if (outputStatus == MediaCodec::getINFO_TRY_AGAIN_LATER()) {
         // We might want to call mCallback->InputExhausted() here, but there seems to be
         // some possible bad interactions here with the threading
       } else if (outputStatus == MediaCodec::getINFO_OUTPUT_BUFFERS_CHANGED()) {
-        res = ResetOutputBuffers();
-        if (NS_FAILED(res)) {
-          printf_stderr("exiting decoder loop due to exception while restting output buffers\n");
-          mCallback->Error();
-          break;
-        }
+        ResetOutputBuffers();
       } else if (outputStatus == MediaCodec::getINFO_OUTPUT_FORMAT_CHANGED()) {
         outputFormat = new MediaFormat(mDecoder->GetOutputFormat(), GetJNIForThread());
       } else if (outputStatus < 0) {
         printf_stderr("unknown error from decoder! %d\n", outputStatus);
         mCallback->Error();
       } else {
         // We have a valid buffer index >= 0 here
         if (bufferInfo.getFlags() & MediaCodec::getBUFFER_FLAG_END_OF_STREAM()) {
@@ -469,48 +449,36 @@ void MediaCodecDataDecoder::ClearQueue()
 nsresult MediaCodecDataDecoder::Input(mp4_demuxer::MP4Sample* aSample) {
   MonitorAutoLock lock(mMonitor);
   mQueue.push(aSample);
   lock.NotifyAll();
 
   return NS_OK;
 }
 
-nsresult MediaCodecDataDecoder::ResetInputBuffers()
+void MediaCodecDataDecoder::ResetInputBuffers()
 {
   JNIEnv* env = GetJNIForThread();
 
   if (mInputBuffers) {
     env->DeleteGlobalRef(mInputBuffers);
   }
 
-  nsresult res;
-  mInputBuffers = (jobjectArray) env->NewGlobalRef(mDecoder->GetInputBuffers(&res));
-  if (NS_FAILED(res)) {
-    return res;
-  }
-
-  return NS_OK;
+  mInputBuffers = (jobjectArray) env->NewGlobalRef(mDecoder->GetInputBuffers());
 }
 
-nsresult MediaCodecDataDecoder::ResetOutputBuffers()
+void MediaCodecDataDecoder::ResetOutputBuffers()
 {
   JNIEnv* env = GetJNIForThread();
 
   if (mOutputBuffers) {
     env->DeleteGlobalRef(mOutputBuffers);
   }
 
-  nsresult res;
-  mOutputBuffers = (jobjectArray) env->NewGlobalRef(mDecoder->GetOutputBuffers(&res));
-  if (NS_FAILED(res)) {
-    return res;
-  }
-
-  return NS_OK;
+  mOutputBuffers = (jobjectArray) env->NewGlobalRef(mDecoder->GetOutputBuffers());
 }
 
 nsresult MediaCodecDataDecoder::Flush() {
   Drain();
   return NS_OK;
 }
 
 nsresult MediaCodecDataDecoder::Drain() {
@@ -542,13 +510,12 @@ nsresult MediaCodecDataDecoder::Shutdown
     lock.Wait();
   }
 
   mThread->Shutdown();
   mThread = nullptr;
 
   mDecoder->Stop();
   mDecoder->Release();
-
   return NS_OK;
 }
 
 } // mozilla
--- a/dom/media/fmp4/android/AndroidDecoderModule.h
+++ b/dom/media/fmp4/android/AndroidDecoderModule.h
@@ -1,36 +1,35 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef AndroidDecoderModule_h_
 #define AndroidDecoderModule_h_
 
 #include "PlatformDecoderModule.h"
+#include "AndroidJavaWrappers.h"
 #include "AndroidSurfaceTexture.h"
 
-#include "MediaCodec.h"
+#include "GeneratedSDKWrappers.h"
 #include "mozilla/Monitor.h"
 
 #include <queue>
 
 namespace mozilla {
 
 typedef std::queue<mp4_demuxer::MP4Sample*> SampleQueue;
 
 namespace widget {
 namespace android {
-namespace sdk {
   class MediaCodec;
   class MediaFormat;
   class ByteBuffer;
 }
 }
-}
 
 class MediaCodecDataDecoder;
 
 class AndroidDecoderModule : public PlatformDecoderModule {
 public:
   virtual nsresult Shutdown() MOZ_OVERRIDE;
 
   virtual already_AddRefed<MediaDataDecoder>
@@ -52,59 +51,59 @@ public:
   virtual bool SupportsAudioMimeType(const char* aMimeType) MOZ_OVERRIDE;
 };
 
 class MediaCodecDataDecoder : public MediaDataDecoder {
 public:
 
   MediaCodecDataDecoder(MediaData::Type aType,
                         const char* aMimeType,
-                        mozilla::widget::android::sdk::MediaFormat* aFormat,
+                        mozilla::widget::android::MediaFormat* aFormat,
                         MediaDataDecoderCallback* aCallback);
 
   virtual ~MediaCodecDataDecoder();
 
   virtual nsresult Init() MOZ_OVERRIDE;
   virtual nsresult Flush() MOZ_OVERRIDE;
   virtual nsresult Drain() MOZ_OVERRIDE;
   virtual nsresult Shutdown() MOZ_OVERRIDE;
   virtual nsresult Input(mp4_demuxer::MP4Sample* aSample);
 
 protected:
   friend class AndroidDecoderModule;
 
   MediaData::Type mType;
 
   nsAutoPtr<char> mMimeType;
-  nsAutoPtr<mozilla::widget::android::sdk::MediaFormat> mFormat;
+  nsAutoPtr<mozilla::widget::android::MediaFormat> mFormat;
 
   MediaDataDecoderCallback* mCallback;
 
-  nsAutoPtr<mozilla::widget::android::sdk::MediaCodec> mDecoder;
+  nsAutoPtr<mozilla::widget::android::MediaCodec> mDecoder;
 
   jobjectArray mInputBuffers;
   jobjectArray mOutputBuffers;
 
   nsCOMPtr<nsIThread> mThread;
 
   // Only these members are protected by mMonitor.
   Monitor mMonitor;
   bool mDraining;
   bool mStopping;
 
   SampleQueue mQueue;
   std::queue<Microseconds> mDurations;
 
   virtual nsresult InitDecoder(jobject aSurface = nullptr);
 
-  virtual nsresult Output(mozilla::widget::android::sdk::BufferInfo* aInfo, void* aBuffer, mozilla::widget::android::sdk::MediaFormat* aFormat, Microseconds aDuration) { return NS_OK; }
-  virtual nsresult PostOutput(mozilla::widget::android::sdk::BufferInfo* aInfo, mozilla::widget::android::sdk::MediaFormat* aFormat, Microseconds aDuration) { return NS_OK; }
+  virtual nsresult Output(mozilla::widget::android::BufferInfo* aInfo, void* aBuffer, mozilla::widget::android::MediaFormat* aFormat, Microseconds aDuration) { return NS_OK; }
+  virtual nsresult PostOutput(mozilla::widget::android::BufferInfo* aInfo, mozilla::widget::android::MediaFormat* aFormat, Microseconds aDuration) { return NS_OK; }
 
-  nsresult ResetInputBuffers();
-  nsresult ResetOutputBuffers();
+  void ResetInputBuffers();
+  void ResetOutputBuffers();
 
   void DecoderLoop();
   virtual void ClearQueue();
 };
 
 } // namwspace mozilla
 
 #endif
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp
+++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp
@@ -947,34 +947,33 @@ nsNPAPIPluginInstance::TextureInfo nsNPA
 }
 
 void nsNPAPIPluginInstance::ReleaseContentTexture(nsNPAPIPluginInstance::TextureInfo& aTextureInfo)
 {
   EnsureSharedTexture();
   mContentTexture->Release(aTextureInfo);
 }
 
-TemporaryRef<AndroidSurfaceTexture> nsNPAPIPluginInstance::CreateSurfaceTexture()
+AndroidSurfaceTexture* nsNPAPIPluginInstance::CreateSurfaceTexture()
 {
   if (!EnsureGLContext())
     return nullptr;
 
   GLuint texture = TexturePoolOGL::AcquireTexture();
   if (!texture)
     return nullptr;
 
-  RefPtr<AndroidSurfaceTexture> surface = AndroidSurfaceTexture::Create(TexturePoolOGL::GetGLContext(),
-                                                                        texture);
-  if (!surface) {
+  AndroidSurfaceTexture* surface = AndroidSurfaceTexture::Create(TexturePoolOGL::GetGLContext(),
+                                                                 texture);
+  if (!surface)
     return nullptr;
-  }
 
   nsCOMPtr<nsIRunnable> frameCallback = NS_NewRunnableMethod(this, &nsNPAPIPluginInstance::OnSurfaceTextureFrameAvailable);
   surface->SetFrameAvailableCallback(frameCallback);
-  return surface.forget();
+  return surface;
 }
 
 void nsNPAPIPluginInstance::OnSurfaceTextureFrameAvailable()
 {
   if (mRunning == RUNNING && mOwner)
     AndroidBridge::Bridge()->ScheduleComposite();
 }
 
@@ -1005,20 +1004,19 @@ nsNPAPIPluginInstance::AsSurfaceTexture(
   if (!mContentSurface)
     return nullptr;
 
   return mContentSurface;
 }
 
 void* nsNPAPIPluginInstance::AcquireVideoWindow()
 {
-  RefPtr<AndroidSurfaceTexture> surface = CreateSurfaceTexture();
-  if (!surface) {
+  AndroidSurfaceTexture* surface = CreateSurfaceTexture();
+  if (!surface)
     return nullptr;
-  }
 
   VideoInfo* info = new VideoInfo(surface);
 
   void* window = info->mSurfaceTexture->NativeWindow()->Handle();
   mVideos.insert(std::pair<void*, VideoInfo*>(window, info));
 
   return window;
 }
--- a/dom/plugins/base/nsNPAPIPluginInstance.h
+++ b/dom/plugins/base/nsNPAPIPluginInstance.h
@@ -202,17 +202,17 @@ public:
     {
     }
 
     ~VideoInfo()
     {
       mSurfaceTexture = nullptr;
     }
 
-    mozilla::RefPtr<mozilla::gl::AndroidSurfaceTexture> mSurfaceTexture;
+    nsRefPtr<mozilla::gl::AndroidSurfaceTexture> mSurfaceTexture;
     gfxRect mDimensions;
   };
 
   void* AcquireVideoWindow();
   void ReleaseVideoWindow(void* aWindow);
   void SetVideoDimensions(void* aWindow, gfxRect aDimensions);
 
   void GetVideos(nsTArray<VideoInfo*>& aVideos);
@@ -323,18 +323,18 @@ protected:
   void PopPostedEvent(PluginEventRunnable* r);
   void OnSurfaceTextureFrameAvailable();
 
   uint32_t mFullScreenOrientation;
   bool mWakeLocked;
   bool mFullScreen;
   bool mInverted;
 
-  mozilla::RefPtr<SharedPluginTexture> mContentTexture;
-  mozilla::RefPtr<mozilla::gl::AndroidSurfaceTexture> mContentSurface;
+  nsRefPtr<SharedPluginTexture> mContentTexture;
+  nsRefPtr<mozilla::gl::AndroidSurfaceTexture> mContentSurface;
 #endif
 
   enum {
     NOT_STARTED,
     RUNNING,
     DESTROYING,
     DESTROYED
   } mRunning;
@@ -373,17 +373,17 @@ private:
   void* mCurrentPluginEvent;
 
   // Timestamp for the last time this plugin was stopped.
   // This is only valid when the plugin is actually stopped!
   mozilla::TimeStamp mStopTime;
 
 #ifdef MOZ_WIDGET_ANDROID
   void EnsureSharedTexture();
-  mozilla::TemporaryRef<mozilla::gl::AndroidSurfaceTexture> CreateSurfaceTexture();
+  mozilla::gl::AndroidSurfaceTexture* CreateSurfaceTexture();
 
   std::map<void*, VideoInfo*> mVideos;
   bool mOnScreen;
 
   nsIntSize mCurrentSize;
 #endif
 
   // is this instance Java and affected by bug 750480?
--- a/gfx/gl/AndroidSurfaceTexture.cpp
+++ b/gfx/gl/AndroidSurfaceTexture.cpp
@@ -10,22 +10,20 @@
 #include <map>
 #include <android/log.h>
 #include "AndroidSurfaceTexture.h"
 #include "gfxImageSurface.h"
 #include "AndroidBridge.h"
 #include "nsThreadUtils.h"
 #include "mozilla/gfx/Matrix.h"
 #include "GeneratedJNIWrappers.h"
-#include "SurfaceTexture.h"
 #include "GLContext.h"
 
 using namespace mozilla;
 using namespace mozilla::widget::android;
-using namespace mozilla::widget::android::sdk;
 
 namespace mozilla {
 namespace gl {
 
 // UGH
 static std::map<int, AndroidSurfaceTexture*> sInstances;
 static int sNextID = 0;
 
@@ -36,131 +34,304 @@ IsDetachSupported()
 }
 
 static bool
 IsSTSupported()
 {
   return AndroidBridge::Bridge()->GetAPIVersion() >= 14; /* ICS */
 }
 
-TemporaryRef<AndroidSurfaceTexture>
+static class JNIFunctions {
+public:
+
+  JNIFunctions() : mInitialized(false)
+  {
+  }
+
+  bool EnsureInitialized()
+  {
+    if (mInitialized) {
+      return true;
+    }
+
+    if (!IsSTSupported()) {
+      return false;
+    }
+
+    JNIEnv* env = GetJNIForThread();
+
+    AutoLocalJNIFrame jniFrame(env);
+
+    jSurfaceTextureClass = (jclass)env->NewGlobalRef(env->FindClass("android/graphics/SurfaceTexture"));
+    jSurfaceTexture_Ctor = env->GetMethodID(jSurfaceTextureClass, "<init>", "(I)V");
+    jSurfaceTexture_updateTexImage = env->GetMethodID(jSurfaceTextureClass, "updateTexImage", "()V");
+    jSurfaceTexture_getTransformMatrix = env->GetMethodID(jSurfaceTextureClass, "getTransformMatrix", "([F)V");
+    jSurfaceTexture_setDefaultBufferSize = env->GetMethodID(jSurfaceTextureClass, "setDefaultBufferSize", "(II)V");
+
+    if (IsDetachSupported()) {
+      jSurfaceTexture_attachToGLContext = env->GetMethodID(jSurfaceTextureClass, "attachToGLContext", "(I)V");
+      jSurfaceTexture_detachFromGLContext = env->GetMethodID(jSurfaceTextureClass, "detachFromGLContext", "()V");
+    } else {
+      jSurfaceTexture_attachToGLContext = jSurfaceTexture_detachFromGLContext = 0;
+    }
+
+    jSurfaceClass = (jclass)env->NewGlobalRef(env->FindClass("android/view/Surface"));
+    jSurface_Ctor = env->GetMethodID(jSurfaceClass, "<init>", "(Landroid/graphics/SurfaceTexture;)V");
+
+    mInitialized = true;
+    return true;
+  }
+
+  jobject CreateSurfaceTexture(GLuint aTexture)
+  {
+    if (!EnsureInitialized())
+      return nullptr;
+
+    JNIEnv* env = GetJNIForThread();
+
+    AutoLocalJNIFrame jniFrame(env);
+
+    return env->NewGlobalRef(env->NewObject(jSurfaceTextureClass, jSurfaceTexture_Ctor, (int) aTexture));
+  }
+
+  jobject CreateSurface(jobject aSurfaceTexture)
+  {
+    if (!EnsureInitialized())
+      return nullptr;
+
+    JNIEnv* env = GetJNIForThread();
+    AutoLocalJNIFrame jniFrame(env);
+    return env->NewGlobalRef(env->NewObject(jSurfaceClass, jSurface_Ctor, aSurfaceTexture));
+  }
+
+  void ReleaseSurfaceTexture(jobject aSurfaceTexture)
+  {
+    JNIEnv* env = GetJNIForThread();
+
+    env->DeleteGlobalRef(aSurfaceTexture);
+  }
+
+  void UpdateTexImage(jobject aSurfaceTexture)
+  {
+    JNIEnv* env = GetJNIForThread();
+
+    AutoLocalJNIFrame jniFrame(env);
+    env->CallVoidMethod(aSurfaceTexture, jSurfaceTexture_updateTexImage);
+  }
+
+  bool GetTransformMatrix(jobject aSurfaceTexture, gfx::Matrix4x4& aMatrix)
+  {
+    JNIEnv* env = GetJNIForThread();
+
+    AutoLocalJNIFrame jniFrame(env);
+
+    jfloatArray jarray = env->NewFloatArray(16);
+    env->CallVoidMethod(aSurfaceTexture, jSurfaceTexture_getTransformMatrix, jarray);
+
+    jfloat* array = env->GetFloatArrayElements(jarray, nullptr);
+
+    aMatrix._11 = array[0];
+    aMatrix._12 = array[1];
+    aMatrix._13 = array[2];
+    aMatrix._14 = array[3];
+
+    aMatrix._21 = array[4];
+    aMatrix._22 = array[5];
+    aMatrix._23 = array[6];
+    aMatrix._24 = array[7];
+
+    aMatrix._31 = array[8];
+    aMatrix._32 = array[9];
+    aMatrix._33 = array[10];
+    aMatrix._34 = array[11];
+
+    aMatrix._41 = array[12];
+    aMatrix._42 = array[13];
+    aMatrix._43 = array[14];
+    aMatrix._44 = array[15];
+
+    env->ReleaseFloatArrayElements(jarray, array, 0);
+
+    return false;
+  }
+
+  void SetDefaultBufferSize(jobject aSurfaceTexture, int32_t width, int32_t height)
+  {
+    JNIEnv* env = GetJNIForThread();
+
+    AutoLocalJNIFrame jniFrame(env);
+    env->CallVoidMethod(aSurfaceTexture, jSurfaceTexture_setDefaultBufferSize, width, height);
+  }
+
+  void AttachToGLContext(jobject aSurfaceTexture, int32_t texName)
+  {
+    MOZ_ASSERT(jSurfaceTexture_attachToGLContext);
+
+    JNIEnv* env = GetJNIForThread();
+
+    env->CallVoidMethod(aSurfaceTexture, jSurfaceTexture_attachToGLContext, texName);
+    if (env->ExceptionCheck()) {
+      env->ExceptionDescribe();
+      env->ExceptionClear();
+    }
+  }
+
+  void DetachFromGLContext(jobject aSurfaceTexture)
+  {
+    MOZ_ASSERT(jSurfaceTexture_detachFromGLContext);
+
+    JNIEnv* env = GetJNIForThread();
+
+    env->CallVoidMethod(aSurfaceTexture, jSurfaceTexture_detachFromGLContext);
+    if (env->ExceptionCheck()) {
+      env->ExceptionDescribe();
+      env->ExceptionClear();
+    }
+  }
+
+private:
+  bool mInitialized;
+
+  jclass jSurfaceTextureClass;
+  jmethodID jSurfaceTexture_Ctor;
+  jmethodID jSurfaceTexture_updateTexImage;
+  jmethodID jSurfaceTexture_getTransformMatrix;
+  jmethodID jSurfaceTexture_setDefaultBufferSize;
+
+  jmethodID jSurfaceTexture_attachToGLContext;
+  jmethodID jSurfaceTexture_detachFromGLContext;
+
+  jclass jSurfaceClass;
+  jmethodID jSurface_Ctor;
+
+} sJNIFunctions;
+
+AndroidSurfaceTexture*
 AndroidSurfaceTexture::Create()
 {
   return Create(nullptr, 0);
 }
 
-TemporaryRef<AndroidSurfaceTexture>
+AndroidSurfaceTexture*
 AndroidSurfaceTexture::Create(GLContext* aContext, GLuint aTexture)
 {
   if (!IsSTSupported()) {
     return nullptr;
   }
 
-  RefPtr<AndroidSurfaceTexture> st = new AndroidSurfaceTexture();
+  AndroidSurfaceTexture* st = new AndroidSurfaceTexture();
   if (!st->Init(aContext, aTexture)) {
     printf_stderr("Failed to initialize AndroidSurfaceTexture");
+    delete st;
     st = nullptr;
   }
 
-  return st.forget();
+  return st;
 }
 
 AndroidSurfaceTexture*
 AndroidSurfaceTexture::Find(int id)
 {
   std::map<int, AndroidSurfaceTexture*>::iterator it;
 
   it = sInstances.find(id);
   if (it == sInstances.end())
     return nullptr;
 
   return it->second;
 }
 
+bool
+AndroidSurfaceTexture::Check()
+{
+  return sJNIFunctions.EnsureInitialized();
+}
 
-nsresult
+bool
 AndroidSurfaceTexture::Attach(GLContext* aContext, PRIntervalTime aTimeout)
 {
   MonitorAutoLock lock(mMonitor);
 
   if (mAttachedContext == aContext) {
     NS_WARNING("Tried to attach same GLContext to AndroidSurfaceTexture");
-    return NS_OK;
+    return true;
   }
 
   if (!IsDetachSupported()) {
-    return NS_ERROR_NOT_AVAILABLE;
+    return false;
   }
 
   while (mAttachedContext) {
     // Wait until it's detached (or we time out)
     if (NS_FAILED(lock.Wait(aTimeout))) {
-      return NS_ERROR_NOT_AVAILABLE;
+      return false;
     }
   }
 
   MOZ_ASSERT(aContext->IsOwningThreadCurrent(), "Trying to attach GLContext from different thread");
 
   mAttachedContext = aContext;
   mAttachedContext->MakeCurrent();
   aContext->fGenTextures(1, &mTexture);
 
-  nsresult res;
-  mSurfaceTexture->AttachToGLContext(mTexture, &res);
-  return res;
+  sJNIFunctions.AttachToGLContext(mSurfaceTexture, mTexture);
+  return true;
 }
 
-nsresult
+bool
 AndroidSurfaceTexture::Detach()
 {
   MonitorAutoLock lock(mMonitor);
 
   if (!IsDetachSupported() ||
       !mAttachedContext || !mAttachedContext->IsOwningThreadCurrent()) {
-    return NS_ERROR_FAILURE;
+    return false;
   }
 
   mAttachedContext->MakeCurrent();
 
-  mSurfaceTexture->DetachFromGLContext();
+  // This call takes care of deleting the texture
+  sJNIFunctions.DetachFromGLContext(mSurfaceTexture);
 
   mTexture = 0;
   mAttachedContext = nullptr;
   lock.NotifyAll();
-  return NS_OK;
+  return true;
 }
 
 bool
 AndroidSurfaceTexture::Init(GLContext* aContext, GLuint aTexture)
 {
   if (!aTexture && !IsDetachSupported()) {
     // We have no texture and cannot initialize detached, bail out
     return false;
   }
 
-  nsresult res;
-  mSurfaceTexture = new SurfaceTexture(aTexture, &res);
-  if (NS_FAILED(res)) {
+  if (!sJNIFunctions.EnsureInitialized())
+    return false;
+
+  JNIEnv* env = GetJNIForThread();
+
+  mSurfaceTexture = sJNIFunctions.CreateSurfaceTexture(aTexture);
+  if (!mSurfaceTexture) {
     return false;
   }
 
   if (!aTexture) {
-    mSurfaceTexture->DetachFromGLContext();
+    sJNIFunctions.DetachFromGLContext(mSurfaceTexture);
   }
 
   mAttachedContext = aContext;
 
-  mSurface = new Surface(mSurfaceTexture->wrappedObject(), &res);
-  if (NS_FAILED(res)) {
+  mSurface = sJNIFunctions.CreateSurface(mSurfaceTexture);
+  if (!mSurface) {
     return false;
   }
 
-  mNativeWindow = AndroidNativeWindow::CreateFromSurface(GetJNIForThread(),
-                                                         mSurface->wrappedObject());
-  MOZ_ASSERT(mNativeWindow, "Failed to create native window from surface");
+  mNativeWindow = AndroidNativeWindow::CreateFromSurface(env, mSurface);
 
   mID = ++sNextID;
   sInstances.insert(std::pair<int, AndroidSurfaceTexture*>(mID, this));
 
   return true;
 }
 
 AndroidSurfaceTexture::AndroidSurfaceTexture()
@@ -173,79 +344,59 @@ AndroidSurfaceTexture::AndroidSurfaceTex
 }
 
 AndroidSurfaceTexture::~AndroidSurfaceTexture()
 {
   sInstances.erase(mID);
 
   mFrameAvailableCallback = nullptr;
 
+  JNIEnv* env = GetJNIForThread();
+
   if (mSurfaceTexture) {
-    GeckoAppShell::UnregisterSurfaceTextureFrameListener(mSurfaceTexture->wrappedObject());
+    GeckoAppShell::UnregisterSurfaceTextureFrameListener(mSurfaceTexture);
+
+    env->DeleteGlobalRef(mSurfaceTexture);
     mSurfaceTexture = nullptr;
   }
+
+  if (mSurface) {
+    env->DeleteGlobalRef(mSurface);
+    mSurface = nullptr;
+  }
 }
 
 void
 AndroidSurfaceTexture::UpdateTexImage()
 {
-  mSurfaceTexture->UpdateTexImage();
+  sJNIFunctions.UpdateTexImage(mSurfaceTexture);
 }
 
-void
+bool
 AndroidSurfaceTexture::GetTransformMatrix(gfx::Matrix4x4& aMatrix)
 {
-  JNIEnv* env = GetJNIForThread();
-
-  AutoLocalJNIFrame jniFrame(env);
-
-  jfloatArray jarray = env->NewFloatArray(16);
-  mSurfaceTexture->GetTransformMatrix(jarray);
-
-  jfloat* array = env->GetFloatArrayElements(jarray, nullptr);
-
-  aMatrix._11 = array[0];
-  aMatrix._12 = array[1];
-  aMatrix._13 = array[2];
-  aMatrix._14 = array[3];
-
-  aMatrix._21 = array[4];
-  aMatrix._22 = array[5];
-  aMatrix._23 = array[6];
-  aMatrix._24 = array[7];
-
-  aMatrix._31 = array[8];
-  aMatrix._32 = array[9];
-  aMatrix._33 = array[10];
-  aMatrix._34 = array[11];
-
-  aMatrix._41 = array[12];
-  aMatrix._42 = array[13];
-  aMatrix._43 = array[14];
-  aMatrix._44 = array[15];
-
-  env->ReleaseFloatArrayElements(jarray, array, 0);
+  return sJNIFunctions.GetTransformMatrix(mSurfaceTexture, aMatrix);
 }
 
 void
 AndroidSurfaceTexture::SetFrameAvailableCallback(nsIRunnable* aRunnable)
 {
   if (aRunnable) {
-    GeckoAppShell::RegisterSurfaceTextureFrameListener(mSurfaceTexture->wrappedObject(), mID);
+    GeckoAppShell::RegisterSurfaceTextureFrameListener(mSurfaceTexture, mID);
   } else {
-     GeckoAppShell::UnregisterSurfaceTextureFrameListener(mSurfaceTexture->wrappedObject());
+     GeckoAppShell::UnregisterSurfaceTextureFrameListener(mSurfaceTexture);
   }
 
   mFrameAvailableCallback = aRunnable;
 }
 
 void
 AndroidSurfaceTexture::SetDefaultSize(mozilla::gfx::IntSize size)
 {
-  mSurfaceTexture->SetDefaultBufferSize(size.width, size.height);
+  sJNIFunctions.SetDefaultBufferSize(mSurfaceTexture, size.width, size.height);
 }
 
 void
 AndroidSurfaceTexture::NotifyFrameAvailable()
 {
   if (mFrameAvailableCallback) {
     // Proxy to main thread if we aren't on it
     if (!NS_IsMainThread()) {
--- a/gfx/gl/AndroidSurfaceTexture.h
+++ b/gfx/gl/AndroidSurfaceTexture.h
@@ -10,17 +10,16 @@
 
 #include <jni.h>
 #include "nsIRunnable.h"
 #include "gfxPlatform.h"
 #include "GLDefs.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/Monitor.h"
 
-#include "SurfaceTexture.h"
 #include "AndroidNativeWindow.h"
 
 class gfxASurface;
 
 namespace mozilla {
 namespace gfx {
 class Matrix4x4;
 }
@@ -38,70 +37,74 @@ class GLContext;
  */
 class AndroidSurfaceTexture {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AndroidSurfaceTexture)
 
 public:
 
   // The SurfaceTexture is created in an attached state. This method requires
   // Android Ice Cream Sandwich.
-  static TemporaryRef<AndroidSurfaceTexture> Create(GLContext* aGLContext, GLuint aTexture);
+  static AndroidSurfaceTexture* Create(GLContext* aGLContext, GLuint aTexture);
 
   // Here the SurfaceTexture will be created in a detached state. You must call
   // Attach() with the GLContext you wish to composite with. It must be done
   // on the thread where that GLContext is current. This method requires
   // Android Jelly Bean.
-  static TemporaryRef<AndroidSurfaceTexture> Create();
+  static AndroidSurfaceTexture* Create();
 
   static AndroidSurfaceTexture* Find(int id);
 
+  // Returns with reasonable certainty whether or not we'll
+  // be able to create and use a SurfaceTexture
+  static bool Check();
+
   // If we are on Jelly Bean, the SurfaceTexture can be detached and reattached
   // to allow consumption from different GLContexts. It is recommended to only
   // attach while you are consuming in order to allow this.
   //
   // Only one GLContext may be attached at any given time. If another is already
   // attached, we try to wait for it to become detached.
-  nsresult Attach(GLContext* aContext, PRIntervalTime aTiemout = PR_INTERVAL_NO_TIMEOUT);
+  bool Attach(GLContext* aContext, PRIntervalTime aTiemout = PR_INTERVAL_NO_TIMEOUT);
 
   // This is a noop on ICS, and will always fail
-  nsresult Detach();
+  bool Detach();
 
   GLContext* GetAttachedContext() { return mAttachedContext; }
 
   AndroidNativeWindow* NativeWindow() {
     return mNativeWindow;
   }
 
   // This attaches the updated data to the TEXTURE_EXTERNAL target
   void UpdateTexImage();
 
-  void GetTransformMatrix(mozilla::gfx::Matrix4x4& aMatrix);
+  bool GetTransformMatrix(mozilla::gfx::Matrix4x4& aMatrix);
   int ID() { return mID; }
 
   void SetDefaultSize(mozilla::gfx::IntSize size);
 
   // The callback is guaranteed to be called on the main thread even
   // if the upstream callback is received on a different thread
   void SetFrameAvailableCallback(nsIRunnable* aRunnable);
 
   // Only should be called by AndroidJNI when we get a
   // callback from the underlying SurfaceTexture instance
   void NotifyFrameAvailable();
 
   GLuint Texture() { return mTexture; }
-  jobject JavaSurface() { return mSurface->wrappedObject(); }
+  jobject JavaSurface() { return mSurface; }
 private:
   AndroidSurfaceTexture();
   ~AndroidSurfaceTexture();
 
   bool Init(GLContext* aContext, GLuint aTexture);
 
   GLuint mTexture;
-  nsAutoPtr<mozilla::widget::android::sdk::SurfaceTexture> mSurfaceTexture;
-  nsAutoPtr<mozilla::widget::android::sdk::Surface> mSurface;
+  jobject mSurfaceTexture;
+  jobject mSurface;
 
   Monitor mMonitor;
   GLContext* mAttachedContext;
 
   RefPtr<AndroidNativeWindow> mNativeWindow;
   int mID;
   nsRefPtr<nsIRunnable> mFrameAvailableCallback;
 };
--- a/gfx/gl/GLBlitHelper.cpp
+++ b/gfx/gl/GLBlitHelper.cpp
@@ -723,17 +723,17 @@ bool
 GLBlitHelper::BlitSurfaceTextureImage(layers::SurfaceTextureImage* stImage)
 {
     AndroidSurfaceTexture* surfaceTexture = stImage->GetData()->mSurfTex;
     bool yFlip = stImage->GetData()->mInverted;
 
     ScopedBindTextureUnit boundTU(mGL, LOCAL_GL_TEXTURE0);
     mGL->fClear(LOCAL_GL_COLOR_BUFFER_BIT);
 
-    if (NS_FAILED(surfaceTexture->Attach(mGL))) {
+    if (!surfaceTexture->Attach(mGL)) {
         return false;
     }
 
     // UpdateTexImage() changes the EXTERNAL binding, so save it here
     // so we can restore it after.
     int oldBinding = 0;
     mGL->fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_EXTERNAL, &oldBinding);
 
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -529,17 +529,19 @@ SurfaceTextureHost::Lock()
     mTextureSource = new SurfaceTextureSource(mCompositor,
                                               mSurfTex,
                                               format,
                                               target,
                                               wrapMode,
                                               mSize);
   }
 
-  return NS_SUCCEEDED(mSurfTex->Attach(gl()));
+  mSurfTex->Attach(gl());
+
+  return true;
 }
 
 void
 SurfaceTextureHost::Unlock()
 {
   mSurfTex->Detach();
 }
 
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -414,28 +414,21 @@ include $(topsrcdir)/config/android-comm
 	$(RM) $(DIST)/fennec/$(notdir $(OMNIJAR_NAME))
 
 # Targets built very early during a Gradle build.
 gradle-targets: $(abspath $(DIST)/fennec/$(OMNIJAR_NAME))
 gradle-targets: .aapt.deps
 
 .PHONY: gradle-targets
 
-update-generated-wrappers:
-	mv $(topsrcdir)/widget/android/GeneratedJNIWrappers.cpp $(topsrcdir)/widget/android/GeneratedJNIWrappers.cpp.old
-	mv $(topsrcdir)/widget/android/GeneratedJNIWrappers.h $(topsrcdir)/widget/android/GeneratedJNIWrappers.h.old
-	@cp $(CURDIR)/jni-stubs.inc $(topsrcdir)/mozglue/android
-	@cp $(CURDIR)/GeneratedJNIWrappers.* $(topsrcdir)/widget/android
-	@echo Updated GeneratedJNIWrappers
-
 libs:: geckoview_resources.zip classes.dex jni-stubs.inc GeneratedJNIWrappers.cpp fennec_ids.txt
 	$(INSTALL) geckoview_resources.zip $(FINAL_TARGET)
 	$(INSTALL) classes.dex $(FINAL_TARGET)
 	@(diff jni-stubs.inc $(topsrcdir)/mozglue/android/jni-stubs.inc >/dev/null && diff GeneratedJNIWrappers.cpp $(topsrcdir)/widget/android/GeneratedJNIWrappers.cpp >/dev/null) || \
 	 (echo '*****************************************************' && \
 	  echo '***   Error: The generated JNI code has changed   ***' && \
 	  echo '* To update generated code in the tree, please run  *' && \
 	  echo && \
-	  echo '  make -C $(CURDIR) update-generated-wrappers' && \
+	  echo '  cp $(CURDIR)/jni-stubs.inc $(topsrcdir)/mozglue/android && cp $(CURDIR)/GeneratedJNIWrappers.* $(topsrcdir)/widget/android' && \
 	  echo && \
 	  echo '* Repeat the build, and check in any changes.       *' && \
 	  echo '*****************************************************' && \
 	  exit 1)
--- a/mobile/android/base/mozglue/generatorannotations/WrapElementForJNI.java
+++ b/mobile/android/base/mozglue/generatorannotations/WrapElementForJNI.java
@@ -39,19 +39,10 @@ public @interface WrapElementForJNI {
     boolean allowMultithread() default false;
 
     /**
      * If set, the generated stub will not handle uncaught exceptions.
      * Any exception must be handled or cleared by the code calling the stub.
      */
     boolean noThrow() default false;
 
-    /**
-     * If set, uses UTF-8 strings
-     */
     boolean narrowChars() default false;
-
-    /**
-     * If set, the generated stub will catch any exception thrown and
-     * set a passed-in nsresult to NS_ERROR_FAILURE
-     */
-    boolean catchException() default false;
 }
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -36,19 +36,17 @@
 #include "nsIDOMClientRect.h"
 #include "StrongPointer.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "nsPrintfCString.h"
 #include "NativeJSContainer.h"
 #include "nsContentUtils.h"
 #include "nsIScriptError.h"
 #include "nsIHttpChannel.h"
-
-#include "MediaCodec.h"
-#include "SurfaceTexture.h"
+#include "GeneratedSDKWrappers.h"
 
 using namespace mozilla;
 using namespace mozilla::widget::android;
 using namespace mozilla::gfx;
 
 AndroidBridge* AndroidBridge::sBridge;
 pthread_t AndroidBridge::sJavaUiThread = -1;
 static unsigned sJavaEnvThreadIndex = 0;
@@ -219,21 +217,18 @@ AndroidBridge::Init(JNIEnv *jEnv)
 
     jInputStream = getClassGlobalRef("java/io/InputStream");
     jClose = jEnv->GetMethodID(jInputStream, "close", "()V");
     jAvailable = jEnv->GetMethodID(jInputStream, "available", "()I");
 
     InitAndroidJavaWrappers(jEnv);
 
     if (mAPIVersion >= 16 /* Jelly Bean */) {
-        sdk::InitMediaCodecStubs(jEnv);
-    }
-
-    if (mAPIVersion >= 14 /* ICS */) {
-        sdk::InitSurfaceTextureStubs(jEnv);
+        // We only use this for MediaCodec right now
+        InitSDKStubs(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;
 }
--- a/widget/android/AndroidJavaWrappers.cpp
+++ b/widget/android/AndroidJavaWrappers.cpp
@@ -6,16 +6,17 @@
 #include "AndroidJavaWrappers.h"
 #include "AndroidBridge.h"
 #include "AndroidBridgeUtilities.h"
 #include "nsIDOMKeyEvent.h"
 #include "nsIWidget.h"
 #include "mozilla/BasicEvents.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/TouchEvents.h"
+#include "GeneratedSDKWrappers.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::widget::android;
 
 jclass AndroidGeckoEvent::jGeckoEventClass = 0;
 jfieldID AndroidGeckoEvent::jActionField = 0;
 jfieldID AndroidGeckoEvent::jTypeField = 0;
--- a/widget/android/GeneratedJNIWrappers.cpp
+++ b/widget/android/GeneratedJNIWrappers.cpp
@@ -8,19 +8,21 @@
 #include "nsXPCOMStrings.h"
 #include "AndroidBridge.h"
 
 namespace mozilla {
 namespace widget {
 namespace android {
 jclass DownloadsIntegration::mDownloadsIntegrationClass = 0;
 jmethodID DownloadsIntegration::jScanMedia = 0;
-void DownloadsIntegration::InitStubs(JNIEnv *env) {
-    mDownloadsIntegrationClass = AndroidBridge::GetClassGlobalRef(env, "org/mozilla/gecko/DownloadsIntegration");
-    jScanMedia = AndroidBridge::GetStaticMethodID(env, mDownloadsIntegrationClass, "scanMedia", "(Ljava/lang/String;Ljava/lang/String;)V");
+void DownloadsIntegration::InitStubs(JNIEnv *jEnv) {
+    initInit();
+
+    mDownloadsIntegrationClass = getClassGlobalRef("org/mozilla/gecko/DownloadsIntegration");
+    jScanMedia = getStaticMethod("scanMedia", "(Ljava/lang/String;Ljava/lang/String;)V");
 }
 
 DownloadsIntegration* DownloadsIntegration::Wrap(jobject obj) {
     JNIEnv *env = GetJNIForThread();
     DownloadsIntegration* ret = new DownloadsIntegration(obj, env);
     env->DeleteLocalRef(obj);
     return ret;
 }
@@ -117,100 +119,102 @@ jmethodID GeckoAppShell::jShowAlertNotif
 jmethodID GeckoAppShell::jShowInputMethodPicker = 0;
 jmethodID GeckoAppShell::jStartMonitoringGamepad = 0;
 jmethodID GeckoAppShell::jStopMonitoringGamepad = 0;
 jmethodID GeckoAppShell::jUnlockProfile = 0;
 jmethodID GeckoAppShell::jUnlockScreenOrientation = 0;
 jmethodID GeckoAppShell::jUnregisterSurfaceTextureFrameListener = 0;
 jmethodID GeckoAppShell::jVibrate1 = 0;
 jmethodID GeckoAppShell::jVibrateA = 0;
-void GeckoAppShell::InitStubs(JNIEnv *env) {
-    mGeckoAppShellClass = AndroidBridge::GetClassGlobalRef(env, "org/mozilla/gecko/GeckoAppShell");
-    jAcknowledgeEvent = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "acknowledgeEvent", "()V");
-    jAddPluginViewWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "addPluginView", "(Landroid/view/View;FFFFZ)V");
-    jAlertsProgressListener_OnProgress = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "alertsProgressListener_OnProgress", "(Ljava/lang/String;JJLjava/lang/String;)V");
-    jCancelVibrate = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "cancelVibrate", "()V");
-    jCheckURIVisited = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "checkUriVisited", "(Ljava/lang/String;)V");
-    jClearMessageList = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "clearMessageList", "(I)V");
-    jCloseCamera = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "closeCamera", "()V");
-    jCloseNotification = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "closeNotification", "(Ljava/lang/String;)V");
-    jConnectionGetMimeType = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "connectionGetMimeType", "(Ljava/net/URLConnection;)Ljava/lang/String;");
-    jCreateInputStream = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "createInputStream", "(Ljava/net/URLConnection;)Ljava/io/InputStream;");
-    jCreateMessageListWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "createMessageList", "(JJ[Ljava/lang/String;ILjava/lang/String;ZZJZI)V");
-    jCreateShortcut = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "createShortcut", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
-    jDeleteMessageWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "deleteMessage", "(II)V");
-    jDisableBatteryNotifications = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "disableBatteryNotifications", "()V");
-    jDisableNetworkNotifications = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "disableNetworkNotifications", "()V");
-    jDisableScreenOrientationNotifications = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "disableScreenOrientationNotifications", "()V");
-    jDisableSensor = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "disableSensor", "(I)V");
-    jEnableBatteryNotifications = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "enableBatteryNotifications", "()V");
-    jEnableLocation = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "enableLocation", "(Z)V");
-    jEnableLocationHighAccuracy = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "enableLocationHighAccuracy", "(Z)V");
-    jEnableNetworkNotifications = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "enableNetworkNotifications", "()V");
-    jEnableScreenOrientationNotifications = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "enableScreenOrientationNotifications", "()V");
-    jEnableSensor = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "enableSensor", "(I)V");
-    jGamepadAdded = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "gamepadAdded", "(II)V");
-    jGetConnection = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "getConnection", "(Ljava/lang/String;)Ljava/net/URLConnection;");
-    jGetContext = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "getContext", "()Landroid/content/Context;");
-    jGetCurrentBatteryInformationWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "getCurrentBatteryInformation", "()[D");
-    jGetCurrentNetworkInformationWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "getCurrentNetworkInformation", "()[D");
-    jGetDensity = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "getDensity", "()F");
-    jGetDpiWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "getDpi", "()I");
-    jGetExtensionFromMimeTypeWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "getExtensionFromMimeType", "(Ljava/lang/String;)Ljava/lang/String;");
-    jGetExternalPublicDirectory = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "getExternalPublicDirectory", "(Ljava/lang/String;)Ljava/lang/String;");
-    jGetHandlersForMimeTypeWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "getHandlersForMimeType", "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;");
-    jGetHandlersForURLWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "getHandlersForURL", "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;");
-    jGetIconForExtensionWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "getIconForExtension", "(Ljava/lang/String;I)[B");
-    jGetMessageWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "getMessage", "(II)V");
-    jGetMimeTypeFromExtensionsWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "getMimeTypeFromExtensions", "(Ljava/lang/String;)Ljava/lang/String;");
-    jGetNextMessageInListWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "getNextMessageInList", "(II)V");
-    jGetProxyForURIWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "getProxyForURI", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)Ljava/lang/String;");
-    jGetScreenDepthWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "getScreenDepth", "()I");
-    jGetScreenOrientationWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "getScreenOrientation", "()S");
-    jGetShowPasswordSetting = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "getShowPasswordSetting", "()Z");
-    jGetSystemColoursWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "getSystemColors", "()[I");
-    jHandleGeckoMessageWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "handleGeckoMessage", "(Lorg/mozilla/gecko/util/NativeJSContainer;)V");
-    jHandleUncaughtException = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "handleUncaughtException", "(Ljava/lang/Thread;Ljava/lang/Throwable;)V");
-    jHideProgressDialog = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "hideProgressDialog", "()V");
-    jInitCameraWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "initCamera", "(Ljava/lang/String;III)[I");
-    jIsNetworkLinkKnown = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "isNetworkLinkKnown", "()Z");
-    jIsNetworkLinkUp = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "isNetworkLinkUp", "()Z");
-    jIsTablet = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "isTablet", "()Z");
-    jKillAnyZombies = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "killAnyZombies", "()V");
-    jLoadPluginClass = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "loadPluginClass", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Class;");
-    jLockScreenOrientation = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "lockScreenOrientation", "(I)V");
-    jMarkURIVisited = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "markUriVisited", "(Ljava/lang/String;)V");
-    jMoveTaskToBack = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "moveTaskToBack", "()V");
-    jNetworkLinkType = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "networkLinkType", "()I");
-    jNotifyDefaultPrevented = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "notifyDefaultPrevented", "(Z)V");
-    jNotifyIME = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "notifyIME", "(I)V");
-    jNotifyIMEChange = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "notifyIMEChange", "(Ljava/lang/String;III)V");
-    jNotifyIMEContext = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "notifyIMEContext", "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
-    jNotifyWakeLockChanged = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "notifyWakeLockChanged", "(Ljava/lang/String;Ljava/lang/String;)V");
-    jNotifyXreExit = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "onXreExit", "()V");
-    jOpenUriExternal = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "openUriExternal", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z");
-    jPerformHapticFeedback = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "performHapticFeedback", "(Z)V");
-    jPumpMessageLoop = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "pumpMessageLoop", "()Z");
-    jRegisterSurfaceTextureFrameListener = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "registerSurfaceTextureFrameListener", "(Ljava/lang/Object;I)V");
-    jRemovePluginView = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "removePluginView", "(Landroid/view/View;Z)V");
-    jRequestUiThreadCallback = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "requestUiThreadCallback", "(J)V");
-    jScheduleRestart = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "scheduleRestart", "()V");
-    jSendMessageWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "sendMessage", "(Ljava/lang/String;Ljava/lang/String;I)V");
-    jSetFullScreen = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "setFullScreen", "(Z)V");
-    jSetKeepScreenOn = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "setKeepScreenOn", "(Z)V");
-    jSetURITitle = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "setUriTitle", "(Ljava/lang/String;Ljava/lang/String;)V");
-    jShowAlertNotificationWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "showAlertNotification", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
-    jShowInputMethodPicker = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "showInputMethodPicker", "()V");
-    jStartMonitoringGamepad = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "startMonitoringGamepad", "()V");
-    jStopMonitoringGamepad = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "stopMonitoringGamepad", "()V");
-    jUnlockProfile = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "unlockProfile", "()Z");
-    jUnlockScreenOrientation = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "unlockScreenOrientation", "()V");
-    jUnregisterSurfaceTextureFrameListener = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "unregisterSurfaceTextureFrameListener", "(Ljava/lang/Object;)V");
-    jVibrate1 = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "vibrate", "(J)V");
-    jVibrateA = AndroidBridge::GetStaticMethodID(env, mGeckoAppShellClass, "vibrate", "([JI)V");
+void GeckoAppShell::InitStubs(JNIEnv *jEnv) {
+    initInit();
+
+    mGeckoAppShellClass = getClassGlobalRef("org/mozilla/gecko/GeckoAppShell");
+    jAcknowledgeEvent = getStaticMethod("acknowledgeEvent", "()V");
+    jAddPluginViewWrapper = getStaticMethod("addPluginView", "(Landroid/view/View;FFFFZ)V");
+    jAlertsProgressListener_OnProgress = getStaticMethod("alertsProgressListener_OnProgress", "(Ljava/lang/String;JJLjava/lang/String;)V");
+    jCancelVibrate = getStaticMethod("cancelVibrate", "()V");
+    jCheckURIVisited = getStaticMethod("checkUriVisited", "(Ljava/lang/String;)V");
+    jClearMessageList = getStaticMethod("clearMessageList", "(I)V");
+    jCloseCamera = getStaticMethod("closeCamera", "()V");
+    jCloseNotification = getStaticMethod("closeNotification", "(Ljava/lang/String;)V");
+    jConnectionGetMimeType = getStaticMethod("connectionGetMimeType", "(Ljava/net/URLConnection;)Ljava/lang/String;");
+    jCreateInputStream = getStaticMethod("createInputStream", "(Ljava/net/URLConnection;)Ljava/io/InputStream;");
+    jCreateMessageListWrapper = getStaticMethod("createMessageList", "(JJ[Ljava/lang/String;ILjava/lang/String;ZZJZI)V");
+    jCreateShortcut = getStaticMethod("createShortcut", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+    jDeleteMessageWrapper = getStaticMethod("deleteMessage", "(II)V");
+    jDisableBatteryNotifications = getStaticMethod("disableBatteryNotifications", "()V");
+    jDisableNetworkNotifications = getStaticMethod("disableNetworkNotifications", "()V");
+    jDisableScreenOrientationNotifications = getStaticMethod("disableScreenOrientationNotifications", "()V");
+    jDisableSensor = getStaticMethod("disableSensor", "(I)V");
+    jEnableBatteryNotifications = getStaticMethod("enableBatteryNotifications", "()V");
+    jEnableLocation = getStaticMethod("enableLocation", "(Z)V");
+    jEnableLocationHighAccuracy = getStaticMethod("enableLocationHighAccuracy", "(Z)V");
+    jEnableNetworkNotifications = getStaticMethod("enableNetworkNotifications", "()V");
+    jEnableScreenOrientationNotifications = getStaticMethod("enableScreenOrientationNotifications", "()V");
+    jEnableSensor = getStaticMethod("enableSensor", "(I)V");
+    jGamepadAdded = getStaticMethod("gamepadAdded", "(II)V");
+    jGetConnection = getStaticMethod("getConnection", "(Ljava/lang/String;)Ljava/net/URLConnection;");
+    jGetContext = getStaticMethod("getContext", "()Landroid/content/Context;");
+    jGetCurrentBatteryInformationWrapper = getStaticMethod("getCurrentBatteryInformation", "()[D");
+    jGetCurrentNetworkInformationWrapper = getStaticMethod("getCurrentNetworkInformation", "()[D");
+    jGetDensity = getStaticMethod("getDensity", "()F");
+    jGetDpiWrapper = getStaticMethod("getDpi", "()I");
+    jGetExtensionFromMimeTypeWrapper = getStaticMethod("getExtensionFromMimeType", "(Ljava/lang/String;)Ljava/lang/String;");
+    jGetExternalPublicDirectory = getStaticMethod("getExternalPublicDirectory", "(Ljava/lang/String;)Ljava/lang/String;");
+    jGetHandlersForMimeTypeWrapper = getStaticMethod("getHandlersForMimeType", "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;");
+    jGetHandlersForURLWrapper = getStaticMethod("getHandlersForURL", "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;");
+    jGetIconForExtensionWrapper = getStaticMethod("getIconForExtension", "(Ljava/lang/String;I)[B");
+    jGetMessageWrapper = getStaticMethod("getMessage", "(II)V");
+    jGetMimeTypeFromExtensionsWrapper = getStaticMethod("getMimeTypeFromExtensions", "(Ljava/lang/String;)Ljava/lang/String;");
+    jGetNextMessageInListWrapper = getStaticMethod("getNextMessageInList", "(II)V");
+    jGetProxyForURIWrapper = getStaticMethod("getProxyForURI", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)Ljava/lang/String;");
+    jGetScreenDepthWrapper = getStaticMethod("getScreenDepth", "()I");
+    jGetScreenOrientationWrapper = getStaticMethod("getScreenOrientation", "()S");
+    jGetShowPasswordSetting = getStaticMethod("getShowPasswordSetting", "()Z");
+    jGetSystemColoursWrapper = getStaticMethod("getSystemColors", "()[I");
+    jHandleGeckoMessageWrapper = getStaticMethod("handleGeckoMessage", "(Lorg/mozilla/gecko/util/NativeJSContainer;)V");
+    jHandleUncaughtException = getStaticMethod("handleUncaughtException", "(Ljava/lang/Thread;Ljava/lang/Throwable;)V");
+    jHideProgressDialog = getStaticMethod("hideProgressDialog", "()V");
+    jInitCameraWrapper = getStaticMethod("initCamera", "(Ljava/lang/String;III)[I");
+    jIsNetworkLinkKnown = getStaticMethod("isNetworkLinkKnown", "()Z");
+    jIsNetworkLinkUp = getStaticMethod("isNetworkLinkUp", "()Z");
+    jIsTablet = getStaticMethod("isTablet", "()Z");
+    jKillAnyZombies = getStaticMethod("killAnyZombies", "()V");
+    jLoadPluginClass = getStaticMethod("loadPluginClass", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Class;");
+    jLockScreenOrientation = getStaticMethod("lockScreenOrientation", "(I)V");
+    jMarkURIVisited = getStaticMethod("markUriVisited", "(Ljava/lang/String;)V");
+    jMoveTaskToBack = getStaticMethod("moveTaskToBack", "()V");
+    jNetworkLinkType = getStaticMethod("networkLinkType", "()I");
+    jNotifyDefaultPrevented = getStaticMethod("notifyDefaultPrevented", "(Z)V");
+    jNotifyIME = getStaticMethod("notifyIME", "(I)V");
+    jNotifyIMEChange = getStaticMethod("notifyIMEChange", "(Ljava/lang/String;III)V");
+    jNotifyIMEContext = getStaticMethod("notifyIMEContext", "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+    jNotifyWakeLockChanged = getStaticMethod("notifyWakeLockChanged", "(Ljava/lang/String;Ljava/lang/String;)V");
+    jNotifyXreExit = getStaticMethod("onXreExit", "()V");
+    jOpenUriExternal = getStaticMethod("openUriExternal", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z");
+    jPerformHapticFeedback = getStaticMethod("performHapticFeedback", "(Z)V");
+    jPumpMessageLoop = getStaticMethod("pumpMessageLoop", "()Z");
+    jRegisterSurfaceTextureFrameListener = getStaticMethod("registerSurfaceTextureFrameListener", "(Ljava/lang/Object;I)V");
+    jRemovePluginView = getStaticMethod("removePluginView", "(Landroid/view/View;Z)V");
+    jRequestUiThreadCallback = getStaticMethod("requestUiThreadCallback", "(J)V");
+    jScheduleRestart = getStaticMethod("scheduleRestart", "()V");
+    jSendMessageWrapper = getStaticMethod("sendMessage", "(Ljava/lang/String;Ljava/lang/String;I)V");
+    jSetFullScreen = getStaticMethod("setFullScreen", "(Z)V");
+    jSetKeepScreenOn = getStaticMethod("setKeepScreenOn", "(Z)V");
+    jSetURITitle = getStaticMethod("setUriTitle", "(Ljava/lang/String;Ljava/lang/String;)V");
+    jShowAlertNotificationWrapper = getStaticMethod("showAlertNotification", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+    jShowInputMethodPicker = getStaticMethod("showInputMethodPicker", "()V");
+    jStartMonitoringGamepad = getStaticMethod("startMonitoringGamepad", "()V");
+    jStopMonitoringGamepad = getStaticMethod("stopMonitoringGamepad", "()V");
+    jUnlockProfile = getStaticMethod("unlockProfile", "()Z");
+    jUnlockScreenOrientation = getStaticMethod("unlockScreenOrientation", "()V");
+    jUnregisterSurfaceTextureFrameListener = getStaticMethod("unregisterSurfaceTextureFrameListener", "(Ljava/lang/Object;)V");
+    jVibrate1 = getStaticMethod("vibrate", "(J)V");
+    jVibrateA = getStaticMethod("vibrate", "([JI)V");
 }
 
 GeckoAppShell* GeckoAppShell::Wrap(jobject obj) {
     JNIEnv *env = GetJNIForThread();
     GeckoAppShell* ret = new GeckoAppShell(obj, env);
     env->DeleteLocalRef(obj);
     return ret;
 }
@@ -1333,25 +1337,27 @@ void GeckoAppShell::VibrateA(jlongArray 
 jclass GeckoJavaSampler::mGeckoJavaSamplerClass = 0;
 jmethodID GeckoJavaSampler::jGetFrameNameJavaProfilingWrapper = 0;
 jmethodID GeckoJavaSampler::jGetSampleTimeJavaProfiling = 0;
 jmethodID GeckoJavaSampler::jGetThreadNameJavaProfilingWrapper = 0;
 jmethodID GeckoJavaSampler::jPauseJavaProfiling = 0;
 jmethodID GeckoJavaSampler::jStartJavaProfiling = 0;
 jmethodID GeckoJavaSampler::jStopJavaProfiling = 0;
 jmethodID GeckoJavaSampler::jUnpauseJavaProfiling = 0;
-void GeckoJavaSampler::InitStubs(JNIEnv *env) {
-    mGeckoJavaSamplerClass = AndroidBridge::GetClassGlobalRef(env, "org/mozilla/gecko/GeckoJavaSampler");
-    jGetFrameNameJavaProfilingWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoJavaSamplerClass, "getFrameName", "(III)Ljava/lang/String;");
-    jGetSampleTimeJavaProfiling = AndroidBridge::GetStaticMethodID(env, mGeckoJavaSamplerClass, "getSampleTime", "(II)D");
-    jGetThreadNameJavaProfilingWrapper = AndroidBridge::GetStaticMethodID(env, mGeckoJavaSamplerClass, "getThreadName", "(I)Ljava/lang/String;");
-    jPauseJavaProfiling = AndroidBridge::GetStaticMethodID(env, mGeckoJavaSamplerClass, "pause", "()V");
-    jStartJavaProfiling = AndroidBridge::GetStaticMethodID(env, mGeckoJavaSamplerClass, "start", "(II)V");
-    jStopJavaProfiling = AndroidBridge::GetStaticMethodID(env, mGeckoJavaSamplerClass, "stop", "()V");
-    jUnpauseJavaProfiling = AndroidBridge::GetStaticMethodID(env, mGeckoJavaSamplerClass, "unpause", "()V");
+void GeckoJavaSampler::InitStubs(JNIEnv *jEnv) {
+    initInit();
+
+    mGeckoJavaSamplerClass = getClassGlobalRef("org/mozilla/gecko/GeckoJavaSampler");
+    jGetFrameNameJavaProfilingWrapper = getStaticMethod("getFrameName", "(III)Ljava/lang/String;");
+    jGetSampleTimeJavaProfiling = getStaticMethod("getSampleTime", "(II)D");
+    jGetThreadNameJavaProfilingWrapper = getStaticMethod("getThreadName", "(I)Ljava/lang/String;");
+    jPauseJavaProfiling = getStaticMethod("pause", "()V");
+    jStartJavaProfiling = getStaticMethod("start", "(II)V");
+    jStopJavaProfiling = getStaticMethod("stop", "()V");
+    jUnpauseJavaProfiling = getStaticMethod("unpause", "()V");
 }
 
 GeckoJavaSampler* GeckoJavaSampler::Wrap(jobject obj) {
     JNIEnv *env = GetJNIForThread();
     GeckoJavaSampler* ret = new GeckoJavaSampler(obj, env);
     env->DeleteLocalRef(obj);
     return ret;
 }
@@ -1446,21 +1452,23 @@ void GeckoJavaSampler::UnpauseJavaProfil
     env->CallStaticVoidMethod(mGeckoJavaSamplerClass, jUnpauseJavaProfiling);
     AndroidBridge::HandleUncaughtException(env);
     env->PopLocalFrame(nullptr);
 }
 jclass RestrictedProfiles::mRestrictedProfilesClass = 0;
 jmethodID RestrictedProfiles::jGetUserRestrictions = 0;
 jmethodID RestrictedProfiles::jIsAllowed = 0;
 jmethodID RestrictedProfiles::jIsUserRestricted = 0;
-void RestrictedProfiles::InitStubs(JNIEnv *env) {
-    mRestrictedProfilesClass = AndroidBridge::GetClassGlobalRef(env, "org/mozilla/gecko/RestrictedProfiles");
-    jGetUserRestrictions = AndroidBridge::GetStaticMethodID(env, mRestrictedProfilesClass, "getUserRestrictions", "()Ljava/lang/String;");
-    jIsAllowed = AndroidBridge::GetStaticMethodID(env, mRestrictedProfilesClass, "isAllowed", "(ILjava/lang/String;)Z");
-    jIsUserRestricted = AndroidBridge::GetStaticMethodID(env, mRestrictedProfilesClass, "isUserRestricted", "()Z");
+void RestrictedProfiles::InitStubs(JNIEnv *jEnv) {
+    initInit();
+
+    mRestrictedProfilesClass = getClassGlobalRef("org/mozilla/gecko/RestrictedProfiles");
+    jGetUserRestrictions = getStaticMethod("getUserRestrictions", "()Ljava/lang/String;");
+    jIsAllowed = getStaticMethod("isAllowed", "(ILjava/lang/String;)Z");
+    jIsUserRestricted = getStaticMethod("isUserRestricted", "()Z");
 }
 
 RestrictedProfiles* RestrictedProfiles::Wrap(jobject obj) {
     JNIEnv *env = GetJNIForThread();
     RestrictedProfiles* ret = new RestrictedProfiles(obj, env);
     env->DeleteLocalRef(obj);
     return ret;
 }
@@ -1506,23 +1514,25 @@ bool RestrictedProfiles::IsUserRestricte
     return temp;
 }
 jclass SurfaceBits::mSurfaceBitsClass = 0;
 jmethodID SurfaceBits::jSurfaceBits = 0;
 jfieldID SurfaceBits::jbuffer = 0;
 jfieldID SurfaceBits::jformat = 0;
 jfieldID SurfaceBits::jheight = 0;
 jfieldID SurfaceBits::jwidth = 0;
-void SurfaceBits::InitStubs(JNIEnv *env) {
-    mSurfaceBitsClass = AndroidBridge::GetClassGlobalRef(env, "org/mozilla/gecko/SurfaceBits");
-    jSurfaceBits = AndroidBridge::GetMethodID(env, mSurfaceBitsClass, "<init>", "()V");
-    jbuffer = AndroidBridge::GetFieldID(env, mSurfaceBitsClass, "buffer", "Ljava/nio/ByteBuffer;");
-    jformat = AndroidBridge::GetFieldID(env, mSurfaceBitsClass, "format", "I");
-    jheight = AndroidBridge::GetFieldID(env, mSurfaceBitsClass, "height", "I");
-    jwidth = AndroidBridge::GetFieldID(env, mSurfaceBitsClass, "width", "I");
+void SurfaceBits::InitStubs(JNIEnv *jEnv) {
+    initInit();
+
+    mSurfaceBitsClass = getClassGlobalRef("org/mozilla/gecko/SurfaceBits");
+    jSurfaceBits = getMethod("<init>", "()V");
+    jbuffer = getField("buffer", "Ljava/nio/ByteBuffer;");
+    jformat = getField("format", "I");
+    jheight = getField("height", "I");
+    jwidth = getField("width", "I");
 }
 
 SurfaceBits* SurfaceBits::Wrap(jobject obj) {
     JNIEnv *env = GetJNIForThread();
     SurfaceBits* ret = new SurfaceBits(obj, env);
     env->DeleteLocalRef(obj);
     return ret;
 }
@@ -1574,19 +1584,21 @@ int32_t SurfaceBits::getwidth() {
 }
 
 void SurfaceBits::setwidth(int32_t a0) {
     JNIEnv *env = GetJNIForThread();
     env->SetIntField(wrapped_obj, jwidth, a0);
 }
 jclass ThumbnailHelper::mThumbnailHelperClass = 0;
 jmethodID ThumbnailHelper::jSendThumbnail = 0;
-void ThumbnailHelper::InitStubs(JNIEnv *env) {
-    mThumbnailHelperClass = AndroidBridge::GetClassGlobalRef(env, "org/mozilla/gecko/ThumbnailHelper");
-    jSendThumbnail = AndroidBridge::GetStaticMethodID(env, mThumbnailHelperClass, "notifyThumbnail", "(Ljava/nio/ByteBuffer;IZZ)V");
+void ThumbnailHelper::InitStubs(JNIEnv *jEnv) {
+    initInit();
+
+    mThumbnailHelperClass = getClassGlobalRef("org/mozilla/gecko/ThumbnailHelper");
+    jSendThumbnail = getStaticMethod("notifyThumbnail", "(Ljava/nio/ByteBuffer;IZZ)V");
 }
 
 ThumbnailHelper* ThumbnailHelper::Wrap(jobject obj) {
     JNIEnv *env = GetJNIForThread();
     ThumbnailHelper* ret = new ThumbnailHelper(obj, env);
     env->DeleteLocalRef(obj);
     return ret;
 }
@@ -1607,21 +1619,23 @@ void ThumbnailHelper::SendThumbnail(jobj
     env->CallStaticVoidMethodA(mThumbnailHelperClass, jSendThumbnail, args);
     AndroidBridge::HandleUncaughtException(env);
     env->PopLocalFrame(nullptr);
 }
 jclass DisplayPortMetrics::mDisplayPortMetricsClass = 0;
 jmethodID DisplayPortMetrics::jDisplayPortMetrics = 0;
 jfieldID DisplayPortMetrics::jMPosition = 0;
 jfieldID DisplayPortMetrics::jResolution = 0;
-void DisplayPortMetrics::InitStubs(JNIEnv *env) {
-    mDisplayPortMetricsClass = AndroidBridge::GetClassGlobalRef(env, "org/mozilla/gecko/gfx/DisplayPortMetrics");
-    jDisplayPortMetrics = AndroidBridge::GetMethodID(env, mDisplayPortMetricsClass, "<init>", "(FFFFF)V");
-    jMPosition = AndroidBridge::GetFieldID(env, mDisplayPortMetricsClass, "mPosition", "Landroid/graphics/RectF;");
-    jResolution = AndroidBridge::GetFieldID(env, mDisplayPortMetricsClass, "resolution", "F");
+void DisplayPortMetrics::InitStubs(JNIEnv *jEnv) {
+    initInit();
+
+    mDisplayPortMetricsClass = getClassGlobalRef("org/mozilla/gecko/gfx/DisplayPortMetrics");
+    jDisplayPortMetrics = getMethod("<init>", "(FFFFF)V");
+    jMPosition = getField("mPosition", "Landroid/graphics/RectF;");
+    jResolution = getField("resolution", "F");
 }
 
 DisplayPortMetrics* DisplayPortMetrics::Wrap(jobject obj) {
     JNIEnv *env = GetJNIForThread();
     DisplayPortMetrics* ret = new DisplayPortMetrics(obj, env);
     env->DeleteLocalRef(obj);
     return ret;
 }
@@ -1650,19 +1664,21 @@ jobject DisplayPortMetrics::getMPosition
 }
 
 jfloat DisplayPortMetrics::getResolution() {
     JNIEnv *env = GetJNIForThread();
     return env->GetFloatField(wrapped_obj, jResolution);
 }
 jclass GLController::mGLControllerClass = 0;
 jmethodID GLController::jCreateEGLSurfaceForCompositorWrapper = 0;
-void GLController::InitStubs(JNIEnv *env) {
-    mGLControllerClass = AndroidBridge::GetClassGlobalRef(env, "org/mozilla/gecko/gfx/GLController");
-    jCreateEGLSurfaceForCompositorWrapper = AndroidBridge::GetMethodID(env, mGLControllerClass, "createEGLSurfaceForCompositor", "()Ljavax/microedition/khronos/egl/EGLSurface;");
+void GLController::InitStubs(JNIEnv *jEnv) {
+    initInit();
+
+    mGLControllerClass = getClassGlobalRef("org/mozilla/gecko/gfx/GLController");
+    jCreateEGLSurfaceForCompositorWrapper = getMethod("createEGLSurfaceForCompositor", "()Ljavax/microedition/khronos/egl/EGLSurface;");
 }
 
 GLController* GLController::Wrap(jobject obj) {
     JNIEnv *env = GetJNIForThread();
     GLController* ret = new GLController(obj, env);
     env->DeleteLocalRef(obj);
     return ret;
 }
@@ -1686,29 +1702,31 @@ jmethodID GeckoLayerClient::jCreateFrame
 jmethodID GeckoLayerClient::jDeactivateProgramAndRestoreState = 0;
 jmethodID GeckoLayerClient::jGetDisplayPort = 0;
 jmethodID GeckoLayerClient::jIsContentDocumentDisplayed = 0;
 jmethodID GeckoLayerClient::jProgressiveUpdateCallback = 0;
 jmethodID GeckoLayerClient::jSetFirstPaintViewport = 0;
 jmethodID GeckoLayerClient::jSetPageRect = 0;
 jmethodID GeckoLayerClient::jSyncFrameMetrics = 0;
 jmethodID GeckoLayerClient::jSyncViewportInfo = 0;
-void GeckoLayerClient::InitStubs(JNIEnv *env) {
-    mGeckoLayerClientClass = AndroidBridge::GetClassGlobalRef(env, "org/mozilla/gecko/gfx/GeckoLayerClient");
-    jActivateProgram = AndroidBridge::GetMethodID(env, mGeckoLayerClientClass, "activateProgram", "()V");
-    jContentDocumentChanged = AndroidBridge::GetMethodID(env, mGeckoLayerClientClass, "contentDocumentChanged", "()V");
-    jCreateFrame = AndroidBridge::GetMethodID(env, mGeckoLayerClientClass, "createFrame", "()Lorg/mozilla/gecko/gfx/LayerRenderer$Frame;");
-    jDeactivateProgramAndRestoreState = AndroidBridge::GetMethodID(env, mGeckoLayerClientClass, "deactivateProgramAndRestoreState", "(ZIIII)V");
-    jGetDisplayPort = AndroidBridge::GetMethodID(env, mGeckoLayerClientClass, "getDisplayPort", "(ZZILorg/mozilla/gecko/gfx/ImmutableViewportMetrics;)Lorg/mozilla/gecko/gfx/DisplayPortMetrics;");
-    jIsContentDocumentDisplayed = AndroidBridge::GetMethodID(env, mGeckoLayerClientClass, "isContentDocumentDisplayed", "()Z");
-    jProgressiveUpdateCallback = AndroidBridge::GetMethodID(env, mGeckoLayerClientClass, "progressiveUpdateCallback", "(ZFFFFFZ)Lorg/mozilla/gecko/gfx/ProgressiveUpdateData;");
-    jSetFirstPaintViewport = AndroidBridge::GetMethodID(env, mGeckoLayerClientClass, "setFirstPaintViewport", "(FFFFFFF)V");
-    jSetPageRect = AndroidBridge::GetMethodID(env, mGeckoLayerClientClass, "setPageRect", "(FFFF)V");
-    jSyncFrameMetrics = AndroidBridge::GetMethodID(env, mGeckoLayerClientClass, "syncFrameMetrics", "(FFFFFFFZIIIIFZ)Lorg/mozilla/gecko/gfx/ViewTransform;");
-    jSyncViewportInfo = AndroidBridge::GetMethodID(env, mGeckoLayerClientClass, "syncViewportInfo", "(IIIIFZ)Lorg/mozilla/gecko/gfx/ViewTransform;");
+void GeckoLayerClient::InitStubs(JNIEnv *jEnv) {
+    initInit();
+
+    mGeckoLayerClientClass = getClassGlobalRef("org/mozilla/gecko/gfx/GeckoLayerClient");
+    jActivateProgram = getMethod("activateProgram", "()V");
+    jContentDocumentChanged = getMethod("contentDocumentChanged", "()V");
+    jCreateFrame = getMethod("createFrame", "()Lorg/mozilla/gecko/gfx/LayerRenderer$Frame;");
+    jDeactivateProgramAndRestoreState = getMethod("deactivateProgramAndRestoreState", "(ZIIII)V");
+    jGetDisplayPort = getMethod("getDisplayPort", "(ZZILorg/mozilla/gecko/gfx/ImmutableViewportMetrics;)Lorg/mozilla/gecko/gfx/DisplayPortMetrics;");
+    jIsContentDocumentDisplayed = getMethod("isContentDocumentDisplayed", "()Z");
+    jProgressiveUpdateCallback = getMethod("progressiveUpdateCallback", "(ZFFFFFZ)Lorg/mozilla/gecko/gfx/ProgressiveUpdateData;");
+    jSetFirstPaintViewport = getMethod("setFirstPaintViewport", "(FFFFFFF)V");
+    jSetPageRect = getMethod("setPageRect", "(FFFF)V");
+    jSyncFrameMetrics = getMethod("syncFrameMetrics", "(FFFFFFFZIIIIFZ)Lorg/mozilla/gecko/gfx/ViewTransform;");
+    jSyncViewportInfo = getMethod("syncViewportInfo", "(IIIIFZ)Lorg/mozilla/gecko/gfx/ViewTransform;");
 }
 
 GeckoLayerClient* GeckoLayerClient::Wrap(jobject obj) {
     JNIEnv *env = GetJNIForThread();
     GeckoLayerClient* ret = new GeckoLayerClient(obj, env);
     env->DeleteLocalRef(obj);
     return ret;
 }
@@ -1908,19 +1926,21 @@ jobject GeckoLayerClient::SyncViewportIn
 
     jobject temp = env->CallObjectMethodA(wrapped_obj, jSyncViewportInfo, args);
     AndroidBridge::HandleUncaughtException(env);
     jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
     return ret;
 }
 jclass ImmutableViewportMetrics::mImmutableViewportMetricsClass = 0;
 jmethodID ImmutableViewportMetrics::jImmutableViewportMetrics = 0;
-void ImmutableViewportMetrics::InitStubs(JNIEnv *env) {
-    mImmutableViewportMetricsClass = AndroidBridge::GetClassGlobalRef(env, "org/mozilla/gecko/gfx/ImmutableViewportMetrics");
-    jImmutableViewportMetrics = AndroidBridge::GetMethodID(env, mImmutableViewportMetricsClass, "<init>", "(FFFFFFFFFFFFF)V");
+void ImmutableViewportMetrics::InitStubs(JNIEnv *jEnv) {
+    initInit();
+
+    mImmutableViewportMetricsClass = getClassGlobalRef("org/mozilla/gecko/gfx/ImmutableViewportMetrics");
+    jImmutableViewportMetrics = getMethod("<init>", "(FFFFFFFFFFFFF)V");
 }
 
 ImmutableViewportMetrics* ImmutableViewportMetrics::Wrap(jobject obj) {
     JNIEnv *env = GetJNIForThread();
     ImmutableViewportMetrics* ret = new ImmutableViewportMetrics(obj, env);
     env->DeleteLocalRef(obj);
     return ret;
 }
@@ -1947,19 +1967,21 @@ ImmutableViewportMetrics::ImmutableViewp
     args[11].f = a11;
     args[12].f = a12;
 
     Init(env->NewObjectA(mImmutableViewportMetricsClass, jImmutableViewportMetrics, args), env);
     env->PopLocalFrame(nullptr);
 }
 jclass LayerView::mLayerViewClass = 0;
 jmethodID LayerView::jRegisterCompositorWrapper = 0;
-void LayerView::InitStubs(JNIEnv *env) {
-    mLayerViewClass = AndroidBridge::GetClassGlobalRef(env, "org/mozilla/gecko/gfx/LayerView");
-    jRegisterCompositorWrapper = AndroidBridge::GetStaticMethodID(env, mLayerViewClass, "registerCxxCompositor", "()Lorg/mozilla/gecko/gfx/GLController;");
+void LayerView::InitStubs(JNIEnv *jEnv) {
+    initInit();
+
+    mLayerViewClass = getClassGlobalRef("org/mozilla/gecko/gfx/LayerView");
+    jRegisterCompositorWrapper = getStaticMethod("registerCxxCompositor", "()Lorg/mozilla/gecko/gfx/GLController;");
 }
 
 LayerView* LayerView::Wrap(jobject obj) {
     JNIEnv *env = GetJNIForThread();
     LayerView* ret = new LayerView(obj, env);
     env->DeleteLocalRef(obj);
     return ret;
 }
@@ -1973,19 +1995,21 @@ jobject LayerView::RegisterCompositorWra
 
     jobject temp = env->CallStaticObjectMethod(mLayerViewClass, jRegisterCompositorWrapper);
     AndroidBridge::HandleUncaughtException(env);
     jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
     return ret;
 }
 jclass NativePanZoomController::mNativePanZoomControllerClass = 0;
 jmethodID NativePanZoomController::jRequestContentRepaintWrapper = 0;
-void NativePanZoomController::InitStubs(JNIEnv *env) {
-    mNativePanZoomControllerClass = AndroidBridge::GetClassGlobalRef(env, "org/mozilla/gecko/gfx/NativePanZoomController");
-    jRequestContentRepaintWrapper = AndroidBridge::GetMethodID(env, mNativePanZoomControllerClass, "requestContentRepaint", "(FFFFF)V");
+void NativePanZoomController::InitStubs(JNIEnv *jEnv) {
+    initInit();
+
+    mNativePanZoomControllerClass = getClassGlobalRef("org/mozilla/gecko/gfx/NativePanZoomController");
+    jRequestContentRepaintWrapper = getMethod("requestContentRepaint", "(FFFFF)V");
 }
 
 NativePanZoomController* NativePanZoomController::Wrap(jobject obj) {
     JNIEnv *env = GetJNIForThread();
     NativePanZoomController* ret = new NativePanZoomController(obj, env);
     env->DeleteLocalRef(obj);
     return ret;
 }
@@ -2010,24 +2034,26 @@ void NativePanZoomController::RequestCon
 }
 jclass ProgressiveUpdateData::mProgressiveUpdateDataClass = 0;
 jmethodID ProgressiveUpdateData::jProgressiveUpdateData = 0;
 jmethodID ProgressiveUpdateData::jsetViewport = 0;
 jfieldID ProgressiveUpdateData::jabort = 0;
 jfieldID ProgressiveUpdateData::jscale = 0;
 jfieldID ProgressiveUpdateData::jx = 0;
 jfieldID ProgressiveUpdateData::jy = 0;
-void ProgressiveUpdateData::InitStubs(JNIEnv *env) {
-    mProgressiveUpdateDataClass = AndroidBridge::GetClassGlobalRef(env, "org/mozilla/gecko/gfx/ProgressiveUpdateData");
-    jProgressiveUpdateData = AndroidBridge::GetMethodID(env, mProgressiveUpdateDataClass, "<init>", "()V");
-    jsetViewport = AndroidBridge::GetMethodID(env, mProgressiveUpdateDataClass, "setViewport", "(Lorg/mozilla/gecko/gfx/ImmutableViewportMetrics;)V");
-    jabort = AndroidBridge::GetFieldID(env, mProgressiveUpdateDataClass, "abort", "Z");
-    jscale = AndroidBridge::GetFieldID(env, mProgressiveUpdateDataClass, "scale", "F");
-    jx = AndroidBridge::GetFieldID(env, mProgressiveUpdateDataClass, "x", "F");
-    jy = AndroidBridge::GetFieldID(env, mProgressiveUpdateDataClass, "y", "F");
+void ProgressiveUpdateData::InitStubs(JNIEnv *jEnv) {
+    initInit();
+
+    mProgressiveUpdateDataClass = getClassGlobalRef("org/mozilla/gecko/gfx/ProgressiveUpdateData");
+    jProgressiveUpdateData = getMethod("<init>", "()V");
+    jsetViewport = getMethod("setViewport", "(Lorg/mozilla/gecko/gfx/ImmutableViewportMetrics;)V");
+    jabort = getField("abort", "Z");
+    jscale = getField("scale", "F");
+    jx = getField("x", "F");
+    jy = getField("y", "F");
 }
 
 ProgressiveUpdateData* ProgressiveUpdateData::Wrap(jobject obj) {
     JNIEnv *env = GetJNIForThread();
     ProgressiveUpdateData* ret = new ProgressiveUpdateData(obj, env);
     env->DeleteLocalRef(obj);
     return ret;
 }
@@ -2100,28 +2126,30 @@ jfieldID ViewTransform::jfixedLayerMargi
 jfieldID ViewTransform::jfixedLayerMarginLeft = 0;
 jfieldID ViewTransform::jfixedLayerMarginRight = 0;
 jfieldID ViewTransform::jfixedLayerMarginTop = 0;
 jfieldID ViewTransform::joffsetX = 0;
 jfieldID ViewTransform::joffsetY = 0;
 jfieldID ViewTransform::jscale = 0;
 jfieldID ViewTransform::jx = 0;
 jfieldID ViewTransform::jy = 0;
-void ViewTransform::InitStubs(JNIEnv *env) {
-    mViewTransformClass = AndroidBridge::GetClassGlobalRef(env, "org/mozilla/gecko/gfx/ViewTransform");
-    jViewTransform = AndroidBridge::GetMethodID(env, mViewTransformClass, "<init>", "(FFF)V");
-    jfixedLayerMarginBottom = AndroidBridge::GetFieldID(env, mViewTransformClass, "fixedLayerMarginBottom", "F");
-    jfixedLayerMarginLeft = AndroidBridge::GetFieldID(env, mViewTransformClass, "fixedLayerMarginLeft", "F");
-    jfixedLayerMarginRight = AndroidBridge::GetFieldID(env, mViewTransformClass, "fixedLayerMarginRight", "F");
-    jfixedLayerMarginTop = AndroidBridge::GetFieldID(env, mViewTransformClass, "fixedLayerMarginTop", "F");
-    joffsetX = AndroidBridge::GetFieldID(env, mViewTransformClass, "offsetX", "F");
-    joffsetY = AndroidBridge::GetFieldID(env, mViewTransformClass, "offsetY", "F");
-    jscale = AndroidBridge::GetFieldID(env, mViewTransformClass, "scale", "F");
-    jx = AndroidBridge::GetFieldID(env, mViewTransformClass, "x", "F");
-    jy = AndroidBridge::GetFieldID(env, mViewTransformClass, "y", "F");
+void ViewTransform::InitStubs(JNIEnv *jEnv) {
+    initInit();
+
+    mViewTransformClass = getClassGlobalRef("org/mozilla/gecko/gfx/ViewTransform");
+    jViewTransform = getMethod("<init>", "(FFF)V");
+    jfixedLayerMarginBottom = getField("fixedLayerMarginBottom", "F");
+    jfixedLayerMarginLeft = getField("fixedLayerMarginLeft", "F");
+    jfixedLayerMarginRight = getField("fixedLayerMarginRight", "F");
+    jfixedLayerMarginTop = getField("fixedLayerMarginTop", "F");
+    joffsetX = getField("offsetX", "F");
+    joffsetY = getField("offsetY", "F");
+    jscale = getField("scale", "F");
+    jx = getField("x", "F");
+    jy = getField("y", "F");
 }
 
 ViewTransform* ViewTransform::Wrap(jobject obj) {
     JNIEnv *env = GetJNIForThread();
     ViewTransform* ret = new ViewTransform(obj, env);
     env->DeleteLocalRef(obj);
     return ret;
 }
@@ -2228,19 +2256,21 @@ jfloat ViewTransform::gety() {
 }
 
 void ViewTransform::sety(jfloat a0) {
     JNIEnv *env = GetJNIForThread();
     env->SetFloatField(wrapped_obj, jy, a0);
 }
 jclass NativeZip::mNativeZipClass = 0;
 jmethodID NativeZip::jCreateInputStream = 0;
-void NativeZip::InitStubs(JNIEnv *env) {
-    mNativeZipClass = AndroidBridge::GetClassGlobalRef(env, "org/mozilla/gecko/mozglue/NativeZip");
-    jCreateInputStream = AndroidBridge::GetMethodID(env, mNativeZipClass, "createInputStream", "(Ljava/nio/ByteBuffer;I)Ljava/io/InputStream;");
+void NativeZip::InitStubs(JNIEnv *jEnv) {
+    initInit();
+
+    mNativeZipClass = getClassGlobalRef("org/mozilla/gecko/mozglue/NativeZip");
+    jCreateInputStream = getMethod("createInputStream", "(Ljava/nio/ByteBuffer;I)Ljava/io/InputStream;");
 }
 
 NativeZip* NativeZip::Wrap(jobject obj) {
     JNIEnv *env = GetJNIForThread();
     NativeZip* ret = new NativeZip(obj, env);
     env->DeleteLocalRef(obj);
     return ret;
 }
@@ -2258,23 +2288,25 @@ jobject NativeZip::CreateInputStream(job
     return ret;
 }
 jclass MatrixBlobCursor::mMatrixBlobCursorClass = 0;
 jmethodID MatrixBlobCursor::jMatrixBlobCursor = 0;
 jmethodID MatrixBlobCursor::jMatrixBlobCursor0 = 0;
 jmethodID MatrixBlobCursor::jAddRow = 0;
 jmethodID MatrixBlobCursor::jAddRow1 = 0;
 jmethodID MatrixBlobCursor::jAddRow2 = 0;
-void MatrixBlobCursor::InitStubs(JNIEnv *env) {
-    mMatrixBlobCursorClass = AndroidBridge::GetClassGlobalRef(env, "org/mozilla/gecko/sqlite/MatrixBlobCursor");
-    jMatrixBlobCursor = AndroidBridge::GetMethodID(env, mMatrixBlobCursorClass, "<init>", "([Ljava/lang/String;)V");
-    jMatrixBlobCursor0 = AndroidBridge::GetMethodID(env, mMatrixBlobCursorClass, "<init>", "([Ljava/lang/String;I)V");
-    jAddRow = AndroidBridge::GetMethodID(env, mMatrixBlobCursorClass, "addRow", "(Ljava/lang/Iterable;)V");
-    jAddRow1 = AndroidBridge::GetMethodID(env, mMatrixBlobCursorClass, "addRow", "(Ljava/util/ArrayList;I)V");
-    jAddRow2 = AndroidBridge::GetMethodID(env, mMatrixBlobCursorClass, "addRow", "([Ljava/lang/Object;)V");
+void MatrixBlobCursor::InitStubs(JNIEnv *jEnv) {
+    initInit();
+
+    mMatrixBlobCursorClass = getClassGlobalRef("org/mozilla/gecko/sqlite/MatrixBlobCursor");
+    jMatrixBlobCursor = getMethod("<init>", "([Ljava/lang/String;)V");
+    jMatrixBlobCursor0 = getMethod("<init>", "([Ljava/lang/String;I)V");
+    jAddRow = getMethod("addRow", "(Ljava/lang/Iterable;)V");
+    jAddRow1 = getMethod("addRow", "(Ljava/util/ArrayList;I)V");
+    jAddRow2 = getMethod("addRow", "([Ljava/lang/Object;)V");
 }
 
 MatrixBlobCursor* MatrixBlobCursor::Wrap(jobject obj) {
     JNIEnv *env = GetJNIForThread();
     MatrixBlobCursor* ret = new MatrixBlobCursor(obj, env);
     env->DeleteLocalRef(obj);
     return ret;
 }
@@ -2335,21 +2367,23 @@ void MatrixBlobCursor::AddRow(jobjectArr
     env->CallVoidMethod(wrapped_obj, jAddRow2, a0);
     AndroidBridge::HandleUncaughtException(env);
     env->PopLocalFrame(nullptr);
 }
 jclass SQLiteBridgeException::mSQLiteBridgeExceptionClass = 0;
 jmethodID SQLiteBridgeException::jSQLiteBridgeException = 0;
 jmethodID SQLiteBridgeException::jSQLiteBridgeException0 = 0;
 jfieldID SQLiteBridgeException::jserialVersionUID = 0;
-void SQLiteBridgeException::InitStubs(JNIEnv *env) {
-    mSQLiteBridgeExceptionClass = AndroidBridge::GetClassGlobalRef(env, "org/mozilla/gecko/sqlite/SQLiteBridgeException");
-    jSQLiteBridgeException = AndroidBridge::GetMethodID(env, mSQLiteBridgeExceptionClass, "<init>", "()V");
-    jSQLiteBridgeException0 = AndroidBridge::GetMethodID(env, mSQLiteBridgeExceptionClass, "<init>", "(Ljava/lang/String;)V");
-    jserialVersionUID = AndroidBridge::GetStaticFieldID(env, mSQLiteBridgeExceptionClass, "serialVersionUID", "J");
+void SQLiteBridgeException::InitStubs(JNIEnv *jEnv) {
+    initInit();
+
+    mSQLiteBridgeExceptionClass = getClassGlobalRef("org/mozilla/gecko/sqlite/SQLiteBridgeException");
+    jSQLiteBridgeException = getMethod("<init>", "()V");
+    jSQLiteBridgeException0 = getMethod("<init>", "(Ljava/lang/String;)V");
+    jserialVersionUID = getStaticField("serialVersionUID", "J");
 }
 
 SQLiteBridgeException* SQLiteBridgeException::Wrap(jobject obj) {
     JNIEnv *env = GetJNIForThread();
     SQLiteBridgeException* ret = new SQLiteBridgeException(obj, env);
     env->DeleteLocalRef(obj);
     return ret;
 }
@@ -2382,22 +2416,24 @@ int64_t SQLiteBridgeException::getserial
     JNIEnv *env = GetJNIForThread();
     return env->GetStaticLongField(mSQLiteBridgeExceptionClass, jserialVersionUID);
 }
 jclass Clipboard::mClipboardClass = 0;
 jmethodID Clipboard::jClearText = 0;
 jmethodID Clipboard::jGetClipboardTextWrapper = 0;
 jmethodID Clipboard::jHasText = 0;
 jmethodID Clipboard::jSetClipboardText = 0;
-void Clipboard::InitStubs(JNIEnv *env) {
-    mClipboardClass = AndroidBridge::GetClassGlobalRef(env, "org/mozilla/gecko/util/Clipboard");
-    jClearText = AndroidBridge::GetStaticMethodID(env, mClipboardClass, "clearText", "()V");
-    jGetClipboardTextWrapper = AndroidBridge::GetStaticMethodID(env, mClipboardClass, "getText", "()Ljava/lang/String;");
-    jHasText = AndroidBridge::GetStaticMethodID(env, mClipboardClass, "hasText", "()Z");
-    jSetClipboardText = AndroidBridge::GetStaticMethodID(env, mClipboardClass, "setText", "(Ljava/lang/CharSequence;)V");
+void Clipboard::InitStubs(JNIEnv *jEnv) {
+    initInit();
+
+    mClipboardClass = getClassGlobalRef("org/mozilla/gecko/util/Clipboard");
+    jClearText = getStaticMethod("clearText", "()V");
+    jGetClipboardTextWrapper = getStaticMethod("getText", "()Ljava/lang/String;");
+    jHasText = getStaticMethod("hasText", "()Z");
+    jSetClipboardText = getStaticMethod("setText", "(Ljava/lang/CharSequence;)V");
 }
 
 Clipboard* Clipboard::Wrap(jobject obj) {
     JNIEnv *env = GetJNIForThread();
     Clipboard* ret = new Clipboard(obj, env);
     env->DeleteLocalRef(obj);
     return ret;
 }
@@ -2449,31 +2485,31 @@ void Clipboard::SetClipboardText(const n
 
     jstring j0 = AndroidBridge::NewJavaString(env, a0);
 
     env->CallStaticVoidMethod(mClipboardClass, jSetClipboardText, j0);
     AndroidBridge::HandleUncaughtException(env);
     env->PopLocalFrame(nullptr);
 }
 
-void InitStubs(JNIEnv *env) {
-    DownloadsIntegration::InitStubs(env);
-    GeckoAppShell::InitStubs(env);
-    GeckoJavaSampler::InitStubs(env);
-    RestrictedProfiles::InitStubs(env);
-    SurfaceBits::InitStubs(env);
-    ThumbnailHelper::InitStubs(env);
-    DisplayPortMetrics::InitStubs(env);
-    GLController::InitStubs(env);
-    GeckoLayerClient::InitStubs(env);
-    ImmutableViewportMetrics::InitStubs(env);
-    LayerView::InitStubs(env);
-    NativePanZoomController::InitStubs(env);
-    ProgressiveUpdateData::InitStubs(env);
-    ViewTransform::InitStubs(env);
-    NativeZip::InitStubs(env);
-    MatrixBlobCursor::InitStubs(env);
-    SQLiteBridgeException::InitStubs(env);
-    Clipboard::InitStubs(env);
+void InitStubs(JNIEnv *jEnv) {
+    DownloadsIntegration::InitStubs(jEnv);
+    GeckoAppShell::InitStubs(jEnv);
+    GeckoJavaSampler::InitStubs(jEnv);
+    RestrictedProfiles::InitStubs(jEnv);
+    SurfaceBits::InitStubs(jEnv);
+    ThumbnailHelper::InitStubs(jEnv);
+    DisplayPortMetrics::InitStubs(jEnv);
+    GLController::InitStubs(jEnv);
+    GeckoLayerClient::InitStubs(jEnv);
+    ImmutableViewportMetrics::InitStubs(jEnv);
+    LayerView::InitStubs(jEnv);
+    NativePanZoomController::InitStubs(jEnv);
+    ProgressiveUpdateData::InitStubs(jEnv);
+    ViewTransform::InitStubs(jEnv);
+    NativeZip::InitStubs(jEnv);
+    MatrixBlobCursor::InitStubs(jEnv);
+    SQLiteBridgeException::InitStubs(jEnv);
+    Clipboard::InitStubs(jEnv);
 }
 } /* android */
 } /* widget */
 } /* mozilla */
--- a/widget/android/GeneratedJNIWrappers.h
+++ b/widget/android/GeneratedJNIWrappers.h
@@ -7,33 +7,33 @@
 #define GeneratedJNIWrappers_h__
 
 #include "nsXPCOMStrings.h"
 #include "AndroidJavaWrappers.h"
 
 namespace mozilla {
 namespace widget {
 namespace android {
-void InitStubs(JNIEnv *env);
+void InitStubs(JNIEnv *jEnv);
 
 class DownloadsIntegration : public AutoGlobalWrappedJavaObject {
 public:
-    static void InitStubs(JNIEnv *env);
+    static void InitStubs(JNIEnv *jEnv);
     static DownloadsIntegration* Wrap(jobject obj);
     DownloadsIntegration(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
     static void ScanMedia(const nsAString& a0, const nsAString& a1);
     DownloadsIntegration() : AutoGlobalWrappedJavaObject() {};
 protected:
     static jclass mDownloadsIntegrationClass;
     static jmethodID jScanMedia;
 };
 
 class GeckoAppShell : public AutoGlobalWrappedJavaObject {
 public:
-    static void InitStubs(JNIEnv *env);
+    static void InitStubs(JNIEnv *jEnv);
     static GeckoAppShell* Wrap(jobject obj);
     GeckoAppShell(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
     static void AcknowledgeEvent();
     static void AddPluginViewWrapper(jobject a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4, bool a5);
     static void AlertsProgressListener_OnProgress(const nsAString& a0, int64_t a1, int64_t a2, const nsAString& a3);
     static void CancelVibrate();
     static void CheckURIVisited(const nsAString& a0);
     static void ClearMessageList(int32_t a0);
@@ -197,17 +197,17 @@ protected:
     static jmethodID jUnlockScreenOrientation;
     static jmethodID jUnregisterSurfaceTextureFrameListener;
     static jmethodID jVibrate1;
     static jmethodID jVibrateA;
 };
 
 class GeckoJavaSampler : public AutoGlobalWrappedJavaObject {
 public:
-    static void InitStubs(JNIEnv *env);
+    static void InitStubs(JNIEnv *jEnv);
     static GeckoJavaSampler* Wrap(jobject obj);
     GeckoJavaSampler(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
     static jstring GetFrameNameJavaProfilingWrapper(int32_t a0, int32_t a1, int32_t a2);
     static jdouble GetSampleTimeJavaProfiling(int32_t a0, int32_t a1);
     static jstring GetThreadNameJavaProfilingWrapper(int32_t a0);
     static void PauseJavaProfiling();
     static void StartJavaProfiling(int32_t a0, int32_t a1);
     static void StopJavaProfiling();
@@ -221,33 +221,33 @@ protected:
     static jmethodID jPauseJavaProfiling;
     static jmethodID jStartJavaProfiling;
     static jmethodID jStopJavaProfiling;
     static jmethodID jUnpauseJavaProfiling;
 };
 
 class RestrictedProfiles : public AutoGlobalWrappedJavaObject {
 public:
-    static void InitStubs(JNIEnv *env);
+    static void InitStubs(JNIEnv *jEnv);
     static RestrictedProfiles* Wrap(jobject obj);
     RestrictedProfiles(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
     static jstring GetUserRestrictions();
     static bool IsAllowed(int32_t a0, const nsAString& a1);
     static bool IsUserRestricted();
     RestrictedProfiles() : AutoGlobalWrappedJavaObject() {};
 protected:
     static jclass mRestrictedProfilesClass;
     static jmethodID jGetUserRestrictions;
     static jmethodID jIsAllowed;
     static jmethodID jIsUserRestricted;
 };
 
 class SurfaceBits : public AutoGlobalWrappedJavaObject {
 public:
-    static void InitStubs(JNIEnv *env);
+    static void InitStubs(JNIEnv *jEnv);
     static SurfaceBits* Wrap(jobject obj);
     SurfaceBits(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
     SurfaceBits();
     jobject getbuffer();
     void setbuffer(jobject a0);
     int32_t getformat();
     void setformat(int32_t a0);
     int32_t getheight();
@@ -260,57 +260,57 @@ protected:
     static jfieldID jbuffer;
     static jfieldID jformat;
     static jfieldID jheight;
     static jfieldID jwidth;
 };
 
 class ThumbnailHelper : public AutoGlobalWrappedJavaObject {
 public:
-    static void InitStubs(JNIEnv *env);
+    static void InitStubs(JNIEnv *jEnv);
     static ThumbnailHelper* Wrap(jobject obj);
     ThumbnailHelper(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
     static void SendThumbnail(jobject a0, int32_t a1, bool a2, bool a3);
     ThumbnailHelper() : AutoGlobalWrappedJavaObject() {};
 protected:
     static jclass mThumbnailHelperClass;
     static jmethodID jSendThumbnail;
 };
 
 class DisplayPortMetrics : public AutoGlobalWrappedJavaObject {
 public:
-    static void InitStubs(JNIEnv *env);
+    static void InitStubs(JNIEnv *jEnv);
     static DisplayPortMetrics* Wrap(jobject obj);
     DisplayPortMetrics(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
     DisplayPortMetrics(jfloat a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4);
     jobject getMPosition();
     jfloat getResolution();
     DisplayPortMetrics() : AutoGlobalWrappedJavaObject() {};
 protected:
     static jclass mDisplayPortMetricsClass;
     static jmethodID jDisplayPortMetrics;
     static jfieldID jMPosition;
     static jfieldID jResolution;
 };
 
 class GLController : public AutoGlobalWrappedJavaObject {
 public:
-    static void InitStubs(JNIEnv *env);
+    static void InitStubs(JNIEnv *jEnv);
     static GLController* Wrap(jobject obj);
     GLController(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
     jobject CreateEGLSurfaceForCompositorWrapper();
     GLController() : AutoGlobalWrappedJavaObject() {};
 protected:
     static jclass mGLControllerClass;
     static jmethodID jCreateEGLSurfaceForCompositorWrapper;
 };
 
 class GeckoLayerClient : public AutoGlobalWrappedJavaObject {
 public:
-    static void InitStubs(JNIEnv *env);
+    static void InitStubs(JNIEnv *jEnv);
     static GeckoLayerClient* Wrap(jobject obj);
     GeckoLayerClient(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
     void ActivateProgram();
     void ContentDocumentChanged();
     jobject CreateFrame();
     void DeactivateProgramAndRestoreState(bool a0, int32_t a1, int32_t a2, int32_t a3, int32_t a4);
     jobject GetDisplayPort(bool a0, bool a1, int32_t a2, jobject a3);
     bool IsContentDocumentDisplayed();
@@ -332,53 +332,53 @@ protected:
     static jmethodID jSetFirstPaintViewport;
     static jmethodID jSetPageRect;
     static jmethodID jSyncFrameMetrics;
     static jmethodID jSyncViewportInfo;
 };
 
 class ImmutableViewportMetrics : public AutoGlobalWrappedJavaObject {
 public:
-    static void InitStubs(JNIEnv *env);
+    static void InitStubs(JNIEnv *jEnv);
     static ImmutableViewportMetrics* Wrap(jobject obj);
     ImmutableViewportMetrics(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
     ImmutableViewportMetrics(jfloat a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4, jfloat a5, jfloat a6, jfloat a7, jfloat a8, jfloat a9, jfloat a10, jfloat a11, jfloat a12);
     ImmutableViewportMetrics() : AutoGlobalWrappedJavaObject() {};
 protected:
     static jclass mImmutableViewportMetricsClass;
     static jmethodID jImmutableViewportMetrics;
 };
 
 class LayerView : public AutoGlobalWrappedJavaObject {
 public:
-    static void InitStubs(JNIEnv *env);
+    static void InitStubs(JNIEnv *jEnv);
     static LayerView* Wrap(jobject obj);
     LayerView(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
     static jobject RegisterCompositorWrapper();
     LayerView() : AutoGlobalWrappedJavaObject() {};
 protected:
     static jclass mLayerViewClass;
     static jmethodID jRegisterCompositorWrapper;
 };
 
 class NativePanZoomController : public AutoGlobalWrappedJavaObject {
 public:
-    static void InitStubs(JNIEnv *env);
+    static void InitStubs(JNIEnv *jEnv);
     static NativePanZoomController* Wrap(jobject obj);
     NativePanZoomController(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
     void RequestContentRepaintWrapper(jfloat a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4);
     NativePanZoomController() : AutoGlobalWrappedJavaObject() {};
 protected:
     static jclass mNativePanZoomControllerClass;
     static jmethodID jRequestContentRepaintWrapper;
 };
 
 class ProgressiveUpdateData : public AutoGlobalWrappedJavaObject {
 public:
-    static void InitStubs(JNIEnv *env);
+    static void InitStubs(JNIEnv *jEnv);
     static ProgressiveUpdateData* Wrap(jobject obj);
     ProgressiveUpdateData(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
     ProgressiveUpdateData();
     void setViewport(jobject a0);
     bool getabort();
     void setabort(bool a0);
     jfloat getscale();
     void setscale(jfloat a0);
@@ -393,17 +393,17 @@ protected:
     static jfieldID jabort;
     static jfieldID jscale;
     static jfieldID jx;
     static jfieldID jy;
 };
 
 class ViewTransform : public AutoGlobalWrappedJavaObject {
 public:
-    static void InitStubs(JNIEnv *env);
+    static void InitStubs(JNIEnv *jEnv);
     static ViewTransform* Wrap(jobject obj);
     ViewTransform(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
     ViewTransform(jfloat a0, jfloat a1, jfloat a2);
     jfloat getfixedLayerMarginBottom();
     void setfixedLayerMarginBottom(jfloat a0);
     jfloat getfixedLayerMarginLeft();
     void setfixedLayerMarginLeft(jfloat a0);
     jfloat getfixedLayerMarginRight();
@@ -432,29 +432,29 @@ protected:
     static jfieldID joffsetY;
     static jfieldID jscale;
     static jfieldID jx;
     static jfieldID jy;
 };
 
 class NativeZip : public AutoGlobalWrappedJavaObject {
 public:
-    static void InitStubs(JNIEnv *env);
+    static void InitStubs(JNIEnv *jEnv);
     static NativeZip* Wrap(jobject obj);
     NativeZip(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
     jobject CreateInputStream(jobject a0, int32_t a1);
     NativeZip() : AutoGlobalWrappedJavaObject() {};
 protected:
     static jclass mNativeZipClass;
     static jmethodID jCreateInputStream;
 };
 
 class MatrixBlobCursor : public AutoGlobalWrappedJavaObject {
 public:
-    static void InitStubs(JNIEnv *env);
+    static void InitStubs(JNIEnv *jEnv);
     static MatrixBlobCursor* Wrap(jobject obj);
     MatrixBlobCursor(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
     MatrixBlobCursor(jobjectArray a0);
     MatrixBlobCursor(jobjectArray a0, int32_t a1);
     void AddRow(jobject a0);
     void AddRow(jobject a0, int32_t a1);
     void AddRow(jobjectArray a0);
     MatrixBlobCursor() : AutoGlobalWrappedJavaObject() {};
@@ -464,32 +464,32 @@ protected:
     static jmethodID jMatrixBlobCursor0;
     static jmethodID jAddRow;
     static jmethodID jAddRow1;
     static jmethodID jAddRow2;
 };
 
 class SQLiteBridgeException : public AutoGlobalWrappedJavaObject {
 public:
-    static void InitStubs(JNIEnv *env);
+    static void InitStubs(JNIEnv *jEnv);
     static SQLiteBridgeException* Wrap(jobject obj);
     SQLiteBridgeException(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
     SQLiteBridgeException();
     SQLiteBridgeException(const nsAString& a0);
     static int64_t getserialVersionUID();
 protected:
     static jclass mSQLiteBridgeExceptionClass;
     static jmethodID jSQLiteBridgeException;
     static jmethodID jSQLiteBridgeException0;
     static jfieldID jserialVersionUID;
 };
 
 class Clipboard : public AutoGlobalWrappedJavaObject {
 public:
-    static void InitStubs(JNIEnv *env);
+    static void InitStubs(JNIEnv *jEnv);
     static Clipboard* Wrap(jobject obj);
     Clipboard(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
     static void ClearText();
     static jstring GetClipboardTextWrapper();
     static bool HasText();
     static void SetClipboardText(const nsAString& a0);
     Clipboard() : AutoGlobalWrappedJavaObject() {};
 protected:
new file mode 100644
--- /dev/null
+++ b/widget/android/GeneratedSDKWrappers.cpp
@@ -0,0 +1,1877 @@
+// GENERATED CODE
+// Generated by the Java program at /build/jarClassProcessors at compile time from
+// a given set of jars and a set of requested methods. To update, change the annotations
+// on the corresponding Java methods and rerun the build. Manually updating this file
+// will cause your build to fail.
+
+#include "GeneratedSDKWrappers.h"
+#include "AndroidBridgeUtilities.h"
+#include "nsXPCOMStrings.h"
+#include "AndroidBridge.h"
+#include "nsDebug.h"
+
+namespace mozilla {
+namespace widget {
+namespace android {
+jclass MediaCodec::mMediaCodecClass = 0;
+jmethodID MediaCodec::jConfigure = 0;
+jmethodID MediaCodec::jCreateByCodecName = 0;
+jmethodID MediaCodec::jCreateDecoderByType = 0;
+jmethodID MediaCodec::jCreateEncoderByType = 0;
+jmethodID MediaCodec::jDequeueInputBuffer = 0;
+jmethodID MediaCodec::jDequeueOutputBuffer = 0;
+jmethodID MediaCodec::jFinalize = 0;
+jmethodID MediaCodec::jFlush = 0;
+jmethodID MediaCodec::jGetInputBuffers = 0;
+jmethodID MediaCodec::jGetOutputBuffers = 0;
+jmethodID MediaCodec::jGetOutputFormat = 0;
+jmethodID MediaCodec::jQueueInputBuffer = 0;
+jmethodID MediaCodec::jQueueSecureInputBuffer = 0;
+jmethodID MediaCodec::jRelease = 0;
+jmethodID MediaCodec::jReleaseOutputBuffer = 0;
+jmethodID MediaCodec::jSetVideoScalingMode = 0;
+jmethodID MediaCodec::jStart = 0;
+jmethodID MediaCodec::jStop = 0;
+jfieldID MediaCodec::jBUFFER_FLAG_CODEC_CONFIG = 0;
+jfieldID MediaCodec::jBUFFER_FLAG_END_OF_STREAM = 0;
+jfieldID MediaCodec::jBUFFER_FLAG_SYNC_FRAME = 0;
+jfieldID MediaCodec::jCONFIGURE_FLAG_ENCODE = 0;
+jfieldID MediaCodec::jCRYPTO_MODE_AES_CTR = 0;
+jfieldID MediaCodec::jCRYPTO_MODE_UNENCRYPTED = 0;
+jfieldID MediaCodec::jINFO_OUTPUT_BUFFERS_CHANGED = 0;
+jfieldID MediaCodec::jINFO_OUTPUT_FORMAT_CHANGED = 0;
+jfieldID MediaCodec::jINFO_TRY_AGAIN_LATER = 0;
+jfieldID MediaCodec::jVIDEO_SCALING_MODE_SCALE_TO_FIT = 0;
+jfieldID MediaCodec::jVIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 0;
+void MediaCodec::InitStubs(JNIEnv *jEnv) {
+    initInit();
+
+    mMediaCodecClass = getClassGlobalRef("android/media/MediaCodec");
+    jConfigure = getMethod("configure", "(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/MediaCrypto;I)V");
+    jCreateByCodecName = getStaticMethod("createByCodecName", "(Ljava/lang/String;)Landroid/media/MediaCodec;");
+    jCreateDecoderByType = getStaticMethod("createDecoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;");
+    jCreateEncoderByType = getStaticMethod("createEncoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;");
+    jDequeueInputBuffer = getMethod("dequeueInputBuffer", "(J)I");
+    jDequeueOutputBuffer = getMethod("dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I");
+    jFinalize = getMethod("finalize", "()V");
+    jFlush = getMethod("flush", "()V");
+    jGetInputBuffers = getMethod("getInputBuffers", "()[Ljava/nio/ByteBuffer;");
+    jGetOutputBuffers = getMethod("getOutputBuffers", "()[Ljava/nio/ByteBuffer;");
+    jGetOutputFormat = getMethod("getOutputFormat", "()Landroid/media/MediaFormat;");
+    jQueueInputBuffer = getMethod("queueInputBuffer", "(IIIJI)V");
+    jQueueSecureInputBuffer = getMethod("queueSecureInputBuffer", "(IILandroid/media/MediaCodec$CryptoInfo;JI)V");
+    jRelease = getMethod("release", "()V");
+    jReleaseOutputBuffer = getMethod("releaseOutputBuffer", "(IZ)V");
+    jSetVideoScalingMode = getMethod("setVideoScalingMode", "(I)V");
+    jStart = getMethod("start", "()V");
+    jStop = getMethod("stop", "()V");
+    jBUFFER_FLAG_CODEC_CONFIG = getStaticField("BUFFER_FLAG_CODEC_CONFIG", "I");
+    jBUFFER_FLAG_END_OF_STREAM = getStaticField("BUFFER_FLAG_END_OF_STREAM", "I");
+    jBUFFER_FLAG_SYNC_FRAME = getStaticField("BUFFER_FLAG_SYNC_FRAME", "I");
+    jCONFIGURE_FLAG_ENCODE = getStaticField("CONFIGURE_FLAG_ENCODE", "I");
+    jCRYPTO_MODE_AES_CTR = getStaticField("CRYPTO_MODE_AES_CTR", "I");
+    jCRYPTO_MODE_UNENCRYPTED = getStaticField("CRYPTO_MODE_UNENCRYPTED", "I");
+    jINFO_OUTPUT_BUFFERS_CHANGED = getStaticField("INFO_OUTPUT_BUFFERS_CHANGED", "I");
+    jINFO_OUTPUT_FORMAT_CHANGED = getStaticField("INFO_OUTPUT_FORMAT_CHANGED", "I");
+    jINFO_TRY_AGAIN_LATER = getStaticField("INFO_TRY_AGAIN_LATER", "I");
+    jVIDEO_SCALING_MODE_SCALE_TO_FIT = getStaticField("VIDEO_SCALING_MODE_SCALE_TO_FIT", "I");
+    jVIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = getStaticField("VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING", "I");
+}
+
+MediaCodec* MediaCodec::Wrap(jobject obj) {
+    JNIEnv *env = GetJNIForThread();
+    MediaCodec* ret = new MediaCodec(obj, env);
+    env->DeleteLocalRef(obj);
+    return ret;
+}
+
+bool MediaCodec::Configure(jobject a0, jobject a1, jobject a2, int32_t a3) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(3) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jvalue args[4];
+    args[0].l = a0;
+    args[1].l = a1;
+    args[2].l = a2;
+    args[3].i = a3;
+
+    env->CallVoidMethodA(wrapped_obj, jConfigure, args);
+    if (env->ExceptionCheck()) {
+        env->ExceptionClear();
+        env->PopLocalFrame(nullptr);
+        return false;
+    }
+    env->PopLocalFrame(nullptr);
+    return true;
+}
+
+jobject MediaCodec::CreateByCodecName(const nsAString& a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(2) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jstring j0 = AndroidBridge::NewJavaString(env, a0);
+
+    jobject temp = env->CallStaticObjectMethod(mMediaCodecClass, jCreateByCodecName, j0);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject MediaCodec::CreateDecoderByType(const nsAString& a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(2) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jstring j0 = AndroidBridge::NewJavaString(env, a0);
+
+    jobject temp = env->CallStaticObjectMethod(mMediaCodecClass, jCreateDecoderByType, j0);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject MediaCodec::CreateEncoderByType(const nsAString& a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(2) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jstring j0 = AndroidBridge::NewJavaString(env, a0);
+
+    jobject temp = env->CallStaticObjectMethod(mMediaCodecClass, jCreateEncoderByType, j0);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+int32_t MediaCodec::DequeueInputBuffer(int64_t a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    int32_t temp = env->CallIntMethod(wrapped_obj, jDequeueInputBuffer, a0);
+    if (env->ExceptionCheck()) {
+        env->ExceptionClear();
+        env->PopLocalFrame(nullptr);
+        return MEDIACODEC_EXCEPTION_INDEX;
+    }
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+int32_t MediaCodec::DequeueOutputBuffer(jobject a0, int64_t a1) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    int32_t temp = env->CallIntMethod(wrapped_obj, jDequeueOutputBuffer, a0, a1);
+    if (env->ExceptionCheck()) {
+        env->ExceptionClear();
+        env->PopLocalFrame(nullptr);
+        return MEDIACODEC_EXCEPTION_INDEX;
+    }
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+void MediaCodec::Finalize() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    env->CallVoidMethod(wrapped_obj, jFinalize);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+}
+
+void MediaCodec::Flush() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    env->CallVoidMethod(wrapped_obj, jFlush);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+}
+
+jobjectArray MediaCodec::GetInputBuffers() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jGetInputBuffers);
+    AndroidBridge::HandleUncaughtException(env);
+    jobjectArray ret = static_cast<jobjectArray>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobjectArray MediaCodec::GetOutputBuffers() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jGetOutputBuffers);
+    AndroidBridge::HandleUncaughtException(env);
+    jobjectArray ret = static_cast<jobjectArray>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject MediaCodec::GetOutputFormat() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jGetOutputFormat);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+void MediaCodec::QueueInputBuffer(int32_t a0, int32_t a1, int32_t a2, int64_t a3, int32_t a4) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(5) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jvalue args[5];
+    args[0].i = a0;
+    args[1].i = a1;
+    args[2].i = a2;
+    args[3].j = a3;
+    args[4].i = a4;
+
+    env->CallVoidMethodA(wrapped_obj, jQueueInputBuffer, args);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+}
+
+void MediaCodec::QueueSecureInputBuffer(int32_t a0, int32_t a1, jobject a2, int64_t a3, int32_t a4) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jvalue args[5];
+    args[0].i = a0;
+    args[1].i = a1;
+    args[2].l = a2;
+    args[3].j = a3;
+    args[4].i = a4;
+
+    env->CallVoidMethodA(wrapped_obj, jQueueSecureInputBuffer, args);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+}
+
+void MediaCodec::Release() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    env->CallVoidMethod(wrapped_obj, jRelease);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+}
+
+void MediaCodec::ReleaseOutputBuffer(int32_t a0, bool a1) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    env->CallVoidMethod(wrapped_obj, jReleaseOutputBuffer, a0, a1);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+}
+
+void MediaCodec::SetVideoScalingMode(int32_t a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    env->CallVoidMethod(wrapped_obj, jSetVideoScalingMode, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+}
+
+bool MediaCodec::Start() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    env->CallVoidMethod(wrapped_obj, jStart);
+    if (env->ExceptionCheck()) {
+        env->ExceptionClear();
+        env->PopLocalFrame(nullptr);
+        return false;
+    }
+    env->PopLocalFrame(nullptr);
+    return true;
+}
+
+void MediaCodec::Stop() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    env->CallVoidMethod(wrapped_obj, jStop);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+}
+
+int32_t MediaCodec::getBUFFER_FLAG_CODEC_CONFIG() {
+    JNIEnv *env = GetJNIForThread();
+    return env->GetStaticIntField(mMediaCodecClass, jBUFFER_FLAG_CODEC_CONFIG);
+}
+
+int32_t MediaCodec::getBUFFER_FLAG_END_OF_STREAM() {
+    JNIEnv *env = GetJNIForThread();
+    return env->GetStaticIntField(mMediaCodecClass, jBUFFER_FLAG_END_OF_STREAM);
+}
+
+int32_t MediaCodec::getBUFFER_FLAG_SYNC_FRAME() {
+    JNIEnv *env = GetJNIForThread();
+    return env->GetStaticIntField(mMediaCodecClass, jBUFFER_FLAG_SYNC_FRAME);
+}
+
+int32_t MediaCodec::getCONFIGURE_FLAG_ENCODE() {
+    JNIEnv *env = GetJNIForThread();
+    return env->GetStaticIntField(mMediaCodecClass, jCONFIGURE_FLAG_ENCODE);
+}
+
+int32_t MediaCodec::getCRYPTO_MODE_AES_CTR() {
+    JNIEnv *env = GetJNIForThread();
+    return env->GetStaticIntField(mMediaCodecClass, jCRYPTO_MODE_AES_CTR);
+}
+
+int32_t MediaCodec::getCRYPTO_MODE_UNENCRYPTED() {
+    JNIEnv *env = GetJNIForThread();
+    return env->GetStaticIntField(mMediaCodecClass, jCRYPTO_MODE_UNENCRYPTED);
+}
+
+int32_t MediaCodec::getINFO_OUTPUT_BUFFERS_CHANGED() {
+    JNIEnv *env = GetJNIForThread();
+    return env->GetStaticIntField(mMediaCodecClass, jINFO_OUTPUT_BUFFERS_CHANGED);
+}
+
+int32_t MediaCodec::getINFO_OUTPUT_FORMAT_CHANGED() {
+    JNIEnv *env = GetJNIForThread();
+    return env->GetStaticIntField(mMediaCodecClass, jINFO_OUTPUT_FORMAT_CHANGED);
+}
+
+int32_t MediaCodec::getINFO_TRY_AGAIN_LATER() {
+    JNIEnv *env = GetJNIForThread();
+    return env->GetStaticIntField(mMediaCodecClass, jINFO_TRY_AGAIN_LATER);
+}
+
+int32_t MediaCodec::getVIDEO_SCALING_MODE_SCALE_TO_FIT() {
+    JNIEnv *env = GetJNIForThread();
+    return env->GetStaticIntField(mMediaCodecClass, jVIDEO_SCALING_MODE_SCALE_TO_FIT);
+}
+
+int32_t MediaCodec::getVIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING() {
+    JNIEnv *env = GetJNIForThread();
+    return env->GetStaticIntField(mMediaCodecClass, jVIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
+}
+jclass MediaFormat::mMediaFormatClass = 0;
+jmethodID MediaFormat::jMediaFormat = 0;
+jmethodID MediaFormat::jContainsKey = 0;
+jmethodID MediaFormat::jCreateAudioFormat = 0;
+jmethodID MediaFormat::jCreateVideoFormat = 0;
+jmethodID MediaFormat::jGetByteBuffer = 0;
+jmethodID MediaFormat::jGetFloat = 0;
+jmethodID MediaFormat::jGetInteger = 0;
+jmethodID MediaFormat::jGetLong = 0;
+jmethodID MediaFormat::jGetString = 0;
+jmethodID MediaFormat::jSetByteBuffer = 0;
+jmethodID MediaFormat::jSetFloat = 0;
+jmethodID MediaFormat::jSetInteger = 0;
+jmethodID MediaFormat::jSetLong = 0;
+jmethodID MediaFormat::jSetString = 0;
+jmethodID MediaFormat::jToString = 0;
+jfieldID MediaFormat::jKEY_AAC_PROFILE = 0;
+jfieldID MediaFormat::jKEY_BIT_RATE = 0;
+jfieldID MediaFormat::jKEY_CHANNEL_COUNT = 0;
+jfieldID MediaFormat::jKEY_CHANNEL_MASK = 0;
+jfieldID MediaFormat::jKEY_COLOR_FORMAT = 0;
+jfieldID MediaFormat::jKEY_DURATION = 0;
+jfieldID MediaFormat::jKEY_FLAC_COMPRESSION_LEVEL = 0;
+jfieldID MediaFormat::jKEY_FRAME_RATE = 0;
+jfieldID MediaFormat::jKEY_HEIGHT = 0;
+jfieldID MediaFormat::jKEY_IS_ADTS = 0;
+jfieldID MediaFormat::jKEY_I_FRAME_INTERVAL = 0;
+jfieldID MediaFormat::jKEY_MAX_INPUT_SIZE = 0;
+jfieldID MediaFormat::jKEY_MIME = 0;
+jfieldID MediaFormat::jKEY_SAMPLE_RATE = 0;
+jfieldID MediaFormat::jKEY_WIDTH = 0;
+void MediaFormat::InitStubs(JNIEnv *jEnv) {
+    initInit();
+
+    mMediaFormatClass = getClassGlobalRef("android/media/MediaFormat");
+    jMediaFormat = getMethod("<init>", "()V");
+    jContainsKey = getMethod("containsKey", "(Ljava/lang/String;)Z");
+    jCreateAudioFormat = getStaticMethod("createAudioFormat", "(Ljava/lang/String;II)Landroid/media/MediaFormat;");
+    jCreateVideoFormat = getStaticMethod("createVideoFormat", "(Ljava/lang/String;II)Landroid/media/MediaFormat;");
+    jGetByteBuffer = getMethod("getByteBuffer", "(Ljava/lang/String;)Ljava/nio/ByteBuffer;");
+    jGetFloat = getMethod("getFloat", "(Ljava/lang/String;)F");
+    jGetInteger = getMethod("getInteger", "(Ljava/lang/String;)I");
+    jGetLong = getMethod("getLong", "(Ljava/lang/String;)J");
+    jGetString = getMethod("getString", "(Ljava/lang/String;)Ljava/lang/String;");
+    jSetByteBuffer = getMethod("setByteBuffer", "(Ljava/lang/String;Ljava/nio/ByteBuffer;)V");
+    jSetFloat = getMethod("setFloat", "(Ljava/lang/String;F)V");
+    jSetInteger = getMethod("setInteger", "(Ljava/lang/String;I)V");
+    jSetLong = getMethod("setLong", "(Ljava/lang/String;J)V");
+    jSetString = getMethod("setString", "(Ljava/lang/String;Ljava/lang/String;)V");
+    jToString = getMethod("toString", "()Ljava/lang/String;");
+    jKEY_AAC_PROFILE = getStaticField("KEY_AAC_PROFILE", "Ljava/lang/String;");
+    jKEY_BIT_RATE = getStaticField("KEY_BIT_RATE", "Ljava/lang/String;");
+    jKEY_CHANNEL_COUNT = getStaticField("KEY_CHANNEL_COUNT", "Ljava/lang/String;");
+    jKEY_CHANNEL_MASK = getStaticField("KEY_CHANNEL_MASK", "Ljava/lang/String;");
+    jKEY_COLOR_FORMAT = getStaticField("KEY_COLOR_FORMAT", "Ljava/lang/String;");
+    jKEY_DURATION = getStaticField("KEY_DURATION", "Ljava/lang/String;");
+    jKEY_FLAC_COMPRESSION_LEVEL = getStaticField("KEY_FLAC_COMPRESSION_LEVEL", "Ljava/lang/String;");
+    jKEY_FRAME_RATE = getStaticField("KEY_FRAME_RATE", "Ljava/lang/String;");
+    jKEY_HEIGHT = getStaticField("KEY_HEIGHT", "Ljava/lang/String;");
+    jKEY_IS_ADTS = getStaticField("KEY_IS_ADTS", "Ljava/lang/String;");
+    jKEY_I_FRAME_INTERVAL = getStaticField("KEY_I_FRAME_INTERVAL", "Ljava/lang/String;");
+    jKEY_MAX_INPUT_SIZE = getStaticField("KEY_MAX_INPUT_SIZE", "Ljava/lang/String;");
+    jKEY_MIME = getStaticField("KEY_MIME", "Ljava/lang/String;");
+    jKEY_SAMPLE_RATE = getStaticField("KEY_SAMPLE_RATE", "Ljava/lang/String;");
+    jKEY_WIDTH = getStaticField("KEY_WIDTH", "Ljava/lang/String;");
+}
+
+MediaFormat* MediaFormat::Wrap(jobject obj) {
+    JNIEnv *env = GetJNIForThread();
+    MediaFormat* ret = new MediaFormat(obj, env);
+    env->DeleteLocalRef(obj);
+    return ret;
+}
+
+MediaFormat::MediaFormat() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    Init(env->NewObject(mMediaFormatClass, jMediaFormat), env);
+    env->PopLocalFrame(nullptr);
+}
+
+bool MediaFormat::ContainsKey(const nsAString& a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jstring j0 = AndroidBridge::NewJavaString(env, a0);
+
+    bool temp = env->CallBooleanMethod(wrapped_obj, jContainsKey, j0);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+jobject MediaFormat::CreateAudioFormat(const nsAString& a0, int32_t a1, int32_t a2) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(2) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jvalue args[3];
+    args[0].l = AndroidBridge::NewJavaString(env, a0);
+    args[1].i = a1;
+    args[2].i = a2;
+
+    jobject temp = env->CallStaticObjectMethodA(mMediaFormatClass, jCreateAudioFormat, args);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject MediaFormat::CreateVideoFormat(const nsAString& a0, int32_t a1, int32_t a2) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(2) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jvalue args[3];
+    args[0].l = AndroidBridge::NewJavaString(env, a0);
+    args[1].i = a1;
+    args[2].i = a2;
+
+    jobject temp = env->CallStaticObjectMethodA(mMediaFormatClass, jCreateVideoFormat, args);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject MediaFormat::GetByteBuffer(const nsAString& a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(2) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jstring j0 = AndroidBridge::NewJavaString(env, a0);
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jGetByteBuffer, j0);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jfloat MediaFormat::GetFloat(const nsAString& a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jstring j0 = AndroidBridge::NewJavaString(env, a0);
+
+    jfloat temp = env->CallFloatMethod(wrapped_obj, jGetFloat, j0);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+int32_t MediaFormat::GetInteger(const nsAString& a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jstring j0 = AndroidBridge::NewJavaString(env, a0);
+
+    int32_t temp = env->CallIntMethod(wrapped_obj, jGetInteger, j0);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+int64_t MediaFormat::GetLong(const nsAString& a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jstring j0 = AndroidBridge::NewJavaString(env, a0);
+
+    int64_t temp = env->CallLongMethod(wrapped_obj, jGetLong, j0);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+jstring MediaFormat::GetString(const nsAString& a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(2) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jstring j0 = AndroidBridge::NewJavaString(env, a0);
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jGetString, j0);
+    AndroidBridge::HandleUncaughtException(env);
+    jstring ret = static_cast<jstring>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+void MediaFormat::SetByteBuffer(const nsAString& a0, jobject a1) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(2) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jstring j0 = AndroidBridge::NewJavaString(env, a0);
+
+    env->CallVoidMethod(wrapped_obj, jSetByteBuffer, j0, a1);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+}
+
+void MediaFormat::SetFloat(const nsAString& a0, jfloat a1) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jstring j0 = AndroidBridge::NewJavaString(env, a0);
+
+    env->CallVoidMethod(wrapped_obj, jSetFloat, j0, a1);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+}
+
+void MediaFormat::SetInteger(const nsAString& a0, int32_t a1) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jstring j0 = AndroidBridge::NewJavaString(env, a0);
+
+    env->CallVoidMethod(wrapped_obj, jSetInteger, j0, a1);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+}
+
+void MediaFormat::SetLong(const nsAString& a0, int64_t a1) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jstring j0 = AndroidBridge::NewJavaString(env, a0);
+
+    env->CallVoidMethod(wrapped_obj, jSetLong, j0, a1);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+}
+
+void MediaFormat::SetString(const nsAString& a0, const nsAString& a1) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(2) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jstring j0 = AndroidBridge::NewJavaString(env, a0);
+    jstring j1 = AndroidBridge::NewJavaString(env, a1);
+
+    env->CallVoidMethod(wrapped_obj, jSetString, j0, j1);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+}
+
+jstring MediaFormat::ToString() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jToString);
+    AndroidBridge::HandleUncaughtException(env);
+    jstring ret = static_cast<jstring>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jstring MediaFormat::getKEY_AAC_PROFILE() {
+    JNIEnv *env = GetJNIForThread();
+    return static_cast<jstring>(env->GetStaticObjectField(mMediaFormatClass, jKEY_AAC_PROFILE));
+}
+
+jstring MediaFormat::getKEY_BIT_RATE() {
+    JNIEnv *env = GetJNIForThread();
+    return static_cast<jstring>(env->GetStaticObjectField(mMediaFormatClass, jKEY_BIT_RATE));
+}
+
+jstring MediaFormat::getKEY_CHANNEL_COUNT() {
+    JNIEnv *env = GetJNIForThread();
+    return static_cast<jstring>(env->GetStaticObjectField(mMediaFormatClass, jKEY_CHANNEL_COUNT));
+}
+
+jstring MediaFormat::getKEY_CHANNEL_MASK() {
+    JNIEnv *env = GetJNIForThread();
+    return static_cast<jstring>(env->GetStaticObjectField(mMediaFormatClass, jKEY_CHANNEL_MASK));
+}
+
+jstring MediaFormat::getKEY_COLOR_FORMAT() {
+    JNIEnv *env = GetJNIForThread();
+    return static_cast<jstring>(env->GetStaticObjectField(mMediaFormatClass, jKEY_COLOR_FORMAT));
+}
+
+jstring MediaFormat::getKEY_DURATION() {
+    JNIEnv *env = GetJNIForThread();
+    return static_cast<jstring>(env->GetStaticObjectField(mMediaFormatClass, jKEY_DURATION));
+}
+
+jstring MediaFormat::getKEY_FLAC_COMPRESSION_LEVEL() {
+    JNIEnv *env = GetJNIForThread();
+    return static_cast<jstring>(env->GetStaticObjectField(mMediaFormatClass, jKEY_FLAC_COMPRESSION_LEVEL));
+}
+
+jstring MediaFormat::getKEY_FRAME_RATE() {
+    JNIEnv *env = GetJNIForThread();
+    return static_cast<jstring>(env->GetStaticObjectField(mMediaFormatClass, jKEY_FRAME_RATE));
+}
+
+jstring MediaFormat::getKEY_HEIGHT() {
+    JNIEnv *env = GetJNIForThread();
+    return static_cast<jstring>(env->GetStaticObjectField(mMediaFormatClass, jKEY_HEIGHT));
+}
+
+jstring MediaFormat::getKEY_IS_ADTS() {
+    JNIEnv *env = GetJNIForThread();
+    return static_cast<jstring>(env->GetStaticObjectField(mMediaFormatClass, jKEY_IS_ADTS));
+}
+
+jstring MediaFormat::getKEY_I_FRAME_INTERVAL() {
+    JNIEnv *env = GetJNIForThread();
+    return static_cast<jstring>(env->GetStaticObjectField(mMediaFormatClass, jKEY_I_FRAME_INTERVAL));
+}
+
+jstring MediaFormat::getKEY_MAX_INPUT_SIZE() {
+    JNIEnv *env = GetJNIForThread();
+    return static_cast<jstring>(env->GetStaticObjectField(mMediaFormatClass, jKEY_MAX_INPUT_SIZE));
+}
+
+jstring MediaFormat::getKEY_MIME() {
+    JNIEnv *env = GetJNIForThread();
+    return static_cast<jstring>(env->GetStaticObjectField(mMediaFormatClass, jKEY_MIME));
+}
+
+jstring MediaFormat::getKEY_SAMPLE_RATE() {
+    JNIEnv *env = GetJNIForThread();
+    return static_cast<jstring>(env->GetStaticObjectField(mMediaFormatClass, jKEY_SAMPLE_RATE));
+}
+
+jstring MediaFormat::getKEY_WIDTH() {
+    JNIEnv *env = GetJNIForThread();
+    return static_cast<jstring>(env->GetStaticObjectField(mMediaFormatClass, jKEY_WIDTH));
+}
+jclass ByteBuffer::mByteBufferClass = 0;
+jmethodID ByteBuffer::j_get = 0;
+jmethodID ByteBuffer::j_put = 0;
+jmethodID ByteBuffer::jAllocate = 0;
+jmethodID ByteBuffer::jAllocateDirect = 0;
+jmethodID ByteBuffer::jArray = 0;
+jmethodID ByteBuffer::jArray1 = 0;
+jmethodID ByteBuffer::jArrayOffset = 0;
+jmethodID ByteBuffer::jAsCharBuffer = 0;
+jmethodID ByteBuffer::jAsDoubleBuffer = 0;
+jmethodID ByteBuffer::jAsFloatBuffer = 0;
+jmethodID ByteBuffer::jAsIntBuffer = 0;
+jmethodID ByteBuffer::jAsLongBuffer = 0;
+jmethodID ByteBuffer::jAsReadOnlyBuffer = 0;
+jmethodID ByteBuffer::jAsShortBuffer = 0;
+jmethodID ByteBuffer::jCompact = 0;
+jmethodID ByteBuffer::jCompareTo = 0;
+jmethodID ByteBuffer::jCompareTo1 = 0;
+jmethodID ByteBuffer::jDuplicate = 0;
+jmethodID ByteBuffer::jEquals = 0;
+jmethodID ByteBuffer::jGet = 0;
+jmethodID ByteBuffer::jGet1 = 0;
+jmethodID ByteBuffer::jGet10 = 0;
+jmethodID ByteBuffer::jGet11 = 0;
+jmethodID ByteBuffer::jGetChar = 0;
+jmethodID ByteBuffer::jGetChar1 = 0;
+jmethodID ByteBuffer::jGetDouble = 0;
+jmethodID ByteBuffer::jGetDouble1 = 0;
+jmethodID ByteBuffer::jGetFloat = 0;
+jmethodID ByteBuffer::jGetFloat1 = 0;
+jmethodID ByteBuffer::jGetInt = 0;
+jmethodID ByteBuffer::jGetInt1 = 0;
+jmethodID ByteBuffer::jGetLong = 0;
+jmethodID ByteBuffer::jGetLong1 = 0;
+jmethodID ByteBuffer::jGetShort = 0;
+jmethodID ByteBuffer::jGetShort1 = 0;
+jmethodID ByteBuffer::jHasArray = 0;
+jmethodID ByteBuffer::jHashCode = 0;
+jmethodID ByteBuffer::jIsDirect = 0;
+jmethodID ByteBuffer::jOrder = 0;
+jmethodID ByteBuffer::jOrder1 = 0;
+jmethodID ByteBuffer::jPut = 0;
+jmethodID ByteBuffer::jPut1 = 0;
+jmethodID ByteBuffer::jPut12 = 0;
+jmethodID ByteBuffer::jPut13 = 0;
+jmethodID ByteBuffer::jPut14 = 0;
+jmethodID ByteBuffer::jPutChar = 0;
+jmethodID ByteBuffer::jPutChar1 = 0;
+jmethodID ByteBuffer::jPutDouble = 0;
+jmethodID ByteBuffer::jPutDouble1 = 0;
+jmethodID ByteBuffer::jPutFloat = 0;
+jmethodID ByteBuffer::jPutFloat1 = 0;
+jmethodID ByteBuffer::jPutInt = 0;
+jmethodID ByteBuffer::jPutInt1 = 0;
+jmethodID ByteBuffer::jPutLong = 0;
+jmethodID ByteBuffer::jPutLong1 = 0;
+jmethodID ByteBuffer::jPutShort = 0;
+jmethodID ByteBuffer::jPutShort1 = 0;
+jmethodID ByteBuffer::jSlice = 0;
+jmethodID ByteBuffer::jToString = 0;
+jmethodID ByteBuffer::jWrap = 0;
+jmethodID ByteBuffer::jWrap1 = 0;
+jfieldID ByteBuffer::jBigEndian = 0;
+jfieldID ByteBuffer::jHb = 0;
+jfieldID ByteBuffer::jIsReadOnly = 0;
+jfieldID ByteBuffer::jNativeByteOrder = 0;
+jfieldID ByteBuffer::jOffset = 0;
+void ByteBuffer::InitStubs(JNIEnv *jEnv) {
+    initInit();
+
+    mByteBufferClass = getClassGlobalRef("java/nio/ByteBuffer");
+    //j_get = getMethod("_get", "(I)B");
+    //j_put = getMethod("_put", "(IB)V");
+    jAllocate = getStaticMethod("allocate", "(I)Ljava/nio/ByteBuffer;");
+    jAllocateDirect = getStaticMethod("allocateDirect", "(I)Ljava/nio/ByteBuffer;");
+    jArray = getMethod("array", "()Ljava/lang/Object;");
+    jArray1 = getMethod("array", "()[B");
+    jArrayOffset = getMethod("arrayOffset", "()I");
+    jAsCharBuffer = getMethod("asCharBuffer", "()Ljava/nio/CharBuffer;");
+    jAsDoubleBuffer = getMethod("asDoubleBuffer", "()Ljava/nio/DoubleBuffer;");
+    jAsFloatBuffer = getMethod("asFloatBuffer", "()Ljava/nio/FloatBuffer;");
+    jAsIntBuffer = getMethod("asIntBuffer", "()Ljava/nio/IntBuffer;");
+    jAsLongBuffer = getMethod("asLongBuffer", "()Ljava/nio/LongBuffer;");
+    jAsReadOnlyBuffer = getMethod("asReadOnlyBuffer", "()Ljava/nio/ByteBuffer;");
+    jAsShortBuffer = getMethod("asShortBuffer", "()Ljava/nio/ShortBuffer;");
+    jCompact = getMethod("compact", "()Ljava/nio/ByteBuffer;");
+    jCompareTo = getMethod("compareTo", "(Ljava/lang/Object;)I");
+    jCompareTo1 = getMethod("compareTo", "(Ljava/nio/ByteBuffer;)I");
+    jDuplicate = getMethod("duplicate", "()Ljava/nio/ByteBuffer;");
+    jEquals = getMethod("equals", "(Ljava/lang/Object;)Z");
+    jGet = getMethod("get", "()B");
+    jGet1 = getMethod("get", "(I)B");
+    jGet10 = getMethod("get", "([B)Ljava/nio/ByteBuffer;");
+    jGet11 = getMethod("get", "([BII)Ljava/nio/ByteBuffer;");
+    jGetChar = getMethod("getChar", "()C");
+    jGetChar1 = getMethod("getChar", "(I)C");
+    jGetDouble = getMethod("getDouble", "()D");
+    jGetDouble1 = getMethod("getDouble", "(I)D");
+    jGetFloat = getMethod("getFloat", "()F");
+    jGetFloat1 = getMethod("getFloat", "(I)F");
+    jGetInt = getMethod("getInt", "()I");
+    jGetInt1 = getMethod("getInt", "(I)I");
+    jGetLong = getMethod("getLong", "()J");
+    jGetLong1 = getMethod("getLong", "(I)J");
+    jGetShort = getMethod("getShort", "()S");
+    jGetShort1 = getMethod("getShort", "(I)S");
+    jHasArray = getMethod("hasArray", "()Z");
+    jHashCode = getMethod("hashCode", "()I");
+    jIsDirect = getMethod("isDirect", "()Z");
+    jOrder = getMethod("order", "()Ljava/nio/ByteOrder;");
+    jOrder1 = getMethod("order", "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;");
+    jPut = getMethod("put", "(B)Ljava/nio/ByteBuffer;");
+    jPut1 = getMethod("put", "(IB)Ljava/nio/ByteBuffer;");
+    jPut12 = getMethod("put", "(Ljava/nio/ByteBuffer;)Ljava/nio/ByteBuffer;");
+    jPut13 = getMethod("put", "([B)Ljava/nio/ByteBuffer;");
+    jPut14 = getMethod("put", "([BII)Ljava/nio/ByteBuffer;");
+    jPutChar = getMethod("putChar", "(C)Ljava/nio/ByteBuffer;");
+    jPutChar1 = getMethod("putChar", "(IC)Ljava/nio/ByteBuffer;");
+    jPutDouble = getMethod("putDouble", "(D)Ljava/nio/ByteBuffer;");
+    jPutDouble1 = getMethod("putDouble", "(ID)Ljava/nio/ByteBuffer;");
+    jPutFloat = getMethod("putFloat", "(F)Ljava/nio/ByteBuffer;");
+    jPutFloat1 = getMethod("putFloat", "(IF)Ljava/nio/ByteBuffer;");
+    jPutInt = getMethod("putInt", "(I)Ljava/nio/ByteBuffer;");
+    jPutInt1 = getMethod("putInt", "(II)Ljava/nio/ByteBuffer;");
+    jPutLong = getMethod("putLong", "(IJ)Ljava/nio/ByteBuffer;");
+    jPutLong1 = getMethod("putLong", "(J)Ljava/nio/ByteBuffer;");
+    jPutShort = getMethod("putShort", "(IS)Ljava/nio/ByteBuffer;");
+    jPutShort1 = getMethod("putShort", "(S)Ljava/nio/ByteBuffer;");
+    jSlice = getMethod("slice", "()Ljava/nio/ByteBuffer;");
+    jToString = getMethod("toString", "()Ljava/lang/String;");
+    jWrap = getStaticMethod("wrap", "([B)Ljava/nio/ByteBuffer;");
+    jWrap1 = getStaticMethod("wrap", "([BII)Ljava/nio/ByteBuffer;");
+    /*
+    jBigEndian = getField("bigEndian", "Z");
+    jHb = getField("hb", "[B");
+    jIsReadOnly = getField("isReadOnly", "Z");
+    jNativeByteOrder = getField("nativeByteOrder", "Z");
+    jOffset = getField("offset", "I");
+  */
+}
+
+ByteBuffer* ByteBuffer::Wrap(jobject obj) {
+    JNIEnv *env = GetJNIForThread();
+    ByteBuffer* ret = new ByteBuffer(obj, env);
+    env->DeleteLocalRef(obj);
+    return ret;
+}
+
+int8_t ByteBuffer::_get(int32_t a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    int8_t temp = env->CallByteMethod(wrapped_obj, j_get, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+void ByteBuffer::_put(int32_t a0, int8_t a1) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    env->CallVoidMethod(wrapped_obj, j_put, a0, a1);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+}
+
+jobject ByteBuffer::Allocate(int32_t a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallStaticObjectMethod(mByteBufferClass, jAllocate, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::AllocateDirect(int32_t a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallStaticObjectMethod(mByteBufferClass, jAllocateDirect, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::Array() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jArray);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jbyteArray ByteBuffer::Array1() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jArray1);
+    AndroidBridge::HandleUncaughtException(env);
+    jbyteArray ret = static_cast<jbyteArray>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+int32_t ByteBuffer::ArrayOffset() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    int32_t temp = env->CallIntMethod(wrapped_obj, jArrayOffset);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+jstring ByteBuffer::AsCharBuffer() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jAsCharBuffer);
+    AndroidBridge::HandleUncaughtException(env);
+    jstring ret = static_cast<jstring>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::AsDoubleBuffer() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jAsDoubleBuffer);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::AsFloatBuffer() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jAsFloatBuffer);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::AsIntBuffer() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jAsIntBuffer);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::AsLongBuffer() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jAsLongBuffer);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::AsReadOnlyBuffer() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jAsReadOnlyBuffer);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::AsShortBuffer() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jAsShortBuffer);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::Compact() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jCompact);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+int32_t ByteBuffer::CompareTo(jobject a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    int32_t temp = env->CallIntMethod(wrapped_obj, jCompareTo, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+int32_t ByteBuffer::CompareTo1(jobject a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    int32_t temp = env->CallIntMethod(wrapped_obj, jCompareTo1, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+jobject ByteBuffer::Duplicate() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jDuplicate);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+bool ByteBuffer::Equals(jobject a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    bool temp = env->CallBooleanMethod(wrapped_obj, jEquals, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+int8_t ByteBuffer::Get() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    int8_t temp = env->CallByteMethod(wrapped_obj, jGet);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+int8_t ByteBuffer::Get1(int32_t a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    int8_t temp = env->CallByteMethod(wrapped_obj, jGet1, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+jobject ByteBuffer::Get1(jbyteArray a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(2) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jGet10, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::Get1(jbyteArray a0, int32_t a1, int32_t a2) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(2) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jvalue args[3];
+    args[0].l = a0;
+    args[1].i = a1;
+    args[2].i = a2;
+
+    jobject temp = env->CallObjectMethodA(wrapped_obj, jGet11, args);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+uint16_t ByteBuffer::GetChar() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    uint16_t temp = env->CallCharMethod(wrapped_obj, jGetChar);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+uint16_t ByteBuffer::GetChar1(int32_t a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    uint16_t temp = env->CallCharMethod(wrapped_obj, jGetChar1, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+jdouble ByteBuffer::GetDouble() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jdouble temp = env->CallDoubleMethod(wrapped_obj, jGetDouble);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+jdouble ByteBuffer::GetDouble1(int32_t a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jdouble temp = env->CallDoubleMethod(wrapped_obj, jGetDouble1, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+jfloat ByteBuffer::GetFloat() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jfloat temp = env->CallFloatMethod(wrapped_obj, jGetFloat);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+jfloat ByteBuffer::GetFloat1(int32_t a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jfloat temp = env->CallFloatMethod(wrapped_obj, jGetFloat1, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+int32_t ByteBuffer::GetInt() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    int32_t temp = env->CallIntMethod(wrapped_obj, jGetInt);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+int32_t ByteBuffer::GetInt1(int32_t a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    int32_t temp = env->CallIntMethod(wrapped_obj, jGetInt1, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+int64_t ByteBuffer::GetLong() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    int64_t temp = env->CallLongMethod(wrapped_obj, jGetLong);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+int64_t ByteBuffer::GetLong1(int32_t a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    int64_t temp = env->CallLongMethod(wrapped_obj, jGetLong1, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+int16_t ByteBuffer::GetShort() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    int16_t temp = env->CallShortMethod(wrapped_obj, jGetShort);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+int16_t ByteBuffer::GetShort1(int32_t a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    int16_t temp = env->CallShortMethod(wrapped_obj, jGetShort1, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+bool ByteBuffer::HasArray() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    bool temp = env->CallBooleanMethod(wrapped_obj, jHasArray);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+int32_t ByteBuffer::HashCode() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    int32_t temp = env->CallIntMethod(wrapped_obj, jHashCode);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+bool ByteBuffer::IsDirect() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    bool temp = env->CallBooleanMethod(wrapped_obj, jIsDirect);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+    return temp;
+}
+
+jobject ByteBuffer::Order() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jOrder);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::Order1(jobject a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(2) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jOrder1, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::Put(int8_t a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jPut, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::Put1(int32_t a0, int8_t a1) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jPut1, a0, a1);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::Put1(jobject a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(2) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jPut12, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::Put1(jbyteArray a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(2) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jPut13, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::Put1(jbyteArray a0, int32_t a1, int32_t a2) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(2) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jvalue args[3];
+    args[0].l = a0;
+    args[1].i = a1;
+    args[2].i = a2;
+
+    jobject temp = env->CallObjectMethodA(wrapped_obj, jPut14, args);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::PutChar(uint16_t a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jPutChar, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::PutChar1(int32_t a0, uint16_t a1) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jPutChar1, a0, a1);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::PutDouble(jdouble a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jPutDouble, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::PutDouble1(int32_t a0, jdouble a1) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jPutDouble1, a0, a1);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::PutFloat(jfloat a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jPutFloat, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::PutFloat1(int32_t a0, jfloat a1) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jPutFloat1, a0, a1);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::PutInt(int32_t a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jPutInt, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::PutInt1(int32_t a0, int32_t a1) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jPutInt1, a0, a1);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::PutLong(int32_t a0, int64_t a1) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jPutLong, a0, a1);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::PutLong1(int64_t a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jPutLong1, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::PutShort(int32_t a0, int16_t a1) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jPutShort, a0, a1);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::PutShort1(int16_t a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jPutShort1, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::Slice() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jSlice);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jstring ByteBuffer::ToString() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(1) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallObjectMethod(wrapped_obj, jToString);
+    AndroidBridge::HandleUncaughtException(env);
+    jstring ret = static_cast<jstring>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::Wrap1(jbyteArray a0) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(2) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jobject temp = env->CallStaticObjectMethod(mByteBufferClass, jWrap, a0);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+jobject ByteBuffer::Wrap2(jbyteArray a0, int32_t a1, int32_t a2) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(2) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jvalue args[3];
+    args[0].l = a0;
+    args[1].i = a1;
+    args[2].i = a2;
+
+    jobject temp = env->CallStaticObjectMethodA(mByteBufferClass, jWrap1, args);
+    AndroidBridge::HandleUncaughtException(env);
+    jobject ret = static_cast<jobject>(env->PopLocalFrame(temp));
+    return ret;
+}
+
+bool ByteBuffer::getBigEndian() {
+    JNIEnv *env = GetJNIForThread();
+    return env->GetBooleanField(wrapped_obj, jBigEndian);
+}
+
+void ByteBuffer::setBigEndian(bool a0) {
+    JNIEnv *env = GetJNIForThread();
+    env->SetBooleanField(wrapped_obj, jBigEndian, a0);
+}
+
+jbyteArray ByteBuffer::getHb() {
+    JNIEnv *env = GetJNIForThread();
+    return static_cast<jbyteArray>(env->GetObjectField(wrapped_obj, jHb));
+}
+
+bool ByteBuffer::getIsReadOnly() {
+    JNIEnv *env = GetJNIForThread();
+    return env->GetBooleanField(wrapped_obj, jIsReadOnly);
+}
+
+void ByteBuffer::setIsReadOnly(bool a0) {
+    JNIEnv *env = GetJNIForThread();
+    env->SetBooleanField(wrapped_obj, jIsReadOnly, a0);
+}
+
+bool ByteBuffer::getNativeByteOrder() {
+    JNIEnv *env = GetJNIForThread();
+    return env->GetBooleanField(wrapped_obj, jNativeByteOrder);
+}
+
+void ByteBuffer::setNativeByteOrder(bool a0) {
+    JNIEnv *env = GetJNIForThread();
+    env->SetBooleanField(wrapped_obj, jNativeByteOrder, a0);
+}
+
+int32_t ByteBuffer::getOffset() {
+    JNIEnv *env = GetJNIForThread();
+    return env->GetIntField(wrapped_obj, jOffset);
+}
+
+jclass BufferInfo::mBufferInfoClass = 0;
+jmethodID BufferInfo::jBufferInfo = 0;
+jmethodID BufferInfo::jSet = 0;
+jfieldID BufferInfo::jFlags = 0;
+jfieldID BufferInfo::jOffset = 0;
+jfieldID BufferInfo::jPresentationTimeUs = 0;
+jfieldID BufferInfo::jSize = 0;
+void BufferInfo::InitStubs(JNIEnv *jEnv) {
+    initInit();
+
+    mBufferInfoClass = getClassGlobalRef("android/media/MediaCodec$BufferInfo");
+    jBufferInfo = getMethod("<init>", "()V");
+    jSet = getMethod("set", "(IIJI)V");
+    jFlags = getField("flags", "I");
+    jOffset = getField("offset", "I");
+    jPresentationTimeUs = getField("presentationTimeUs", "J");
+    jSize = getField("size", "I");
+}
+
+BufferInfo* BufferInfo::Wrap(jobject obj) {
+    JNIEnv *env = GetJNIForThread();
+    BufferInfo* ret = new BufferInfo(obj, env);
+    env->DeleteLocalRef(obj);
+    return ret;
+}
+
+BufferInfo::BufferInfo() {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    Init(env->NewObject(mBufferInfoClass, jBufferInfo), env);
+    env->PopLocalFrame(nullptr);
+}
+
+void BufferInfo::Set(int32_t a0, int32_t a1, int64_t a2, int32_t a3) {
+    JNIEnv *env = GetJNIForThread();
+    if (env->PushLocalFrame(0) != 0) {
+        AndroidBridge::HandleUncaughtException(env);
+        MOZ_CRASH("Exception should have caused crash.");
+    }
+
+    jvalue args[4];
+    args[0].i = a0;
+    args[1].i = a1;
+    args[2].j = a2;
+    args[3].i = a3;
+
+    env->CallVoidMethodA(wrapped_obj, jSet, args);
+    AndroidBridge::HandleUncaughtException(env);
+    env->PopLocalFrame(nullptr);
+}
+
+int32_t BufferInfo::getFlags() {
+    JNIEnv *env = GetJNIForThread();
+    return env->GetIntField(wrapped_obj, jFlags);
+}
+
+void BufferInfo::setFlags(int32_t a0) {
+    JNIEnv *env = GetJNIForThread();
+    env->SetIntField(wrapped_obj, jFlags, a0);
+}
+
+int32_t BufferInfo::getOffset() {
+    JNIEnv *env = GetJNIForThread();
+    return env->GetIntField(wrapped_obj, jOffset);
+}
+
+void BufferInfo::setOffset(int32_t a0) {
+    JNIEnv *env = GetJNIForThread();
+    env->SetIntField(wrapped_obj, jOffset, a0);
+}
+
+int64_t BufferInfo::getPresentationTimeUs() {
+    JNIEnv *env = GetJNIForThread();
+    return env->GetLongField(wrapped_obj, jPresentationTimeUs);
+}
+
+void BufferInfo::setPresentationTimeUs(int64_t a0) {
+    JNIEnv *env = GetJNIForThread();
+    env->SetLongField(wrapped_obj, jPresentationTimeUs, a0);
+}
+
+int32_t BufferInfo::getSize() {
+    JNIEnv *env = GetJNIForThread();
+    return env->GetIntField(wrapped_obj, jSize);
+}
+
+void BufferInfo::setSize(int32_t a0) {
+    JNIEnv *env = GetJNIForThread();
+    env->SetIntField(wrapped_obj, jSize, a0);
+}
+
+void InitSDKStubs(JNIEnv *jEnv) {
+    MediaCodec::InitStubs(jEnv);
+    MediaFormat::InitStubs(jEnv);
+    ByteBuffer::InitStubs(jEnv);
+    BufferInfo::InitStubs(jEnv);
+}
+} /* android */
+} /* widget */
+} /* mozilla */
new file mode 100644
--- /dev/null
+++ b/widget/android/GeneratedSDKWrappers.h
@@ -0,0 +1,335 @@
+// GENERATED CODE
+
+// NOTE: This code has been doctored. The JarClassProcessor is still a work in progress,
+// and so additions and deletions have been made to make this file valid.
+
+// Generated by the Java program at /build/jarClassProcessors at compile time from
+// a given set of jars and a set of requested methods. To update, change the annotations
+// on the corresponding Java methods and rerun the build. Manually updating this file
+// will cause your build to fail.
+
+#ifndef GeneratedSDKWrappers_h__
+#define GeneratedSDKWrappers_h__
+
+#include "nsXPCOMStrings.h"
+#include "AndroidJavaWrappers.h"
+
+namespace mozilla {
+namespace widget {
+namespace android {
+
+#define MEDIACODEC_EXCEPTION_INDEX -255
+
+void InitSDKStubs(JNIEnv *jEnv);
+
+class MediaCodec : public AutoGlobalWrappedJavaObject {
+public:
+    static void InitStubs(JNIEnv *jEnv);
+    static MediaCodec* Wrap(jobject obj);
+    MediaCodec(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
+    bool Configure(jobject a0, jobject a1, jobject a2, int32_t a3);
+    static jobject CreateByCodecName(const nsAString& a0);
+    static jobject CreateDecoderByType(const nsAString& a0);
+    static jobject CreateEncoderByType(const nsAString& a0);
+    int32_t DequeueInputBuffer(int64_t a0);
+    int32_t DequeueOutputBuffer(jobject a0, int64_t a1);
+    void Finalize();
+    void Flush();
+    jobjectArray GetInputBuffers();
+    jobjectArray GetOutputBuffers();
+    jobject GetOutputFormat();
+    void QueueInputBuffer(int32_t a0, int32_t a1, int32_t a2, int64_t a3, int32_t a4);
+    void QueueSecureInputBuffer(int32_t a0, int32_t a1, jobject a2, int64_t a3, int32_t a4);
+    void Release();
+    void ReleaseOutputBuffer(int32_t a0, bool a1);
+    void SetVideoScalingMode(int32_t a0);
+    bool Start();
+    void Stop();
+    static int32_t getBUFFER_FLAG_CODEC_CONFIG();
+    static int32_t getBUFFER_FLAG_END_OF_STREAM();
+    static int32_t getBUFFER_FLAG_SYNC_FRAME();
+    static int32_t getCONFIGURE_FLAG_ENCODE();
+    static int32_t getCRYPTO_MODE_AES_CTR();
+    static int32_t getCRYPTO_MODE_UNENCRYPTED();
+    static int32_t getINFO_OUTPUT_BUFFERS_CHANGED();
+    static int32_t getINFO_OUTPUT_FORMAT_CHANGED();
+    static int32_t getINFO_TRY_AGAIN_LATER();
+    static int32_t getVIDEO_SCALING_MODE_SCALE_TO_FIT();
+    static int32_t getVIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING();
+    MediaCodec() : AutoGlobalWrappedJavaObject() {};
+protected:
+    static jclass mMediaCodecClass;
+    static jmethodID jConfigure;
+    static jmethodID jCreateByCodecName;
+    static jmethodID jCreateDecoderByType;
+    static jmethodID jCreateEncoderByType;
+    static jmethodID jDequeueInputBuffer;
+    static jmethodID jDequeueOutputBuffer;
+    static jmethodID jFinalize;
+    static jmethodID jFlush;
+    static jmethodID jGetInputBuffers;
+    static jmethodID jGetOutputBuffers;
+    static jmethodID jGetOutputFormat;
+    static jmethodID jQueueInputBuffer;
+    static jmethodID jQueueSecureInputBuffer;
+    static jmethodID jRelease;
+    static jmethodID jReleaseOutputBuffer;
+    static jmethodID jSetVideoScalingMode;
+    static jmethodID jStart;
+    static jmethodID jStop;
+    static jfieldID jBUFFER_FLAG_CODEC_CONFIG;
+    static jfieldID jBUFFER_FLAG_END_OF_STREAM;
+    static jfieldID jBUFFER_FLAG_SYNC_FRAME;
+    static jfieldID jCONFIGURE_FLAG_ENCODE;
+    static jfieldID jCRYPTO_MODE_AES_CTR;
+    static jfieldID jCRYPTO_MODE_UNENCRYPTED;
+    static jfieldID jINFO_OUTPUT_BUFFERS_CHANGED;
+    static jfieldID jINFO_OUTPUT_FORMAT_CHANGED;
+    static jfieldID jINFO_TRY_AGAIN_LATER;
+    static jfieldID jVIDEO_SCALING_MODE_SCALE_TO_FIT;
+    static jfieldID jVIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING;
+};
+
+class MediaFormat : public AutoGlobalWrappedJavaObject {
+public:
+    static void InitStubs(JNIEnv *jEnv);
+    static MediaFormat* Wrap(jobject obj);
+    MediaFormat(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
+    MediaFormat();
+    bool ContainsKey(const nsAString& a0);
+    static jobject CreateAudioFormat(const nsAString& a0, int32_t a1, int32_t a2);
+    static jobject CreateVideoFormat(const nsAString& a0, int32_t a1, int32_t a2);
+    jobject GetByteBuffer(const nsAString& a0);
+    jfloat GetFloat(const nsAString& a0);
+    int32_t GetInteger(const nsAString& a0);
+    int64_t GetLong(const nsAString& a0);
+    jstring GetString(const nsAString& a0);
+    void SetByteBuffer(const nsAString& a0, jobject a1);
+    void SetFloat(const nsAString& a0, jfloat a1);
+    void SetInteger(const nsAString& a0, int32_t a1);
+    void SetLong(const nsAString& a0, int64_t a1);
+    void SetString(const nsAString& a0, const nsAString& a1);
+    jstring ToString();
+    static jstring getKEY_AAC_PROFILE();
+    static jstring getKEY_BIT_RATE();
+    static jstring getKEY_CHANNEL_COUNT();
+    static jstring getKEY_CHANNEL_MASK();
+    static jstring getKEY_COLOR_FORMAT();
+    static jstring getKEY_DURATION();
+    static jstring getKEY_FLAC_COMPRESSION_LEVEL();
+    static jstring getKEY_FRAME_RATE();
+    static jstring getKEY_HEIGHT();
+    static jstring getKEY_IS_ADTS();
+    static jstring getKEY_I_FRAME_INTERVAL();
+    static jstring getKEY_MAX_INPUT_SIZE();
+    static jstring getKEY_MIME();
+    static jstring getKEY_SAMPLE_RATE();
+    static jstring getKEY_WIDTH();
+protected:
+    static jclass mMediaFormatClass;
+    static jmethodID jMediaFormat;
+    static jmethodID jContainsKey;
+    static jmethodID jCreateAudioFormat;
+    static jmethodID jCreateVideoFormat;
+    static jmethodID jGetByteBuffer;
+    static jmethodID jGetFloat;
+    static jmethodID jGetInteger;
+    static jmethodID jGetLong;
+    static jmethodID jGetString;
+    static jmethodID jSetByteBuffer;
+    static jmethodID jSetFloat;
+    static jmethodID jSetInteger;
+    static jmethodID jSetLong;
+    static jmethodID jSetString;
+    static jmethodID jToString;
+    static jfieldID jKEY_AAC_PROFILE;
+    static jfieldID jKEY_BIT_RATE;
+    static jfieldID jKEY_CHANNEL_COUNT;
+    static jfieldID jKEY_CHANNEL_MASK;
+    static jfieldID jKEY_COLOR_FORMAT;
+    static jfieldID jKEY_DURATION;
+    static jfieldID jKEY_FLAC_COMPRESSION_LEVEL;
+    static jfieldID jKEY_FRAME_RATE;
+    static jfieldID jKEY_HEIGHT;
+    static jfieldID jKEY_IS_ADTS;
+    static jfieldID jKEY_I_FRAME_INTERVAL;
+    static jfieldID jKEY_MAX_INPUT_SIZE;
+    static jfieldID jKEY_MIME;
+    static jfieldID jKEY_SAMPLE_RATE;
+    static jfieldID jKEY_WIDTH;
+};
+
+class ByteBuffer : public AutoGlobalWrappedJavaObject {
+public:
+    static void InitStubs(JNIEnv *jEnv);
+    static ByteBuffer* Wrap(jobject obj);
+    ByteBuffer(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
+    int8_t _get(int32_t a0);
+    void _put(int32_t a0, int8_t a1);
+    static jobject Allocate(int32_t a0);
+    static jobject AllocateDirect(int32_t a0);
+    jobject Array();
+    jbyteArray Array1();
+    int32_t ArrayOffset();
+    jstring AsCharBuffer();
+    jobject AsDoubleBuffer();
+    jobject AsFloatBuffer();
+    jobject AsIntBuffer();
+    jobject AsLongBuffer();
+    jobject AsReadOnlyBuffer();
+    jobject AsShortBuffer();
+    jobject Compact();
+    int32_t CompareTo(jobject a0);
+    int32_t CompareTo1(jobject a0);
+    jobject Duplicate();
+    bool Equals(jobject a0);
+    int8_t Get();
+    int8_t Get1(int32_t a0);
+    jobject Get1(jbyteArray a0);
+    jobject Get1(jbyteArray a0, int32_t a1, int32_t a2);
+    uint16_t GetChar();
+    uint16_t GetChar1(int32_t a0);
+    jdouble GetDouble();
+    jdouble GetDouble1(int32_t a0);
+    jfloat GetFloat();
+    jfloat GetFloat1(int32_t a0);
+    int32_t GetInt();
+    int32_t GetInt1(int32_t a0);
+    int64_t GetLong();
+    int64_t GetLong1(int32_t a0);
+    int16_t GetShort();
+    int16_t GetShort1(int32_t a0);
+    bool HasArray();
+    int32_t HashCode();
+    bool IsDirect();
+    jobject Order();
+    jobject Order1(jobject a0);
+    jobject Put(int8_t a0);
+    jobject Put1(int32_t a0, int8_t a1);
+    jobject Put1(jobject a0);
+    jobject Put1(jbyteArray a0);
+    jobject Put1(jbyteArray a0, int32_t a1, int32_t a2);
+    jobject PutChar(uint16_t a0);
+    jobject PutChar1(int32_t a0, uint16_t a1);
+    jobject PutDouble(jdouble a0);
+    jobject PutDouble1(int32_t a0, jdouble a1);
+    jobject PutFloat(jfloat a0);
+    jobject PutFloat1(int32_t a0, jfloat a1);
+    jobject PutInt(int32_t a0);
+    jobject PutInt1(int32_t a0, int32_t a1);
+    jobject PutLong(int32_t a0, int64_t a1);
+    jobject PutLong1(int64_t a0);
+    jobject PutShort(int32_t a0, int16_t a1);
+    jobject PutShort1(int16_t a0);
+    jobject Slice();
+    jstring ToString();
+    static jobject Wrap1(jbyteArray a0);
+    static jobject Wrap2(jbyteArray a0, int32_t a1, int32_t a2);
+    bool getBigEndian();
+    void setBigEndian(bool a0);
+    jbyteArray getHb();
+    bool getIsReadOnly();
+    void setIsReadOnly(bool a0);
+    bool getNativeByteOrder();
+    void setNativeByteOrder(bool a0);
+    int32_t getOffset();
+    ByteBuffer() : AutoGlobalWrappedJavaObject() {};
+protected:
+    static jclass mByteBufferClass;
+    static jmethodID j_get;
+    static jmethodID j_put;
+    static jmethodID jAllocate;
+    static jmethodID jAllocateDirect;
+    static jmethodID jArray;
+    static jmethodID jArray1;
+    static jmethodID jArrayOffset;
+    static jmethodID jAsCharBuffer;
+    static jmethodID jAsDoubleBuffer;
+    static jmethodID jAsFloatBuffer;
+    static jmethodID jAsIntBuffer;
+    static jmethodID jAsLongBuffer;
+    static jmethodID jAsReadOnlyBuffer;
+    static jmethodID jAsShortBuffer;
+    static jmethodID jCompact;
+    static jmethodID jCompareTo;
+    static jmethodID jCompareTo1;
+    static jmethodID jDuplicate;
+    static jmethodID jEquals;
+    static jmethodID jGet;
+    static jmethodID jGet1;
+    static jmethodID jGet10;
+    static jmethodID jGet11;
+    static jmethodID jGetChar;
+    static jmethodID jGetChar1;
+    static jmethodID jGetDouble;
+    static jmethodID jGetDouble1;
+    static jmethodID jGetFloat;
+    static jmethodID jGetFloat1;
+    static jmethodID jGetInt;
+    static jmethodID jGetInt1;
+    static jmethodID jGetLong;
+    static jmethodID jGetLong1;
+    static jmethodID jGetShort;
+    static jmethodID jGetShort1;
+    static jmethodID jHasArray;
+    static jmethodID jHashCode;
+    static jmethodID jIsDirect;
+    static jmethodID jOrder;
+    static jmethodID jOrder1;
+    static jmethodID jPut;
+    static jmethodID jPut1;
+    static jmethodID jPut12;
+    static jmethodID jPut13;
+    static jmethodID jPut14;
+    static jmethodID jPutChar;
+    static jmethodID jPutChar1;
+    static jmethodID jPutDouble;
+    static jmethodID jPutDouble1;
+    static jmethodID jPutFloat;
+    static jmethodID jPutFloat1;
+    static jmethodID jPutInt;
+    static jmethodID jPutInt1;
+    static jmethodID jPutLong;
+    static jmethodID jPutLong1;
+    static jmethodID jPutShort;
+    static jmethodID jPutShort1;
+    static jmethodID jSlice;
+    static jmethodID jToString;
+    static jmethodID jWrap;
+    static jmethodID jWrap1;
+    static jfieldID jBigEndian;
+    static jfieldID jHb;
+    static jfieldID jIsReadOnly;
+    static jfieldID jNativeByteOrder;
+    static jfieldID jOffset;
+};
+
+class BufferInfo : public AutoGlobalWrappedJavaObject {
+public:
+    static void InitStubs(JNIEnv *jEnv);
+    static BufferInfo* Wrap(jobject obj);
+    BufferInfo(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
+    BufferInfo();
+    void Set(int32_t a0, int32_t a1, int64_t a2, int32_t a3);
+    int32_t getFlags();
+    void setFlags(int32_t a0);
+    int32_t getOffset();
+    void setOffset(int32_t a0);
+    int64_t getPresentationTimeUs();
+    void setPresentationTimeUs(int64_t a0);
+    int32_t getSize();
+    void setSize(int32_t a0);
+protected:
+    static jclass mBufferInfoClass;
+    static jmethodID jBufferInfo;
+    static jmethodID jSet;
+    static jfieldID jFlags;
+    static jfieldID jOffset;
+    static jfieldID jPresentationTimeUs;
+    static jfieldID jSize;
+};
+
+} /* android */
+} /* widget */
+} /* mozilla */
+#endif
deleted file mode 100644
--- a/widget/android/bindings/Makefile.in
+++ /dev/null
@@ -1,26 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-ANNOTATION_PROCESSOR_JAR_FILES := $(DEPTH)/build/annotationProcessors/annotationProcessors.jar:$(ANDROID_SDK)/android.jar:$(ANDROID_SDK)/../../tools/lib/lint.jar:$(ANDROID_SDK)/../../tools/lib/lint-checks.jar
-
-MediaCodec.cpp: $(ANDROID_SDK)/android.jar mediacodec-classes.txt
-	$(JAVA) -classpath $(ANNOTATION_PROCESSOR_JAR_FILES) org.mozilla.gecko.annotationProcessors.SDKProcessor $(ANDROID_SDK)/android.jar $(srcdir)/mediacodec-classes.txt $(CURDIR) MediaCodec 16
-
-MediaCodec.h: MediaCodec.cpp ;
-
-SurfaceTexture.cpp: $(ANDROID_SDK)/android.jar surfacetexture-classes.txt
-	$(JAVA) -classpath $(ANNOTATION_PROCESSOR_JAR_FILES) org.mozilla.gecko.annotationProcessors.SDKProcessor $(ANDROID_SDK)/android.jar $(srcdir)/surfacetexture-classes.txt $(CURDIR) SurfaceTexture 16
-
-SurfaceTexture.h: SurfaceTexture.cpp ;
-
-# We'd like these to be defined in a future GENERATED_EXPORTS list.
-bindings_exports := \
-  MediaCodec.h \
-  SurfaceTexture.h \
-  $(NULL)
-
-INSTALL_TARGETS += bindings_exports
-bindings_exports_FILES := $(bindings_exports)
-bindings_exports_DEST = $(DIST)/include
-bindings_exports_TARGET := export
deleted file mode 100644
--- a/widget/android/bindings/mediacodec-classes.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-android.media.MediaCodec
-android.media.MediaCodec$BufferInfo
-android.media.MediaFormat
deleted file mode 100644
--- a/widget/android/bindings/moz.build
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-GENERATED_SOURCES += [
-    'MediaCodec.cpp',
-    'SurfaceTexture.cpp',
-]
-
-# We'd like to add these to a future GENERATED_EXPORTS list, but for now we mark
-# them as generated here and manually install them in Makefile.in.
-GENERATED_INCLUDES += [
-    'MediaCodec.h',
-    'SurfaceTexture.h',
-]
-
-FAIL_ON_WARNINGS = True
-FINAL_LIBRARY = 'xul'
-
-LOCAL_INCLUDES += [
-    '/widget/android',
-]
deleted file mode 100644
--- a/widget/android/bindings/surfacetexture-classes.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-android.graphics.SurfaceTexture
-android.view.Surface
--- a/widget/android/moz.build
+++ b/widget/android/moz.build
@@ -1,40 +1,38 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-DIRS += [
-    'bindings',
-]
-
 XPIDL_SOURCES += [
     'nsIAndroidBridge.idl',
 ]
 
 XPIDL_MODULE = 'widget_android'
 
 EXPORTS += [
     'AndroidBridge.h',
     'AndroidJavaWrappers.h',
     'AndroidJNIWrapper.h',
     'GeneratedJNIWrappers.h',
+    'GeneratedSDKWrappers.h',
 ]
 
 SOURCES += [
     'AndroidBridge.cpp',
     'AndroidDirectTexture.cpp',
     'AndroidGraphicBuffer.cpp',
     'AndroidJavaWrappers.cpp',
     'AndroidJNI.cpp',
     'AndroidJNIWrapper.cpp',
     'APZCCallbackHandler.cpp',
     'GeneratedJNIWrappers.cpp',
+    'GeneratedSDKWrappers.cpp',
     'GfxInfo.cpp',
     'NativeJSContainer.cpp',
     'nsAndroidProtocolHandler.cpp',
     'nsAppShell.cpp',
     'nsClipboard.cpp',
     'nsDeviceContextAndroid.cpp',
     'nsIdleServiceAndroid.cpp',
     'nsIMEPicker.cpp',