author | Ryan VanderMeulen <ryanvm@gmail.com> |
Fri, 27 Sep 2013 17:02:09 -0400 | |
changeset 163813 | f7d9445c77a7620a2ed5e89bb7a77645b2334712 |
parent 163812 | 9d7b0dc99acf475459cc50bbd26903fa1da53323 |
child 163814 | 2106260cb59b7c7ba82ad93c979c329259e02864 |
push id | unknown |
push user | unknown |
push date | unknown |
bugs | 913985 |
milestone | 27.0a1 |
backs out | de21920d2b8ebd5bc369081140b5cf9b65786d95 f0f5497d65bbae137f8edc9ce5c8fe32eaf9017c 1e16ca4ad8018ec29543113f2056e40ae2448077 9c069a0820eadd3061f5bffa851176c29aabcad0 274df3abc9918c78879b65eb4650a865e9b91618 05fe8b17516ad91b194a60806a82ea4b88359d35 |
--- a/build/annotationProcessors/AnnotationProcessor.java +++ b/build/annotationProcessors/AnnotationProcessor.java @@ -1,34 +1,26 @@ /* 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 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.GeneratableEntryPointIterator; import java.io.FileOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.Iterator; public class AnnotationProcessor { public static final String OUTFILE = "GeneratedJNIWrappers.cpp"; public static final String HEADERFILE = "GeneratedJNIWrappers.h"; - 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"; - public static void main(String[] args) { // We expect a list of jars on the commandline. If missing, whinge about it. if (args.length <= 1) { System.err.println("Usage: java AnnotationProcessor jarfiles ..."); System.exit(1); } System.out.println("Processing annotations..."); @@ -36,126 +28,49 @@ public class AnnotationProcessor { // We want to produce the same output as last time as often as possible. Ordering of // generated statements, therefore, needs to be consistent. Arrays.sort(args); // 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 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 *jEnv);\n\n"); + Iterator<Class<?>> jarClassIterator = IterableJarLoadingURLClassLoader.getIteratorOverJars(args); - 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 *jEnv) {\n"); + CodeGenerator generatorInstance = new CodeGenerator(); while (jarClassIterator.hasNext()) { - ClassWithOptions aClassTuple = jarClassIterator.next(); - - CodeGenerator generatorInstance; + Class<?> aClass = jarClassIterator.next(); // Get an iterator over the appropriately generated methods of this class - Iterator<AnnotatableEntity> methodIterator = new GeneratableElementIterator(aClassTuple.wrappedClass); + Iterator<MethodWithAnnotationInfo> methodIterator = new GeneratableEntryPointIterator(aClass.getDeclaredMethods()); - if (!methodIterator.hasNext()) { - continue; - } - generatorInstance = new CodeGenerator(aClassTuple.wrappedClass, aClassTuple.generatedName); - - stubInitialiser.append(" ").append(aClassTuple.generatedName).append("::InitStubs(jEnv);\n"); - - // Iterate all annotated members in this class.. + // Iterate all annotated methods in this class.. while (methodIterator.hasNext()) { - AnnotatableEntity aElementTuple = methodIterator.next(); - switch (aElementTuple.mEntityType) { - case METHOD: - generatorInstance.generateMethod(aElementTuple); - break; - case FIELD: - generatorInstance.generateField(aElementTuple); - break; - case CONSTRUCTOR: - generatorInstance.generateConstructor(aElementTuple); - break; - } + MethodWithAnnotationInfo aMethodTuple = methodIterator.next(); + generatorInstance.generateMethod(aMethodTuple, aClass); } - headerFile.append(generatorInstance.getHeaderFileContents()); - implementationFile.append(generatorInstance.getWrapperFileContents()); } - implementationFile.append('\n'); - stubInitialiser.append("}"); - implementationFile.append(stubInitialiser); - - implementationFile.append("\n} /* android */\n" + - "} /* widget */\n" + - "} /* mozilla */\n"); - - headerFile.append("\n} /* android */\n" + - "} /* widget */\n" + - "} /* mozilla */\n" + - "#endif\n"); - - writeOutputFiles(headerFile, implementationFile); + writeOutputFiles(generatorInstance); long e = System.currentTimeMillis(); System.out.println("Annotation processing complete in " + (e - s) + "ms"); } - private static void writeOutputFiles(StringBuilder aHeaderFile, StringBuilder aImplementationFile) { - FileOutputStream headerStream = null; + private static void writeOutputFiles(CodeGenerator aGenerator) { try { - headerStream = new FileOutputStream(OUTFILE); - headerStream.write(aImplementationFile.toString().getBytes()); + FileOutputStream outStream = new FileOutputStream(OUTFILE); + outStream.write(aGenerator.getWrapperFileContents()); } catch (IOException e) { System.err.println("Unable to write " + OUTFILE + ". 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); - } - } } - FileOutputStream outStream = null; try { - outStream = new FileOutputStream(HEADERFILE); - outStream.write(aHeaderFile.toString().getBytes()); + FileOutputStream headerStream = new FileOutputStream(HEADERFILE); + headerStream.write(aGenerator.getHeaderFileContents()); } catch (IOException e) { - System.err.println("Unable to write " + HEADERFILE + ". Perhaps a permissions issue?"); + System.err.println("Unable to write " + OUTFILE + ". Perhaps a permissions issue?"); e.printStackTrace(System.err); - } finally { - if (outStream != null) { - try { - outStream.close(); - } catch (IOException e) { - System.err.println("Unable to close outStream due to "+e); - e.printStackTrace(System.err); - } - } } } } \ No newline at end of file
--- a/build/annotationProcessors/CodeGenerator.java +++ b/build/annotationProcessors/CodeGenerator.java @@ -1,618 +1,336 @@ /* 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 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]; - // Buffers holding the strings to ultimately be written to the output files. - private final StringBuilder zeroingCode = new StringBuilder(); private final StringBuilder wrapperStartupCode = new StringBuilder(); private final StringBuilder wrapperMethodBodies = new StringBuilder(); - private final StringBuilder headerPublic = new StringBuilder(); - private final StringBuilder headerProtected = new StringBuilder(); + private final StringBuilder headerFields = new StringBuilder(); + private final StringBuilder headerMethods = new StringBuilder(); private final HashSet<String> seenClasses = new HashSet<String>(); - private final String mCClassName; - - private final Class<?> mClassToWrap; - - private boolean mHasEncounteredDefaultConstructor; + private 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"; - // 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; - - public CodeGenerator(Class<?> aClass, String aGeneratedName) { - mClassToWrap = aClass; - mCClassName = aGeneratedName; - + public CodeGenerator() { // 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 *jEnv) {\n" + - " initInit();\n"); - + // wrapperMethodBodies. Similarly, GeneratedJNIWrappers.h is the concatenation of headerFields + // with headerMethods. + wrapperStartupCode.append(GENERATED_COMMENT); + wrapperStartupCode.append( + "#include \"nsXPCOMStrings.h\"\n" + + "#include \"AndroidBridge.h\"\n" + + "#include \"AndroidBridgeUtilities.h\"\n" + + "\n" + + "#ifdef DEBUG\n" + + "#define ALOG_BRIDGE(args...) ALOG(args)\n" + + "#else\n" + + "#define ALOG_BRIDGE(args...) ((void)0)\n" + + "#endif\n" + + "\n" + + "using namespace mozilla;\n" + + "void AndroidBridge::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 *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. - */ - private void generateWrapperMethod() { - headerPublic.append(" static ").append(mCClassName).append("* Wrap(jobject obj);\n" + - " ").append(mCClassName).append("(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};\n"); - - wrapperMethodBodies.append("\n").append(mCClassName).append("* ").append(mCClassName).append("::Wrap(jobject obj) {\n" + - " JNIEnv *env = GetJNIForThread();\n\n" + - " if (!env) {\n" + - " ALOG_BRIDGE(\"Aborted: No env - %s\", __PRETTY_FUNCTION__);\n" + - " return NULL;\n" + - " }\n\n" + - " ").append(mCClassName).append("* ret = new ").append(mCClassName).append("(obj, env);\n" + - " env->DeleteLocalRef(obj);\n" + - " return ret;\n" + - "}\n"); - } - - private void generateMemberCommon(Member theMethod, String aCMethodName, Class<?> aClass) { - ensureClassHeaderAndStartup(aClass); - writeMemberIdField(theMethod, aCMethodName); - writeStartupCode(theMethod); + headerFields.append("protected:\n\n"); + headerMethods.append(GENERATED_COMMENT); + headerMethods.append("public:\n\n"); } /** * Append the appropriate generated code to the buffers for the method provided. * - * @param aMethodTuple The Java method, plus annotation data. + * @param aMethodTuple The Java method, plus the name for the generated method. + * @param aClass The class to which the Java method belongs. */ - public void generateMethod(AnnotatableEntity aMethodTuple) { + public void generateMethod(MethodWithAnnotationInfo aMethodTuple, Class<?> aClass) { // Unpack the tuple and extract some useful fields from the Method.. - Method theMethod = aMethodTuple.getMethod(); - - String CMethodName = aMethodTuple.mAnnotationInfo.wrapperName; + Method aMethod = aMethodTuple.method; + String CMethodName = aMethodTuple.wrapperName; - generateMemberCommon(theMethod, CMethodName, mClassToWrap); + String javaMethodName = aMethod.getName(); - boolean isFieldStatic = Utils.isMemberStatic(theMethod); - boolean shallGenerateStatic = isFieldStatic || aMethodTuple.mAnnotationInfo.isStatic; + ensureClassHeaderAndStartup(aClass); - Class<?>[] parameterTypes = theMethod.getParameterTypes(); - Class<?> returnType = theMethod.getReturnType(); + writeHeaderField(CMethodName); + writeStartupCode(CMethodName, javaMethodName, aMethod, aClass); // Get the C++ method signature for this method. - String implementationSignature = Utils.getCImplementationMethodSignature(parameterTypes, returnType, CMethodName, mCClassName); - String headerSignature = Utils.getCHeaderMethodSignature(parameterTypes, theMethod.getParameterAnnotations(), returnType, CMethodName, mCClassName, shallGenerateStatic); + String implementationSignature = Utils.getCImplementationMethodSignature(aMethod, CMethodName); + String headerSignature = Utils.getCHeaderMethodSignature(aMethod, CMethodName, aMethodTuple.isStatic); // Add the header signature to the header file. - writeSignatureToHeader(headerSignature); + headerMethods.append(headerSignature); + headerMethods.append(";\n"); // Use the implementation signature to generate the method body... - writeMethodBody(implementationSignature, CMethodName, theMethod, mClassToWrap, aMethodTuple.mAnnotationInfo.isStatic, aMethodTuple.mAnnotationInfo.isMultithreaded); - } - - private void generateGetterOrSetterBody(Class<?> aFieldType, String aFieldName, boolean aIsFieldStatic, boolean isSetter) { - StringBuilder argumentContent = null; - - if (isSetter) { - Class<?>[] setterArguments = new Class<?>[]{aFieldType}; - // Marshall the argument.. - argumentContent = getArgumentMarshalling(setterArguments); - } - - 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(aFieldType)).append(">("); - } - - wrapperMethodBodies.append("env->Get"); - } - - if (aIsFieldStatic) { - wrapperMethodBodies.append("Static"); - } - 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"); - } - wrapperMethodBodies.append(", j") - .append(aFieldName); - if (isSetter) { - wrapperMethodBodies.append(argumentContent); - } - - if (!isSetter && isObjectReturningMethod) { - wrapperMethodBodies.append(')'); - } - wrapperMethodBodies.append(");\n" + - "}\n"); - } - - public void generateField(AnnotatableEntity aFieldTuple) { - Field theField = aFieldTuple.getField(); - - // Handles a peculiar case when dealing with enum types. We don't care about this field. - // It just gets in the way and stops our code from compiling. - if (theField.getName().equals("$VALUES")) { - return; - } - - String CFieldName = aFieldTuple.mAnnotationInfo.wrapperName; - - Class<?> fieldType = theField.getType(); - - generateMemberCommon(theField, CFieldName, mClassToWrap); - - boolean isFieldStatic = Utils.isMemberStatic(theField); - boolean isFieldFinal = Utils.isMemberFinal(theField); - boolean shallGenerateStatic = isFieldStatic || aFieldTuple.mAnnotationInfo.isStatic; - - String getterName = "get" + CFieldName; - String getterSignature = Utils.getCImplementationMethodSignature(EMPTY_CLASS_ARRAY, fieldType, getterName, mCClassName); - String getterHeaderSignature = Utils.getCHeaderMethodSignature(EMPTY_CLASS_ARRAY, GETTER_ARGUMENT_ANNOTATIONS, fieldType, getterName, mCClassName, shallGenerateStatic); - - writeSignatureToHeader(getterHeaderSignature); - - writeFunctionStartupBoilerPlate(getterSignature, fieldType, isFieldStatic, true); - - generateGetterOrSetterBody(fieldType, CFieldName, isFieldStatic, false); - - // 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); - String setterHeaderSignature = Utils.getCHeaderMethodSignature(setterArguments, SETTER_ARGUMENT_ANNOTATIONS, Void.class, setterName, mCClassName, shallGenerateStatic); - - writeSignatureToHeader(setterHeaderSignature); - - writeFunctionStartupBoilerPlate(setterSignature, Void.class, isFieldStatic, true); - - generateGetterOrSetterBody(fieldType, CFieldName, isFieldStatic, true); - } - } - - 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); - String headerSignature = Utils.getCHeaderMethodSignature(theCtor.getParameterTypes(), theCtor.getParameterAnnotations(), Void.class, CMethodName, mCClassName, false); - - // 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); - - if (theCtor.getParameterTypes().length == 0) { - mHasEncounteredDefaultConstructor = true; - } + writeMethodBody(implementationSignature, CMethodName, aMethod, aClass, aMethodTuple.isStatic, aMethodTuple.isMultithreaded); } /** * 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(); if (seenClasses.contains(className)) { return; } - zeroingCode.append("jclass ") - .append(mCClassName) - .append("::") - .append(Utils.getClassReferenceName(aClass)) - .append(" = 0;\n"); - // Add a field to hold the reference... - headerProtected.append("\n static jclass ") - .append(Utils.getClassReferenceName(aClass)) - .append(";\n"); + headerFields.append("\njclass "); + headerFields.append(Utils.getClassReferenceName(aClass)); + headerFields.append(";\n"); // Add startup code to populate it.. - wrapperStartupCode.append('\n') - .append(Utils.getStartupLineForClass(aClass)); + wrapperStartupCode.append('\n'); + wrapperStartupCode.append(Utils.getStartupLineForClass(aClass)); seenClasses.add(className); } /** - * Write out the function startup boilerplate for the method described. Check for environment - * existence, - * @param methodSignature - * @param returnType - * @param aIsStatic - * @param aIsThreaded - */ - private void writeFunctionStartupBoilerPlate(String methodSignature, Class<?> returnType, boolean aIsStatic, boolean aIsThreaded) { - // The start-of-function boilerplate. Does the bridge exist? Does the env exist? etc. - wrapperMethodBodies.append('\n') - .append(methodSignature) - .append(" {\n"); - - wrapperMethodBodies.append(" JNIEnv *env = "); - if (!aIsThreaded) { - wrapperMethodBodies.append("AndroidBridge::GetJNIEnv();\n"); - } else { - wrapperMethodBodies.append("GetJNIForThread();\n"); - } - wrapperMethodBodies.append(" if (!env) {\n" + - " ALOG_BRIDGE(\"Aborted: No env - %s\", __PRETTY_FUNCTION__);\n" + - " return").append(Utils.getFailureReturnForType(returnType)).append(";\n" + - " }\n\n"); - } - - /** - * Write out the appropriate JNI frame pushing boilerplate for a call to the member provided ( - * which must be a constructor or method). - * - * @param aMethod A constructor/method being wrapped. - * @param aIsObjectReturningMethod Does the method being wrapped return an object? - */ - private void writeFramePushBoilerplate(Member aMethod, boolean aIsObjectReturningMethod) { - if (aMethod instanceof Field) { - throw new IllegalArgumentException("Tried to push frame for a FIELD?!"); - } - - Method m; - Constructor c; - - Class<?> returnType; - - int localReferencesNeeded; - if (aMethod instanceof Method) { - m = (Method) aMethod; - returnType = m.getReturnType(); - localReferencesNeeded = Utils.enumerateReferenceArguments(m.getParameterTypes()); - } else { - c = (Constructor) aMethod; - returnType = Void.class; - localReferencesNeeded = Utils.enumerateReferenceArguments(c.getParameterTypes()); - } - - // Determine the number of local refs required for our local frame.. - // AutoLocalJNIFrame is not applicable here due to it's inability to handle return values. - if (aIsObjectReturningMethod) { - localReferencesNeeded++; - } - wrapperMethodBodies.append(" if (env->PushLocalFrame(").append(localReferencesNeeded).append(") != 0) {\n" + - " ALOG_BRIDGE(\"Exceptional exit of: %s\", __PRETTY_FUNCTION__);\n" + - " env->ExceptionDescribe();\n"+ - " env->ExceptionClear();\n" + - " return").append(Utils.getFailureReturnForType(returnType)).append(";\n" + - " }\n\n"); - - } - - private StringBuilder getArgumentMarshalling(Class<?>[] argumentTypes) { - StringBuilder argumentContent = new StringBuilder(); - - // If we have >2 arguments, use the jvalue[] calling approach. - argumentContent.append(", "); - if (argumentTypes.length > 2) { - wrapperMethodBodies.append(" jvalue args[").append(argumentTypes.length).append("];\n"); - for (int aT = 0; aT < argumentTypes.length; aT++) { - wrapperMethodBodies.append(" args[").append(aT).append("].") - .append(Utils.getArrayArgumentMashallingLine(argumentTypes[aT], "a" + aT)); - } - - // The only argument is the array of arguments. - argumentContent.append("args"); - wrapperMethodBodies.append('\n'); - } else { - // Otherwise, use the vanilla calling approach. - boolean needsNewline = false; - for (int aT = 0; aT < argumentTypes.length; aT++) { - // If the argument is a string-esque type, create a jstring from it, otherwise - // it can be passed directly. - if (Utils.isCharSequence(argumentTypes[aT])) { - wrapperMethodBodies.append(" jstring j").append(aT).append(" = AndroidBridge::NewJavaString(env, a").append(aT).append(");\n"); - needsNewline = true; - // Ensure we refer to the newly constructed Java string - not to the original - // parameter to the wrapper function. - argumentContent.append('j').append(aT); - } else { - argumentContent.append('a').append(aT); - } - if (aT != argumentTypes.length - 1) { - argumentContent.append(", "); - } - } - if (needsNewline) { - wrapperMethodBodies.append('\n'); - } - } - - return argumentContent; - } - - private void writeCtorBody(String implementationSignature, Constructor theCtor, boolean aIsThreaded) { - Class<?>[] argumentTypes = theCtor.getParameterTypes(); - - writeFunctionStartupBoilerPlate(implementationSignature, Void.class, false, aIsThreaded); - - writeFramePushBoilerplate(theCtor, false); - - // Marshall arguments for this constructor, if any... - boolean hasArguments = argumentTypes.length != 0; - - StringBuilder argumentContent = new StringBuilder(); - if (hasArguments) { - argumentContent = getArgumentMarshalling(argumentTypes); - } - - // The call into Java - wrapperMethodBodies.append(" Init(env->NewObject"); - if (argumentTypes.length > 2) { - wrapperMethodBodies.append('A'); - } - - wrapperMethodBodies.append('('); - - - // 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" + - " env->PopLocalFrame(NULL);\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 aCMethodName The C++ method name 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, String aCMethodName, Method aMethod, Class<?> aClass, boolean aIsStaticBridgeMethod, boolean aIsMultithreaded) { Class<?>[] argumentTypes = aMethod.getParameterTypes(); Class<?> returnType = aMethod.getReturnType(); - writeFunctionStartupBoilerPlate(methodSignature, returnType, aIsStaticBridgeMethod, aIsMultithreaded); + // The start-of-function boilerplate. Does the bridge exist? Does the env exist? etc. + wrapperMethodBodies.append('\n'); + wrapperMethodBodies.append(methodSignature); + + wrapperMethodBodies.append(" {\n"); - boolean isObjectReturningMethod = !returnType.getCanonicalName().equals("void") && Utils.isObjectType(returnType); + // Static stubs check the bridge instance has been created before trying to run. + if (aIsStaticBridgeMethod) { + wrapperMethodBodies.append(" if (!sBridge) {\n" + + " ALOG_BRIDGE(\"Aborted: No sBridge - %s\", __PRETTY_FUNCTION__);\n" + + " return").append(Utils.getFailureReturnForType(returnType)).append(";\n" + + " }\n\n"); + } + wrapperMethodBodies.append(" JNIEnv *env = "); + if (!aIsMultithreaded) { + wrapperMethodBodies.append("GetJNIEnv();\n"); + } else { + wrapperMethodBodies.append("GetJNIForThread();\n"); + } + wrapperMethodBodies.append(" if (!env) {\n" + + " ALOG_BRIDGE(\"Aborted: No env - %s\", __PRETTY_FUNCTION__);\n" + + " return").append(Utils.getFailureReturnForType(returnType)).append(";\n" + + " }\n\n"); - writeFramePushBoilerplate(aMethod, isObjectReturningMethod); + boolean isObjectReturningMethod = !returnType.getCanonicalName().equals("void") && Utils.doesReturnObjectType(aMethod); + + // Determine the number of local refs required for our local frame.. + // AutoLocalJNIFrame is not applicable here due to it's inability to handle return values. + int localReferencesNeeded = Utils.enumerateReferenceArguments(aMethod); + if (isObjectReturningMethod) { + localReferencesNeeded++; + } + wrapperMethodBodies.append(" if (env->PushLocalFrame(").append(localReferencesNeeded).append(") != 0) {\n" + + " ALOG_BRIDGE(\"Exceptional exit of: %s\", __PRETTY_FUNCTION__);\n" + + " env->ExceptionDescribe();\n"+ + " env->ExceptionClear();\n" + + " return").append(Utils.getFailureReturnForType(returnType)).append(";\n" + + " }\n\n"); // 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). StringBuilder argumentContent = new StringBuilder(); if (hasArguments) { - argumentContent = getArgumentMarshalling(argumentTypes); + argumentContent.append(", "); + // If we have >2 arguments, use the jvalue[] calling approach. + if (argumentTypes.length > 2) { + wrapperMethodBodies.append(" jvalue args[").append(argumentTypes.length).append("];\n"); + for (int aT = 0; aT < argumentTypes.length; aT++) { + wrapperMethodBodies.append(" args[").append(aT).append("]."); + wrapperMethodBodies.append(Utils.getArrayArgumentMashallingLine(argumentTypes[aT], "a" + aT)); + } + + // The only argument is the array of arguments. + argumentContent.append("args"); + wrapperMethodBodies.append('\n'); + } else { + // Otherwise, use the vanilla calling approach. + boolean needsNewline = false; + for (int aT = 0; aT < argumentTypes.length; aT++) { + // If the argument is a string-esque type, create a jstring from it, otherwise + // it can be passed directly. + if (Utils.isCharSequence(argumentTypes[aT])) { + wrapperMethodBodies.append(" jstring j").append(aT).append(" = NewJavaString(env, a").append(aT).append(");\n"); + needsNewline = true; + // Ensure we refer to the newly constructed Java string - not to the original + // parameter to the wrapper function. + argumentContent.append('j').append(aT); + } else { + argumentContent.append('a').append(aT); + } + if (aT != argumentTypes.length - 1) { + argumentContent.append(", "); + } + } + if (needsNewline) { + wrapperMethodBodies.append('\n'); + } + } } - // Allocate a temporary variable to hold the return type from Java. wrapperMethodBodies.append(" "); if (!returnType.getCanonicalName().equals("void")) { if (isObjectReturningMethod) { wrapperMethodBodies.append("jobject"); } else { wrapperMethodBodies.append(Utils.getCReturnType(returnType)); } wrapperMethodBodies.append(" temp = "); } - boolean isStaticJavaMethod = Utils.isMemberStatic(aMethod); + boolean isStaticJavaMethod = Utils.isMethodStatic(aMethod); // The call into Java - wrapperMethodBodies.append("env->") - .append(Utils.getCallPrefix(returnType, isStaticJavaMethod)); + wrapperMethodBodies.append("env->"); + wrapperMethodBodies.append(Utils.getCallPrefix(returnType, isStaticJavaMethod)); if (argumentTypes.length > 2) { wrapperMethodBodies.append('A'); } wrapperMethodBodies.append('('); // If the underlying Java method is nonstatic, we provide the target object to the JNI. if (!isStaticJavaMethod) { - wrapperMethodBodies.append("wrapped_obj, "); + wrapperMethodBodies.append("aTarget, "); } else { - // If this is a static underlying Java method, we need to use the class reference in our + // If the stub to be generated is static, we need to use the singleton to access the class + // reference. + if (aIsStaticBridgeMethod) { + wrapperMethodBodies.append("sBridge->"); + } + // If this is a static underlyin Java method, we need to use the class reference in our // call. wrapperMethodBodies.append(Utils.getClassReferenceName(aClass)).append(", "); } - wrapperMethodBodies.append(mMembersToIds.get(aMethod)); + // Write the method id out.. + if (aIsStaticBridgeMethod) { + wrapperMethodBodies.append("sBridge->"); + } + wrapperMethodBodies.append('j'); + wrapperMethodBodies.append(aCMethodName); // Tack on the arguments, if any.. - wrapperMethodBodies.append(argumentContent) - .append(");\n\n"); + wrapperMethodBodies.append(argumentContent); + wrapperMethodBodies.append(");\n\n"); // Check for exception and return the failure value.. wrapperMethodBodies.append(" if (env->ExceptionCheck()) {\n" + " ALOG_BRIDGE(\"Exceptional exit of: %s\", __PRETTY_FUNCTION__);\n" + " env->ExceptionDescribe();\n" + " env->ExceptionClear();\n" + " env->PopLocalFrame(NULL);\n" + " return").append(Utils.getFailureReturnForType(returnType)).append(";\n" + - " }\n\n"); + " }\n"); // 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)) - .append(" ret = static_cast<").append(Utils.getCReturnType(returnType)).append(">(env->PopLocalFrame(temp));\n" + + wrapperMethodBodies.append(" "); + wrapperMethodBodies.append(Utils.getCReturnType(returnType)); + wrapperMethodBodies.append(" ret = static_cast<").append(Utils.getCReturnType(returnType)).append(">(env->PopLocalFrame(temp));\n" + " return ret;\n"); } else if (!returnType.getCanonicalName().equals("void")) { // If we're a primitive-returning function, just return the directly-obtained primative // from the call to Java. wrapperMethodBodies.append(" env->PopLocalFrame(NULL);\n" + " return temp;\n"); } else { // If we don't return anything, just pop the stack frame and move on with life. wrapperMethodBodies.append(" env->PopLocalFrame(NULL);\n"); } wrapperMethodBodies.append("}\n"); } /** - * Generates the code to get the id of the given member on startup. + * Generates the code to get the method id of the given method on startup. * - * @param aMember The Java member being wrapped. + * @param aCMethodName The C method name of the method being generated. + * @param aJavaMethodName The name of the Java method being wrapped. + * @param aMethod The Java method being wrapped. */ - private void writeStartupCode(Member aMember) { - wrapperStartupCode.append(" ") - .append(mMembersToIds.get(aMember)) - .append(" = get"); - if (Utils.isMemberStatic(aMember)) { + private void writeStartupCode(String aCMethodName, String aJavaMethodName, Method aMethod, Class<?> aClass) { + wrapperStartupCode.append(" j"); + wrapperStartupCode.append(aCMethodName); + wrapperStartupCode.append(" = get"); + if (Utils.isMethodStatic(aMethod)) { wrapperStartupCode.append("Static"); } - - boolean isField = aMember instanceof Field; - if (isField) { - wrapperStartupCode.append("Field(\""); - } else { - wrapperStartupCode.append("Method(\""); - } - if (aMember instanceof Constructor) { - wrapperStartupCode.append("<init>"); - } else { - wrapperStartupCode.append(aMember.getName()); - } - - wrapperStartupCode.append("\", \"") - .append(Utils.getTypeSignatureStringForMember(aMember)) - .append("\");\n"); - } - - private void writeZeroingFor(Member aMember, final String aMemberName) { - if (aMember instanceof Field) { - zeroingCode.append("jfieldID "); - } else { - zeroingCode.append("jmethodID "); - } - zeroingCode.append(mCClassName) - .append("::") - .append(aMemberName) - .append(" = 0;\n"); + wrapperStartupCode.append("Method(\""); + wrapperStartupCode.append(aJavaMethodName); + wrapperStartupCode.append("\", \""); + wrapperStartupCode.append(Utils.getTypeSignatureString(aMethod)); + wrapperStartupCode.append("\");\n"); } /** - * Write the field declaration for the C++ id field of the given member. + * Create a method id field in the header file for the C method name provided. * - * @param aMember Member for which an id field needs to be generated. + * @param aMethodName C method name to generate a method id field for. */ - private void writeMemberIdField(Member aMember, final String aCMethodName) { - String memberName = 'j'+ aCMethodName; - - if (aMember instanceof Field) { - headerProtected.append(" static jfieldID "); - } else { - headerProtected.append(" static jmethodID "); - } - - while(mTakenMemberNames.contains(memberName)) { - memberName = 'j' + aCMethodName + mNameMunger; - mNameMunger++; - } - - writeZeroingFor(aMember, memberName); - mMembersToIds.put(aMember, memberName); - mTakenMemberNames.add(memberName); - - headerProtected.append(memberName) - .append(";\n"); - } - - /** - * Helper function to add a provided method signature to the public section of the generated header. - * - * @param aSignature The header to add. - */ - private void writeSignatureToHeader(String aSignature) { - headerPublic.append(" ") - .append(aSignature) - .append(";\n"); + private void writeHeaderField(String aMethodName) { + headerFields.append("jmethodID j"); + headerFields.append(aMethodName); + headerFields.append(";\n"); } /** * Get the finalised bytes to go into the generated wrappers file. * * @return The bytes to be written to the wrappers file. */ - public String getWrapperFileContents() { + public byte[] getWrapperFileContents() { wrapperStartupCode.append("}\n"); - zeroingCode.append(wrapperStartupCode) - .append(wrapperMethodBodies); + wrapperStartupCode.append(wrapperMethodBodies); wrapperMethodBodies.setLength(0); - wrapperStartupCode.setLength(0); - return zeroingCode.toString(); + return wrapperStartupCode.toString().getBytes(); } /** * Get the finalised bytes to go into the generated header file. * * @return The bytes to be written to the header file. */ - public String getHeaderFileContents() { - if (!mHasEncounteredDefaultConstructor) { - headerPublic.append(" ").append(mCClassName).append("() : AutoGlobalWrappedJavaObject() {};\n"); - } - headerProtected.append("};\n\n"); - headerPublic.append(headerProtected); - headerProtected.setLength(0); - return headerPublic.toString(); + public byte[] getHeaderFileContents() { + headerFields.append('\n'); + headerFields.append(headerMethods); + headerMethods.setLength(0); + return headerFields.toString().getBytes(); } }
rename from build/annotationProcessors/AnnotationInfo.java rename to build/annotationProcessors/MethodWithAnnotationInfo.java --- a/build/annotationProcessors/AnnotationInfo.java +++ b/build/annotationProcessors/MethodWithAnnotationInfo.java @@ -1,20 +1,24 @@ /* 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 java.lang.reflect.Method; + /** - * Object holding annotation data. Used by GeneratableElementIterator. + * Object holding method and annotation. Used by GeneratableEntryPointIterator. */ -public class AnnotationInfo { +public class MethodWithAnnotationInfo { + public final Method method; public final String wrapperName; public final boolean isStatic; public final boolean isMultithreaded; - public AnnotationInfo(String aWrapperName, boolean aIsStatic, boolean aIsMultithreaded) { + public MethodWithAnnotationInfo(Method aMethod, String aWrapperName, boolean aIsStatic, boolean aIsMultithreaded) { + method = aMethod; wrapperName = aWrapperName; isStatic = aIsStatic; isMultithreaded = aIsMultithreaded; } }
deleted file mode 100644 --- a/build/annotationProcessors/classloader/AnnotatableEntity.java +++ /dev/null @@ -1,57 +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.classloader; - -import org.mozilla.gecko.annotationProcessors.AnnotationInfo; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Member; -import java.lang.reflect.Method; - -/** - * Union type to hold either a method, field, or ctor. Allows us to iterate "The generatable stuff", despite - * the fact that such things can be of either flavour. - */ -public class AnnotatableEntity { - public enum ENTITY_TYPE {METHOD, FIELD, CONSTRUCTOR} - - private final Member mMember; - public final ENTITY_TYPE mEntityType; - - public final AnnotationInfo mAnnotationInfo; - - public AnnotatableEntity(Member aObject, AnnotationInfo aAnnotationInfo) { - mMember = aObject; - mAnnotationInfo = aAnnotationInfo; - - if (aObject instanceof Method) { - mEntityType = ENTITY_TYPE.METHOD; - } else if (aObject instanceof Field) { - mEntityType = ENTITY_TYPE.FIELD; - } else { - mEntityType = ENTITY_TYPE.CONSTRUCTOR; - } - } - - public Method getMethod() { - if (mEntityType != ENTITY_TYPE.METHOD) { - throw new UnsupportedOperationException("Attempt to cast to unsupported member type."); - } - return (Method) mMember; - } - public Field getField() { - if (mEntityType != ENTITY_TYPE.FIELD) { - throw new UnsupportedOperationException("Attempt to cast to unsupported member type."); - } - return (Field) mMember; - } - public Constructor getConstructor() { - if (mEntityType != ENTITY_TYPE.CONSTRUCTOR) { - throw new UnsupportedOperationException("Attempt to cast to unsupported member type."); - } - return (Constructor) mMember; - } -}
deleted file mode 100644 --- a/build/annotationProcessors/classloader/ClassWithOptions.java +++ /dev/null @@ -1,15 +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.classloader; - -public class ClassWithOptions { - public final Class<?> wrappedClass; - public final String generatedName; - - public ClassWithOptions(Class<?> someClass, String name) { - wrappedClass = someClass; - generatedName = name; - } -}
--- a/build/annotationProcessors/classloader/IterableJarLoadingURLClassLoader.java +++ b/build/annotationProcessors/classloader/IterableJarLoadingURLClassLoader.java @@ -16,45 +16,50 @@ import java.util.jar.JarEntry; import java.util.jar.JarFile; /** * A classloader which can be initialised with a list of jar files and which can provide an iterator * over the top level classes in the jar files it was initialised with. * classNames is kept sorted to ensure iteration order is consistent across program invocations. * Otherwise, we'd forever be reporting the outdatedness of the generated code as we permute its * contents. + * This classloader does not support inner classes. (You probably shouldn't be putting JNI entry + * points in inner classes anyway) */ public class IterableJarLoadingURLClassLoader extends URLClassLoader { LinkedList<String> classNames = new LinkedList<String>(); /** * Create an instance and return its iterator. Provides an iterator over the classes in the jar * files provided as arguments. * Inner classes are not supported. * * @param args A list of jar file names an iterator over the classes of which is desired. * @return An iterator over the top level classes in the jar files provided, in arbitrary order. */ - public static Iterator<ClassWithOptions> getIteratorOverJars(String[] args) { + public static Iterator<Class<?>> getIteratorOverJars(String[] args) { URL[] urlArray = new URL[args.length]; LinkedList<String> aClassNames = new LinkedList<String>(); for (int i = 0; i < args.length; i++) { try { urlArray[i] = (new File(args[i])).toURI().toURL(); Enumeration<JarEntry> entries = new JarFile(args[i]).entries(); while (entries.hasMoreElements()) { JarEntry e = entries.nextElement(); String fName = e.getName(); if (!fName.endsWith(".class")) { continue; } final String className = fName.substring(0, fName.length() - 6).replace('/', '.'); - + // Inner classes are not supported. + if (className.contains("$")) { + continue; + } aClassNames.add(className); } } catch (IOException e) { System.err.println("Error loading jar file \"" + args[i] + '"'); e.printStackTrace(System.err); } } Collections.sort(aClassNames);
--- a/build/annotationProcessors/classloader/JarClassIterator.java +++ b/build/annotationProcessors/classloader/JarClassIterator.java @@ -1,77 +1,38 @@ /* 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.classloader; -import java.lang.annotation.Annotation; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.Iterator; /** * Class for iterating over an IterableJarLoadingURLClassLoader's classes. */ -public class JarClassIterator implements Iterator<ClassWithOptions> { +public class JarClassIterator implements Iterator<Class<?>> { private IterableJarLoadingURLClassLoader mTarget; private Iterator<String> mTargetClassListIterator; public JarClassIterator(IterableJarLoadingURLClassLoader aTarget) { mTarget = aTarget; mTargetClassListIterator = aTarget.classNames.iterator(); } @Override public boolean hasNext() { return mTargetClassListIterator.hasNext(); } @Override - public ClassWithOptions next() { + public Class<?> next() { String className = mTargetClassListIterator.next(); try { - Class<?> ret = mTarget.loadClass(className); - if (ret.getCanonicalName() == null || "null".equals(ret.getCanonicalName())) { - // Anonymous inner class - unsupported. - return next(); - } else { - String generateName = null; - for (Annotation annotation : ret.getAnnotations()) { - Class<?> annotationType = annotation.annotationType(); - if (annotationType.getCanonicalName().equals("org.mozilla.gecko.mozglue.generatorannotations.GeneratorOptions")) { - try { - // Determine the explicitly-given name of the stub to generate, if any. - final Method generateNameMethod = annotationType.getDeclaredMethod("generatedClassName"); - generateNameMethod.setAccessible(true); - generateName = (String) generateNameMethod.invoke(annotation); - break; - } catch (NoSuchMethodException e) { - System.err.println("Unable to find expected field on GeneratorOptions annotation. Did the signature change?"); - e.printStackTrace(System.err); - System.exit(3); - } catch (IllegalAccessException e) { - System.err.println("IllegalAccessException reading fields on GeneratorOptions annotation. Seems the semantics of Reflection have changed..."); - e.printStackTrace(System.err); - System.exit(4); - } catch (InvocationTargetException e) { - System.err.println("InvocationTargetException reading fields on GeneratorOptions annotation. This really shouldn't happen."); - e.printStackTrace(System.err); - System.exit(5); - } - } - } - - if (generateName == null) { - generateName = ret.getSimpleName(); - } - - return new ClassWithOptions(ret, generateName); - } + return mTarget.loadClass(className); } catch (ClassNotFoundException e) { System.err.println("Unable to enumerate class: " + className + ". Corrupted jar file?"); e.printStackTrace(); System.exit(2); } return null; }
rename from build/annotationProcessors/utils/AlphabeticAnnotatableEntityComparator.java rename to build/annotationProcessors/utils/AlphabeticMethodComparator.java --- a/build/annotationProcessors/utils/AlphabeticAnnotatableEntityComparator.java +++ b/build/annotationProcessors/utils/AlphabeticMethodComparator.java @@ -1,81 +1,28 @@ /* 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.utils; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Member; import java.lang.reflect.Method; import java.util.Comparator; -public class AlphabeticAnnotatableEntityComparator<T extends Member> implements Comparator<T> { +public class AlphabeticMethodComparator implements Comparator<Method> { @Override - public int compare(T aLhs, T aRhs) { - // Constructors, Methods, Fields. - boolean lIsConstructor = aLhs instanceof Constructor; - boolean rIsConstructor = aRhs instanceof Constructor; - boolean lIsMethod = aLhs instanceof Method; - boolean rIsField = aRhs instanceof Field; - - if (lIsConstructor) { - if (!rIsConstructor) { - return -1; - } - } else if (lIsMethod) { - if (rIsConstructor) { - return 1; - } else if (rIsField) { - return -1; - } - } else { - if (!rIsField) { - return 1; - } - } - - // Verify these objects are the same type and cast them. - if (aLhs instanceof Method) { - return compare((Method) aLhs, (Method) aRhs); - } else if (aLhs instanceof Field) { - return compare((Field) aLhs, (Field) aRhs); - } else { - return compare((Constructor) aLhs, (Constructor) aRhs); - } - } - - // Alas, the type system fails us. - private static int compare(Method aLhs, Method aRhs) { + public int compare(Method lhs, Method rhs) { // Initially, attempt to differentiate the methods be name alone.. - String lName = aLhs.getName(); - String rName = aRhs.getName(); + String lName = lhs.getName(); + String rName = rhs.getName(); int ret = lName.compareTo(rName); if (ret != 0) { return ret; } // The names were the same, so we need to compare signatures to find their uniqueness.. - lName = Utils.getTypeSignatureStringForMethod(aLhs); - rName = Utils.getTypeSignatureStringForMethod(aRhs); - - return lName.compareTo(rName); - } - - private static int compare(Constructor aLhs, Constructor aRhs) { - // The names will be the same, so we need to compare signatures to find their uniqueness.. - String lName = Utils.getTypeSignatureString(aLhs); - String rName = Utils.getTypeSignatureString(aRhs); - - return lName.compareTo(rName); - } - - private static int compare(Field aLhs, Field aRhs) { - // Compare field names.. - String lName = aLhs.getName(); - String rName = aRhs.getName(); + lName = Utils.getTypeSignatureString(lhs); + rName = Utils.getTypeSignatureString(rhs); return lName.compareTo(rName); } }
rename from build/annotationProcessors/utils/GeneratableElementIterator.java rename to build/annotationProcessors/utils/GeneratableEntryPointIterator.java --- a/build/annotationProcessors/utils/GeneratableElementIterator.java +++ b/build/annotationProcessors/utils/GeneratableEntryPointIterator.java @@ -1,84 +1,57 @@ /* 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.utils; -import org.mozilla.gecko.annotationProcessors.AnnotationInfo; -import org.mozilla.gecko.annotationProcessors.classloader.AnnotatableEntity; +import org.mozilla.gecko.annotationProcessors.MethodWithAnnotationInfo; import java.lang.annotation.Annotation; -import java.lang.reflect.AnnotatedElement; import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Member; import java.lang.reflect.Method; import java.util.Arrays; +import java.util.Collections; import java.util.Iterator; +import java.util.List; /** - * Iterator over the methods in a given method list which have the WrappedJNIMethod + * Iterator over the methods in a given method list which have the GeneratableAndroidBridgeTarget * annotation. Returns an object containing both the annotation (Which may contain interesting * parameters) and the argument. */ -public class GeneratableElementIterator implements Iterator<AnnotatableEntity> { - private final Member[] mObjects; - private AnnotatableEntity mNextReturnValue; - private int mElementIndex; - - private boolean mIterateEveryEntry; - - public GeneratableElementIterator(Class<?> aClass) { - // Get all the elements of this class as AccessibleObjects. - Member[] aMethods = aClass.getDeclaredMethods(); - Member[] aFields = aClass.getDeclaredFields(); - Member[] aCtors = aClass.getConstructors(); +public class GeneratableEntryPointIterator implements Iterator<MethodWithAnnotationInfo> { + private final Method[] mMethods; + private MethodWithAnnotationInfo mNextReturnValue; + private int mMethodIndex; - // Shove them all into one buffer. - Member[] objs = new Member[aMethods.length + aFields.length + aCtors.length]; - int offset = 0; - System.arraycopy(aMethods, 0, objs, 0, aMethods.length); - offset += aMethods.length; - System.arraycopy(aFields, 0, objs, offset, aFields.length); - offset += aFields.length; - System.arraycopy(aCtors, 0, objs, offset, aCtors.length); - - // Sort the elements to ensure determinism. - Arrays.sort(objs, new AlphabeticAnnotatableEntityComparator()); - - mObjects = objs; - - // Check for "Wrap ALL the things" flag. - for (Annotation annotation : aClass.getDeclaredAnnotations()) { - final String annotationTypeName = annotation.annotationType().getName(); - - if (annotationTypeName.equals("org.mozilla.gecko.mozglue.generatorannotations.WrapEntireClassForJNI")) { - mIterateEveryEntry = true; - break; - } - } + public GeneratableEntryPointIterator(Method[] aMethods) { + // Sort the methods into alphabetical order by name, to ensure we always iterate methods + // in the same order.. + Arrays.sort(aMethods, new AlphabeticMethodComparator()); + mMethods = aMethods; findNextValue(); } /** * Find and cache the next appropriately annotated method, plus the annotation parameter, if * one exists. Otherwise cache null, so hasNext returns false. */ private void findNextValue() { - while (mElementIndex < mObjects.length) { - Member candidateElement = mObjects[mElementIndex]; - mElementIndex++; - for (Annotation annotation : ((AnnotatedElement) candidateElement).getDeclaredAnnotations()) { - // WrappedJNIMethod has a parameter. Use Reflection to obtain it. + while (mMethodIndex < mMethods.length) { + Method candidateMethod = mMethods[mMethodIndex]; + mMethodIndex++; + for (Annotation annotation : candidateMethod.getDeclaredAnnotations()) { + // GeneratableAndroidBridgeTarget has a parameter. Use Reflection to obtain it. Class<? extends Annotation> annotationType = annotation.annotationType(); final String annotationTypeName = annotationType.getName(); - if (annotationTypeName.equals("org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI")) { + if (annotationTypeName.equals("org.mozilla.gecko.mozglue.GeneratableAndroidBridgeTarget")) { String stubName = null; boolean isStaticStub = false; boolean isMultithreadedStub = 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); @@ -88,61 +61,51 @@ public class GeneratableElementIterator staticStubMethod.setAccessible(true); isStaticStub = (Boolean) staticStubMethod.invoke(annotation); // Determine if the generated stub is to allow calls from multiple threads. final Method multithreadedStubMethod = annotationType.getDeclaredMethod("allowMultithread"); multithreadedStubMethod.setAccessible(true); isMultithreadedStub = (Boolean) multithreadedStubMethod.invoke(annotation); } catch (NoSuchMethodException e) { - System.err.println("Unable to find expected field on WrappedJNIMethod annotation. Did the signature change?"); + System.err.println("Unable to find expected field on GeneratableAndroidBridgeTarget annotation. Did the signature change?"); e.printStackTrace(System.err); System.exit(3); } catch (IllegalAccessException e) { - System.err.println("IllegalAccessException reading fields on WrappedJNIMethod annotation. Seems the semantics of Reflection have changed..."); + System.err.println("IllegalAccessException reading fields on GeneratableAndroidBridgeTarget annotation. Seems the semantics of Reflection have changed..."); e.printStackTrace(System.err); System.exit(4); } catch (InvocationTargetException e) { - System.err.println("InvocationTargetException reading fields on WrappedJNIMethod annotation. This really shouldn't happen."); + System.err.println("InvocationTargetException reading fields on GeneratableAndroidBridgeTarget annotation. This really shouldn't happen."); e.printStackTrace(System.err); System.exit(5); } - - // If the element name was not explicitly given in the annotation generate one... + // If the method name was not explicitly given in the annotation generate one... if (stubName.isEmpty()) { - String elementName = candidateElement.getName(); - stubName = elementName.substring(0, 1).toUpperCase() + elementName.substring(1); + String aMethodName = candidateMethod.getName(); + stubName = aMethodName.substring(0, 1).toUpperCase() + aMethodName.substring(1); } - AnnotationInfo annotationInfo = new AnnotationInfo(stubName, isStaticStub, isMultithreadedStub); - mNextReturnValue = new AnnotatableEntity(candidateElement, annotationInfo); + mNextReturnValue = new MethodWithAnnotationInfo(candidateMethod, stubName, isStaticStub, isMultithreadedStub); 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); - mNextReturnValue = new AnnotatableEntity(candidateElement, annotationInfo); - return; - } } mNextReturnValue = null; } @Override public boolean hasNext() { return mNextReturnValue != null; } @Override - public AnnotatableEntity next() { - AnnotatableEntity ret = mNextReturnValue; + public MethodWithAnnotationInfo next() { + MethodWithAnnotationInfo ret = mNextReturnValue; findNextValue(); return ret; } @Override public void remove() { - throw new UnsupportedOperationException("Removal of methods from GeneratableElementIterator not supported."); + throw new UnsupportedOperationException("Removal of methods from GeneratableEntryPointIterator not supported."); } }
--- a/build/annotationProcessors/utils/Utils.java +++ b/build/annotationProcessors/utils/Utils.java @@ -1,18 +1,15 @@ /* 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.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; /** * A collection of utility methods used by CodeGenerator. Largely used for translating types. */ public class Utils { @@ -68,48 +65,33 @@ public class Utils { sInstanceCallTypes.put("long", "CallLongMethod"); sInstanceCallTypes.put("double", "CallDoubleMethod"); sInstanceCallTypes.put("float", "CallFloatMethod"); sInstanceCallTypes.put("char", "CallCharMethod"); sInstanceCallTypes.put("byte", "CallByteMethod"); sInstanceCallTypes.put("short", "CallShortMethod"); } - private static final HashMap<String, String> sFieldTypes = new HashMap<String, String>(); - - static { - sFieldTypes.put("int", "Int"); - sFieldTypes.put("boolean", "Boolean"); - sFieldTypes.put("long", "Long"); - sFieldTypes.put("double", "Double"); - sFieldTypes.put("float", "Float"); - sFieldTypes.put("char", "Char"); - sFieldTypes.put("byte", "Byte"); - sFieldTypes.put("short", "Short"); - } - private static final HashMap<String, String> sFailureReturns = new HashMap<String, String>(); static { - sFailureReturns.put("java.lang.Void", ""); sFailureReturns.put("void", ""); sFailureReturns.put("int", " 0"); sFailureReturns.put("boolean", " false"); sFailureReturns.put("long", " 0"); sFailureReturns.put("double", " 0.0"); sFailureReturns.put("float", " 0.0"); sFailureReturns.put("char", " 0"); sFailureReturns.put("byte", " 0"); sFailureReturns.put("short", " 0"); } private static final HashMap<String, String> sCanonicalSignatureParts = new HashMap<String, String>(); static { - sCanonicalSignatureParts.put("java/lang/Void", "V"); sCanonicalSignatureParts.put("void", "V"); sCanonicalSignatureParts.put("int", "I"); sCanonicalSignatureParts.put("boolean", "Z"); sCanonicalSignatureParts.put("long", "J"); sCanonicalSignatureParts.put("double", "D"); sCanonicalSignatureParts.put("float", "F"); sCanonicalSignatureParts.put("char", "C"); sCanonicalSignatureParts.put("byte", "B"); @@ -177,43 +159,26 @@ public class Utils { /** * For a given Java type, get the corresponding C++ type if we're returning it from a function. * * @param type The Java return type. * @return A string representation of the C++ return type. */ public static String getCReturnType(Class<?> type) { - if (type.getCanonicalName().equals("java.lang.Void")) { - return "void"; - } + // Since there's only one thing we want to do differently... String cParameterType = getCParameterType(type); if (cParameterType.equals("const nsAString&")) { return "jstring"; } else { return cParameterType; } } /** - * Gets the type-specific part of the JNI function to use to get or set a field of a given type. - * - * @param aFieldType The Java type of the field. - * @return A string representation of the JNI call function substring to use. - */ - public static String getFieldType(Class<?> aFieldType) { - String name = aFieldType.getCanonicalName(); - - if (sFieldTypes.containsKey(name)) { - return sFieldTypes.get(name); - } - return "Object"; - } - - /** * Gets the appropriate JNI call function to use to invoke a Java method with the given return * type. This, plus a call postfix (Such as "A") forms a complete JNI call function name. * * @param aReturnType The Java return type of the method being generated. * @param isStatic Boolean indicating if the underlying Java method is declared static. * @return A string representation of the JNI call function prefix to use. */ public static String getCallPrefix(Class<?> aReturnType, boolean isStatic) { @@ -242,221 +207,158 @@ public class Utils { String name = type.getCanonicalName(); if (sFailureReturns.containsKey(name)) { return sFailureReturns.get(name); } return " nullptr"; } /** - * Helper method to get the type signature for methods, given argument and return type. - * Allows for the near-identical logic needed for constructors and methods to be shared. - * (Alas, constructor does not extend method) + * Get the canonical JNI type signature for a method. * - * @param arguments Argument types of the underlying method. - * @param returnType Return type of the underlying method. - * @return The canonical Java type string for the method. eg. (IIIIFZ)Lorg/mozilla/gecko/gfx/ViewTransform; + * @param aMethod The method to generate a signature for. + * @return The canonical JNI type signature for this method. */ - private static String getTypeSignatureInternal(Class<?>[] arguments, Class<?> returnType) { + public static String getTypeSignatureString(Method aMethod) { + Class<?>[] arguments = aMethod.getParameterTypes(); + Class<?> returnType = aMethod.getReturnType(); + 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]); } sb.append(')'); // Write the return value's signature.. writeTypeSignature(sb, returnType); return sb.toString(); } /** - * Get the canonical JNI type signature for a Field. - * - * @param aField The field to generate a signature for. - * @return The canonical JNI type signature for this method. - */ - protected static String getTypeSignatureStringForField(Field aField) { - StringBuilder sb = new StringBuilder(); - writeTypeSignature(sb, aField.getType()); - return sb.toString(); - } - - /** - * Get the canonical JNI type signature for a method. - * - * @param aMethod The method to generate a signature for. - * @return The canonical JNI type signature for this method. - */ - protected static String getTypeSignatureStringForMethod(Method aMethod) { - Class<?>[] arguments = aMethod.getParameterTypes(); - Class<?> returnType = aMethod.getReturnType(); - - return getTypeSignatureInternal(arguments, returnType); - } - - /** - * Get the canonical JNI type signature for a Constructor. - * - * @param aConstructor The Constructor to generate a signature for. - * @return The canonical JNI type signature for this method. - */ - protected static String getTypeSignatureStringForConstructor(Constructor aConstructor) { - Class<?>[] arguments = aConstructor.getParameterTypes(); - - return getTypeSignatureInternal(arguments, Void.class); - } - - public static String getTypeSignatureStringForMember(Member aMember) { - if (aMember instanceof Method) { - return getTypeSignatureStringForMethod((Method) aMember); - } else if (aMember instanceof Field) { - return getTypeSignatureStringForField((Field) aMember); - } else { - return getTypeSignatureStringForConstructor((Constructor) aMember); - } - } - - 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]); - } - - // Constructors always return Void. - sb.append(")V"); - return sb.toString(); - } - - /** - * Helper method used by getTypeSignatureStringForMethod to build the signature. Write the subsignature + * Helper method used by getTypeSignatureString 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 = 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); } - if (c.isArray()) { - c = c.getComponentType(); - } - - Class<?> containerClass = c.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); - } - // Look in the hashmap for the remainder... if (sCanonicalSignatureParts.containsKey(name)) { // It was a primitive type, so lookup was a success. sb.append(sCanonicalSignatureParts.get(name)); } else { // It was a reference type - generate. sb.append('L'); sb.append(name); sb.append(';'); } } /** * Produces a C method signature, sans semicolon, for the given Java Method. Useful for both * 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. + * @param aMethod The Java method to generate the corresponding wrapper signature for. + * @param aCMethodName The name of the generated method this is to be the signatgure for. + * @return The generated method signature. */ - public static String getCImplementationMethodSignature(Class<?>[] aArgumentTypes, Class<?> aReturnType, String aCMethodName, String aCClassName) { - StringBuilder retBuffer = new StringBuilder(); + public static String getCImplementationMethodSignature(Method aMethod, String aCMethodName) { + Class<?>[] argumentTypes = aMethod.getParameterTypes(); + Class<?> returnType = aMethod.getReturnType(); - retBuffer.append(getCReturnType(aReturnType)); - retBuffer.append(' '); - retBuffer.append(aCClassName); - retBuffer.append("::"); + StringBuilder retBuffer = new StringBuilder(); + // Write return type.. + retBuffer.append(getCReturnType(returnType)); + retBuffer.append(" AndroidBridge::"); retBuffer.append(aCMethodName); retBuffer.append('('); + // For an instance method, the first argument is the target object. + if (!isMethodStatic(aMethod)) { + retBuffer.append("jobject aTarget"); + if (argumentTypes.length > 0) { + retBuffer.append(", "); + } + } + // Write argument types... - for (int aT = 0; aT < aArgumentTypes.length; aT++) { - retBuffer.append(getCParameterType(aArgumentTypes[aT])); + for (int aT = 0; aT < argumentTypes.length; aT++) { + retBuffer.append(getCParameterType(argumentTypes[aT])); retBuffer.append(" a"); // 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) { + if (aT != argumentTypes.length - 1) { retBuffer.append(", "); } } 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. * * @param aMethod The Java method to generate the corresponding wrapper signature for. * @param aCMethodName The name of the generated method this is to be the signatgure for. * @return The generated method signature. */ - /** - * - * @param aArgumentTypes Argument types of the Java method being wrapped. - * @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) { + public static String getCHeaderMethodSignature(Method aMethod, String aCMethodName, boolean aIsStaticStub) { + Class<?>[] argumentTypes = aMethod.getParameterTypes(); + + // The annotations on the parameters of this method, in declaration order. + // Importantly - the same order as those in argumentTypes. + Annotation[][] argumentAnnotations = aMethod.getParameterAnnotations(); + Class<?> returnType = aMethod.getReturnType(); + StringBuilder retBuffer = new StringBuilder(); // Add the static keyword, if applicable. if (aIsStaticStub) { retBuffer.append("static "); } // Write return type.. - retBuffer.append(getCReturnType(aReturnType)); + retBuffer.append(getCReturnType(returnType)); retBuffer.append(' '); retBuffer.append(aCMethodName); retBuffer.append('('); + // For an instance method, the first argument is the target object. + if (!isMethodStatic(aMethod)) { + retBuffer.append("jobject aTarget"); + if (argumentTypes.length > 0) { + retBuffer.append(", "); + } + } + // Write argument types... - for (int aT = 0; aT < aArgumentTypes.length; aT++) { - retBuffer.append(getCParameterType(aArgumentTypes[aT])); + for (int aT = 0; aT < argumentTypes.length; aT++) { + retBuffer.append(getCParameterType(argumentTypes[aT])); retBuffer.append(" a"); // 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); // Append the default value, if there is one.. - retBuffer.append(getDefaultValueString(aArgumentTypes[aT], aArgumentAnnotations[aT])); + retBuffer.append(getDefaultValueString(argumentTypes[aT], argumentAnnotations[aT])); - if (aT != aArgumentTypes.length - 1) { + if (aT != argumentTypes.length - 1) { retBuffer.append(", "); } } retBuffer.append(')'); return retBuffer.toString(); } /** @@ -468,17 +370,17 @@ public class Utils { * @param aArgumentAnnotations The annotations on the argument to consider. * @return An appropriate string to append to the signature of this argument assigning it to a * default value (Or not, as applicable). */ public static String getDefaultValueString(Class<?> aArgumentType, Annotation[] aArgumentAnnotations) { for (int i = 0; i < aArgumentAnnotations.length; i++) { Class<? extends Annotation> annotationType = aArgumentAnnotations[i].annotationType(); final String annotationTypeName = annotationType.getName(); - if (annotationTypeName.equals("org.mozilla.gecko.mozglue.generatorannotations.OptionalGeneratedParameter")) { + if (annotationTypeName.equals("org.mozilla.gecko.mozglue.OptionalGeneratedParameter")) { return " = " + getDefaultParameterValueForType(aArgumentType); } } return ""; } /** * Helper method to return an appropriate default parameter value for an argument of a given type. @@ -498,23 +400,24 @@ public class Utils { } else { return "nullptr"; } } /** * Helper method that returns the number of reference types in the arguments of m. * - * @param aArgs The method arguments to consider. + * @param m The method to consider. * @return How many of the arguments of m are nonprimitive. */ - public static int enumerateReferenceArguments(Class<?>[] aArgs) { + public static int enumerateReferenceArguments(Method m) { int ret = 0; - for (int i = 0; i < aArgs.length; i++) { - String name = aArgs[i].getCanonicalName(); + Class<?>[] args = m.getParameterTypes(); + for (int i = 0; i < args.length; i++) { + String name = args[i].getCanonicalName(); if (!sBasicCTypes.containsKey(name)) { ret++; } } return ret; } /** @@ -544,33 +447,35 @@ public class Utils { StringBuilder sb = new StringBuilder(); String name = type.getCanonicalName(); if (sCanonicalSignatureParts.containsKey(name)) { sb.append(sCanonicalSignatureParts.get(name).toLowerCase()); sb.append(" = ").append(argName).append(";\n"); } else { if (isCharSequence(type)) { - sb.append("l = AndroidBridge::NewJavaString(env, ").append(argName).append(");\n"); + sb.append("l = NewJavaString(env, ").append(argName).append(");\n"); } else { sb.append("l = ").append(argName).append(";\n"); } } return sb.toString(); } /** - * Returns true if the type provided is an object type. Returns false otherwise + * Returns true if the method provided returns an object type. Returns false if it returns a + * primitive type. * - * @param aType The type to consider. - * @return true if the method provided is an object type, false otherwise. + * @param aMethod The method to consider. + * @return true if the method provided returns an object type, false otherwise. */ - public static boolean isObjectType(Class<?> aType) { - return !sBasicCTypes.containsKey(aType.getCanonicalName()); + public static boolean doesReturnObjectType(Method aMethod) { + Class<?> returnType = aMethod.getReturnType(); + return !sBasicCTypes.containsKey(returnType.getCanonicalName()); } /** * For a given Java class, get the name of the value in C++ which holds a reference to it. * * @param aClass Target Java class. * @return The name of the C++ jclass entity referencing the given class. */ @@ -585,26 +490,17 @@ 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(" = getClassGlobalRef(\""); - - 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); + sb.append(aClass.getCanonicalName().replaceAll("\\.", "/")); sb.append("\");\n"); return sb.toString(); } /** * Helper method to determine if this object implements CharSequence * @param aClass Class to check for CharSequence-esqueness * @return True if the given class implements CharSequence, false otherwise. @@ -619,26 +515,16 @@ public class Utils { return true; } } return false; } /** * Helper method to read the modifier bits of the given method to determine if it is static. - * @param aMember The Member to check. + * @param aMethod The Method to check. * @return true of the method is declared static, false otherwise. */ - public static boolean isMemberStatic(Member aMember) { - int aMethodModifiers = aMember.getModifiers(); + public static boolean isMethodStatic(Method aMethod) { + int aMethodModifiers = aMethod.getModifiers(); return Modifier.isStatic(aMethodModifiers); } - - /** - * Helper method to read the modifier bits of the given method to determine if it is static. - * @param aMember The Member to check. - * @return true of the method is declared static, false otherwise. - */ - public static boolean isMemberFinal(Member aMember) { - int aMethodModifiers = aMember.getModifiers(); - return Modifier.isFinal(aMethodModifiers); - } }
--- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -1554,18 +1554,18 @@ ContentParent::RecvGetIconForExtension(c bool ContentParent::RecvGetShowPasswordSetting(bool* showPassword) { // default behavior is to show the last password character *showPassword = true; #ifdef MOZ_WIDGET_ANDROID NS_ASSERTION(AndroidBridge::Bridge() != nullptr, "AndroidBridge is not available"); - - *showPassword = GeckoAppShell::GetShowPasswordSetting(); + if (AndroidBridge::Bridge() != nullptr) + *showPassword = AndroidBridge::Bridge()->GetShowPasswordSetting(); #endif return true; } bool ContentParent::RecvFirstIdle() { // When the ContentChild goes idle, it sends us a FirstIdle message which we
--- a/dom/plugins/base/nsNPAPIPlugin.cpp +++ b/dom/plugins/base/nsNPAPIPlugin.cpp @@ -2255,17 +2255,21 @@ NPError NP_CALLBACK case kSupportedDrawingModel_ANPGetValue: { LOG("get supported drawing model"); uint32_t* bits = reinterpret_cast<uint32_t*>(result); *bits = kBitmap_ANPDrawingModel && kSurface_ANPDrawingModel; return NPERR_NO_ERROR; } case kJavaContext_ANPGetValue: { - jobject ret = GeckoAppShell::GetContext(); + AndroidBridge *bridge = AndroidBridge::Bridge(); + if (!bridge) + return NPERR_GENERIC_ERROR; + + jobject ret = bridge->GetContext(); if (!ret) return NPERR_GENERIC_ERROR; int32_t* i = reinterpret_cast<int32_t*>(result); *i = reinterpret_cast<int32_t>(ret); return NPERR_NO_ERROR; }
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp +++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp @@ -860,17 +860,17 @@ void nsNPAPIPluginInstance::NotifyFullSc if (RUNNING != mRunning || mFullScreen == aFullScreen) return; mFullScreen = aFullScreen; SendLifecycleEvent(this, mFullScreen ? kEnterFullScreen_ANPLifecycleAction : kExitFullScreen_ANPLifecycleAction); if (mFullScreen && mFullScreenOrientation != dom::eScreenOrientation_None) { - GeckoAppShell::LockScreenOrientation(mFullScreenOrientation); + AndroidBridge::Bridge()->LockScreenOrientation(mFullScreenOrientation); } } void nsNPAPIPluginInstance::NotifySize(nsIntSize size) { if (kOpenGL_ANPDrawingModel != GetANPDrawingModel() || size == mCurrentSize) return; @@ -917,21 +917,21 @@ void nsNPAPIPluginInstance::SetFullScree uint32_t oldOrientation = mFullScreenOrientation; mFullScreenOrientation = orientation; if (mFullScreen) { // We're already fullscreen so immediately apply the orientation change if (mFullScreenOrientation != dom::eScreenOrientation_None) { - GeckoAppShell::LockScreenOrientation(mFullScreenOrientation); + AndroidBridge::Bridge()->LockScreenOrientation(mFullScreenOrientation); } else if (oldOrientation != dom::eScreenOrientation_None) { // We applied an orientation when we entered fullscreen, but // we don't want it anymore - GeckoAppShell::UnlockScreenOrientation(); + AndroidBridge::Bridge()->UnlockScreenOrientation(); } } } void nsNPAPIPluginInstance::PopPostedEvent(PluginEventRunnable* r) { mPostedEvents.RemoveElement(r); }
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -1653,17 +1653,19 @@ bool nsPluginInstanceOwner::AddPluginVie return true; } void nsPluginInstanceOwner::RemovePluginView() { if (!mInstance || !mJavaView) return; - GeckoAppShell::RemovePluginView((jobject)mJavaView, mFullScreen); + if (AndroidBridge::Bridge()) + AndroidBridge::Bridge()->RemovePluginView((jobject)mJavaView, mFullScreen); + AndroidBridge::GetJNIEnv()->DeleteGlobalRef((jobject)mJavaView); mJavaView = nullptr; if (mFullScreen) sFullScreenInstance = nullptr; } void nsPluginInstanceOwner::GetVideos(nsTArray<nsNPAPIPluginInstance::VideoInfo*>& aVideos)
--- a/dom/system/android/AndroidLocationProvider.cpp +++ b/dom/system/android/AndroidLocationProvider.cpp @@ -21,34 +21,40 @@ AndroidLocationProvider::AndroidLocation AndroidLocationProvider::~AndroidLocationProvider() { NS_IF_RELEASE(gLocationCallback); } NS_IMETHODIMP AndroidLocationProvider::Startup() { - GeckoAppShell::EnableLocation(true); + if (!AndroidBridge::Bridge()) + return NS_ERROR_NOT_IMPLEMENTED; + AndroidBridge::Bridge()->EnableLocation(true); return NS_OK; } NS_IMETHODIMP AndroidLocationProvider::Watch(nsIGeolocationUpdate* aCallback) { NS_IF_RELEASE(gLocationCallback); gLocationCallback = aCallback; NS_IF_ADDREF(gLocationCallback); return NS_OK; } NS_IMETHODIMP AndroidLocationProvider::Shutdown() { - GeckoAppShell::EnableLocation(false); + if (!AndroidBridge::Bridge()) + return NS_ERROR_NOT_IMPLEMENTED; + AndroidBridge::Bridge()->EnableLocation(false); return NS_OK; } NS_IMETHODIMP AndroidLocationProvider::SetHighAccuracy(bool enable) { - GeckoAppShell::EnableLocationHighAccuracy(enable); + if (!AndroidBridge::Bridge()) + return NS_ERROR_NOT_IMPLEMENTED; + AndroidBridge::Bridge()->EnableLocationHighAccuracy(enable); return NS_OK; }
--- a/dom/system/android/nsHapticFeedback.cpp +++ b/dom/system/android/nsHapticFeedback.cpp @@ -9,11 +9,15 @@ using namespace mozilla; NS_IMPL_ISUPPORTS1(nsHapticFeedback, nsIHapticFeedback) NS_IMETHODIMP nsHapticFeedback::PerformSimpleAction(int32_t aType) { - GeckoAppShell::PerformHapticFeedback(aType == LongPress); - return NS_OK; + AndroidBridge* bridge = AndroidBridge::Bridge(); + if (bridge) { + bridge->PerformHapticFeedback(aType == LongPress); + return NS_OK; + } + return NS_ERROR_FAILURE; }
--- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -2413,17 +2413,17 @@ public: #ifdef MOZ_WIDGET_GONK virtual EGLImage CreateEGLImageForNativeBuffer(void* buffer) = 0; virtual void DestroyEGLImage(EGLImage image) = 0; virtual EGLImage GetNullEGLImage() = 0; #endif virtual already_AddRefed<TextureImage> - CreateDirectTextureImage(::android::GraphicBuffer* aBuffer, GLenum aWrapMode) + CreateDirectTextureImage(android::GraphicBuffer* aBuffer, GLenum aWrapMode) { return nullptr; } // Before reads from offscreen texture void GuaranteeResolve(); protected: GLuint mTexBlit_Buffer; GLuint mTexBlit_VertShader;
--- a/gfx/thebes/nsSurfaceTexture.cpp +++ b/gfx/thebes/nsSurfaceTexture.cpp @@ -205,17 +205,17 @@ nsSurfaceTexture::~nsSurfaceTexture() mNativeWindow = nullptr; } JNIEnv* env = GetJNIForThread(); if (!env) return; if (mSurfaceTexture && env) { - GeckoAppShell::UnregisterSurfaceTextureFrameListener(mSurfaceTexture); + AndroidBridge::Bridge()->UnregisterSurfaceTextureFrameListener(mSurfaceTexture); env->DeleteGlobalRef(mSurfaceTexture); mSurfaceTexture = nullptr; } } void* nsSurfaceTexture::GetNativeWindow() @@ -234,19 +234,19 @@ nsSurfaceTexture::GetTransformMatrix(gfx { return sJNIFunctions.GetTransformMatrix(mSurfaceTexture, aMatrix); } void nsSurfaceTexture::SetFrameAvailableCallback(nsIRunnable* aRunnable) { if (aRunnable) - GeckoAppShell::RegisterSurfaceTextureFrameListener(mSurfaceTexture, mID); + AndroidBridge::Bridge()->RegisterSurfaceTextureFrameListener(mSurfaceTexture, mID); else - GeckoAppShell::UnregisterSurfaceTextureFrameListener(mSurfaceTexture); + AndroidBridge::Bridge()->UnregisterSurfaceTextureFrameListener(mSurfaceTexture); mFrameAvailableCallback = aRunnable; } void nsSurfaceTexture::NotifyFrameAvailable() { if (mFrameAvailableCallback) {
--- a/hal/android/AndroidHal.cpp +++ b/hal/android/AndroidHal.cpp @@ -9,17 +9,16 @@ #include "AndroidBridge.h" #include "mozilla/dom/network/Constants.h" #include "mozilla/dom/ScreenOrientation.h" #include "nsIScreenManager.h" #include "nsServiceManagerUtils.h" using namespace mozilla::dom; using namespace mozilla::hal; -using namespace mozilla::widget::android; namespace mozilla { namespace hal_impl { void Vibrate(const nsTArray<uint32_t> &pattern, const WindowIdentifier &) { // Ignore the WindowIdentifier parameter; it's here only because hal::Vibrate, @@ -50,65 +49,107 @@ Vibrate(const nsTArray<uint32_t> &patter b->Vibrate(pattern); } void CancelVibrate(const WindowIdentifier &) { // Ignore WindowIdentifier parameter. - GeckoAppShell::CancelVibrate(); + AndroidBridge* b = AndroidBridge::Bridge(); + if (b) + b->CancelVibrate(); } void EnableBatteryNotifications() { - GeckoAppShell::EnableBatteryNotifications(); + AndroidBridge* bridge = AndroidBridge::Bridge(); + if (!bridge) { + return; + } + + bridge->EnableBatteryNotifications(); } void DisableBatteryNotifications() { - GeckoAppShell::DisableBatteryNotifications(); + AndroidBridge* bridge = AndroidBridge::Bridge(); + if (!bridge) { + return; + } + + bridge->DisableBatteryNotifications(); } void GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo) { - AndroidBridge::Bridge()->GetCurrentBatteryInformation(aBatteryInfo); + AndroidBridge* bridge = AndroidBridge::Bridge(); + if (!bridge) { + return; + } + + bridge->GetCurrentBatteryInformation(aBatteryInfo); } void EnableNetworkNotifications() { - GeckoAppShell::EnableNetworkNotifications(); + AndroidBridge* bridge = AndroidBridge::Bridge(); + if (!bridge) { + return; + } + + bridge->EnableNetworkNotifications(); } void DisableNetworkNotifications() { - GeckoAppShell::DisableNetworkNotifications(); + AndroidBridge* bridge = AndroidBridge::Bridge(); + if (!bridge) { + return; + } + + bridge->DisableNetworkNotifications(); } void GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInfo) { - AndroidBridge::Bridge()->GetCurrentNetworkInformation(aNetworkInfo); + AndroidBridge* bridge = AndroidBridge::Bridge(); + if (!bridge) { + return; + } + + bridge->GetCurrentNetworkInformation(aNetworkInfo); } void EnableScreenConfigurationNotifications() { - GeckoAppShell::EnableScreenOrientationNotifications(); + AndroidBridge* bridge = AndroidBridge::Bridge(); + if (!bridge) { + return; + } + + bridge->EnableScreenOrientationNotifications(); } void DisableScreenConfigurationNotifications() { - GeckoAppShell::DisableScreenOrientationNotifications(); + AndroidBridge* bridge = AndroidBridge::Bridge(); + if (!bridge) { + return; + } + + bridge->DisableScreenOrientationNotifications(); } void GetCurrentScreenConfiguration(ScreenConfiguration* aScreenConfiguration) { AndroidBridge* bridge = AndroidBridge::Bridge(); if (!bridge) { return; @@ -135,32 +176,42 @@ GetCurrentScreenConfiguration(ScreenConf *aScreenConfiguration = hal::ScreenConfiguration(rect, orientation, colorDepth, pixelDepth); } bool LockScreenOrientation(const ScreenOrientation& aOrientation) { + AndroidBridge* bridge = AndroidBridge::Bridge(); + if (!bridge) { + return false; + } + switch (aOrientation) { // The Android backend only supports these orientations. case eScreenOrientation_PortraitPrimary: case eScreenOrientation_PortraitSecondary: case eScreenOrientation_PortraitPrimary | eScreenOrientation_PortraitSecondary: case eScreenOrientation_LandscapePrimary: case eScreenOrientation_LandscapeSecondary: case eScreenOrientation_LandscapePrimary | eScreenOrientation_LandscapeSecondary: - GeckoAppShell::LockScreenOrientation(aOrientation); + bridge->LockScreenOrientation(aOrientation); return true; default: return false; } } void UnlockScreenOrientation() { - GeckoAppShell::UnlockScreenOrientation(); + AndroidBridge* bridge = AndroidBridge::Bridge(); + if (!bridge) { + return; + } + + bridge->UnlockScreenOrientation(); } } // hal_impl } // mozilla
--- a/hal/android/AndroidSensor.cpp +++ b/hal/android/AndroidSensor.cpp @@ -8,18 +8,18 @@ using namespace mozilla::hal; namespace mozilla { namespace hal_impl { void EnableSensorNotifications(SensorType aSensor) { - GeckoAppShell::EnableSensor(aSensor); + AndroidBridge::Bridge()->EnableSensor(aSensor); } void DisableSensorNotifications(SensorType aSensor) { - GeckoAppShell::DisableSensor(aSensor); + AndroidBridge::Bridge()->DisableSensor(aSensor); } } // hal_impl } // mozilla
--- a/ipc/glue/MessagePump.cpp +++ b/ipc/glue/MessagePump.cpp @@ -86,17 +86,17 @@ MessagePump::Run(MessagePump::Delegate* // here. To ensure that MessageLoop tasks and XPCOM events have // equal priority, we sensitively rely on processing exactly one // Task per DoWorkRunnable XPCOM event. #ifdef MOZ_WIDGET_ANDROID // This processes messages in the Android Looper. Note that we only // get here if the normal Gecko event loop has been awoken above. // Bug 750713 - did_work |= GeckoAppShell::PumpMessageLoop(); + did_work |= AndroidBridge::Bridge()->PumpMessageLoop(); #endif did_work |= aDelegate->DoDelayedWork(&delayed_work_time_); if (did_work && delayed_work_time_.is_null()) mDelayedWorkTimer->Cancel(); if (!keep_running_)
--- a/mobile/android/base/GeckoAppShell.java +++ b/mobile/android/base/GeckoAppShell.java @@ -6,18 +6,18 @@ package org.mozilla.gecko; import org.mozilla.gecko.gfx.BitmapUtils; import org.mozilla.gecko.gfx.GeckoLayerClient; import org.mozilla.gecko.gfx.GfxInfoThread; import org.mozilla.gecko.gfx.LayerView; import org.mozilla.gecko.gfx.PanZoomController; import org.mozilla.gecko.mozglue.GeckoLoader; -import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; -import org.mozilla.gecko.mozglue.generatorannotations.OptionalGeneratedParameter; +import org.mozilla.gecko.mozglue.GeneratableAndroidBridgeTarget; +import org.mozilla.gecko.mozglue.OptionalGeneratedParameter; import org.mozilla.gecko.util.EventDispatcher; import org.mozilla.gecko.util.GeckoEventListener; import org.mozilla.gecko.util.HardwareUtils; import org.mozilla.gecko.util.ThreadUtils; import android.app.Activity; import android.app.ActivityManager; import android.app.PendingIntent; @@ -368,33 +368,33 @@ public class GeckoAppShell } // Tell the Gecko event loop that an event is available. public static native void notifyGeckoOfEvent(GeckoEvent event); /* * The Gecko-side API: API methods that Gecko calls */ - @WrapElementForJNI(generateStatic = true) + @GeneratableAndroidBridgeTarget(generateStatic = true) public static void notifyIME(int type) { if (mEditableListener != null) { mEditableListener.notifyIME(type); } } - @WrapElementForJNI(generateStatic = true) + @GeneratableAndroidBridgeTarget(generateStatic = true) public static void notifyIMEContext(int state, String typeHint, String modeHint, String actionHint) { if (mEditableListener != null) { mEditableListener.notifyIMEContext(state, typeHint, modeHint, actionHint); } } - @WrapElementForJNI(generateStatic = true) + @GeneratableAndroidBridgeTarget(generateStatic = true) public static void notifyIMEChange(String text, int start, int end, int newEnd) { if (newEnd < 0) { // Selection change mEditableListener.onSelectionChange(start, end); } else { // Text change mEditableListener.onTextChange(text, start, end, newEnd); } } @@ -428,17 +428,17 @@ public class GeckoAppShell } long waited = SystemClock.uptimeMillis() - time; Log.d(LOGTAG, "Gecko event sync taking too long: " + waited + "ms"); } } } // Signal the Java thread that it's time to wake up - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void acknowledgeEvent() { synchronized (sEventAckLock) { sWaitingForEventAck = false; sEventAckLock.notifyAll(); } } private static float getLocationAccuracy(Location location) { @@ -467,17 +467,17 @@ public class GeckoAppShell getLocationAccuracy(location) < getLocationAccuracy(lastKnownLocation))) { lastKnownLocation = location; } } return lastKnownLocation; } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void enableLocation(final boolean enable) { ThreadUtils.postToUiThread(new Runnable() { @Override public void run() { LocationManager lm = getLocationManager(getContext()); if (lm == null) { return; } @@ -523,22 +523,22 @@ public class GeckoAppShell // which allows enabling/disabling location update notifications from the cell radio. // CONTROL_LOCATION_UPDATES is not for use by normal applications, but we might be // hitting this problem if the Tegras are confused about missing cell radios. Log.e(LOGTAG, "LOCATION_SERVICE not found?!", e); return null; } } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void enableLocationHighAccuracy(final boolean enable) { mLocationHighAccuracy = enable; } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void enableSensor(int aSensortype) { GeckoInterface gi = getGeckoInterface(); if (gi == null) return; SensorManager sm = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE); switch(aSensortype) { @@ -583,17 +583,17 @@ public class GeckoAppShell if (gGyroscopeSensor != null) sm.registerListener(gi.getSensorEventListener(), gGyroscopeSensor, sDefaultSensorHint); break; default: Log.w(LOGTAG, "Error! Can't enable unknown SENSOR type " + aSensortype); } } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void disableSensor(int aSensortype) { GeckoInterface gi = getGeckoInterface(); if (gi == null) return; SensorManager sm = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE); @@ -627,44 +627,44 @@ public class GeckoAppShell if (gGyroscopeSensor != null) sm.unregisterListener(gi.getSensorEventListener(), gGyroscopeSensor); break; default: Log.w(LOGTAG, "Error! Can't disable unknown SENSOR type " + aSensortype); } } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void moveTaskToBack() { if (getGeckoInterface() != null) getGeckoInterface().getActivity().moveTaskToBack(true); } public static void returnIMEQueryResult(String result, int selectionStart, int selectionLength) { // This method may be called from JNI to report Gecko's current selection indexes, but // Native Fennec doesn't care because the Java code already knows the selection indexes. } - @WrapElementForJNI(stubName = "NotifyXreExit") + @GeneratableAndroidBridgeTarget(stubName = "NotifyXreExit") static void onXreExit() { // The launch state can only be Launched or GeckoRunning at this point GeckoThread.setLaunchState(GeckoThread.LaunchState.GeckoExiting); if (getGeckoInterface() != null) { if (gRestartScheduled) { getGeckoInterface().doRestart(); } else { getGeckoInterface().getActivity().finish(); } } Log.d(LOGTAG, "Killing via System.exit()"); System.exit(0); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget static void scheduleRestart() { gRestartScheduled = true; } public static File preInstallWebApp(String aTitle, String aURI, String aOrigin) { int index = WebAppAllocator.getInstance(getContext()).findAndAllocateIndex(aOrigin, aTitle, (String) null); GeckoProfile profile = GeckoProfile.get(getContext(), "webapp" + index); return profile.getDir(); @@ -697,17 +697,17 @@ public class GeckoAppShell intent.setData(Uri.parse(aURI)); intent.setClassName(AppConstants.ANDROID_PACKAGE_NAME, AppConstants.ANDROID_PACKAGE_NAME + ".WebApps$WebApp" + aIndex); return intent; } // "Installs" an application by creating a shortcut // This is the entry point from AndroidBridge.h - @WrapElementForJNI + @GeneratableAndroidBridgeTarget static void createShortcut(String aTitle, String aURI, String aIconData, String aType) { if ("webapp".equals(aType)) { Log.w(LOGTAG, "createShortcut with no unique URI should not be used for aType = webapp!"); } createShortcut(aTitle, aURI, aURI, aIconData, aType); } @@ -892,25 +892,25 @@ public class GeckoAppShell halfSize - sHeight, halfSize + sWidth, halfSize + sHeight), null); return bitmap; } - @WrapElementForJNI(stubName = "GetHandlersForMimeTypeWrapper") + @GeneratableAndroidBridgeTarget(stubName = "GetHandlersForMimeTypeWrapper") static String[] getHandlersForMimeType(String aMimeType, String aAction) { Intent intent = getIntentForActionString(aAction); if (aMimeType != null && aMimeType.length() > 0) intent.setType(aMimeType); return getHandlersForIntent(intent); } - @WrapElementForJNI(stubName = "GetHandlersForURLWrapper") + @GeneratableAndroidBridgeTarget(stubName = "GetHandlersForURLWrapper") static String[] getHandlersForURL(String aURL, String aAction) { // aURL may contain the whole URL or just the protocol Uri uri = aURL.indexOf(':') >= 0 ? Uri.parse(aURL) : new Uri.Builder().scheme(aURL).build(); Intent intent = getOpenURIIntent(getContext(), uri.toString(), "", TextUtils.isEmpty(aAction) ? Intent.ACTION_VIEW : aAction, ""); return getHandlersForIntent(intent); @@ -943,22 +943,22 @@ public class GeckoAppShell static Intent getIntentForActionString(String aAction) { // Default to the view action if no other action as been specified. if (TextUtils.isEmpty(aAction)) { return new Intent(Intent.ACTION_VIEW); } return new Intent(aAction); } - @WrapElementForJNI(stubName = "GetExtensionFromMimeTypeWrapper") + @GeneratableAndroidBridgeTarget(stubName = "GetExtensionFromMimeTypeWrapper") static String getExtensionFromMimeType(String aMimeType) { return MimeTypeMap.getSingleton().getExtensionFromMimeType(aMimeType); } - @WrapElementForJNI(stubName = "GetMimeTypeFromExtensionsWrapper") + @GeneratableAndroidBridgeTarget(stubName = "GetMimeTypeFromExtensionsWrapper") static String getMimeTypeFromExtensions(String aFileExt) { StringTokenizer st = new StringTokenizer(aFileExt, ".,; "); String type = null; String subType = null; while (st.hasMoreElements()) { String ext = st.nextToken(); String mt = getMimeTypeFromExtension(ext); if (mt == null) @@ -1081,17 +1081,17 @@ public class GeckoAppShell * * @param targetURI the string spec of the URI to open. * @param mimeType an optional MIME type string. * @param action an Android action specifier, such as * <code>Intent.ACTION_SEND</code>. * @param title the title to use in <code>ACTION_SEND</code> intents. * @return true if the activity started successfully; false otherwise. */ - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static boolean openUriExternal(String targetURI, String mimeType, @OptionalGeneratedParameter String packageName, @OptionalGeneratedParameter String className, @OptionalGeneratedParameter String action, @OptionalGeneratedParameter String title) { final Context context = getContext(); final Intent intent = getOpenURIIntent(context, targetURI, @@ -1267,17 +1267,17 @@ public class GeckoAppShell public static void setNotificationClient(NotificationClient client) { if (sNotificationClient == null) { sNotificationClient = client; } else { Log.d(LOGTAG, "Notification client already set"); } } - @WrapElementForJNI(stubName = "ShowAlertNotificationWrapper") + @GeneratableAndroidBridgeTarget(stubName = "ShowAlertNotificationWrapper") public static void showAlertNotification(String aImageUrl, String aAlertTitle, String aAlertText, String aAlertCookie, String aAlertName) { // The intent to launch when the user clicks the expanded notification String app = getContext().getClass().getName(); Intent notificationIntent = new Intent(GeckoApp.ACTION_ALERT_CALLBACK); notificationIntent.setClassName(AppConstants.ANDROID_PACKAGE_NAME, app); notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); @@ -1294,23 +1294,23 @@ public class GeckoAppShell getContext(), 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); mAlertCookies.put(aAlertName, aAlertCookie); callObserver(aAlertName, "alertshow", aAlertCookie); sNotificationClient.add(notificationID, aImageUrl, aAlertTitle, aAlertText, contentIntent); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void alertsProgressListener_OnProgress(String aAlertName, long aProgress, long aProgressMax, String aAlertText) { int notificationID = aAlertName.hashCode(); sNotificationClient.update(notificationID, aProgress, aProgressMax, aAlertText); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void closeNotification(String aAlertName) { String alertCookie = mAlertCookies.get(aAlertName); if (alertCookie != null) { callObserver(aAlertName, "alertfinished", alertCookie); mAlertCookies.remove(aAlertName); } removeObserver(aAlertName); @@ -1328,26 +1328,26 @@ public class GeckoAppShell if (sNotificationClient.isOngoing(notificationID)) { // When clicked, keep the notification if it displays progress return; } } closeNotification(aAlertName); } - @WrapElementForJNI(stubName = "GetDpiWrapper") + @GeneratableAndroidBridgeTarget(stubName = "GetDpiWrapper") public static int getDpi() { if (sDensityDpi == 0) { sDensityDpi = getContext().getResources().getDisplayMetrics().densityDpi; } return sDensityDpi; } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget() public static float getDensity() { return getContext().getResources().getDisplayMetrics().density; } private static boolean isHighMemoryDevice() { BufferedReader br = null; FileReader fr = null; try { @@ -1372,17 +1372,17 @@ public class GeckoAppShell } return false; } /** * Returns the colour depth of the default screen. This will either be * 24 or 16. */ - @WrapElementForJNI(stubName = "GetScreenDepthWrapper") + @GeneratableAndroidBridgeTarget(stubName = "GetScreenDepthWrapper") public static synchronized int getScreenDepth() { if (sScreenDepth == 0) { sScreenDepth = 16; PixelFormat info = new PixelFormat(); PixelFormat.getPixelFormatInfo(getGeckoInterface().getActivity().getWindowManager().getDefaultDisplay().getPixelFormat(), info); if (info.bitsPerPixel >= 24 && isHighMemoryDevice()) { sScreenDepth = 24; } @@ -1395,133 +1395,133 @@ public class GeckoAppShell if (sScreenDepth != 0) { Log.e(LOGTAG, "Tried to override screen depth after it's already been set"); return; } sScreenDepth = aScreenDepth; } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void setFullScreen(boolean fullscreen) { if (getGeckoInterface() != null) getGeckoInterface().setFullScreen(fullscreen); } - @WrapElementForJNI(stubName = "ShowFilePickerForExtensionsWrapper") + @GeneratableAndroidBridgeTarget(stubName = "ShowFilePickerForExtensionsWrapper") public static String showFilePickerForExtensions(String aExtensions) { if (getGeckoInterface() != null) return sActivityHelper.showFilePicker(getGeckoInterface().getActivity(), getMimeTypeFromExtensions(aExtensions)); return ""; } - @WrapElementForJNI(stubName = "ShowFilePickerForMimeTypeWrapper") + @GeneratableAndroidBridgeTarget(stubName = "ShowFilePickerForMimeTypeWrapper") public static String showFilePickerForMimeType(String aMimeType) { if (getGeckoInterface() != null) return sActivityHelper.showFilePicker(getGeckoInterface().getActivity(), aMimeType); return ""; } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void performHapticFeedback(boolean aIsLongPress) { // Don't perform haptic feedback if a vibration is currently playing, // because the haptic feedback will nuke the vibration. if (!sVibrationMaybePlaying || System.nanoTime() >= sVibrationEndTime) { LayerView layerView = getLayerView(); layerView.performHapticFeedback(aIsLongPress ? HapticFeedbackConstants.LONG_PRESS : HapticFeedbackConstants.VIRTUAL_KEY); } } private static Vibrator vibrator() { LayerView layerView = getLayerView(); return (Vibrator) layerView.getContext().getSystemService(Context.VIBRATOR_SERVICE); } - @WrapElementForJNI(stubName = "Vibrate1") + @GeneratableAndroidBridgeTarget(stubName = "Vibrate1") public static void vibrate(long milliseconds) { sVibrationEndTime = System.nanoTime() + milliseconds * 1000000; sVibrationMaybePlaying = true; vibrator().vibrate(milliseconds); } - @WrapElementForJNI(stubName = "VibrateA") + @GeneratableAndroidBridgeTarget(stubName = "VibrateA") public static void vibrate(long[] pattern, int repeat) { // If pattern.length is even, the last element in the pattern is a // meaningless delay, so don't include it in vibrationDuration. long vibrationDuration = 0; int iterLen = pattern.length - (pattern.length % 2 == 0 ? 1 : 0); for (int i = 0; i < iterLen; i++) { vibrationDuration += pattern[i]; } sVibrationEndTime = System.nanoTime() + vibrationDuration * 1000000; sVibrationMaybePlaying = true; vibrator().vibrate(pattern, repeat); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void cancelVibrate() { sVibrationMaybePlaying = false; sVibrationEndTime = 0; vibrator().cancel(); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void showInputMethodPicker() { InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.showInputMethodPicker(); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void setKeepScreenOn(final boolean on) { ThreadUtils.postToUiThread(new Runnable() { @Override public void run() { // TODO } }); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void notifyDefaultPrevented(final boolean defaultPrevented) { ThreadUtils.postToUiThread(new Runnable() { @Override public void run() { LayerView view = getLayerView(); PanZoomController controller = (view == null ? null : view.getPanZoomController()); if (controller != null) { controller.notifyDefaultActionPrevented(defaultPrevented); } } }); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static boolean isNetworkLinkUp() { ConnectivityManager cm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info = cm.getActiveNetworkInfo(); if (info == null || !info.isConnected()) return false; return true; } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static boolean isNetworkLinkKnown() { ConnectivityManager cm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); if (cm.getActiveNetworkInfo() == null) return false; return true; } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void setSelectedLocale(String localeCode) { /* Bug 713464: This method is still called from Gecko side. Earlier we had an option to run Firefox in a language other than system's language. However, this is not supported as of now. Gecko resets the locale to en-US by calling this function with an empty string. This affects GeckoPreferences activity in multi-locale builds. //We're not using this, not need to save it (see bug 635342) @@ -1544,17 +1544,17 @@ public class GeckoAppShell Resources res = getContext().getBaseContext().getResources(); Configuration config = res.getConfiguration(); config.locale = locale; res.updateConfiguration(config, res.getDisplayMetrics()); */ } - @WrapElementForJNI(stubName = "GetSystemColoursWrapper") + @GeneratableAndroidBridgeTarget(stubName = "GetSystemColoursWrapper") public static int[] getSystemColors() { // attrsAppearance[] must correspond to AndroidSystemColors structure in android/AndroidBridge.h final int[] attrsAppearance = { android.R.attr.textColor, android.R.attr.textColorPrimary, android.R.attr.textColorPrimaryInverse, android.R.attr.textColorSecondary, android.R.attr.textColorSecondaryInverse, @@ -1581,17 +1581,17 @@ public class GeckoAppShell result[idx] = color; } appearance.recycle(); } return result; } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void killAnyZombies() { GeckoProcessesVisitor visitor = new GeckoProcessesVisitor() { @Override public boolean callback(int pid) { if (pid != android.os.Process.myPid()) android.os.Process.killProcess(pid); return true; } @@ -1737,31 +1737,31 @@ public class GeckoAppShell String file = split[nameColumn]; if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(file) && file.startsWith(filter)) Log.i(LOGTAG, "[OPENFILE] " + name + "(" + split[pidColumn] + ") : " + file); } in.close(); } catch (Exception e) { } } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void scanMedia(String aFile, String aMimeType) { // If the platform didn't give us a mimetype, try to guess one from the filename if (TextUtils.isEmpty(aMimeType)) { int extPosition = aFile.lastIndexOf("."); if (extPosition > 0 && extPosition < aFile.length() - 1) { aMimeType = getMimeTypeFromExtension(aFile.substring(extPosition+1)); } } Context context = getContext(); GeckoMediaScannerClient.startScan(context, aFile, aMimeType); } - @WrapElementForJNI(stubName = "GetIconForExtensionWrapper") + @GeneratableAndroidBridgeTarget(stubName = "GetIconForExtensionWrapper") public static byte[] getIconForExtension(String aExt, int iconSize) { try { if (iconSize <= 0) iconSize = 16; if (aExt != null && aExt.length() > 1 && aExt.charAt(0) == '.') aExt = aExt.substring(1); @@ -1809,39 +1809,39 @@ public class GeckoAppShell if (resolveInfo == null) return null; ActivityInfo activityInfo = resolveInfo.activityInfo; return activityInfo.loadIcon(pm); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static boolean getShowPasswordSetting() { try { int showPassword = Settings.System.getInt(getContext().getContentResolver(), Settings.System.TEXT_SHOW_PASSWORD, 1); return (showPassword > 0); } catch (Exception e) { return true; } } - @WrapElementForJNI(stubName = "AddPluginViewWrapper") + @GeneratableAndroidBridgeTarget(stubName = "AddPluginViewWrapper") public static void addPluginView(View view, float x, float y, float w, float h, boolean isFullScreen) { if (getGeckoInterface() != null) getGeckoInterface().addPluginView(view, new RectF(x, y, x + w, y + h), isFullScreen); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void removePluginView(View view, boolean isFullScreen) { if (getGeckoInterface() != null) getGeckoInterface().removePluginView(view, isFullScreen); } /** * A plugin that wish to be loaded in the WebView must provide this permission * in their AndroidManifest.xml. @@ -2055,17 +2055,17 @@ public class GeckoAppShell } catch (android.content.pm.PackageManager.NameNotFoundException nnfe) { Log.w(LOGTAG, "Couldn't find package.", nnfe); return null; } } private static ContextGetter sContextGetter; - @WrapElementForJNI(allowMultithread = true) + @GeneratableAndroidBridgeTarget(allowMultithread = true) public static Context getContext() { return sContextGetter.getContext(); } public static void setContextGetter(ContextGetter cg) { sContextGetter = cg; } @@ -2113,17 +2113,17 @@ public class GeckoAppShell public static android.hardware.Camera sCamera = null; static native void cameraCallbackBridge(byte[] data); static int kPreferedFps = 25; static byte[] sCameraBuffer = null; - @WrapElementForJNI(stubName = "InitCameraWrapper") + @GeneratableAndroidBridgeTarget(stubName = "InitCameraWrapper") static int[] initCamera(String aContentType, int aCamera, int aWidth, int aHeight) { ThreadUtils.postToUiThread(new Runnable() { @Override public void run() { try { if (getGeckoInterface() != null) getGeckoInterface().enableCameraView(); } catch (Exception e) {} @@ -2214,17 +2214,17 @@ public class GeckoAppShell result[3] = params.getPreviewFrameRate(); } catch(RuntimeException e) { Log.w(LOGTAG, "initCamera RuntimeException.", e); result[0] = result[1] = result[2] = result[3] = 0; } return result; } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget static synchronized void closeCamera() { ThreadUtils.postToUiThread(new Runnable() { @Override public void run() { try { if (getGeckoInterface() != null) getGeckoInterface().disableCameraView(); } catch (Exception e) {} @@ -2266,148 +2266,148 @@ public class GeckoAppShell */ public static void unregisterEventListener(String event, GeckoEventListener listener) { sEventDispatcher.unregisterEventListener(event, listener); } /* * Battery API related methods. */ - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void enableBatteryNotifications() { GeckoBatteryManager.enableNotifications(); } - @WrapElementForJNI(stubName = "HandleGeckoMessageWrapper") + @GeneratableAndroidBridgeTarget(stubName = "HandleGeckoMessageWrapper") public static String handleGeckoMessage(String message) { return sEventDispatcher.dispatchEvent(message); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void disableBatteryNotifications() { GeckoBatteryManager.disableNotifications(); } - @WrapElementForJNI(stubName = "GetCurrentBatteryInformationWrapper") + @GeneratableAndroidBridgeTarget(stubName = "GetCurrentBatteryInformationWrapper") public static double[] getCurrentBatteryInformation() { return GeckoBatteryManager.getCurrentInformation(); } - @WrapElementForJNI(stubName = "CheckURIVisited") + @GeneratableAndroidBridgeTarget(stubName = "CheckURIVisited") static void checkUriVisited(String uri) { GlobalHistory.getInstance().checkUriVisited(uri); } - @WrapElementForJNI(stubName = "MarkURIVisited") + @GeneratableAndroidBridgeTarget(stubName = "MarkURIVisited") static void markUriVisited(final String uri) { ThreadUtils.postToBackgroundThread(new Runnable() { @Override public void run() { GlobalHistory.getInstance().add(uri); } }); } - @WrapElementForJNI(stubName = "SetURITitle") + @GeneratableAndroidBridgeTarget(stubName = "SetURITitle") static void setUriTitle(final String uri, final String title) { ThreadUtils.postToBackgroundThread(new Runnable() { @Override public void run() { GlobalHistory.getInstance().update(uri, title); } }); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget static void hideProgressDialog() { // unused stub } /* * WebSMS related methods. */ - @WrapElementForJNI(stubName = "SendMessageWrapper") + @GeneratableAndroidBridgeTarget(stubName = "SendMessageWrapper") public static void sendMessage(String aNumber, String aMessage, int aRequestId) { if (SmsManager.getInstance() == null) { return; } SmsManager.getInstance().send(aNumber, aMessage, aRequestId); } - @WrapElementForJNI(stubName = "GetMessageWrapper") + @GeneratableAndroidBridgeTarget(stubName = "GetMessageWrapper") public static void getMessage(int aMessageId, int aRequestId) { if (SmsManager.getInstance() == null) { return; } SmsManager.getInstance().getMessage(aMessageId, aRequestId); } - @WrapElementForJNI(stubName = "DeleteMessageWrapper") + @GeneratableAndroidBridgeTarget(stubName = "DeleteMessageWrapper") public static void deleteMessage(int aMessageId, int aRequestId) { if (SmsManager.getInstance() == null) { return; } SmsManager.getInstance().deleteMessage(aMessageId, aRequestId); } - @WrapElementForJNI(stubName = "CreateMessageListWrapper") + @GeneratableAndroidBridgeTarget(stubName = "CreateMessageListWrapper") public static void createMessageList(long aStartDate, long aEndDate, String[] aNumbers, int aNumbersCount, int aDeliveryState, boolean aReverse, int aRequestId) { if (SmsManager.getInstance() == null) { return; } SmsManager.getInstance().createMessageList(aStartDate, aEndDate, aNumbers, aNumbersCount, aDeliveryState, aReverse, aRequestId); } - @WrapElementForJNI(stubName = "GetNextMessageInListWrapper") + @GeneratableAndroidBridgeTarget(stubName = "GetNextMessageInListWrapper") public static void getNextMessageInList(int aListId, int aRequestId) { if (SmsManager.getInstance() == null) { return; } SmsManager.getInstance().getNextMessageInList(aListId, aRequestId); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void clearMessageList(int aListId) { if (SmsManager.getInstance() == null) { return; } SmsManager.getInstance().clearMessageList(aListId); } /* Called by JNI from AndroidBridge, and by reflection from tests/BaseTest.java.in */ - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static boolean isTablet() { return HardwareUtils.isTablet(); } public static void viewSizeChanged() { LayerView v = getLayerView(); if (v != null && v.isIMEEnabled()) { sendEventToGecko(GeckoEvent.createBroadcastEvent( "ScrollTo:FocusedInput", "")); } } - @WrapElementForJNI(stubName = "GetCurrentNetworkInformationWrapper") + @GeneratableAndroidBridgeTarget(stubName = "GetCurrentNetworkInformationWrapper") public static double[] getCurrentNetworkInformation() { return GeckoNetworkManager.getInstance().getCurrentInformation(); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void enableNetworkNotifications() { GeckoNetworkManager.getInstance().enableNotifications(); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void disableNetworkNotifications() { GeckoNetworkManager.getInstance().disableNotifications(); } // values taken from android's Base64 public static final int BASE64_DEFAULT = 0; public static final int BASE64_URL_SAFE = 8; @@ -2511,42 +2511,42 @@ public class GeckoAppShell if (op<oLen) out[op++] = (byte)o2; } return out; } public static byte[] decodeBase64(String s, int flags) { return decodeBase64(s.getBytes(), flags); } - @WrapElementForJNI(stubName = "GetScreenOrientationWrapper") + @GeneratableAndroidBridgeTarget(stubName = "GetScreenOrientationWrapper") public static short getScreenOrientation() { return GeckoScreenOrientationListener.getInstance().getScreenOrientation(); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void enableScreenOrientationNotifications() { GeckoScreenOrientationListener.getInstance().enableNotifications(); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void disableScreenOrientationNotifications() { GeckoScreenOrientationListener.getInstance().disableNotifications(); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void lockScreenOrientation(int aOrientation) { GeckoScreenOrientationListener.getInstance().lockScreenOrientation(aOrientation); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void unlockScreenOrientation() { GeckoScreenOrientationListener.getInstance().unlockScreenOrientation(); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static boolean pumpMessageLoop() { Handler geckoHandler = ThreadUtils.sGeckoHandler; Message msg = getNextMessageFromQueue(ThreadUtils.sGeckoQueue); if (msg == null) return false; if (msg.obj == geckoHandler && msg.getTarget() == geckoHandler) { // Our "queue is empty" message; see runGecko() @@ -2558,66 +2558,66 @@ public class GeckoAppShell else msg.getTarget().dispatchMessage(msg); msg.recycle(); return true; } static native void notifyFilePickerResult(String filePath, long id); - @WrapElementForJNI(stubName = "ShowFilePickerAsyncWrapper") + @GeneratableAndroidBridgeTarget(stubName = "ShowFilePickerAsyncWrapper") public static void showFilePickerAsync(String aMimeType, final long id) { sActivityHelper.showFilePickerAsync(getGeckoInterface().getActivity(), aMimeType, new ActivityHandlerHelper.FileResultHandler() { public void gotFile(String filename) { GeckoAppShell.notifyFilePickerResult(filename, id); } }); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void notifyWakeLockChanged(String topic, String state) { if (getGeckoInterface() != null) getGeckoInterface().notifyWakeLockChanged(topic, state); } - @WrapElementForJNI(stubName = "GetGfxInfoDataWrapper") + @GeneratableAndroidBridgeTarget(stubName = "GetGfxInfoDataWrapper") public static String getGfxInfoData() { return GfxInfoThread.getData(); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static void registerSurfaceTextureFrameListener(Object surfaceTexture, final int id) { ((SurfaceTexture)surfaceTexture).setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() { @Override public void onFrameAvailable(SurfaceTexture surfaceTexture) { GeckoAppShell.onSurfaceTextureFrameAvailable(surfaceTexture, id); } }); } - @WrapElementForJNI(allowMultithread = true) + @GeneratableAndroidBridgeTarget(allowMultithread = true) public static void unregisterSurfaceTextureFrameListener(Object surfaceTexture) { ((SurfaceTexture)surfaceTexture).setOnFrameAvailableListener(null); } - @WrapElementForJNI + @GeneratableAndroidBridgeTarget public static boolean unlockProfile() { // Try to kill any zombie Fennec's that might be running GeckoAppShell.killAnyZombies(); // Then force unlock this profile if (getGeckoInterface() != null) { GeckoProfile profile = getGeckoInterface().getProfile(); File lock = profile.getFile(".parentlock"); return lock.exists() && lock.delete(); } return false; } - @WrapElementForJNI(stubName = "GetProxyForURIWrapper") + @GeneratableAndroidBridgeTarget(stubName = "GetProxyForURIWrapper") public static String getProxyForURI(String spec, String scheme, String host, int port) { URI uri = null; try { uri = new URI(spec); } catch(java.net.URISyntaxException uriEx) { try { uri = new URI(scheme, null, host, port, null, null, null); } catch(java.net.URISyntaxException uriEx2) {
--- a/mobile/android/base/GeckoEvent.java +++ b/mobile/android/base/GeckoEvent.java @@ -2,18 +2,16 @@ * 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; import org.mozilla.gecko.gfx.DisplayPortMetrics; import org.mozilla.gecko.gfx.ImmutableViewportMetrics; -import org.mozilla.gecko.mozglue.generatorannotations.GeneratorOptions; -import org.mozilla.gecko.mozglue.generatorannotations.WrapEntireClassForJNI; import android.content.res.Resources; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorManager; @@ -80,18 +78,16 @@ public class GeckoEvent { this.value = value; } } /** * The DomKeyLocation enum encapsulates the DOM KeyboardEvent's constants. * @see https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent#Key_location_constants */ - @GeneratorOptions(generatedClassName = "JavaDomKeyLocation") - @WrapEntireClassForJNI public enum DomKeyLocation { DOM_KEY_LOCATION_STANDARD(0), DOM_KEY_LOCATION_LEFT(1), DOM_KEY_LOCATION_RIGHT(2), DOM_KEY_LOCATION_NUMPAD(3), DOM_KEY_LOCATION_MOBILE(4), DOM_KEY_LOCATION_JOYSTICK(5);
--- a/mobile/android/base/GeckoJavaSampler.java +++ b/mobile/android/base/GeckoJavaSampler.java @@ -3,17 +3,17 @@ * 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; import android.os.SystemClock; import android.util.Log; -import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; +import org.mozilla.gecko.mozglue.GeneratableAndroidBridgeTarget; import java.lang.Thread; import java.util.HashMap; import java.util.Map; import java.util.Set; public class GeckoJavaSampler { private static final String LOGTAG = "JavaSampler"; @@ -121,82 +121,82 @@ public class GeckoJavaSampler { int readPos = (startPos + aSampleId) % mSamples.get(aThreadId).length; return mSamples.get(aThreadId)[readPos]; } return null; } } - @WrapElementForJNI(allowMultithread = true, stubName = "GetThreadNameJavaProfilingWrapper") + @GeneratableAndroidBridgeTarget(allowMultithread = true, stubName = "GetThreadNameJavaProfilingWrapper") public synchronized static String getThreadName(int aThreadId) { if (aThreadId == 0 && sMainThread != null) { return sMainThread.getName(); } return null; } private synchronized static Sample getSample(int aThreadId, int aSampleId) { return sSamplingRunnable.getSample(aThreadId, aSampleId); } - @WrapElementForJNI(allowMultithread = true, stubName = "GetSampleTimeJavaProfiling") + @GeneratableAndroidBridgeTarget(allowMultithread = true, stubName = "GetSampleTimeJavaProfiling") public synchronized static double getSampleTime(int aThreadId, int aSampleId) { Sample sample = getSample(aThreadId, aSampleId); if (sample != null) { if (sample.mJavaTime != 0) { return (double)(sample.mJavaTime - SystemClock.elapsedRealtime()) + getProfilerTime(); } System.out.println("Sample: " + sample.mTime); return sample.mTime; } return 0; } - @WrapElementForJNI(allowMultithread = true, stubName = "GetFrameNameJavaProfilingWrapper") + @GeneratableAndroidBridgeTarget(allowMultithread = true, stubName = "GetFrameNameJavaProfilingWrapper") public synchronized static String getFrameName(int aThreadId, int aSampleId, int aFrameId) { Sample sample = getSample(aThreadId, aSampleId); if (sample != null && aFrameId < sample.mFrames.length) { Frame frame = sample.mFrames[aFrameId]; if (frame == null) { return null; } return frame.className + "." + frame.methodName + "()"; } return null; } - @WrapElementForJNI(allowMultithread = true, stubName = "StartJavaProfiling") + @GeneratableAndroidBridgeTarget(allowMultithread = true, stubName = "StartJavaProfiling") public static void start(int aInterval, int aSamples) { synchronized (GeckoJavaSampler.class) { if (sSamplingRunnable != null) { return; } sSamplingRunnable = new SamplingThread(aInterval, aSamples); sSamplingThread = new Thread(sSamplingRunnable, "Java Sampler"); sSamplingThread.start(); } } - @WrapElementForJNI(allowMultithread = true, stubName = "PauseJavaProfiling") + @GeneratableAndroidBridgeTarget(allowMultithread = true, stubName = "PauseJavaProfiling") public static void pause() { synchronized (GeckoJavaSampler.class) { sSamplingRunnable.mPauseSampler = true; } } - @WrapElementForJNI(allowMultithread = true, stubName = "UnpauseJavaProfiling") + @GeneratableAndroidBridgeTarget(allowMultithread = true, stubName = "UnpauseJavaProfiling") public static void unpause() { synchronized (GeckoJavaSampler.class) { sSamplingRunnable.mPauseSampler = false; } } - @WrapElementForJNI(allowMultithread = true, stubName = "StopJavaProfiling") + @GeneratableAndroidBridgeTarget(allowMultithread = true, stubName = "StopJavaProfiling") public static void stop() { synchronized (GeckoJavaSampler.class) { if (sSamplingThread == null) { return; } sSamplingRunnable.mStopSampler = true; try {
--- a/mobile/android/base/Makefile.in +++ b/mobile/android/base/Makefile.in @@ -4,22 +4,20 @@ DIST_FILES = package-name.txt include $(topsrcdir)/mobile/android/base/android-services-files.mk MOZGLUE_JAVA_FILES := \ mozglue/ByteBufferInputStream.java \ mozglue/DirectBufferAllocator.java \ - mozglue/generatorannotations/GeneratorOptions.java \ - mozglue/generatorannotations/OptionalGeneratedParameter.java \ - mozglue/generatorannotations/WrapEntireClassForJNI.java \ - mozglue/generatorannotations/WrapElementForJNI.java \ + mozglue/GeneratableAndroidBridgeTarget.java \ mozglue/NativeReference.java \ mozglue/NativeZip.java \ + mozglue/OptionalGeneratedParameter.java \ $(NULL) MOZGLUE_PP_JAVA_FILES := \ mozglue/GeckoLoader.java \ $(NULL) UTIL_JAVA_FILES := \ util/ActivityResultHandler.java \ @@ -1305,23 +1303,21 @@ endif jni-stubs.inc: jars/gecko-browser.jar jars/gecko-mozglue.jar jars/gecko-util.jar jars/sync-thirdparty.jar $(JAVAH) -o javah.out -bootclasspath $(JAVA_BOOTCLASSPATH) -classpath $(subst $(NULL) $(NULL),:,$^) $(CLASSES_WITH_JNI) $(PYTHON) $(topsrcdir)/mobile/android/base/jni-generator.py javah.out $@ ANNOTATION_PROCESSOR_JAVA_FILES = \ build/annotationProcessors/AnnotationProcessor.java \ build/annotationProcessors/CodeGenerator.java \ - build/annotationProcessors/AnnotationInfo.java \ - build/annotationProcessors/classloader/AnnotatableEntity.java \ - build/annotationProcessors/classloader/ClassWithOptions.java \ + build/annotationProcessors/MethodWithAnnotationInfo.java \ build/annotationProcessors/classloader/IterableJarLoadingURLClassLoader.java \ build/annotationProcessors/classloader/JarClassIterator.java \ - build/annotationProcessors/utils/AlphabeticAnnotatableEntityComparator.java \ - build/annotationProcessors/utils/GeneratableElementIterator.java \ + build/annotationProcessors/utils/AlphabeticMethodComparator.java \ + build/annotationProcessors/utils/GeneratableEntryPointIterator.java \ build/annotationProcessors/utils/Utils.java \ $(NULL) GeneratedJNIWrappers.cpp: jars/gecko-browser.jar jars/gecko-mozglue.jar jars/gecko-util.jar jars/sync-thirdparty.jar $(JAVAC) $(addprefix $(topsrcdir)/,$(ANNOTATION_PROCESSOR_JAVA_FILES)) -d $(CURDIR) $(JAVA) -classpath $(JAVA_BOOTCLASSPATH):$(CURDIR) org.mozilla.gecko.annotationProcessors.AnnotationProcessor $^ PP_RES_XML= \
--- a/mobile/android/base/SurfaceBits.java +++ b/mobile/android/base/SurfaceBits.java @@ -1,17 +1,14 @@ /* 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; -import org.mozilla.gecko.mozglue.generatorannotations.WrapEntireClassForJNI; - import java.nio.ByteBuffer; -@WrapEntireClassForJNI public class SurfaceBits { public int width; public int height; public int format; public ByteBuffer buffer; }
--- a/mobile/android/base/ThumbnailHelper.java +++ b/mobile/android/base/ThumbnailHelper.java @@ -4,17 +4,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.gecko; import org.mozilla.gecko.db.BrowserDB; import org.mozilla.gecko.gfx.BitmapUtils; import org.mozilla.gecko.gfx.IntSize; import org.mozilla.gecko.mozglue.DirectBufferAllocator; -import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; +import org.mozilla.gecko.mozglue.GeneratableAndroidBridgeTarget; import android.graphics.Bitmap; import android.util.Log; import java.nio.ByteBuffer; import java.util.LinkedList; import java.util.concurrent.atomic.AtomicInteger; @@ -139,17 +139,17 @@ public final class ThumbnailHelper { return; } GeckoEvent e = GeckoEvent.createThumbnailEvent(tab.getId(), mWidth, mHeight, mBuffer); GeckoAppShell.sendEventToGecko(e); } /* This method is invoked by JNI once the thumbnail data is ready. */ - @WrapElementForJNI(stubName = "SendThumbnail") + @GeneratableAndroidBridgeTarget(stubName = "SendThumbnail") public static void notifyThumbnail(ByteBuffer data, int tabId, boolean success) { Tab tab = Tabs.getInstance().getTab(tabId); ThumbnailHelper helper = ThumbnailHelper.getInstance(); if (success && tab != null) { helper.handleThumbnailData(tab, data); } helper.processNextThumbnail(tab); }
--- a/mobile/android/base/gfx/DisplayPortMetrics.java +++ b/mobile/android/base/gfx/DisplayPortMetrics.java @@ -1,39 +1,35 @@ /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- * 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.gfx; -import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; import org.mozilla.gecko.util.FloatUtils; import android.graphics.RectF; /* * This class keeps track of the area we request Gecko to paint, as well * as the resolution of the paint. The area may be different from the visible * area of the page, and the resolution may be different from the resolution * used in the compositor to render the page. This is so that we can ask Gecko * to paint a much larger area without using extra memory, and then render some * subsection of that with compositor scaling. */ public final class DisplayPortMetrics { - @WrapElementForJNI public final float resolution; - @WrapElementForJNI private final RectF mPosition; public DisplayPortMetrics() { this(0, 0, 0, 0, 1); } - @WrapElementForJNI public DisplayPortMetrics(float left, float top, float right, float bottom, float resolution) { this.resolution = resolution; mPosition = new RectF(left, top, right, bottom); } public float getLeft() { return mPosition.left; }
--- a/mobile/android/base/gfx/GLController.java +++ b/mobile/android/base/gfx/GLController.java @@ -3,17 +3,17 @@ * 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.gfx; import org.mozilla.gecko.GeckoAppShell; import org.mozilla.gecko.GeckoEvent; import org.mozilla.gecko.GeckoThread; -import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; +import org.mozilla.gecko.mozglue.GeneratableAndroidBridgeTarget; import org.mozilla.gecko.util.ThreadUtils; import android.util.Log; import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLContext; import javax.microedition.khronos.egl.EGLDisplay; @@ -258,17 +258,17 @@ public class GLController { if (red[0] == rSize && green[0] == gSize && blue[0] == bSize) { return config; } } throw new GLControllerException("No suitable EGL configuration found"); } - @WrapElementForJNI(allowMultithread = true, stubName = "ProvideEGLSurfaceWrapper") + @GeneratableAndroidBridgeTarget(allowMultithread = true, stubName = "ProvideEGLSurfaceWrapper") private EGLSurface provideEGLSurface() { return mEGLSurface; } private String getEGLError() { return "Error " + (mEGL == null ? "(no mEGL)" : mEGL.eglGetError()); }
--- a/mobile/android/base/gfx/GeckoLayerClient.java +++ b/mobile/android/base/gfx/GeckoLayerClient.java @@ -6,17 +6,16 @@ package org.mozilla.gecko.gfx; import org.mozilla.gecko.BrowserApp; import org.mozilla.gecko.GeckoAppShell; import org.mozilla.gecko.GeckoEvent; import org.mozilla.gecko.Tab; import org.mozilla.gecko.Tabs; import org.mozilla.gecko.ZoomConstraints; -import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; import org.mozilla.gecko.util.EventDispatcher; import org.mozilla.gecko.util.FloatUtils; import org.mozilla.gecko.util.ThreadUtils; import android.content.Context; import android.graphics.PointF; import android.graphics.RectF; import android.os.SystemClock; @@ -405,49 +404,48 @@ public class GeckoLayerClient implements }); setViewportMetrics(newMetrics, type == ViewportMessageType.UPDATE); mDisplayPort = DisplayPortCalculator.calculate(getViewportMetrics(), null); } return mDisplayPort; } - @WrapElementForJNI + /* This is invoked by JNI on the gecko thread */ DisplayPortMetrics getDisplayPort(boolean pageSizeUpdate, boolean isBrowserContentDisplayed, int tabId, ImmutableViewportMetrics metrics) { Tabs tabs = Tabs.getInstance(); if (tabs.isSelectedTab(tabs.getTab(tabId)) && isBrowserContentDisplayed) { // for foreground tabs, send the viewport update unless the document // displayed is different from the content document. In that case, just // calculate the display port. return handleViewportMessage(metrics, pageSizeUpdate ? ViewportMessageType.PAGE_SIZE : ViewportMessageType.UPDATE); } else { // for background tabs, request a new display port calculation, so that // when we do switch to that tab, we have the correct display port and // don't need to draw twice (once to allow the first-paint viewport to // get to java, and again once java figures out the display port). return DisplayPortCalculator.calculate(metrics, null); } } - @WrapElementForJNI + /* This is invoked by JNI on the gecko thread */ void contentDocumentChanged() { mContentDocumentIsDisplayed = false; } - @WrapElementForJNI + /* This is invoked by JNI on the gecko thread */ boolean isContentDocumentDisplayed() { return mContentDocumentIsDisplayed; } // This is called on the Gecko thread to determine if we're still interested // in the update of this display-port to continue. We can return true here // to abort the current update and continue with any subsequent ones. This // is useful for slow-to-render pages when the display-port starts lagging // behind enough that continuing to draw it is wasted effort. - @WrapElementForJNI(allowMultithread = true) public ProgressiveUpdateData progressiveUpdateCallback(boolean aHasPendingNewThebesContent, float x, float y, float width, float height, float resolution, boolean lowPrecision) { // Reset the checkerboard risk flag when switching to low precision // rendering. if (lowPrecision && !mLastProgressiveUpdateWasLowPrecision) { // Skip low precision rendering until we're at risk of checkerboarding. if (!mProgressiveUpdateWasInDanger) { @@ -545,23 +543,23 @@ public class GeckoLayerClient implements void setIsRTL(boolean aIsRTL) { synchronized (getLock()) { ImmutableViewportMetrics newMetrics = getViewportMetrics().setIsRTL(aIsRTL); setViewportMetrics(newMetrics, false); } } - /** The compositor invokes this function just before compositing a frame where the document + /** This function is invoked by Gecko via JNI; be careful when modifying signature. + * The compositor invokes this function just before compositing a frame where the document * is different from the document composited on the last frame. In these cases, the viewport * information we have in Java is no longer valid and needs to be replaced with the new * viewport information provided. setPageRect will never be invoked on the same frame that * this function is invoked on; and this function will always be called prior to syncViewportInfo. */ - @WrapElementForJNI(allowMultithread = true) public void setFirstPaintViewport(float offsetX, float offsetY, float zoom, float cssPageLeft, float cssPageTop, float cssPageRight, float cssPageBottom) { synchronized (getLock()) { ImmutableViewportMetrics currentMetrics = getViewportMetrics(); Tab tab = Tabs.getInstance().getSelectedTab(); RectF cssPageRect = new RectF(cssPageLeft, cssPageTop, cssPageRight, cssPageBottom); @@ -604,43 +602,43 @@ public class GeckoLayerClient implements } } DisplayPortCalculator.resetPageState(); mDrawTimingQueue.reset(); mContentDocumentIsDisplayed = true; } - /** The compositor invokes this function whenever it determines that the page rect + /** This function is invoked by Gecko via JNI; be careful when modifying signature. + * The compositor invokes this function whenever it determines that the page rect * has changed (based on the information it gets from layout). If setFirstPaintViewport * is invoked on a frame, then this function will not be. For any given frame, this * function will be invoked before syncViewportInfo. */ - @WrapElementForJNI(allowMultithread = true) public void setPageRect(float cssPageLeft, float cssPageTop, float cssPageRight, float cssPageBottom) { synchronized (getLock()) { RectF cssPageRect = new RectF(cssPageLeft, cssPageTop, cssPageRight, cssPageBottom); float ourZoom = getViewportMetrics().zoomFactor; setPageRect(RectUtils.scale(cssPageRect, ourZoom), cssPageRect); // Here the page size of the document has changed, but the document being displayed // is still the same. Therefore, we don't need to send anything to browser.js; any // changes we need to make to the display port will get sent the next time we call // adjustViewport(). } } - /** The compositor invokes this function on every frame to figure out what part of the + /** This function is invoked by Gecko via JNI; be careful when modifying signature. + * The compositor invokes this function on every frame to figure out what part of the * page to display, and to inform Java of the current display port. Since it is called * on every frame, it needs to be ultra-fast. * It avoids taking any locks or allocating any objects. We keep around a * mCurrentViewTransform so we don't need to allocate a new ViewTransform * everytime we're called. NOTE: we might be able to return a ImmutableViewportMetrics * which would avoid the copy into mCurrentViewTransform. */ - @WrapElementForJNI(allowMultithread = true) public ViewTransform syncViewportInfo(int x, int y, int width, int height, float resolution, boolean layersUpdated) { // getViewportMetrics is thread safe so we don't need to synchronize. // We save the viewport metrics here, so we later use it later in // createFrame (which will be called by nsWindow::DrawWindowUnderlay on // the native side, by the compositor). The viewport // metrics can change between here and there, as it's accessed outside // of the compositor thread. mFrameMetrics = getViewportMetrics(); @@ -684,48 +682,48 @@ public class GeckoLayerClient implements if (layersUpdated && mDrawListener != null) { /* Used by robocop for testing purposes */ mDrawListener.drawFinished(); } return mCurrentViewTransform; } - @WrapElementForJNI(allowMultithread = true) + /* Invoked by JNI from the compositor thread */ public ViewTransform syncFrameMetrics(float offsetX, float offsetY, float zoom, float cssPageLeft, float cssPageTop, float cssPageRight, float cssPageBottom, boolean layersUpdated, int x, int y, int width, int height, float resolution, boolean isFirstPaint) { if (isFirstPaint) { setFirstPaintViewport(offsetX, offsetY, zoom, cssPageLeft, cssPageTop, cssPageRight, cssPageBottom); } return syncViewportInfo(x, y, width, height, resolution, layersUpdated); } - @WrapElementForJNI(allowMultithread = true) + /** This function is invoked by Gecko via JNI; be careful when modifying signature. */ public LayerRenderer.Frame createFrame() { // Create the shaders and textures if necessary. if (!mLayerRendererInitialized) { mLayerRenderer.checkMonitoringEnabled(); mLayerRenderer.createDefaultProgram(); mLayerRendererInitialized = true; } return mLayerRenderer.createFrame(mFrameMetrics); } - @WrapElementForJNI(allowMultithread = true) + /** This function is invoked by Gecko via JNI; be careful when modifying signature. */ public void activateProgram() { mLayerRenderer.activateDefaultProgram(); } - @WrapElementForJNI(allowMultithread = true) + /** This function is invoked by Gecko via JNI; be careful when modifying signature. */ public void deactivateProgram() { mLayerRenderer.deactivateDefaultProgram(); } private void geometryChanged(DisplayPortMetrics displayPort) { /* Let Gecko know if the screensize has changed */ sendResizeEventIfNecessary(false); if (getRedrawHint()) {
--- a/mobile/android/base/gfx/ImmutableViewportMetrics.java +++ b/mobile/android/base/gfx/ImmutableViewportMetrics.java @@ -1,16 +1,15 @@ /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- * 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.gfx; -import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; import org.mozilla.gecko.util.FloatUtils; import android.graphics.PointF; import android.graphics.RectF; import android.util.DisplayMetrics; /** * ImmutableViewportMetrics are used to store the viewport metrics @@ -48,18 +47,17 @@ public class ImmutableViewportMetrics { marginLeft = marginTop = marginRight = marginBottom = 0; zoomFactor = 1.0f; isRTL = false; } /** This constructor is used by native code in AndroidJavaWrappers.cpp, be * careful when modifying the signature. */ - @WrapElementForJNI(allowMultithread = true) - public ImmutableViewportMetrics(float aPageRectLeft, float aPageRectTop, + private ImmutableViewportMetrics(float aPageRectLeft, float aPageRectTop, float aPageRectRight, float aPageRectBottom, float aCssPageRectLeft, float aCssPageRectTop, float aCssPageRectRight, float aCssPageRectBottom, float aViewportRectLeft, float aViewportRectTop, float aViewportRectRight, float aViewportRectBottom, float aZoomFactor) { this(aPageRectLeft, aPageRectTop, aPageRectRight, aPageRectBottom, aCssPageRectLeft, aCssPageRectTop, aCssPageRectRight, aCssPageRectBottom,
--- a/mobile/android/base/gfx/LayerRenderer.java +++ b/mobile/android/base/gfx/LayerRenderer.java @@ -7,25 +7,24 @@ package org.mozilla.gecko.gfx; import org.mozilla.gecko.GeckoAppShell; import org.mozilla.gecko.R; import org.mozilla.gecko.Tab; import org.mozilla.gecko.Tabs; import org.mozilla.gecko.gfx.Layer.RenderContext; import org.mozilla.gecko.gfx.RenderTask; import org.mozilla.gecko.mozglue.DirectBufferAllocator; -import org.mozilla.gecko.mozglue.generatorannotations.GeneratorOptions; -import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; import android.content.Context; import android.content.SharedPreferences; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; +import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; import android.opengl.GLES20; import android.os.SystemClock; import android.util.Log; import java.nio.ByteBuffer; @@ -433,17 +432,16 @@ public class LayerRenderer implements Ta } else { // reached the run-at time, execute mStarted = false; mView.requestRender(); } } } - @GeneratorOptions(generatedClassName = "LayerRendererFrame") public class Frame { // The timestamp recording the start of this frame. private long mFrameStartTime; // A fixed snapshot of the viewport metrics that this frame is using to render content. private ImmutableViewportMetrics mFrameMetrics; // A rendering context for page-positioned layers, and one for screen-positioned layers. private RenderContext mPageContext, mScreenContext; // Whether a layer was updated. @@ -487,17 +485,16 @@ public class LayerRenderer implements Ta Rect scissorRect = new Rect(left, screenSize.height - bottom, right, (screenSize.height - bottom) + (bottom - top)); scissorRect.offset(Math.round(-mRenderOffset.x), Math.round(-mRenderOffset.y)); return scissorRect; } /** This function is invoked via JNI; be careful when modifying signature. */ - @WrapElementForJNI(allowMultithread = true) public void beginDrawing() { mFrameStartTime = System.nanoTime(); TextureReaper.get().reap(); TextureGenerator.get().fill(); mUpdated = true; @@ -577,17 +574,16 @@ public class LayerRenderer implements Ta 0.0f); // The bits set here need to match up with those used // in gfx/layers/opengl/LayerManagerOGL.cpp. GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); } /** This function is invoked via JNI; be careful when modifying signature. */ - @WrapElementForJNI(allowMultithread = true) public void drawBackground() { GLES20.glDisable(GLES20.GL_SCISSOR_TEST); // Draw the overscroll background area as a solid color clear(mOverscrollColor); // Update background color. mBackgroundColor = mView.getBackgroundColor(); @@ -610,17 +606,16 @@ public class LayerRenderer implements Ta if (rootLayer == null) { return; } rootLayer.draw(mPageContext); } /** This function is invoked via JNI; be careful when modifying signature. */ - @WrapElementForJNI(allowMultithread = true) public void drawForeground() { /* Draw any extra layers that were added (likely plugins) */ if (mExtraLayers.size() > 0) { for (Layer layer : mExtraLayers) { layer.draw(mPageContext); } } @@ -661,17 +656,16 @@ public class LayerRenderer implements Ta GLES20.glEnable(GLES20.GL_BLEND); GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); mFrameRateLayer.draw(mScreenContext); } } /** This function is invoked via JNI; be careful when modifying signature. */ - @WrapElementForJNI(allowMultithread = true) public void endDrawing() { // If a layer update requires further work, schedule another redraw if (!mUpdated) mView.requestRender(); PanningPerfAPI.recordFrameTime(); /* Used by robocop for testing purposes */
--- a/mobile/android/base/gfx/LayerView.java +++ b/mobile/android/base/gfx/LayerView.java @@ -7,17 +7,17 @@ package org.mozilla.gecko.gfx; import org.mozilla.gecko.GeckoAccessibility; import org.mozilla.gecko.GeckoAppShell; import org.mozilla.gecko.GeckoEvent; import org.mozilla.gecko.PrefsHelper; import org.mozilla.gecko.R; import org.mozilla.gecko.TouchEventInterceptor; import org.mozilla.gecko.ZoomConstraints; -import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; +import org.mozilla.gecko.mozglue.GeneratableAndroidBridgeTarget; import org.mozilla.gecko.util.EventDispatcher; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.PixelFormat; import android.graphics.PointF; @@ -503,17 +503,17 @@ public class LayerView extends FrameLayo public Object getNativeWindow() { if (mSurfaceView != null) return mSurfaceView.getHolder(); return mTextureView.getSurfaceTexture(); } - @WrapElementForJNI(allowMultithread = true, stubName = "RegisterCompositorWrapper") + @GeneratableAndroidBridgeTarget(allowMultithread = true, stubName = "RegisterCompositorWrapper") public static GLController registerCxxCompositor() { try { LayerView layerView = GeckoAppShell.getLayerView(); GLController controller = layerView.getGLController(); controller.compositorCreated(); return controller; } catch (Exception e) { Log.e(LOGTAG, "Error registering compositor!", e);
--- a/mobile/android/base/gfx/NativePanZoomController.java +++ b/mobile/android/base/gfx/NativePanZoomController.java @@ -2,17 +2,17 @@ * 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.gfx; import org.mozilla.gecko.GeckoEvent; import org.mozilla.gecko.GeckoThread; -import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; +import org.mozilla.gecko.mozglue.GeneratableAndroidBridgeTarget; import org.mozilla.gecko.util.EventDispatcher; import org.mozilla.gecko.util.GeckoEventListener; import org.json.JSONObject; import android.graphics.PointF; import android.view.KeyEvent; import android.view.MotionEvent; @@ -78,22 +78,22 @@ class NativePanZoomController implements private native long runDelayedCallback(); public native void destroy(); public native void notifyDefaultActionPrevented(boolean prevented); public native boolean getRedrawHint(); public native void setOverScrollMode(int overscrollMode); public native int getOverScrollMode(); - @WrapElementForJNI(allowMultithread = true, stubName = "RequestContentRepaintWrapper") + @GeneratableAndroidBridgeTarget(allowMultithread = true, stubName = "RequestContentRepaintWrapper") private void requestContentRepaint(float x, float y, float width, float height, float resolution) { mTarget.forceRedraw(new DisplayPortMetrics(x, y, x + width, y + height, resolution)); } - @WrapElementForJNI(allowMultithread = true, stubName = "PostDelayedCallbackWrapper") + @GeneratableAndroidBridgeTarget(allowMultithread = true, stubName = "PostDelayedCallbackWrapper") private void postDelayedCallback(long delay) { mTarget.postDelayed(mCallbackRunnable, delay); } class CallbackRunnable implements Runnable { @Override public void run() { long nextDelay = runDelayedCallback();
--- a/mobile/android/base/gfx/ProgressiveUpdateData.java +++ b/mobile/android/base/gfx/ProgressiveUpdateData.java @@ -1,24 +1,21 @@ /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- * 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.gfx; -import org.mozilla.gecko.mozglue.generatorannotations.WrapEntireClassForJNI; - /** * This is the data structure that's returned by the progressive tile update * callback function. It encompasses the current viewport and a boolean value * representing whether the front-end is interested in the current progressive * update continuing. */ -@WrapEntireClassForJNI public class ProgressiveUpdateData { public float x; public float y; public float width; public float height; public float scale; public boolean abort;
--- a/mobile/android/base/gfx/ViewTransform.java +++ b/mobile/android/base/gfx/ViewTransform.java @@ -1,18 +1,15 @@ /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- * 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.gfx; -import org.mozilla.gecko.mozglue.generatorannotations.WrapEntireClassForJNI; - -@WrapEntireClassForJNI public class ViewTransform { public float x; public float y; public float scale; public float fixedLayerMarginLeft; public float fixedLayerMarginTop; public float fixedLayerMarginRight; public float fixedLayerMarginBottom;
rename from mobile/android/base/mozglue/generatorannotations/WrapElementForJNI.java rename to mobile/android/base/mozglue/GeneratableAndroidBridgeTarget.java --- a/mobile/android/base/mozglue/generatorannotations/WrapElementForJNI.java +++ b/mobile/android/base/mozglue/GeneratableAndroidBridgeTarget.java @@ -1,13 +1,13 @@ /* 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.mozglue.generatorannotations; +package org.mozilla.gecko.mozglue; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * This annotation is used to tag methods that are to have wrapper methods generated in the android * bridge. Such methods will be protected from destruction by Proguard, and allow us to avoid writing * by hand large amounts of boring boilerplate. @@ -16,17 +16,17 @@ import java.lang.annotation.RetentionPol * the first letter in upper case. The stubName property may be used to specify a custom name for the * generated method stub. * * allowMultithreaded should be used as sparingly as possible - the resulting code will allow the * Java method to be invoked from the C side from multiple threads. Often, this isn't what is wanted * and may lead to subtle bugs. */ @Retention(RetentionPolicy.RUNTIME) -public @interface WrapElementForJNI { +public @interface GeneratableAndroidBridgeTarget { // Optional parameter specifying the name of the generated method stub. If omitted, the name // of the Java method will be used. String stubName() default ""; // Optional parameter specifying if the generated method should be a static member of AndroidBridge // By default, an instance member is produced. This is almost always what is wanted. boolean generateStatic() default false;
--- a/mobile/android/base/mozglue/NativeZip.java +++ b/mobile/android/base/mozglue/NativeZip.java @@ -1,17 +1,15 @@ /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- * 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.mozglue; -import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; - import java.io.InputStream; import java.nio.ByteBuffer; import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; public class NativeZip implements NativeReference { private static final int DEFLATE = 8; private static final int STORE = 0; @@ -65,17 +63,16 @@ public class NativeZip implements Native return _getInputStream(mObj, path); } private static native long getZip(String path); private static native long getZipFromByteBuffer(ByteBuffer buffer); private static native void _release(long obj); private native InputStream _getInputStream(long obj, String path); - @WrapElementForJNI private InputStream createInputStream(ByteBuffer buffer, int compression) { if (compression != STORE && compression != DEFLATE) { throw new IllegalArgumentException("Unexpected compression: " + compression); } InputStream input = new ByteBufferInputStream(buffer, this); if (compression == DEFLATE) { Inflater inflater = new Inflater(true);
rename from mobile/android/base/mozglue/generatorannotations/OptionalGeneratedParameter.java rename to mobile/android/base/mozglue/OptionalGeneratedParameter.java --- a/mobile/android/base/mozglue/generatorannotations/OptionalGeneratedParameter.java +++ b/mobile/android/base/mozglue/OptionalGeneratedParameter.java @@ -1,13 +1,13 @@ /* 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.mozglue.generatorannotations; +package org.mozilla.gecko.mozglue; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Used to annotate parameters which are optional on the C++ side of the bridge. The annotation is * used by the annotation processor to generate the appropriate C++ headers so calls into the Java * method all have the optional params set to the default value.
deleted file mode 100644 --- a/mobile/android/base/mozglue/generatorannotations/GeneratorOptions.java +++ /dev/null @@ -1,14 +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.mozglue.generatorannotations; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@Retention(RetentionPolicy.RUNTIME) -public @interface GeneratorOptions { - // Specifies a custom name for the generated C++ class. If left empty, is AndroidJavaClassName. - String generatedClassName() default ""; -} \ No newline at end of file
deleted file mode 100644 --- a/mobile/android/base/mozglue/generatorannotations/WrapEntireClassForJNI.java +++ /dev/null @@ -1,15 +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.mozglue.generatorannotations; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Handy shortcut annotation. Functionally equivalent to tagging every member individually with default - * settings. - */ -@Retention(RetentionPolicy.RUNTIME) -public @interface WrapEntireClassForJNI {}
--- a/mobile/android/base/sqlite/MatrixBlobCursor.java +++ b/mobile/android/base/sqlite/MatrixBlobCursor.java @@ -12,18 +12,16 @@ * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.mozilla.gecko.sqlite; -import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; - import android.database.AbstractCursor; import android.database.CursorIndexOutOfBoundsException; import java.nio.ByteBuffer; import java.util.ArrayList; /* * Android's AbstractCursor throws on getBlob() @@ -47,17 +45,16 @@ public class MatrixBlobCursor extends Ab /** * Constructs a new cursor with the given initial capacity. * * @param columnNames names of the columns, the ordering of which * determines column ordering elsewhere in this cursor * @param initialCapacity in rows */ - @WrapElementForJNI public MatrixBlobCursor(String[] columnNames, int initialCapacity) { this.columnNames = columnNames; this.columnCount = columnNames.length; if (initialCapacity < 1) { initialCapacity = 1; } @@ -65,17 +62,16 @@ public class MatrixBlobCursor extends Ab } /** * Constructs a new cursor. * * @param columnNames names of the columns, the ordering of which * determines column ordering elsewhere in this cursor */ - @WrapElementForJNI public MatrixBlobCursor(String[] columnNames) { this(columnNames, 16); } /** * Gets value at the given column for the current row. */ protected Object get(int column) { @@ -111,17 +107,16 @@ public class MatrixBlobCursor extends Ab * Adds a new row to the end with the given column values. Not safe * for concurrent use. * * @throws IllegalArgumentException if {@code columnValues.length != * columnNames.length} * @param columnValues in the same order as the the column names specified * at cursor construction time */ - @WrapElementForJNI public void addRow(Object[] columnValues) { if (columnValues.length != columnCount) { throw new IllegalArgumentException("columnNames.length = " + columnCount + ", columnValues.length = " + columnValues.length); } int start = rowCount++ * columnCount; @@ -133,17 +128,16 @@ public class MatrixBlobCursor extends Ab * Adds a new row to the end with the given column values. Not safe * for concurrent use. * * @throws IllegalArgumentException if {@code columnValues.size() != * columnNames.length} * @param columnValues in the same order as the the column names specified * at cursor construction time */ - @WrapElementForJNI public void addRow(Iterable<?> columnValues) { int start = rowCount * columnCount; int end = start + columnCount; ensureCapacity(end); if (columnValues instanceof ArrayList<?>) { addRow((ArrayList<?>) columnValues, start); return; @@ -166,17 +160,16 @@ public class MatrixBlobCursor extends Ab "columnValues.size() < columnNames.length"); } // Increase row count here in case we encounter an exception. rowCount++; } /** Optimization for {@link ArrayList}. */ - @WrapElementForJNI private void addRow(ArrayList<?> columnValues, int start) { int size = columnValues.size(); if (size != columnCount) { throw new IllegalArgumentException("columnNames.length = " + columnCount + ", columnValues.size() = " + size); } rowCount++;
--- a/mobile/android/base/sqlite/SQLiteBridgeException.java +++ b/mobile/android/base/sqlite/SQLiteBridgeException.java @@ -1,18 +1,15 @@ /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- * 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.sqlite; -import org.mozilla.gecko.mozglue.generatorannotations.WrapEntireClassForJNI; - -@WrapEntireClassForJNI public class SQLiteBridgeException extends RuntimeException { static final long serialVersionUID = 1L; public SQLiteBridgeException() {} public SQLiteBridgeException(String msg) { super(msg); } }
--- a/mobile/android/base/util/Clipboard.java +++ b/mobile/android/base/util/Clipboard.java @@ -4,17 +4,17 @@ package org.mozilla.gecko.util; import android.content.ClipData; import android.content.Context; import android.os.Build; import android.util.Log; -import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; +import org.mozilla.gecko.mozglue.GeneratableAndroidBridgeTarget; import java.util.concurrent.SynchronousQueue; public final class Clipboard { private static Context mContext; private final static String LOG_TAG = "Clipboard"; private final static SynchronousQueue<String> sClipboardQueue = new SynchronousQueue<String>(); @@ -24,17 +24,17 @@ public final class Clipboard { public static void init(Context c) { if (mContext != null) { Log.w(LOG_TAG, "Clipboard.init() called twice!"); return; } mContext = c; } - @WrapElementForJNI(stubName = "GetClipboardTextWrapper") + @GeneratableAndroidBridgeTarget(stubName = "GetClipboardTextWrapper") public static String getText() { // If we're on the UI thread or the background thread, we have a looper on the thread // and can just call this directly. For any other threads, post the call to the // background thread. if (ThreadUtils.isOnUiThread() || ThreadUtils.isOnBackgroundThread()) { return getClipboardTextImpl(); } @@ -50,17 +50,17 @@ public final class Clipboard { }); try { return sClipboardQueue.take(); } catch (InterruptedException ie) { return ""; } } - @WrapElementForJNI(stubName = "SetClipboardText") + @GeneratableAndroidBridgeTarget(stubName = "SetClipboardText") public static void setText(final CharSequence text) { ThreadUtils.postToBackgroundThread(new Runnable() { @Override @SuppressWarnings("deprecation") public void run() { if (Build.VERSION.SDK_INT >= 11) { android.content.ClipboardManager cm = getClipboardManager11(mContext); ClipData clip = ClipData.newPlainText("Text", text); @@ -74,35 +74,16 @@ public final class Clipboard { } else { android.text.ClipboardManager cm = getClipboardManager(mContext); cm.setText(text); } } }); } - /** - * Returns true if the clipboard is nonempty, false otherwise. - * - * @return true if the clipboard is nonempty, false otherwise. - */ - @WrapElementForJNI - public static boolean hasText() { - String text = getText(); - return text != null; - } - - /** - * Deletes all text from the clipboard. - */ - @WrapElementForJNI - public static void clearText() { - setText(null); - } - private static android.content.ClipboardManager getClipboardManager11(Context context) { // In API Level 11 and above, CLIPBOARD_SERVICE returns android.content.ClipboardManager, // which is a subclass of android.text.ClipboardManager. return (android.content.ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE); } private static android.text.ClipboardManager getClipboardManager(Context context) { return (android.text.ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);
--- a/mobile/android/components/build/nsAndroidHistory.cpp +++ b/mobile/android/components/build/nsAndroidHistory.cpp @@ -45,17 +45,20 @@ nsAndroidHistory::RegisterVisitedCallbac nsTArray<Link*>* list = mListeners.Get(uriString); if (! list) { list = new nsTArray<Link*>(); mListeners.Put(uriString, list); } list->AppendElement(aContent); - GeckoAppShell::CheckURIVisited(uriString); + AndroidBridge *bridge = AndroidBridge::Bridge(); + if (bridge) { + bridge->CheckURIVisited(uriString); + } return NS_OK; } NS_IMETHODIMP nsAndroidHistory::UnregisterVisitedCallback(nsIURI *aURI, Link *aContent) { if (!aContent || !aURI) @@ -88,33 +91,37 @@ nsAndroidHistory::VisitURI(nsIURI *aURI, return NS_OK; if (aFlags & VisitFlags::REDIRECT_SOURCE) return NS_OK; if (aFlags & VisitFlags::UNRECOVERABLE_ERROR) return NS_OK; - nsAutoCString uri; - nsresult rv = aURI->GetSpec(uri); - if (NS_FAILED(rv)) return rv; - NS_ConvertUTF8toUTF16 uriString(uri); - GeckoAppShell::MarkURIVisited(uriString); + AndroidBridge *bridge = AndroidBridge::Bridge(); + if (bridge) { + nsAutoCString uri; + nsresult rv = aURI->GetSpec(uri); + if (NS_FAILED(rv)) return rv; + NS_ConvertUTF8toUTF16 uriString(uri); + bridge->MarkURIVisited(uriString); + } return NS_OK; } NS_IMETHODIMP nsAndroidHistory::SetURITitle(nsIURI *aURI, const nsAString& aTitle) { - if (AndroidBridge::Bridge()) { + AndroidBridge *bridge = AndroidBridge::Bridge(); + if (bridge) { nsAutoCString uri; nsresult rv = aURI->GetSpec(uri); if (NS_FAILED(rv)) return rv; NS_ConvertUTF8toUTF16 uriString(uri); - GeckoAppShell::SetURITitle(uriString, aTitle); + bridge->SetURITitle(uriString, aTitle); } return NS_OK; } NS_IMETHODIMP nsAndroidHistory::NotifyVisited(nsIURI *aURI) { if (aURI && sHistory) {
--- a/mobile/android/components/build/nsShellService.cpp +++ b/mobile/android/components/build/nsShellService.cpp @@ -3,27 +3,25 @@ * 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 "nsShellService.h" #include "nsString.h" #include "AndroidBridge.h" -using namespace mozilla::widget::android; - NS_IMPL_ISUPPORTS1(nsShellService, nsIShellService) NS_IMETHODIMP nsShellService::SwitchTask() { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP nsShellService::CreateShortcut(const nsAString& aTitle, const nsAString& aURI, const nsAString& aIconData, const nsAString& aIntent) { if (!aTitle.Length() || !aURI.Length() || !aIconData.Length()) return NS_ERROR_FAILURE; - GeckoAppShell::CreateShortcut(aTitle, aURI, aIconData, aIntent); + mozilla::AndroidBridge::Bridge()->CreateShortcut(aTitle, aURI, aIconData, aIntent); return NS_OK; }
--- a/netwerk/base/src/Tickler.cpp +++ b/netwerk/base/src/Tickler.cpp @@ -75,17 +75,17 @@ nsresult Tickler::Init() { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(!mTimer); MOZ_ASSERT(!mActive); MOZ_ASSERT(!mThread); MOZ_ASSERT(!mFD); - GeckoAppShell::EnableNetworkNotifications(); + AndroidBridge::Bridge()->EnableNetworkNotifications(); mFD = PR_OpenUDPSocket(PR_AF_INET); if (!mFD) return NS_ERROR_FAILURE; // make sure new socket has a ttl of 1 // failure is not fatal. PRSocketOptionData opt;
--- a/netwerk/protocol/device/CameraStreamImpl.cpp +++ b/netwerk/protocol/device/CameraStreamImpl.cpp @@ -85,14 +85,14 @@ bool CameraStreamImpl::Init(const nsCStr { mCallback = aCallback; mWidth = width; mHeight = height; return AndroidBridge::Bridge()->InitCamera(contentType, camera, &mWidth, &mHeight, &mFps); } void CameraStreamImpl::Close() { - GeckoAppShell::CloseCamera(); + AndroidBridge::Bridge()->CloseCamera(); mCallback = nullptr; } } // namespace net } // namespace mozilla
--- a/netwerk/system/android/nsAndroidNetworkLinkService.cpp +++ b/netwerk/system/android/nsAndroidNetworkLinkService.cpp @@ -5,18 +5,16 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsAndroidNetworkLinkService.h" #include "nsServiceManagerUtils.h" #include "mozilla/Services.h" #include "AndroidBridge.h" -using namespace mozilla::widget::android; - NS_IMPL_ISUPPORTS1(nsAndroidNetworkLinkService, nsINetworkLinkService) nsAndroidNetworkLinkService::nsAndroidNetworkLinkService() { } nsAndroidNetworkLinkService::~nsAndroidNetworkLinkService() @@ -28,26 +26,26 @@ nsAndroidNetworkLinkService::GetIsLinkUp { if (!mozilla::AndroidBridge::Bridge()) { // Fail soft here and assume a connection exists NS_WARNING("GetIsLinkUp is not supported without a bridge connection"); *aIsUp = true; return NS_OK; } - *aIsUp = GeckoAppShell::IsNetworkLinkUp(); + *aIsUp = mozilla::AndroidBridge::Bridge()->IsNetworkLinkUp(); return NS_OK; } NS_IMETHODIMP nsAndroidNetworkLinkService::GetLinkStatusKnown(bool *aIsKnown) { NS_ENSURE_TRUE(mozilla::AndroidBridge::Bridge(), NS_ERROR_NOT_IMPLEMENTED); - *aIsKnown = GeckoAppShell::IsNetworkLinkKnown(); + *aIsKnown = mozilla::AndroidBridge::Bridge()->IsNetworkLinkKnown(); return NS_OK; } NS_IMETHODIMP nsAndroidNetworkLinkService::GetLinkType(uint32_t *aLinkType) { NS_ENSURE_ARG_POINTER(aLinkType);
--- a/toolkit/components/alerts/nsAlertsService.cpp +++ b/toolkit/components/alerts/nsAlertsService.cpp @@ -5,17 +5,16 @@ #include "mozilla/dom/ContentChild.h" #include "nsXULAppAPI.h" #include "nsAlertsService.h" #ifdef MOZ_WIDGET_ANDROID #include "AndroidBridge.h" -using namespace mozilla::widget::android; #else #include "nsXPCOM.h" #include "nsIServiceManager.h" #include "nsIDOMWindow.h" #include "nsPromiseFlatString.h" #include "nsToolkitCompsCID.h" @@ -119,17 +118,17 @@ NS_IMETHODIMP nsAlertsService::CloseAler { if (XRE_GetProcessType() == GeckoProcessType_Content) { ContentChild* cpc = ContentChild::GetSingleton(); cpc->SendCloseAlert(nsAutoString(aAlertName)); return NS_OK; } #ifdef MOZ_WIDGET_ANDROID - GeckoAppShell::CloseNotification(aAlertName); + mozilla::AndroidBridge::Bridge()->CloseNotification(aAlertName); return NS_OK; #else // Try the system notification service. nsCOMPtr<nsIAlertsService> sysAlerts(do_GetService(NS_SYSTEMALERTSERVICE_CONTRACTID)); if (sysAlerts) { return sysAlerts->CloseAlert(aAlertName); } @@ -140,24 +139,24 @@ NS_IMETHODIMP nsAlertsService::CloseAler NS_IMETHODIMP nsAlertsService::OnProgress(const nsAString & aAlertName, int64_t aProgress, int64_t aProgressMax, const nsAString & aAlertText) { #ifdef MOZ_WIDGET_ANDROID - GeckoAppShell::AlertsProgressListener_OnProgress(aAlertName, aProgress, aProgressMax, aAlertText); + mozilla::AndroidBridge::Bridge()->AlertsProgressListener_OnProgress(aAlertName, aProgress, aProgressMax, aAlertText); return NS_OK; #else return NS_ERROR_NOT_IMPLEMENTED; #endif // !MOZ_WIDGET_ANDROID } NS_IMETHODIMP nsAlertsService::OnCancel(const nsAString & aAlertName) { #ifdef MOZ_WIDGET_ANDROID - GeckoAppShell::CloseNotification(aAlertName); + mozilla::AndroidBridge::Bridge()->CloseNotification(aAlertName); return NS_OK; #else return NS_ERROR_NOT_IMPLEMENTED; #endif // !MOZ_WIDGET_ANDROID }
--- a/toolkit/components/downloads/nsDownloadManager.cpp +++ b/toolkit/components/downloads/nsDownloadManager.cpp @@ -46,17 +46,16 @@ #endif #ifdef XP_MACOSX #include <CoreFoundation/CoreFoundation.h> #endif #ifdef MOZ_WIDGET_ANDROID #include "AndroidBridge.h" -using namespace mozilla::widget::android; #endif #ifdef MOZ_WIDGET_GTK #include <gtk/gtk.h> #endif using namespace mozilla; using mozilla::downloads::GenerateGUID; @@ -2771,17 +2770,17 @@ nsDownload::SetState(DownloadState aStat #ifdef MOZ_WIDGET_ANDROID nsCOMPtr<nsIMIMEInfo> mimeInfo; nsAutoCString contentType; GetMIMEInfo(getter_AddRefs(mimeInfo)); if (mimeInfo) mimeInfo->GetMIMEType(contentType); - GeckoAppShell::ScanMedia(path, NS_ConvertUTF8toUTF16(contentType)); + mozilla::AndroidBridge::Bridge()->ScanMedia(path, NS_ConvertUTF8toUTF16(contentType)); #endif } #ifdef XP_WIN // Adjust file attributes so that by default, new files are indexed // by desktop search services. Skip off those that land in the temp // folder. nsCOMPtr<nsIFile> tempDir, fileDir;
--- a/toolkit/components/jsdownloads/src/DownloadPlatform.cpp +++ b/toolkit/components/jsdownloads/src/DownloadPlatform.cpp @@ -113,17 +113,17 @@ nsresult DownloadPlatform::DownloadDone( kCFStringEncodingUTF8); CFNotificationCenterRef center = ::CFNotificationCenterGetDistributedCenter(); ::CFNotificationCenterPostNotification(center, CFSTR("com.apple.DownloadFileFinished"), observedObject, NULL, TRUE); ::CFRelease(observedObject); #endif #ifdef MOZ_WIDGET_ANDROID if (!aContentType.IsEmpty()) { - mozilla::widget::android::GeckoAppShell::ScanMedia(path, NS_ConvertUTF8toUTF16(aContentType)); + mozilla::AndroidBridge::Bridge()->ScanMedia(path, NS_ConvertUTF8toUTF16(aContentType)); } #endif } #ifdef XP_WIN // Adjust file attributes so that by default, new files are indexed by // desktop search services. Skip off those that land in the temp folder. nsCOMPtr<nsIFile> tempDir, fileDir;
--- a/toolkit/xre/nsAndroidStartup.cpp +++ b/toolkit/xre/nsAndroidStartup.cpp @@ -70,14 +70,14 @@ GeckoStart(void *data, const nsXREAppDat } targs.AppendElement(static_cast<char *>(nullptr)); int result = XRE_main(targs.Length() - 1, targs.Elements(), appData, 0); if (result) LOG("XRE_main returned %d", result); - mozilla::widget::android::GeckoAppShell::NotifyXreExit(); + mozilla::AndroidBridge::Bridge()->NotifyXreExit(); free(targs[0]); nsMemory::Free(data); return; }
--- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -1642,17 +1642,17 @@ static nsresult LaunchChild(nsINativeApp gRestartArgc = 1; gRestartArgv[gRestartArgc] = nullptr; #endif } SaveToEnv("MOZ_LAUNCHED_CHILD=1"); #if defined(MOZ_WIDGET_ANDROID) - mozilla::widget::android::GeckoAppShell::ScheduleRestart(); + mozilla::AndroidBridge::Bridge()->ScheduleRestart(); #else #if defined(XP_MACOSX) CommandLineServiceMac::SetupMacCommandLine(gRestartArgc, gRestartArgv, true); uint32_t restartMode = 0; restartMode = gRestartMode; LaunchChildMac(gRestartArgc, gRestartArgv, restartMode); #else nsCOMPtr<nsIFile> lf; @@ -1754,17 +1754,17 @@ ProfileLockedDialog(nsIFile* aProfileDir nsCOMPtr<nsIPromptService> ps (do_GetService(NS_PROMPTSERVICE_CONTRACTID)); NS_ENSURE_TRUE(ps, NS_ERROR_FAILURE); if (aUnlocker) { int32_t button; #ifdef MOZ_WIDGET_ANDROID - mozilla::widget::android::GeckoAppShell::KillAnyZombies(); + mozilla::AndroidBridge::Bridge()->KillAnyZombies(); button = 1; #else const uint32_t flags = (nsIPromptService::BUTTON_TITLE_CANCEL * nsIPromptService::BUTTON_POS_0) + (nsIPromptService::BUTTON_TITLE_IS_STRING * nsIPromptService::BUTTON_POS_1) + nsIPromptService::BUTTON_POS_1_DEFAULT; @@ -1781,17 +1781,17 @@ ProfileLockedDialog(nsIFile* aProfileDir if (NS_FAILED(rv)) return rv; return NS_LockProfilePath(aProfileDir, aProfileLocalDir, nullptr, aResult); } } else { #ifdef MOZ_WIDGET_ANDROID - if (mozilla::widget::android::GeckoAppShell::UnlockProfile()) { + if (mozilla::AndroidBridge::Bridge()->UnlockProfile()) { return NS_LockProfilePath(aProfileDir, aProfileLocalDir, nullptr, aResult); } #else rv = ps->Alert(nullptr, killTitle, killMessage); NS_ENSURE_SUCCESS_LOG(rv, rv); #endif }
--- a/tools/profiler/TableTicker.cpp +++ b/tools/profiler/TableTicker.cpp @@ -225,17 +225,17 @@ typename Builder::Object BuildJavaThread break; } if (!sample) { sample = b.CreateObject(); frames = b.CreateArray(); b.DefineProperty(sample, "frames", frames); b.ArrayPush(samples, sample); - double sampleTime = GeckoJavaSampler::GetSampleTimeJavaProfiling(0, sampleId); + double sampleTime = AndroidBridge::Bridge()->GetSampleTimeJavaProfiling(0, sampleId); b.DefineProperty(sample, "time", sampleTime); } typename Builder::RootedObject frame(b.context(), b.CreateObject()); b.DefineProperty(frame, "location", result.BeginReading()); b.ArrayPush(frames, frame); frameId++; } if (frameId == 0) { @@ -277,22 +277,22 @@ void TableTicker::BuildJSObject(Builder& typename Builder::RootedObject threadSamples(b.context(), b.CreateObject()); sRegisteredThreads->at(i)->Profile()->BuildJSObject(b, threadSamples); b.ArrayPush(threads, threadSamples); } } #if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK) if (ProfileJava()) { - GeckoJavaSampler::PauseJavaProfiling(); + AndroidBridge::Bridge()->PauseJavaProfiling(); typename Builder::RootedObject javaThread(b.context(), BuildJavaThreadJSObject(b)); b.ArrayPush(threads, javaThread); - GeckoJavaSampler::UnpauseJavaProfiling(); + AndroidBridge::Bridge()->UnpauseJavaProfiling(); } #endif SetPaused(false); // Send a event asking any subprocesses (plugins) to // give us their information SubprocessClosure<Builder> closure(&b, threads);
--- a/tools/profiler/platform.cpp +++ b/tools/profiler/platform.cpp @@ -22,17 +22,16 @@ #include "nsDirectoryServiceUtils.h" #include "nsDirectoryServiceDefs.h" #include "mozilla/Services.h" #include "nsThreadUtils.h" #include "ProfilerMarkers.h" #if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK) #include "AndroidBridge.h" - using namespace mozilla::widget::android; #endif mozilla::ThreadLocal<PseudoStack *> tlsPseudoStack; mozilla::ThreadLocal<TableTicker *> tlsTicker; mozilla::ThreadLocal<void *> tlsStackTop; // We need to track whether we've been initialized otherwise // we end up using tlsStack without initializing it. // Because tlsStack is totally opaque to us we can't reuse @@ -594,17 +593,17 @@ void mozilla_sampler_start(int aProfileE #if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK) if (t->ProfileJava()) { int javaInterval = aInterval; // Java sampling doesn't accuratly keep up with 1ms sampling if (javaInterval < 10) { aInterval = 10; } - GeckoJavaSampler::StartJavaProfiling(javaInterval, 1000); + mozilla::AndroidBridge::Bridge()->StartJavaProfiling(javaInterval, 1000); } #endif if (t->AddMainThreadIO()) { if (!sInterposeObserver) { // Lazily create IO interposer observer sInterposeObserver = new mozilla::ProfilerIOInterposeObserver(); }
--- a/uriloader/exthandler/android/nsAndroidHandlerApp.cpp +++ b/uriloader/exthandler/android/nsAndroidHandlerApp.cpp @@ -1,18 +1,16 @@ /* -*- Mode: c++; c-basic-offset: 2; tab-width: 20; indent-tabs-mode: nil; -*- * 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 "nsAndroidHandlerApp.h" #include "AndroidBridge.h" -using namespace mozilla::widget::android; - NS_IMPL_ISUPPORTS2(nsAndroidHandlerApp, nsIHandlerApp, nsISharingHandlerApp) nsAndroidHandlerApp::nsAndroidHandlerApp(const nsAString& aName, const nsAString& aDescription, const nsAString& aPackageName, const nsAString& aClassName, const nsACString& aMimeType, @@ -62,21 +60,29 @@ nsAndroidHandlerApp::Equals(nsIHandlerAp *aRetval = aApp && aApp->mName.Equals(mName) && aApp->mDescription.Equals(mDescription); return NS_OK; } NS_IMETHODIMP nsAndroidHandlerApp::LaunchWithURI(nsIURI *aURI, nsIInterfaceRequestor *aWindowContext) { + if (!mozilla::AndroidBridge::Bridge()) + return NS_ERROR_FAILURE; + nsCString uriSpec; aURI->GetSpec(uriSpec); - return GeckoAppShell::OpenUriExternal(NS_ConvertUTF8toUTF16(uriSpec), NS_ConvertUTF8toUTF16(mMimeType), mPackageName, mClassName, mAction) ? + return mozilla::AndroidBridge::Bridge()-> + OpenUriExternal(NS_ConvertUTF8toUTF16(uriSpec), NS_ConvertUTF8toUTF16(mMimeType), mPackageName, mClassName, mAction) ? NS_OK : NS_ERROR_FAILURE; } NS_IMETHODIMP nsAndroidHandlerApp::Share(const nsAString & data, const nsAString & title) { - return GeckoAppShell::OpenUriExternal(data, NS_ConvertUTF8toUTF16(mMimeType), mPackageName, + if (!mozilla::AndroidBridge::Bridge()) + return NS_ERROR_FAILURE; + + return mozilla::AndroidBridge::Bridge()-> + OpenUriExternal(data, NS_ConvertUTF8toUTF16(mMimeType), mPackageName, mClassName, mAction) ? NS_OK : NS_ERROR_FAILURE; }
--- a/uriloader/exthandler/android/nsExternalSharingAppService.cpp +++ b/uriloader/exthandler/android/nsExternalSharingAppService.cpp @@ -26,17 +26,22 @@ nsExternalSharingAppService::~nsExternal NS_IMETHODIMP nsExternalSharingAppService::ShareWithDefault(const nsAString & data, const nsAString & mime, const nsAString & title) { NS_NAMED_LITERAL_STRING(sendAction, "android.intent.action.SEND"); const nsString emptyString = EmptyString(); - return GeckoAppShell::OpenUriExternal(data, mime, emptyString,emptyString, sendAction, title) ? NS_OK : NS_ERROR_FAILURE; + if (AndroidBridge::Bridge()) + return AndroidBridge::Bridge()-> + OpenUriExternal(data, mime, + emptyString,emptyString, sendAction, title) ? NS_OK : NS_ERROR_FAILURE; + + return NS_ERROR_FAILURE; } NS_IMETHODIMP nsExternalSharingAppService::GetSharingApps(const nsAString & aMIMEType, uint32_t *aLen, nsISharingHandlerApp ***aHandlers) { nsresult rv;
--- a/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp +++ b/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp @@ -5,18 +5,16 @@ #include "nsMIMEInfoAndroid.h" #include "AndroidBridge.h" #include "nsAndroidHandlerApp.h" #include "nsArrayUtils.h" #include "nsISupportsUtils.h" #include "nsStringEnumerator.h" #include "nsNetUtil.h" -using namespace mozilla::widget::android; - NS_IMPL_ISUPPORTS2(nsMIMEInfoAndroid, nsIMIMEInfo, nsIHandlerInfo) NS_IMETHODIMP nsMIMEInfoAndroid::LaunchDefaultWithFile(nsIFile* aFile) { LaunchWithFile(aFile); return NS_OK; } @@ -25,17 +23,21 @@ NS_IMETHODIMP nsMIMEInfoAndroid::LoadUriInternal(nsIURI * aURI) { nsCString uriSpec; aURI->GetSpec(uriSpec); nsCString uriScheme; aURI->GetScheme(uriScheme); - return GeckoAppShell::OpenUriExternal(NS_ConvertUTF8toUTF16(uriSpec), (mType.Equals(uriScheme) || mType.Equals(uriSpec)) ? EmptyString() : NS_ConvertUTF8toUTF16(mType)) ? NS_OK : NS_ERROR_FAILURE; + if (mozilla::AndroidBridge::Bridge()) + return mozilla::AndroidBridge::Bridge()-> + OpenUriExternal(NS_ConvertUTF8toUTF16(uriSpec), (mType.Equals(uriScheme) || mType.Equals(uriSpec)) ? EmptyString() : NS_ConvertUTF8toUTF16(mType)) ? NS_OK : NS_ERROR_FAILURE; + + return NS_ERROR_FAILURE; } bool nsMIMEInfoAndroid::GetMimeInfoForMimeType(const nsACString& aMimeType, nsMIMEInfoAndroid** aMimeInfo) { nsRefPtr<nsMIMEInfoAndroid> info = new nsMIMEInfoAndroid(aMimeType);
--- a/widget/android/AndroidBridge.cpp +++ b/widget/android/AndroidBridge.cpp @@ -32,18 +32,23 @@ #include "nsPIDOMWindow.h" #include "mozilla/dom/ScreenOrientation.h" #include "nsIDOMWindowUtils.h" #include "nsIDOMClientRect.h" #include "StrongPointer.h" #include "mozilla/ClearOnShutdown.h" #include "nsPrintfCString.h" +#ifdef DEBUG +#define ALOG_BRIDGE(args...) ALOG(args) +#else +#define ALOG_BRIDGE(args...) ((void)0) +#endif + using namespace mozilla; -using namespace mozilla::widget::android; NS_IMPL_ISUPPORTS0(nsFilePickerCallback) StaticRefPtr<AndroidBridge> AndroidBridge::sBridge; static unsigned sJavaEnvThreadIndex = 0; static jobject sGlobalContext = nullptr; static void JavaThreadDetachFunc(void *arg); @@ -157,23 +162,24 @@ AndroidBridge::Init(JNIEnv *jEnv) { ALOG_BRIDGE("AndroidBridge::Init"); jEnv->GetJavaVM(&mJavaVM); AutoLocalJNIFrame jniFrame(jEnv); mJNIEnv = nullptr; mThread = -1; - mGLControllerObj = NULL; + mGLControllerObj = nullptr; mOpenedGraphicsLibraries = false; mHasNativeBitmapAccess = false; mHasNativeWindowAccess = false; mHasNativeWindowFallback = false; initInit(); + InitStubs(jEnv); #ifdef MOZ_WEBSMS_BACKEND mAndroidSmsMessageClass = getClassGlobalRef("android/telephony/SmsMessage"); jCalculateLength = getStaticMethod("calculateLength", "(Ljava/lang/CharSequence;Z)[I"); #endif jStringClass = getClassGlobalRef("java/lang/String"); @@ -261,62 +267,16 @@ jstring AndroidBridge::NewJavaString(Aut jstring AndroidBridge::NewJavaString(AutoLocalJNIFrame* frame, const char* string) { return NewJavaString(frame, NS_ConvertUTF8toUTF16(string)); } jstring AndroidBridge::NewJavaString(AutoLocalJNIFrame* frame, const nsACString& string) { return NewJavaString(frame, NS_ConvertUTF8toUTF16(string)); } -extern "C" { - __attribute__ ((visibility("default"))) - JNIEnv * GetJNIForThread() - { - JNIEnv *jEnv = NULL; - JavaVM *jVm = mozilla::AndroidBridge::GetVM(); - if (!jVm) { - __android_log_print(ANDROID_LOG_INFO, "GetJNIForThread", "Returned a null VM"); - return NULL; - } - jEnv = static_cast<JNIEnv*>(PR_GetThreadPrivate(sJavaEnvThreadIndex)); - - if (jEnv) - return jEnv; - - int status = jVm->GetEnv((void**) &jEnv, JNI_VERSION_1_2); - if (status) { - - status = jVm->AttachCurrentThread(&jEnv, NULL); - if (status) { - __android_log_print(ANDROID_LOG_INFO, "GetJNIForThread", "Could not attach"); - return NULL; - } - - PR_SetThreadPrivate(sJavaEnvThreadIndex, jEnv); - } - if (!jEnv) { - __android_log_print(ANDROID_LOG_INFO, "GetJNIForThread", "returning NULL"); - } - return jEnv; - } -} - -void AutoGlobalWrappedJavaObject::Dispose() { - if (isNull()) { - return; - } - - GetJNIForThread()->DeleteGlobalRef(wrapped_obj); - wrapped_obj = NULL; -} - -AutoGlobalWrappedJavaObject::~AutoGlobalWrappedJavaObject() { - Dispose(); -} - static void getHandlersFromStringArray(JNIEnv *aJNIEnv, jobjectArray jArr, jsize aLen, nsIMutableArray *aHandlersArray, nsIHandlerApp **aDefaultApp, const nsAString& aAction = EmptyString(), const nsACString& aMimeType = EmptyCString()) { nsString empty = EmptyString(); @@ -346,17 +306,17 @@ AndroidBridge::GetHandlersForMimeType(co const nsAString& aAction) { ALOG_BRIDGE("AndroidBridge::GetHandlersForMimeType"); JNIEnv *env = GetJNIEnv(); if (!env) return false; - jobjectArray arr = GeckoAppShell::GetHandlersForMimeTypeWrapper(aMimeType, aAction); + jobjectArray arr = GetHandlersForMimeTypeWrapper(aMimeType, aAction); if (!arr) return false; jsize len = env->GetArrayLength(arr); if (!aHandlersArray) return len > 0; @@ -375,17 +335,17 @@ AndroidBridge::GetHandlersForURL(const n const nsAString& aAction) { ALOG_BRIDGE("AndroidBridge::GetHandlersForURL"); JNIEnv *env = GetJNIEnv(); if (!env) return false; - jobjectArray arr = GeckoAppShell::GetHandlersForURLWrapper(aURL, aAction); + jobjectArray arr = GetHandlersForURLWrapper(aURL, aAction); if (!arr) return false; jsize len = env->GetArrayLength(arr); if (!aHandlersArray) return len > 0; @@ -400,17 +360,17 @@ void AndroidBridge::GetMimeTypeFromExtensions(const nsACString& aFileExt, nsCString& aMimeType) { ALOG_BRIDGE("AndroidBridge::GetMimeTypeFromExtensions"); JNIEnv *env = GetJNIEnv(); if (!env) return; - jstring jstrType = GeckoAppShell::GetMimeTypeFromExtensionsWrapper(NS_ConvertUTF8toUTF16(aFileExt)); + jstring jstrType = GetMimeTypeFromExtensionsWrapper(NS_ConvertUTF8toUTF16(aFileExt)); if (!jstrType) { return; } nsJNIString jniStr(jstrType, env); CopyUTF16toUTF8(jniStr.get(), aMimeType); env->DeleteLocalRef(jstrType); } @@ -419,17 +379,17 @@ void AndroidBridge::GetExtensionFromMimeType(const nsACString& aMimeType, nsACString& aFileExt) { ALOG_BRIDGE("AndroidBridge::GetExtensionFromMimeType"); JNIEnv *env = GetJNIEnv(); if (!env) return; - jstring jstrExt = GeckoAppShell::GetExtensionFromMimeTypeWrapper(NS_ConvertUTF8toUTF16(aMimeType)); + jstring jstrExt = GetExtensionFromMimeTypeWrapper(NS_ConvertUTF8toUTF16(aMimeType)); if (!jstrExt) { return; } nsJNIString jniStr(jstrExt, env); CopyUTF16toUTF8(jniStr.get(), aFileExt); env->DeleteLocalRef(jstrExt); } @@ -438,53 +398,83 @@ bool AndroidBridge::GetClipboardText(nsAString& aText) { ALOG_BRIDGE("AndroidBridge::GetClipboardText"); JNIEnv *env = GetJNIEnv(); if (!env) return false; - jstring result = Clipboard::GetClipboardTextWrapper(); + jstring result = GetClipboardTextWrapper(); if (!result) return false; nsJNIString jniStr(result, env); aText.Assign(jniStr); env->DeleteLocalRef(result); return true; } +bool +AndroidBridge::ClipboardHasText() +{ + ALOG_BRIDGE("AndroidBridge::ClipboardHasText"); + + JNIEnv *env = GetJNIEnv(); + if (!env) + return false; + + AutoLocalJNIFrame jniFrame(env); + + jstring jStr = GetClipboardTextWrapper(); + bool ret = jStr; + + return ret; +} + +void +AndroidBridge::EmptyClipboard() +{ + ALOG_BRIDGE("AndroidBridge::EmptyClipboard"); + + JNIEnv *env = GetJNIEnv(); + if (!env) + return; + + AutoLocalJNIFrame jniFrame(env, 0); + env->CallStaticVoidMethod(mClipboardClass, jSetClipboardText, nullptr); +} + void AndroidBridge::ShowAlertNotification(const nsAString& aImageUrl, const nsAString& aAlertTitle, const nsAString& aAlertText, const nsAString& aAlertCookie, nsIObserver *aAlertListener, const nsAString& aAlertName) { if (nsAppShell::gAppShell && aAlertListener) { // This will remove any observers already registered for this id nsAppShell::gAppShell->PostEvent(AndroidGeckoEvent::MakeAddObserver(aAlertName, aAlertListener)); } - GeckoAppShell::ShowAlertNotificationWrapper(aImageUrl, aAlertTitle, aAlertText, aAlertCookie, aAlertName); + ShowAlertNotificationWrapper(aImageUrl, aAlertTitle, aAlertText, aAlertCookie, aAlertName); } int AndroidBridge::GetDPI() { static int sDPI = 0; if (sDPI) return sDPI; const int DEFAULT_DPI = 160; - sDPI = GeckoAppShell::GetDpiWrapper(); + sDPI = GetDpiWrapper(); if (!sDPI) { return DEFAULT_DPI; } return sDPI; } int @@ -493,60 +483,72 @@ AndroidBridge::GetScreenDepth() ALOG_BRIDGE("%s", __PRETTY_FUNCTION__); static int sDepth = 0; if (sDepth) return sDepth; const int DEFAULT_DEPTH = 16; - sDepth = GeckoAppShell::GetScreenDepthWrapper(); + sDepth = GetScreenDepthWrapper(); if (!sDepth) return DEFAULT_DEPTH; return sDepth; } void AndroidBridge::ShowFilePickerForExtensions(nsAString& aFilePath, const nsAString& aExtensions) { JNIEnv *env = GetJNIEnv(); if (!env) return; - jstring jstr = GeckoAppShell::ShowFilePickerForExtensionsWrapper(aExtensions); + jstring jstr = ShowFilePickerForExtensionsWrapper(aExtensions); if (jstr == nullptr) { return; } aFilePath.Assign(nsJNIString(jstr, env)); env->DeleteLocalRef(jstr); } void AndroidBridge::ShowFilePickerForMimeType(nsAString& aFilePath, const nsAString& aMimeType) { JNIEnv *env = GetJNIEnv(); if (!env) return; - jstring jstr = GeckoAppShell::ShowFilePickerForMimeTypeWrapper(aMimeType); + jstring jstr = ShowFilePickerForMimeTypeWrapper(aMimeType); if (jstr == nullptr) { return; } aFilePath.Assign(nsJNIString(jstr, env)); env->DeleteLocalRef(jstr); } void AndroidBridge::ShowFilePickerAsync(const nsAString& aMimeType, nsFilePickerCallback* callback) { callback->AddRef(); - GeckoAppShell::ShowFilePickerAsyncWrapper(aMimeType, (int64_t) callback); + ShowFilePickerAsyncWrapper(aMimeType, (int64_t) callback); +} + +void +AndroidBridge::HideProgressDialogOnce() +{ + static bool once = false; + if (once) + return; + + HideProgressDialog(); + + once = true; } void AndroidBridge::Vibrate(const nsTArray<uint32_t>& aPattern) { ALOG_BRIDGE("%s", __PRETTY_FUNCTION__); uint32_t len = aPattern.Length(); @@ -564,17 +566,17 @@ AndroidBridge::Vibrate(const nsTArray<ui // It's clear if this worth special-casing, but it creates less // java junk, so dodges the GC. if (len == 1) { jlong d = aPattern[0]; if (d < 0) { ALOG_BRIDGE(" invalid vibration duration < 0"); return; } - GeckoAppShell::Vibrate1(d); + Vibrate1(d); return; } // First element of the array vibrate() expects is how long to wait // *before* vibrating. For us, this is always 0. jlongArray array = env->NewLongArray(len + 1); if (!array) { @@ -590,34 +592,34 @@ AndroidBridge::Vibrate(const nsTArray<ui ALOG_BRIDGE(" invalid vibration duration < 0"); env->ReleaseLongArrayElements(array, elts, JNI_ABORT); return; } elts[i + 1] = d; } env->ReleaseLongArrayElements(array, elts, 0); - GeckoAppShell::VibrateA(array, -1/*don't repeat*/); + VibrateA(array, -1/*don't repeat*/); } void AndroidBridge::GetSystemColors(AndroidSystemColors *aColors) { NS_ASSERTION(aColors != nullptr, "AndroidBridge::GetSystemColors: aColors is null!"); if (!aColors) return; JNIEnv *env = GetJNIEnv(); if (!env) return; AutoLocalJNIFrame jniFrame(env); - jintArray arr = GeckoAppShell::GetSystemColoursWrapper(); + jintArray arr = GetSystemColoursWrapper(); if (!arr) return; uint32_t len = static_cast<uint32_t>(env->GetArrayLength(arr)); jint *elements = env->GetIntArrayElements(arr, 0); uint32_t colorsCount = sizeof(AndroidSystemColors) / sizeof(nscolor); if (len < colorsCount) @@ -645,17 +647,17 @@ AndroidBridge::GetIconForExtension(const return; JNIEnv *env = GetJNIEnv(); if (!env) return; AutoLocalJNIFrame jniFrame(env); - jbyteArray arr = GeckoAppShell::GetIconForExtensionWrapper(NS_ConvertUTF8toUTF16(aFileExt), aIconSize); + jbyteArray arr = GetIconForExtensionWrapper(NS_ConvertUTF8toUTF16(aFileExt), aIconSize); NS_ASSERTION(arr != nullptr, "AndroidBridge::GetIconForExtension: Returned pixels array is null!"); if (!arr) return; uint32_t len = static_cast<uint32_t>(env->GetArrayLength(arr)); jbyte *elements = env->GetByteArrayElements(arr, 0); @@ -673,60 +675,72 @@ AndroidBridge::SetLayerClient(JNIEnv* en // if resetting is true, that means Android destroyed our GeckoApp activity // and we had to recreate it, but all the Gecko-side things were not destroyed. // We therefore need to link up the new java objects to Gecko, and that's what // we do here. bool resetting = (mLayerClient != NULL); if (resetting) { // clear out the old layer client + env->DeleteGlobalRef(mLayerClient->wrappedObject()); delete mLayerClient; mLayerClient = NULL; } - mLayerClient = GeckoLayerClient::Wrap(jobj); + AndroidGeckoLayerClient *client = new AndroidGeckoLayerClient(); + client->Init(env->NewGlobalRef(jobj)); + mLayerClient = client; if (resetting) { // since we are re-linking the new java objects to Gecko, we need to get // the viewport from the compositor (since the Java copy was thrown away) // and we do that by setting the first-paint flag. nsWindow::ForceIsFirstPaint(); } } void AndroidBridge::RegisterCompositor(JNIEnv *env) { - if (mGLControllerObj != NULL && !mGLControllerObj->isNull()) { + ALOG_BRIDGE("AndroidBridge::RegisterCompositor"); + if (mGLControllerObj) { // we already have this set up, no need to do it again return; } - jobject glController = LayerView::RegisterCompositorWrapper(); + if (!env) { + env = GetJNIForThread(); // called on the compositor thread + } + if (!env) { + return; + } + + jobject glController = RegisterCompositorWrapper(); if (!glController) { return; } - mGLControllerObj = GLController::Wrap(glController); + mGLControllerObj = env->NewGlobalRef(glController); + env->DeleteLocalRef(glController); } EGLSurface AndroidBridge::ProvideEGLSurface() { if (!jEGLSurfacePointerField) { return NULL; } MOZ_ASSERT(mGLControllerObj, "AndroidBridge::ProvideEGLSurface called with a null GL controller ref"); JNIEnv* env = GetJNIForThread(); // called on the compositor thread if (!env) { return NULL; } - jobject eglSurface = mGLControllerObj->ProvideEGLSurfaceWrapper(); + jobject eglSurface = ProvideEGLSurfaceWrapper(mGLControllerObj); if (!eglSurface) return NULL; EGLSurface ret = reinterpret_cast<EGLSurface>(env->GetIntField(eglSurface, jEGLSurfacePointerField)); env->DeleteLocalRef(eglSurface); return ret; } @@ -788,16 +802,21 @@ AndroidBridge::GetStaticStringField(cons // Available for places elsewhere in the code to link to. bool mozilla_AndroidBridge_SetMainThread(pthread_t thr) { return AndroidBridge::Bridge()->SetMainThread(thr); } +jclass GetGeckoAppShellClass() +{ + return mozilla::AndroidBridge::GetGeckoAppShellClass(); +} + void* AndroidBridge::GetNativeSurface(JNIEnv* env, jobject surface) { if (!env || !mHasNativeWindowFallback || !jSurfacePointerField) return nullptr; return (void*)env->GetIntField(surface, jSurfacePointerField); } @@ -984,17 +1003,17 @@ AndroidBridge::ValidateBitmap(jobject bi bool AndroidBridge::InitCamera(const nsCString& contentType, uint32_t camera, uint32_t *width, uint32_t *height, uint32_t *fps) { JNIEnv *env = GetJNIEnv(); if (!env) return false; AutoLocalJNIFrame jniFrame(env); - jintArray arr = GeckoAppShell::InitCameraWrapper(NS_ConvertUTF8toUTF16(contentType), (int32_t) camera, (int32_t) width, (int32_t) height); + jintArray arr = InitCameraWrapper(NS_ConvertUTF8toUTF16(contentType), (int32_t) camera, (int32_t) width, (int32_t) height); if (!arr) return false; jint *elements = env->GetIntArrayElements(arr, 0); *width = elements[1]; *height = elements[2]; @@ -1015,17 +1034,17 @@ AndroidBridge::GetCurrentBatteryInformat JNIEnv *env = GetJNIEnv(); if (!env) return; AutoLocalJNIFrame jniFrame(env); // To prevent calling too many methods through JNI, the Java method returns // an array of double even if we actually want a double and a boolean. - jdoubleArray arr = GeckoAppShell::GetCurrentBatteryInformationWrapper(); + jdoubleArray arr = GetCurrentBatteryInformationWrapper(); if (!arr || env->GetArrayLength(arr) != 3) { return; } jdouble* info = env->GetDoubleArrayElements(arr, 0); aBatteryInfo->level() = info[0]; aBatteryInfo->charging() = info[1] == 1.0f; @@ -1039,17 +1058,17 @@ AndroidBridge::HandleGeckoMessage(const { ALOG_BRIDGE("%s", __PRETTY_FUNCTION__); JNIEnv *env = GetJNIEnv(); if (!env) return; AutoLocalJNIFrame jniFrame(env); - jstring returnMessage = GeckoAppShell::HandleGeckoMessageWrapper(aMessage); + jstring returnMessage = HandleGeckoMessageWrapper(aMessage); if (!returnMessage) return; nsJNIString jniStr(returnMessage, env); aRet.Assign(jniStr); ALOG_BRIDGE("leaving %s", __PRETTY_FUNCTION__); } @@ -1106,41 +1125,41 @@ AndroidBridge::SendMessage(const nsAStri nsIMobileMessageCallback* aRequest) { ALOG_BRIDGE("AndroidBridge::SendMessage"); uint32_t requestId; if (!QueueSmsRequest(aRequest, &requestId)) return; - GeckoAppShell::SendMessageWrapper(aNumber, aMessage, requestId); + SendMessageWrapper(aNumber, aMessage, requestId); } void AndroidBridge::GetMessage(int32_t aMessageId, nsIMobileMessageCallback* aRequest) { ALOG_BRIDGE("AndroidBridge::GetMessage"); uint32_t requestId; if (!QueueSmsRequest(aRequest, &requestId)) return; - GeckoAppShell::GetMessageWrapper(aMessageId, requestId); + GetMessageWrapper(aMessageId, requestId); } void AndroidBridge::DeleteMessage(int32_t aMessageId, nsIMobileMessageCallback* aRequest) { ALOG_BRIDGE("AndroidBridge::DeleteMessage"); uint32_t requestId; if (!QueueSmsRequest(aRequest, &requestId)) return; - GeckoAppShell::DeleteMessageWrapper(aMessageId, requestId); + DeleteMessageWrapper(aMessageId, requestId); } void AndroidBridge::CreateMessageList(const dom::mobilemessage::SmsFilterData& aFilter, bool aReverse, nsIMobileMessageCallback* aRequest) { ALOG_BRIDGE("AndroidBridge::CreateMessageList"); @@ -1159,31 +1178,31 @@ AndroidBridge::CreateMessageList(const d jStringClass, NewJavaString(&jniFrame, EmptyString())); for (uint32_t i = 0; i < aFilter.numbers().Length(); ++i) { env->SetObjectArrayElement(numbers, i, NewJavaString(&jniFrame, aFilter.numbers()[i])); } - GeckoAppShell::CreateMessageListWrapper(aFilter.startDate(), aFilter.endDate(), + CreateMessageListWrapper(aFilter.startDate(), aFilter.endDate(), numbers, aFilter.numbers().Length(), aFilter.delivery(), aReverse, requestId); } void AndroidBridge::GetNextMessageInList(int32_t aListId, nsIMobileMessageCallback* aRequest) { ALOG_BRIDGE("AndroidBridge::GetNextMessageInList"); uint32_t requestId; if (!QueueSmsRequest(aRequest, &requestId)) return; - GeckoAppShell::GetNextMessageInListWrapper(aListId, requestId); + GetNextMessageInListWrapper(aListId, requestId); } bool AndroidBridge::QueueSmsRequest(nsIMobileMessageCallback* aRequest, uint32_t* aRequestIdOut) { MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); MOZ_ASSERT(aRequest && aRequestIdOut); @@ -1225,17 +1244,17 @@ AndroidBridge::GetCurrentNetworkInformat if (!env) return; AutoLocalJNIFrame jniFrame(env); // To prevent calling too many methods through JNI, the Java method returns // an array of double even if we actually want a double, two booleans, and an integer. - jdoubleArray arr = GeckoAppShell::GetCurrentNetworkInformationWrapper(); + jdoubleArray arr = GetCurrentNetworkInformationWrapper(); if (!arr || env->GetArrayLength(arr) != 4) { return; } jdouble* info = env->GetDoubleArrayElements(arr, 0); aNetworkInfo->bandwidth() = info[0]; aNetworkInfo->canBeMetered() = info[1] == 1.0f; @@ -1418,17 +1437,17 @@ jobject AndroidBridge::GetGlobalContextRef() { if (sGlobalContext == nullptr) { JNIEnv *env = GetJNIForThread(); if (!env) return 0; AutoLocalJNIFrame jniFrame(env, 4); - jobject context = GeckoAppShell::GetContext(); + jobject context = GetContext(); if (!context) { ALOG_BRIDGE("%s: Could not GetContext()", __FUNCTION__); return 0; } jclass contextClass = env->FindClass("android/content/Context"); if (!contextClass) { ALOG_BRIDGE("%s: Could not find Context class.", __FUNCTION__); return 0; @@ -1469,109 +1488,58 @@ AndroidBridge::UnlockWindow(void* window } return true; } void AndroidBridge::SetFirstPaintViewport(const LayerIntPoint& aOffset, const CSSToLayerScale& aZoom, const CSSRect& aCssPageRect) { - GeckoLayerClient *client = mLayerClient; + AndroidGeckoLayerClient *client = mLayerClient; if (!client) return; - client->SetFirstPaintViewport((float)aOffset.x, (float)aOffset.y, aZoom.scale, - aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost()); + client->SetFirstPaintViewport(aOffset, aZoom, aCssPageRect); } void AndroidBridge::SetPageRect(const CSSRect& aCssPageRect) { - GeckoLayerClient *client = mLayerClient; + AndroidGeckoLayerClient *client = mLayerClient; if (!client) return; - client->SetPageRect(aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost()); + client->SetPageRect(aCssPageRect); } void AndroidBridge::SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution, bool aLayersUpdated, ScreenPoint& aScrollOffset, CSSToScreenScale& aScale, LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset) { - ALOG_BRIDGE("Enter: %s", __PRETTY_FUNCTION__); - GeckoLayerClient *client = mLayerClient; - if (!client) { - ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__); + AndroidGeckoLayerClient *client = mLayerClient; + if (!client) return; - } - - jobject viewTransformJObj = client->SyncViewportInfo(aDisplayPort.x, aDisplayPort.y, - aDisplayPort.width, aDisplayPort.height, - aDisplayResolution.scale, aLayersUpdated); - - NS_ABORT_IF_FALSE(viewTransformJObj, "No view transform object!"); - if (!viewTransformJObj) { - return; - } - ViewTransform* viewTransform = ViewTransform::Wrap(viewTransformJObj); - - aScrollOffset = ScreenPoint(viewTransform->getx(), viewTransform->gety()); - aScale.scale = viewTransform->getscale(); - - aFixedLayerMargins.top = viewTransform->getfixedLayerMarginTop(); - aFixedLayerMargins.right = viewTransform->getfixedLayerMarginRight(); - aFixedLayerMargins.bottom = viewTransform->getfixedLayerMarginBottom(); - aFixedLayerMargins.left = viewTransform->getfixedLayerMarginLeft(); - - aOffset.x = viewTransform->getoffsetX(); - aOffset.y = viewTransform->getoffsetY(); - - delete viewTransform; - ALOG_BRIDGE("Exit: %s", __PRETTY_FUNCTION__); + client->SyncViewportInfo(aDisplayPort, aDisplayResolution, aLayersUpdated, + aScrollOffset, aScale, aFixedLayerMargins, + aOffset); } void AndroidBridge::SyncFrameMetrics(const ScreenPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect, bool aLayersUpdated, const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution, bool aIsFirstPaint, LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset) { - ALOG_BRIDGE("Enter: %s", __PRETTY_FUNCTION__); - GeckoLayerClient *client = mLayerClient; - if (!client) { - ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__); + AndroidGeckoLayerClient *client = mLayerClient; + if (!client) return; - } - - // convert the displayport rect from scroll-relative CSS pixels to document-relative device pixels - LayerRect dpUnrounded = aDisplayPort * aDisplayResolution; - dpUnrounded += LayerPoint::FromUnknownPoint(aScrollOffset.ToUnknownPoint()); - LayerIntRect dp = gfx::RoundedToInt(dpUnrounded); - - jobject viewTransformJObj = client->SyncFrameMetrics(aScrollOffset.x, aScrollOffset.y, aZoom, - aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost(), - aLayersUpdated, dp.x, dp.y, dp.width, dp.height, aDisplayResolution.scale, - aIsFirstPaint); - NS_ABORT_IF_FALSE(viewTransformJObj, "No view transform object!"); - if (!viewTransformJObj) { - return; - } - ViewTransform* viewTransform = ViewTransform::Wrap(viewTransformJObj); - - aFixedLayerMargins.top = viewTransform->getfixedLayerMarginTop(); - aFixedLayerMargins.right = viewTransform->getfixedLayerMarginRight(); - aFixedLayerMargins.bottom = viewTransform->getfixedLayerMarginBottom(); - aFixedLayerMargins.left = viewTransform->getfixedLayerMarginLeft(); - - aOffset.x = viewTransform->getoffsetX(); - aOffset.y = viewTransform->getoffsetY(); - - delete viewTransform; - ALOG_BRIDGE("Exit: %s", __PRETTY_FUNCTION__); + client->SyncFrameMetrics(aScrollOffset, aZoom, aCssPageRect, + aLayersUpdated, aDisplayPort, aDisplayResolution, + aIsFirstPaint, aFixedLayerMargins, aOffset); } AndroidBridge::AndroidBridge() : mLayerClient(NULL), mNativePanZoomController(NULL) { } @@ -1626,22 +1594,55 @@ static void JavaThreadDetachFunc(void *arg) { JNIEnv *env = (JNIEnv*) arg; JavaVM *vm = NULL; env->GetJavaVM(&vm); vm->DetachCurrentThread(); } +extern "C" { + __attribute__ ((visibility("default"))) + JNIEnv * GetJNIForThread() + { + JNIEnv *jEnv = NULL; + JavaVM *jVm = mozilla::AndroidBridge::GetVM(); + if (!jVm) { + __android_log_print(ANDROID_LOG_INFO, "GetJNIForThread", "Returned a null VM"); + return NULL; + } + jEnv = static_cast<JNIEnv*>(PR_GetThreadPrivate(sJavaEnvThreadIndex)); + + if (jEnv) + return jEnv; + + int status = jVm->GetEnv((void**) &jEnv, JNI_VERSION_1_2); + if (status) { + + status = jVm->AttachCurrentThread(&jEnv, NULL); + if (status) { + __android_log_print(ANDROID_LOG_INFO, "GetJNIForThread", "Could not attach"); + return NULL; + } + + PR_SetThreadPrivate(sJavaEnvThreadIndex, jEnv); + } + if (!jEnv) { + __android_log_print(ANDROID_LOG_INFO, "GetJNIForThread", "returning NULL"); + } + return jEnv; + } +} + uint32_t AndroidBridge::GetScreenOrientation() { ALOG_BRIDGE("AndroidBridge::GetScreenOrientation"); - int16_t orientation = GeckoAppShell::GetScreenOrientationWrapper(); + int16_t orientation = GetScreenOrientationWrapper(); if (!orientation) return dom::eScreenOrientation_None; return static_cast<dom::ScreenOrientation>(orientation); } void @@ -1655,17 +1656,17 @@ AndroidBridge::GetGfxInfoData(nsACString { ALOG_BRIDGE("AndroidBridge::GetGfxInfoData"); JNIEnv* env = GetJNIEnv(); if (!env) return; AutoLocalJNIFrame jniFrame(env); - jstring jstrRet = GeckoAppShell::GetGfxInfoDataWrapper(); + jstring jstrRet = GetGfxInfoDataWrapper(); if (!jstrRet) return; nsJNIString jniStr(jstrRet, env); CopyUTF16toUTF8(jniStr, aRet); } @@ -1676,17 +1677,17 @@ AndroidBridge::GetProxyForURI(const nsAC const int32_t aPort, nsACString & aResult) { JNIEnv* env = GetJNIEnv(); if (!env) return NS_ERROR_FAILURE; AutoLocalJNIFrame jniFrame(env); - jstring jstrRet = GeckoAppShell::GetProxyForURIWrapper(NS_ConvertUTF8toUTF16(aSpec), + jstring jstrRet = GetProxyForURIWrapper(NS_ConvertUTF8toUTF16(aSpec), NS_ConvertUTF8toUTF16(aScheme), NS_ConvertUTF8toUTF16(aHost), aPort); if (!jstrRet) return NS_ERROR_FAILURE; nsJNIString jniStr(jstrRet, env); @@ -1712,34 +1713,34 @@ NS_IMETHODIMP nsAndroidBridge::SetBrowse void AndroidBridge::AddPluginView(jobject view, const LayoutDeviceRect& rect, bool isFullScreen) { nsWindow* win = nsWindow::TopWindow(); if (!win) return; CSSRect cssRect = rect / win->GetDefaultScale(); - GeckoAppShell::AddPluginViewWrapper(view, cssRect.x, cssRect.y, cssRect.width, cssRect.height, isFullScreen); + AddPluginViewWrapper(view, cssRect.x, cssRect.y, cssRect.width, cssRect.height, isFullScreen); } extern "C" __attribute__ ((visibility("default"))) jobject JNICALL Java_org_mozilla_gecko_GeckoAppShell_allocateDirectBuffer(JNIEnv *env, jclass, jlong size); bool AndroidBridge::GetThreadNameJavaProfiling(uint32_t aThreadId, nsCString & aResult) { JNIEnv* env = GetJNIForThread(); if (!env) return false; AutoLocalJNIFrame jniFrame(env); - jstring jstrThreadName = GeckoJavaSampler::GetThreadNameJavaProfilingWrapper(aThreadId); + jstring jstrThreadName = GetThreadNameJavaProfilingWrapper(aThreadId); if (!jstrThreadName) return false; nsJNIString jniStr(jstrThreadName, env); CopyUTF16toUTF8(jniStr.get(), aResult); return true; } @@ -1749,17 +1750,17 @@ AndroidBridge::GetFrameNameJavaProfiling uint32_t aFrameId, nsCString & aResult) { JNIEnv* env = GetJNIForThread(); if (!env) return false; AutoLocalJNIFrame jniFrame(env); - jstring jstrSampleName = GeckoJavaSampler::GetFrameNameJavaProfilingWrapper(aThreadId, aSampleId, aFrameId); + jstring jstrSampleName = GetFrameNameJavaProfilingWrapper(aThreadId, aSampleId, aFrameId); if (!jstrSampleName) return false; nsJNIString jniStr(jstrSampleName, env); CopyUTF16toUTF8(jniStr.get(), aResult); env->DeleteLocalRef(jstrSampleName); return true; @@ -1857,144 +1858,71 @@ nsresult AndroidBridge::CaptureThumbnail } NS_ENSURE_SUCCESS(rv, rv); return NS_OK; } void AndroidBridge::GetDisplayPort(bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort) { - - ALOG_BRIDGE("Enter: %s", __PRETTY_FUNCTION__); JNIEnv* env = GetJNIEnv(); - if (!env || !mLayerClient || mLayerClient->isNull()) { - - ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__); + if (!env || !mLayerClient) return; - } AutoLocalJNIFrame jniFrame(env, 0); - - float x, y, width, height, - pageLeft, pageTop, pageRight, pageBottom, - cssPageLeft, cssPageTop, cssPageRight, cssPageBottom, - zoom; - metrics->GetX(&x); - metrics->GetY(&y); - metrics->GetWidth(&width); - metrics->GetHeight(&height); - metrics->GetPageLeft(&pageLeft); - metrics->GetPageTop(&pageTop); - metrics->GetPageRight(&pageRight); - metrics->GetPageBottom(&pageBottom); - metrics->GetCssPageLeft(&cssPageLeft); - metrics->GetCssPageTop(&cssPageTop); - metrics->GetCssPageRight(&cssPageRight); - metrics->GetCssPageBottom(&cssPageBottom); - metrics->GetZoom(&zoom); - - ImmutableViewportMetrics jmetrics = ImmutableViewportMetrics(pageLeft, pageTop, pageRight, pageBottom, - cssPageLeft, cssPageTop, cssPageRight, cssPageBottom, - x, y, x + width, y + height, - zoom); - - jobject jobj = mLayerClient->GetDisplayPort(aPageSizeUpdate, aIsBrowserContentDisplayed, tabId, jmetrics.wrappedObject()); - if (!jobj) { - ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__); - return; - } - DisplayPortMetrics* displayPortMetrics = DisplayPortMetrics::Wrap(jobj); - - AndroidRectF rect(env, displayPortMetrics->getMPosition()); - if (jniFrame.CheckForException()) { - ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__); - return; - } - - float resolution = displayPortMetrics->getResolution(); - if (jniFrame.CheckForException()) { - ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__); - return; - } - - *displayPort = new nsAndroidDisplayport(rect, resolution); - (*displayPort)->AddRef(); - - delete displayPortMetrics; - ALOG_BRIDGE("Exit: %s", __PRETTY_FUNCTION__); + mLayerClient->GetDisplayPort(&jniFrame, aPageSizeUpdate, aIsBrowserContentDisplayed, tabId, metrics, displayPort); } void AndroidBridge::ContentDocumentChanged() { - if (!mLayerClient) { + JNIEnv* env = GetJNIEnv(); + if (!env || !mLayerClient) return; - } - mLayerClient->ContentDocumentChanged(); + AutoLocalJNIFrame jniFrame(env, 0); + mLayerClient->ContentDocumentChanged(&jniFrame); } bool AndroidBridge::IsContentDocumentDisplayed() { JNIEnv* env = GetJNIEnv(); if (!env || !mLayerClient) return false; - - return mLayerClient->IsContentDocumentDisplayed(); + AutoLocalJNIFrame jniFrame(env, 0); + return mLayerClient->IsContentDocumentDisplayed(&jniFrame); } bool AndroidBridge::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const LayerRect& aDisplayPort, float aDisplayResolution, bool aDrawingCritical, gfx::Rect& aViewport, float& aScaleX, float& aScaleY) { - GeckoLayerClient *client = mLayerClient; - if (!client) { - ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__); + AndroidGeckoLayerClient *client = mLayerClient; + if (!client) return false; - } - - jobject progressiveUpdateDataJObj = client->ProgressiveUpdateCallback(aHasPendingNewThebesContent, - (float)aDisplayPort.x, - (float)aDisplayPort.y, - (float)aDisplayPort.width, - (float)aDisplayPort.height, - aDisplayResolution, - !aDrawingCritical); - NS_ABORT_IF_FALSE(progressiveUpdateDataJObj, "No progressive update data!"); - - ProgressiveUpdateData* progressiveUpdateData = ProgressiveUpdateData::Wrap(progressiveUpdateDataJObj); - - aViewport.x = progressiveUpdateData->getx(); - aViewport.y = progressiveUpdateData->gety(); - aViewport.width = progressiveUpdateData->getwidth(); - aViewport.height = progressiveUpdateData->getheight(); - aScaleX = aScaleY = progressiveUpdateData->getscale(); - - bool ret = progressiveUpdateData->getabort(); - delete progressiveUpdateData; - - return ret; + return client->ProgressiveUpdateCallback(aHasPendingNewThebesContent, aDisplayPort, aDisplayResolution, aDrawingCritical, aViewport, aScaleX, aScaleY); } -NativePanZoomController* +jobject AndroidBridge::SetNativePanZoomController(jobject obj) { - NativePanZoomController* old = mNativePanZoomController; - mNativePanZoomController = NativePanZoomController::Wrap(obj); + jobject old = mNativePanZoomController; + mNativePanZoomController = obj; return old; } void AndroidBridge::RequestContentRepaint(const mozilla::layers::FrameMetrics& aFrameMetrics) { ALOG_BRIDGE("AndroidBridge::RequestContentRepaint"); CSSToScreenScale resolution = aFrameMetrics.mZoom; ScreenRect dp = (aFrameMetrics.mDisplayPort + aFrameMetrics.mScrollOffset) * resolution; - mNativePanZoomController->RequestContentRepaintWrapper(dp.x, dp.y, dp.width, dp.height, resolution.scale); + RequestContentRepaintWrapper(mNativePanZoomController, + dp.x, dp.y, dp.width, dp.height, resolution.scale); } void AndroidBridge::HandleDoubleTap(const CSSIntPoint& aPoint) { nsCString data = nsPrintfCString("{ \"x\": %d, \"y\": %d }", aPoint.x, aPoint.y); nsAppShell::gAppShell->PostEvent(AndroidGeckoEvent::MakeBroadcastEvent( NS_LITERAL_CSTRING("Gesture:DoubleTap"), data)); @@ -2041,17 +1969,17 @@ AndroidBridge::PostDelayedTask(Task* aTa if (i == mDelayedTaskQueue.Length()) { // this new task will run after all the existing tasks in the queue mDelayedTaskQueue.AppendElement(newTask); } if (i == 0) { // if we're inserting it at the head of the queue, notify Java because // we need to get a callback at an earlier time than the last scheduled // callback - mNativePanZoomController->PostDelayedCallbackWrapper((int64_t)aDelayMs); + PostDelayedCallbackWrapper(mNativePanZoomController, (int64_t)aDelayMs); } } int64_t AndroidBridge::RunDelayedTasks() { while (mDelayedTaskQueue.Length() > 0) { DelayedTask* nextTask = mDelayedTaskQueue[0];
--- a/widget/android/AndroidBridge.h +++ b/widget/android/AndroidBridge.h @@ -9,17 +9,17 @@ #include <jni.h> #include <android/log.h> #include <cstdlib> #include <pthread.h> #include "nsCOMPtr.h" #include "nsCOMArray.h" -#include "GeneratedJNIWrappers.h" +#include "AndroidJavaWrappers.h" #include "nsIMutableArray.h" #include "nsIMIMEInfo.h" #include "nsColor.h" #include "gfxRect.h" #include "nsIAndroidBridge.h" #include "nsIMobileMessageCallback.h" @@ -36,25 +36,24 @@ class nsWindow; class nsIDOMMozSmsMessage; class nsIObserver; /* See the comment in AndroidBridge about this function before using it */ extern "C" JNIEnv * GetJNIForThread(); extern bool mozilla_AndroidBridge_SetMainThread(pthread_t); +extern jclass GetGeckoAppShellClass(); namespace base { class Thread; } // end namespace base typedef void* EGLSurface; -using namespace mozilla::widget::android; - namespace mozilla { namespace hal { class BatteryInformation; class NetworkInformation; } // namespace hal namespace dom { @@ -156,16 +155,20 @@ public: return nullptr; } return sBridge->mJNIEnv; } return nullptr; } + static jclass GetGeckoAppShellClass() { + return sBridge->mGeckoAppShellClass; + } + // The bridge needs to be constructed via ConstructBridge first, // and then once the Gecko main thread is spun up (Gecko side), // SetMainThread should be called which will create the JNIEnv for // us to use. toolkit/xre/nsAndroidStartup.cpp calls // SetMainThread. bool SetMainThread(pthread_t thr); /* These are all implemented in Java */ @@ -175,32 +178,36 @@ public: nsresult CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int32_t bufH, int32_t tabId, jobject buffer); void GetDisplayPort(bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort); void ContentDocumentChanged(); bool IsContentDocumentDisplayed(); bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const LayerRect& aDisplayPort, float aDisplayResolution, bool aDrawingCritical, gfx::Rect& aViewport, float& aScaleX, float& aScaleY); void SetLayerClient(JNIEnv* env, jobject jobj); - GeckoLayerClient* GetLayerClient() { return mLayerClient; } + AndroidGeckoLayerClient &GetLayerClient() { return *mLayerClient; } bool GetHandlersForURL(const nsAString& aURL, nsIMutableArray* handlersArray = nullptr, nsIHandlerApp **aDefaultApp = nullptr, const nsAString& aAction = EmptyString()); bool GetHandlersForMimeType(const nsAString& aMimeType, nsIMutableArray* handlersArray = nullptr, nsIHandlerApp **aDefaultApp = nullptr, const nsAString& aAction = EmptyString()); void GetMimeTypeFromExtensions(const nsACString& aFileExt, nsCString& aMimeType); void GetExtensionFromMimeType(const nsACString& aMimeType, nsACString& aFileExt); bool GetClipboardText(nsAString& aText); + + void EmptyClipboard(); + + bool ClipboardHasText(); void ShowAlertNotification(const nsAString& aImageUrl, const nsAString& aAlertTitle, const nsAString& aAlertText, const nsAString& aAlertData, nsIObserver *aAlertListener, const nsAString& aAlertName); @@ -208,16 +215,18 @@ public: int GetScreenDepth(); void ShowFilePickerForExtensions(nsAString& aFilePath, const nsAString& aExtensions); void ShowFilePickerForMimeType(nsAString& aFilePath, const nsAString& aMimeType); void ShowFilePickerAsync(const nsAString& aMimeType, nsFilePickerCallback* callback); void Vibrate(const nsTArray<uint32_t>& aPattern); + void HideProgressDialogOnce(); + void GetSystemColors(AndroidSystemColors *aColors); void GetIconForExtension(const nsACString& aFileExt, uint32_t aIconSize, uint8_t * const aBuf); // Switch Java to composite with the Gecko Compositor thread void RegisterCompositor(JNIEnv* env = NULL); EGLSurface ProvideEGLSurface(); @@ -327,17 +336,17 @@ protected: // the global JavaVM JavaVM *mJavaVM; // the JNIEnv for the main thread JNIEnv *mJNIEnv; pthread_t mThread; - GeckoLayerClient *mLayerClient = NULL; + AndroidGeckoLayerClient *mLayerClient; // the android.telephony.SmsMessage class jclass mAndroidSmsMessageClass; AndroidBridge(); ~AndroidBridge(); void InitStubs(JNIEnv *jEnv); @@ -368,17 +377,17 @@ protected: // For native surface stuff jclass jSurfaceClass; jfieldID jSurfacePointerField; jclass jLayerView; jfieldID jEGLSurfacePointerField; - GLController *mGLControllerObj; + jobject mGLControllerObj; // some convinient types to have around jclass jStringClass; // calls we've dlopened from libjnigraphics.so int (* AndroidBitmap_getInfo)(JNIEnv *env, jobject bitmap, void *info); int (* AndroidBitmap_lockPixels)(JNIEnv *env, jobject bitmap, void **buffer); int (* AndroidBitmap_unlockPixels)(JNIEnv *env, jobject bitmap); @@ -392,24 +401,25 @@ protected: int (* ANativeWindow_unlockAndPost)(void *window); int (* Surface_lock)(void* surface, void* surfaceInfo, void* region, bool block); int (* Surface_unlockAndPost)(void* surface); void (* Region_constructor)(void* region); void (* Region_set)(void* region, void* rect); private: - NativePanZoomController* mNativePanZoomController; + jobject mNativePanZoomController; // This will always be accessed from one thread (the APZC "controller" // thread, which is the Java UI thread), so we don't need to do locking // to touch it nsTArray<DelayedTask*> mDelayedTaskQueue; public: - NativePanZoomController* SetNativePanZoomController(jobject obj); + #include "GeneratedJNIWrappers.h" + jobject SetNativePanZoomController(jobject obj); // GeckoContentController methods void RequestContentRepaint(const mozilla::layers::FrameMetrics& aFrameMetrics) MOZ_OVERRIDE; void HandleDoubleTap(const CSSIntPoint& aPoint) MOZ_OVERRIDE; void HandleSingleTap(const CSSIntPoint& aPoint) MOZ_OVERRIDE; void HandleLongTap(const CSSIntPoint& aPoint) MOZ_OVERRIDE; void SendAsyncScrollDOMEvent(mozilla::layers::FrameMetrics::ViewID aScrollId, const CSSRect& aContentRect, const CSSSize& aScrollableSize) MOZ_OVERRIDE;
--- a/widget/android/AndroidBridgeUtilities.h +++ b/widget/android/AndroidBridgeUtilities.h @@ -12,22 +12,8 @@ #define getMethod(fname, ftype) \ AndroidBridge::GetMethodID(jEnv, jClass, fname, ftype) #define getStaticField(fname, ftype) \ AndroidBridge::GetStaticFieldID(jEnv, jClass, fname, ftype) #define getStaticMethod(fname, ftype) \ AndroidBridge::GetStaticMethodID(jEnv, jClass, fname, ftype) - -#ifndef ALOG -#if defined(DEBUG) || defined(FORCE_ALOG) -#define ALOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gecko" , ## args) -#else -#define ALOG(args...) ((void)0) -#endif -#endif - -#ifdef DEBUG -#define ALOG_BRIDGE(args...) ALOG(args) -#else -#define ALOG_BRIDGE(args...) ((void)0) -#endif
--- a/widget/android/AndroidJNI.cpp +++ b/widget/android/AndroidJNI.cpp @@ -856,20 +856,20 @@ Java_org_mozilla_gecko_gfx_NativePanZoom NS_EXPORT void JNICALL Java_org_mozilla_gecko_gfx_NativePanZoomController_init(JNIEnv* env, jobject instance) { if (!AndroidBridge::Bridge()) { return; } - NativePanZoomController* oldRef = AndroidBridge::Bridge()->SetNativePanZoomController(instance); - if (oldRef && !oldRef->isNull()) { + jobject oldRef = AndroidBridge::Bridge()->SetNativePanZoomController(env->NewGlobalRef(instance)); + if (oldRef) { MOZ_ASSERT(false, "Registering a new NPZC when we already have one"); - delete oldRef; + env->DeleteGlobalRef(oldRef); } } NS_EXPORT void JNICALL Java_org_mozilla_gecko_gfx_NativePanZoomController_handleTouchEvent(JNIEnv* env, jobject instance, jobject event) { APZCTreeManager *controller = nsWindow::GetAPZCTreeManager(); if (controller) { @@ -900,21 +900,21 @@ Java_org_mozilla_gecko_gfx_NativePanZoom NS_EXPORT void JNICALL Java_org_mozilla_gecko_gfx_NativePanZoomController_destroy(JNIEnv* env, jobject instance) { if (!AndroidBridge::Bridge()) { return; } - NativePanZoomController* oldRef = AndroidBridge::Bridge()->SetNativePanZoomController(NULL); - if (!oldRef || oldRef->isNull()) { + jobject oldRef = AndroidBridge::Bridge()->SetNativePanZoomController(NULL); + if (!oldRef) { MOZ_ASSERT(false, "Clearing a non-existent NPZC"); } else { - delete oldRef; + env->DeleteGlobalRef(oldRef); } } NS_EXPORT void JNICALL Java_org_mozilla_gecko_gfx_NativePanZoomController_notifyDefaultActionPrevented(JNIEnv* env, jobject instance, jboolean prevented) { APZCTreeManager *controller = nsWindow::GetAPZCTreeManager(); if (controller) {
--- a/widget/android/AndroidJNIWrapper.cpp +++ b/widget/android/AndroidJNIWrapper.cpp @@ -9,16 +9,22 @@ #include <dlfcn.h> #include <prthread.h> #include "mozilla/DebugOnly.h" #include "mozilla/Assertions.h" #include "nsThreadUtils.h" #include "AndroidBridge.h" +#ifdef DEBUG +#define ALOG_BRIDGE(args...) ALOG(args) +#else +#define ALOG_BRIDGE(args...) +#endif + extern "C" { jclass __jsjni_GetGlobalClassRef(const char *className); } class GetGlobalClassRefRunnable : public nsRunnable { public: GetGlobalClassRefRunnable(const char *className, jclass *foundClass) : mClassName(className), mResult(foundClass) {}
--- a/widget/android/AndroidJavaWrappers.cpp +++ b/widget/android/AndroidJavaWrappers.cpp @@ -1,23 +1,23 @@ /* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- * 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 "AndroidJavaWrappers.h" #include "AndroidBridge.h" #include "AndroidBridgeUtilities.h" +#include "nsIAndroidBridge.h" #include "nsIDOMKeyEvent.h" #include "nsIWidget.h" #include "mozilla/TouchEvents.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; jfieldID AndroidGeckoEvent::jAckNeededField = 0; jfieldID AndroidGeckoEvent::jTimeField = 0; jfieldID AndroidGeckoEvent::jPoints = 0; jfieldID AndroidGeckoEvent::jPointIndicies = 0; @@ -86,31 +86,77 @@ jclass AndroidLocation::jLocationClass = jmethodID AndroidLocation::jGetLatitudeMethod = 0; jmethodID AndroidLocation::jGetLongitudeMethod = 0; jmethodID AndroidLocation::jGetAltitudeMethod = 0; jmethodID AndroidLocation::jGetAccuracyMethod = 0; jmethodID AndroidLocation::jGetBearingMethod = 0; jmethodID AndroidLocation::jGetSpeedMethod = 0; jmethodID AndroidLocation::jGetTimeMethod = 0; +jclass AndroidGeckoLayerClient::jGeckoLayerClientClass = 0; +jclass AndroidGeckoLayerClient::jViewportClass = 0; +jclass AndroidGeckoLayerClient::jDisplayportClass = 0; +jmethodID AndroidGeckoLayerClient::jSetFirstPaintViewport = 0; +jmethodID AndroidGeckoLayerClient::jSetPageRect = 0; +jmethodID AndroidGeckoLayerClient::jSyncViewportInfoMethod = 0; +jmethodID AndroidGeckoLayerClient::jSyncFrameMetricsMethod = 0; +jmethodID AndroidGeckoLayerClient::jCreateFrameMethod = 0; +jmethodID AndroidGeckoLayerClient::jActivateProgramMethod = 0; +jmethodID AndroidGeckoLayerClient::jDeactivateProgramMethod = 0; +jmethodID AndroidGeckoLayerClient::jGetDisplayPort = 0; +jmethodID AndroidGeckoLayerClient::jContentDocumentChanged = 0; +jmethodID AndroidGeckoLayerClient::jIsContentDocumentDisplayed = 0; +jmethodID AndroidGeckoLayerClient::jViewportCtor = 0; +jfieldID AndroidGeckoLayerClient::jDisplayportPosition = 0; +jfieldID AndroidGeckoLayerClient::jDisplayportResolution = 0; +jmethodID AndroidGeckoLayerClient::jProgressiveUpdateCallbackMethod = 0; + +jclass AndroidLayerRendererFrame::jLayerRendererFrameClass = 0; +jmethodID AndroidLayerRendererFrame::jBeginDrawingMethod = 0; +jmethodID AndroidLayerRendererFrame::jDrawBackgroundMethod = 0; +jmethodID AndroidLayerRendererFrame::jDrawForegroundMethod = 0; +jmethodID AndroidLayerRendererFrame::jEndDrawingMethod = 0; + +jclass AndroidViewTransform::jViewTransformClass = 0; +jfieldID AndroidViewTransform::jXField = 0; +jfieldID AndroidViewTransform::jYField = 0; +jfieldID AndroidViewTransform::jScaleField = 0; +jfieldID AndroidViewTransform::jFixedLayerMarginLeft = 0; +jfieldID AndroidViewTransform::jFixedLayerMarginTop = 0; +jfieldID AndroidViewTransform::jFixedLayerMarginRight = 0; +jfieldID AndroidViewTransform::jFixedLayerMarginBottom = 0; +jfieldID AndroidViewTransform::jOffsetXField = 0; +jfieldID AndroidViewTransform::jOffsetYField = 0; + +jclass AndroidProgressiveUpdateData::jProgressiveUpdateDataClass = 0; +jfieldID AndroidProgressiveUpdateData::jXField = 0; +jfieldID AndroidProgressiveUpdateData::jYField = 0; +jfieldID AndroidProgressiveUpdateData::jWidthField = 0; +jfieldID AndroidProgressiveUpdateData::jHeightField = 0; +jfieldID AndroidProgressiveUpdateData::jScaleField = 0; +jfieldID AndroidProgressiveUpdateData::jShouldAbortField = 0; + RefCountedJavaObject::~RefCountedJavaObject() { if (mObject) GetJNIForThread()->DeleteGlobalRef(mObject); mObject = NULL; } void mozilla::InitAndroidJavaWrappers(JNIEnv *jEnv) { AndroidGeckoEvent::InitGeckoEventClass(jEnv); AndroidPoint::InitPointClass(jEnv); AndroidLocation::InitLocationClass(jEnv); AndroidRect::InitRectClass(jEnv); AndroidRectF::InitRectFClass(jEnv); - InitStubs(jEnv); + AndroidGeckoLayerClient::InitGeckoLayerClientClass(jEnv); + AndroidLayerRendererFrame::InitLayerRendererFrameClass(jEnv); + AndroidViewTransform::InitViewTransformClass(jEnv); + AndroidProgressiveUpdateData::InitProgressiveUpdateDataClass(jEnv); } void AndroidGeckoEvent::InitGeckoEventClass(JNIEnv *jEnv) { initInit(); jGeckoEventClass = getClassGlobalRef("org/mozilla/gecko/GeckoEvent"); @@ -239,16 +285,92 @@ AndroidRectF::InitRectFClass(JNIEnv *jEn jRectClass = getClassGlobalRef("android/graphics/RectF"); jBottomField = getField("bottom", "F"); jLeftField = getField("left", "F"); jTopField = getField("top", "F"); jRightField = getField("right", "F"); } +void +AndroidGeckoLayerClient::InitGeckoLayerClientClass(JNIEnv *jEnv) +{ + initInit(); + + jGeckoLayerClientClass = getClassGlobalRef("org/mozilla/gecko/gfx/GeckoLayerClient"); + + jProgressiveUpdateCallbackMethod = getMethod("progressiveUpdateCallback", + "(ZFFFFFZ)Lorg/mozilla/gecko/gfx/ProgressiveUpdateData;"); + jSetFirstPaintViewport = getMethod("setFirstPaintViewport", "(FFFFFFF)V"); + jSetPageRect = getMethod("setPageRect", "(FFFF)V"); + jSyncViewportInfoMethod = getMethod("syncViewportInfo", + "(IIIIFZ)Lorg/mozilla/gecko/gfx/ViewTransform;"); + jSyncFrameMetricsMethod = getMethod("syncFrameMetrics", + "(FFFFFFFZIIIIFZ)Lorg/mozilla/gecko/gfx/ViewTransform;"); + jCreateFrameMethod = getMethod("createFrame", "()Lorg/mozilla/gecko/gfx/LayerRenderer$Frame;"); + jActivateProgramMethod = getMethod("activateProgram", "()V"); + jDeactivateProgramMethod = getMethod("deactivateProgram", "()V"); + jGetDisplayPort = getMethod("getDisplayPort", "(ZZILorg/mozilla/gecko/gfx/ImmutableViewportMetrics;)Lorg/mozilla/gecko/gfx/DisplayPortMetrics;"); + jContentDocumentChanged = getMethod("contentDocumentChanged", "()V"); + jIsContentDocumentDisplayed = getMethod("isContentDocumentDisplayed", "()Z"); + + jViewportClass = getClassGlobalRef("org/mozilla/gecko/gfx/ImmutableViewportMetrics"); + jViewportCtor = getMethod("<init>", "(FFFFFFFFFFFFF)V"); + + jDisplayportClass = getClassGlobalRef("org/mozilla/gecko/gfx/DisplayPortMetrics"); + jDisplayportPosition = getField("mPosition", "Landroid/graphics/RectF;"); + jDisplayportResolution = getField("resolution", "F"); +} + +void +AndroidLayerRendererFrame::InitLayerRendererFrameClass(JNIEnv *jEnv) +{ + initInit(); + + jLayerRendererFrameClass = getClassGlobalRef("org/mozilla/gecko/gfx/LayerRenderer$Frame"); + + jBeginDrawingMethod = getMethod("beginDrawing", "()V"); + jDrawBackgroundMethod = getMethod("drawBackground", "()V"); + jDrawForegroundMethod = getMethod("drawForeground", "()V"); + jEndDrawingMethod = getMethod("endDrawing", "()V"); +} + +void +AndroidViewTransform::InitViewTransformClass(JNIEnv *jEnv) +{ + initInit(); + + jViewTransformClass = getClassGlobalRef("org/mozilla/gecko/gfx/ViewTransform"); + + jXField = getField("x", "F"); + jYField = getField("y", "F"); + jScaleField = getField("scale", "F"); + jFixedLayerMarginLeft = getField("fixedLayerMarginLeft", "F"); + jFixedLayerMarginTop = getField("fixedLayerMarginTop", "F"); + jFixedLayerMarginRight = getField("fixedLayerMarginRight", "F"); + jFixedLayerMarginBottom = getField("fixedLayerMarginBottom", "F"); + jOffsetXField = getField("offsetX", "F"); + jOffsetYField = getField("offsetY", "F"); +} + +void +AndroidProgressiveUpdateData::InitProgressiveUpdateDataClass(JNIEnv *jEnv) +{ + initInit(); + + jProgressiveUpdateDataClass = getClassGlobalRef("org/mozilla/gecko/gfx/ProgressiveUpdateData"); + + jXField = getField("x", "F"); + jYField = getField("y", "F"); + jWidthField = getField("width", "F"); + jHeightField = getField("height", "F"); + jScaleField = getField("scale", "F"); + jShouldAbortField = getField("abort", "Z"); +} + #undef initInit #undef initClassGlobalRef #undef getField #undef getMethod void AndroidGeckoEvent::ReadPointArray(nsTArray<nsIntPoint> &points, JNIEnv *jenv, @@ -718,18 +840,471 @@ AndroidPoint::Init(JNIEnv *jenv, jobject mX = jenv->GetIntField(jobj, jXField); mY = jenv->GetIntField(jobj, jYField); } else { mX = 0; mY = 0; } } +void +AndroidGeckoLayerClient::Init(jobject jobj) +{ + NS_ASSERTION(wrapped_obj == nullptr, "Init called on non-null wrapped_obj!"); + wrapped_obj = jobj; +} + +void +AndroidLayerRendererFrame::Init(JNIEnv *env, jobject jobj) +{ + if (!isNull()) { + Dispose(env); + } + + wrapped_obj = env->NewGlobalRef(jobj); +} + +void +AndroidLayerRendererFrame::Dispose(JNIEnv *env) +{ + if (isNull()) { + return; + } + + env->DeleteGlobalRef(wrapped_obj); + wrapped_obj = 0; +} + +void +AndroidViewTransform::Init(jobject jobj) +{ + NS_ABORT_IF_FALSE(wrapped_obj == nullptr, "Init called on non-null wrapped_obj!"); + wrapped_obj = jobj; +} + +void +AndroidProgressiveUpdateData::Init(jobject jobj) +{ + NS_ABORT_IF_FALSE(wrapped_obj == nullptr, "Init called on non-null wrapped_obj!"); + wrapped_obj = jobj; +} + +void +AndroidGeckoLayerClient::SetFirstPaintViewport(const LayerIntPoint& aOffset, const CSSToLayerScale& aZoom, const CSSRect& aCssPageRect) +{ + NS_ASSERTION(!isNull(), "SetFirstPaintViewport called on null layer client!"); + JNIEnv *env = GetJNIForThread(); // this is called on the compositor thread + if (!env) + return; + + AutoLocalJNIFrame jniFrame(env, 0); + return env->CallVoidMethod(wrapped_obj, jSetFirstPaintViewport, (float)aOffset.x, (float)aOffset.y, aZoom.scale, + aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost()); +} + +void +AndroidGeckoLayerClient::SetPageRect(const CSSRect& aCssPageRect) +{ + NS_ASSERTION(!isNull(), "SetPageRect called on null layer client!"); + JNIEnv *env = GetJNIForThread(); // this is called on the compositor thread + if (!env) + return; + + AutoLocalJNIFrame jniFrame(env, 0); + return env->CallVoidMethod(wrapped_obj, jSetPageRect, + aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost()); +} + +void +AndroidGeckoLayerClient::SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution, + bool aLayersUpdated, ScreenPoint& aScrollOffset, CSSToScreenScale& aScale, + LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset) +{ + NS_ASSERTION(!isNull(), "SyncViewportInfo called on null layer client!"); + JNIEnv *env = GetJNIForThread(); // this is called on the compositor thread + if (!env) + return; + + AutoLocalJNIFrame jniFrame(env); + + jobject viewTransformJObj = env->CallObjectMethod(wrapped_obj, jSyncViewportInfoMethod, + aDisplayPort.x, aDisplayPort.y, + aDisplayPort.width, aDisplayPort.height, + aDisplayResolution.scale, aLayersUpdated); + if (jniFrame.CheckForException()) + return; + + NS_ABORT_IF_FALSE(viewTransformJObj, "No view transform object!"); + + AndroidViewTransform viewTransform; + viewTransform.Init(viewTransformJObj); + + aScrollOffset = ScreenPoint(viewTransform.GetX(env), viewTransform.GetY(env)); + aScale.scale = viewTransform.GetScale(env); + viewTransform.GetFixedLayerMargins(env, aFixedLayerMargins); + + aOffset.x = viewTransform.GetOffsetX(env); + aOffset.y = viewTransform.GetOffsetY(env); +} + +void +AndroidGeckoLayerClient::SyncFrameMetrics(const ScreenPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect, + bool aLayersUpdated, const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution, + bool aIsFirstPaint, LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset) +{ + NS_ASSERTION(!isNull(), "SyncFrameMetrics called on null layer client!"); + JNIEnv *env = GetJNIForThread(); // this is called on the compositor thread + if (!env) + return; + + AutoLocalJNIFrame jniFrame(env); + + // convert the displayport rect from scroll-relative CSS pixels to document-relative device pixels + LayerRect dpUnrounded = aDisplayPort * aDisplayResolution; + dpUnrounded += LayerPoint::FromUnknownPoint(aScrollOffset.ToUnknownPoint()); + LayerIntRect dp = gfx::RoundedToInt(dpUnrounded); + + jobject viewTransformJObj = env->CallObjectMethod(wrapped_obj, jSyncFrameMetricsMethod, + aScrollOffset.x, aScrollOffset.y, aZoom, + aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost(), + aLayersUpdated, dp.x, dp.y, dp.width, dp.height, aDisplayResolution.scale, + aIsFirstPaint); + + if (jniFrame.CheckForException()) + return; + + NS_ABORT_IF_FALSE(viewTransformJObj, "No view transform object!"); + + AndroidViewTransform viewTransform; + viewTransform.Init(viewTransformJObj); + viewTransform.GetFixedLayerMargins(env, aFixedLayerMargins); + aOffset.x = viewTransform.GetOffsetX(env); + aOffset.y = viewTransform.GetOffsetY(env); +} + +bool +AndroidGeckoLayerClient::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, + const LayerRect& aDisplayPort, + float aDisplayResolution, + bool aDrawingCritical, + gfx::Rect& aViewport, + float& aScaleX, + float& aScaleY) +{ + JNIEnv *env = AndroidBridge::GetJNIEnv(); + if (!env) + return false; + + AutoJObject progressiveUpdateDataJObj(env, env->CallObjectMethod(wrapped_obj, + jProgressiveUpdateCallbackMethod, + aHasPendingNewThebesContent, + (float)aDisplayPort.x, + (float)aDisplayPort.y, + (float)aDisplayPort.width, + (float)aDisplayPort.height, + aDisplayResolution, + !aDrawingCritical)); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + env->ExceptionClear(); + return false; + } + + NS_ABORT_IF_FALSE(progressiveUpdateDataJObj, "No progressive update data!"); + + AndroidProgressiveUpdateData progressiveUpdateData(progressiveUpdateDataJObj); + + aViewport.x = progressiveUpdateData.GetX(env); + aViewport.y = progressiveUpdateData.GetY(env); + aViewport.width = progressiveUpdateData.GetWidth(env); + aViewport.height = progressiveUpdateData.GetHeight(env); + aScaleX = aScaleY = progressiveUpdateData.GetScale(env); + + return progressiveUpdateData.GetShouldAbort(env); +} + +jobject ConvertToJavaViewportMetrics(JNIEnv* env, nsIAndroidViewport* metrics) { + float x, y, width, height, + pageLeft, pageTop, pageRight, pageBottom, + cssPageLeft, cssPageTop, cssPageRight, cssPageBottom, + zoom; + metrics->GetX(&x); + metrics->GetY(&y); + metrics->GetWidth(&width); + metrics->GetHeight(&height); + metrics->GetPageLeft(&pageLeft); + metrics->GetPageTop(&pageTop); + metrics->GetPageRight(&pageRight); + metrics->GetPageBottom(&pageBottom); + metrics->GetCssPageLeft(&cssPageLeft); + metrics->GetCssPageTop(&cssPageTop); + metrics->GetCssPageRight(&cssPageRight); + metrics->GetCssPageBottom(&cssPageBottom); + metrics->GetZoom(&zoom); + + jobject jobj = env->NewObject(AndroidGeckoLayerClient::jViewportClass, AndroidGeckoLayerClient::jViewportCtor, + pageLeft, pageTop, pageRight, pageBottom, + cssPageLeft, cssPageTop, cssPageRight, cssPageBottom, + x, y, x + width, y + height, + zoom); + return jobj; +} + +class nsAndroidDisplayport MOZ_FINAL : public nsIAndroidDisplayport +{ +public: + NS_DECL_ISUPPORTS + virtual nsresult GetLeft(float *aLeft) { *aLeft = mLeft; return NS_OK; } + virtual nsresult GetTop(float *aTop) { *aTop = mTop; return NS_OK; } + virtual nsresult GetRight(float *aRight) { *aRight = mRight; return NS_OK; } + virtual nsresult GetBottom(float *aBottom) { *aBottom = mBottom; return NS_OK; } + virtual nsresult GetResolution(float *aResolution) { *aResolution = mResolution; return NS_OK; } + virtual nsresult SetLeft(float aLeft) { mLeft = aLeft; return NS_OK; } + virtual nsresult SetTop(float aTop) { mTop = aTop; return NS_OK; } + virtual nsresult SetRight(float aRight) { mRight = aRight; return NS_OK; } + virtual nsresult SetBottom(float aBottom) { mBottom = aBottom; return NS_OK; } + virtual nsresult SetResolution(float aResolution) { mResolution = aResolution; return NS_OK; } + + nsAndroidDisplayport(AndroidRectF aRect, float aResolution): + mLeft(aRect.Left()), mTop(aRect.Top()), mRight(aRect.Right()), mBottom(aRect.Bottom()), mResolution(aResolution) {} + +private: + ~nsAndroidDisplayport() {} + float mLeft, mTop, mRight, mBottom, mResolution; +}; + NS_IMPL_ISUPPORTS1(nsAndroidDisplayport, nsIAndroidDisplayport) +void createDisplayPort(AutoLocalJNIFrame *jniFrame, jobject jobj, nsIAndroidDisplayport** displayPort) { + JNIEnv* env = jniFrame->GetEnv(); + AndroidRectF rect(env, env->GetObjectField(jobj, AndroidGeckoLayerClient::jDisplayportPosition)); + if (jniFrame->CheckForException()) return; + float resolution = env->GetFloatField(jobj, AndroidGeckoLayerClient::jDisplayportResolution); + if (jniFrame->CheckForException()) return; + *displayPort = new nsAndroidDisplayport(rect, resolution); +} + +void +AndroidGeckoLayerClient::GetDisplayPort(AutoLocalJNIFrame *jniFrame, bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort) +{ + jobject jmetrics = ConvertToJavaViewportMetrics(jniFrame->GetEnv(), metrics); + if (jniFrame->CheckForException()) return; + if (!jmetrics) + return; + jobject jobj = jniFrame->GetEnv()->CallObjectMethod(wrapped_obj, jGetDisplayPort, aPageSizeUpdate, aIsBrowserContentDisplayed, tabId, jmetrics); + if (jniFrame->CheckForException()) return; + createDisplayPort(jniFrame, jobj, displayPort); + (*displayPort)->AddRef(); +} + +void +AndroidGeckoLayerClient::ContentDocumentChanged(AutoLocalJNIFrame *jniFrame) +{ + jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jContentDocumentChanged); +} + +bool +AndroidGeckoLayerClient::IsContentDocumentDisplayed(AutoLocalJNIFrame *jniFrame) +{ + return jniFrame->GetEnv()->CallBooleanMethod(wrapped_obj, jIsContentDocumentDisplayed); +} + +bool +AndroidGeckoLayerClient::CreateFrame(AutoLocalJNIFrame *jniFrame, AndroidLayerRendererFrame& aFrame) +{ + if (!jniFrame || !jniFrame->GetEnv()) + return false; + + jobject frameJObj = jniFrame->GetEnv()->CallObjectMethod(wrapped_obj, jCreateFrameMethod); + if (jniFrame->CheckForException()) + return false; + NS_ABORT_IF_FALSE(frameJObj, "No frame object!"); + + aFrame.Init(jniFrame->GetEnv(), frameJObj); + return true; +} + +bool +AndroidGeckoLayerClient::ActivateProgram(AutoLocalJNIFrame *jniFrame) +{ + if (!jniFrame || !jniFrame->GetEnv()) + return false; + + jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jActivateProgramMethod); + if (jniFrame->CheckForException()) + return false; + + return true; +} + +bool +AndroidGeckoLayerClient::DeactivateProgram(AutoLocalJNIFrame *jniFrame) +{ + if (!jniFrame || !jniFrame->GetEnv()) + return false; + + jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jDeactivateProgramMethod); + if (jniFrame->CheckForException()) + return false; + + return true; +} + +bool +AndroidLayerRendererFrame::BeginDrawing(AutoLocalJNIFrame *jniFrame) +{ + if (!jniFrame || !jniFrame->GetEnv()) + return false; + + jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jBeginDrawingMethod); + if (jniFrame->CheckForException()) + return false; + + return true; +} + +bool +AndroidLayerRendererFrame::DrawBackground(AutoLocalJNIFrame *jniFrame) +{ + if (!jniFrame || !jniFrame->GetEnv()) + return false; + + jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jDrawBackgroundMethod); + if (jniFrame->CheckForException()) + return false; + + return true; +} + +bool +AndroidLayerRendererFrame::DrawForeground(AutoLocalJNIFrame *jniFrame) +{ + if (!jniFrame || !jniFrame->GetEnv()) + return false; + + jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jDrawForegroundMethod); + if (jniFrame->CheckForException()) + return false; + + return true; +} + +bool +AndroidLayerRendererFrame::EndDrawing(AutoLocalJNIFrame *jniFrame) +{ + if (!jniFrame || !jniFrame->GetEnv()) + return false; + + jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jEndDrawingMethod); + if (jniFrame->CheckForException()) + return false; + + return true; +} + +float +AndroidViewTransform::GetX(JNIEnv *env) +{ + if (!env) + return 0.0f; + return env->GetFloatField(wrapped_obj, jXField); +} + +float +AndroidViewTransform::GetY(JNIEnv *env) +{ + if (!env) + return 0.0f; + return env->GetFloatField(wrapped_obj, jYField); +} + +float +AndroidViewTransform::GetScale(JNIEnv *env) +{ + if (!env) + return 0.0f; + return env->GetFloatField(wrapped_obj, jScaleField); +} + +void +AndroidViewTransform::GetFixedLayerMargins(JNIEnv *env, LayerMargin &aFixedLayerMargins) +{ + if (!env) + return; + + aFixedLayerMargins.top = env->GetFloatField(wrapped_obj, jFixedLayerMarginTop); + aFixedLayerMargins.right = env->GetFloatField(wrapped_obj, jFixedLayerMarginRight); + aFixedLayerMargins.bottom = env->GetFloatField(wrapped_obj, jFixedLayerMarginBottom); + aFixedLayerMargins.left = env->GetFloatField(wrapped_obj, jFixedLayerMarginLeft); +} + +float +AndroidViewTransform::GetOffsetX(JNIEnv *env) +{ + if (!env) + return 0.0f; + return env->GetFloatField(wrapped_obj, jOffsetXField); +} + +float +AndroidViewTransform::GetOffsetY(JNIEnv *env) +{ + if (!env) + return 0.0f; + return env->GetFloatField(wrapped_obj, jOffsetYField); +} + +float +AndroidProgressiveUpdateData::GetX(JNIEnv *env) +{ + if (!env) + return 0.0f; + return env->GetFloatField(wrapped_obj, jXField); +} + +float +AndroidProgressiveUpdateData::GetY(JNIEnv *env) +{ + if (!env) + return 0.0f; + return env->GetFloatField(wrapped_obj, jYField); +} + +float +AndroidProgressiveUpdateData::GetWidth(JNIEnv *env) +{ + if (!env) + return 0.0f; + return env->GetFloatField(wrapped_obj, jWidthField); +} + +float +AndroidProgressiveUpdateData::GetHeight(JNIEnv *env) +{ + if (!env) + return 0.0f; + return env->GetFloatField(wrapped_obj, jHeightField); +} + +float +AndroidProgressiveUpdateData::GetScale(JNIEnv *env) +{ + if (!env) + return 0.0f; + return env->GetFloatField(wrapped_obj, jScaleField); +} + +bool +AndroidProgressiveUpdateData::GetShouldAbort(JNIEnv *env) +{ + if (!env) + return false; + return env->GetBooleanField(wrapped_obj, jShouldAbortField); +} + void AndroidRect::Init(JNIEnv *jenv, jobject jobj) { NS_ASSERTION(wrapped_obj == nullptr, "Init called on non-null wrapped_obj!"); wrapped_obj = jobj; if (jobj) {
--- a/widget/android/AndroidJavaWrappers.h +++ b/widget/android/AndroidJavaWrappers.h @@ -9,32 +9,40 @@ #include <jni.h> #include <android/input.h> #include <android/log.h> #include "nsGeoPosition.h" #include "nsRect.h" #include "nsString.h" #include "nsTArray.h" -#include "nsIAndroidBridge.h" #include "nsIObserver.h" #include "mozilla/gfx/Rect.h" #include "mozilla/dom/Touch.h" #include "mozilla/EventForwards.h" #include "InputData.h" #include "Units.h" //#define FORCE_ALOG 1 +#ifndef ALOG +#if defined(DEBUG) || defined(FORCE_ALOG) +#define ALOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gecko" , ## args) +#else +#define ALOG(args...) ((void)0) +#endif +#endif + class nsIAndroidDisplayport; class nsIAndroidViewport; class nsIWidget; namespace mozilla { +class AndroidGeckoLayerClient; class AutoLocalJNIFrame; void InitAndroidJavaWrappers(JNIEnv *jEnv); /* * Note: do not store global refs to any WrappedJavaObject; * these are live only during a particular JNI method, as * NewGlobalRef is -not- called on the jobject. @@ -62,61 +70,29 @@ public: private: int32_t mRefCnt; jobject mObject; }; class WrappedJavaObject { public: WrappedJavaObject() : - wrapped_obj(NULL) + wrapped_obj(0) { } - WrappedJavaObject(jobject jobj) : wrapped_obj(NULL) { + WrappedJavaObject(jobject jobj) { Init(jobj); } void Init(jobject jobj) { wrapped_obj = jobj; } bool isNull() const { - return wrapped_obj == NULL; - } - - jobject wrappedObject() const { - return wrapped_obj; - } - -protected: - jobject wrapped_obj; -}; - -class AutoGlobalWrappedJavaObject : protected WrappedJavaObject{ -public: - AutoGlobalWrappedJavaObject() : - wrapped_obj(NULL) - { } - - AutoGlobalWrappedJavaObject(jobject jobj, JNIEnv* env) : wrapped_obj(NULL) { - Init(jobj, env); - } - - virtual ~AutoGlobalWrappedJavaObject(); - void Dispose(); - - void Init(jobject jobj, JNIEnv* env) { - if (!isNull()) { - env->DeleteGlobalRef(wrapped_obj); - } - wrapped_obj = env->NewGlobalRef(jobj); - } - - bool isNull() const { - return wrapped_obj == NULL; + return wrapped_obj == 0; } jobject wrappedObject() const { return wrapped_obj; } protected: jobject wrapped_obj; @@ -205,16 +181,138 @@ protected: static jclass jRectClass; static jfieldID jBottomField; static jfieldID jLeftField; static jfieldID jRightField; static jfieldID jTopField; }; +class AndroidViewTransform : public WrappedJavaObject { +public: + static void InitViewTransformClass(JNIEnv *jEnv); + + void Init(jobject jobj); + + AndroidViewTransform() {} + AndroidViewTransform(jobject jobj) { Init(jobj); } + + float GetX(JNIEnv *env); + float GetY(JNIEnv *env); + float GetScale(JNIEnv *env); + void GetFixedLayerMargins(JNIEnv *env, LayerMargin &aFixedLayerMargins); + float GetOffsetX(JNIEnv *env); + float GetOffsetY(JNIEnv *env); + +private: + static jclass jViewTransformClass; + static jfieldID jXField; + static jfieldID jYField; + static jfieldID jScaleField; + static jfieldID jFixedLayerMarginLeft; + static jfieldID jFixedLayerMarginTop; + static jfieldID jFixedLayerMarginRight; + static jfieldID jFixedLayerMarginBottom; + static jfieldID jOffsetXField; + static jfieldID jOffsetYField; +}; + +class AndroidProgressiveUpdateData : public WrappedJavaObject { +public: + static void InitProgressiveUpdateDataClass(JNIEnv *jEnv); + + void Init(jobject jobj); + + AndroidProgressiveUpdateData() {} + AndroidProgressiveUpdateData(jobject jobj) { Init(jobj); } + + float GetX(JNIEnv *env); + float GetY(JNIEnv *env); + float GetWidth(JNIEnv *env); + float GetHeight(JNIEnv *env); + float GetScale(JNIEnv *env); + bool GetShouldAbort(JNIEnv *env); + +private: + static jclass jProgressiveUpdateDataClass; + static jfieldID jXField; + static jfieldID jYField; + static jfieldID jWidthField; + static jfieldID jHeightField; + static jfieldID jScaleField; + static jfieldID jShouldAbortField; +}; + +class AndroidLayerRendererFrame : public WrappedJavaObject { +public: + static void InitLayerRendererFrameClass(JNIEnv *jEnv); + + void Init(JNIEnv *env, jobject jobj); + void Dispose(JNIEnv *env); + + bool BeginDrawing(AutoLocalJNIFrame *jniFrame); + bool DrawBackground(AutoLocalJNIFrame *jniFrame); + bool DrawForeground(AutoLocalJNIFrame *jniFrame); + bool EndDrawing(AutoLocalJNIFrame *jniFrame); + +private: + static jclass jLayerRendererFrameClass; + static jmethodID jBeginDrawingMethod; + static jmethodID jDrawBackgroundMethod; + static jmethodID jDrawForegroundMethod; + static jmethodID jEndDrawingMethod; +}; + +class AndroidGeckoLayerClient : public WrappedJavaObject { +public: + static void InitGeckoLayerClientClass(JNIEnv *jEnv); + + void Init(jobject jobj); + + AndroidGeckoLayerClient() {} + AndroidGeckoLayerClient(jobject jobj) { Init(jobj); } + + void SetFirstPaintViewport(const LayerIntPoint& aOffset, const CSSToLayerScale& aZoom, const CSSRect& aCssPageRect); + void SetPageRect(const CSSRect& aCssPageRect); + void SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution, + bool aLayersUpdated, ScreenPoint& aScrollOffset, CSSToScreenScale& aScale, + LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset); + void SyncFrameMetrics(const ScreenPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect, + bool aLayersUpdated, const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution, + bool aIsFirstPaint, LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset); + bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const LayerRect& aDisplayPort, float aDisplayResolution, bool aDrawingCritical, gfx::Rect& aViewport, float& aScaleX, float& aScaleY); + bool CreateFrame(AutoLocalJNIFrame *jniFrame, AndroidLayerRendererFrame& aFrame); + bool ActivateProgram(AutoLocalJNIFrame *jniFrame); + bool DeactivateProgram(AutoLocalJNIFrame *jniFrame); + void GetDisplayPort(AutoLocalJNIFrame *jniFrame, bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort); + void ContentDocumentChanged(AutoLocalJNIFrame *jniFrame); + bool IsContentDocumentDisplayed(AutoLocalJNIFrame *jniFrame); + +protected: + static jclass jGeckoLayerClientClass; + static jmethodID jSetFirstPaintViewport; + static jmethodID jSetPageRect; + static jmethodID jSyncViewportInfoMethod; + static jmethodID jSyncFrameMetricsMethod; + static jmethodID jCreateFrameMethod; + static jmethodID jActivateProgramMethod; + static jmethodID jDeactivateProgramMethod; + static jmethodID jGetDisplayPort; + static jmethodID jContentDocumentChanged; + static jmethodID jIsContentDocumentDisplayed; + static jmethodID jProgressiveUpdateCallbackMethod; + +public: + static jclass jViewportClass; + static jclass jDisplayportClass; + static jmethodID jViewportCtor; + static jfieldID jDisplayportPosition; + static jfieldID jDisplayportResolution; +}; + enum { // These keycode masks are not defined in android/keycodes.h: AKEYCODE_ESCAPE = 111, AKEYCODE_FORWARD_DEL = 112, AKEYCODE_CTRL_LEFT = 113, AKEYCODE_CTRL_RIGHT = 114, AKEYCODE_CAPS_LOCK = 115, AKEYCODE_SCROLL_LOCK = 116, @@ -330,39 +428,16 @@ enum { AMETA_META_RIGHT_ON = 0x00040000, AMETA_ALT_MASK = AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON | AMETA_ALT_ON, AMETA_CTRL_MASK = AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON | AMETA_CTRL_ON, AMETA_META_MASK = AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON | AMETA_META_ON, AMETA_SHIFT_MASK = AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON | AMETA_SHIFT_ON, }; -class nsAndroidDisplayport MOZ_FINAL : public nsIAndroidDisplayport -{ -public: - NS_DECL_ISUPPORTS - virtual nsresult GetLeft(float *aLeft) { *aLeft = mLeft; return NS_OK; } - virtual nsresult GetTop(float *aTop) { *aTop = mTop; return NS_OK; } - virtual nsresult GetRight(float *aRight) { *aRight = mRight; return NS_OK; } - virtual nsresult GetBottom(float *aBottom) { *aBottom = mBottom; return NS_OK; } - virtual nsresult GetResolution(float *aResolution) { *aResolution = mResolution; return NS_OK; } - virtual nsresult SetLeft(float aLeft) { mLeft = aLeft; return NS_OK; } - virtual nsresult SetTop(float aTop) { mTop = aTop; return NS_OK; } - virtual nsresult SetRight(float aRight) { mRight = aRight; return NS_OK; } - virtual nsresult SetBottom(float aBottom) { mBottom = aBottom; return NS_OK; } - virtual nsresult SetResolution(float aResolution) { mResolution = aResolution; return NS_OK; } - - nsAndroidDisplayport(AndroidRectF aRect, float aResolution): - mLeft(aRect.Left()), mTop(aRect.Top()), mRight(aRect.Right()), mBottom(aRect.Bottom()), mResolution(aResolution) {} - -private: - ~nsAndroidDisplayport() {} - float mLeft, mTop, mRight, mBottom, mResolution; -}; - class AndroidMotionEvent { public: enum { ACTION_DOWN = 0, ACTION_UP = 1, ACTION_MOVE = 2, ACTION_CANCEL = 3,
--- a/widget/android/GeneratedJNIWrappers.cpp +++ b/widget/android/GeneratedJNIWrappers.cpp @@ -1,100 +1,25 @@ // GENERATED CODE // Generated by the Java program at /build/annotationProcessors at compile time from // annotations on Java 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 "GeneratedJNIWrappers.h" -#include "AndroidBridgeUtilities.h" #include "nsXPCOMStrings.h" #include "AndroidBridge.h" - -namespace mozilla { -namespace widget { -namespace android { -jclass GeckoAppShell::mGeckoAppShellClass = 0; -jmethodID GeckoAppShell::jAcknowledgeEvent = 0; -jmethodID GeckoAppShell::jAddPluginViewWrapper = 0; -jmethodID GeckoAppShell::jAlertsProgressListener_OnProgress = 0; -jmethodID GeckoAppShell::jCancelVibrate = 0; -jmethodID GeckoAppShell::jCheckURIVisited = 0; -jmethodID GeckoAppShell::jClearMessageList = 0; -jmethodID GeckoAppShell::jCloseCamera = 0; -jmethodID GeckoAppShell::jCloseNotification = 0; -jmethodID GeckoAppShell::jCreateMessageListWrapper = 0; -jmethodID GeckoAppShell::jCreateShortcut = 0; -jmethodID GeckoAppShell::jDeleteMessageWrapper = 0; -jmethodID GeckoAppShell::jDisableBatteryNotifications = 0; -jmethodID GeckoAppShell::jDisableNetworkNotifications = 0; -jmethodID GeckoAppShell::jDisableScreenOrientationNotifications = 0; -jmethodID GeckoAppShell::jDisableSensor = 0; -jmethodID GeckoAppShell::jEnableBatteryNotifications = 0; -jmethodID GeckoAppShell::jEnableLocation = 0; -jmethodID GeckoAppShell::jEnableLocationHighAccuracy = 0; -jmethodID GeckoAppShell::jEnableNetworkNotifications = 0; -jmethodID GeckoAppShell::jEnableScreenOrientationNotifications = 0; -jmethodID GeckoAppShell::jEnableSensor = 0; -jmethodID GeckoAppShell::jGetContext = 0; -jmethodID GeckoAppShell::jGetCurrentBatteryInformationWrapper = 0; -jmethodID GeckoAppShell::jGetCurrentNetworkInformationWrapper = 0; -jmethodID GeckoAppShell::jGetDensity = 0; -jmethodID GeckoAppShell::jGetDpiWrapper = 0; -jmethodID GeckoAppShell::jGetExtensionFromMimeTypeWrapper = 0; -jmethodID GeckoAppShell::jGetGfxInfoDataWrapper = 0; -jmethodID GeckoAppShell::jGetHandlersForMimeTypeWrapper = 0; -jmethodID GeckoAppShell::jGetHandlersForURLWrapper = 0; -jmethodID GeckoAppShell::jGetIconForExtensionWrapper = 0; -jmethodID GeckoAppShell::jGetMessageWrapper = 0; -jmethodID GeckoAppShell::jGetMimeTypeFromExtensionsWrapper = 0; -jmethodID GeckoAppShell::jGetNextMessageInListWrapper = 0; -jmethodID GeckoAppShell::jGetProxyForURIWrapper = 0; -jmethodID GeckoAppShell::jGetScreenDepthWrapper = 0; -jmethodID GeckoAppShell::jGetScreenOrientationWrapper = 0; -jmethodID GeckoAppShell::jGetShowPasswordSetting = 0; -jmethodID GeckoAppShell::jGetSystemColoursWrapper = 0; -jmethodID GeckoAppShell::jHandleGeckoMessageWrapper = 0; -jmethodID GeckoAppShell::jHideProgressDialog = 0; -jmethodID GeckoAppShell::jInitCameraWrapper = 0; -jmethodID GeckoAppShell::jIsNetworkLinkKnown = 0; -jmethodID GeckoAppShell::jIsNetworkLinkUp = 0; -jmethodID GeckoAppShell::jIsTablet = 0; -jmethodID GeckoAppShell::jKillAnyZombies = 0; -jmethodID GeckoAppShell::jLockScreenOrientation = 0; -jmethodID GeckoAppShell::jMarkURIVisited = 0; -jmethodID GeckoAppShell::jMoveTaskToBack = 0; -jmethodID GeckoAppShell::jNotifyDefaultPrevented = 0; -jmethodID GeckoAppShell::jNotifyIME = 0; -jmethodID GeckoAppShell::jNotifyIMEChange = 0; -jmethodID GeckoAppShell::jNotifyIMEContext = 0; -jmethodID GeckoAppShell::jNotifyWakeLockChanged = 0; -jmethodID GeckoAppShell::jNotifyXreExit = 0; -jmethodID GeckoAppShell::jOpenUriExternal = 0; -jmethodID GeckoAppShell::jPerformHapticFeedback = 0; -jmethodID GeckoAppShell::jPumpMessageLoop = 0; -jmethodID GeckoAppShell::jRegisterSurfaceTextureFrameListener = 0; -jmethodID GeckoAppShell::jRemovePluginView = 0; -jmethodID GeckoAppShell::jScanMedia = 0; -jmethodID GeckoAppShell::jScheduleRestart = 0; -jmethodID GeckoAppShell::jSendMessageWrapper = 0; -jmethodID GeckoAppShell::jSetFullScreen = 0; -jmethodID GeckoAppShell::jSetKeepScreenOn = 0; -jmethodID GeckoAppShell::jSetSelectedLocale = 0; -jmethodID GeckoAppShell::jSetURITitle = 0; -jmethodID GeckoAppShell::jShowAlertNotificationWrapper = 0; -jmethodID GeckoAppShell::jShowFilePickerAsyncWrapper = 0; -jmethodID GeckoAppShell::jShowFilePickerForExtensionsWrapper = 0; -jmethodID GeckoAppShell::jShowFilePickerForMimeTypeWrapper = 0; -jmethodID GeckoAppShell::jShowInputMethodPicker = 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 *jEnv) { +#include "AndroidBridgeUtilities.h" + +#ifdef DEBUG +#define ALOG_BRIDGE(args...) ALOG(args) +#else +#define ALOG_BRIDGE(args...) ((void)0) +#endif + +using namespace mozilla; +void AndroidBridge::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"); @@ -165,33 +90,46 @@ void GeckoAppShell::InitStubs(JNIEnv *jE jShowFilePickerForExtensionsWrapper = getStaticMethod("showFilePickerForExtensions", "(Ljava/lang/String;)Ljava/lang/String;"); jShowFilePickerForMimeTypeWrapper = getStaticMethod("showFilePickerForMimeType", "(Ljava/lang/String;)Ljava/lang/String;"); jShowInputMethodPicker = getStaticMethod("showInputMethodPicker", "()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"); + + 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"); + + mThumbnailHelperClass = getClassGlobalRef("org/mozilla/gecko/ThumbnailHelper"); + jSendThumbnail = getStaticMethod("notifyThumbnail", "(Ljava/nio/ByteBuffer;IZ)V"); + + mGLControllerClass = getClassGlobalRef("org/mozilla/gecko/gfx/GLController"); + jProvideEGLSurfaceWrapper = getMethod("provideEGLSurface", "()Ljavax/microedition/khronos/egl/EGLSurface;"); + + mLayerViewClass = getClassGlobalRef("org/mozilla/gecko/gfx/LayerView"); + jRegisterCompositorWrapper = getStaticMethod("registerCxxCompositor", "()Lorg/mozilla/gecko/gfx/GLController;"); + + mNativePanZoomControllerClass = getClassGlobalRef("org/mozilla/gecko/gfx/NativePanZoomController"); + jPostDelayedCallbackWrapper = getMethod("postDelayedCallback", "(J)V"); + jRequestContentRepaintWrapper = getMethod("requestContentRepaint", "(FFFFF)V"); + + mClipboardClass = getClassGlobalRef("org/mozilla/gecko/util/Clipboard"); + jGetClipboardTextWrapper = getStaticMethod("getText", "()Ljava/lang/String;"); + jSetClipboardText = getStaticMethod("setText", "(Ljava/lang/CharSequence;)V"); } -GeckoAppShell* GeckoAppShell::Wrap(jobject obj) { - JNIEnv *env = GetJNIForThread(); - - if (!env) { - ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); - return NULL; - } - - GeckoAppShell* ret = new GeckoAppShell(obj, env); - env->DeleteLocalRef(obj); - return ret; -} - -void GeckoAppShell::AcknowledgeEvent() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::AcknowledgeEvent() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -203,22 +141,21 @@ void GeckoAppShell::AcknowledgeEvent() { if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::AddPluginViewWrapper(jobject a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4, bool a5) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::AddPluginViewWrapper(jobject a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4, bool a5) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(1) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -238,55 +175,53 @@ void GeckoAppShell::AddPluginViewWrapper if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::AlertsProgressListener_OnProgress(const nsAString& a0, int64_t a1, int64_t a2, const nsAString& a3) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::AlertsProgressListener_OnProgress(const nsAString& a0, int64_t a1, int64_t a2, const nsAString& a3) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(2) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return; } jvalue args[4]; - args[0].l = AndroidBridge::NewJavaString(env, a0); + args[0].l = NewJavaString(env, a0); args[1].j = a1; args[2].j = a2; - args[3].l = AndroidBridge::NewJavaString(env, a3); + args[3].l = NewJavaString(env, a3); env->CallStaticVoidMethodA(mGeckoAppShellClass, jAlertsProgressListener_OnProgress, args); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::CancelVibrate() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::CancelVibrate() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -298,51 +233,49 @@ void GeckoAppShell::CancelVibrate() { if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::CheckURIVisited(const nsAString& a0) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::CheckURIVisited(const nsAString& a0) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(1) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return; } - jstring j0 = AndroidBridge::NewJavaString(env, a0); + jstring j0 = NewJavaString(env, a0); env->CallStaticVoidMethod(mGeckoAppShellClass, jCheckURIVisited, j0); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::ClearMessageList(int32_t a0) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::ClearMessageList(int32_t a0) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -354,22 +287,21 @@ void GeckoAppShell::ClearMessageList(int if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::CloseCamera() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::CloseCamera() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -381,51 +313,49 @@ void GeckoAppShell::CloseCamera() { if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::CloseNotification(const nsAString& a0) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::CloseNotification(const nsAString& a0) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(1) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return; } - jstring j0 = AndroidBridge::NewJavaString(env, a0); + jstring j0 = NewJavaString(env, a0); env->CallStaticVoidMethod(mGeckoAppShellClass, jCloseNotification, j0); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::CreateMessageListWrapper(int64_t a0, int64_t a1, jobjectArray a2, int32_t a3, int32_t a4, bool a5, int32_t a6) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::CreateMessageListWrapper(int64_t a0, int64_t a1, jobjectArray a2, int32_t a3, int32_t a4, bool a5, int32_t a6) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(1) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -446,55 +376,53 @@ void GeckoAppShell::CreateMessageListWra if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::CreateShortcut(const nsAString& a0, const nsAString& a1, const nsAString& a2, const nsAString& a3) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::CreateShortcut(const nsAString& a0, const nsAString& a1, const nsAString& a2, const nsAString& a3) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(4) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return; } jvalue args[4]; - args[0].l = AndroidBridge::NewJavaString(env, a0); - args[1].l = AndroidBridge::NewJavaString(env, a1); - args[2].l = AndroidBridge::NewJavaString(env, a2); - args[3].l = AndroidBridge::NewJavaString(env, a3); + args[0].l = NewJavaString(env, a0); + args[1].l = NewJavaString(env, a1); + args[2].l = NewJavaString(env, a2); + args[3].l = NewJavaString(env, a3); env->CallStaticVoidMethodA(mGeckoAppShellClass, jCreateShortcut, args); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::DeleteMessageWrapper(int32_t a0, int32_t a1) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::DeleteMessageWrapper(int32_t a0, int32_t a1) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -506,22 +434,21 @@ void GeckoAppShell::DeleteMessageWrapper if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::DisableBatteryNotifications() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::DisableBatteryNotifications() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -533,22 +460,21 @@ void GeckoAppShell::DisableBatteryNotifi if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::DisableNetworkNotifications() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::DisableNetworkNotifications() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -560,22 +486,21 @@ void GeckoAppShell::DisableNetworkNotifi if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::DisableScreenOrientationNotifications() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::DisableScreenOrientationNotifications() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -587,22 +512,21 @@ void GeckoAppShell::DisableScreenOrienta if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::DisableSensor(int32_t a0) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::DisableSensor(int32_t a0) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -614,22 +538,21 @@ void GeckoAppShell::DisableSensor(int32_ if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::EnableBatteryNotifications() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::EnableBatteryNotifications() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -641,22 +564,21 @@ void GeckoAppShell::EnableBatteryNotific if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::EnableLocation(bool a0) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::EnableLocation(bool a0) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -668,22 +590,21 @@ void GeckoAppShell::EnableLocation(bool if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::EnableLocationHighAccuracy(bool a0) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::EnableLocationHighAccuracy(bool a0) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -695,22 +616,21 @@ void GeckoAppShell::EnableLocationHighAc if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::EnableNetworkNotifications() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::EnableNetworkNotifications() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -722,22 +642,21 @@ void GeckoAppShell::EnableNetworkNotific if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::EnableScreenOrientationNotifications() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::EnableScreenOrientationNotifications() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -749,22 +668,21 @@ void GeckoAppShell::EnableScreenOrientat if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::EnableSensor(int32_t a0) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::EnableSensor(int32_t a0) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -776,21 +694,20 @@ void GeckoAppShell::EnableSensor(int32_t if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -jobject GeckoAppShell::GetContext() { +jobject AndroidBridge::GetContext() { JNIEnv *env = GetJNIForThread(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; } if (env->PushLocalFrame(1) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); @@ -803,23 +720,22 @@ jobject GeckoAppShell::GetContext() { if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return nullptr; } - jobject ret = static_cast<jobject>(env->PopLocalFrame(temp)); return ret; } -jdoubleArray GeckoAppShell::GetCurrentBatteryInformationWrapper() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +jdoubleArray AndroidBridge::GetCurrentBatteryInformationWrapper() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; } if (env->PushLocalFrame(1) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -831,23 +747,22 @@ jdoubleArray GeckoAppShell::GetCurrentBa if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return nullptr; } - jdoubleArray ret = static_cast<jdoubleArray>(env->PopLocalFrame(temp)); return ret; } -jdoubleArray GeckoAppShell::GetCurrentNetworkInformationWrapper() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +jdoubleArray AndroidBridge::GetCurrentNetworkInformationWrapper() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; } if (env->PushLocalFrame(1) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -859,23 +774,22 @@ jdoubleArray GeckoAppShell::GetCurrentNe if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return nullptr; } - jdoubleArray ret = static_cast<jdoubleArray>(env->PopLocalFrame(temp)); return ret; } -jfloat GeckoAppShell::GetDensity() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +jfloat AndroidBridge::GetDensity() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return 0.0; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -887,23 +801,22 @@ jfloat GeckoAppShell::GetDensity() { if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return 0.0; } - env->PopLocalFrame(NULL); return temp; } -int32_t GeckoAppShell::GetDpiWrapper() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +int32_t AndroidBridge::GetDpiWrapper() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return 0; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -915,53 +828,51 @@ int32_t GeckoAppShell::GetDpiWrapper() { if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return 0; } - env->PopLocalFrame(NULL); return temp; } -jstring GeckoAppShell::GetExtensionFromMimeTypeWrapper(const nsAString& a0) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +jstring AndroidBridge::GetExtensionFromMimeTypeWrapper(const nsAString& a0) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; } if (env->PushLocalFrame(2) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return nullptr; } - jstring j0 = AndroidBridge::NewJavaString(env, a0); + jstring j0 = NewJavaString(env, a0); jobject temp = env->CallStaticObjectMethod(mGeckoAppShellClass, jGetExtensionFromMimeTypeWrapper, j0); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return nullptr; } - jstring ret = static_cast<jstring>(env->PopLocalFrame(temp)); return ret; } -jstring GeckoAppShell::GetGfxInfoDataWrapper() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +jstring AndroidBridge::GetGfxInfoDataWrapper() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; } if (env->PushLocalFrame(1) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -973,115 +884,111 @@ jstring GeckoAppShell::GetGfxInfoDataWra if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return nullptr; } - jstring ret = static_cast<jstring>(env->PopLocalFrame(temp)); return ret; } -jobjectArray GeckoAppShell::GetHandlersForMimeTypeWrapper(const nsAString& a0, const nsAString& a1) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +jobjectArray AndroidBridge::GetHandlersForMimeTypeWrapper(const nsAString& a0, const nsAString& a1) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; } if (env->PushLocalFrame(3) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return nullptr; } - jstring j0 = AndroidBridge::NewJavaString(env, a0); - jstring j1 = AndroidBridge::NewJavaString(env, a1); + jstring j0 = NewJavaString(env, a0); + jstring j1 = NewJavaString(env, a1); jobject temp = env->CallStaticObjectMethod(mGeckoAppShellClass, jGetHandlersForMimeTypeWrapper, j0, j1); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return nullptr; } - jobjectArray ret = static_cast<jobjectArray>(env->PopLocalFrame(temp)); return ret; } -jobjectArray GeckoAppShell::GetHandlersForURLWrapper(const nsAString& a0, const nsAString& a1) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +jobjectArray AndroidBridge::GetHandlersForURLWrapper(const nsAString& a0, const nsAString& a1) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; } if (env->PushLocalFrame(3) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return nullptr; } - jstring j0 = AndroidBridge::NewJavaString(env, a0); - jstring j1 = AndroidBridge::NewJavaString(env, a1); + jstring j0 = NewJavaString(env, a0); + jstring j1 = NewJavaString(env, a1); jobject temp = env->CallStaticObjectMethod(mGeckoAppShellClass, jGetHandlersForURLWrapper, j0, j1); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return nullptr; } - jobjectArray ret = static_cast<jobjectArray>(env->PopLocalFrame(temp)); return ret; } -jbyteArray GeckoAppShell::GetIconForExtensionWrapper(const nsAString& a0, int32_t a1) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +jbyteArray AndroidBridge::GetIconForExtensionWrapper(const nsAString& a0, int32_t a1) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; } if (env->PushLocalFrame(2) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return nullptr; } - jstring j0 = AndroidBridge::NewJavaString(env, a0); + jstring j0 = NewJavaString(env, a0); jobject temp = env->CallStaticObjectMethod(mGeckoAppShellClass, jGetIconForExtensionWrapper, j0, a1); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return nullptr; } - jbyteArray ret = static_cast<jbyteArray>(env->PopLocalFrame(temp)); return ret; } -void GeckoAppShell::GetMessageWrapper(int32_t a0, int32_t a1) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::GetMessageWrapper(int32_t a0, int32_t a1) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -1093,52 +1000,50 @@ void GeckoAppShell::GetMessageWrapper(in if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -jstring GeckoAppShell::GetMimeTypeFromExtensionsWrapper(const nsAString& a0) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +jstring AndroidBridge::GetMimeTypeFromExtensionsWrapper(const nsAString& a0) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; } if (env->PushLocalFrame(2) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return nullptr; } - jstring j0 = AndroidBridge::NewJavaString(env, a0); + jstring j0 = NewJavaString(env, a0); jobject temp = env->CallStaticObjectMethod(mGeckoAppShellClass, jGetMimeTypeFromExtensionsWrapper, j0); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return nullptr; } - jstring ret = static_cast<jstring>(env->PopLocalFrame(temp)); return ret; } -void GeckoAppShell::GetNextMessageInListWrapper(int32_t a0, int32_t a1) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::GetNextMessageInListWrapper(int32_t a0, int32_t a1) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -1150,56 +1055,54 @@ void GeckoAppShell::GetNextMessageInList if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -jstring GeckoAppShell::GetProxyForURIWrapper(const nsAString& a0, const nsAString& a1, const nsAString& a2, int32_t a3) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +jstring AndroidBridge::GetProxyForURIWrapper(const nsAString& a0, const nsAString& a1, const nsAString& a2, int32_t a3) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; } if (env->PushLocalFrame(4) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return nullptr; } jvalue args[4]; - args[0].l = AndroidBridge::NewJavaString(env, a0); - args[1].l = AndroidBridge::NewJavaString(env, a1); - args[2].l = AndroidBridge::NewJavaString(env, a2); + args[0].l = NewJavaString(env, a0); + args[1].l = NewJavaString(env, a1); + args[2].l = NewJavaString(env, a2); args[3].i = a3; jobject temp = env->CallStaticObjectMethodA(mGeckoAppShellClass, jGetProxyForURIWrapper, args); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return nullptr; } - jstring ret = static_cast<jstring>(env->PopLocalFrame(temp)); return ret; } -int32_t GeckoAppShell::GetScreenDepthWrapper() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +int32_t AndroidBridge::GetScreenDepthWrapper() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return 0; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -1211,23 +1114,22 @@ int32_t GeckoAppShell::GetScreenDepthWra if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return 0; } - env->PopLocalFrame(NULL); return temp; } -int16_t GeckoAppShell::GetScreenOrientationWrapper() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +int16_t AndroidBridge::GetScreenOrientationWrapper() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return 0; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -1239,23 +1141,22 @@ int16_t GeckoAppShell::GetScreenOrientat if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return 0; } - env->PopLocalFrame(NULL); return temp; } -bool GeckoAppShell::GetShowPasswordSetting() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +bool AndroidBridge::GetShowPasswordSetting() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return false; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -1267,23 +1168,22 @@ bool GeckoAppShell::GetShowPasswordSetti if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return false; } - env->PopLocalFrame(NULL); return temp; } -jintArray GeckoAppShell::GetSystemColoursWrapper() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +jintArray AndroidBridge::GetSystemColoursWrapper() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; } if (env->PushLocalFrame(1) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -1295,53 +1195,51 @@ jintArray GeckoAppShell::GetSystemColour if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return nullptr; } - jintArray ret = static_cast<jintArray>(env->PopLocalFrame(temp)); return ret; } -jstring GeckoAppShell::HandleGeckoMessageWrapper(const nsAString& a0) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +jstring AndroidBridge::HandleGeckoMessageWrapper(const nsAString& a0) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; } if (env->PushLocalFrame(2) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return nullptr; } - jstring j0 = AndroidBridge::NewJavaString(env, a0); + jstring j0 = NewJavaString(env, a0); jobject temp = env->CallStaticObjectMethod(mGeckoAppShellClass, jHandleGeckoMessageWrapper, j0); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return nullptr; } - jstring ret = static_cast<jstring>(env->PopLocalFrame(temp)); return ret; } -void GeckoAppShell::HideProgressDialog() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::HideProgressDialog() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -1353,56 +1251,54 @@ void GeckoAppShell::HideProgressDialog() if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -jintArray GeckoAppShell::InitCameraWrapper(const nsAString& a0, int32_t a1, int32_t a2, int32_t a3) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +jintArray AndroidBridge::InitCameraWrapper(const nsAString& a0, int32_t a1, int32_t a2, int32_t a3) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; } if (env->PushLocalFrame(2) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return nullptr; } jvalue args[4]; - args[0].l = AndroidBridge::NewJavaString(env, a0); + args[0].l = NewJavaString(env, a0); args[1].i = a1; args[2].i = a2; args[3].i = a3; jobject temp = env->CallStaticObjectMethodA(mGeckoAppShellClass, jInitCameraWrapper, args); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return nullptr; } - jintArray ret = static_cast<jintArray>(env->PopLocalFrame(temp)); return ret; } -bool GeckoAppShell::IsNetworkLinkKnown() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +bool AndroidBridge::IsNetworkLinkKnown() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return false; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -1414,23 +1310,22 @@ bool GeckoAppShell::IsNetworkLinkKnown() if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return false; } - env->PopLocalFrame(NULL); return temp; } -bool GeckoAppShell::IsNetworkLinkUp() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +bool AndroidBridge::IsNetworkLinkUp() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return false; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -1442,23 +1337,22 @@ bool GeckoAppShell::IsNetworkLinkUp() { if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return false; } - env->PopLocalFrame(NULL); return temp; } -bool GeckoAppShell::IsTablet() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +bool AndroidBridge::IsTablet() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return false; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -1470,23 +1364,22 @@ bool GeckoAppShell::IsTablet() { if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return false; } - env->PopLocalFrame(NULL); return temp; } -void GeckoAppShell::KillAnyZombies() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::KillAnyZombies() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -1498,22 +1391,21 @@ void GeckoAppShell::KillAnyZombies() { if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::LockScreenOrientation(int32_t a0) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::LockScreenOrientation(int32_t a0) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -1525,51 +1417,49 @@ void GeckoAppShell::LockScreenOrientatio if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::MarkURIVisited(const nsAString& a0) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::MarkURIVisited(const nsAString& a0) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(1) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return; } - jstring j0 = AndroidBridge::NewJavaString(env, a0); + jstring j0 = NewJavaString(env, a0); env->CallStaticVoidMethod(mGeckoAppShellClass, jMarkURIVisited, j0); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::MoveTaskToBack() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::MoveTaskToBack() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -1581,22 +1471,21 @@ void GeckoAppShell::MoveTaskToBack() { if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::NotifyDefaultPrevented(bool a0) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::NotifyDefaultPrevented(bool a0) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -1608,145 +1497,155 @@ void GeckoAppShell::NotifyDefaultPrevent if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::NotifyIME(int32_t a0) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::NotifyIME(int32_t a0) { + if (!sBridge) { + ALOG_BRIDGE("Aborted: No sBridge - %s", __PRETTY_FUNCTION__); + return; + } + + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return; } - env->CallStaticVoidMethod(mGeckoAppShellClass, jNotifyIME, a0); + env->CallStaticVoidMethod(sBridge->mGeckoAppShellClass, sBridge->jNotifyIME, a0); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::NotifyIMEChange(const nsAString& a0, int32_t a1, int32_t a2, int32_t a3) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::NotifyIMEChange(const nsAString& a0, int32_t a1, int32_t a2, int32_t a3) { + if (!sBridge) { + ALOG_BRIDGE("Aborted: No sBridge - %s", __PRETTY_FUNCTION__); + return; + } + + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(1) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return; } jvalue args[4]; - args[0].l = AndroidBridge::NewJavaString(env, a0); + args[0].l = NewJavaString(env, a0); args[1].i = a1; args[2].i = a2; args[3].i = a3; - env->CallStaticVoidMethodA(mGeckoAppShellClass, jNotifyIMEChange, args); + env->CallStaticVoidMethodA(sBridge->mGeckoAppShellClass, sBridge->jNotifyIMEChange, args); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::NotifyIMEContext(int32_t a0, const nsAString& a1, const nsAString& a2, const nsAString& a3) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::NotifyIMEContext(int32_t a0, const nsAString& a1, const nsAString& a2, const nsAString& a3) { + if (!sBridge) { + ALOG_BRIDGE("Aborted: No sBridge - %s", __PRETTY_FUNCTION__); + return; + } + + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(3) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return; } jvalue args[4]; args[0].i = a0; - args[1].l = AndroidBridge::NewJavaString(env, a1); - args[2].l = AndroidBridge::NewJavaString(env, a2); - args[3].l = AndroidBridge::NewJavaString(env, a3); - - env->CallStaticVoidMethodA(mGeckoAppShellClass, jNotifyIMEContext, args); + args[1].l = NewJavaString(env, a1); + args[2].l = NewJavaString(env, a2); + args[3].l = NewJavaString(env, a3); + + env->CallStaticVoidMethodA(sBridge->mGeckoAppShellClass, sBridge->jNotifyIMEContext, args); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::NotifyWakeLockChanged(const nsAString& a0, const nsAString& a1) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::NotifyWakeLockChanged(const nsAString& a0, const nsAString& a1) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(2) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return; } - jstring j0 = AndroidBridge::NewJavaString(env, a0); - jstring j1 = AndroidBridge::NewJavaString(env, a1); + jstring j0 = NewJavaString(env, a0); + jstring j1 = NewJavaString(env, a1); env->CallStaticVoidMethod(mGeckoAppShellClass, jNotifyWakeLockChanged, j0, j1); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::NotifyXreExit() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::NotifyXreExit() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -1758,58 +1657,56 @@ void GeckoAppShell::NotifyXreExit() { if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -bool GeckoAppShell::OpenUriExternal(const nsAString& a0, const nsAString& a1, const nsAString& a2, const nsAString& a3, const nsAString& a4, const nsAString& a5) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +bool AndroidBridge::OpenUriExternal(const nsAString& a0, const nsAString& a1, const nsAString& a2, const nsAString& a3, const nsAString& a4, const nsAString& a5) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return false; } if (env->PushLocalFrame(6) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return false; } jvalue args[6]; - args[0].l = AndroidBridge::NewJavaString(env, a0); - args[1].l = AndroidBridge::NewJavaString(env, a1); - args[2].l = AndroidBridge::NewJavaString(env, a2); - args[3].l = AndroidBridge::NewJavaString(env, a3); - args[4].l = AndroidBridge::NewJavaString(env, a4); - args[5].l = AndroidBridge::NewJavaString(env, a5); + args[0].l = NewJavaString(env, a0); + args[1].l = NewJavaString(env, a1); + args[2].l = NewJavaString(env, a2); + args[3].l = NewJavaString(env, a3); + args[4].l = NewJavaString(env, a4); + args[5].l = NewJavaString(env, a5); bool temp = env->CallStaticBooleanMethodA(mGeckoAppShellClass, jOpenUriExternal, args); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return false; } - env->PopLocalFrame(NULL); return temp; } -void GeckoAppShell::PerformHapticFeedback(bool a0) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::PerformHapticFeedback(bool a0) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -1821,22 +1718,21 @@ void GeckoAppShell::PerformHapticFeedbac if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -bool GeckoAppShell::PumpMessageLoop() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +bool AndroidBridge::PumpMessageLoop() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return false; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -1848,23 +1744,22 @@ bool GeckoAppShell::PumpMessageLoop() { if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return false; } - env->PopLocalFrame(NULL); return temp; } -void GeckoAppShell::RegisterSurfaceTextureFrameListener(jobject a0, int32_t a1) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::RegisterSurfaceTextureFrameListener(jobject a0, int32_t a1) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(1) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -1876,22 +1771,21 @@ void GeckoAppShell::RegisterSurfaceTextu if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::RemovePluginView(jobject a0, bool a1) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::RemovePluginView(jobject a0, bool a1) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(1) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -1903,52 +1797,50 @@ void GeckoAppShell::RemovePluginView(job if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::ScanMedia(const nsAString& a0, const nsAString& a1) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::ScanMedia(const nsAString& a0, const nsAString& a1) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(2) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return; } - jstring j0 = AndroidBridge::NewJavaString(env, a0); - jstring j1 = AndroidBridge::NewJavaString(env, a1); + jstring j0 = NewJavaString(env, a0); + jstring j1 = NewJavaString(env, a1); env->CallStaticVoidMethod(mGeckoAppShellClass, jScanMedia, j0, j1); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::ScheduleRestart() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::ScheduleRestart() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -1960,54 +1852,52 @@ void GeckoAppShell::ScheduleRestart() { if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::SendMessageWrapper(const nsAString& a0, const nsAString& a1, int32_t a2) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::SendMessageWrapper(const nsAString& a0, const nsAString& a1, int32_t a2) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(2) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return; } jvalue args[3]; - args[0].l = AndroidBridge::NewJavaString(env, a0); - args[1].l = AndroidBridge::NewJavaString(env, a1); + args[0].l = NewJavaString(env, a0); + args[1].l = NewJavaString(env, a1); args[2].i = a2; env->CallStaticVoidMethodA(mGeckoAppShellClass, jSendMessageWrapper, args); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::SetFullScreen(bool a0) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::SetFullScreen(bool a0) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -2019,22 +1909,21 @@ void GeckoAppShell::SetFullScreen(bool a if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::SetKeepScreenOn(bool a0) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::SetKeepScreenOn(bool a0) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -2046,204 +1935,197 @@ void GeckoAppShell::SetKeepScreenOn(bool if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::SetSelectedLocale(const nsAString& a0) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::SetSelectedLocale(const nsAString& a0) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(1) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return; } - jstring j0 = AndroidBridge::NewJavaString(env, a0); + jstring j0 = NewJavaString(env, a0); env->CallStaticVoidMethod(mGeckoAppShellClass, jSetSelectedLocale, j0); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::SetURITitle(const nsAString& a0, const nsAString& a1) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::SetURITitle(const nsAString& a0, const nsAString& a1) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(2) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return; } - jstring j0 = AndroidBridge::NewJavaString(env, a0); - jstring j1 = AndroidBridge::NewJavaString(env, a1); + jstring j0 = NewJavaString(env, a0); + jstring j1 = NewJavaString(env, a1); env->CallStaticVoidMethod(mGeckoAppShellClass, jSetURITitle, j0, j1); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::ShowAlertNotificationWrapper(const nsAString& a0, const nsAString& a1, const nsAString& a2, const nsAString& a3, const nsAString& a4) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::ShowAlertNotificationWrapper(const nsAString& a0, const nsAString& a1, const nsAString& a2, const nsAString& a3, const nsAString& a4) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(5) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return; } jvalue args[5]; - args[0].l = AndroidBridge::NewJavaString(env, a0); - args[1].l = AndroidBridge::NewJavaString(env, a1); - args[2].l = AndroidBridge::NewJavaString(env, a2); - args[3].l = AndroidBridge::NewJavaString(env, a3); - args[4].l = AndroidBridge::NewJavaString(env, a4); + args[0].l = NewJavaString(env, a0); + args[1].l = NewJavaString(env, a1); + args[2].l = NewJavaString(env, a2); + args[3].l = NewJavaString(env, a3); + args[4].l = NewJavaString(env, a4); env->CallStaticVoidMethodA(mGeckoAppShellClass, jShowAlertNotificationWrapper, args); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::ShowFilePickerAsyncWrapper(const nsAString& a0, int64_t a1) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::ShowFilePickerAsyncWrapper(const nsAString& a0, int64_t a1) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(1) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return; } - jstring j0 = AndroidBridge::NewJavaString(env, a0); + jstring j0 = NewJavaString(env, a0); env->CallStaticVoidMethod(mGeckoAppShellClass, jShowFilePickerAsyncWrapper, j0, a1); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -jstring GeckoAppShell::ShowFilePickerForExtensionsWrapper(const nsAString& a0) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +jstring AndroidBridge::ShowFilePickerForExtensionsWrapper(const nsAString& a0) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; } if (env->PushLocalFrame(2) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return nullptr; } - jstring j0 = AndroidBridge::NewJavaString(env, a0); + jstring j0 = NewJavaString(env, a0); jobject temp = env->CallStaticObjectMethod(mGeckoAppShellClass, jShowFilePickerForExtensionsWrapper, j0); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return nullptr; } - jstring ret = static_cast<jstring>(env->PopLocalFrame(temp)); return ret; } -jstring GeckoAppShell::ShowFilePickerForMimeTypeWrapper(const nsAString& a0) { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +jstring AndroidBridge::ShowFilePickerForMimeTypeWrapper(const nsAString& a0) { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; } if (env->PushLocalFrame(2) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); return nullptr; } - jstring j0 = AndroidBridge::NewJavaString(env, a0); + jstring j0 = NewJavaString(env, a0); jobject temp = env->CallStaticObjectMethod(mGeckoAppShellClass, jShowFilePickerForMimeTypeWrapper, j0); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return nullptr; } - jstring ret = static_cast<jstring>(env->PopLocalFrame(temp)); return ret; } -void GeckoAppShell::ShowInputMethodPicker() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::ShowInputMethodPicker() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -2255,22 +2137,21 @@ void GeckoAppShell::ShowInputMethodPicke if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -bool GeckoAppShell::UnlockProfile() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +bool AndroidBridge::UnlockProfile() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return false; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -2282,23 +2163,22 @@ bool GeckoAppShell::UnlockProfile() { if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return false; } - env->PopLocalFrame(NULL); return temp; } -void GeckoAppShell::UnlockScreenOrientation() { - JNIEnv *env = AndroidBridge::GetJNIEnv(); +void AndroidBridge::UnlockScreenOrientation() { + JNIEnv *env = GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(0) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); @@ -2310,21 +2190,20 @@ void GeckoAppShell::UnlockScreenOrientat if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); env->ExceptionDescribe(); env->ExceptionClear(); env->PopLocalFrame(NULL); return; } - env->PopLocalFrame(NULL); } -void GeckoAppShell::UnregisterSurfaceTextureFrameListener(jobject a0) { +void AndroidBridge::UnregisterSurfaceTextureFrameListener(jobject a0) { JNIEnv *env = GetJNIForThread(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; } if (env->PushLocalFrame(1) != 0) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); @@ -2337,22 +2216,21 @@ void GeckoAppShell::UnregisterSurfaceTex if (env->ExceptionCheck()) { <