mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1116589 - Use templated JNI classes in generated bindings; r=snorp
This commit is contained in:
parent
b7e5322f21
commit
c02561a822
2
CLOBBER
2
CLOBBER
@ -22,4 +22,4 @@
|
||||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Bug 1056337 - Change default compiler for B2G ICS builds.
|
||||
Bug 1116589 - Clobber needed to update autogenerated Android library bindings.
|
||||
|
@ -22,7 +22,7 @@ public class AnnotationInfo {
|
||||
narrowChars = aNarrowChars;
|
||||
catchException = aCatchException;
|
||||
|
||||
if (!noThrow && catchException) {
|
||||
if (noThrow && catchException) {
|
||||
// It doesn't make sense to have these together
|
||||
throw new IllegalArgumentException("noThrow and catchException are not allowed together");
|
||||
}
|
||||
|
@ -20,9 +20,11 @@ public class AnnotationProcessor {
|
||||
|
||||
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";
|
||||
"// Generated by the Java program at /build/annotationProcessors at compile time\n" +
|
||||
"// from annotations on Java methods. To update, change the annotations on the\n" +
|
||||
"// corresponding Javamethods and rerun the build. Manually updating this file\n" +
|
||||
"// 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.
|
||||
@ -44,29 +46,24 @@ public class AnnotationProcessor {
|
||||
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 *env);\n\n");
|
||||
headerFile.append(
|
||||
"#ifndef GeneratedJNIWrappers_h__\n" +
|
||||
"#define GeneratedJNIWrappers_h__\n" +
|
||||
"\n" +
|
||||
"#include \"mozilla/jni/Refs.h\"\n" +
|
||||
"\n" +
|
||||
"namespace mozilla {\n" +
|
||||
"namespace widget {\n" +
|
||||
"\n");
|
||||
|
||||
StringBuilder implementationFile = new StringBuilder(GENERATED_COMMENT);
|
||||
implementationFile.append("#include \"GeneratedJNIWrappers.h\"\n" +
|
||||
"#include \"AndroidBridgeUtilities.h\"\n" +
|
||||
"#include \"nsXPCOMStrings.h\"\n" +
|
||||
"#include \"AndroidBridge.h\"\n" +
|
||||
"\n" +
|
||||
"namespace mozilla {\n" +
|
||||
"namespace widget {\n" +
|
||||
"namespace android {\n");
|
||||
|
||||
// Used to track the calls to the various class-specific initialisation functions.
|
||||
StringBuilder stubInitialiser = new StringBuilder();
|
||||
stubInitialiser.append("void InitStubs(JNIEnv *env) {\n");
|
||||
implementationFile.append(
|
||||
"#include \"GeneratedJNIWrappers.h\"\n" +
|
||||
"#include \"mozilla/jni/Accessors.h\"\n" +
|
||||
"\n" +
|
||||
"namespace mozilla {\n" +
|
||||
"namespace widget {\n" +
|
||||
"\n");
|
||||
|
||||
while (jarClassIterator.hasNext()) {
|
||||
ClassWithOptions aClassTuple = jarClassIterator.next();
|
||||
@ -79,9 +76,7 @@ public class AnnotationProcessor {
|
||||
if (!methodIterator.hasNext()) {
|
||||
continue;
|
||||
}
|
||||
generatorInstance = new CodeGenerator(aClassTuple.wrappedClass, aClassTuple.generatedName);
|
||||
|
||||
stubInitialiser.append(" ").append(aClassTuple.generatedName).append("::InitStubs(env);\n");
|
||||
generatorInstance = new CodeGenerator(aClassTuple);
|
||||
|
||||
// Iterate all annotated members in this class..
|
||||
while (methodIterator.hasNext()) {
|
||||
@ -103,18 +98,16 @@ public class AnnotationProcessor {
|
||||
implementationFile.append(generatorInstance.getWrapperFileContents());
|
||||
}
|
||||
|
||||
implementationFile.append('\n');
|
||||
stubInitialiser.append("}");
|
||||
implementationFile.append(stubInitialiser);
|
||||
implementationFile.append(
|
||||
"\n" +
|
||||
"} /* widget */\n" +
|
||||
"} /* mozilla */\n");
|
||||
|
||||
implementationFile.append("\n} /* android */\n" +
|
||||
"} /* widget */\n" +
|
||||
"} /* mozilla */\n");
|
||||
|
||||
headerFile.append("\n} /* android */\n" +
|
||||
"} /* widget */\n" +
|
||||
"} /* mozilla */\n" +
|
||||
"#endif\n");
|
||||
headerFile.append(
|
||||
"\n" +
|
||||
"} /* widget */\n" +
|
||||
"} /* mozilla */\n" +
|
||||
"#endif // GeneratedJNIWrappers_h__\n");
|
||||
|
||||
writeOutputFiles(headerFile, implementationFile);
|
||||
long e = System.currentTimeMillis();
|
||||
@ -158,4 +151,4 @@ public class AnnotationProcessor {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -36,9 +36,11 @@ import java.lang.reflect.Modifier;
|
||||
public class SDKProcessor {
|
||||
public static final String GENERATED_COMMENT =
|
||||
"// GENERATED CODE\n" +
|
||||
"// Generated by the Java program at /build/annotationProcessors at compile time from\n" +
|
||||
"// annotations on Java methods. To update, change the annotations on the corresponding Java\n" +
|
||||
"// methods and rerun the build. Manually updating this file will cause your build to fail.\n\n";
|
||||
"// Generated by the Java program at /build/annotationProcessors at compile time\n" +
|
||||
"// from annotations on Java methods. To update, change the annotations on the\n" +
|
||||
"// corresponding Javamethods and rerun the build. Manually updating this file\n" +
|
||||
"// will cause your build to fail.\n" +
|
||||
"\n";
|
||||
|
||||
private static ApiLookup sApiLookup;
|
||||
private static int sMaxSdkVersion;
|
||||
@ -68,38 +70,34 @@ public class SDKProcessor {
|
||||
// Iterator<ClassWithOptions> jarClassIterator = IterableJarLoadingURLClassLoader.getIteratorOverJars(args);
|
||||
|
||||
StringBuilder headerFile = new StringBuilder(GENERATED_COMMENT);
|
||||
headerFile.append("#ifndef " + generatedFilePrefix + "_h__\n" +
|
||||
"#define " + generatedFilePrefix + "_h__\n" +
|
||||
"#include \"nsXPCOMStrings.h\"\n" +
|
||||
"#include \"AndroidJavaWrappers.h\"\n" +
|
||||
"\n" +
|
||||
"namespace mozilla {\n" +
|
||||
"namespace widget {\n" +
|
||||
"namespace android {\n" +
|
||||
"namespace sdk {\n" +
|
||||
"void Init" + generatedFilePrefix + "Stubs(JNIEnv *jEnv);\n\n");
|
||||
headerFile.append(
|
||||
"#ifndef " + generatedFilePrefix + "_h__\n" +
|
||||
"#define " + generatedFilePrefix + "_h__\n" +
|
||||
"\n" +
|
||||
"#include \"mozilla/jni/Refs.h\"\n" +
|
||||
"\n" +
|
||||
"namespace mozilla {\n" +
|
||||
"namespace widget {\n" +
|
||||
"namespace sdk {\n" +
|
||||
"\n");
|
||||
|
||||
StringBuilder implementationFile = new StringBuilder(GENERATED_COMMENT);
|
||||
implementationFile.append("#include \"" + generatedFilePrefix + ".h\"\n" +
|
||||
"#include \"AndroidBridgeUtilities.h\"\n" +
|
||||
"#include \"nsXPCOMStrings.h\"\n" +
|
||||
"#include \"AndroidBridge.h\"\n" +
|
||||
"\n" +
|
||||
"namespace mozilla {\n" +
|
||||
"namespace widget {\n" +
|
||||
"namespace android {\n" +
|
||||
"namespace sdk {\n");
|
||||
implementationFile.append(
|
||||
"#include \"" + generatedFilePrefix + ".h\"\n" +
|
||||
"#include \"mozilla/jni/Accessors.h\"\n" +
|
||||
"\n" +
|
||||
"namespace mozilla {\n" +
|
||||
"namespace widget {\n" +
|
||||
"namespace sdk {\n" +
|
||||
"\n");
|
||||
|
||||
// Used to track the calls to the various class-specific initialisation functions.
|
||||
StringBuilder stubInitializer = new StringBuilder();
|
||||
stubInitializer.append("void Init" + generatedFilePrefix + "Stubs(JNIEnv *jEnv) {\n");
|
||||
|
||||
ClassLoader loader = null;
|
||||
try {
|
||||
loader = URLClassLoader.newInstance(new URL[] { new URL("file://" + sdkJar) },
|
||||
SDKProcessor.class.getClassLoader());
|
||||
} catch (Exception e) {
|
||||
System.out.println(e);
|
||||
throw new RuntimeException(e.toString());
|
||||
}
|
||||
|
||||
for (Iterator<String> i = classes.iterator(); i.hasNext(); ) {
|
||||
@ -107,25 +105,20 @@ public class SDKProcessor {
|
||||
System.out.println("Looking up: " + className);
|
||||
|
||||
generateClass(Class.forName(className, true, loader),
|
||||
stubInitializer,
|
||||
implementationFile,
|
||||
headerFile);
|
||||
}
|
||||
|
||||
implementationFile.append('\n');
|
||||
stubInitializer.append("}");
|
||||
implementationFile.append(stubInitializer);
|
||||
implementationFile.append(
|
||||
"} /* sdk */\n" +
|
||||
"} /* widget */\n" +
|
||||
"} /* mozilla */\n");
|
||||
|
||||
implementationFile.append("\n} /* sdk */\n" +
|
||||
"} /* android */\n" +
|
||||
"} /* widget */\n" +
|
||||
"} /* mozilla */\n");
|
||||
|
||||
headerFile.append("\n} /* sdk */\n" +
|
||||
"} /* android */\n" +
|
||||
"} /* widget */\n" +
|
||||
"} /* mozilla */\n" +
|
||||
"#endif\n");
|
||||
headerFile.append(
|
||||
"} /* sdk */\n" +
|
||||
"} /* widget */\n" +
|
||||
"} /* mozilla */\n" +
|
||||
"#endif\n");
|
||||
|
||||
writeOutputFiles(outdir, generatedFilePrefix, headerFile, implementationFile);
|
||||
long e = System.currentTimeMillis();
|
||||
@ -145,12 +138,13 @@ public class SDKProcessor {
|
||||
int version = 0;
|
||||
|
||||
if (m instanceof Method || m instanceof Constructor) {
|
||||
version = sApiLookup.getCallVersion(Utils.getTypeSignatureStringForClass(m.getDeclaringClass()),
|
||||
m.getName(),
|
||||
Utils.getTypeSignatureStringForMember(m));
|
||||
version = sApiLookup.getCallVersion(
|
||||
Utils.getClassDescriptor(m.getDeclaringClass()),
|
||||
m.getName(),
|
||||
Utils.getSignature(m));
|
||||
} else if (m instanceof Field) {
|
||||
version = sApiLookup.getFieldVersion(Utils.getTypeSignatureStringForClass(m.getDeclaringClass()),
|
||||
m.getName());
|
||||
version = sApiLookup.getFieldVersion(
|
||||
Utils.getClassDescriptor(m.getDeclaringClass()), m.getName());
|
||||
} else {
|
||||
throw new IllegalArgumentException("expected member to be Method, Constructor, or Field");
|
||||
}
|
||||
@ -168,13 +162,11 @@ public class SDKProcessor {
|
||||
}
|
||||
|
||||
private static void generateClass(Class<?> clazz,
|
||||
StringBuilder stubInitializer,
|
||||
StringBuilder implementationFile,
|
||||
StringBuilder headerFile) {
|
||||
String generatedName = clazz.getSimpleName();
|
||||
|
||||
CodeGenerator generator = new CodeGenerator(clazz, generatedName, true);
|
||||
stubInitializer.append(" ").append(generatedName).append("::InitStubs(jEnv);\n");
|
||||
CodeGenerator generator = new CodeGenerator(new ClassWithOptions(clazz, generatedName));
|
||||
|
||||
generator.generateMembers(sortAndFilterMembers(clazz.getDeclaredConstructors()));
|
||||
generator.generateMembers(sortAndFilterMembers(clazz.getDeclaredMethods()));
|
||||
|
@ -57,16 +57,16 @@ public class AlphabeticAnnotatableEntityComparator<T extends Member> implements
|
||||
}
|
||||
|
||||
// The names were the same, so we need to compare signatures to find their uniqueness..
|
||||
lName = Utils.getTypeSignatureStringForMethod(aLhs);
|
||||
rName = Utils.getTypeSignatureStringForMethod(aRhs);
|
||||
lName = Utils.getSignature(aLhs);
|
||||
rName = Utils.getSignature(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);
|
||||
String lName = Utils.getSignature(aLhs);
|
||||
String rName = Utils.getSignature(aRhs);
|
||||
|
||||
return lName.compareTo(rName);
|
||||
}
|
||||
|
@ -119,8 +119,7 @@ public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
|
||||
|
||||
// If the method name was not explicitly given in the annotation generate one...
|
||||
if (stubName.isEmpty()) {
|
||||
String aMethodName = candidateElement.getName();
|
||||
stubName = aMethodName.substring(0, 1).toUpperCase() + aMethodName.substring(1);
|
||||
stubName = Utils.getNativeName(candidateElement);
|
||||
}
|
||||
|
||||
AnnotationInfo annotationInfo = new AnnotationInfo(
|
||||
@ -130,11 +129,15 @@ public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
|
||||
}
|
||||
}
|
||||
|
||||
// If no annotation found, we might be expected to generate anyway using default arguments,
|
||||
// thanks to the "Generate everything" annotation.
|
||||
// If no annotation found, we might be expected to generate anyway
|
||||
// using default arguments, thanks to the "Generate everything" annotation.
|
||||
if (mIterateEveryEntry) {
|
||||
AnnotationInfo annotationInfo = new AnnotationInfo(
|
||||
candidateElement.getName(), false, false, false, false);
|
||||
Utils.getNativeName(candidateElement),
|
||||
/* multithreaded */ true,
|
||||
/* noThrow */ false,
|
||||
/* narrowChars */ false,
|
||||
/* catchException */ false);
|
||||
mNextReturnValue = new AnnotatableEntity(candidateElement, annotationInfo);
|
||||
return;
|
||||
}
|
||||
|
@ -4,7 +4,8 @@
|
||||
|
||||
package org.mozilla.gecko.annotationProcessors.utils;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import org.mozilla.gecko.annotationProcessors.AnnotationInfo;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Member;
|
||||
@ -18,647 +19,229 @@ import java.util.HashMap;
|
||||
public class Utils {
|
||||
|
||||
// A collection of lookup tables to simplify the functions to follow...
|
||||
private static final HashMap<String, String> sBasicCTypes = new HashMap<String, String>();
|
||||
private static final HashMap<String, String> NATIVE_TYPES = new HashMap<String, String>();
|
||||
|
||||
static {
|
||||
sBasicCTypes.put("void", "void");
|
||||
sBasicCTypes.put("int", "int32_t");
|
||||
sBasicCTypes.put("boolean", "bool");
|
||||
sBasicCTypes.put("long", "int64_t");
|
||||
sBasicCTypes.put("double", "jdouble");
|
||||
sBasicCTypes.put("float", "jfloat");
|
||||
sBasicCTypes.put("char", "uint16_t");
|
||||
sBasicCTypes.put("byte", "int8_t");
|
||||
sBasicCTypes.put("short", "int16_t");
|
||||
NATIVE_TYPES.put("void", "void");
|
||||
NATIVE_TYPES.put("boolean", "bool");
|
||||
NATIVE_TYPES.put("byte", "int8_t");
|
||||
NATIVE_TYPES.put("char", "char16_t");
|
||||
NATIVE_TYPES.put("short", "int16_t");
|
||||
NATIVE_TYPES.put("int", "int32_t");
|
||||
NATIVE_TYPES.put("long", "int64_t");
|
||||
NATIVE_TYPES.put("float", "float");
|
||||
NATIVE_TYPES.put("double", "double");
|
||||
}
|
||||
|
||||
private static final HashMap<String, String> sArrayCTypes = new HashMap<String, String>();
|
||||
private static final HashMap<String, String> NATIVE_ARRAY_TYPES = new HashMap<String, String>();
|
||||
|
||||
static {
|
||||
sArrayCTypes.put("int", "jintArray");
|
||||
sArrayCTypes.put("boolean", "jbooleanArray");
|
||||
sArrayCTypes.put("long", "jlongArray");
|
||||
sArrayCTypes.put("double", "jdoubleArray");
|
||||
sArrayCTypes.put("float", "jfloatArray");
|
||||
sArrayCTypes.put("char", "jcharArray");
|
||||
sArrayCTypes.put("byte", "jbyteArray");
|
||||
sArrayCTypes.put("short", "jshortArray");
|
||||
NATIVE_ARRAY_TYPES.put("boolean", "mozilla::jni::BooleanArray");
|
||||
NATIVE_ARRAY_TYPES.put("byte", "mozilla::jni::ByteArray");
|
||||
NATIVE_ARRAY_TYPES.put("char", "mozilla::jni::CharArray");
|
||||
NATIVE_ARRAY_TYPES.put("short", "mozilla::jni::ShortArray");
|
||||
NATIVE_ARRAY_TYPES.put("int", "mozilla::jni::IntArray");
|
||||
NATIVE_ARRAY_TYPES.put("long", "mozilla::jni::LongArray");
|
||||
NATIVE_ARRAY_TYPES.put("float", "mozilla::jni::FloatArray");
|
||||
NATIVE_ARRAY_TYPES.put("double", "mozilla::jni::DoubleArray");
|
||||
}
|
||||
|
||||
private static final HashMap<String, String> sStaticCallTypes = new HashMap<String, String>();
|
||||
private static final HashMap<String, String> CLASS_DESCRIPTORS = new HashMap<String, String>();
|
||||
|
||||
static {
|
||||
sStaticCallTypes.put("void", "CallStaticVoidMethod");
|
||||
sStaticCallTypes.put("int", "CallStaticIntMethod");
|
||||
sStaticCallTypes.put("boolean", "CallStaticBooleanMethod");
|
||||
sStaticCallTypes.put("long", "CallStaticLongMethod");
|
||||
sStaticCallTypes.put("double", "CallStaticDoubleMethod");
|
||||
sStaticCallTypes.put("float", "CallStaticFloatMethod");
|
||||
sStaticCallTypes.put("char", "CallStaticCharMethod");
|
||||
sStaticCallTypes.put("byte", "CallStaticByteMethod");
|
||||
sStaticCallTypes.put("short", "CallStaticShortMethod");
|
||||
}
|
||||
|
||||
private static final HashMap<String, String> sInstanceCallTypes = new HashMap<String, String>();
|
||||
|
||||
static {
|
||||
sInstanceCallTypes.put("void", "CallVoidMethod");
|
||||
sInstanceCallTypes.put("int", "CallIntMethod");
|
||||
sInstanceCallTypes.put("boolean", "CallBooleanMethod");
|
||||
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");
|
||||
sCanonicalSignatureParts.put("short", "S");
|
||||
}
|
||||
|
||||
|
||||
private static final HashMap<String, String> sDefaultParameterValues = new HashMap<String, String>();
|
||||
|
||||
static {
|
||||
sDefaultParameterValues.put("int", "0");
|
||||
sDefaultParameterValues.put("boolean", "false");
|
||||
sDefaultParameterValues.put("long", "0");
|
||||
sDefaultParameterValues.put("double", "0");
|
||||
sDefaultParameterValues.put("float", "0.0");
|
||||
sDefaultParameterValues.put("char", "0");
|
||||
sDefaultParameterValues.put("byte", "0");
|
||||
sDefaultParameterValues.put("short", "0");
|
||||
CLASS_DESCRIPTORS.put("void", "V");
|
||||
CLASS_DESCRIPTORS.put("boolean", "Z");
|
||||
CLASS_DESCRIPTORS.put("byte", "B");
|
||||
CLASS_DESCRIPTORS.put("char", "C");
|
||||
CLASS_DESCRIPTORS.put("short", "S");
|
||||
CLASS_DESCRIPTORS.put("int", "I");
|
||||
CLASS_DESCRIPTORS.put("long", "J");
|
||||
CLASS_DESCRIPTORS.put("float", "F");
|
||||
CLASS_DESCRIPTORS.put("double", "D");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the C type corresponding to the provided type parameter. Used for generating argument
|
||||
* types for the wrapper method.
|
||||
* Get the C++ type corresponding to the provided type parameter.
|
||||
*
|
||||
* @param type Class to determine the corresponding JNI type for.
|
||||
* @return true if the type an object type, false otherwise.
|
||||
* @return C++ type as a String
|
||||
*/
|
||||
public static String getCParameterType(Class<?> type, boolean aNarrowChars) {
|
||||
String name = type.getCanonicalName();
|
||||
if (sBasicCTypes.containsKey(name)) {
|
||||
return sBasicCTypes.get(name);
|
||||
}
|
||||
// Are we dealing with an array type?
|
||||
int len = name.length();
|
||||
if (name.endsWith("[]")) {
|
||||
// Determine if it is a 2D array - these map to jobjectArrays
|
||||
name = name.substring(0, len - 2);
|
||||
if (name.endsWith("[]")) {
|
||||
return "jobjectArray";
|
||||
} else {
|
||||
// Which flavour of Array is it?
|
||||
if (sArrayCTypes.containsKey(name)) {
|
||||
return sArrayCTypes.get(name);
|
||||
}
|
||||
return "jobjectArray";
|
||||
}
|
||||
}
|
||||
// Not an array type, check the remaining possibilities before we fall back to jobject
|
||||
public static String getNativeParameterType(Class<?> type, AnnotationInfo info) {
|
||||
final String name = type.getName().replace('.', '/');
|
||||
|
||||
// Check for CharSequences (Strings and things that are string-like)
|
||||
if (isCharSequence(type)) {
|
||||
if (aNarrowChars) {
|
||||
return "const nsACString&";
|
||||
}
|
||||
return "const nsAString&";
|
||||
if (NATIVE_TYPES.containsKey(name)) {
|
||||
return NATIVE_TYPES.get(name);
|
||||
}
|
||||
|
||||
if (name.equals("java.lang.Class")) {
|
||||
if (type.isArray()) {
|
||||
final String compName = type.getComponentType().getName();
|
||||
if (NATIVE_ARRAY_TYPES.containsKey(compName)) {
|
||||
return NATIVE_ARRAY_TYPES.get(compName) + "::Param";
|
||||
}
|
||||
return "mozilla::jni::ObjectArray::Param";
|
||||
}
|
||||
|
||||
if (type == String.class || type == CharSequence.class) {
|
||||
return "mozilla::jni::String::Param";
|
||||
}
|
||||
|
||||
if (type == Class.class) {
|
||||
// You're doing reflection on Java objects from inside C, returning Class objects
|
||||
// to C, generating the corresponding code using this Java program. Really?!
|
||||
return "jclass";
|
||||
return "mozilla::jni::ClassObject::Param";
|
||||
}
|
||||
if (name.equals("java.lang.Throwable")) {
|
||||
return "jthrowable";
|
||||
|
||||
if (type == Throwable.class) {
|
||||
return "mozilla::jni::Throwable::Param";
|
||||
}
|
||||
return "jobject";
|
||||
|
||||
return "mozilla::jni::Object::Param";
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, boolean aNarrowChars) {
|
||||
if (type.getCanonicalName().equals("java.lang.Void")) {
|
||||
return "void";
|
||||
}
|
||||
String cParameterType = getCParameterType(type, aNarrowChars);
|
||||
if (cParameterType.equals("const nsAString&") || cParameterType.equals("const nsACString&")) {
|
||||
return "jstring";
|
||||
} else {
|
||||
return cParameterType;
|
||||
}
|
||||
}
|
||||
public static String getNativeReturnType(Class<?> type, AnnotationInfo info) {
|
||||
final String name = type.getName().replace('.', '/');
|
||||
|
||||
/**
|
||||
* 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);
|
||||
if (NATIVE_TYPES.containsKey(name)) {
|
||||
return NATIVE_TYPES.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) {
|
||||
String name = aReturnType.getCanonicalName();
|
||||
if (isStatic) {
|
||||
if (sStaticCallTypes.containsKey(name)) {
|
||||
return sStaticCallTypes.get(name);
|
||||
if (type.isArray()) {
|
||||
final String compName = type.getComponentType().getName();
|
||||
if (NATIVE_ARRAY_TYPES.containsKey(compName)) {
|
||||
return NATIVE_ARRAY_TYPES.get(compName) + "::LocalRef";
|
||||
}
|
||||
return "CallStaticObjectMethod";
|
||||
} else {
|
||||
if (sInstanceCallTypes.containsKey(name)) {
|
||||
return sInstanceCallTypes.get(name);
|
||||
}
|
||||
return "CallObjectMethod";
|
||||
return "mozilla::jni::ObjectArray::LocalRef";
|
||||
}
|
||||
|
||||
if (type == String.class) {
|
||||
return "mozilla::jni::String::LocalRef";
|
||||
}
|
||||
|
||||
if (type == Class.class) {
|
||||
// You're doing reflection on Java objects from inside C, returning Class objects
|
||||
// to C, generating the corresponding code using this Java program. Really?!
|
||||
return "mozilla::jni::ClassObject::LocalRef";
|
||||
}
|
||||
|
||||
if (type == Throwable.class) {
|
||||
return "mozilla::jni::Throwable::LocalRef";
|
||||
}
|
||||
|
||||
return "mozilla::jni::Object::LocalRef";
|
||||
}
|
||||
|
||||
/**
|
||||
* On failure, the generated method returns a null-esque value. This helper method gets the
|
||||
* appropriate failure return value for a given Java return type, plus a leading space.
|
||||
* Get the JNI class descriptor corresponding to the provided type parameter.
|
||||
*
|
||||
* @param type Java return type of method being generated
|
||||
* @return String representation of the failure return value to be used in the generated code.
|
||||
* @param type Class to determine the corresponding JNI descriptor for.
|
||||
* @return Class descripor as a String
|
||||
*/
|
||||
public static String getFailureReturnForType(Class<?> type) {
|
||||
String name = type.getCanonicalName();
|
||||
if (sFailureReturns.containsKey(name)) {
|
||||
return sFailureReturns.get(name);
|
||||
public static String getClassDescriptor(Class<?> type) {
|
||||
final String name = type.getName().replace('.', '/');
|
||||
|
||||
if (CLASS_DESCRIPTORS.containsKey(name)) {
|
||||
return CLASS_DESCRIPTORS.get(name);
|
||||
}
|
||||
return " nullptr";
|
||||
|
||||
if (type.isArray()) {
|
||||
// Array names are already in class descriptor form.
|
||||
return name;
|
||||
}
|
||||
|
||||
return "L" + name + ';';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 JNI signaure for a member.
|
||||
*
|
||||
* @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 member Member to get the signature for.
|
||||
* @return JNI signature as a string
|
||||
*/
|
||||
private static String getTypeSignatureInternal(Class<?>[] arguments, Class<?> returnType) {
|
||||
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();
|
||||
public static String getSignature(Member member) {
|
||||
return member instanceof Field ? getSignature((Field) member) :
|
||||
member instanceof Method ? getSignature((Method) member) :
|
||||
getSignature((Constructor<?>) member);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the canonical JNI type signature for a Field.
|
||||
* Get the JNI signaure for a field.
|
||||
*
|
||||
* @param aField The field to generate a signature for.
|
||||
* @return The canonical JNI type signature for this method.
|
||||
* @param member Field to get the signature for.
|
||||
* @return JNI signature as a string
|
||||
*/
|
||||
protected static String getTypeSignatureStringForField(Field aField) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
writeTypeSignature(sb, aField.getType());
|
||||
return sb.toString();
|
||||
public static String getSignature(Field member) {
|
||||
return getClassDescriptor(member.getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 getTypeSignatureStringForClass(Class<?> clazz) {
|
||||
return clazz.getCanonicalName().replace('.', '/');
|
||||
}
|
||||
|
||||
public static String getTypeSignatureString(Constructor<?> aConstructor) {
|
||||
Class<?>[] arguments = aConstructor.getParameterTypes();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('(');
|
||||
|
||||
// For each argument, write its signature component to the buffer..
|
||||
for (int i = 0; i < arguments.length; i++) {
|
||||
writeTypeSignature(sb, arguments[i]);
|
||||
}
|
||||
|
||||
// Constructors always return Void.
|
||||
sb.append(")V");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method used by getTypeSignatureStringForMethod to build the signature. Write the subsignature
|
||||
* of a given type into the buffer.
|
||||
*
|
||||
* @param sb The buffer to write into.
|
||||
* @param c The type of the element to write the subsignature of.
|
||||
*/
|
||||
private static void writeTypeSignature(StringBuilder sb, Class<?> c) {
|
||||
String name = Utils.getTypeSignatureStringForClass(c);
|
||||
|
||||
// Determine if this is an array type and, if so, peel away the array operators..
|
||||
int len = name.length();
|
||||
while (name.endsWith("[]")) {
|
||||
sb.append('[');
|
||||
name = name.substring(0, len - 2);
|
||||
len = len - 2;
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
public static String getCImplementationMethodSignature(Class<?>[] aArgumentTypes, Class<?> aReturnType,
|
||||
String aCMethodName, String aCClassName, boolean aNarrowChars, boolean aCatchException) {
|
||||
StringBuilder retBuffer = new StringBuilder();
|
||||
|
||||
retBuffer.append(getCReturnType(aReturnType, aNarrowChars));
|
||||
retBuffer.append(' ');
|
||||
retBuffer.append(aCClassName);
|
||||
retBuffer.append("::");
|
||||
retBuffer.append(aCMethodName);
|
||||
retBuffer.append('(');
|
||||
|
||||
// Write argument types...
|
||||
for (int aT = 0; aT < aArgumentTypes.length; aT++) {
|
||||
retBuffer.append(getCParameterType(aArgumentTypes[aT], aNarrowChars));
|
||||
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) {
|
||||
retBuffer.append(", ");
|
||||
}
|
||||
}
|
||||
|
||||
if (aCatchException) {
|
||||
if (aArgumentTypes.length > 0) {
|
||||
retBuffer.append(", ");
|
||||
}
|
||||
retBuffer.append("nsresult* aResult");
|
||||
}
|
||||
|
||||
retBuffer.append(')');
|
||||
return retBuffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces a C method signature, sans semicolon, for the given Java Method. Useful for both
|
||||
* generating header files and method bodies.
|
||||
*
|
||||
* @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, boolean aNarrowChars, boolean aCatchException) {
|
||||
StringBuilder retBuffer = new StringBuilder();
|
||||
|
||||
// Add the static keyword, if applicable.
|
||||
if (aIsStaticStub) {
|
||||
retBuffer.append("static ");
|
||||
}
|
||||
|
||||
// Write return type..
|
||||
retBuffer.append(getCReturnType(aReturnType, aNarrowChars));
|
||||
retBuffer.append(' ');
|
||||
retBuffer.append(aCMethodName);
|
||||
retBuffer.append('(');
|
||||
|
||||
// Write argument types...
|
||||
for (int aT = 0; aT < aArgumentTypes.length; aT++) {
|
||||
retBuffer.append(getCParameterType(aArgumentTypes[aT], aNarrowChars));
|
||||
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]));
|
||||
|
||||
if (aT != aArgumentTypes.length - 1) {
|
||||
retBuffer.append(", ");
|
||||
}
|
||||
}
|
||||
|
||||
if (aCatchException) {
|
||||
if (aArgumentTypes.length > 0) {
|
||||
retBuffer.append(", ");
|
||||
}
|
||||
retBuffer.append("nsresult* aResult = nullptr");
|
||||
}
|
||||
|
||||
retBuffer.append(')');
|
||||
return retBuffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* If the given Annotation[] contains an OptionalGeneratedParameter annotation then return a
|
||||
* string assigning an argument of type aArgumentType to the default value for that type.
|
||||
* Otherwise, return the empty string.
|
||||
*
|
||||
* @param aArgumentType The type of the argument to consider.
|
||||
* @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")) {
|
||||
return " = " + getDefaultParameterValueForType(aArgumentType);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to return an appropriate default parameter value for an argument of a given type.
|
||||
* The lookup table contains values for primitive types and strings. All other object types default
|
||||
* to null pointers.
|
||||
*
|
||||
* @param aArgumentType The parameter type for which a default value is desired.
|
||||
* @return An appropriate string representation of the default value selected, for use in generated
|
||||
* C++ code.
|
||||
*/
|
||||
private static String getDefaultParameterValueForType(Class<?> aArgumentType) {
|
||||
String typeName = aArgumentType.getCanonicalName();
|
||||
if (sDefaultParameterValues.containsKey(typeName)) {
|
||||
return sDefaultParameterValues.get(typeName);
|
||||
} else if (isCharSequence(aArgumentType)) {
|
||||
return "EmptyString()";
|
||||
} else {
|
||||
return "nullptr";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that returns the number of reference types in the arguments of m.
|
||||
*
|
||||
* @param aArgs The method arguments to consider.
|
||||
* @return How many of the arguments of m are nonprimitive.
|
||||
*/
|
||||
public static int enumerateReferenceArguments(Class<?>[] aArgs) {
|
||||
int ret = 0;
|
||||
for (int i = 0; i < aArgs.length; i++) {
|
||||
String name = aArgs[i].getCanonicalName();
|
||||
if (!sBasicCTypes.containsKey(name)) {
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that returns true iff the given method has a string argument.
|
||||
*
|
||||
* @param m The method to consider.
|
||||
* @return True if the given method has a string argument, false otherwise.
|
||||
*/
|
||||
public static boolean hasStringArgument(Method m) {
|
||||
Class<?>[] args = m.getParameterTypes();
|
||||
private static String getSignature(Class<?>[] args, Class<?> ret) {
|
||||
final StringBuilder sig = new StringBuilder("(");
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (isCharSequence(args[i])) {
|
||||
return true;
|
||||
}
|
||||
sig.append(getClassDescriptor(args[i]));
|
||||
}
|
||||
return false;
|
||||
return sig.append(')').append(getClassDescriptor(ret)).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the argument array assignment line for the given argument type. Does not support array
|
||||
* types.
|
||||
* Get the JNI signaure for a method.
|
||||
*
|
||||
* @param type Type of this argument according to the target Java method's signature.
|
||||
* @param argName Wrapper function argument name corresponding to this argument.
|
||||
* @param member Method to get the signature for.
|
||||
* @return JNI signature as a string
|
||||
*/
|
||||
public static String getArrayArgumentMashallingLine(Class<?> type, String argName) {
|
||||
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");
|
||||
} else {
|
||||
sb.append("l = ").append(argName).append(";\n");
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
public static String getSignature(Method member) {
|
||||
return getSignature(member.getParameterTypes(), member.getReturnType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the type provided is an object type. Returns false otherwise
|
||||
* Get the JNI signaure for a constructor.
|
||||
*
|
||||
* @param aType The type to consider.
|
||||
* @return true if the method provided is an object type, false otherwise.
|
||||
* @param member Constructor to get the signature for.
|
||||
* @return JNI signature as a string
|
||||
*/
|
||||
public static boolean isObjectType(Class<?> aType) {
|
||||
return !sBasicCTypes.containsKey(aType.getCanonicalName());
|
||||
public static String getSignature(Constructor<?> member) {
|
||||
return getSignature(member.getParameterTypes(), void.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given Java class, get the name of the value in C++ which holds a reference to it.
|
||||
* Get the C++ name for a member.
|
||||
*
|
||||
* @param aClass Target Java class.
|
||||
* @return The name of the C++ jclass entity referencing the given class.
|
||||
* @param member Member to get the name for.
|
||||
* @return JNI name as a string
|
||||
*/
|
||||
public static String getClassReferenceName(Class<?> aClass) {
|
||||
String className = aClass.getSimpleName();
|
||||
return 'm' + className + "Class";
|
||||
public static String getNativeName(Member member) {
|
||||
final String name = getMemberName(member);
|
||||
return name.substring(0, 1).toUpperCase() + name.substring(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a line to get a global reference to the Java class given.
|
||||
* Get the JNI name for a member.
|
||||
*
|
||||
* @param aClass The target Java class.
|
||||
* @return The generated code to populate the reference to the class.
|
||||
* @param member Member to get the name for.
|
||||
* @return JNI name as a string
|
||||
*/
|
||||
public static String getStartupLineForClass(Class<?> aClass) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(" ");
|
||||
sb.append(getClassReferenceName(aClass));
|
||||
sb.append(" = AndroidBridge::GetClassGlobalRef(env, \"");
|
||||
|
||||
String name = Utils.getTypeSignatureStringForClass(aClass);
|
||||
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);
|
||||
public static String getMemberName(Member member) {
|
||||
if (member instanceof Constructor) {
|
||||
return "<init>";
|
||||
}
|
||||
|
||||
sb.append(name);
|
||||
sb.append("\");\n");
|
||||
return sb.toString();
|
||||
return member.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* Determine if a member is declared static.
|
||||
*
|
||||
* @param member The Member to check.
|
||||
* @return true if the member is declared static, false otherwise.
|
||||
*/
|
||||
public static boolean isCharSequence(Class<?> aClass) {
|
||||
if (aClass.getCanonicalName().equals("java.lang.CharSequence")) {
|
||||
return true;
|
||||
}
|
||||
Class<?>[] interfaces = aClass.getInterfaces();
|
||||
for (Class<?> c : interfaces) {
|
||||
if (c.getCanonicalName().equals("java.lang.CharSequence")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
public static boolean isStatic(final Member member) {
|
||||
return Modifier.isStatic(member.getModifiers());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* Determine if a member is declared final.
|
||||
*
|
||||
* @param member The Member to check.
|
||||
* @return true if the member is declared final, false otherwise.
|
||||
*/
|
||||
public static boolean isMemberStatic(Member aMember) {
|
||||
int aMethodModifiers = aMember.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);
|
||||
public static boolean isFinal(final Member member) {
|
||||
return Modifier.isFinal(member.getModifiers());
|
||||
}
|
||||
}
|
||||
|
@ -2493,7 +2493,7 @@ ContentParent::RecvGetShowPasswordSetting(bool* showPassword)
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
NS_ASSERTION(AndroidBridge::Bridge() != nullptr, "AndroidBridge is not available");
|
||||
|
||||
*showPassword = mozilla::widget::android::GeckoAppShell::GetShowPasswordSetting();
|
||||
*showPassword = mozilla::widget::GeckoAppShell::GetShowPasswordSetting();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
@ -24,25 +24,25 @@
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gl;
|
||||
using namespace mozilla::widget::android::sdk;
|
||||
using namespace mozilla::widget::sdk;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
static MediaCodec* CreateDecoder(JNIEnv* aEnv, const char* aMimeType)
|
||||
static MediaCodec::LocalRef CreateDecoder(const char* aMimeType)
|
||||
{
|
||||
if (!aMimeType) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
jobject decoder = MediaCodec::CreateDecoderByType(nsCString(aMimeType));
|
||||
|
||||
return new MediaCodec(decoder, aEnv);
|
||||
MediaCodec::LocalRef codec;
|
||||
NS_ENSURE_SUCCESS(MediaCodec::CreateDecoderByType(aMimeType, &codec), nullptr);
|
||||
return codec;
|
||||
}
|
||||
|
||||
class VideoDataDecoder : public MediaCodecDataDecoder {
|
||||
public:
|
||||
VideoDataDecoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
|
||||
MediaFormat* aFormat, MediaDataDecoderCallback* aCallback,
|
||||
MediaFormat::Param aFormat, MediaDataDecoderCallback* aCallback,
|
||||
layers::ImageContainer* aImageContainer)
|
||||
: MediaCodecDataDecoder(MediaData::Type::VIDEO_DATA, aConfig.mime_type, aFormat, aCallback)
|
||||
, mImageContainer(aImageContainer)
|
||||
@ -108,7 +108,7 @@ public:
|
||||
return eglImage;
|
||||
}
|
||||
|
||||
virtual nsresult PostOutput(BufferInfo* aInfo, MediaFormat* aFormat, Microseconds aDuration) MOZ_OVERRIDE {
|
||||
virtual nsresult PostOutput(BufferInfo::Param aInfo, MediaFormat::Param aFormat, Microseconds aDuration) MOZ_OVERRIDE {
|
||||
VideoInfo videoInfo;
|
||||
videoInfo.mDisplay = nsIntSize(mConfig.display_width, mConfig.display_height);
|
||||
|
||||
@ -143,13 +143,23 @@ public:
|
||||
layers::EGLImageImage* typedImg = static_cast<layers::EGLImageImage*>(img.get());
|
||||
typedImg->SetData(data);
|
||||
|
||||
bool isSync = !!(MediaCodec::getBUFFER_FLAG_SYNC_FRAME() & aInfo->getFlags());
|
||||
nsresult rv;
|
||||
int32_t flags;
|
||||
NS_ENSURE_SUCCESS(rv = aInfo->Flags(&flags), rv);
|
||||
|
||||
nsRefPtr<VideoData> v = VideoData::CreateFromImage(videoInfo, mImageContainer, aInfo->getOffset(),
|
||||
aInfo->getPresentationTimeUs(),
|
||||
bool isSync = !!(flags & MediaCodec::BUFFER_FLAG_SYNC_FRAME);
|
||||
|
||||
int32_t offset;
|
||||
NS_ENSURE_SUCCESS(rv = aInfo->Offset(&offset), rv);
|
||||
|
||||
int64_t presentationTimeUs;
|
||||
NS_ENSURE_SUCCESS(rv = aInfo->PresentationTimeUs(&presentationTimeUs), rv);
|
||||
|
||||
nsRefPtr<VideoData> v = VideoData::CreateFromImage(videoInfo, mImageContainer, offset,
|
||||
presentationTimeUs,
|
||||
aDuration,
|
||||
img, isSync,
|
||||
aInfo->getPresentationTimeUs(),
|
||||
presentationTimeUs,
|
||||
gfx::IntRect(0, 0,
|
||||
mConfig.display_width,
|
||||
mConfig.display_height));
|
||||
@ -174,23 +184,53 @@ protected:
|
||||
};
|
||||
|
||||
class AudioDataDecoder : public MediaCodecDataDecoder {
|
||||
private:
|
||||
uint8_t csd0[2];
|
||||
|
||||
public:
|
||||
AudioDataDecoder(const char* aMimeType, MediaFormat* aFormat, MediaDataDecoderCallback* aCallback)
|
||||
: MediaCodecDataDecoder(MediaData::Type::AUDIO_DATA, aMimeType, aFormat, aCallback)
|
||||
AudioDataDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig, MediaFormat::Param aFormat, MediaDataDecoderCallback* aCallback)
|
||||
: MediaCodecDataDecoder(MediaData::Type::AUDIO_DATA, aConfig.mime_type, aFormat, aCallback)
|
||||
{
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
|
||||
jni::Object::LocalRef buffer(env);
|
||||
NS_ENSURE_SUCCESS_VOID(aFormat->GetByteBuffer(NS_LITERAL_STRING("csd-0"), &buffer));
|
||||
|
||||
if (!buffer) {
|
||||
csd0[0] = (*aConfig.audio_specific_config)[0];
|
||||
csd0[1] = (*aConfig.audio_specific_config)[1];
|
||||
|
||||
buffer = jni::Object::LocalRef::Adopt(env, env->NewDirectByteBuffer(csd0, 2));
|
||||
NS_ENSURE_SUCCESS_VOID(aFormat->SetByteBuffer(NS_LITERAL_STRING("csd-0"), buffer));
|
||||
}
|
||||
}
|
||||
|
||||
nsresult Output(BufferInfo* aInfo, void* aBuffer, MediaFormat* aFormat, Microseconds aDuration) {
|
||||
nsresult Output(BufferInfo::Param aInfo, void* aBuffer, MediaFormat::Param aFormat, Microseconds aDuration) {
|
||||
// The output on Android is always 16-bit signed
|
||||
|
||||
uint32_t numChannels = aFormat->GetInteger(NS_LITERAL_CSTRING("channel-count"));
|
||||
uint32_t sampleRate = aFormat->GetInteger(NS_LITERAL_CSTRING("sample-rate"));
|
||||
uint32_t numFrames = (aInfo->getSize() / numChannels) / 2;
|
||||
nsresult rv;
|
||||
int32_t numChannels;
|
||||
NS_ENSURE_SUCCESS(rv =
|
||||
aFormat->GetInteger(NS_LITERAL_STRING("channel-count"), &numChannels), rv);
|
||||
|
||||
AudioDataValue* audio = new AudioDataValue[aInfo->getSize()];
|
||||
PodCopy(audio, static_cast<AudioDataValue*>(aBuffer), aInfo->getSize());
|
||||
int32_t sampleRate;
|
||||
NS_ENSURE_SUCCESS(rv =
|
||||
aFormat->GetInteger(NS_LITERAL_STRING("sample-rate"), &sampleRate), rv);
|
||||
|
||||
nsRefPtr<AudioData> data = new AudioData(aInfo->getOffset(), aInfo->getPresentationTimeUs(),
|
||||
int32_t size;
|
||||
NS_ENSURE_SUCCESS(rv = aInfo->Size(&size), rv);
|
||||
|
||||
const int32_t numFrames = (size / numChannels) / 2;
|
||||
AudioDataValue* audio = new AudioDataValue[size];
|
||||
PodCopy(audio, static_cast<AudioDataValue*>(aBuffer), size);
|
||||
|
||||
int32_t offset;
|
||||
NS_ENSURE_SUCCESS(rv = aInfo->Offset(&offset), rv);
|
||||
|
||||
int64_t presentationTimeUs;
|
||||
NS_ENSURE_SUCCESS(rv = aInfo->PresentationTimeUs(&presentationTimeUs), rv);
|
||||
|
||||
nsRefPtr<AudioData> data = new AudioData(offset, presentationTimeUs,
|
||||
aDuration,
|
||||
numFrames,
|
||||
audio,
|
||||
@ -203,11 +243,7 @@ public:
|
||||
|
||||
|
||||
bool AndroidDecoderModule::SupportsAudioMimeType(const char* aMimeType) {
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
MediaCodec* decoder = CreateDecoder(env, aMimeType);
|
||||
bool supports = (decoder != nullptr);
|
||||
delete decoder;
|
||||
return supports;
|
||||
return static_cast<bool>(CreateDecoder(aMimeType));
|
||||
}
|
||||
|
||||
already_AddRefed<MediaDataDecoder>
|
||||
@ -218,19 +254,13 @@ AndroidDecoderModule::CreateVideoDecoder(
|
||||
MediaTaskQueue* aVideoTaskQueue,
|
||||
MediaDataDecoderCallback* aCallback)
|
||||
{
|
||||
jobject jFormat = MediaFormat::CreateVideoFormat(nsCString(aConfig.mime_type),
|
||||
aConfig.display_width,
|
||||
aConfig.display_height);
|
||||
MediaFormat::LocalRef format;
|
||||
|
||||
if (!jFormat) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MediaFormat* format = MediaFormat::Wrap(jFormat);
|
||||
|
||||
if (!format) {
|
||||
return nullptr;
|
||||
}
|
||||
NS_ENSURE_SUCCESS(MediaFormat::CreateVideoFormat(
|
||||
aConfig.mime_type,
|
||||
aConfig.display_width,
|
||||
aConfig.display_height,
|
||||
&format), nullptr);
|
||||
|
||||
nsRefPtr<MediaDataDecoder> decoder =
|
||||
new VideoDataDecoder(aConfig, format, aCallback, aImageContainer);
|
||||
@ -245,34 +275,16 @@ AndroidDecoderModule::CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig&
|
||||
{
|
||||
MOZ_ASSERT(aConfig.bits_per_sample == 16, "We only handle 16-bit audio!");
|
||||
|
||||
jobject jFormat = MediaFormat::CreateAudioFormat(nsCString(aConfig.mime_type),
|
||||
aConfig.samples_per_second,
|
||||
aConfig.channel_count);
|
||||
MediaFormat::LocalRef format;
|
||||
|
||||
if (jFormat == nullptr)
|
||||
return nullptr;
|
||||
|
||||
MediaFormat* format = MediaFormat::Wrap(jFormat);
|
||||
|
||||
if(format == nullptr)
|
||||
return nullptr;
|
||||
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
|
||||
if (!format->GetByteBuffer(NS_LITERAL_CSTRING("csd-0"))) {
|
||||
uint8_t* csd0 = new uint8_t[2];
|
||||
|
||||
csd0[0] = (*aConfig.audio_specific_config)[0];
|
||||
csd0[1] = (*aConfig.audio_specific_config)[1];
|
||||
|
||||
jobject buffer = env->NewDirectByteBuffer(csd0, 2);
|
||||
format->SetByteBuffer(NS_LITERAL_CSTRING("csd-0"), buffer);
|
||||
|
||||
env->DeleteLocalRef(buffer);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(MediaFormat::CreateAudioFormat(
|
||||
aConfig.mime_type,
|
||||
aConfig.samples_per_second,
|
||||
aConfig.channel_count,
|
||||
&format), nullptr);
|
||||
|
||||
nsRefPtr<MediaDataDecoder> decoder =
|
||||
new AudioDataDecoder(aConfig.mime_type, format, aCallback);
|
||||
new AudioDataDecoder(aConfig, format, aCallback);
|
||||
|
||||
return decoder.forget();
|
||||
|
||||
@ -286,7 +298,7 @@ nsresult AndroidDecoderModule::Shutdown()
|
||||
|
||||
MediaCodecDataDecoder::MediaCodecDataDecoder(MediaData::Type aType,
|
||||
const char* aMimeType,
|
||||
MediaFormat* aFormat,
|
||||
MediaFormat::Param aFormat,
|
||||
MediaDataDecoderCallback* aCallback)
|
||||
: mType(aType)
|
||||
, mMimeType(strdup(aMimeType))
|
||||
@ -304,55 +316,28 @@ MediaCodecDataDecoder::MediaCodecDataDecoder(MediaData::Type aType,
|
||||
|
||||
MediaCodecDataDecoder::~MediaCodecDataDecoder()
|
||||
{
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
|
||||
Shutdown();
|
||||
|
||||
if (mInputBuffers) {
|
||||
env->DeleteGlobalRef(mInputBuffers);
|
||||
mInputBuffers = nullptr;
|
||||
}
|
||||
|
||||
if (mOutputBuffers) {
|
||||
env->DeleteGlobalRef(mOutputBuffers);
|
||||
mOutputBuffers = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult MediaCodecDataDecoder::Init()
|
||||
{
|
||||
return InitDecoder();
|
||||
return InitDecoder(nullptr);
|
||||
}
|
||||
|
||||
nsresult MediaCodecDataDecoder::InitDecoder(jobject aSurface)
|
||||
nsresult MediaCodecDataDecoder::InitDecoder(Surface::Param aSurface)
|
||||
{
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
mDecoder = CreateDecoder(env, mMimeType);
|
||||
mDecoder = CreateDecoder(mMimeType);
|
||||
if (!mDecoder) {
|
||||
mCallback->Error();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult res;
|
||||
mDecoder->Configure(mFormat->wrappedObject(), aSurface, nullptr, 0, &res);
|
||||
if (NS_FAILED(res)) {
|
||||
return res;
|
||||
}
|
||||
nsresult rv;
|
||||
NS_ENSURE_SUCCESS(rv = mDecoder->Configure(mFormat, aSurface, nullptr, 0), rv);
|
||||
NS_ENSURE_SUCCESS(rv = mDecoder->Start(), rv);
|
||||
|
||||
mDecoder->Start(&res);
|
||||
if (NS_FAILED(res)) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = ResetInputBuffers();
|
||||
if (NS_FAILED(res)) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = ResetOutputBuffers();
|
||||
if (NS_FAILED(res)) {
|
||||
return res;
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv = ResetInputBuffers(), rv);
|
||||
NS_ENSURE_SUCCESS(rv = ResetOutputBuffers(), rv);
|
||||
|
||||
NS_NewNamedThread("MC Decoder", getter_AddRefs(mThread),
|
||||
NS_NewRunnableMethod(this, &MediaCodecDataDecoder::DecoderLoop));
|
||||
@ -377,10 +362,10 @@ void MediaCodecDataDecoder::DecoderLoop()
|
||||
bool draining = false;
|
||||
bool waitingEOF = false;
|
||||
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
AutoLocalJNIFrame frame(GetJNIForThread(), 1);
|
||||
mp4_demuxer::MP4Sample* sample = nullptr;
|
||||
|
||||
nsAutoPtr<MediaFormat> outputFormat;
|
||||
MediaFormat::LocalRef outputFormat(frame.GetEnv());
|
||||
nsresult res;
|
||||
|
||||
for (;;) {
|
||||
@ -420,61 +405,69 @@ void MediaCodecDataDecoder::DecoderLoop()
|
||||
if (draining && !waitingEOF) {
|
||||
MOZ_ASSERT(!sample, "Shouldn't have a sample when pushing EOF frame");
|
||||
|
||||
int inputIndex = mDecoder->DequeueInputBuffer(DECODER_TIMEOUT, &res);
|
||||
int32_t inputIndex;
|
||||
res = mDecoder->DequeueInputBuffer(DECODER_TIMEOUT, &inputIndex);
|
||||
HANDLE_DECODER_ERROR();
|
||||
|
||||
if (inputIndex >= 0) {
|
||||
mDecoder->QueueInputBuffer(inputIndex, 0, 0, 0, MediaCodec::getBUFFER_FLAG_END_OF_STREAM(), &res);
|
||||
res = mDecoder->QueueInputBuffer(inputIndex, 0, 0, 0, MediaCodec::BUFFER_FLAG_END_OF_STREAM);
|
||||
HANDLE_DECODER_ERROR();
|
||||
|
||||
waitingEOF = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (sample) {
|
||||
// We have a sample, try to feed it to the decoder
|
||||
int inputIndex = mDecoder->DequeueInputBuffer(DECODER_TIMEOUT, &res);
|
||||
int inputIndex;
|
||||
res = mDecoder->DequeueInputBuffer(DECODER_TIMEOUT, &inputIndex);
|
||||
HANDLE_DECODER_ERROR();
|
||||
|
||||
if (inputIndex >= 0) {
|
||||
jobject buffer = env->GetObjectArrayElement(mInputBuffers, inputIndex);
|
||||
void* directBuffer = env->GetDirectBufferAddress(buffer);
|
||||
auto buffer = jni::Object::LocalRef::Adopt(
|
||||
frame.GetEnv()->GetObjectArrayElement(mInputBuffers.Get(), inputIndex));
|
||||
void* directBuffer = frame.GetEnv()->GetDirectBufferAddress(buffer.Get());
|
||||
|
||||
// We're feeding this to the decoder, so remove it from the queue
|
||||
mMonitor.Lock();
|
||||
mQueue.pop();
|
||||
mMonitor.Unlock();
|
||||
|
||||
MOZ_ASSERT(env->GetDirectBufferCapacity(buffer) >= sample->size,
|
||||
MOZ_ASSERT(frame.GetEnv()->GetDirectBufferCapacity(buffer.Get()) >= sample->size,
|
||||
"Decoder buffer is not large enough for sample");
|
||||
|
||||
{
|
||||
// We're feeding this to the decoder, so remove it from the queue
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
mQueue.pop();
|
||||
}
|
||||
|
||||
PodCopy((uint8_t*)directBuffer, sample->data, sample->size);
|
||||
|
||||
mDecoder->QueueInputBuffer(inputIndex, 0, sample->size, sample->composition_timestamp, 0, &res);
|
||||
res = mDecoder->QueueInputBuffer(inputIndex, 0, sample->size,
|
||||
sample->composition_timestamp, 0);
|
||||
HANDLE_DECODER_ERROR();
|
||||
|
||||
mDurations.push(sample->duration);
|
||||
|
||||
delete sample;
|
||||
sample = nullptr;
|
||||
|
||||
outputDone = false;
|
||||
env->DeleteLocalRef(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (!outputDone) {
|
||||
BufferInfo bufferInfo;
|
||||
|
||||
int outputStatus = mDecoder->DequeueOutputBuffer(bufferInfo.wrappedObject(), DECODER_TIMEOUT, &res);
|
||||
BufferInfo::LocalRef bufferInfo;
|
||||
res = BufferInfo::New(&bufferInfo);
|
||||
HANDLE_DECODER_ERROR();
|
||||
|
||||
if (outputStatus == MediaCodec::getINFO_TRY_AGAIN_LATER()) {
|
||||
int32_t outputStatus;
|
||||
res = mDecoder->DequeueOutputBuffer(bufferInfo, DECODER_TIMEOUT, &outputStatus);
|
||||
HANDLE_DECODER_ERROR();
|
||||
|
||||
if (outputStatus == MediaCodec::INFO_TRY_AGAIN_LATER) {
|
||||
// We might want to call mCallback->InputExhausted() here, but there seems to be
|
||||
// some possible bad interactions here with the threading
|
||||
} else if (outputStatus == MediaCodec::getINFO_OUTPUT_BUFFERS_CHANGED()) {
|
||||
} else if (outputStatus == MediaCodec::INFO_OUTPUT_BUFFERS_CHANGED) {
|
||||
res = ResetOutputBuffers();
|
||||
HANDLE_DECODER_ERROR();
|
||||
} else if (outputStatus == MediaCodec::getINFO_OUTPUT_FORMAT_CHANGED()) {
|
||||
outputFormat = new MediaFormat(mDecoder->GetOutputFormat(), GetJNIForThread());
|
||||
} else if (outputStatus == MediaCodec::INFO_OUTPUT_FORMAT_CHANGED) {
|
||||
res = mDecoder->GetOutputFormat(ReturnTo(&outputFormat));
|
||||
HANDLE_DECODER_ERROR();
|
||||
} else if (outputStatus < 0) {
|
||||
NS_WARNING("unknown error from decoder!");
|
||||
mCallback->Error();
|
||||
@ -482,8 +475,12 @@ void MediaCodecDataDecoder::DecoderLoop()
|
||||
// Don't break here just in case it's recoverable. If it's not, others stuff will fail later and
|
||||
// we'll bail out.
|
||||
} else {
|
||||
int32_t flags;
|
||||
res = bufferInfo->Flags(&flags);
|
||||
HANDLE_DECODER_ERROR();
|
||||
|
||||
// We have a valid buffer index >= 0 here
|
||||
if (bufferInfo.getFlags() & MediaCodec::getBUFFER_FLAG_END_OF_STREAM()) {
|
||||
if (flags & MediaCodec::BUFFER_FLAG_END_OF_STREAM) {
|
||||
if (draining) {
|
||||
draining = false;
|
||||
waitingEOF = false;
|
||||
@ -511,21 +508,18 @@ void MediaCodecDataDecoder::DecoderLoop()
|
||||
mDurations.pop();
|
||||
}
|
||||
|
||||
jobject buffer = env->GetObjectArrayElement(mOutputBuffers, outputStatus);
|
||||
auto buffer = jni::Object::LocalRef::Adopt(
|
||||
frame.GetEnv()->GetObjectArrayElement(mOutputBuffers.Get(), outputStatus));
|
||||
if (buffer) {
|
||||
// The buffer will be null on Android L if we are decoding to a Surface
|
||||
void* directBuffer = env->GetDirectBufferAddress(buffer);
|
||||
Output(&bufferInfo, directBuffer, outputFormat, duration);
|
||||
void* directBuffer = frame.GetEnv()->GetDirectBufferAddress(buffer.Get());
|
||||
Output(bufferInfo, directBuffer, outputFormat, duration);
|
||||
}
|
||||
|
||||
// The Surface will be updated at this point (for video)
|
||||
mDecoder->ReleaseOutputBuffer(outputStatus, true);
|
||||
|
||||
PostOutput(&bufferInfo, outputFormat, duration);
|
||||
|
||||
if (buffer) {
|
||||
env->DeleteLocalRef(buffer);
|
||||
}
|
||||
PostOutput(bufferInfo, outputFormat, duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -533,10 +527,9 @@ void MediaCodecDataDecoder::DecoderLoop()
|
||||
Cleanup();
|
||||
|
||||
// We're done
|
||||
mMonitor.Lock();
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
mStopping = false;
|
||||
mMonitor.Notify();
|
||||
mMonitor.Unlock();
|
||||
}
|
||||
|
||||
void MediaCodecDataDecoder::ClearQueue()
|
||||
@ -561,36 +554,12 @@ nsresult MediaCodecDataDecoder::Input(mp4_demuxer::MP4Sample* aSample) {
|
||||
|
||||
nsresult MediaCodecDataDecoder::ResetInputBuffers()
|
||||
{
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
|
||||
if (mInputBuffers) {
|
||||
env->DeleteGlobalRef(mInputBuffers);
|
||||
}
|
||||
|
||||
nsresult res;
|
||||
mInputBuffers = (jobjectArray) env->NewGlobalRef(mDecoder->GetInputBuffers(&res));
|
||||
if (NS_FAILED(res)) {
|
||||
return res;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return mDecoder->GetInputBuffers(ReturnTo(&mInputBuffers));
|
||||
}
|
||||
|
||||
nsresult MediaCodecDataDecoder::ResetOutputBuffers()
|
||||
{
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
|
||||
if (mOutputBuffers) {
|
||||
env->DeleteGlobalRef(mOutputBuffers);
|
||||
}
|
||||
|
||||
nsresult res;
|
||||
mOutputBuffers = (jobjectArray) env->NewGlobalRef(mDecoder->GetOutputBuffers(&res));
|
||||
if (NS_FAILED(res)) {
|
||||
return res;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return mDecoder->GetOutputBuffers(ReturnTo(&mOutputBuffers));
|
||||
}
|
||||
|
||||
nsresult MediaCodecDataDecoder::Flush() {
|
||||
|
@ -17,18 +17,6 @@ namespace mozilla {
|
||||
|
||||
typedef std::queue<mp4_demuxer::MP4Sample*> SampleQueue;
|
||||
|
||||
namespace widget {
|
||||
namespace android {
|
||||
namespace sdk {
|
||||
class MediaCodec;
|
||||
class MediaFormat;
|
||||
class ByteBuffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MediaCodecDataDecoder;
|
||||
|
||||
class AndroidDecoderModule : public PlatformDecoderModule {
|
||||
public:
|
||||
virtual nsresult Shutdown() MOZ_OVERRIDE;
|
||||
@ -57,7 +45,7 @@ public:
|
||||
|
||||
MediaCodecDataDecoder(MediaData::Type aType,
|
||||
const char* aMimeType,
|
||||
mozilla::widget::android::sdk::MediaFormat* aFormat,
|
||||
widget::sdk::MediaFormat::Param aFormat,
|
||||
MediaDataDecoderCallback* aCallback);
|
||||
|
||||
virtual ~MediaCodecDataDecoder();
|
||||
@ -74,14 +62,14 @@ protected:
|
||||
MediaData::Type mType;
|
||||
|
||||
nsAutoPtr<char> mMimeType;
|
||||
nsAutoPtr<mozilla::widget::android::sdk::MediaFormat> mFormat;
|
||||
widget::sdk::MediaFormat::GlobalRef mFormat;
|
||||
|
||||
MediaDataDecoderCallback* mCallback;
|
||||
|
||||
nsAutoPtr<mozilla::widget::android::sdk::MediaCodec> mDecoder;
|
||||
widget::sdk::MediaCodec::GlobalRef mDecoder;
|
||||
|
||||
jobjectArray mInputBuffers;
|
||||
jobjectArray mOutputBuffers;
|
||||
jni::ObjectArray::GlobalRef mInputBuffers;
|
||||
jni::ObjectArray::GlobalRef mOutputBuffers;
|
||||
|
||||
nsCOMPtr<nsIThread> mThread;
|
||||
|
||||
@ -94,10 +82,10 @@ protected:
|
||||
SampleQueue mQueue;
|
||||
std::queue<Microseconds> mDurations;
|
||||
|
||||
virtual nsresult InitDecoder(jobject aSurface = nullptr);
|
||||
virtual nsresult InitDecoder(widget::sdk::Surface::Param aSurface);
|
||||
|
||||
virtual nsresult Output(mozilla::widget::android::sdk::BufferInfo* aInfo, void* aBuffer, mozilla::widget::android::sdk::MediaFormat* aFormat, Microseconds aDuration) { return NS_OK; }
|
||||
virtual nsresult PostOutput(mozilla::widget::android::sdk::BufferInfo* aInfo, mozilla::widget::android::sdk::MediaFormat* aFormat, Microseconds aDuration) { return NS_OK; }
|
||||
virtual nsresult Output(widget::sdk::BufferInfo::Param aInfo, void* aBuffer, widget::sdk::MediaFormat::Param aFormat, Microseconds aDuration) { return NS_OK; }
|
||||
virtual nsresult PostOutput(widget::sdk::BufferInfo::Param aInfo, widget::sdk::MediaFormat::Param aFormat, Microseconds aDuration) { return NS_OK; }
|
||||
virtual void Cleanup() {};
|
||||
|
||||
nsresult ResetInputBuffers();
|
||||
|
@ -50,20 +50,17 @@ anp_system_getApplicationDataDirectory()
|
||||
return anp_system_getApplicationDataDirectory(nullptr);
|
||||
}
|
||||
|
||||
jclass anp_system_loadJavaClass(NPP instance, const char* classNameStr)
|
||||
jclass anp_system_loadJavaClass(NPP instance, const char* className)
|
||||
{
|
||||
LOG("%s", __PRETTY_FUNCTION__);
|
||||
|
||||
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
||||
mozilla::PluginPRLibrary* lib = static_cast<mozilla::PluginPRLibrary*>(pinst->GetPlugin()->GetLibrary());
|
||||
|
||||
NS_ConvertUTF8toUTF16 className(classNameStr);
|
||||
nsCString libName;
|
||||
lib->GetLibraryPath(libName);
|
||||
|
||||
nsCString libNameUtf8;
|
||||
lib->GetLibraryPath(libNameUtf8);
|
||||
NS_ConvertUTF8toUTF16 libName(libNameUtf8);
|
||||
|
||||
return mozilla::widget::android::GeckoAppShell::LoadPluginClass(className, libName);
|
||||
return mozilla::widget::GeckoAppShell::LoadPluginClass(className, libName).Forget();
|
||||
}
|
||||
|
||||
void anp_system_setPowerState(NPP instance, ANPPowerState powerState)
|
||||
|
@ -2269,12 +2269,11 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
|
||||
}
|
||||
|
||||
case kJavaContext_ANPGetValue: {
|
||||
jobject ret = mozilla::widget::android::GeckoAppShell::GetContext();
|
||||
auto ret = widget::GeckoAppShell::GetContext();
|
||||
if (!ret)
|
||||
return NPERR_GENERIC_ERROR;
|
||||
|
||||
int32_t* i = reinterpret_cast<int32_t*>(result);
|
||||
*i = reinterpret_cast<int32_t>(ret);
|
||||
*static_cast<jobject*>(result) = ret.Forget();
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
@ -849,7 +849,7 @@ void nsNPAPIPluginInstance::NotifyFullScreen(bool aFullScreen)
|
||||
SendLifecycleEvent(this, mFullScreen ? kEnterFullScreen_ANPLifecycleAction : kExitFullScreen_ANPLifecycleAction);
|
||||
|
||||
if (mFullScreen && mFullScreenOrientation != dom::eScreenOrientation_None) {
|
||||
mozilla::widget::android::GeckoAppShell::LockScreenOrientation(mFullScreenOrientation);
|
||||
widget::GeckoAppShell::LockScreenOrientation(mFullScreenOrientation);
|
||||
}
|
||||
}
|
||||
|
||||
@ -906,11 +906,11 @@ void nsNPAPIPluginInstance::SetFullScreenOrientation(uint32_t orientation)
|
||||
// We're already fullscreen so immediately apply the orientation change
|
||||
|
||||
if (mFullScreenOrientation != dom::eScreenOrientation_None) {
|
||||
mozilla::widget::android::GeckoAppShell::LockScreenOrientation(mFullScreenOrientation);
|
||||
widget::GeckoAppShell::LockScreenOrientation(mFullScreenOrientation);
|
||||
} else if (oldOrientation != dom::eScreenOrientation_None) {
|
||||
// We applied an orientation when we entered fullscreen, but
|
||||
// we don't want it anymore
|
||||
mozilla::widget::android::GeckoAppShell::UnlockScreenOrientation();
|
||||
widget::GeckoAppShell::UnlockScreenOrientation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1356,7 +1356,8 @@ void nsPluginInstanceOwner::RemovePluginView()
|
||||
if (!mInstance || !mJavaView)
|
||||
return;
|
||||
|
||||
mozilla::widget::android::GeckoAppShell::RemovePluginView((jobject)mJavaView, mFullScreen);
|
||||
widget::GeckoAppShell::RemovePluginView(
|
||||
jni::Object::Ref::From(jobject(mJavaView)), mFullScreen);
|
||||
AndroidBridge::GetJNIEnv()->DeleteGlobalRef((jobject)mJavaView);
|
||||
mJavaView = nullptr;
|
||||
|
||||
|
@ -26,7 +26,7 @@ AndroidLocationProvider::~AndroidLocationProvider()
|
||||
NS_IMETHODIMP
|
||||
AndroidLocationProvider::Startup()
|
||||
{
|
||||
mozilla::widget::android::GeckoAppShell::EnableLocation(true);
|
||||
widget::GeckoAppShell::EnableLocation(true);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -42,13 +42,13 @@ AndroidLocationProvider::Watch(nsIGeolocationUpdate* aCallback)
|
||||
NS_IMETHODIMP
|
||||
AndroidLocationProvider::Shutdown()
|
||||
{
|
||||
mozilla::widget::android::GeckoAppShell::EnableLocation(false);
|
||||
widget::GeckoAppShell::EnableLocation(false);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
AndroidLocationProvider::SetHighAccuracy(bool enable)
|
||||
{
|
||||
mozilla::widget::android::GeckoAppShell::EnableLocationHighAccuracy(enable);
|
||||
widget::GeckoAppShell::EnableLocationHighAccuracy(enable);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -14,6 +14,6 @@ NS_IMPL_ISUPPORTS(nsHapticFeedback, nsIHapticFeedback)
|
||||
NS_IMETHODIMP
|
||||
nsHapticFeedback::PerformSimpleAction(int32_t aType)
|
||||
{
|
||||
mozilla::widget::android::GeckoAppShell::PerformHapticFeedback(aType == LongPress);
|
||||
widget::GeckoAppShell::PerformHapticFeedback(aType == LongPress);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -19,8 +19,9 @@
|
||||
#include "GLContext.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::widget::android;
|
||||
using namespace mozilla::widget::android::sdk;
|
||||
using namespace mozilla::jni;
|
||||
using namespace mozilla::widget;
|
||||
using namespace mozilla::widget::sdk;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
@ -103,9 +104,7 @@ AndroidSurfaceTexture::Attach(GLContext* aContext, PRIntervalTime aTimeout)
|
||||
mAttachedContext->MakeCurrent();
|
||||
aContext->fGenTextures(1, &mTexture);
|
||||
|
||||
nsresult res;
|
||||
mSurfaceTexture->AttachToGLContext(mTexture, &res);
|
||||
return res;
|
||||
return mSurfaceTexture->AttachToGLContext(mTexture);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -136,9 +135,8 @@ AndroidSurfaceTexture::Init(GLContext* aContext, GLuint aTexture)
|
||||
return false;
|
||||
}
|
||||
|
||||
nsresult res;
|
||||
mSurfaceTexture = new SurfaceTexture(aTexture, &res);
|
||||
if (NS_FAILED(res)) {
|
||||
if (NS_WARN_IF(NS_FAILED(
|
||||
SurfaceTexture::New(aTexture, ReturnTo(&mSurfaceTexture))))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -148,13 +146,13 @@ AndroidSurfaceTexture::Init(GLContext* aContext, GLuint aTexture)
|
||||
|
||||
mAttachedContext = aContext;
|
||||
|
||||
mSurface = new Surface(mSurfaceTexture->wrappedObject(), &res);
|
||||
if (NS_FAILED(res)) {
|
||||
if (NS_WARN_IF(NS_FAILED(
|
||||
Surface::New(mSurfaceTexture, ReturnTo(&mSurface))))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mNativeWindow = AndroidNativeWindow::CreateFromSurface(GetJNIForThread(),
|
||||
mSurface->wrappedObject());
|
||||
mSurface.Get());
|
||||
MOZ_ASSERT(mNativeWindow, "Failed to create native window from surface");
|
||||
|
||||
mID = ++sNextID;
|
||||
@ -165,8 +163,8 @@ AndroidSurfaceTexture::Init(GLContext* aContext, GLuint aTexture)
|
||||
|
||||
AndroidSurfaceTexture::AndroidSurfaceTexture()
|
||||
: mTexture(0)
|
||||
, mSurfaceTexture(nullptr)
|
||||
, mSurface(nullptr)
|
||||
, mSurfaceTexture()
|
||||
, mSurface()
|
||||
, mMonitor("AndroidSurfaceTexture::mContextMonitor")
|
||||
, mAttachedContext(nullptr)
|
||||
{
|
||||
@ -179,7 +177,7 @@ AndroidSurfaceTexture::~AndroidSurfaceTexture()
|
||||
mFrameAvailableCallback = nullptr;
|
||||
|
||||
if (mSurfaceTexture) {
|
||||
GeckoAppShell::UnregisterSurfaceTextureFrameListener(mSurfaceTexture->wrappedObject());
|
||||
GeckoAppShell::UnregisterSurfaceTextureFrameListener(mSurfaceTexture);
|
||||
mSurfaceTexture = nullptr;
|
||||
}
|
||||
}
|
||||
@ -195,12 +193,10 @@ AndroidSurfaceTexture::GetTransformMatrix(gfx::Matrix4x4& aMatrix)
|
||||
{
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env);
|
||||
|
||||
jfloatArray jarray = env->NewFloatArray(16);
|
||||
auto jarray = FloatArray::LocalRef::Adopt(env, env->NewFloatArray(16));
|
||||
mSurfaceTexture->GetTransformMatrix(jarray);
|
||||
|
||||
jfloat* array = env->GetFloatArrayElements(jarray, nullptr);
|
||||
jfloat* array = env->GetFloatArrayElements(jarray.Get(), nullptr);
|
||||
|
||||
aMatrix._11 = array[0];
|
||||
aMatrix._12 = array[1];
|
||||
@ -222,16 +218,16 @@ AndroidSurfaceTexture::GetTransformMatrix(gfx::Matrix4x4& aMatrix)
|
||||
aMatrix._43 = array[14];
|
||||
aMatrix._44 = array[15];
|
||||
|
||||
env->ReleaseFloatArrayElements(jarray, array, 0);
|
||||
env->ReleaseFloatArrayElements(jarray.Get(), array, 0);
|
||||
}
|
||||
|
||||
void
|
||||
AndroidSurfaceTexture::SetFrameAvailableCallback(nsIRunnable* aRunnable)
|
||||
{
|
||||
if (aRunnable) {
|
||||
GeckoAppShell::RegisterSurfaceTextureFrameListener(mSurfaceTexture->wrappedObject(), mID);
|
||||
GeckoAppShell::RegisterSurfaceTextureFrameListener(mSurfaceTexture, mID);
|
||||
} else {
|
||||
GeckoAppShell::UnregisterSurfaceTextureFrameListener(mSurfaceTexture->wrappedObject());
|
||||
GeckoAppShell::UnregisterSurfaceTextureFrameListener(mSurfaceTexture);
|
||||
}
|
||||
|
||||
mFrameAvailableCallback = aRunnable;
|
||||
|
@ -87,7 +87,8 @@ public:
|
||||
void NotifyFrameAvailable();
|
||||
|
||||
GLuint Texture() { return mTexture; }
|
||||
jobject JavaSurface() { return mSurface->wrappedObject(); }
|
||||
const widget::sdk::Surface::Ref& JavaSurface() { return mSurface; }
|
||||
|
||||
private:
|
||||
AndroidSurfaceTexture();
|
||||
~AndroidSurfaceTexture();
|
||||
@ -95,8 +96,8 @@ private:
|
||||
bool Init(GLContext* aContext, GLuint aTexture);
|
||||
|
||||
GLuint mTexture;
|
||||
nsAutoPtr<mozilla::widget::android::sdk::SurfaceTexture> mSurfaceTexture;
|
||||
nsAutoPtr<mozilla::widget::android::sdk::Surface> mSurface;
|
||||
widget::sdk::SurfaceTexture::GlobalRef mSurfaceTexture;
|
||||
widget::sdk::Surface::GlobalRef mSurface;
|
||||
|
||||
Monitor mMonitor;
|
||||
GLContext* mAttachedContext;
|
||||
|
@ -14,13 +14,13 @@ namespace hal_impl {
|
||||
void
|
||||
StartMonitoringGamepadStatus()
|
||||
{
|
||||
mozilla::widget::android::GeckoAppShell::StartMonitoringGamepad();
|
||||
widget::GeckoAppShell::StartMonitoringGamepad();
|
||||
}
|
||||
|
||||
void
|
||||
StopMonitoringGamepadStatus()
|
||||
{
|
||||
mozilla::widget::android::GeckoAppShell::StopMonitoringGamepad();
|
||||
widget::GeckoAppShell::StopMonitoringGamepad();
|
||||
}
|
||||
|
||||
} // hal_impl
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::hal;
|
||||
using namespace mozilla::widget::android;
|
||||
|
||||
namespace mozilla {
|
||||
namespace hal_impl {
|
||||
@ -55,19 +54,19 @@ CancelVibrate(const WindowIdentifier &)
|
||||
{
|
||||
// Ignore WindowIdentifier parameter.
|
||||
|
||||
mozilla::widget::android::GeckoAppShell::CancelVibrate();
|
||||
mozilla::widget::GeckoAppShell::CancelVibrate();
|
||||
}
|
||||
|
||||
void
|
||||
EnableBatteryNotifications()
|
||||
{
|
||||
mozilla::widget::android::GeckoAppShell::EnableBatteryNotifications();
|
||||
mozilla::widget::GeckoAppShell::EnableBatteryNotifications();
|
||||
}
|
||||
|
||||
void
|
||||
DisableBatteryNotifications()
|
||||
{
|
||||
mozilla::widget::android::GeckoAppShell::DisableBatteryNotifications();
|
||||
mozilla::widget::GeckoAppShell::DisableBatteryNotifications();
|
||||
}
|
||||
|
||||
void
|
||||
@ -79,13 +78,13 @@ GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo)
|
||||
void
|
||||
EnableNetworkNotifications()
|
||||
{
|
||||
mozilla::widget::android::GeckoAppShell::EnableNetworkNotifications();
|
||||
mozilla::widget::GeckoAppShell::EnableNetworkNotifications();
|
||||
}
|
||||
|
||||
void
|
||||
DisableNetworkNotifications()
|
||||
{
|
||||
mozilla::widget::android::GeckoAppShell::DisableNetworkNotifications();
|
||||
mozilla::widget::GeckoAppShell::DisableNetworkNotifications();
|
||||
}
|
||||
|
||||
void
|
||||
@ -97,13 +96,13 @@ GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInfo)
|
||||
void
|
||||
EnableScreenConfigurationNotifications()
|
||||
{
|
||||
mozilla::widget::android::GeckoAppShell::EnableScreenOrientationNotifications();
|
||||
mozilla::widget::GeckoAppShell::EnableScreenOrientationNotifications();
|
||||
}
|
||||
|
||||
void
|
||||
DisableScreenConfigurationNotifications()
|
||||
{
|
||||
mozilla::widget::android::GeckoAppShell::DisableScreenOrientationNotifications();
|
||||
mozilla::widget::GeckoAppShell::DisableScreenOrientationNotifications();
|
||||
}
|
||||
|
||||
void
|
||||
@ -149,7 +148,7 @@ LockScreenOrientation(const ScreenOrientation& aOrientation)
|
||||
case eScreenOrientation_LandscapeSecondary:
|
||||
case eScreenOrientation_LandscapePrimary | eScreenOrientation_LandscapeSecondary:
|
||||
case eScreenOrientation_Default:
|
||||
mozilla::widget::android::GeckoAppShell::LockScreenOrientation(aOrientation);
|
||||
mozilla::widget::GeckoAppShell::LockScreenOrientation(aOrientation);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@ -159,7 +158,7 @@ LockScreenOrientation(const ScreenOrientation& aOrientation)
|
||||
void
|
||||
UnlockScreenOrientation()
|
||||
{
|
||||
mozilla::widget::android::GeckoAppShell::UnlockScreenOrientation();
|
||||
mozilla::widget::GeckoAppShell::UnlockScreenOrientation();
|
||||
}
|
||||
|
||||
} // hal_impl
|
||||
|
@ -13,12 +13,12 @@ namespace hal_impl {
|
||||
|
||||
void
|
||||
EnableSensorNotifications(SensorType aSensor) {
|
||||
mozilla::widget::android::GeckoAppShell::EnableSensor(aSensor);
|
||||
widget::GeckoAppShell::EnableSensor(aSensor);
|
||||
}
|
||||
|
||||
void
|
||||
DisableSensorNotifications(SensorType aSensor) {
|
||||
mozilla::widget::android::GeckoAppShell::DisableSensor(aSensor);
|
||||
widget::GeckoAppShell::DisableSensor(aSensor);
|
||||
}
|
||||
|
||||
} // hal_impl
|
||||
|
@ -110,7 +110,7 @@ MessagePump::Run(MessagePump::Delegate* aDelegate)
|
||||
// get here if the normal Gecko event loop has been awoken above.
|
||||
// Bug 750713
|
||||
if (MOZ_LIKELY(AndroidBridge::HasEnv())) {
|
||||
did_work |= mozilla::widget::android::GeckoAppShell::PumpMessageLoop();
|
||||
did_work |= mozilla::widget::GeckoAppShell::PumpMessageLoop();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -255,7 +255,7 @@ public class GeckoAppShell
|
||||
|
||||
// Initialization methods
|
||||
public static native void registerJavaUiThread();
|
||||
public static native void nativeInit();
|
||||
public static native void nativeInit(ClassLoader clsLoader);
|
||||
|
||||
// helper methods
|
||||
public static native void onResume();
|
||||
@ -339,8 +339,8 @@ public class GeckoAppShell
|
||||
};
|
||||
Looper.myQueue().addIdleHandler(idleHandler);
|
||||
|
||||
// run gecko -- it will spawn its own thread
|
||||
GeckoAppShell.nativeInit();
|
||||
// Initialize AndroidBridge.
|
||||
nativeInit(GeckoAppShell.class.getClassLoader());
|
||||
|
||||
// First argument is the .apk path
|
||||
String combinedArgs = apkPath + " -greomni " + apkPath;
|
||||
|
@ -77,7 +77,7 @@ nsAndroidHistory::RegisterVisitedCallback(nsIURI *aURI, Link *aContent)
|
||||
list->AppendElement(aContent);
|
||||
|
||||
if (AndroidBridge::HasEnv()) {
|
||||
mozilla::widget::android::GeckoAppShell::CheckURIVisited(uriString);
|
||||
widget::GeckoAppShell::CheckURIVisited(uriString);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -203,7 +203,7 @@ nsAndroidHistory::SaveVisitURI(nsIURI* aURI) {
|
||||
// Save this URI in our history
|
||||
nsAutoCString spec;
|
||||
(void)aURI->GetSpec(spec);
|
||||
mozilla::widget::android::GeckoAppShell::MarkURIVisited(NS_ConvertUTF8toUTF16(spec));
|
||||
widget::GeckoAppShell::MarkURIVisited(NS_ConvertUTF8toUTF16(spec));
|
||||
}
|
||||
|
||||
// Finally, notify that we've been visited.
|
||||
@ -288,7 +288,7 @@ nsAndroidHistory::SetURITitle(nsIURI *aURI, const nsAString& aTitle)
|
||||
nsresult rv = aURI->GetSpec(uri);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
NS_ConvertUTF8toUTF16 uriString(uri);
|
||||
mozilla::widget::android::GeckoAppShell::SetURITitle(uriString, aTitle);
|
||||
widget::GeckoAppShell::SetURITitle(uriString, aTitle);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "AndroidBridge.h"
|
||||
|
||||
using namespace mozilla::widget::android;
|
||||
using namespace mozilla;
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsShellService, nsIShellService)
|
||||
|
||||
@ -25,6 +25,6 @@ nsShellService::CreateShortcut(const nsAString& aTitle, const nsAString& aURI,
|
||||
if (!aTitle.Length() || !aURI.Length() || !aIconData.Length())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mozilla::widget::android::GeckoAppShell::CreateShortcut(aTitle, aURI, aIconData);
|
||||
widget::GeckoAppShell::CreateShortcut(aTitle, aURI, aIconData);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -77,16 +77,16 @@ Java_org_mozilla_gecko_GeckoAppShell_registerJavaUiThread(JNIEnv * arg0, jclass
|
||||
|
||||
#ifdef JNI_STUBS
|
||||
|
||||
typedef void (*Java_org_mozilla_gecko_GeckoAppShell_nativeInit_t)(JNIEnv *, jclass);
|
||||
typedef void (*Java_org_mozilla_gecko_GeckoAppShell_nativeInit_t)(JNIEnv *, jclass, jobject);
|
||||
static Java_org_mozilla_gecko_GeckoAppShell_nativeInit_t f_Java_org_mozilla_gecko_GeckoAppShell_nativeInit;
|
||||
extern "C" NS_EXPORT void JNICALL
|
||||
Java_org_mozilla_gecko_GeckoAppShell_nativeInit(JNIEnv * arg0, jclass arg1) {
|
||||
Java_org_mozilla_gecko_GeckoAppShell_nativeInit(JNIEnv * arg0, jclass arg1, jobject arg2) {
|
||||
if (!f_Java_org_mozilla_gecko_GeckoAppShell_nativeInit) {
|
||||
arg0->ThrowNew(arg0->FindClass("java/lang/UnsupportedOperationException"),
|
||||
"JNI Function called before it was loaded");
|
||||
return ;
|
||||
}
|
||||
f_Java_org_mozilla_gecko_GeckoAppShell_nativeInit(arg0, arg1);
|
||||
f_Java_org_mozilla_gecko_GeckoAppShell_nativeInit(arg0, arg1, arg2);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -81,7 +81,7 @@ Tickler::Init()
|
||||
MOZ_ASSERT(!mFD);
|
||||
|
||||
if (AndroidBridge::HasEnv()) {
|
||||
mozilla::widget::android::GeckoAppShell::EnableNetworkNotifications();
|
||||
widget::GeckoAppShell::EnableNetworkNotifications();
|
||||
}
|
||||
|
||||
mFD = PR_OpenUDPSocket(PR_AF_INET);
|
||||
|
@ -90,7 +90,7 @@ bool CameraStreamImpl::Init(const nsCString& contentType, const uint32_t& camera
|
||||
}
|
||||
|
||||
void CameraStreamImpl::Close() {
|
||||
mozilla::widget::android::GeckoAppShell::CloseCamera();
|
||||
mozilla::widget::GeckoAppShell::CloseCamera();
|
||||
mCallback = nullptr;
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,6 @@
|
||||
|
||||
#include "AndroidBridge.h"
|
||||
|
||||
using namespace mozilla::widget::android;
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsAndroidNetworkLinkService,
|
||||
nsINetworkLinkService)
|
||||
|
||||
@ -33,7 +31,7 @@ nsAndroidNetworkLinkService::GetIsLinkUp(bool *aIsUp)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
*aIsUp = mozilla::widget::android::GeckoAppShell::IsNetworkLinkUp();
|
||||
*aIsUp = mozilla::widget::GeckoAppShell::IsNetworkLinkUp();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -42,7 +40,7 @@ nsAndroidNetworkLinkService::GetLinkStatusKnown(bool *aIsKnown)
|
||||
{
|
||||
NS_ENSURE_TRUE(mozilla::AndroidBridge::Bridge(), NS_ERROR_NOT_IMPLEMENTED);
|
||||
|
||||
*aIsKnown = mozilla::widget::android::GeckoAppShell::IsNetworkLinkKnown();
|
||||
*aIsKnown = mozilla::widget::GeckoAppShell::IsNetworkLinkKnown();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -58,6 +56,6 @@ nsAndroidNetworkLinkService::GetLinkType(uint32_t *aLinkType)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
*aLinkType = mozilla::widget::android::GeckoAppShell::NetworkLinkType();
|
||||
*aLinkType = mozilla::widget::GeckoAppShell::NetworkLinkType();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "AndroidBridge.h"
|
||||
using namespace mozilla::widget::android;
|
||||
#else
|
||||
|
||||
#include "nsXPCOM.h"
|
||||
@ -136,7 +135,7 @@ NS_IMETHODIMP nsAlertsService::CloseAlert(const nsAString& aAlertName,
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
mozilla::widget::android::GeckoAppShell::CloseNotification(aAlertName);
|
||||
widget::GeckoAppShell::CloseNotification(aAlertName);
|
||||
return NS_OK;
|
||||
#else
|
||||
|
||||
@ -157,9 +156,9 @@ NS_IMETHODIMP nsAlertsService::OnProgress(const nsAString & aAlertName,
|
||||
const nsAString & aAlertText)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
mozilla::widget::android::GeckoAppShell::AlertsProgressListener_OnProgress(aAlertName,
|
||||
aProgress, aProgressMax,
|
||||
aAlertText);
|
||||
widget::GeckoAppShell::AlertsProgressListener_OnProgress(aAlertName,
|
||||
aProgress, aProgressMax,
|
||||
aAlertText);
|
||||
return NS_OK;
|
||||
#else
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
@ -169,7 +168,7 @@ NS_IMETHODIMP nsAlertsService::OnProgress(const nsAString & aAlertName,
|
||||
NS_IMETHODIMP nsAlertsService::OnCancel(const nsAString & aAlertName)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
mozilla::widget::android::GeckoAppShell::CloseNotification(aAlertName);
|
||||
widget::GeckoAppShell::CloseNotification(aAlertName);
|
||||
return NS_OK;
|
||||
#else
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
@ -57,7 +57,6 @@
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "AndroidBridge.h"
|
||||
using namespace mozilla::widget::android;
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
@ -2787,7 +2786,7 @@ nsDownload::SetState(DownloadState aState)
|
||||
if (mimeInfo)
|
||||
mimeInfo->GetMIMEType(contentType);
|
||||
|
||||
mozilla::widget::android::DownloadsIntegration::ScanMedia(path, NS_ConvertUTF8toUTF16(contentType));
|
||||
mozilla::widget::DownloadsIntegration::ScanMedia(path, NS_ConvertUTF8toUTF16(contentType));
|
||||
}
|
||||
#else
|
||||
if (addToRecentDocs && !mPrivate) {
|
||||
|
@ -84,7 +84,7 @@ nsresult DownloadPlatform::DownloadDone(nsIURI* aSource, nsIFile* aTarget,
|
||||
bool addToRecentDocs = Preferences::GetBool(PREF_BDM_ADDTORECENTDOCS);
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
if (addToRecentDocs) {
|
||||
mozilla::widget::android::DownloadsIntegration::ScanMedia(path, NS_ConvertUTF8toUTF16(aContentType));
|
||||
mozilla::widget::DownloadsIntegration::ScanMedia(path, NS_ConvertUTF8toUTF16(aContentType));
|
||||
}
|
||||
#else
|
||||
if (addToRecentDocs && !aIsPrivate) {
|
||||
|
@ -14,7 +14,7 @@ nsParentalControlsService::nsParentalControlsService() :
|
||||
mEnabled(false)
|
||||
{
|
||||
if (mozilla::AndroidBridge::HasEnv()) {
|
||||
mEnabled = mozilla::widget::android::RestrictedProfiles::IsUserRestricted();
|
||||
mEnabled = mozilla::widget::RestrictedProfiles::IsUserRestricted();
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ nsParentalControlsService::IsAllowed(int16_t aAction,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
*_retval = mozilla::widget::android::RestrictedProfiles::IsAllowed(aAction,
|
||||
*_retval = mozilla::widget::RestrictedProfiles::IsAllowed(aAction,
|
||||
NS_ConvertUTF8toUTF16(url));
|
||||
return rv;
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ GeckoStart(void *data, const nsXREAppData *appData)
|
||||
if (result)
|
||||
LOG("XRE_main returned %d", result);
|
||||
|
||||
mozilla::widget::android::GeckoAppShell::NotifyXreExit();
|
||||
mozilla::widget::GeckoAppShell::NotifyXreExit();
|
||||
|
||||
free(targs[0]);
|
||||
nsMemory::Free(data);
|
||||
|
@ -1701,7 +1701,7 @@ static nsresult LaunchChild(nsINativeAppSupport* aNative,
|
||||
SaveToEnv("MOZ_LAUNCHED_CHILD=1");
|
||||
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
mozilla::widget::android::GeckoAppShell::ScheduleRestart();
|
||||
mozilla::widget::GeckoAppShell::ScheduleRestart();
|
||||
#else
|
||||
#if defined(XP_MACOSX)
|
||||
CommandLineServiceMac::SetupMacCommandLine(gRestartArgc, gRestartArgv, true);
|
||||
@ -1839,7 +1839,7 @@ ProfileLockedDialog(nsIFile* aProfileDir, nsIFile* aProfileLocalDir,
|
||||
if (aUnlocker) {
|
||||
int32_t button;
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
mozilla::widget::android::GeckoAppShell::KillAnyZombies();
|
||||
mozilla::widget::GeckoAppShell::KillAnyZombies();
|
||||
button = 0;
|
||||
#else
|
||||
const uint32_t flags =
|
||||
@ -1868,7 +1868,7 @@ ProfileLockedDialog(nsIFile* aProfileDir, nsIFile* aProfileLocalDir,
|
||||
}
|
||||
} else {
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
if (mozilla::widget::android::GeckoAppShell::UnlockProfile()) {
|
||||
if (mozilla::widget::GeckoAppShell::UnlockProfile()) {
|
||||
return NS_LockProfilePath(aProfileDir, aProfileLocalDir,
|
||||
nullptr, aResult);
|
||||
}
|
||||
|
@ -273,7 +273,7 @@ void BuildJavaThreadJSObject(JSStreamWriter& b)
|
||||
firstRun = false;
|
||||
|
||||
double sampleTime =
|
||||
mozilla::widget::android::GeckoJavaSampler::GetSampleTimeJavaProfiling(0, sampleId);
|
||||
mozilla::widget::GeckoJavaSampler::GetSampleTimeJavaProfiling(0, sampleId);
|
||||
|
||||
b.BeginObject();
|
||||
b.NameValue("time", sampleTime);
|
||||
@ -350,11 +350,11 @@ void TableTicker::StreamJSObject(JSStreamWriter& b)
|
||||
|
||||
#if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK)
|
||||
if (ProfileJava()) {
|
||||
mozilla::widget::android::GeckoJavaSampler::PauseJavaProfiling();
|
||||
mozilla::widget::GeckoJavaSampler::PauseJavaProfiling();
|
||||
|
||||
BuildJavaThreadJSObject(b);
|
||||
|
||||
mozilla::widget::android::GeckoJavaSampler::UnpauseJavaProfiling();
|
||||
mozilla::widget::GeckoJavaSampler::UnpauseJavaProfiling();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -27,7 +27,6 @@
|
||||
|
||||
#if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK)
|
||||
#include "AndroidBridge.h"
|
||||
using namespace mozilla::widget::android;
|
||||
#endif
|
||||
|
||||
mozilla::ThreadLocal<PseudoStack *> tlsPseudoStack;
|
||||
@ -789,7 +788,7 @@ void mozilla_sampler_start(int aProfileEntries, double aInterval,
|
||||
if (javaInterval < 10) {
|
||||
aInterval = 10;
|
||||
}
|
||||
mozilla::widget::android::GeckoJavaSampler::StartJavaProfiling(javaInterval, 1000);
|
||||
mozilla::widget::GeckoJavaSampler::StartJavaProfiling(javaInterval, 1000);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "nsAndroidHandlerApp.h"
|
||||
#include "AndroidBridge.h"
|
||||
|
||||
using namespace mozilla::widget::android;
|
||||
using namespace mozilla;
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsAndroidHandlerApp, nsIHandlerApp, nsISharingHandlerApp)
|
||||
@ -76,15 +76,16 @@ nsAndroidHandlerApp::LaunchWithURI(nsIURI *aURI, nsIInterfaceRequestor *aWindowC
|
||||
{
|
||||
nsCString uriSpec;
|
||||
aURI->GetSpec(uriSpec);
|
||||
return mozilla::widget::android::GeckoAppShell::OpenUriExternal
|
||||
(NS_ConvertUTF8toUTF16(uriSpec), NS_ConvertUTF8toUTF16(mMimeType), mPackageName, mClassName, mAction) ?
|
||||
NS_OK : NS_ERROR_FAILURE;
|
||||
return widget::GeckoAppShell::OpenUriExternal(
|
||||
uriSpec, mMimeType, mPackageName, mClassName,
|
||||
mAction, EmptyString()) ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAndroidHandlerApp::Share(const nsAString & data, const nsAString & title)
|
||||
{
|
||||
return mozilla::widget::android::GeckoAppShell::OpenUriExternal(data, NS_ConvertUTF8toUTF16(mMimeType),
|
||||
mPackageName, mClassName, mAction) ? NS_OK : NS_ERROR_FAILURE;
|
||||
return widget::GeckoAppShell::OpenUriExternal(
|
||||
data, mMimeType, mPackageName, mClassName,
|
||||
mAction, EmptyString()) ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -31,8 +31,8 @@ nsExternalSharingAppService::ShareWithDefault(const nsAString & data,
|
||||
{
|
||||
NS_NAMED_LITERAL_STRING(sendAction, "android.intent.action.SEND");
|
||||
const nsString emptyString = EmptyString();
|
||||
return mozilla::widget::android::GeckoAppShell::OpenUriExternal(data,
|
||||
mime, emptyString,emptyString, sendAction, title) ? NS_OK : NS_ERROR_FAILURE;
|
||||
return widget::GeckoAppShell::OpenUriExternal(data,
|
||||
mime, emptyString, emptyString, sendAction, title) ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "nsStringEnumerator.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
using namespace mozilla::widget::android;
|
||||
using namespace mozilla;
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsMIMEInfoAndroid, nsIMIMEInfo, nsIHandlerInfo)
|
||||
|
||||
@ -36,7 +36,9 @@ nsMIMEInfoAndroid::LoadUriInternal(nsIURI * aURI)
|
||||
mimeType = NS_ConvertUTF8toUTF16(mType);
|
||||
}
|
||||
|
||||
if (GeckoAppShell::OpenUriExternal(NS_ConvertUTF8toUTF16(uriSpec), mimeType)) {
|
||||
if (widget::GeckoAppShell::OpenUriExternal(
|
||||
NS_ConvertUTF8toUTF16(uriSpec), mimeType, EmptyString(),
|
||||
EmptyString(), EmptyString(), EmptyString())) {
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -27,11 +27,11 @@ namespace android {
|
||||
|
||||
StaticRefPtr<APZCCallbackHandler> APZCCallbackHandler::sInstance;
|
||||
|
||||
NativePanZoomController*
|
||||
APZCCallbackHandler::SetNativePanZoomController(jobject obj)
|
||||
NativePanZoomController::LocalRef
|
||||
APZCCallbackHandler::SetNativePanZoomController(NativePanZoomController::Param obj)
|
||||
{
|
||||
NativePanZoomController* old = mNativePanZoomController;
|
||||
mNativePanZoomController = NativePanZoomController::Wrap(obj);
|
||||
NativePanZoomController::LocalRef old = mNativePanZoomController;
|
||||
mNativePanZoomController = obj;
|
||||
return old;
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define APZCCallbackHandler_h__
|
||||
|
||||
#include "mozilla/layers/GeckoContentController.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "GeneratedJNIWrappers.h"
|
||||
#include "nsIDOMWindowUtils.h"
|
||||
@ -20,7 +21,7 @@ class APZCCallbackHandler MOZ_FINAL : public mozilla::layers::GeckoContentContro
|
||||
{
|
||||
private:
|
||||
static StaticRefPtr<APZCCallbackHandler> sInstance;
|
||||
NativePanZoomController* mNativePanZoomController;
|
||||
NativePanZoomController::GlobalRef mNativePanZoomController;
|
||||
|
||||
private:
|
||||
APZCCallbackHandler()
|
||||
@ -37,7 +38,7 @@ public:
|
||||
return sInstance.get();
|
||||
}
|
||||
|
||||
NativePanZoomController* SetNativePanZoomController(jobject obj);
|
||||
NativePanZoomController::LocalRef SetNativePanZoomController(NativePanZoomController::Param obj);
|
||||
void NotifyDefaultPrevented(uint64_t aInputBlockId, bool aDefaultPrevented);
|
||||
|
||||
public: // GeckoContentController methods
|
||||
|
@ -46,8 +46,9 @@
|
||||
#include "SurfaceTexture.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::widget::android;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::jni;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
AndroidBridge* AndroidBridge::sBridge;
|
||||
pthread_t AndroidBridge::sJavaUiThread = -1;
|
||||
@ -66,22 +67,29 @@ static android::sp<AndroidRefable> (*android_SurfaceTexture_getNativeWindow)(JNI
|
||||
|
||||
jclass AndroidBridge::GetClassGlobalRef(JNIEnv* env, const char* className)
|
||||
{
|
||||
jobject classLocalRef = env->FindClass(className);
|
||||
if (!classLocalRef) {
|
||||
ALOG(">>> FATAL JNI ERROR! FindClass(className=\"%s\") failed. Did ProGuard optimize away something it shouldn't have?",
|
||||
// First try the default class loader.
|
||||
auto classRef = ClassObject::LocalRef::Adopt(
|
||||
env, env->FindClass(className));
|
||||
|
||||
if (!classRef && sBridge && sBridge->mClassLoader) {
|
||||
// If the default class loader failed but we have an app class loader, try that.
|
||||
// Clear the pending exception from failed FindClass call above.
|
||||
env->ExceptionClear();
|
||||
classRef = ClassObject::LocalRef::Adopt(env,
|
||||
env->CallObjectMethod(sBridge->mClassLoader.Get(),
|
||||
sBridge->mClassLoaderLoadClass,
|
||||
Param<String>::Type(className, env).Get()));
|
||||
}
|
||||
|
||||
if (!classRef) {
|
||||
ALOG(">>> FATAL JNI ERROR! FindClass(className=\"%s\") failed. "
|
||||
"Did ProGuard optimize away something it shouldn't have?",
|
||||
className);
|
||||
env->ExceptionDescribe();
|
||||
MOZ_CRASH();
|
||||
}
|
||||
jobject classGlobalRef = env->NewGlobalRef(classLocalRef);
|
||||
if (!classGlobalRef) {
|
||||
env->ExceptionDescribe();
|
||||
MOZ_CRASH();
|
||||
}
|
||||
// Local ref no longer necessary because we have a global ref.
|
||||
env->DeleteLocalRef(classLocalRef);
|
||||
classLocalRef = nullptr;
|
||||
return static_cast<jclass>(classGlobalRef);
|
||||
|
||||
return ClassObject::GlobalRef(env, classRef).Forget();
|
||||
}
|
||||
|
||||
jmethodID AndroidBridge::GetMethodID(JNIEnv* env, jclass jClass,
|
||||
@ -141,7 +149,7 @@ jfieldID AndroidBridge::GetStaticFieldID(JNIEnv* env, jclass jClass,
|
||||
}
|
||||
|
||||
void
|
||||
AndroidBridge::ConstructBridge(JNIEnv *jEnv)
|
||||
AndroidBridge::ConstructBridge(JNIEnv *jEnv, Object::Param clsLoader)
|
||||
{
|
||||
/* NSS hack -- bionic doesn't handle recursive unloads correctly,
|
||||
* because library finalizer functions are called with the dynamic
|
||||
@ -154,14 +162,14 @@ AndroidBridge::ConstructBridge(JNIEnv *jEnv)
|
||||
PR_NewThreadPrivateIndex(&sJavaEnvThreadIndex, JavaThreadDetachFunc);
|
||||
|
||||
AndroidBridge *bridge = new AndroidBridge();
|
||||
if (!bridge->Init(jEnv)) {
|
||||
if (!bridge->Init(jEnv, clsLoader)) {
|
||||
delete bridge;
|
||||
}
|
||||
sBridge = bridge;
|
||||
}
|
||||
|
||||
bool
|
||||
AndroidBridge::Init(JNIEnv *jEnv)
|
||||
AndroidBridge::Init(JNIEnv *jEnv, Object::Param clsLoader)
|
||||
{
|
||||
ALOG_BRIDGE("AndroidBridge::Init");
|
||||
jEnv->GetJavaVM(&mJavaVM);
|
||||
@ -171,6 +179,11 @@ AndroidBridge::Init(JNIEnv *jEnv)
|
||||
|
||||
AutoLocalJNIFrame jniFrame(jEnv);
|
||||
|
||||
mClassLoader = Object::GlobalRef(jEnv, clsLoader);
|
||||
mClassLoaderLoadClass = GetMethodID(
|
||||
jEnv, jEnv->GetObjectClass(clsLoader.Get()),
|
||||
"loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
|
||||
|
||||
mJNIEnv = nullptr;
|
||||
mThread = -1;
|
||||
mGLControllerObj = nullptr;
|
||||
@ -228,14 +241,6 @@ AndroidBridge::Init(JNIEnv *jEnv)
|
||||
|
||||
InitAndroidJavaWrappers(jEnv);
|
||||
|
||||
if (mAPIVersion >= 16 /* Jelly Bean */) {
|
||||
sdk::InitMediaCodecStubs(jEnv);
|
||||
}
|
||||
|
||||
if (mAPIVersion >= 14 /* ICS */) {
|
||||
sdk::InitSurfaceTextureStubs(jEnv);
|
||||
}
|
||||
|
||||
// jEnv should NOT be cached here by anything -- the jEnv here
|
||||
// is not valid for the real gecko main thread, which is set
|
||||
// at SetMainThread time.
|
||||
@ -434,20 +439,17 @@ AndroidBridge::GetHandlersForMimeType(const nsAString& aMimeType,
|
||||
{
|
||||
ALOG_BRIDGE("AndroidBridge::GetHandlersForMimeType");
|
||||
|
||||
JNIEnv *env = GetJNIEnv();
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env, 1);
|
||||
jobjectArray arr =
|
||||
mozilla::widget::android::GeckoAppShell::GetHandlersForMimeTypeWrapper(aMimeType, aAction);
|
||||
auto arr = GeckoAppShell::GetHandlersForMimeTypeWrapper(aMimeType, aAction);
|
||||
if (!arr)
|
||||
return false;
|
||||
|
||||
jsize len = env->GetArrayLength(arr);
|
||||
JNIEnv* const env = arr.Env();
|
||||
jsize len = env->GetArrayLength(arr.Get());
|
||||
|
||||
if (!aHandlersArray)
|
||||
return len > 0;
|
||||
|
||||
getHandlersFromStringArray(env, arr, len, aHandlersArray,
|
||||
getHandlersFromStringArray(env, arr.Get(), len, aHandlersArray,
|
||||
aDefaultApp, aAction,
|
||||
NS_ConvertUTF16toUTF8(aMimeType));
|
||||
return true;
|
||||
@ -461,19 +463,17 @@ AndroidBridge::GetHandlersForURL(const nsAString& aURL,
|
||||
{
|
||||
ALOG_BRIDGE("AndroidBridge::GetHandlersForURL");
|
||||
|
||||
JNIEnv *env = GetJNIEnv();
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env, 1);
|
||||
jobjectArray arr = mozilla::widget::android::GeckoAppShell::GetHandlersForURLWrapper(aURL, aAction);
|
||||
auto arr = GeckoAppShell::GetHandlersForURLWrapper(aURL, aAction);
|
||||
if (!arr)
|
||||
return false;
|
||||
|
||||
jsize len = env->GetArrayLength(arr);
|
||||
JNIEnv* const env = arr.Env();
|
||||
jsize len = env->GetArrayLength(arr.Get());
|
||||
|
||||
if (!aHandlersArray)
|
||||
return len > 0;
|
||||
|
||||
getHandlersFromStringArray(env, arr, len, aHandlersArray,
|
||||
getHandlersFromStringArray(env, arr.Get(), len, aHandlersArray,
|
||||
aDefaultApp, aAction);
|
||||
return true;
|
||||
}
|
||||
@ -483,16 +483,11 @@ AndroidBridge::GetMimeTypeFromExtensions(const nsACString& aFileExt, nsCString&
|
||||
{
|
||||
ALOG_BRIDGE("AndroidBridge::GetMimeTypeFromExtensions");
|
||||
|
||||
JNIEnv *env = GetJNIEnv();
|
||||
auto jstrType = GeckoAppShell::GetMimeTypeFromExtensionsWrapper(aFileExt);
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env, 1);
|
||||
jstring jstrType = mozilla::widget::android::GeckoAppShell::GetMimeTypeFromExtensionsWrapper
|
||||
(NS_ConvertUTF8toUTF16(aFileExt));
|
||||
if (!jstrType) {
|
||||
return;
|
||||
if (jstrType) {
|
||||
aMimeType = jstrType;
|
||||
}
|
||||
nsJNIString jniStr(jstrType, env);
|
||||
CopyUTF16toUTF8(jniStr.get(), aMimeType);
|
||||
}
|
||||
|
||||
void
|
||||
@ -500,16 +495,11 @@ AndroidBridge::GetExtensionFromMimeType(const nsACString& aMimeType, nsACString&
|
||||
{
|
||||
ALOG_BRIDGE("AndroidBridge::GetExtensionFromMimeType");
|
||||
|
||||
JNIEnv *env = GetJNIEnv();
|
||||
auto jstrExt = GeckoAppShell::GetExtensionFromMimeTypeWrapper(aMimeType);
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env, 1);
|
||||
jstring jstrExt = mozilla::widget::android::GeckoAppShell::GetExtensionFromMimeTypeWrapper
|
||||
(NS_ConvertUTF8toUTF16(aMimeType));
|
||||
if (!jstrExt) {
|
||||
return;
|
||||
if (jstrExt) {
|
||||
aFileExt = nsCString(jstrExt);
|
||||
}
|
||||
nsJNIString jniStr(jstrExt, env);
|
||||
CopyUTF16toUTF8(jniStr.get(), aFileExt);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -517,16 +507,12 @@ AndroidBridge::GetClipboardText(nsAString& aText)
|
||||
{
|
||||
ALOG_BRIDGE("AndroidBridge::GetClipboardText");
|
||||
|
||||
JNIEnv *env = GetJNIEnv();
|
||||
auto text = Clipboard::GetClipboardTextWrapper();
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env, 1);
|
||||
jstring result = Clipboard::GetClipboardTextWrapper();
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
nsJNIString jniStr(result, env);
|
||||
aText.Assign(jniStr);
|
||||
return true;
|
||||
if (text) {
|
||||
aText = nsString(text);
|
||||
}
|
||||
return !!text;
|
||||
}
|
||||
|
||||
void
|
||||
@ -542,7 +528,7 @@ AndroidBridge::ShowAlertNotification(const nsAString& aImageUrl,
|
||||
nsAppShell::gAppShell->PostEvent(AndroidGeckoEvent::MakeAddObserver(aAlertName, aAlertListener));
|
||||
}
|
||||
|
||||
mozilla::widget::android::GeckoAppShell::ShowAlertNotificationWrapper
|
||||
GeckoAppShell::ShowAlertNotificationWrapper
|
||||
(aImageUrl, aAlertTitle, aAlertText, aAlertCookie, aAlertName);
|
||||
}
|
||||
|
||||
@ -555,7 +541,7 @@ AndroidBridge::GetDPI()
|
||||
|
||||
const int DEFAULT_DPI = 160;
|
||||
|
||||
sDPI = mozilla::widget::android::GeckoAppShell::GetDpiWrapper();
|
||||
sDPI = GeckoAppShell::GetDpiWrapper();
|
||||
if (!sDPI) {
|
||||
return DEFAULT_DPI;
|
||||
}
|
||||
@ -575,7 +561,7 @@ AndroidBridge::GetScreenDepth()
|
||||
const int DEFAULT_DEPTH = 16;
|
||||
|
||||
if (HasEnv()) {
|
||||
sDepth = mozilla::widget::android::GeckoAppShell::GetScreenDepthWrapper();
|
||||
sDepth = GeckoAppShell::GetScreenDepthWrapper();
|
||||
}
|
||||
if (!sDepth)
|
||||
return DEFAULT_DEPTH;
|
||||
@ -593,10 +579,6 @@ AndroidBridge::Vibrate(const nsTArray<uint32_t>& aPattern)
|
||||
return;
|
||||
}
|
||||
|
||||
JNIEnv *env = GetJNIEnv();
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env, 1);
|
||||
|
||||
// It's clear if this worth special-casing, but it creates less
|
||||
// java junk, so dodges the GC.
|
||||
if (len == 1) {
|
||||
@ -605,13 +587,16 @@ AndroidBridge::Vibrate(const nsTArray<uint32_t>& aPattern)
|
||||
ALOG_BRIDGE(" invalid vibration duration < 0");
|
||||
return;
|
||||
}
|
||||
mozilla::widget::android::GeckoAppShell::Vibrate1(d);
|
||||
GeckoAppShell::Vibrate1(d);
|
||||
return;
|
||||
}
|
||||
|
||||
// First element of the array vibrate() expects is how long to wait
|
||||
// *before* vibrating. For us, this is always 0.
|
||||
|
||||
JNIEnv *env = GetJNIEnv();
|
||||
AutoLocalJNIFrame jniFrame(env, 1);
|
||||
|
||||
jlongArray array = env->NewLongArray(len + 1);
|
||||
if (!array) {
|
||||
ALOG_BRIDGE(" failed to allocate array");
|
||||
@ -631,7 +616,7 @@ AndroidBridge::Vibrate(const nsTArray<uint32_t>& aPattern)
|
||||
}
|
||||
env->ReleaseLongArrayElements(array, elts, 0);
|
||||
|
||||
mozilla::widget::android::GeckoAppShell::VibrateA(array, -1/*don't repeat*/);
|
||||
GeckoAppShell::VibrateA(LongArray::Ref::From(array), -1 /* don't repeat */);
|
||||
}
|
||||
|
||||
void
|
||||
@ -642,16 +627,13 @@ AndroidBridge::GetSystemColors(AndroidSystemColors *aColors)
|
||||
if (!aColors)
|
||||
return;
|
||||
|
||||
JNIEnv *env = GetJNIEnv();
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env, 1);
|
||||
|
||||
jintArray arr = mozilla::widget::android::GeckoAppShell::GetSystemColoursWrapper();
|
||||
auto arr = GeckoAppShell::GetSystemColoursWrapper();
|
||||
if (!arr)
|
||||
return;
|
||||
|
||||
uint32_t len = static_cast<uint32_t>(env->GetArrayLength(arr));
|
||||
jint *elements = env->GetIntArrayElements(arr, 0);
|
||||
JNIEnv* const env = arr.Env();
|
||||
uint32_t len = static_cast<uint32_t>(env->GetArrayLength(arr.Get()));
|
||||
jint *elements = env->GetIntArrayElements(arr.Get(), 0);
|
||||
|
||||
uint32_t colorsCount = sizeof(AndroidSystemColors) / sizeof(nscolor);
|
||||
if (len < colorsCount)
|
||||
@ -667,7 +649,7 @@ AndroidBridge::GetSystemColors(AndroidSystemColors *aColors)
|
||||
colors[i] = (androidColor & 0xff00ff00) | (b << 16) | r;
|
||||
}
|
||||
|
||||
env->ReleaseIntArrayElements(arr, elements, 0);
|
||||
env->ReleaseIntArrayElements(arr.Get(), elements, 0);
|
||||
}
|
||||
|
||||
void
|
||||
@ -678,30 +660,27 @@ AndroidBridge::GetIconForExtension(const nsACString& aFileExt, uint32_t aIconSiz
|
||||
if (!aBuf)
|
||||
return;
|
||||
|
||||
JNIEnv *env = GetJNIEnv();
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env, 1);
|
||||
|
||||
jbyteArray arr = mozilla::widget::android::GeckoAppShell::GetIconForExtensionWrapper
|
||||
auto arr = GeckoAppShell::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);
|
||||
JNIEnv* const env = arr.Env();
|
||||
uint32_t len = static_cast<uint32_t>(env->GetArrayLength(arr.Get()));
|
||||
jbyte *elements = env->GetByteArrayElements(arr.Get(), 0);
|
||||
|
||||
uint32_t bufSize = aIconSize * aIconSize * 4;
|
||||
NS_ASSERTION(len == bufSize, "AndroidBridge::GetIconForExtension: Pixels array is incomplete!");
|
||||
if (len == bufSize)
|
||||
memcpy(aBuf, elements, bufSize);
|
||||
|
||||
env->ReleaseByteArrayElements(arr, elements, 0);
|
||||
env->ReleaseByteArrayElements(arr.Get(), elements, 0);
|
||||
}
|
||||
|
||||
void
|
||||
AndroidBridge::SetLayerClient(JNIEnv* env, jobject jobj)
|
||||
AndroidBridge::SetLayerClient(GeckoLayerClient::Param jobj)
|
||||
{
|
||||
// if resetting is true, that means Android destroyed our GeckoApp activity
|
||||
// and we had to recreate it, but all the Gecko-side things were not destroyed.
|
||||
@ -709,13 +688,7 @@ AndroidBridge::SetLayerClient(JNIEnv* env, jobject jobj)
|
||||
// we do here.
|
||||
bool resetting = (mLayerClient != nullptr);
|
||||
|
||||
if (resetting) {
|
||||
// clear out the old layer client
|
||||
delete mLayerClient;
|
||||
mLayerClient = nullptr;
|
||||
}
|
||||
|
||||
mLayerClient = mozilla::widget::android::GeckoLayerClient::Wrap(jobj);
|
||||
mLayerClient = jobj;
|
||||
|
||||
if (resetting) {
|
||||
// since we are re-linking the new java objects to Gecko, we need to get
|
||||
@ -728,17 +701,13 @@ AndroidBridge::SetLayerClient(JNIEnv* env, jobject jobj)
|
||||
void
|
||||
AndroidBridge::RegisterCompositor(JNIEnv *env)
|
||||
{
|
||||
if (mGLControllerObj != nullptr && !mGLControllerObj->isNull()) {
|
||||
if (mGLControllerObj != nullptr) {
|
||||
// we already have this set up, no need to do it again
|
||||
return;
|
||||
}
|
||||
|
||||
jobject glController = LayerView::RegisterCompositorWrapper();
|
||||
if (!glController) {
|
||||
return;
|
||||
}
|
||||
|
||||
mGLControllerObj = GLController::Wrap(glController);
|
||||
mGLControllerObj = GLController::LocalRef(
|
||||
LayerView::RegisterCompositorWrapper());
|
||||
}
|
||||
|
||||
EGLSurface
|
||||
@ -749,15 +718,14 @@ AndroidBridge::CreateEGLSurfaceForCompositor()
|
||||
}
|
||||
MOZ_ASSERT(mGLControllerObj, "AndroidBridge::CreateEGLSurfaceForCompositor called with a null GL controller ref");
|
||||
|
||||
JNIEnv* env = GetJNIForThread(); // called on the compositor thread
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env, 1);
|
||||
jobject eglSurface = mGLControllerObj->CreateEGLSurfaceForCompositorWrapper();
|
||||
if (!eglSurface)
|
||||
auto eglSurface = mGLControllerObj->CreateEGLSurfaceForCompositorWrapper();
|
||||
if (!eglSurface) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EGLSurface ret = reinterpret_cast<EGLSurface>(env->GetIntField(eglSurface, jEGLSurfacePointerField));
|
||||
return ret;
|
||||
JNIEnv* const env = GetJNIForThread(); // called on the compositor thread
|
||||
return reinterpret_cast<EGLSurface>(
|
||||
env->GetIntField(eglSurface.Get(), jEGLSurfacePointerField));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1007,16 +975,14 @@ AndroidBridge::ValidateBitmap(jobject bitmap, int width, int height)
|
||||
bool
|
||||
AndroidBridge::InitCamera(const nsCString& contentType, uint32_t camera, uint32_t *width, uint32_t *height, uint32_t *fps)
|
||||
{
|
||||
JNIEnv *env = GetJNIEnv();
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env, 1);
|
||||
jintArray arr = mozilla::widget::android::GeckoAppShell::InitCameraWrapper
|
||||
auto arr = GeckoAppShell::InitCameraWrapper
|
||||
(NS_ConvertUTF8toUTF16(contentType), (int32_t) camera, (int32_t) *width, (int32_t) *height);
|
||||
|
||||
if (!arr)
|
||||
return false;
|
||||
|
||||
jint *elements = env->GetIntArrayElements(arr, 0);
|
||||
JNIEnv* const env = arr.Env();
|
||||
jint *elements = env->GetIntArrayElements(arr.Get(), 0);
|
||||
|
||||
*width = elements[1];
|
||||
*height = elements[2];
|
||||
@ -1024,7 +990,7 @@ AndroidBridge::InitCamera(const nsCString& contentType, uint32_t camera, uint32_
|
||||
|
||||
bool res = elements[0] == 1;
|
||||
|
||||
env->ReleaseIntArrayElements(arr, elements, 0);
|
||||
env->ReleaseIntArrayElements(arr.Get(), elements, 0);
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -1034,24 +1000,22 @@ AndroidBridge::GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInf
|
||||
{
|
||||
ALOG_BRIDGE("AndroidBridge::GetCurrentBatteryInformation");
|
||||
|
||||
JNIEnv *env = GetJNIEnv();
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env, 1);
|
||||
|
||||
// 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 = mozilla::widget::android::GeckoAppShell::GetCurrentBatteryInformationWrapper();
|
||||
if (!arr || env->GetArrayLength(arr) != 3) {
|
||||
auto arr = GeckoAppShell::GetCurrentBatteryInformationWrapper();
|
||||
|
||||
JNIEnv* const env = arr.Env();
|
||||
if (!arr || env->GetArrayLength(arr.Get()) != 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
jdouble* info = env->GetDoubleArrayElements(arr, 0);
|
||||
jdouble* info = env->GetDoubleArrayElements(arr.Get(), 0);
|
||||
|
||||
aBatteryInfo->level() = info[0];
|
||||
aBatteryInfo->charging() = info[1] == 1.0f;
|
||||
aBatteryInfo->remainingTime() = info[2];
|
||||
|
||||
env->ReleaseDoubleArrayElements(arr, info, 0);
|
||||
env->ReleaseDoubleArrayElements(arr.Get(), info, 0);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1060,9 +1024,8 @@ AndroidBridge::HandleGeckoMessage(JSContext* cx, JS::HandleObject object)
|
||||
ALOG_BRIDGE("%s", __PRETTY_FUNCTION__);
|
||||
|
||||
JNIEnv* const env = GetJNIEnv();
|
||||
AutoLocalJNIFrame jniFrame(env, 1);
|
||||
const jobject message =
|
||||
mozilla::widget::CreateNativeJSContainer(env, cx, object);
|
||||
auto message = Object::LocalRef::Adopt(env,
|
||||
mozilla::widget::CreateNativeJSContainer(env, cx, object));
|
||||
GeckoAppShell::HandleGeckoMessageWrapper(message);
|
||||
}
|
||||
|
||||
@ -1118,7 +1081,7 @@ AndroidBridge::SendMessage(const nsAString& aNumber,
|
||||
if (!QueueSmsRequest(aRequest, &requestId))
|
||||
return;
|
||||
|
||||
mozilla::widget::android::GeckoAppShell::SendMessageWrapper(aNumber, aMessage, requestId);
|
||||
GeckoAppShell::SendMessageWrapper(aNumber, aMessage, requestId);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1130,7 +1093,7 @@ AndroidBridge::GetMessage(int32_t aMessageId, nsIMobileMessageCallback* aRequest
|
||||
if (!QueueSmsRequest(aRequest, &requestId))
|
||||
return;
|
||||
|
||||
mozilla::widget::android::GeckoAppShell::GetMessageWrapper(aMessageId, requestId);
|
||||
GeckoAppShell::GetMessageWrapper(aMessageId, requestId);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1142,7 +1105,7 @@ AndroidBridge::DeleteMessage(int32_t aMessageId, nsIMobileMessageCallback* aRequ
|
||||
if (!QueueSmsRequest(aRequest, &requestId))
|
||||
return;
|
||||
|
||||
mozilla::widget::android::GeckoAppShell::DeleteMessageWrapper(aMessageId, requestId);
|
||||
GeckoAppShell::DeleteMessageWrapper(aMessageId, requestId);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1173,7 +1136,8 @@ AndroidBridge::CreateMessageList(const dom::mobilemessage::SmsFilterData& aFilte
|
||||
int64_t startDate = aFilter.hasStartDate() ? aFilter.startDate() : -1;
|
||||
int64_t endDate = aFilter.hasEndDate() ? aFilter.endDate() : -1;
|
||||
GeckoAppShell::CreateMessageListWrapper(startDate, endDate,
|
||||
numbers, aFilter.numbers().Length(),
|
||||
ObjectArray::Ref::From(numbers),
|
||||
aFilter.numbers().Length(),
|
||||
aFilter.delivery(),
|
||||
aFilter.hasRead(), aFilter.read(),
|
||||
aFilter.threadId(),
|
||||
@ -1189,7 +1153,7 @@ AndroidBridge::GetNextMessageInList(int32_t aListId, nsIMobileMessageCallback* a
|
||||
if (!QueueSmsRequest(aRequest, &requestId))
|
||||
return;
|
||||
|
||||
mozilla::widget::android::GeckoAppShell::GetNextMessageInListWrapper(aListId, requestId);
|
||||
GeckoAppShell::GetNextMessageInListWrapper(aListId, requestId);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1232,25 +1196,23 @@ AndroidBridge::GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInf
|
||||
{
|
||||
ALOG_BRIDGE("AndroidBridge::GetCurrentNetworkInformation");
|
||||
|
||||
JNIEnv *env = GetJNIEnv();
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env, 1);
|
||||
|
||||
// To prevent calling too many methods through JNI, the Java method returns
|
||||
// an array of double even if we actually want an integer, a boolean, and an integer.
|
||||
|
||||
jdoubleArray arr = mozilla::widget::android::GeckoAppShell::GetCurrentNetworkInformationWrapper();
|
||||
if (!arr || env->GetArrayLength(arr) != 3) {
|
||||
auto arr = GeckoAppShell::GetCurrentNetworkInformationWrapper();
|
||||
|
||||
JNIEnv* const env = arr.Env();
|
||||
if (!arr || env->GetArrayLength(arr.Get()) != 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
jdouble* info = env->GetDoubleArrayElements(arr, 0);
|
||||
jdouble* info = env->GetDoubleArrayElements(arr.Get(), 0);
|
||||
|
||||
aNetworkInfo->type() = info[0];
|
||||
aNetworkInfo->isWifi() = info[1] == 1.0f;
|
||||
aNetworkInfo->dhcpGateway() = info[2];
|
||||
|
||||
env->ReleaseDoubleArrayElements(arr, info, 0);
|
||||
env->ReleaseDoubleArrayElements(arr.Get(), info, 0);
|
||||
}
|
||||
|
||||
void *
|
||||
@ -1258,8 +1220,6 @@ AndroidBridge::LockBitmap(jobject bitmap)
|
||||
{
|
||||
JNIEnv *env = GetJNIEnv();
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env, 0);
|
||||
|
||||
int err;
|
||||
void *buf;
|
||||
|
||||
@ -1276,8 +1236,6 @@ AndroidBridge::UnlockBitmap(jobject bitmap)
|
||||
{
|
||||
JNIEnv *env = GetJNIEnv();
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env, 0);
|
||||
|
||||
int err;
|
||||
|
||||
if ((err = AndroidBitmap_unlockPixels(env, bitmap)) != 0)
|
||||
@ -1420,37 +1378,37 @@ AndroidBridge::LockWindow(void *window, unsigned char **bits, int *width, int *h
|
||||
|
||||
jobject
|
||||
AndroidBridge::GetGlobalContextRef() {
|
||||
if (sGlobalContext == nullptr) {
|
||||
JNIEnv *env = GetJNIForThread();
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env, 4);
|
||||
|
||||
jobject context = mozilla::widget::android::GeckoAppShell::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;
|
||||
}
|
||||
jmethodID mid = env->GetMethodID(contextClass, "getApplicationContext",
|
||||
"()Landroid/content/Context;");
|
||||
if (!mid) {
|
||||
ALOG_BRIDGE("%s: Could not find getApplicationContext.", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
jobject appContext = env->CallObjectMethod(context, mid);
|
||||
if (!appContext) {
|
||||
ALOG_BRIDGE("%s: getApplicationContext failed.", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sGlobalContext = env->NewGlobalRef(appContext);
|
||||
MOZ_ASSERT(sGlobalContext);
|
||||
if (sGlobalContext) {
|
||||
return sGlobalContext;
|
||||
}
|
||||
|
||||
JNIEnv* const env = GetJNIForThread();
|
||||
AutoLocalJNIFrame jniFrame(env, 4);
|
||||
|
||||
auto context = GeckoAppShell::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;
|
||||
}
|
||||
jmethodID mid = env->GetMethodID(contextClass, "getApplicationContext",
|
||||
"()Landroid/content/Context;");
|
||||
if (!mid) {
|
||||
ALOG_BRIDGE("%s: Could not find getApplicationContext.", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
jobject appContext = env->CallObjectMethod(context.Get(), mid);
|
||||
if (!appContext) {
|
||||
ALOG_BRIDGE("%s: getApplicationContext failed.", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sGlobalContext = env->NewGlobalRef(appContext);
|
||||
MOZ_ASSERT(sGlobalContext);
|
||||
return sGlobalContext;
|
||||
}
|
||||
|
||||
@ -1476,22 +1434,23 @@ AndroidBridge::UnlockWindow(void* window)
|
||||
void
|
||||
AndroidBridge::SetFirstPaintViewport(const LayerIntPoint& aOffset, const CSSToLayerScale& aZoom, const CSSRect& aCssPageRect)
|
||||
{
|
||||
mozilla::widget::android::GeckoLayerClient *client = mLayerClient;
|
||||
if (!client)
|
||||
if (!mLayerClient) {
|
||||
return;
|
||||
}
|
||||
|
||||
client->SetFirstPaintViewport((float)aOffset.x, (float)aOffset.y, aZoom.scale,
|
||||
aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost());
|
||||
mLayerClient->SetFirstPaintViewport(float(aOffset.x), float(aOffset.y), aZoom.scale,
|
||||
aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost());
|
||||
}
|
||||
|
||||
void
|
||||
AndroidBridge::SetPageRect(const CSSRect& aCssPageRect)
|
||||
{
|
||||
mozilla::widget::android::GeckoLayerClient *client = mLayerClient;
|
||||
if (!client)
|
||||
if (!mLayerClient) {
|
||||
return;
|
||||
}
|
||||
|
||||
client->SetPageRect(aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost());
|
||||
mLayerClient->SetPageRect(aCssPageRect.x, aCssPageRect.y,
|
||||
aCssPageRect.XMost(), aCssPageRect.YMost());
|
||||
}
|
||||
|
||||
void
|
||||
@ -1499,39 +1458,33 @@ AndroidBridge::SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLay
|
||||
bool aLayersUpdated, ParentLayerPoint& aScrollOffset, CSSToParentLayerScale& aScale,
|
||||
LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset)
|
||||
{
|
||||
mozilla::widget::android::GeckoLayerClient *client = mLayerClient;
|
||||
if (!client) {
|
||||
if (!mLayerClient) {
|
||||
ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__);
|
||||
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!");
|
||||
ViewTransform::LocalRef viewTransform = mLayerClient->SyncViewportInfo(
|
||||
aDisplayPort.x, aDisplayPort.y,
|
||||
aDisplayPort.width, aDisplayPort.height,
|
||||
aDisplayResolution.scale, aLayersUpdated);
|
||||
|
||||
if (!viewTransformJObj) {
|
||||
return;
|
||||
}
|
||||
NS_ABORT_IF_FALSE(viewTransform, "No view transform object!");
|
||||
|
||||
ViewTransform* viewTransform = ViewTransform::Wrap(viewTransformJObj);
|
||||
aScrollOffset = ParentLayerPoint(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;
|
||||
aScrollOffset = ParentLayerPoint(viewTransform->X(), viewTransform->Y());
|
||||
aScale.scale = viewTransform->Scale();
|
||||
aFixedLayerMargins.top = viewTransform->FixedLayerMarginTop();
|
||||
aFixedLayerMargins.right = viewTransform->FixedLayerMarginRight();
|
||||
aFixedLayerMargins.bottom = viewTransform->FixedLayerMarginBottom();
|
||||
aFixedLayerMargins.left = viewTransform->FixedLayerMarginLeft();
|
||||
aOffset.x = viewTransform->OffsetX();
|
||||
aOffset.y = viewTransform->OffsetY();
|
||||
}
|
||||
|
||||
void AndroidBridge::SyncFrameMetrics(const ParentLayerPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect,
|
||||
bool aLayersUpdated, const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution,
|
||||
bool aIsFirstPaint, LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset)
|
||||
{
|
||||
mozilla::widget::android::GeckoLayerClient *client = mLayerClient;
|
||||
if (!client) {
|
||||
if (!mLayerClient) {
|
||||
ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__);
|
||||
return;
|
||||
}
|
||||
@ -1541,26 +1494,21 @@ void AndroidBridge::SyncFrameMetrics(const ParentLayerPoint& aScrollOffset, floa
|
||||
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);
|
||||
ViewTransform::LocalRef viewTransform = mLayerClient->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);
|
||||
NS_ABORT_IF_FALSE(viewTransform, "No view transform object!");
|
||||
|
||||
aFixedLayerMargins.top = viewTransform->getfixedLayerMarginTop();
|
||||
aFixedLayerMargins.right = viewTransform->getfixedLayerMarginRight();
|
||||
aFixedLayerMargins.bottom = viewTransform->getfixedLayerMarginBottom();
|
||||
aFixedLayerMargins.left = viewTransform->getfixedLayerMarginLeft();
|
||||
aFixedLayerMargins.top = viewTransform->FixedLayerMarginTop();
|
||||
aFixedLayerMargins.right = viewTransform->FixedLayerMarginRight();
|
||||
aFixedLayerMargins.bottom = viewTransform->FixedLayerMarginBottom();
|
||||
aFixedLayerMargins.left = viewTransform->FixedLayerMarginLeft();
|
||||
|
||||
aOffset.x = viewTransform->getoffsetX();
|
||||
aOffset.y = viewTransform->getoffsetY();
|
||||
|
||||
delete viewTransform;
|
||||
aOffset.x = viewTransform->OffsetX();
|
||||
aOffset.y = viewTransform->OffsetY();
|
||||
}
|
||||
|
||||
AndroidBridge::AndroidBridge()
|
||||
@ -1664,7 +1612,7 @@ AndroidBridge::GetScreenOrientation()
|
||||
{
|
||||
ALOG_BRIDGE("AndroidBridge::GetScreenOrientation");
|
||||
|
||||
int16_t orientation = mozilla::widget::android::GeckoAppShell::GetScreenOrientationWrapper();
|
||||
int16_t orientation = GeckoAppShell::GetScreenOrientationWrapper();
|
||||
|
||||
if (!orientation)
|
||||
return dom::eScreenOrientation_None;
|
||||
@ -1688,20 +1636,13 @@ AndroidBridge::GetProxyForURI(const nsACString & aSpec,
|
||||
if (!HasEnv()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
JNIEnv* env = GetJNIEnv();
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env, 1);
|
||||
jstring jstrRet =
|
||||
mozilla::widget::android::GeckoAppShell::GetProxyForURIWrapper(NS_ConvertUTF8toUTF16(aSpec),
|
||||
NS_ConvertUTF8toUTF16(aScheme),
|
||||
NS_ConvertUTF8toUTF16(aHost),
|
||||
aPort);
|
||||
auto jstrRet = GeckoAppShell::GetProxyForURIWrapper(aSpec, aScheme, aHost, aPort);
|
||||
|
||||
if (!jstrRet)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsJNIString jniStr(jstrRet, env);
|
||||
CopyUTF16toUTF8(jniStr, aResult);
|
||||
aResult = nsCString(jstrRet);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1728,8 +1669,8 @@ AndroidBridge::AddPluginView(jobject view, const LayoutDeviceRect& rect, bool is
|
||||
return;
|
||||
|
||||
CSSRect cssRect = rect / win->GetDefaultScale();
|
||||
mozilla::widget::android::GeckoAppShell::AddPluginViewWrapper(view, cssRect.x, cssRect.y,
|
||||
cssRect.width, cssRect.height, isFullScreen);
|
||||
GeckoAppShell::AddPluginViewWrapper(Object::Ref::From(view), cssRect.x, cssRect.y,
|
||||
cssRect.width, cssRect.height, isFullScreen);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
@ -1740,18 +1681,12 @@ Java_org_mozilla_gecko_GeckoAppShell_allocateDirectBuffer(JNIEnv *env, jclass, j
|
||||
bool
|
||||
AndroidBridge::GetThreadNameJavaProfiling(uint32_t aThreadId, nsCString & aResult)
|
||||
{
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env, 1);
|
||||
|
||||
jstring jstrThreadName =
|
||||
mozilla::widget::android::GeckoJavaSampler::GetThreadNameJavaProfilingWrapper(aThreadId);
|
||||
auto jstrThreadName = GeckoJavaSampler::GetThreadNameJavaProfilingWrapper(aThreadId);
|
||||
|
||||
if (!jstrThreadName)
|
||||
return false;
|
||||
|
||||
nsJNIString jniStr(jstrThreadName, env);
|
||||
CopyUTF16toUTF8(jniStr.get(), aResult);
|
||||
aResult = nsCString(jstrThreadName);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1759,22 +1694,17 @@ bool
|
||||
AndroidBridge::GetFrameNameJavaProfiling(uint32_t aThreadId, uint32_t aSampleId,
|
||||
uint32_t aFrameId, nsCString & aResult)
|
||||
{
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env, 1);
|
||||
|
||||
jstring jstrSampleName = mozilla::widget::android::GeckoJavaSampler::GetFrameNameJavaProfilingWrapper
|
||||
(aThreadId, aSampleId, aFrameId);
|
||||
auto jstrSampleName = GeckoJavaSampler::GetFrameNameJavaProfilingWrapper
|
||||
(aThreadId, aSampleId, aFrameId);
|
||||
|
||||
if (!jstrSampleName)
|
||||
return false;
|
||||
|
||||
nsJNIString jniStr(jstrSampleName, env);
|
||||
CopyUTF16toUTF8(jniStr.get(), aResult);
|
||||
aResult = nsCString(jstrSampleName);
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult AndroidBridge::CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int32_t bufH, int32_t tabId, jobject buffer, bool &shouldStore)
|
||||
nsresult AndroidBridge::CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int32_t bufH, int32_t tabId, Object::Param buffer, bool &shouldStore)
|
||||
{
|
||||
nsresult rv;
|
||||
float scale = 1.0;
|
||||
@ -1848,7 +1778,7 @@ nsresult AndroidBridge::CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int
|
||||
bool is24bit = (GetScreenDepth() == 24);
|
||||
uint32_t stride = bufW * (is24bit ? 4 : 2);
|
||||
|
||||
uint8_t* data = static_cast<uint8_t*>(env->GetDirectBufferAddress(buffer));
|
||||
uint8_t* data = static_cast<uint8_t*>(env->GetDirectBufferAddress(buffer.Get()));
|
||||
if (!data)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
@ -1882,13 +1812,13 @@ AndroidBridge::GetDisplayPort(bool aPageSizeUpdate, bool aIsBrowserContentDispla
|
||||
{
|
||||
|
||||
ALOG_BRIDGE("Enter: %s", __PRETTY_FUNCTION__);
|
||||
JNIEnv* env = GetJNIEnv();
|
||||
if (!mLayerClient || mLayerClient->isNull()) {
|
||||
|
||||
if (!mLayerClient) {
|
||||
ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__);
|
||||
return;
|
||||
}
|
||||
AutoLocalJNIFrame jniFrame(env, 0);
|
||||
|
||||
JNIEnv* const env = GetJNIEnv();
|
||||
AutoLocalJNIFrame jniFrame(env, 1);
|
||||
|
||||
float x, y, width, height,
|
||||
pageLeft, pageTop, pageRight, pageBottom,
|
||||
@ -1908,34 +1838,26 @@ AndroidBridge::GetDisplayPort(bool aPageSizeUpdate, bool aIsBrowserContentDispla
|
||||
metrics->GetCssPageBottom(&cssPageBottom);
|
||||
metrics->GetZoom(&zoom);
|
||||
|
||||
ImmutableViewportMetrics jmetrics = ImmutableViewportMetrics(pageLeft, pageTop, pageRight, pageBottom,
|
||||
cssPageLeft, cssPageTop, cssPageRight, cssPageBottom,
|
||||
x, y, x + width, y + height,
|
||||
zoom);
|
||||
auto jmetrics = ImmutableViewportMetrics::New(
|
||||
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);
|
||||
DisplayPortMetrics::LocalRef displayPortMetrics = mLayerClient->GetDisplayPort(
|
||||
aPageSizeUpdate, aIsBrowserContentDisplayed, tabId, jmetrics);
|
||||
|
||||
AndroidRectF rect(env, displayPortMetrics->getMPosition());
|
||||
if (jniFrame.CheckForException()) {
|
||||
if (!displayPortMetrics) {
|
||||
ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
float resolution = displayPortMetrics->getResolution();
|
||||
if (jniFrame.CheckForException()) {
|
||||
ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__);
|
||||
return;
|
||||
}
|
||||
AndroidRectF rect(env, displayPortMetrics->MPosition().Get());
|
||||
float resolution = displayPortMetrics->Resolution();
|
||||
|
||||
*displayPort = new nsAndroidDisplayport(rect, resolution);
|
||||
(*displayPort)->AddRef();
|
||||
|
||||
delete displayPortMetrics;
|
||||
ALOG_BRIDGE("Exit: %s", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
@ -1958,35 +1880,30 @@ AndroidBridge::IsContentDocumentDisplayed()
|
||||
}
|
||||
|
||||
bool
|
||||
AndroidBridge::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const LayerRect& aDisplayPort, float aDisplayResolution,
|
||||
bool aDrawingCritical, ParentLayerPoint& aScrollOffset, CSSToParentLayerScale& aZoom)
|
||||
AndroidBridge::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
|
||||
const LayerRect& aDisplayPort, float aDisplayResolution,
|
||||
bool aDrawingCritical, ParentLayerPoint& aScrollOffset,
|
||||
CSSToParentLayerScale& aZoom)
|
||||
{
|
||||
mozilla::widget::android::GeckoLayerClient *client = mLayerClient;
|
||||
if (!client) {
|
||||
if (!mLayerClient) {
|
||||
ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
|
||||
jobject progressiveUpdateDataJObj = client->ProgressiveUpdateCallback(aHasPendingNewThebesContent,
|
||||
(float)aDisplayPort.x,
|
||||
(float)aDisplayPort.y,
|
||||
(float)aDisplayPort.width,
|
||||
(float)aDisplayPort.height,
|
||||
aDisplayResolution,
|
||||
!aDrawingCritical);
|
||||
ProgressiveUpdateData::LocalRef progressiveUpdateData =
|
||||
mLayerClient->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!");
|
||||
aScrollOffset.x = progressiveUpdateData->X();
|
||||
aScrollOffset.y = progressiveUpdateData->Y();
|
||||
aZoom.scale = progressiveUpdateData->Scale();
|
||||
|
||||
ProgressiveUpdateData* progressiveUpdateData = ProgressiveUpdateData::Wrap(progressiveUpdateDataJObj);
|
||||
|
||||
aScrollOffset.x = progressiveUpdateData->getx();
|
||||
aScrollOffset.y = progressiveUpdateData->gety();
|
||||
aZoom.scale = progressiveUpdateData->getscale();
|
||||
|
||||
bool ret = progressiveUpdateData->getabort();
|
||||
delete progressiveUpdateData;
|
||||
|
||||
return ret;
|
||||
return progressiveUpdateData->Abort();
|
||||
}
|
||||
|
||||
void
|
||||
@ -2040,30 +1957,31 @@ AndroidBridge::RunDelayedUiThreadTasks()
|
||||
return -1;
|
||||
}
|
||||
|
||||
jobject AndroidBridge::ChannelCreate(jobject stream) {
|
||||
JNIEnv *env = GetJNIForThread();
|
||||
env->PushLocalFrame(1);
|
||||
jobject channel = env->CallStaticObjectMethod(sBridge->jReadableByteChannel, sBridge->jChannelCreate, stream);
|
||||
return env->PopLocalFrame(channel);
|
||||
Object::LocalRef AndroidBridge::ChannelCreate(Object::Param stream) {
|
||||
JNIEnv* const env = GetJNIForThread();
|
||||
auto rv = Object::LocalRef::Adopt(env, env->CallStaticObjectMethod(
|
||||
sBridge->jReadableByteChannel, sBridge->jChannelCreate, stream.Get()));
|
||||
HandleUncaughtException(env);
|
||||
return rv;
|
||||
}
|
||||
|
||||
void AndroidBridge::InputStreamClose(jobject obj) {
|
||||
JNIEnv *env = GetJNIForThread();
|
||||
AutoLocalJNIFrame jniFrame(env, 1);
|
||||
env->CallVoidMethod(obj, sBridge->jClose);
|
||||
void AndroidBridge::InputStreamClose(Object::Param obj) {
|
||||
JNIEnv* const env = GetJNIForThread();
|
||||
env->CallVoidMethod(obj.Get(), sBridge->jClose);
|
||||
HandleUncaughtException(env);
|
||||
}
|
||||
|
||||
uint32_t AndroidBridge::InputStreamAvailable(jobject obj) {
|
||||
JNIEnv *env = GetJNIForThread();
|
||||
AutoLocalJNIFrame jniFrame(env, 1);
|
||||
return env->CallIntMethod(obj, sBridge->jAvailable);
|
||||
uint32_t AndroidBridge::InputStreamAvailable(Object::Param obj) {
|
||||
JNIEnv* const env = GetJNIForThread();
|
||||
auto rv = env->CallIntMethod(obj.Get(), sBridge->jAvailable);
|
||||
HandleUncaughtException(env);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult AndroidBridge::InputStreamRead(jobject obj, char *aBuf, uint32_t aCount, uint32_t *aRead) {
|
||||
JNIEnv *env = GetJNIForThread();
|
||||
AutoLocalJNIFrame jniFrame(env, 1);
|
||||
jobject arr = env->NewDirectByteBuffer(aBuf, aCount);
|
||||
jint read = env->CallIntMethod(obj, sBridge->jByteBufferRead, arr);
|
||||
nsresult AndroidBridge::InputStreamRead(Object::Param obj, char *aBuf, uint32_t aCount, uint32_t *aRead) {
|
||||
JNIEnv* const env = GetJNIForThread();
|
||||
auto arr = Object::LocalRef::Adopt(env, env->NewDirectByteBuffer(aBuf, aCount));
|
||||
jint read = env->CallIntMethod(obj.Get(), sBridge->jByteBufferRead, arr.Get());
|
||||
|
||||
if (env->ExceptionCheck()) {
|
||||
env->ExceptionClear();
|
||||
@ -2079,12 +1997,10 @@ nsresult AndroidBridge::InputStreamRead(jobject obj, char *aBuf, uint32_t aCount
|
||||
}
|
||||
|
||||
nsresult AndroidBridge::GetExternalPublicDirectory(const nsAString& aType, nsAString& aPath) {
|
||||
AutoLocalJNIFrame frame(1);
|
||||
const jstring path = GeckoAppShell::GetExternalPublicDirectory(aType);
|
||||
auto path = GeckoAppShell::GetExternalPublicDirectory(aType);
|
||||
if (!path) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
nsJNIString pathStr(path, frame.GetEnv());
|
||||
aPath.Assign(pathStr);
|
||||
aPath = nsString(path);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "nsCOMArray.h"
|
||||
|
||||
#include "GeneratedJNIWrappers.h"
|
||||
#include "AndroidJavaWrappers.h"
|
||||
|
||||
#include "nsIMutableArray.h"
|
||||
#include "nsIMIMEInfo.h"
|
||||
@ -137,7 +138,7 @@ public:
|
||||
return pthread_equal(pthread_self(), sJavaUiThread);
|
||||
}
|
||||
|
||||
static void ConstructBridge(JNIEnv *jEnv);
|
||||
static void ConstructBridge(JNIEnv *jEnv, jni::Object::Param clsLoader);
|
||||
|
||||
static AndroidBridge *Bridge() {
|
||||
return sBridge;
|
||||
@ -187,7 +188,7 @@ public:
|
||||
bool GetThreadNameJavaProfiling(uint32_t aThreadId, nsCString & aResult);
|
||||
bool GetFrameNameJavaProfiling(uint32_t aThreadId, uint32_t aSampleId, uint32_t aFrameId, nsCString & aResult);
|
||||
|
||||
nsresult CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int32_t bufH, int32_t tabId, jobject buffer, bool &shouldStore);
|
||||
nsresult CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int32_t bufH, int32_t tabId, jni::Object::Param buffer, bool &shouldStore);
|
||||
void GetDisplayPort(bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort);
|
||||
void ContentDocumentChanged();
|
||||
bool IsContentDocumentDisplayed();
|
||||
@ -195,8 +196,8 @@ public:
|
||||
bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const LayerRect& aDisplayPort, float aDisplayResolution, bool aDrawingCritical,
|
||||
mozilla::ParentLayerPoint& aScrollOffset, mozilla::CSSToParentLayerScale& aZoom);
|
||||
|
||||
void SetLayerClient(JNIEnv* env, jobject jobj);
|
||||
mozilla::widget::android::GeckoLayerClient* GetLayerClient() { return mLayerClient; }
|
||||
void SetLayerClient(widget::GeckoLayerClient::Param jobj);
|
||||
const widget::GeckoLayerClient::Ref& GetLayerClient() { return mLayerClient; }
|
||||
|
||||
bool GetHandlersForURL(const nsAString& aURL,
|
||||
nsIMutableArray* handlersArray = nullptr,
|
||||
@ -333,11 +334,11 @@ public:
|
||||
static jmethodID GetMethodID(JNIEnv* env, jclass jClass, const char* methodName, const char* methodType);
|
||||
static jmethodID GetStaticMethodID(JNIEnv* env, jclass jClass, const char* methodName, const char* methodType);
|
||||
|
||||
static jobject ChannelCreate(jobject);
|
||||
static jni::Object::LocalRef ChannelCreate(jni::Object::Param);
|
||||
|
||||
static void InputStreamClose(jobject obj);
|
||||
static uint32_t InputStreamAvailable(jobject obj);
|
||||
static nsresult InputStreamRead(jobject obj, char *aBuf, uint32_t aCount, uint32_t *aRead);
|
||||
static void InputStreamClose(jni::Object::Param obj);
|
||||
static uint32_t InputStreamAvailable(jni::Object::Param obj);
|
||||
static nsresult InputStreamRead(jni::Object::Param obj, char *aBuf, uint32_t aCount, uint32_t *aRead);
|
||||
|
||||
static nsresult GetExternalPublicDirectory(const nsAString& aType, nsAString& aPath);
|
||||
|
||||
@ -353,7 +354,7 @@ protected:
|
||||
JNIEnv *mJNIEnv;
|
||||
pthread_t mThread;
|
||||
|
||||
mozilla::widget::android::GeckoLayerClient *mLayerClient;
|
||||
widget::GeckoLayerClient::GlobalRef mLayerClient;
|
||||
|
||||
// the android.telephony.SmsMessage class
|
||||
jclass mAndroidSmsMessageClass;
|
||||
@ -362,7 +363,7 @@ protected:
|
||||
~AndroidBridge();
|
||||
|
||||
void InitStubs(JNIEnv *jEnv);
|
||||
bool Init(JNIEnv *jEnv);
|
||||
bool Init(JNIEnv *jEnv, jni::Object::Param clsLoader);
|
||||
|
||||
bool mOpenedGraphicsLibraries;
|
||||
void OpenGraphicsLibraries();
|
||||
@ -404,11 +405,14 @@ protected:
|
||||
jclass jLayerView;
|
||||
|
||||
jfieldID jEGLSurfacePointerField;
|
||||
mozilla::widget::android::GLController *mGLControllerObj;
|
||||
widget::GLController::GlobalRef mGLControllerObj;
|
||||
|
||||
// some convinient types to have around
|
||||
jclass jStringClass;
|
||||
|
||||
jni::Object::GlobalRef mClassLoader;
|
||||
jmethodID mClassLoaderLoadClass;
|
||||
|
||||
// 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);
|
||||
|
@ -48,6 +48,7 @@ using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::dom::mobilemessage;
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::widget;
|
||||
using namespace mozilla::widget::android;
|
||||
|
||||
/* Forward declare all the JNI methods as extern "C" */
|
||||
@ -64,9 +65,9 @@ Java_org_mozilla_gecko_GeckoAppShell_registerJavaUiThread(JNIEnv *jenv, jclass j
|
||||
}
|
||||
|
||||
NS_EXPORT void JNICALL
|
||||
Java_org_mozilla_gecko_GeckoAppShell_nativeInit(JNIEnv *jenv, jclass jc)
|
||||
Java_org_mozilla_gecko_GeckoAppShell_nativeInit(JNIEnv *jenv, jclass, jobject clsLoader)
|
||||
{
|
||||
AndroidBridge::ConstructBridge(jenv);
|
||||
AndroidBridge::ConstructBridge(jenv, jni::Object::Ref::From(clsLoader));
|
||||
}
|
||||
|
||||
NS_EXPORT void JNICALL
|
||||
@ -900,11 +901,11 @@ Java_org_mozilla_gecko_gfx_NativePanZoomController_init(JNIEnv* env, jobject ins
|
||||
return;
|
||||
}
|
||||
|
||||
NativePanZoomController* oldRef = APZCCallbackHandler::GetInstance()->SetNativePanZoomController(instance);
|
||||
if (oldRef && !oldRef->isNull()) {
|
||||
MOZ_ASSERT(false, "Registering a new NPZC when we already have one");
|
||||
delete oldRef;
|
||||
}
|
||||
const auto& newRef = NativePanZoomController::Ref::From(instance);
|
||||
NativePanZoomController::LocalRef oldRef =
|
||||
APZCCallbackHandler::GetInstance()->SetNativePanZoomController(newRef);
|
||||
|
||||
MOZ_ASSERT(!oldRef, "Registering a new NPZC when we already have one");
|
||||
}
|
||||
|
||||
NS_EXPORT jboolean JNICALL
|
||||
@ -945,12 +946,10 @@ Java_org_mozilla_gecko_gfx_NativePanZoomController_destroy(JNIEnv* env, jobject
|
||||
return;
|
||||
}
|
||||
|
||||
NativePanZoomController* oldRef = APZCCallbackHandler::GetInstance()->SetNativePanZoomController(nullptr);
|
||||
if (!oldRef || oldRef->isNull()) {
|
||||
MOZ_ASSERT(false, "Clearing a non-existent NPZC");
|
||||
} else {
|
||||
delete oldRef;
|
||||
}
|
||||
NativePanZoomController::LocalRef oldRef =
|
||||
APZCCallbackHandler::GetInstance()->SetNativePanZoomController(nullptr);
|
||||
|
||||
MOZ_ASSERT(oldRef, "Clearing a non-existent NPZC");
|
||||
}
|
||||
|
||||
NS_EXPORT jboolean JNICALL
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::widget::android;
|
||||
|
||||
jclass AndroidGeckoEvent::jGeckoEventClass = 0;
|
||||
jfieldID AndroidGeckoEvent::jActionField = 0;
|
||||
@ -122,7 +121,6 @@ mozilla::InitAndroidJavaWrappers(JNIEnv *jEnv)
|
||||
AndroidRect::InitRectClass(jEnv);
|
||||
AndroidRectF::InitRectFClass(jEnv);
|
||||
AndroidLayerRendererFrame::InitLayerRendererFrameClass(jEnv);
|
||||
InitStubs(jEnv);
|
||||
}
|
||||
|
||||
void
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -15,47 +15,42 @@
|
||||
#include "GeneratedJNIWrappers.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::widget::android;
|
||||
|
||||
class AndroidInputStream : public nsIInputStream
|
||||
{
|
||||
public:
|
||||
AndroidInputStream(jobject connection) {
|
||||
JNIEnv *env = GetJNIForThread();
|
||||
mBridgeInputStream = env->NewGlobalRef(GeckoAppShell::CreateInputStream(connection));
|
||||
mBridgeChannel = env->NewGlobalRef(AndroidBridge::ChannelCreate(mBridgeInputStream));
|
||||
AndroidInputStream(jni::Object::Param connection) {
|
||||
mBridgeInputStream = widget::GeckoAppShell::CreateInputStream(connection);
|
||||
mBridgeChannel = AndroidBridge::ChannelCreate(mBridgeInputStream);
|
||||
}
|
||||
|
||||
private:
|
||||
virtual ~AndroidInputStream() {
|
||||
JNIEnv *env = GetJNIForThread();
|
||||
env->DeleteGlobalRef(mBridgeInputStream);
|
||||
env->DeleteGlobalRef(mBridgeChannel);
|
||||
}
|
||||
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIINPUTSTREAM
|
||||
|
||||
private:
|
||||
jobject mBridgeInputStream;
|
||||
jobject mBridgeChannel;
|
||||
private:
|
||||
jni::Object::GlobalRef mBridgeInputStream;
|
||||
jni::Object::GlobalRef mBridgeChannel;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(AndroidInputStream, nsIInputStream)
|
||||
|
||||
NS_IMETHODIMP AndroidInputStream::Close(void) {
|
||||
mozilla::AndroidBridge::InputStreamClose(mBridgeInputStream);
|
||||
AndroidBridge::InputStreamClose(mBridgeInputStream);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP AndroidInputStream::Available(uint64_t *_retval) {
|
||||
*_retval = mozilla::AndroidBridge::InputStreamAvailable(mBridgeInputStream);
|
||||
*_retval = AndroidBridge::InputStreamAvailable(mBridgeInputStream);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP AndroidInputStream::Read(char *aBuf, uint32_t aCount, uint32_t *_retval) {
|
||||
return mozilla::AndroidBridge::InputStreamRead(mBridgeChannel, aBuf, aCount, _retval);
|
||||
return AndroidBridge::InputStreamRead(mBridgeChannel, aBuf, aCount, _retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP AndroidInputStream::ReadSegments(nsWriteSegmentFun aWriter, void *aClosure, uint32_t aCount, uint32_t *_retval) {
|
||||
@ -71,27 +66,26 @@ NS_IMETHODIMP AndroidInputStream::IsNonBlocking(bool *_retval) {
|
||||
class AndroidChannel : public nsBaseChannel
|
||||
{
|
||||
private:
|
||||
AndroidChannel(nsIURI *aURI, jobject aConnection) {
|
||||
JNIEnv *env = GetJNIForThread();
|
||||
mConnection = env->NewGlobalRef(aConnection);
|
||||
AndroidChannel(nsIURI *aURI, jni::Object::Param aConnection) {
|
||||
mConnection = aConnection;
|
||||
mURI = aURI;
|
||||
nsCString type;
|
||||
jstring jtype = GeckoAppShell::ConnectionGetMimeType(mConnection);
|
||||
if (jtype)
|
||||
SetContentType(nsJNICString(jtype, env));
|
||||
|
||||
auto type = widget::GeckoAppShell::ConnectionGetMimeType(mConnection);
|
||||
if (type) {
|
||||
SetContentType(nsCString(type));
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
static AndroidChannel* CreateChannel(nsIURI *aURI) {
|
||||
nsCString spec;
|
||||
aURI->GetSpec(spec);
|
||||
jobject connection = GeckoAppShell::GetConnection(spec);
|
||||
if (!connection)
|
||||
return NULL;
|
||||
return new AndroidChannel(aURI, connection);
|
||||
|
||||
auto connection = widget::GeckoAppShell::GetConnection(spec);
|
||||
return connection ? new AndroidChannel(aURI, connection) : nullptr;
|
||||
}
|
||||
~AndroidChannel() {
|
||||
JNIEnv *env = GetJNIForThread();
|
||||
env->DeleteGlobalRef(mConnection);
|
||||
|
||||
virtual ~AndroidChannel() {
|
||||
}
|
||||
|
||||
virtual nsresult OpenContentStream(bool async, nsIInputStream **result,
|
||||
@ -100,8 +94,9 @@ public:
|
||||
NS_ADDREF(*result = stream);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
jobject mConnection;
|
||||
jni::Object::GlobalRef mConnection;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsAndroidProtocolHandler,
|
||||
|
@ -80,18 +80,18 @@ public:
|
||||
mBrowserApp(aBrowserApp), mPoints(aPoints), mTabId(aTabId), mBuffer(aBuffer) {}
|
||||
|
||||
virtual nsresult Run() {
|
||||
jobject buffer = mBuffer->GetObject();
|
||||
const auto& buffer = jni::Object::Ref::From(mBuffer->GetObject());
|
||||
nsCOMPtr<nsIDOMWindow> domWindow;
|
||||
nsCOMPtr<nsIBrowserTab> tab;
|
||||
mBrowserApp->GetBrowserTab(mTabId, getter_AddRefs(tab));
|
||||
if (!tab) {
|
||||
mozilla::widget::android::ThumbnailHelper::SendThumbnail(buffer, mTabId, false, false);
|
||||
widget::ThumbnailHelper::SendThumbnail(buffer, mTabId, false, false);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
tab->GetWindow(getter_AddRefs(domWindow));
|
||||
if (!domWindow) {
|
||||
mozilla::widget::android::ThumbnailHelper::SendThumbnail(buffer, mTabId, false, false);
|
||||
widget::ThumbnailHelper::SendThumbnail(buffer, mTabId, false, false);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ public:
|
||||
|
||||
bool shouldStore = true;
|
||||
nsresult rv = AndroidBridge::Bridge()->CaptureThumbnail(domWindow, mPoints[0].x, mPoints[0].y, mTabId, buffer, shouldStore);
|
||||
mozilla::widget::android::ThumbnailHelper::SendThumbnail(buffer, mTabId, NS_SUCCEEDED(rv), shouldStore);
|
||||
widget::ThumbnailHelper::SendThumbnail(buffer, mTabId, NS_SUCCEEDED(rv), shouldStore);
|
||||
return rv;
|
||||
}
|
||||
private:
|
||||
@ -117,7 +117,7 @@ public:
|
||||
NS_DECL_ISUPPORTS;
|
||||
|
||||
nsresult Callback(const nsAString& topic, const nsAString& state) {
|
||||
mozilla::widget::android::GeckoAppShell::NotifyWakeLockChanged(topic, state);
|
||||
widget::GeckoAppShell::NotifyWakeLockChanged(topic, state);
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
@ -312,14 +312,11 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait)
|
||||
break;
|
||||
|
||||
case AndroidGeckoEvent::PROCESS_OBJECT: {
|
||||
JNIEnv* const env = AndroidBridge::Bridge()->GetJNIEnv();
|
||||
AutoLocalJNIFrame frame(env, 1);
|
||||
|
||||
switch (curEvent->Action()) {
|
||||
case AndroidGeckoEvent::ACTION_OBJECT_LAYER_CLIENT:
|
||||
// SetLayerClient expects a local reference
|
||||
const jobject obj = env->NewLocalRef(curEvent->Object().wrappedObject());
|
||||
AndroidBridge::Bridge()->SetLayerClient(env, obj);
|
||||
AndroidBridge::Bridge()->SetLayerClient(
|
||||
widget::GeckoLayerClient::Ref::From(curEvent->Object().wrappedObject()));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -629,8 +626,8 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait)
|
||||
mozilla::dom::GamepadMappingType::Standard,
|
||||
mozilla::dom::kStandardGamepadButtons,
|
||||
mozilla::dom::kStandardGamepadAxes);
|
||||
mozilla::widget::android::GeckoAppShell::GamepadAdded(curEvent->ID(),
|
||||
svc_id);
|
||||
widget::GeckoAppShell::GamepadAdded(curEvent->ID(),
|
||||
svc_id);
|
||||
} else if (curEvent->Action() == AndroidGeckoEvent::ACTION_GAMEPAD_REMOVED) {
|
||||
svc->RemoveGamepad(curEvent->ID());
|
||||
}
|
||||
@ -671,7 +668,7 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait)
|
||||
}
|
||||
|
||||
if (curEvent->AckNeeded()) {
|
||||
mozilla::widget::android::GeckoAppShell::AcknowledgeEvent();
|
||||
widget::GeckoAppShell::AcknowledgeEvent();
|
||||
}
|
||||
|
||||
EVLOG("nsAppShell: -- done event %p %d", (void*)curEvent.get(), curEvent->Type());
|
||||
|
@ -43,7 +43,7 @@ nsClipboard::SetData(nsITransferable *aTransferable,
|
||||
nsAutoString buffer;
|
||||
supportsString->GetData(buffer);
|
||||
|
||||
mozilla::widget::android::Clipboard::SetClipboardText(buffer);
|
||||
widget::Clipboard::SetClipboardText(buffer);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ nsClipboard::EmptyClipboard(int32_t aWhichClipboard)
|
||||
{
|
||||
if (aWhichClipboard != kGlobalClipboard)
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
mozilla::widget::android::Clipboard::ClearText();
|
||||
widget::Clipboard::ClearText();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -97,7 +97,7 @@ nsClipboard::HasDataMatchingFlavors(const char **aFlavorList,
|
||||
*aHasText = false;
|
||||
if (aWhichClipboard != kGlobalClipboard)
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
*aHasText = mozilla::widget::android::Clipboard::HasText();
|
||||
*aHasText = widget::Clipboard::HasText();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,6 @@ nsIMEPicker::~nsIMEPicker()
|
||||
/* void show (); */
|
||||
NS_IMETHODIMP nsIMEPicker::Show()
|
||||
{
|
||||
mozilla::widget::android::GeckoAppShell::ShowInputMethodPicker();
|
||||
widget::GeckoAppShell::ShowInputMethodPicker();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -470,7 +470,7 @@ nsLookAndFeel::GetEchoPasswordImpl()
|
||||
{
|
||||
if (!mInitializedShowPassword) {
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
mShowPassword = mozilla::widget::android::GeckoAppShell::GetShowPasswordSetting();
|
||||
mShowPassword = widget::GeckoAppShell::GetShowPasswordSetting();
|
||||
} else {
|
||||
ContentChild::GetSingleton()->SendGetShowPasswordSetting(&mShowPassword);
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ nsScreenAndroid::GetColorDepth(int32_t *aColorDepth)
|
||||
void
|
||||
nsScreenAndroid::ApplyMinimumBrightness(uint32_t aBrightness)
|
||||
{
|
||||
mozilla::widget::android::GeckoAppShell::SetKeepScreenOn(aBrightness == BRIGHTNESS_FULL);
|
||||
widget::GeckoAppShell::SetKeepScreenOn(aBrightness == BRIGHTNESS_FULL);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsScreenManagerAndroid, nsIScreenManager)
|
||||
|
@ -355,7 +355,7 @@ nsWindow::GetDefaultScaleInternal()
|
||||
return density;
|
||||
}
|
||||
|
||||
density = mozilla::widget::android::GeckoAppShell::GetDensity();
|
||||
density = GeckoAppShell::GetDensity();
|
||||
|
||||
if (!density) {
|
||||
density = 1.0;
|
||||
@ -517,7 +517,7 @@ nsWindow::SetSizeMode(int32_t aMode)
|
||||
{
|
||||
switch (aMode) {
|
||||
case nsSizeMode_Minimized:
|
||||
mozilla::widget::android::GeckoAppShell::MoveTaskToBack();
|
||||
GeckoAppShell::MoveTaskToBack();
|
||||
break;
|
||||
case nsSizeMode_Fullscreen:
|
||||
MakeFullScreen(true);
|
||||
@ -695,7 +695,7 @@ nsWindow::DispatchEvent(WidgetGUIEvent* aEvent)
|
||||
NS_IMETHODIMP
|
||||
nsWindow::MakeFullScreen(bool aFullScreen, nsIScreen*)
|
||||
{
|
||||
mozilla::widget::android::GeckoAppShell::SetFullScreen(aFullScreen);
|
||||
GeckoAppShell::SetFullScreen(aFullScreen);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1110,9 +1110,9 @@ bool nsWindow::OnMultitouchEvent(AndroidGeckoEvent *ae)
|
||||
// previous block should not be default-prevented
|
||||
bool defaultPrevented = isDownEvent ? false : preventDefaultActions;
|
||||
if (ae->Type() == AndroidGeckoEvent::APZ_INPUT_EVENT) {
|
||||
mozilla::widget::android::APZCCallbackHandler::GetInstance()->NotifyDefaultPrevented(ae->ApzInputBlockId(), defaultPrevented);
|
||||
widget::android::APZCCallbackHandler::GetInstance()->NotifyDefaultPrevented(ae->ApzInputBlockId(), defaultPrevented);
|
||||
} else {
|
||||
mozilla::widget::android::GeckoAppShell::NotifyDefaultPrevented(defaultPrevented);
|
||||
GeckoAppShell::NotifyDefaultPrevented(defaultPrevented);
|
||||
}
|
||||
sDefaultPreventedNotified = true;
|
||||
}
|
||||
@ -1123,9 +1123,9 @@ bool nsWindow::OnMultitouchEvent(AndroidGeckoEvent *ae)
|
||||
if (isDownEvent) {
|
||||
if (preventDefaultActions) {
|
||||
if (ae->Type() == AndroidGeckoEvent::APZ_INPUT_EVENT) {
|
||||
mozilla::widget::android::APZCCallbackHandler::GetInstance()->NotifyDefaultPrevented(ae->ApzInputBlockId(), true);
|
||||
widget::android::APZCCallbackHandler::GetInstance()->NotifyDefaultPrevented(ae->ApzInputBlockId(), true);
|
||||
} else {
|
||||
mozilla::widget::android::GeckoAppShell::NotifyDefaultPrevented(true);
|
||||
GeckoAppShell::NotifyDefaultPrevented(true);
|
||||
}
|
||||
sDefaultPreventedNotified = true;
|
||||
} else {
|
||||
@ -1745,11 +1745,11 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *ae)
|
||||
NotifyIMEOfTextChange(notification);
|
||||
FlushIMEChanges();
|
||||
}
|
||||
mozilla::widget::android::GeckoAppShell::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT);
|
||||
GeckoAppShell::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT);
|
||||
return;
|
||||
|
||||
} else if (ae->Action() == AndroidGeckoEvent::IME_UPDATE_CONTEXT) {
|
||||
mozilla::widget::android::GeckoAppShell::NotifyIMEContext(mInputContext.mIMEState.mEnabled,
|
||||
GeckoAppShell::NotifyIMEContext(mInputContext.mIMEState.mEnabled,
|
||||
mInputContext.mHTMLInputType,
|
||||
mInputContext.mHTMLInputInputmode,
|
||||
mInputContext.mActionHint);
|
||||
@ -1762,7 +1762,7 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *ae)
|
||||
if (ae->Action() == AndroidGeckoEvent::IME_SYNCHRONIZE ||
|
||||
ae->Action() == AndroidGeckoEvent::IME_COMPOSE_TEXT ||
|
||||
ae->Action() == AndroidGeckoEvent::IME_REPLACE_TEXT) {
|
||||
mozilla::widget::android::GeckoAppShell::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT);
|
||||
GeckoAppShell::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1777,7 +1777,7 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *ae)
|
||||
case AndroidGeckoEvent::IME_SYNCHRONIZE:
|
||||
{
|
||||
FlushIMEChanges();
|
||||
mozilla::widget::android::GeckoAppShell::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT);
|
||||
GeckoAppShell::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1822,8 +1822,7 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *ae)
|
||||
}
|
||||
mIMEKeyEvents.Clear();
|
||||
FlushIMEChanges();
|
||||
mozilla::widget::android::GeckoAppShell::NotifyIME(
|
||||
AndroidBridge::NOTIFY_IME_REPLY_EVENT);
|
||||
GeckoAppShell::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT);
|
||||
// Break out of the switch block
|
||||
break;
|
||||
}
|
||||
@ -1867,8 +1866,7 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *ae)
|
||||
}
|
||||
|
||||
FlushIMEChanges();
|
||||
mozilla::widget::android::GeckoAppShell::NotifyIME(
|
||||
AndroidBridge::NOTIFY_IME_REPLY_EVENT);
|
||||
GeckoAppShell::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2056,7 +2054,7 @@ nsWindow::NotifyIME(const IMENotification& aIMENotification)
|
||||
case REQUEST_TO_COMMIT_COMPOSITION:
|
||||
//ALOGIME("IME: REQUEST_TO_COMMIT_COMPOSITION: s=%d", aState);
|
||||
RemoveIMEComposition();
|
||||
mozilla::widget::android::GeckoAppShell::NotifyIME(REQUEST_TO_COMMIT_COMPOSITION);
|
||||
GeckoAppShell::NotifyIME(REQUEST_TO_COMMIT_COMPOSITION);
|
||||
return NS_OK;
|
||||
case REQUEST_TO_CANCEL_COMPOSITION:
|
||||
ALOGIME("IME: REQUEST_TO_CANCEL_COMPOSITION");
|
||||
@ -2073,11 +2071,11 @@ nsWindow::NotifyIME(const IMENotification& aIMENotification)
|
||||
DispatchEvent(&compositionCommitEvent);
|
||||
}
|
||||
|
||||
mozilla::widget::android::GeckoAppShell::NotifyIME(REQUEST_TO_CANCEL_COMPOSITION);
|
||||
GeckoAppShell::NotifyIME(REQUEST_TO_CANCEL_COMPOSITION);
|
||||
return NS_OK;
|
||||
case NOTIFY_IME_OF_FOCUS:
|
||||
ALOGIME("IME: NOTIFY_IME_OF_FOCUS");
|
||||
mozilla::widget::android::GeckoAppShell::NotifyIME(NOTIFY_IME_OF_FOCUS);
|
||||
GeckoAppShell::NotifyIME(NOTIFY_IME_OF_FOCUS);
|
||||
return NS_OK;
|
||||
case NOTIFY_IME_OF_BLUR:
|
||||
ALOGIME("IME: NOTIFY_IME_OF_BLUR");
|
||||
@ -2089,7 +2087,7 @@ nsWindow::NotifyIME(const IMENotification& aIMENotification)
|
||||
mIMEComposing = false;
|
||||
mIMEComposingText.Truncate();
|
||||
|
||||
mozilla::widget::android::GeckoAppShell::NotifyIME(NOTIFY_IME_OF_BLUR);
|
||||
GeckoAppShell::NotifyIME(NOTIFY_IME_OF_BLUR);
|
||||
return NS_OK;
|
||||
case NOTIFY_IME_OF_SELECTION_CHANGE:
|
||||
if (mIMEMaskSelectionUpdate) {
|
||||
@ -2151,7 +2149,7 @@ nsWindow::SetInputContext(const InputContext& aContext,
|
||||
|
||||
if (enabled == IMEState::ENABLED && aAction.UserMightRequestOpenVKB()) {
|
||||
// Don't reset keyboard when we should simply open the vkb
|
||||
mozilla::widget::android::GeckoAppShell::NotifyIME(AndroidBridge::NOTIFY_IME_OPEN_VKB);
|
||||
GeckoAppShell::NotifyIME(AndroidBridge::NOTIFY_IME_OPEN_VKB);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2215,9 +2213,8 @@ nsWindow::FlushIMEChanges()
|
||||
return;
|
||||
}
|
||||
|
||||
mozilla::widget::android::GeckoAppShell::NotifyIMEChange(
|
||||
event.mReply.mString, change.mStart,
|
||||
change.mOldEnd, change.mNewEnd);
|
||||
GeckoAppShell::NotifyIMEChange(event.mReply.mString, change.mStart,
|
||||
change.mOldEnd, change.mNewEnd);
|
||||
}
|
||||
mIMETextChanges.Clear();
|
||||
|
||||
@ -2229,9 +2226,9 @@ nsWindow::FlushIMEChanges()
|
||||
if (!event.mSucceeded)
|
||||
return;
|
||||
|
||||
mozilla::widget::android::GeckoAppShell::NotifyIMEChange(EmptyString(),
|
||||
(int32_t) event.GetSelectionStart(),
|
||||
(int32_t) event.GetSelectionEnd(), -1);
|
||||
GeckoAppShell::NotifyIMEChange(EmptyString(),
|
||||
int32_t(event.GetSelectionStart()),
|
||||
int32_t(event.GetSelectionEnd()), -1);
|
||||
mIMESelectionChanged = false;
|
||||
}
|
||||
}
|
||||
@ -2327,23 +2324,20 @@ nsWindow::GetIMEUpdatePreference()
|
||||
void
|
||||
nsWindow::DrawWindowUnderlay(LayerManagerComposite* aManager, nsIntRect aRect)
|
||||
{
|
||||
JNIEnv *env = GetJNIForThread();
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env);
|
||||
|
||||
mozilla::widget::android::GeckoLayerClient* client = AndroidBridge::Bridge()->GetLayerClient();
|
||||
if (!client || client->isNull()) {
|
||||
GeckoLayerClient::LocalRef client = AndroidBridge::Bridge()->GetLayerClient();
|
||||
if (!client) {
|
||||
ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
jobject frameObj = client->CreateFrame();
|
||||
AutoLocalJNIFrame jniFrame(client.Env());
|
||||
auto frameObj = client->CreateFrame();
|
||||
if (!frameObj) {
|
||||
NS_WARNING("Warning: unable to obtain a LayerRenderer frame; aborting window underlay draw");
|
||||
return;
|
||||
}
|
||||
|
||||
mLayerRendererFrame.Init(env, frameObj);
|
||||
mLayerRendererFrame.Init(client.Env(), frameObj.Get());
|
||||
if (!WidgetPaintsBackground()) {
|
||||
return;
|
||||
}
|
||||
@ -2368,17 +2362,14 @@ nsWindow::DrawWindowOverlay(LayerManagerComposite* aManager, nsIntRect aRect)
|
||||
PROFILER_LABEL("nsWindow", "DrawWindowOverlay",
|
||||
js::ProfileEntry::Category::GRAPHICS);
|
||||
|
||||
JNIEnv *env = GetJNIForThread();
|
||||
|
||||
AutoLocalJNIFrame jniFrame(env);
|
||||
|
||||
if (mLayerRendererFrame.isNull()) {
|
||||
NS_WARNING("Warning: do not have a LayerRenderer frame; aborting window overlay draw");
|
||||
return;
|
||||
}
|
||||
|
||||
mozilla::widget::android::GeckoLayerClient* client = AndroidBridge::Bridge()->GetLayerClient();
|
||||
GeckoLayerClient::LocalRef client = AndroidBridge::Bridge()->GetLayerClient();
|
||||
|
||||
AutoLocalJNIFrame jniFrame(client.Env());
|
||||
CompositorOGL *compositor = static_cast<CompositorOGL*>(aManager->GetCompositor());
|
||||
compositor->ResetProgram();
|
||||
gl::GLContext* gl = compositor->gl();
|
||||
@ -2391,7 +2382,7 @@ nsWindow::DrawWindowOverlay(LayerManagerComposite* aManager, nsIntRect aRect)
|
||||
if (!mLayerRendererFrame.EndDrawing(&jniFrame)) return;
|
||||
client->DeactivateProgramAndRestoreState(scissorEnabled,
|
||||
scissorRect[0], scissorRect[1], scissorRect[2], scissorRect[3]);
|
||||
mLayerRendererFrame.Dispose(env);
|
||||
mLayerRendererFrame.Dispose(client.Env());
|
||||
}
|
||||
|
||||
// off-main-thread compositor fields and functions
|
||||
|
@ -29,7 +29,6 @@
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "AndroidBridge.h"
|
||||
using namespace mozilla::widget::android;
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
@ -308,7 +307,7 @@ nsSystemInfo::Init()
|
||||
"android/os/Build", "HARDWARE", str)) {
|
||||
SetPropertyAsAString(NS_LITERAL_STRING("hardware"), str);
|
||||
}
|
||||
bool isTablet = mozilla::widget::android::GeckoAppShell::IsTablet();
|
||||
bool isTablet = mozilla::widget::GeckoAppShell::IsTablet();
|
||||
SetPropertyAsBool(NS_LITERAL_STRING("tablet"), isTablet);
|
||||
// NSPR "version" is the kernel version. For Android we want the Android version.
|
||||
// Rename SDK version to version and put the kernel version into kernel_version.
|
||||
|
@ -579,7 +579,7 @@ ParseManifest(NSLocationType aType, FileLocation& aFile, char* aBuf,
|
||||
mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build$VERSION",
|
||||
"RELEASE",
|
||||
osVersion);
|
||||
isTablet = mozilla::widget::android::GeckoAppShell::IsTablet();
|
||||
isTablet = mozilla::widget::GeckoAppShell::IsTablet();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2058,9 +2058,13 @@ nsLocalFile::Launch()
|
||||
}
|
||||
|
||||
nsAutoCString fileUri = NS_LITERAL_CSTRING("file://") + mPath;
|
||||
return widget::android::GeckoAppShell::OpenUriExternal(
|
||||
return widget::GeckoAppShell::OpenUriExternal(
|
||||
NS_ConvertUTF8toUTF16(fileUri),
|
||||
NS_ConvertUTF8toUTF16(type)) ? NS_OK : NS_ERROR_FAILURE;
|
||||
NS_ConvertUTF8toUTF16(type),
|
||||
EmptyString(),
|
||||
EmptyString(),
|
||||
EmptyString(),
|
||||
EmptyString()) ? NS_OK : NS_ERROR_FAILURE;
|
||||
#elif defined(MOZ_WIDGET_COCOA)
|
||||
CFURLRef url;
|
||||
if (NS_SUCCEEDED(GetCFURL(&url))) {
|
||||
|
Loading…
Reference in New Issue
Block a user