Merge mozilla-central to fx-team

This commit is contained in:
Carsten "Tomcat" Book 2015-01-12 15:15:24 +01:00
commit 4f4c25ed70
554 changed files with 11164 additions and 7403 deletions

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e0c735ec89df011ea7dd435087a9045ecff9ff9e">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e0c735ec89df011ea7dd435087a9045ecff9ff9e">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e0c735ec89df011ea7dd435087a9045ecff9ff9e">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>

View File

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "3bf54932bcae08eb6cab2453a2be007835423cbd",
"revision": "4f9b71ccf0770ad99ba7f802d951f569e10b1021",
"repo_path": "integration/gaia-central"
}

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>

View File

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f5e481d4caf9ffa561720a6fc9cf521a28bd8439"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="b0254d13e67b0bd4c74c2f2c9b9ea1251949d9fe"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cd63c7ae655ee08ffac32ce36a188f8fefc4b272"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -973,7 +973,7 @@
<resources>
<stylesheet src="chrome://browser/skin/searchbar.css"/>
</resources>
<content ignorekeys="true" level="top">
<content ignorekeys="true" level="top" consumeoutsideclicks="never">
<xul:hbox xbl:inherits="collapsed=showonlysettings" anonid="searchbar-engine"
class="search-panel-header search-panel-current-engine">
<xul:image class="searchbar-engine-image" xbl:inherits="src"/>

View File

@ -2,7 +2,7 @@
support-files = head.js
[browser_bug400731.js]
skip-if = e10s
skip-if = (os == "win") || e10s
[browser_bug415846.js]
skip-if = true
# Disabled because it seems to now touch network resources

View File

@ -906,10 +906,6 @@
// ourselves.
popup.hidden = false;
// showHistoryPopup sets consumeoutsideclicks to true so reset it
// here
popup.setAttribute("consumeoutsideclicks", "false");
popup.mInput = this;
popup.view = this.controller.QueryInterface(Components.interfaces.nsITreeView);
popup.invalidate();

View File

@ -8,7 +8,7 @@
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
const DBG_STRINGS_URI = "chrome://browser/locale/devtools/debugger.properties";
const NEW_SOURCE_IGNORED_URLS = ["debugger eval code", "self-hosted", "XStringBundle"];
const NEW_SOURCE_IGNORED_URLS = ["debugger eval code", "XStringBundle"];
const NEW_SOURCE_DISPLAY_DELAY = 200; // ms
const FETCH_SOURCE_RESPONSE_DELAY = 200; // ms
const FETCH_EVENT_LISTENERS_DELAY = 200; // ms

View File

@ -97,7 +97,7 @@ const CONSOLE_API_LEVELS_TO_SEVERITIES = {
};
// Array of known message source URLs we need to hide from output.
const IGNORED_SOURCE_URLS = ["debugger eval code", "self-hosted"];
const IGNORED_SOURCE_URLS = ["debugger eval code"];
// The maximum length of strings to be displayed by the Web Console.
const MAX_LONG_STRING_LENGTH = 200000;

View File

@ -52,7 +52,7 @@ const VARIABLES_VIEW_URL = "chrome://browser/content/devtools/widgets/VariablesV
const CONSOLE_DIR_VIEW_HEIGHT = 0.6;
const IGNORED_SOURCE_URLS = ["debugger eval code", "self-hosted"];
const IGNORED_SOURCE_URLS = ["debugger eval code"];
// The amount of time in milliseconds that we wait before performing a live
// search.

View File

@ -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");
}

View File

@ -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

View File

@ -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()));

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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());
}
}

View File

@ -1,14 +1,14 @@
LOCAL_PATH := $(call my-dir)
# Normally, we distribute the NDK with prebuilt binaries of STLport
# in $LOCAL_PATH/<abi>/. However,
# in $LOCAL_PATH/libs/<abi>/. However,
#
STLPORT_FORCE_REBUILD := $(strip $(STLPORT_FORCE_REBUILD))
ifndef STLPORT_FORCE_REBUILD
ifeq (,$(strip $(wildcard $(LOCAL_PATH)/libs/$(TARGET_ARCH_ABI)/libstlport_static.a)))
ifeq (,$(strip $(wildcard $(LOCAL_PATH)/libs/$(TARGET_ARCH_ABI)/libstlport_static$(TARGET_LIB_EXTENSION))))
$(call __ndk_info,WARNING: Rebuilding STLport libraries from sources!)
$(call __ndk_info,You might want to use $$NDK/build/tools/build-stlport.sh)
$(call __ndk_info,You might want to use $$NDK/build/tools/build-cxx-stl.sh --stl=stlport)
$(call __ndk_info,in order to build prebuilt versions to speed up your builds!)
STLPORT_FORCE_REBUILD := true
endif
@ -65,6 +65,10 @@ libstlport_c_includes := $(libstlport_path)/stlport
include $(dir $(LOCAL_PATH))/gabi++/sources.mk
libstlport_c_includes += $(libgabi++_c_includes)
ifneq ($(strip $(filter-out $(NDK_KNOWN_ARCHS),$(TARGET_ARCH))),)
libgabi++_src_files := src/delete.cc \
src/new.cc
endif
ifneq ($(STLPORT_FORCE_REBUILD),true)
@ -72,14 +76,28 @@ $(call ndk_log,Using prebuilt STLport libraries)
include $(CLEAR_VARS)
LOCAL_MODULE := stlport_static
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/lib$(LOCAL_MODULE).a
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/lib$(LOCAL_MODULE)$(TARGET_LIB_EXTENSION)
# For armeabi*, choose thumb mode unless LOCAL_ARM_MODE := arm
ifneq (,$(filter armeabi%,$(TARGET_ARCH_ABI)))
ifneq (arm,$(LOCAL_ARM_MODE))
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/thumb/lib$(LOCAL_MODULE)$(TARGET_LIB_EXTENSION)
endif
endif
LOCAL_EXPORT_C_INCLUDES := $(libstlport_c_includes)
LOCAL_CPP_FEATURES := rtti
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := stlport_shared
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/lib$(LOCAL_MODULE).so
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/lib$(LOCAL_MODULE)$(TARGET_SONAME_EXTENSION)
# For armeabi*, choose thumb mode unless LOCAL_ARM_MODE := arm
$(info TARGET_ARCH_ABI=$(TARGET_ARCH_ABI))
$(info LOCAL_ARM_MODE=$(LOCAL_ARM_MODE))
ifneq (,$(filter armeabi%,$(TARGET_ARCH_ABI)))
ifneq (arm,$(LOCAL_ARM_MODE))
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/thumb/lib$(LOCAL_MODULE)$(TARGET_SONAME_EXTENSION)
endif
endif
LOCAL_EXPORT_C_INCLUDES := $(libstlport_c_includes)
LOCAL_CPP_FEATURES := rtti
include $(PREBUILT_SHARED_LIBRARY)

View File

@ -1,12 +1,11 @@
This copy of STLport was taken from the Android NDK r8e.
Android specific changes are listed in README.android.
The libs/ directory containing prebuilt static libraries was removed.
This copy of STLport was taken from the Android NDK git repository:
https://android.googlesource.com/platform/ndk.git
under sources/cxx-stl/stlport/.
The last changes to that directory come from commit ba4baa4
The overrides/ directory contains Mozilla-specific overrides to the standard
C++ headers found in the NDK.
The following patches are applied on top:
- android-mozilla-config.patch: Adjusts Android-specific configuration
to the mozilla codebase use of the STL.
- fix-warnings-as-errors.patch: Fixes warnings which were causing the
B2G emulator-ICS build to fail (related to bug 1073003).

View File

@ -1,70 +0,0 @@
# HG changeset patch
# Parent f89b28ea7c7b7fcb54c34e74fcb047626300bfba
# User Dave Hylands <dhylands@mozilla.com>
Bug 1073003 - Fix warnings in stlport causing errors in emulator build.
diff --git a/build/stlport/stlport/stl/_istream.c b/build/stlport/stlport/stl/_istream.c
--- a/build/stlport/stlport/stl/_istream.c
+++ b/build/stlport/stlport/stl/_istream.c
@@ -1140,17 +1140,16 @@ basic_istream<_CharT, _Traits>::ignore(s
template <class _CharT, class _Traits>
basic_istream<_CharT, _Traits>&
basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __delim) {
sentry __sentry(*this, _No_Skip_WS());
this->_M_gcount = 0;
if (__sentry) {
basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();
- typedef _STLP_PRIV _Constant_unary_fun<bool, int_type> _Const_bool;
typedef _STLP_PRIV _Constant_binary_fun<streamsize, streamsize, streamsize>
_Const_streamsize;
const streamsize __maxss = (numeric_limits<streamsize>::max)();
if (__n == (numeric_limits<int>::max)()) {
if (__buf->gptr() != __buf->egptr())
_M_gcount = _M_ignore_buffered(this, __buf,
__maxss, _Const_streamsize(__maxss),
diff --git a/build/stlport/stlport/stl/_slist.c b/build/stlport/stlport/stl/_slist.c
--- a/build/stlport/stlport/stl/_slist.c
+++ b/build/stlport/stlport/stl/_slist.c
@@ -143,17 +143,16 @@ void _Slist_unique(slist<_Tp, _Alloc>& _
}
}
}
template <class _Tp, class _Alloc, class _StrictWeakOrdering>
void _Slist_merge(slist<_Tp, _Alloc>& __that, slist<_Tp, _Alloc>& __x,
_StrictWeakOrdering __comp) {
typedef _Slist_node<_Tp> _Node;
- typedef _STLP_PRIV _Slist_node_base _Node_base;
if (__that.get_allocator() == __x.get_allocator()) {
typename slist<_Tp, _Alloc>::iterator __ite(__that.before_begin());
while (__ite._M_node->_M_next && !__x.empty()) {
if (__comp(__x.front(), __STATIC_CAST(_Node*, __ite._M_node->_M_next)->_M_data)) {
_STLP_VERBOSE_ASSERT(!__comp(__STATIC_CAST(_Node*, __ite._M_node->_M_next)->_M_data, __x.front()),
_StlMsg_INVALID_STRICT_WEAK_PREDICATE)
__that.splice_after(__ite, __x, __x.before_begin());
}
diff --git a/build/stlport/stlport/stl/config/features.h b/build/stlport/stlport/stl/config/features.h
--- a/build/stlport/stlport/stl/config/features.h
+++ b/build/stlport/stlport/stl/config/features.h
@@ -303,17 +303,18 @@
# undef _STLP_NO_DEFAULT_NON_TYPE_PARAM
# define _STLP_NO_DEFAULT_NON_TYPE_PARAM 1
#endif
#if !defined (_STLP_STATIC_ASSERT)
/* Some compiler support 0 size array so we use negative size array to generate
* a compilation time error.
*/
-# define _STLP_STATIC_ASSERT(expr) typedef char __static_assert[expr ? 1 : -1];
+//# define _STLP_STATIC_ASSERT(expr) typedef char __static_assert[expr ? 1 : -1];
+# define _STLP_STATIC_ASSERT(expr) static_assert(expr, "static_assert failed");
#endif
/* apple mpw exception handling bug */
#ifndef _STLP_MPWFIX_TRY
# define _STLP_MPWFIX_TRY
#endif
#ifndef _STLP_MPWFIX_CATCH
# define _STLP_MPWFIX_CATCH

View File

@ -64,7 +64,7 @@ __Named_exception::__Named_exception(const __Named_exception& __x) {
__Named_exception& __Named_exception::operator = (const __Named_exception& __x) {
size_t __size = strlen(__x._M_name) + 1;
size_t __buf_size = _M_name != _M_static_name ? *(__REINTERPRET_CAST(size_t*, &_M_static_name[0])) : _S_bufsize;
size_t __buf_size = _M_name != _M_static_name ? *(__REINTERPRET_CAST(size_t*, &_M_static_name[0])) : static_cast<size_t>(_S_bufsize);
if (__size > __buf_size) {
// Being here necessarily mean that we need to allocate a buffer:
if (_M_name != _M_static_name) free(_M_name);

View File

@ -151,7 +151,6 @@ __get_formatted_time _STLP_WEAK (_InIt1 __first, _InIt1 __last,
_Ch*, const _TimeInfo& __table,
const ios_base& __s, ios_base::iostate& __err, tm* __t) {
const ctype<_Ch>& __ct = use_facet<ctype<_Ch> >(__s.getloc());
typedef basic_string<_Ch, char_traits<_Ch>, allocator<_Ch> > string_type;
size_t offset;
while (__first != __last && __format != __format_end) {

View File

@ -52,7 +52,7 @@
// The system math library doesn't have long double variants, e.g
// sinl, cosl, etc
#define _STLP_NO_VENDOR_MATH_L 1
#define _STLP_NO_VENDOR_MATH_L
// Include most of the gcc settings.
#include <stl/config/_gcc.h>

View File

@ -115,6 +115,7 @@
((defined(__sparc) || defined(__sparcv9) || defined(__sparcv8plus)) && !defined ( __WORD64 ) && !defined(__arch64__)) /* ? */ || \
(defined(_MIPS_SIM) && (_MIPS_SIM == _ABIO32)) || \
defined(__arm__) || \
defined(__le32__) || \
defined(__sh__)
/* # if defined(__NO_LONG_DOUBLE_MATH) */
# define _STLP_NO_LONG_DOUBLE

View File

@ -308,8 +308,7 @@
/* Some compiler support 0 size array so we use negative size array to generate
* a compilation time error.
*/
//# define _STLP_STATIC_ASSERT(expr) typedef char __static_assert[expr ? 1 : -1];
# define _STLP_STATIC_ASSERT(expr) static_assert(expr, "static_assert failed");
# define _STLP_STATIC_ASSERT(expr) typedef char __static_assert[expr ? 1 : -1] __attribute__((unused));
#endif
/* apple mpw exception handling bug */
@ -1053,7 +1052,7 @@ _TMPL inline bool _STLP_CALL operator>=(const _TP& __x, const _TP& __y) { return
#define _STLP_ARRAY_AND_SIZE(A) A, sizeof(A) / sizeof(A[0])
#if !defined (_STLP_MARK_PARAMETER_AS_UNUSED)
# define _STLP_MARK_PARAMETER_AS_UNUSED(X) (void*)X;
# define _STLP_MARK_PARAMETER_AS_UNUSED(X) (void)X;
#endif
#if defined (_STLP_CHECK_RUNTIME_COMPATIBILITY)

View File

@ -80,7 +80,7 @@
/* __EDG_VERSION__ is an official EDG macro, compilers based
* on EDG have to define it. */
#if defined (__EDG_VERSION__)
# if (__EDG_VERSION__ >= 244) && !defined (_STLP_HAS_INCLUDE_NEXT)
# if (__EDG_VERSION__ >= 244) && !defined (_STLP_HAS_INCLUDE_NEXT) && !defined(__ANDROID__)
# define _STLP_HAS_INCLUDE_NEXT
# endif
# if (__EDG_VERSION__ <= 240) && !defined (_STLP_DONT_RETURN_VOID)

View File

@ -2,8 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/NullPtr.h"
#include <stdexcept>
#include <list>
#include <vector>

View File

@ -290,6 +290,7 @@ if test -n "$gonkdir" ; then
AC_SUBST(MOZ_AUDIO_OFFLOAD)
AC_DEFINE(MOZ_AUDIO_OFFLOAD)
MOZ_FMP4=
MOZ_B2G_CAMERA=1
MOZ_B2G_BT=1
MOZ_B2G_BT_BLUEDROID=1
if test -d "$gonkdir/system/bluetoothd"; then
@ -3385,6 +3386,19 @@ MOZ_CHECK_HEADERS(alloca.h)
AC_CHECK_FUNCS(strndup posix_memalign memalign)
AC_CHECK_FUNCS(malloc_usable_size)
MALLOC_USABLE_SIZE_CONST_PTR=const
MOZ_CHECK_HEADERS([malloc.h], [
AC_MSG_CHECKING([whether malloc_usable_size definition can use const argument])
AC_TRY_COMPILE([#include <malloc.h>
#include <stddef.h>
size_t malloc_usable_size(const void *ptr);],
[return malloc_usable_size(0);],
AC_MSG_RESULT([yes]),
AC_MSG_RESULT([no])
MALLOC_USABLE_SIZE_CONST_PTR=)
])
AC_DEFINE_UNQUOTED([MALLOC_USABLE_SIZE_CONST_PTR],[$MALLOC_USABLE_SIZE_CONST_PTR])
dnl In newer bionic headers, valloc is built but not defined,
dnl so we check more carefully here.

View File

@ -5162,6 +5162,15 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI,
// Display the error as a page or an alert prompt
NS_ENSURE_FALSE(messageStr.IsEmpty(), NS_ERROR_FAILURE);
if (NS_ERROR_NET_INTERRUPT == aError || NS_ERROR_NET_RESET == aError) {
bool isSecureURI = false;
rv = aURI->SchemeIs("https", &isSecureURI);
if (NS_SUCCEEDED(rv) && isSecureURI) {
// Maybe TLS intolerant. Treat this as an SSL error.
error.AssignLiteral("nssFailure2");
}
}
if (UseErrorPages()) {
// Display an error page
LoadErrorPage(aURI, aURL, errorPage.get(), error.get(),

View File

@ -48,7 +48,7 @@ ArchiveReader::Constructor(const GlobalObject& aGlobal,
ArchiveReader::ArchiveReader(File& aBlob, nsPIDOMWindow* aWindow,
const nsACString& aEncoding)
: mBlob(&aBlob)
: mFileImpl(aBlob.Impl())
, mWindow(aWindow)
, mStatus(NOT_STARTED)
, mEncoding(aEncoding)
@ -95,7 +95,7 @@ nsresult
ArchiveReader::GetInputStream(nsIInputStream** aInputStream)
{
// Getting the input stream
mBlob->GetInternalStream(aInputStream);
mFileImpl->GetInternalStream(aInputStream);
NS_ENSURE_TRUE(*aInputStream, NS_ERROR_UNEXPECTED);
return NS_OK;
}
@ -103,9 +103,9 @@ ArchiveReader::GetInputStream(nsIInputStream** aInputStream)
nsresult
ArchiveReader::GetSize(uint64_t* aSize)
{
nsresult rv = mBlob->GetSize(aSize);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
ErrorResult rv;
*aSize = mFileImpl->GetSize(rv);
return rv.ErrorCode();
}
// Here we open the archive:
@ -199,7 +199,7 @@ ArchiveReader::GenerateArchiveRequest()
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ArchiveReader,
mBlob,
mFileImpl,
mWindow,
mData.fileList,
mRequests)

View File

@ -20,6 +20,7 @@ namespace mozilla {
namespace dom {
struct ArchiveReaderOptions;
class File;
class FileImpl;
class GlobalObject;
} // namespace dom
} // namespace mozilla
@ -49,6 +50,7 @@ public:
{
return mWindow;
}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
already_AddRefed<ArchiveRequest> GetFilenames();
@ -62,6 +64,11 @@ public: // for the ArchiveRequest:
nsresult RegisterRequest(ArchiveRequest* aRequest);
public: // For events:
FileImpl* GetFileImpl() const
{
return mFileImpl;
}
void Ready(nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList,
nsresult aStatus);
@ -76,7 +83,7 @@ private:
protected:
// The archive blob/file
nsRefPtr<File> mBlob;
nsRefPtr<FileImpl> mFileImpl;
// The window is needed by the requests
nsCOMPtr<nsPIDOMWindow> mWindow;

View File

@ -88,7 +88,7 @@ ArchiveZipItem::File(ArchiveReader* aArchiveReader)
new ArchiveZipFileImpl(filename,
NS_ConvertUTF8toUTF16(GetType()),
StrToInt32(mCentralStruct.orglen),
mCentralStruct, aArchiveReader));
mCentralStruct, aArchiveReader->GetFileImpl()));
}
uint32_t

View File

@ -362,13 +362,15 @@ ArchiveZipFileImpl::GetInternalStream(nsIInputStream** aStream)
return NS_ERROR_FAILURE;
}
uint64_t size;
nsresult rv = mArchiveReader->GetSize(&size);
NS_ENSURE_SUCCESS(rv, rv);
ErrorResult rv;
uint64_t size = mFileImpl->GetSize(rv);
if (NS_WARN_IF(rv.Failed())) {
return rv.ErrorCode();
}
nsCOMPtr<nsIInputStream> inputStream;
rv = mArchiveReader->GetInputStream(getter_AddRefs(inputStream));
if (NS_FAILED(rv) || !inputStream) {
rv = mFileImpl->GetInternalStream(getter_AddRefs(inputStream));
if (NS_WARN_IF(rv.Failed()) || !inputStream) {
return NS_ERROR_UNEXPECTED;
}
@ -383,20 +385,6 @@ ArchiveZipFileImpl::GetInternalStream(nsIInputStream** aStream)
return NS_OK;
}
void
ArchiveZipFileImpl::Unlink()
{
ArchiveZipFileImpl* tmp = this;
NS_IMPL_CYCLE_COLLECTION_UNLINK(mArchiveReader);
}
void
ArchiveZipFileImpl::Traverse(nsCycleCollectionTraversalCallback &cb)
{
ArchiveZipFileImpl* tmp = this;
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mArchiveReader);
}
already_AddRefed<mozilla::dom::FileImpl>
ArchiveZipFileImpl::CreateSlice(uint64_t aStart,
uint64_t aLength,
@ -405,7 +393,7 @@ ArchiveZipFileImpl::CreateSlice(uint64_t aStart,
{
nsRefPtr<FileImpl> impl =
new ArchiveZipFileImpl(mFilename, mContentType, aStart, mLength, mCentral,
mArchiveReader);
mFileImpl);
return impl.forget();
}

View File

@ -30,13 +30,13 @@ public:
const nsAString& aContentType,
uint64_t aLength,
ZipCentral& aCentral,
ArchiveReader* aReader)
FileImpl* aFileImpl)
: FileImplBase(aName, aContentType, aLength),
mCentral(aCentral),
mArchiveReader(aReader),
mFileImpl(aFileImpl),
mFilename(aName)
{
NS_ASSERTION(mArchiveReader, "must have a reader");
MOZ_ASSERT(mFileImpl);
MOZ_COUNT_CTOR(ArchiveZipFileImpl);
}
@ -45,27 +45,18 @@ public:
uint64_t aStart,
uint64_t aLength,
ZipCentral& aCentral,
ArchiveReader* aReader)
FileImpl* aFileImpl)
: FileImplBase(aContentType, aStart, aLength),
mCentral(aCentral),
mArchiveReader(aReader),
mFileImpl(aFileImpl),
mFilename(aName)
{
NS_ASSERTION(mArchiveReader, "must have a reader");
MOZ_ASSERT(mFileImpl);
MOZ_COUNT_CTOR(ArchiveZipFileImpl);
}
// Overrides:
virtual nsresult GetInternalStream(nsIInputStream**) MOZ_OVERRIDE;
virtual void Unlink() MOZ_OVERRIDE;
virtual void Traverse(nsCycleCollectionTraversalCallback &aCb) MOZ_OVERRIDE;
virtual bool IsCCed() const MOZ_OVERRIDE
{
return true;
}
protected:
virtual ~ArchiveZipFileImpl()
{
@ -78,7 +69,7 @@ protected:
private: // Data
ZipCentral mCentral;
nsRefPtr<ArchiveReader> mArchiveReader;
nsRefPtr<FileImpl> mFileImpl;
nsString mFilename;
};

View File

@ -5,7 +5,6 @@
#include "jsfriendapi.h"
#include "nsCOMPtr.h"
#include "nsIRandomGenerator.h"
#include "nsPIDOMWindow.h"
#include "MainThreadUtils.h"
#include "nsXULAppAPI.h"
@ -27,7 +26,7 @@ NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(Crypto)
NS_IMPL_CYCLE_COLLECTING_RELEASE(Crypto)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Crypto, mWindow, mSubtle)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Crypto, mParent, mSubtle)
Crypto::Crypto()
{
@ -40,10 +39,10 @@ Crypto::~Crypto()
}
void
Crypto::Init(nsIDOMWindow* aWindow)
Crypto::Init(nsIGlobalObject* aParent)
{
mWindow = do_QueryInterface(aWindow);
MOZ_ASSERT(mWindow);
mParent = do_QueryInterface(aParent);
MOZ_ASSERT(mParent);
}
/* virtual */ JSObject*
@ -54,8 +53,8 @@ Crypto::WrapObject(JSContext* aCx)
void
Crypto::GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv)
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv)
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Called on the wrong thread");

View File

@ -6,7 +6,7 @@
#include "nsIDOMCrypto.h"
#include "mozilla/dom/SubtleCrypto.h"
#include "nsPIDOMWindow.h"
#include "nsIGlobalObject.h"
#include "nsWrapperCache.h"
#include "mozilla/dom/TypedArray.h"
@ -35,18 +35,18 @@ public:
void
GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv);
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv);
SubtleCrypto*
Subtle();
// WebIDL
nsPIDOMWindow*
nsIGlobalObject*
GetParentObject() const
{
return mWindow;
return mParent;
}
virtual JSObject*
@ -56,7 +56,7 @@ public:
GetRandomValues(uint32_t aLength);
private:
nsCOMPtr<nsPIDOMWindow> mWindow;
nsCOMPtr<nsIGlobalObject> mParent;
nsRefPtr<SubtleCrypto> mSubtle;
};

View File

@ -129,15 +129,14 @@ nsresult DataOwnerAdapter::Create(DataOwner* aDataOwner,
NS_IMPL_CYCLE_COLLECTION_CLASS(File)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(File)
MOZ_ASSERT(tmp->mImpl);
tmp->mImpl->Unlink();
// No unlink for mImpl bacause FileImpl is not CC-able.
tmp->mImpl = nullptr;
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(File)
MOZ_ASSERT(tmp->mImpl);
tmp->mImpl->Traverse(cb);
// No traverse for mImpl bacause FileImpl is not CC-able.
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@ -718,7 +717,7 @@ FileImpl::Slice(const Optional<int64_t>& aStart,
////////////////////////////////////////////////////////////////////////////
// FileImpl implementation
NS_IMPL_ISUPPORTS(FileImpl, PIFileImpl)
NS_IMPL_ISUPPORTS(FileImpl, FileImpl)
////////////////////////////////////////////////////////////////////////////
// FileImplFile implementation

View File

@ -34,17 +34,9 @@ class nsIFile;
class nsIInputStream;
class nsIClassInfo;
#define PIFILEIMPL_IID \
{ 0x218ee173, 0xf44f, 0x4d30, \
{ 0xab, 0x0c, 0xd6, 0x66, 0xea, 0xc2, 0x84, 0x47 } }
class PIFileImpl : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(PIFILEIMPL_IID)
};
NS_DEFINE_STATIC_IID_ACCESSOR(PIFileImpl, PIFILEIMPL_IID)
#define FILEIMPL_IID \
{ 0xbccb3275, 0x6778, 0x4ac5, \
{ 0xaf, 0x03, 0x90, 0xed, 0x37, 0xad, 0xdf, 0x5d } }
namespace mozilla {
namespace dom {
@ -223,16 +215,17 @@ private:
// It's thread-safe and not CC-able and it's the only element that is moved
// between threads.
// Note: we should not store any other state in this class!
const nsRefPtr<FileImpl> mImpl;
nsRefPtr<FileImpl> mImpl;
nsCOMPtr<nsISupports> mParent;
};
// This is the abstract class for any File backend. It must be nsISupports
// because this class must be ref-counted and it has to work with IPC.
class FileImpl : public PIFileImpl
class FileImpl : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(FILEIMPL_IID)
NS_DECL_THREADSAFE_ISUPPORTS
FileImpl() {}
@ -293,19 +286,18 @@ public:
virtual bool IsFile() const = 0;
// These 2 methods are used when the implementation has to CC something.
virtual void Unlink() = 0;
virtual void Traverse(nsCycleCollectionTraversalCallback &aCb) = 0;
virtual bool IsCCed() const
// True if this implementation can be sent to other threads.
virtual bool MayBeClonedToOtherThreads() const
{
return false;
return true;
}
protected:
virtual ~FileImpl() {}
};
NS_DEFINE_STATIC_IID_ACCESSOR(FileImpl, FILEIMPL_IID)
class FileImplBase : public FileImpl
{
public:
@ -465,9 +457,6 @@ public:
return mLength == UINT64_MAX;
}
virtual void Unlink() MOZ_OVERRIDE {}
virtual void Traverse(nsCycleCollectionTraversalCallback &aCb) MOZ_OVERRIDE {}
protected:
virtual ~FileImplBase() {}

View File

@ -154,7 +154,8 @@ nsIContent::GetFlattenedTreeParent() const
{
nsIContent* parent = GetParent();
if (nsContentUtils::HasDistributedChildren(parent)) {
if (parent && nsContentUtils::HasDistributedChildren(parent) &&
nsContentUtils::IsInSameAnonymousTree(parent, this)) {
// This node is distributed to insertion points, thus we
// need to consult the destination insertion points list to
// figure out where this node was inserted in the flattened tree.
@ -2109,7 +2110,7 @@ private:
uint32_t mLength;
};
public:
StringBuilder() : mLast(MOZ_THIS_IN_INITIALIZER_LIST()), mLength(0)
StringBuilder() : mLast(this), mLength(0)
{
MOZ_COUNT_CTOR(StringBuilder);
}

View File

@ -293,7 +293,7 @@ ImportLoader::ImportLoader(nsIURI* aURI, nsIDocument* aImportParent)
, mReady(false)
, mStopped(false)
, mBlockingScripts(false)
, mUpdater(MOZ_THIS_IN_INITIALIZER_LIST())
, mUpdater(this)
{
}

View File

@ -352,3 +352,15 @@ MultipartFileImpl::InitializeChromeFile(nsPIDOMWindow* aWindow,
InitializeChromeFile(aWindow, file, aBag, false, aRv);
}
bool
MultipartFileImpl::MayBeClonedToOtherThreads() const
{
for (uint32_t i = 0; i < mBlobImpls.Length(); ++i) {
if (!mBlobImpls[i]->MayBeClonedToOtherThreads()) {
return false;
}
}
return true;
}

View File

@ -111,6 +111,8 @@ public:
mIsFromNsIFile = aValue;
}
virtual bool MayBeClonedToOtherThreads() const MOZ_OVERRIDE;
protected:
virtual ~MultipartFileImpl() {}

View File

@ -588,8 +588,12 @@ ShadowRoot::IsPooledNode(nsIContent* aContent, nsIContent* aContainer,
return false;
}
if (aContainer == aHost) {
// Any other child nodes of the host will end up in the pool.
if (aContainer == aHost &&
nsContentUtils::IsInSameAnonymousTree(aContainer, aContent)) {
// Children of the host will end up in the pool. We check to ensure
// that the content is in the same anonymous tree as the container
// because anonymous content may report its container as the host
// but it may not be in the host's child list.
return true;
}

View File

@ -13,7 +13,7 @@
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(SubtleCrypto, mWindow)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(SubtleCrypto, mParent)
NS_IMPL_CYCLE_COLLECTING_ADDREF(SubtleCrypto)
NS_IMPL_CYCLE_COLLECTING_RELEASE(SubtleCrypto)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SubtleCrypto)
@ -23,8 +23,8 @@ NS_INTERFACE_MAP_END
SubtleCrypto::SubtleCrypto(nsPIDOMWindow* aWindow)
: mWindow(aWindow)
SubtleCrypto::SubtleCrypto(nsIGlobalObject* aParent)
: mParent(aParent)
{
}
@ -35,9 +35,8 @@ SubtleCrypto::WrapObject(JSContext* aCx)
}
#define SUBTLECRYPTO_METHOD_BODY(Operation, aRv, ...) \
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mWindow); \
MOZ_ASSERT(global); \
nsRefPtr<Promise> p = Promise::Create(global, aRv); \
MOZ_ASSERT(mParent); \
nsRefPtr<Promise> p = Promise::Create(mParent, aRv); \
if (aRv.Failed()) { \
return nullptr; \
} \

View File

@ -9,7 +9,7 @@
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
#include "nsPIDOMWindow.h"
#include "nsIGlobalObject.h"
#include "mozilla/dom/CryptoKey.h"
#include "js/TypeDecls.h"
@ -31,11 +31,11 @@ public:
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(SubtleCrypto)
public:
explicit SubtleCrypto(nsPIDOMWindow* aWindow);
explicit SubtleCrypto(nsIGlobalObject* aParent);
nsPIDOMWindow* GetParentObject() const
nsIGlobalObject* GetParentObject() const
{
return mWindow;
return mParent;
}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
@ -119,7 +119,7 @@ public:
ErrorResult& aRv);
private:
nsCOMPtr<nsPIDOMWindow> mWindow;
nsCOMPtr<nsIGlobalObject> mParent;
};
} // namespace dom

View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<body>
<style>
#foo {
overflow: scroll;
height: 100px;
}
</style>
<div id="foo">
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
Mozilla Firefox<br>
<script>
foo.createShadowRoot().innerHTML = "<content></content>";
</script>
</body>
</html>

View File

@ -3992,6 +3992,30 @@ nsDOMWindowUtils::AskPermission(nsIContentPermissionRequest* aRequest)
return nsContentPermissionUtils::AskPermission(aRequest, window->GetCurrentInnerWindow());
}
NS_IMETHODIMP
nsDOMWindowUtils::GetFramesConstructed(uint64_t* aResult)
{
nsPresContext* presContext = GetPresContext();
if (!presContext) {
return NS_ERROR_NOT_AVAILABLE;
}
*aResult = presContext->FramesConstructedCount();
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::GetFramesReflowed(uint64_t* aResult)
{
nsPresContext* presContext = GetPresContext();
if (!presContext) {
return NS_ERROR_NOT_AVAILABLE;
}
*aResult = presContext->FramesReflowedCount();
return NS_OK;
}
NS_INTERFACE_MAP_BEGIN(nsTranslationNodeList)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY(nsITranslationNodeList)

View File

@ -499,8 +499,8 @@ nsHostObjectProtocolHandler::NewChannel2(nsIURI* uri,
return NS_ERROR_DOM_BAD_URI;
}
nsCOMPtr<PIFileImpl> blobImpl = do_QueryInterface(info->mObject);
if (!blobImpl) {
nsCOMPtr<FileImpl> blob = do_QueryInterface(info->mObject);
if (!blob) {
return NS_ERROR_DOM_BAD_URI;
}
@ -513,7 +513,6 @@ nsHostObjectProtocolHandler::NewChannel2(nsIURI* uri,
}
#endif
FileImpl* blob = static_cast<FileImpl*>(blobImpl.get());
nsCOMPtr<nsIInputStream> stream;
nsresult rv = blob->GetInternalStream(getter_AddRefs(stream));
NS_ENSURE_SUCCESS(rv, rv);
@ -615,12 +614,11 @@ NS_GetBlobForBlobURI(nsIURI* aURI, FileImpl** aBlob)
*aBlob = nullptr;
nsCOMPtr<PIFileImpl> blobImpl = do_QueryInterface(GetDataObject(aURI));
if (!blobImpl) {
nsCOMPtr<FileImpl> blob = do_QueryInterface(GetDataObject(aURI));
if (!blob) {
return NS_ERROR_DOM_BAD_URI;
}
nsRefPtr<FileImpl> blob = static_cast<FileImpl*>(blobImpl.get());
blob.forget(aBlob);
return NS_OK;
}

View File

@ -317,7 +317,7 @@ public:
mNextSibling(nullptr),
mPreviousSibling(nullptr),
mFirstChild(nullptr),
mSubtreeRoot(MOZ_THIS_IN_INITIALIZER_LIST()),
mSubtreeRoot(this),
mSlots(nullptr)
{
}

View File

@ -14347,6 +14347,13 @@ class GlobalGenRoots():
# Done.
return curr
@staticmethod
def GeneratedEventList(config):
eventList = CGList([]);
for generatedEvent in config.generatedEvents:
eventList.append(CGGeneric(declare=("GENERATED_EVENT(%s)\n" % generatedEvent)))
return eventList
@staticmethod
def PrototypeList(config):
@ -14909,7 +14916,8 @@ class CGEventClass(CGBindingImplClass):
[],
virtual=True,
body="return this;\n",
breakAfterReturnDecl=" ")
breakAfterReturnDecl=" ",
override=True)
CGClass.__init__(self, className,
bases=[ClassBase(self.parentType)],

View File

@ -13,7 +13,7 @@ class Configuration:
Represents global configuration state based on IDL parse data and
the configuration file.
"""
def __init__(self, filename, parseData):
def __init__(self, filename, parseData, generatedEvents=[]):
# Read the configuration file.
glbl = {}
@ -25,6 +25,7 @@ class Configuration:
# |parseData|.
self.descriptors = []
self.interfaces = {}
self.generatedEvents = generatedEvents;
self.maxProtoChainLength = 0;
for thing in parseData:
if isinstance(thing, IDLImplementsStatement):

View File

@ -136,7 +136,6 @@ private:
TypedArray_base(const TypedArray_base&) = delete;
};
template<typename T,
JSObject* UnwrapArray(JSObject*),
T* GetData(JSObject*, const JS::AutoCheckCannotGC&),
@ -301,16 +300,14 @@ class MOZ_STACK_CLASS RootedTypedArray : public ArrayType,
public:
explicit RootedTypedArray(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
ArrayType(),
TypedArrayRooter<ArrayType>(cx,
MOZ_THIS_IN_INITIALIZER_LIST()
TypedArrayRooter<ArrayType>(cx, this
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT)
{
}
RootedTypedArray(JSContext* cx, JSObject* obj MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
ArrayType(obj),
TypedArrayRooter<ArrayType>(cx,
MOZ_THIS_IN_INITIALIZER_LIST()
TypedArrayRooter<ArrayType>(cx, this
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT)
{
}

View File

@ -129,6 +129,7 @@ class WebIDLCodegenManager(LoggingMixin):
GLOBAL_DECLARE_FILES = {
'FeatureList.h',
'GeneratedAtomList.h',
'GeneratedEventList.h',
'PrototypeList.h',
'RegisterBindings.h',
'RegisterWorkerBindings.h',
@ -175,6 +176,7 @@ class WebIDLCodegenManager(LoggingMixin):
self._input_paths = set(input_paths)
self._exported_stems = set(exported_stems)
self._generated_events_stems = set(generated_events_stems)
self._generated_events_stems_as_array = generated_events_stems;
self._example_interfaces = set(example_interfaces)
self._exported_header_dir = exported_header_dir
self._codegen_dir = codegen_dir
@ -324,7 +326,8 @@ class WebIDLCodegenManager(LoggingMixin):
parser.parse(data, path)
self._parser_results = parser.finish()
self._config = Configuration(self._config_path, self._parser_results)
self._config = Configuration(self._config_path, self._parser_results,
self._generated_events_stems_as_array)
self._input_hashes = hashes
def _write_global_derived(self):

View File

@ -46,7 +46,6 @@
#include "mozilla/LazyIdleThread.h"
#include "mozilla/Monitor.h"
#include "mozilla/Mutex.h"
#include "mozilla/NullPtr.h"
#include "mozilla/StaticMutex.h"
#include "mozilla/unused.h"

View File

@ -45,7 +45,6 @@
#include "mozilla/ipc/RawDBusConnection.h"
#include "mozilla/LazyIdleThread.h"
#include "mozilla/Mutex.h"
#include "mozilla/NullPtr.h"
#include "mozilla/StaticMutex.h"
#include "mozilla/unused.h"

View File

@ -36,7 +36,7 @@ DOMCameraDetectedFace::DOMCameraDetectedFace(nsISupports* aParent,
: mParent(aParent)
, mId(aFace.id)
, mScore(aFace.score)
, mBounds(new DOMRect(MOZ_THIS_IN_INITIALIZER_LIST()))
, mBounds(new DOMRect(this))
{
mBounds->SetRect(aFace.bound.left,
aFace.bound.top,

View File

@ -40,6 +40,7 @@
#include "AutoRwLock.h"
#include "GonkCameraHwMgr.h"
#include "GonkRecorderProfiles.h"
#include "GrallocImages.h"
#include "CameraCommon.h"
#include "GonkCameraParameters.h"
#include "DeviceStorageFileDescriptor.h"

View File

@ -183,7 +183,13 @@ GonkCameraHardware::Init()
#if defined(MOZ_WIDGET_GONK)
#if ANDROID_VERSION >= 19
#if ANDROID_VERSION >= 21
sp<IGraphicBufferProducer> producer;
sp<IGonkGraphicBufferConsumer> consumer;
GonkBufferQueue::createBufferQueue(&producer, &consumer);
mNativeWindow = new GonkNativeWindow(consumer, GonkCameraHardware::MIN_UNDEQUEUED_BUFFERS);
mCamera->setPreviewTarget(producer);
#elif ANDROID_VERSION >= 19
mNativeWindow = new GonkNativeWindow(GonkCameraHardware::MIN_UNDEQUEUED_BUFFERS);
sp<GonkBufferQueue> bq = mNativeWindow->getBufferQueue();
bq->setSynchronousMode(false);

View File

@ -1154,7 +1154,11 @@ status_t GonkRecorder::setupMediaSource(
return err;
}
*mediaSource = cameraSource;
#if ANDROID_VERSION >= 21
} else if (mVideoSource == VIDEO_SOURCE_SURFACE) {
#else
} else if (mVideoSource == VIDEO_SOURCE_GRALLOC_BUFFER) {
#endif
return BAD_VALUE;
} else {
return INVALID_OPERATION;

View File

@ -28,9 +28,10 @@ namespace mozilla {
namespace dom {
class EventTarget;
class ErrorEvent;
class ProgressEvent;
class WantsPopupControlCheck;
#define GENERATED_EVENT(EventClass_) class EventClass_;
#include "mozilla/dom/GeneratedEventList.h"
#undef GENERATED_EVENT
// Dummy class so we can cast through it to get from nsISupports to
// Event subclasses with only two non-ambiguous static casts.
@ -95,15 +96,13 @@ public:
virtual JSObject* WrapObjectInternal(JSContext* aCx);
virtual ErrorEvent* AsErrorEvent()
{
return nullptr;
}
virtual ProgressEvent* AsProgressEvent()
{
return nullptr;
#define GENERATED_EVENT(EventClass_) \
virtual EventClass_* As##EventClass_() \
{ \
return nullptr; \
}
#include "mozilla/dom/GeneratedEventList.h"
#undef GENERATED_EVENT
// nsIDOMEvent Interface
NS_DECL_NSIDOMEVENT

View File

@ -101,6 +101,8 @@ EventListenerManager::EventListenerManager(EventTarget* aTarget)
, mMayHaveScrollWheelEventListener(false)
, mMayHaveMouseEnterLeaveEventListener(false)
, mMayHavePointerEnterLeaveEventListener(false)
, mMayHaveKeyEventListener(false)
, mMayHaveInputOrCompositionEventListener(false)
, mClearingListeners(false)
, mIsMainThreadELM(NS_IsMainThread())
, mNoListenerForEvent(0)
@ -386,7 +388,21 @@ EventListenerManager::AddEventListenerInternal(
window->SetHasGamepadEventListener();
}
#endif
} else if (aTypeAtom == nsGkAtoms::onkeydown ||
aTypeAtom == nsGkAtoms::onkeypress ||
aTypeAtom == nsGkAtoms::onkeyup) {
if (!aFlags.mInSystemGroup) {
mMayHaveKeyEventListener = true;
}
} else if (aTypeAtom == nsGkAtoms::oncompositionend ||
aTypeAtom == nsGkAtoms::oncompositionstart ||
aTypeAtom == nsGkAtoms::oncompositionupdate ||
aTypeAtom == nsGkAtoms::oninput) {
if (!aFlags.mInSystemGroup) {
mMayHaveInputOrCompositionEventListener = true;
}
}
if (aTypeAtom && mTarget) {
mTarget->EventListenerAdded(aTypeAtom);
}

View File

@ -403,6 +403,19 @@ public:
bool MayHaveMouseEnterLeaveEventListener() { return mMayHaveMouseEnterLeaveEventListener; }
bool MayHavePointerEnterLeaveEventListener() { return mMayHavePointerEnterLeaveEventListener; }
/**
* Returns true if there may be a key event listener (keydown, keypress,
* or keyup) registered, or false if there definitely isn't.
*/
bool MayHaveKeyEventListener() { return mMayHaveKeyEventListener; }
/**
* Returns true if there may be an advanced input event listener (input,
* compositionstart, compositionupdate, or compositionend) registered,
* or false if there definitely isn't.
*/
bool MayHaveInputOrCompositionEventListener() { return mMayHaveInputOrCompositionEventListener; }
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
uint32_t ListenerCount() const
@ -553,9 +566,11 @@ protected:
uint32_t mMayHaveScrollWheelEventListener : 1;
uint32_t mMayHaveMouseEnterLeaveEventListener : 1;
uint32_t mMayHavePointerEnterLeaveEventListener : 1;
uint32_t mMayHaveKeyEventListener : 1;
uint32_t mMayHaveInputOrCompositionEventListener : 1;
uint32_t mClearingListeners : 1;
uint32_t mIsMainThreadELM : 1;
uint32_t mNoListenerForEvent : 23;
uint32_t mNoListenerForEvent : 20;
nsAutoTObserverArray<Listener, 2> mListeners;
dom::EventTarget* mTarget; // WEAK

View File

@ -9,6 +9,7 @@
#include "mozilla/IMEStateManager.h"
#include "mozilla/Attributes.h"
#include "mozilla/EventListenerManager.h"
#include "mozilla/EventStates.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/Preferences.h"
@ -181,6 +182,7 @@ nsPresContext* IMEStateManager::sPresContext = nullptr;
bool IMEStateManager::sInstalledMenuKeyboardListener = false;
bool IMEStateManager::sIsTestingIME = false;
bool IMEStateManager::sIsGettingNewIMEState = false;
bool IMEStateManager::sCheckForIMEUnawareWebApps = false;
// sActiveIMEContentObserver points to the currently active IMEContentObserver.
// sActiveIMEContentObserver is null if there is no focused editor.
@ -196,6 +198,10 @@ IMEStateManager::Init()
sISMLog = PR_NewLogModule("IMEStateManager");
}
#endif
Preferences::AddBoolVarCache(
&sCheckForIMEUnawareWebApps,
"intl.ime.hack.on_ime_unaware_apps.fire_key_events_for_composition",
false);
}
// static
@ -747,6 +753,25 @@ private:
uint32_t mState;
};
static bool
MayBeIMEUnawareWebApp(nsINode* aNode)
{
bool haveKeyEventsListener = false;
while (aNode) {
EventListenerManager* const mgr = aNode->GetExistingListenerManager();
if (mgr) {
if (mgr->MayHaveInputOrCompositionEventListener()) {
return false;
}
haveKeyEventsListener |= mgr->MayHaveKeyEventListener();
}
aNode = aNode->GetParentNode();
}
return haveKeyEventsListener;
}
// static
void
IMEStateManager::SetIMEState(const IMEState& aState,
@ -769,6 +794,9 @@ IMEStateManager::SetIMEState(const IMEState& aState,
InputContext context;
context.mIMEState = aState;
context.mMayBeIMEUnaware = context.mIMEState.IsEditable() &&
sCheckForIMEUnawareWebApps && MayBeIMEUnawareWebApp(aContent);
if (aContent && aContent->GetNameSpaceID() == kNameSpaceID_XHTML &&
(aContent->Tag() == nsGkAtoms::input ||
aContent->Tag() == nsGkAtoms::textarea)) {

View File

@ -164,6 +164,7 @@ protected:
static bool sInstalledMenuKeyboardListener;
static bool sIsTestingIME;
static bool sIsGettingNewIMEState;
static bool sCheckForIMEUnawareWebApps;
class MOZ_STACK_CLASS GettingNewIMEStateBlocker MOZ_FINAL
{

View File

@ -29,6 +29,7 @@ DEFINE_KEYNAME_WITH_SAME_NAME(Unidentified)
* Our Internal Key Values (must have "Moz" prefix)
*****************************************************************************/
DEFINE_KEYNAME_INTERNAL(PrintableKey, "MozPrintableKey")
DEFINE_KEYNAME_INTERNAL(HomeScreen, "MozHomeScreen")
/******************************************************************************
* Modifier Keys

View File

@ -28,7 +28,7 @@ public:
explicit HTMLAnchorElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
: nsGenericHTMLElement(aNodeInfo)
, Link(MOZ_THIS_IN_INITIALIZER_LIST())
, Link(this)
{
}

View File

@ -19,7 +19,7 @@ namespace dom {
HTMLAreaElement::HTMLAreaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
: nsGenericHTMLElement(aNodeInfo)
, Link(MOZ_THIS_IN_INITIALIZER_LIST())
, Link(this)
{
}

View File

@ -88,7 +88,7 @@ bool HTMLFormElement::gPasswordManagerInitialized = false;
HTMLFormElement::HTMLFormElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
: nsGenericHTMLElement(aNodeInfo),
mControls(new HTMLFormControlsCollection(MOZ_THIS_IN_INITIALIZER_LIST())),
mControls(new HTMLFormControlsCollection(this)),
mSelectedRadioButtons(2),
mRequiredRadioButtonCounts(2),
mValueMissingRadioGroups(2),

View File

@ -37,7 +37,7 @@ namespace dom {
HTMLLinkElement::HTMLLinkElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
: nsGenericHTMLElement(aNodeInfo)
, Link(MOZ_THIS_IN_INITIALIZER_LIST())
, Link(this)
{
}

View File

@ -104,7 +104,7 @@ SafeOptionListMutation::~SafeOptionListMutation()
HTMLSelectElement::HTMLSelectElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
FromParser aFromParser)
: nsGenericHTMLFormElementWithState(aNodeInfo),
mOptions(new HTMLOptionsCollection(MOZ_THIS_IN_INITIALIZER_LIST())),
mOptions(new HTMLOptionsCollection(this)),
mAutocompleteAttrState(nsContentUtils::eAutocompleteAttrState_Unknown),
mIsDoneAddingChildren(!aFromParser),
mDisabledChanged(false),

View File

@ -61,7 +61,7 @@ HTMLTextAreaElement::HTMLTextAreaElement(already_AddRefed<mozilla::dom::NodeInfo
mDisabledChanged(false),
mCanShowInvalidUI(true),
mCanShowValidUI(true),
mState(MOZ_THIS_IN_INITIALIZER_LIST())
mState(this)
{
AddMutationObserver(this);

View File

@ -156,10 +156,10 @@ TimeRanges::Intersection(const TimeRanges* aOtherRanges)
}
TimeRanges::index_type
TimeRanges::Find(double aTime)
TimeRanges::Find(double aTime, double aError /* = 0 */)
{
for (index_type i = 0; i < mRanges.Length(); ++i) {
if (aTime >= mRanges[i].mStart && aTime < mRanges[i].mEnd) {
if (aTime < mRanges[i].mEnd && (aTime + aError) >= mRanges[i].mStart) {
return i;
}
}

View File

@ -91,7 +91,7 @@ public:
typedef nsTArray<TimeRange>::index_type index_type;
static const index_type NoIndex = index_type(-1);
index_type Find(double aTime);
index_type Find(double aTime, double aError = 0);
bool Contains(double aStart, double aEnd) {
index_type target = Find(aStart);

View File

@ -31,7 +31,6 @@ FileImplSnapshot::FileImplSnapshot(const nsAString& aName,
aMetadataParams->Size(),
aMetadataParams->LastModified())
, mFile(aFile)
, mFileHandle(aFileHandle)
, mWholeFile(true)
{
AssertSanity();
@ -43,6 +42,9 @@ FileImplSnapshot::FileImplSnapshot(const nsAString& aName,
MOZ_ASSERT(aFileInfo);
mFileInfos.AppendElement(aFileInfo);
mFileHandle =
do_GetWeakReference(NS_ISUPPORTS_CAST(EventTarget*, aFileHandle));
}
// Create slice
@ -88,39 +90,19 @@ FileImplSnapshot::AssertSanity()
NS_IMPL_ISUPPORTS_INHERITED(FileImplSnapshot, FileImpl, PIFileImplSnapshot)
void
FileImplSnapshot::Unlink()
{
AssertSanity();
FileImplSnapshot* tmp = this;
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFileHandle);
}
void
FileImplSnapshot::Traverse(nsCycleCollectionTraversalCallback &cb)
{
AssertSanity();
FileImplSnapshot* tmp = this;
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFileHandle);
}
bool
FileImplSnapshot::IsCCed() const
{
AssertSanity();
return true;
}
nsresult
FileImplSnapshot::GetInternalStream(nsIInputStream** aStream)
{
AssertSanity();
nsresult rv = mFileHandle->OpenInputStream(mWholeFile, mStart, mLength,
aStream);
nsCOMPtr<EventTarget> et = do_QueryReferent(mFileHandle);
nsRefPtr<IDBFileHandle> fileHandle = static_cast<IDBFileHandle*>(et.get());
if (!fileHandle) {
return NS_ERROR_DOM_FILEHANDLE_INACTIVE_ERR;
}
nsresult rv = fileHandle->OpenInputStream(mWholeFile, mStart, mLength,
aStream);
if (NS_FAILED(rv)) {
return rv;
}

View File

@ -12,6 +12,7 @@
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsISupports.h"
#include "nsWeakPtr.h"
#define FILEIMPLSNAPSHOT_IID \
{0x0dfc11b1, 0x75d3, 0x473b, {0x8c, 0x67, 0xb7, 0x23, 0xf4, 0x67, 0xd6, 0x73}}
@ -40,7 +41,7 @@ class FileImplSnapshot MOZ_FINAL
typedef mozilla::dom::MetadataParameters MetadataParameters;
nsCOMPtr<nsIFile> mFile;
nsRefPtr<IDBFileHandle> mFileHandle;
nsWeakPtr mFileHandle;
bool mWholeFile;
@ -78,14 +79,10 @@ private:
virtual nsresult
GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE;
virtual void
Unlink() MOZ_OVERRIDE;
virtual void
Traverse(nsCycleCollectionTraversalCallback &aCb) MOZ_OVERRIDE;
virtual bool
IsCCed() const MOZ_OVERRIDE;
virtual bool MayBeClonedToOtherThreads() const MOZ_OVERRIDE
{
return false;
}
virtual already_AddRefed<FileImpl>
CreateSlice(uint64_t aStart,

View File

@ -87,6 +87,7 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(IDBFileHandle, DOMEventTargetHelper,
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBFileHandle)
NS_INTERFACE_MAP_ENTRY(nsIRunnable)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(IDBFileHandle, DOMEventTargetHelper)

View File

@ -15,6 +15,7 @@
#include "mozilla/dom/FileHandle.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "nsCycleCollectionParticipant.h"
#include "nsWeakReference.h"
class nsPIDOMWindow;
@ -29,7 +30,8 @@ class IDBMutableFile;
class IDBFileHandle MOZ_FINAL : public DOMEventTargetHelper,
public nsIRunnable,
public FileHandleBase
public FileHandleBase,
public nsSupportsWeakReference
{
public:
NS_DECL_ISUPPORTS_INHERITED

View File

@ -5,10 +5,10 @@
#include "nsISupports.idl"
interface nsIDOMWindow;
interface nsIGlobalObject;
[uuid(729cfcad-11b4-4338-b97e-5c023ae295fa)]
[uuid(48d7f7fd-bb85-4c04-9b8b-5cd9131acdef)]
interface nsIDOMCrypto : nsISupports
{
[notxpcom] void init(in nsIDOMWindow window);
[notxpcom] void init(in nsIGlobalObject parent);
};

View File

@ -51,7 +51,7 @@ interface nsITranslationNodeList;
interface nsIJSRAIIHelper;
interface nsIContentPermissionRequest;
[scriptable, uuid(4922a706-a17e-48e0-ab6f-9fe1bbe4e5f7)]
[scriptable, uuid(0281e107-394d-4c96-830b-2f830b07c6c0)]
interface nsIDOMWindowUtils : nsISupports {
/**
@ -1752,6 +1752,21 @@ interface nsIDOMWindowUtils : nsISupports {
* e10s support properly.
*/
void askPermission(in nsIContentPermissionRequest aRequest);
/**
* Number of frames constructed (excluding breaking) for the curent
* document.
*
* May throw NS_ERROR_NOT_AVAILABLE.
*/
readonly attribute unsigned long long framesConstructed;
/**
* Number of frames reflowed for the curent document.
*
* May throw NS_ERROR_NOT_AVAILABLE.
*/
readonly attribute unsigned long long framesReflowed;
};
[scriptable, uuid(c694e359-7227-4392-a138-33c0cc1f15a6)]

View File

@ -2107,11 +2107,8 @@ public:
virtual bool
IsFile() const MOZ_OVERRIDE;
virtual void
Unlink() MOZ_OVERRIDE;
virtual void
Traverse(nsCycleCollectionTraversalCallback& aCallback) MOZ_OVERRIDE;
virtual bool
MayBeClonedToOtherThreads() const MOZ_OVERRIDE;
virtual BlobChild*
GetBlobChild() MOZ_OVERRIDE;
@ -2840,18 +2837,11 @@ RemoteBlobImpl::IsFile() const
return mBlobImpl->IsFile();
}
void
bool
BlobParent::
RemoteBlobImpl::Unlink()
RemoteBlobImpl::MayBeClonedToOtherThreads() const
{
return mBlobImpl->Unlink();
}
void
BlobParent::
RemoteBlobImpl::Traverse(nsCycleCollectionTraversalCallback& aCallback)
{
return mBlobImpl->Traverse(aCallback);
return mBlobImpl->MayBeClonedToOtherThreads();
}
BlobChild*

View File

@ -2489,6 +2489,20 @@ ContentChild::RecvAssociatePluginId(const uint32_t& aPluginId,
return true;
}
bool
ContentChild::RecvShutdown()
{
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
if (os) {
os->NotifyObservers(this, "content-child-shutdown", nullptr);
}
// Ignore errors here. If this fails, the parent will kill us after a
// timeout.
unused << SendFinishShutdown();
return true;
}
PBrowserOrId
ContentChild::GetBrowserOrId(TabChild* aTabChild)
{

View File

@ -377,6 +377,7 @@ public:
const nsTArray<nsCString>& aThreadNameFilters) MOZ_OVERRIDE;
virtual bool RecvStopProfiler() MOZ_OVERRIDE;
virtual bool RecvGetProfile(nsCString* aProfile) MOZ_OVERRIDE;
virtual bool RecvShutdown() MOZ_OVERRIDE;
#ifdef ANDROID
gfxIntSize GetScreenSize() { return mScreenSize; }

View File

@ -116,6 +116,7 @@
#include "nsISpellChecker.h"
#include "nsIStyleSheet.h"
#include "nsISupportsPrimitives.h"
#include "nsITimer.h"
#include "nsIURIFixup.h"
#include "nsIWindowWatcher.h"
#include "nsIXULRuntime.h"
@ -586,6 +587,7 @@ static uint64_t gContentChildID = 1;
static const char* sObserverTopics[] = {
"xpcom-shutdown",
"profile-before-change",
NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC,
"child-memory-reporter-request",
"memory-pressure",
@ -1496,8 +1498,31 @@ ContentParent::TransformPreallocatedIntoBrowser(ContentParent* aOpener)
}
void
ContentParent::ShutDownProcess(bool aCloseWithError)
ContentParent::ShutDownProcess(ShutDownMethod aMethod)
{
#ifdef MOZ_NUWA_PROCESS
if (aMethod == SEND_SHUTDOWN_MESSAGE && IsNuwaProcess()) {
// We shouldn't send shutdown messages to frozen Nuwa processes,
// so just close the channel.
aMethod = CLOSE_CHANNEL;
}
#endif
// Shutting down by sending a shutdown message works differently than the
// other methods. We first call Shutdown() in the child. After the child is
// ready, it calls FinishShutdown() on us. Then we close the channel.
if (aMethod == SEND_SHUTDOWN_MESSAGE) {
if (mIPCOpen && !mShutdownPending && SendShutdown()) {
mShutdownPending = true;
// Start the force-kill timer if we haven't already.
StartForceKillTimer();
}
// If call was not successful, the channel must have been broken
// somehow, and we will clean up the error in ActorDestroy.
return;
}
using mozilla::dom::quota::QuotaManager;
if (QuotaManager* quotaManager = QuotaManager::Get()) {
@ -1505,10 +1530,10 @@ ContentParent::ShutDownProcess(bool aCloseWithError)
}
// If Close() fails with an error, we'll end up back in this function, but
// with aCloseWithError = true. It's important that we call
// with aMethod = CLOSE_CHANNEL_WITH_ERROR. It's important that we call
// CloseWithError() in this case; see bug 895204.
if (!aCloseWithError && !mCalledClose) {
if (aMethod == CLOSE_CHANNEL && !mCalledClose) {
// Close() can only be called once: It kicks off the destruction
// sequence.
mCalledClose = true;
@ -1522,7 +1547,7 @@ ContentParent::ShutDownProcess(bool aCloseWithError)
#endif
}
if (aCloseWithError && !mCalledCloseWithError) {
if (aMethod == CLOSE_CHANNEL_WITH_ERROR && !mCalledCloseWithError) {
MessageChannel* channel = GetIPCChannel();
if (channel) {
mCalledCloseWithError = true;
@ -1549,6 +1574,17 @@ ContentParent::ShutDownProcess(bool aCloseWithError)
ShutDownMessageManager();
}
bool
ContentParent::RecvFinishShutdown()
{
// At this point, we already called ShutDownProcess once with
// SEND_SHUTDOWN_MESSAGE. To actually close the channel, we call
// ShutDownProcess again with CLOSE_CHANNEL.
MOZ_ASSERT(mShutdownPending);
ShutDownProcess(CLOSE_CHANNEL);
return true;
}
void
ContentParent::ShutDownMessageManager()
{
@ -1744,12 +1780,25 @@ struct DelayedDeleteContentParentTask : public nsRunnable
void
ContentParent::ActorDestroy(ActorDestroyReason why)
{
if (mForceKillTask) {
mForceKillTask->Cancel();
mForceKillTask = nullptr;
if (mForceKillTimer) {
mForceKillTimer->Cancel();
mForceKillTimer = nullptr;
}
ShutDownMessageManager();
// Signal shutdown completion regardless of error state, so we can
// finish waiting in the xpcom-shutdown/profile-before-change observer.
mIPCOpen = false;
if (why == NormalShutdown && !mCalledClose) {
// If we shut down normally but haven't called Close, assume somebody
// else called Close on us. In that case, we still need to call
// ShutDownProcess below to perform other necessary clean up.
mCalledClose = true;
}
// Make sure we always clean up.
ShutDownProcess(why == NormalShutdown ? CLOSE_CHANNEL
: CLOSE_CHANNEL_WITH_ERROR);
nsRefPtr<ContentParent> kungFuDeathGrip(this);
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
@ -1788,8 +1837,6 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
mConsoleService = nullptr;
MarkAsDead();
if (obs) {
nsRefPtr<nsHashPropertyBag> props = new nsHashPropertyBag();
@ -1841,11 +1888,6 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
mIdleListeners.Clear();
// If the child process was terminated due to a SIGKIL, ShutDownProcess
// might not have been called yet. We must call it to ensure that our
// channel is closed, etc.
ShutDownProcess(/* closeWithError */ true);
MessageLoop::current()->
PostTask(FROM_HERE,
NewRunnableFunction(DelayedDeleteSubprocess, mSubprocess));
@ -1869,7 +1911,7 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
MessageLoop::current()->PostTask(
FROM_HERE,
NewRunnableMethod(cp, &ContentParent::ShutDownProcess,
/* closeWithError */ false));
CLOSE_CHANNEL));
}
cpm->RemoveContentProcess(this->ChildID());
}
@ -1891,15 +1933,25 @@ ContentParent::NotifyTabDestroying(PBrowserParent* aTab)
// We're dying now, so prevent this content process from being
// recycled during its shutdown procedure.
MarkAsDead();
StartForceKillTimer();
}
void
ContentParent::StartForceKillTimer()
{
if (mForceKillTimer || !mIPCOpen) {
return;
}
MOZ_ASSERT(!mForceKillTask);
int32_t timeoutSecs =
Preferences::GetInt("dom.ipc.tabs.shutdownTimeoutSecs", 5);
if (timeoutSecs > 0) {
MessageLoop::current()->PostDelayedTask(
FROM_HERE,
mForceKillTask = NewRunnableMethod(this, &ContentParent::KillHard),
timeoutSecs * 1000);
mForceKillTimer = do_CreateInstance("@mozilla.org/timer;1");
MOZ_ASSERT(mForceKillTimer);
mForceKillTimer->InitWithFuncCallback(ContentParent::ForceKillTimerCallback,
this,
timeoutSecs * 1000,
nsITimer::TYPE_ONE_SHOT);
}
}
@ -1915,10 +1967,12 @@ ContentParent::NotifyTabDestroyed(PBrowserParent* aTab,
// because of popup windows. When the last one closes, shut
// us down.
if (ManagedPBrowserParent().Length() == 1) {
// In the case of normal shutdown, send a shutdown message to child to
// allow it to perform shutdown tasks.
MessageLoop::current()->PostTask(
FROM_HERE,
NewRunnableMethod(this, &ContentParent::ShutDownProcess,
/* force */ false));
SEND_SHUTDOWN_MESSAGE));
}
}
@ -1957,7 +2011,6 @@ ContentParent::InitializeMembers()
mSubprocess = nullptr;
mChildID = gContentChildID++;
mGeolocationWatchID = -1;
mForceKillTask = nullptr;
mNumDestroyingTabs = 0;
mIsAlive = true;
mSendPermissionUpdates = false;
@ -1966,6 +2019,8 @@ ContentParent::InitializeMembers()
mCalledCloseWithError = false;
mCalledKillHard = false;
mCreatedPairedMinidumps = false;
mShutdownPending = false;
mIPCOpen = true;
}
ContentParent::ContentParent(mozIApplication* aApp,
@ -2133,8 +2188,8 @@ ContentParent::ContentParent(ContentParent* aTemplate,
ContentParent::~ContentParent()
{
if (mForceKillTask) {
mForceKillTask->Cancel();
if (mForceKillTimer) {
mForceKillTimer->Cancel();
}
if (OtherProcess())
@ -2493,7 +2548,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;
}
@ -2709,8 +2764,17 @@ ContentParent::Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData)
{
if (!strcmp(aTopic, "xpcom-shutdown") && mSubprocess) {
ShutDownProcess(/* closeWithError */ false);
if (mSubprocess && (!strcmp(aTopic, "profile-before-change") ||
!strcmp(aTopic, "xpcom-shutdown"))) {
// Okay to call ShutDownProcess multiple times.
ShutDownProcess(SEND_SHUTDOWN_MESSAGE);
// Wait for shutdown to complete, so that we receive any shutdown
// data (e.g. telemetry) from the child before we quit.
// This loop terminate prematurely based on mForceKillTimer.
while (mIPCOpen) {
NS_ProcessNextEvent(nullptr, true);
}
NS_ASSERTION(!mSubprocess, "Close should have nulled mSubprocess");
}
@ -3116,6 +3180,13 @@ ContentParent::DeallocPRemoteSpellcheckEngineParent(PRemoteSpellcheckEngineParen
return true;
}
/* static */ void
ContentParent::ForceKillTimerCallback(nsITimer* aTimer, void* aClosure)
{
auto self = static_cast<ContentParent*>(aClosure);
self->KillHard();
}
void
ContentParent::KillHard()
{
@ -3126,7 +3197,7 @@ ContentParent::KillHard()
return;
}
mCalledKillHard = true;
mForceKillTask = nullptr;
mForceKillTimer = nullptr;
#if defined(MOZ_CRASHREPORTER) && !defined(MOZ_B2G)
if (ManagedPCrashReporterParent().Length() > 0) {

View File

@ -33,6 +33,7 @@ class nsICycleCollectorLogSink;
class nsIDOMBlob;
class nsIDumpGCAndCCLogsCallback;
class nsIMemoryReporter;
class nsITimer;
class ParentIdleListener;
namespace mozilla {
@ -334,6 +335,8 @@ public:
virtual bool RecvSetOfflinePermission(const IPC::Principal& principal) MOZ_OVERRIDE;
virtual bool RecvFinishShutdown() MOZ_OVERRIDE;
protected:
void OnChannelConnected(int32_t pid) MOZ_OVERRIDE;
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
@ -433,23 +436,40 @@ private:
*/
void MarkAsDead();
/**
* How we will shut down this ContentParent and its subprocess.
*/
enum ShutDownMethod {
// Send a shutdown message and wait for FinishShutdown call back.
SEND_SHUTDOWN_MESSAGE,
// Close the channel ourselves and let the subprocess clean up itself.
CLOSE_CHANNEL,
// Close the channel with error and let the subprocess clean up itself.
CLOSE_CHANNEL_WITH_ERROR,
};
/**
* Exit the subprocess and vamoose. After this call IsAlive()
* will return false and this ContentParent will not be returned
* by the Get*() funtions. However, the shutdown sequence itself
* may be asynchronous.
*
* If aCloseWithError is true and this is the first call to
* ShutDownProcess, then we'll close our channel using CloseWithError()
* If aMethod is CLOSE_CHANNEL_WITH_ERROR and this is the first call
* to ShutDownProcess, then we'll close our channel using CloseWithError()
* rather than vanilla Close(). CloseWithError() indicates to IPC that this
* is an abnormal shutdown (e.g. a crash).
*/
void ShutDownProcess(bool aCloseWithError);
void ShutDownProcess(ShutDownMethod aMethod);
// Perform any steps necesssary to gracefully shtudown the message
// manager and null out mMessageManager.
void ShutDownMessageManager();
// Start the force-kill timer on shutdown.
void StartForceKillTimer();
static void ForceKillTimerCallback(nsITimer* aTimer, void* aClosure);
PCompositorParent*
AllocPCompositorParent(mozilla::ipc::Transport* aTransport,
base::ProcessId aOtherProcess) MOZ_OVERRIDE;
@ -776,7 +796,7 @@ private:
// that even content processes that are 100% blocked (say from
// SIGSTOP), are still killed eventually. This task enforces that
// timer.
CancelableTask* mForceKillTask;
nsCOMPtr<nsITimer> mForceKillTimer;
// How many tabs we're waiting to finish their destruction
// sequence. Precisely, how many TabParents have called
// NotifyTabDestroying() but not called NotifyTabDestroyed().
@ -798,6 +818,8 @@ private:
bool mCalledCloseWithError;
bool mCalledKillHard;
bool mCreatedPairedMinidumps;
bool mShutdownPending;
bool mIPCOpen;
friend class CrashReporterParent;

View File

@ -542,6 +542,13 @@ child:
returns (nsCString aProfile);
NuwaFreeze();
/**
* Notify the child to shutdown. The child will in turn call FinishShutdown
* and let the parent close the channel.
*/
async Shutdown();
parent:
/**
* Tell the parent process a new accessible document has been created.
@ -877,6 +884,12 @@ parent:
*/
SetOfflinePermission(Principal principal);
/**
* Notifies the parent to continue shutting down after the child performs
* its shutdown tasks.
*/
async FinishShutdown();
both:
AsyncMessage(nsString aMessage, ClonedMessageData aData,
CpowEntry[] aCpows, Principal aPrincipal);

View File

@ -777,7 +777,10 @@ private:
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mTabChild);
unused << PBrowserChild::Send__delete__(mTabChild);
// Check in case ActorDestroy was called after RecvDestroy message.
if (mTabChild->IPCOpen()) {
unused << PBrowserChild::Send__delete__(mTabChild);
}
mTabChild = nullptr;
return NS_OK;
@ -905,6 +908,7 @@ TabChild::TabChild(nsIContentChild* aManager,
, mUniqueId(aTabId)
, mDPI(0)
, mDefaultScale(0)
, mIPCOpen(true)
{
if (!sActiveDurationMsSet) {
Preferences::AddIntVarCache(&sActiveDurationMs,
@ -1654,6 +1658,8 @@ TabChild::DestroyWindow()
void
TabChild::ActorDestroy(ActorDestroyReason why)
{
mIPCOpen = false;
DestroyWindow();
if (mTabChildGlobal) {

View File

@ -499,6 +499,8 @@ public:
nsIntPoint GetChromeDisplacement() { return mChromeDisp; };
bool IPCOpen() { return mIPCOpen; }
protected:
virtual ~TabChild();
@ -662,6 +664,7 @@ private:
TabId mUniqueId;
float mDPI;
double mDefaultScale;
bool mIPCOpen;
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
};

View File

@ -142,21 +142,27 @@ private:
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mTabParent);
MOZ_ASSERT(mEventTarget);
MOZ_ASSERT(mFD);
nsRefPtr<TabParent> tabParent;
mTabParent.swap(tabParent);
using mozilla::ipc::FileDescriptor;
FileDescriptor::PlatformHandleType handle =
FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(mFD));
FileDescriptor fd;
if (mFD) {
FileDescriptor::PlatformHandleType handle =
FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(mFD));
fd = FileDescriptor(handle);
}
// Our TabParent may have been destroyed already. If so, don't send any
// fds over, just go back to the IO thread and close them.
if (!tabParent->IsDestroyed()) {
mozilla::unused << tabParent->SendCacheFileDescriptor(mPath,
FileDescriptor(handle));
mozilla::unused << tabParent->SendCacheFileDescriptor(mPath, fd);
}
if (!mFD) {
return;
}
nsCOMPtr<nsIEventTarget> eventTarget;
@ -171,7 +177,8 @@ private:
}
}
void OpenFile()
// Helper method to avoid gnarly control flow for failures.
void OpenFileImpl()
{
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(!mFD);
@ -185,10 +192,21 @@ private:
NS_ENSURE_SUCCESS_VOID(rv);
mFD = fd;
}
void OpenFile()
{
MOZ_ASSERT(!NS_IsMainThread());
OpenFileImpl();
if (NS_FAILED(NS_DispatchToMainThread(this))) {
NS_WARNING("Failed to dispatch to main thread!");
// Intentionally leak the runnable (but not the fd) rather
// than crash when trying to release a main thread object
// off the main thread.
mTabParent.forget();
CloseFile();
}
}
@ -2177,7 +2195,11 @@ TabParent::MaybeForwardEventToRenderFrame(WidgetInputEvent& aEvent,
ScrollableLayerGuid* aOutTargetGuid,
uint64_t* aOutInputBlockId)
{
if (aEvent.mClass == eWheelEventClass) {
if (aEvent.mClass == eWheelEventClass
#ifdef MOZ_WIDGET_GONK
|| aEvent.mClass == eTouchEventClass
#endif
) {
// Wheel events must be sent to APZ directly from the widget. New APZ-
// aware events should follow suit and move there as well. However, we
// do need to inform the child process of the correct target and block

View File

@ -143,7 +143,9 @@ public:
AutoNotifyDecoded(AbstractMediaDecoder* aDecoder, uint32_t& aParsed, uint32_t& aDecoded)
: mDecoder(aDecoder), mParsed(aParsed), mDecoded(aDecoded) {}
~AutoNotifyDecoded() {
mDecoder->NotifyDecodedFrames(mParsed, mDecoded);
if (mDecoder) {
mDecoder->NotifyDecodedFrames(mParsed, mDecoded);
}
}
private:
AbstractMediaDecoder* mDecoder;

View File

@ -132,7 +132,7 @@ AudioStream::AudioStream()
, mChannels(0)
, mOutChannels(0)
, mWritten(0)
, mAudioClock(MOZ_THIS_IN_INITIALIZER_LIST())
, mAudioClock(this)
, mLatencyRequest(HighLatency)
, mReadPoint(0)
, mDumpFile(nullptr)

View File

@ -74,10 +74,10 @@ MediaDecoderReader::MediaDecoderReader(AbstractMediaDecoder* aDecoder)
, mIgnoreAudioOutputFormat(false)
, mStartTime(-1)
, mHitAudioDecodeError(false)
, mShutdown(false)
, mTaskQueueIsBorrowed(false)
, mAudioDiscontinuity(false)
, mVideoDiscontinuity(false)
, mShutdown(false)
{
MOZ_COUNT_CTOR(MediaDecoderReader);
EnsureMediaPromiseLog();

View File

@ -52,7 +52,7 @@ public:
typedef MediaPromise<nsRefPtr<AudioData>, NotDecodedReason> AudioDataPromise;
typedef MediaPromise<nsRefPtr<VideoData>, NotDecodedReason> VideoDataPromise;
typedef MediaPromise<bool, nsresult> SeekPromise;
typedef MediaPromise<int64_t, nsresult> SeekPromise;
typedef MediaPromise<MediaData::Type, WaitForDataRejectValue> WaitForDataPromise;
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDecoderReader)
@ -300,6 +300,7 @@ protected:
// replace this with a promise-y mechanism as we make this stuff properly
// async.
bool mHitAudioDecodeError;
bool mShutdown;
private:
// Promises used only for the base-class (sync->async adapter) implementation
@ -314,7 +315,6 @@ private:
// "discontinuity" in the stream. For example after a seek.
bool mAudioDiscontinuity;
bool mVideoDiscontinuity;
bool mShutdown;
};
} // namespace mozilla

Some files were not shown because too many files have changed in this diff Show More