diff --git a/browser/base/content/test/general/browser.ini b/browser/base/content/test/general/browser.ini index 4d5472c2230f..933d21cf06b1 100644 --- a/browser/base/content/test/general/browser.ini +++ b/browser/base/content/test/general/browser.ini @@ -112,6 +112,8 @@ run-if = crashreporter [browser_aboutSyncProgress.js] [browser_addKeywordSearch.js] [browser_alltabslistener.js] +[browser_backButtonFitts.js] +skip-if = os != "win" # The Fitts Law back button is only supported on Windows (bug 571454) [browser_blob-channelname.js] [browser_bookmark_titles.js] skip-if = toolkit == "windows" # Disabled on Windows due to frequent failures (bugs 825739, 841341) diff --git a/browser/base/content/test/general/browser_backButtonFitts.js b/browser/base/content/test/general/browser_backButtonFitts.js new file mode 100644 index 000000000000..2b4eab637b2c --- /dev/null +++ b/browser/base/content/test/general/browser_backButtonFitts.js @@ -0,0 +1,30 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +function test () { + waitForExplicitFinish(); + var firstLocation = "http://example.org/browser/browser/base/content/test/general/dummy_page.html"; + gBrowser.selectedTab = gBrowser.addTab(firstLocation); + gBrowser.selectedBrowser.addEventListener("pageshow", function onPageShow1() { + gBrowser.selectedBrowser.removeEventListener("pageshow", onPageShow1); + gBrowser.selectedBrowser.contentWindow.history.pushState("page2", "page2", "page2"); + window.maximize(); + + // Find where the nav-bar is vertically. + var navBar = document.getElementById("nav-bar"); + var boundingRect = navBar.getBoundingClientRect(); + var yPixel = boundingRect.top + Math.floor(boundingRect.height / 2); + var xPixel = 0; // Use the first pixel of the screen since it is maximized. + + gBrowser.selectedBrowser.contentWindow.addEventListener("popstate", function onPopState() { + gBrowser.selectedBrowser.contentWindow.removeEventListener("popstate", onPopState); + is(gBrowser.selectedBrowser.contentDocument.location.href, firstLocation, + "Clicking the first pixel should have navigated back."); + window.restore(); + gBrowser.removeCurrentTab(); + finish(); + }); + EventUtils.synthesizeMouseAtPoint(xPixel, yPixel, {}, window); + }); +} diff --git a/browser/components/sessionstore/test/browser_625016.js b/browser/components/sessionstore/test/browser_625016.js index b6263cd59abf..1f1c2d2b3d2a 100644 --- a/browser/components/sessionstore/test/browser_625016.js +++ b/browser/components/sessionstore/test/browser_625016.js @@ -40,17 +40,21 @@ function setup() { } function onSaveState() { + try { + ss.getWindowValue(newWin, "foobar"); + } catch (e) { + // The window is untracked which means that the saveState() call isn't the + // one we're waiting for. It's most likely been triggered by an async + // collection running in the background. + waitForSaveState(onSaveState); + return; + } + // Double check that we have no closed windows is(ss.getClosedWindowCount(), 0, "no closed windows on first save"); Services.obs.addObserver(observe1, "sessionstore-state-write", false); - try { - ss.getWindowValue(newWin, "foobar"); - } catch (e) { - ok(false, "window is untracked!"); - } - // Now close the new window, which should trigger another save event newWin.close(); } diff --git a/browser/devtools/shared/test/browser_outputparser.js b/browser/devtools/shared/test/browser_outputparser.js index 0e366de3a6ef..5cc0e0abdfac 100644 --- a/browser/devtools/shared/test/browser_outputparser.js +++ b/browser/devtools/shared/test/browser_outputparser.js @@ -49,7 +49,6 @@ function testParseHTMLAttribute() { let attrib = "color:red; font-size: 12px; background-image: " + "url(chrome://branding/content/about-logo.png)"; let frag = parser.parseHTMLAttribute(attrib, { - colorSwatchClass: "test-colorswatch", urlClass: "theme-link" }); @@ -57,16 +56,32 @@ function testParseHTMLAttribute() { ok(target, "captain, we have the div"); target.appendChild(frag); - let expected = 'color:#F00; font-size: 12px; ' + + let expected = 'color:#F00; font-size: 12px; ' + 'background-image: url(\'chrome://branding/content/about-logo.png\')'; is(target.innerHTML, expected, "HTML Attribute correctly parsed"); + target.innerHTML = ""; + testParseNonCssHTMLAttribute(); +} + +function testParseNonCssHTMLAttribute() { + let attrib = "someclass background someotherclass red"; + let frag = parser.parseHTMLAttribute(attrib); + + let target = doc.querySelector("div"); + ok(target, "captain, we have the div"); + target.appendChild(frag); + + let expected = 'someclass background someotherclass red'; + + is(target.innerHTML, expected, "Non-CSS HTML Attribute correctly parsed"); + target.innerHTML = ""; finishUp(); } + function finishUp() { Services = Loader = OutputParser = parser = doc = null; gBrowser.removeCurrentTab(); diff --git a/browser/devtools/sourceeditor/editor.js b/browser/devtools/sourceeditor/editor.js index dbe0cdf5e871..a3709118e7f2 100644 --- a/browser/devtools/sourceeditor/editor.js +++ b/browser/devtools/sourceeditor/editor.js @@ -57,7 +57,7 @@ const CM_IFRAME = " " + [ " " for (style of CM_STYLES) ].join("\n") + " " + diff --git a/browser/metro/base/content/contenthandlers/Content.js b/browser/metro/base/content/contenthandlers/Content.js index 27c85e861d22..447599d37b19 100644 --- a/browser/metro/base/content/contenthandlers/Content.js +++ b/browser/metro/base/content/contenthandlers/Content.js @@ -49,6 +49,8 @@ const kReferenceDpi = 240; // standard "pixel" size used in some preferences const kStateActive = 0x00000001; // :active pseudoclass for elements +const kZoomToElementMargin = 16; // in px + /* * getBoundingContentRect * @@ -395,36 +397,37 @@ let Content = { * Zoom utilities */ _zoomOut: function() { - let rect = getBoundingContentRect(content.document.documentElement); - - let utils = Util.getWindowUtils(content); - let viewId = utils.getViewId(content.document.documentElement); - let presShellId = {}; - utils.getPresShellId(presShellId); - let zoomData = [rect.x, - rect.y, - rect.width, - rect.height, - presShellId.value, - viewId].join(","); - Services.obs.notifyObservers(null, "Metro:ZoomToRect", zoomData); + let rect = new Rect(0,0,0,0); + this._zoomToRect(rect); this._isZoomedIn = false; }, _zoomToElement: function(aElement) { let rect = getBoundingContentRect(aElement); + this._inflateRect(rect, kZoomToElementMargin); + this._zoomToRect(rect); + this._isZoomedIn = true; + }, + + _inflateRect: function(aRect, aMargin) { + aRect.left -= aMargin; + aRect.top -= aMargin; + aRect.bottom += aMargin; + aRect.right += aMargin; + }, + + _zoomToRect: function (aRect) { let utils = Util.getWindowUtils(content); let viewId = utils.getViewId(content.document.documentElement); let presShellId = {}; utils.getPresShellId(presShellId); - let zoomData = [rect.x, - rect.y, - rect.width, - rect.height, + let zoomData = [aRect.x, + aRect.y, + aRect.width, + aRect.height, presShellId.value, viewId].join(","); Services.obs.notifyObservers(null, "Metro:ZoomToRect", zoomData); - this._isZoomedIn = true; }, _shouldZoomToElement: function(aElement) { diff --git a/browser/themes/osx/devtools/common.css b/browser/themes/osx/devtools/common.css index f10a04f7d82a..5d1b4a07919b 100644 --- a/browser/themes/osx/devtools/common.css +++ b/browser/themes/osx/devtools/common.css @@ -12,7 +12,7 @@ } .devtools-monospace { - font-family: monospace; + font-family: Menlo, monospace; font-size: 108%; } diff --git a/browser/themes/windows/devtools/common.css b/browser/themes/windows/devtools/common.css index 2ef086768540..8b03a9ebe368 100644 --- a/browser/themes/windows/devtools/common.css +++ b/browser/themes/windows/devtools/common.css @@ -10,7 +10,7 @@ } .devtools-monospace { - font-family: monospace; + font-family: Consolas, monospace; } /* Toolbar and Toolbar items */ diff --git a/build/annotationProcessors/MethodWithAnnotationInfo.java b/build/annotationProcessors/AnnotationInfo.java similarity index 59% rename from build/annotationProcessors/MethodWithAnnotationInfo.java rename to build/annotationProcessors/AnnotationInfo.java index ef4f9725bac9..2d2984ebdd41 100644 --- a/build/annotationProcessors/MethodWithAnnotationInfo.java +++ b/build/annotationProcessors/AnnotationInfo.java @@ -4,19 +4,15 @@ package org.mozilla.gecko.annotationProcessors; -import java.lang.reflect.Method; - /** - * Object holding method and annotation. Used by GeneratableEntryPointIterator. + * Object holding annotation data. Used by GeneratableElementIterator. */ -public class MethodWithAnnotationInfo { - public final Method method; +public class AnnotationInfo { public final String wrapperName; public final boolean isStatic; public final boolean isMultithreaded; - public MethodWithAnnotationInfo(Method aMethod, String aWrapperName, boolean aIsStatic, boolean aIsMultithreaded) { - method = aMethod; + public AnnotationInfo(String aWrapperName, boolean aIsStatic, boolean aIsMultithreaded) { wrapperName = aWrapperName; isStatic = aIsStatic; isMultithreaded = aIsMultithreaded; diff --git a/build/annotationProcessors/AnnotationProcessor.java b/build/annotationProcessors/AnnotationProcessor.java index 851f4037710f..bcd70a58ee8f 100644 --- a/build/annotationProcessors/AnnotationProcessor.java +++ b/build/annotationProcessors/AnnotationProcessor.java @@ -4,8 +4,10 @@ package org.mozilla.gecko.annotationProcessors; +import org.mozilla.gecko.annotationProcessors.classloader.AnnotatableEntity; +import org.mozilla.gecko.annotationProcessors.classloader.ClassWithOptions; import org.mozilla.gecko.annotationProcessors.classloader.IterableJarLoadingURLClassLoader; -import org.mozilla.gecko.annotationProcessors.utils.GeneratableEntryPointIterator; +import org.mozilla.gecko.annotationProcessors.utils.GeneratableElementIterator; import java.io.FileOutputStream; import java.io.IOException; @@ -16,6 +18,12 @@ public class AnnotationProcessor { public static final String OUTFILE = "GeneratedJNIWrappers.cpp"; public static final String HEADERFILE = "GeneratedJNIWrappers.h"; + public static final String GENERATED_COMMENT = + "// GENERATED CODE\n" + + "// Generated by the Java program at /build/annotationProcessors at compile time from\n" + + "// annotations on Java methods. To update, change the annotations on the corresponding Java\n" + + "// methods and rerun the build. Manually updating this file will cause your build to fail.\n\n"; + public static void main(String[] args) { // We expect a list of jars on the commandline. If missing, whinge about it. if (args.length <= 1) { @@ -33,44 +41,121 @@ public class AnnotationProcessor { long s = System.currentTimeMillis(); // Get an iterator over the classes in the jar files given... - Iterator> jarClassIterator = IterableJarLoadingURLClassLoader.getIteratorOverJars(args); + Iterator jarClassIterator = IterableJarLoadingURLClassLoader.getIteratorOverJars(args); - CodeGenerator generatorInstance = new CodeGenerator(); + StringBuilder headerFile = new StringBuilder(GENERATED_COMMENT); + headerFile.append("#ifndef GeneratedJNIWrappers_h__\n" + + "#define GeneratedJNIWrappers_h__\n\n" + + "#include \"nsXPCOMStrings.h\"\n" + + "#include \"AndroidJavaWrappers.h\"\n" + + "\n" + + "namespace mozilla {\n" + + "namespace widget {\n" + + "namespace android {\n" + + "void InitStubs(JNIEnv *jEnv);\n\n"); + + StringBuilder implementationFile = new StringBuilder(GENERATED_COMMENT); + implementationFile.append("#include \"GeneratedJNIWrappers.h\"\n" + + "#include \"AndroidBridgeUtilities.h\"\n" + + "#include \"nsXPCOMStrings.h\"\n" + + "#include \"AndroidBridge.h\"\n" + + "\n" + + "namespace mozilla {\n" + + "namespace widget {\n" + + "namespace android {\n"); + + // Used to track the calls to the various class-specific initialisation functions. + StringBuilder stubInitialiser = new StringBuilder(); + stubInitialiser.append("void InitStubs(JNIEnv *jEnv) {\n"); while (jarClassIterator.hasNext()) { - Class aClass = jarClassIterator.next(); + ClassWithOptions aClassTuple = jarClassIterator.next(); + + CodeGenerator generatorInstance; // Get an iterator over the appropriately generated methods of this class - Iterator methodIterator = new GeneratableEntryPointIterator(aClass.getDeclaredMethods()); + Iterator methodIterator = new GeneratableElementIterator(aClassTuple.wrappedClass); - // Iterate all annotated methods in this class.. + if (!methodIterator.hasNext()) { + continue; + } + generatorInstance = new CodeGenerator(aClassTuple.wrappedClass, aClassTuple.generatedName); + + stubInitialiser.append(" ").append(aClassTuple.generatedName).append("::InitStubs(jEnv);\n"); + + // Iterate all annotated members in this class.. while (methodIterator.hasNext()) { - MethodWithAnnotationInfo aMethodTuple = methodIterator.next(); - generatorInstance.generateMethod(aMethodTuple, aClass); + AnnotatableEntity aElementTuple = methodIterator.next(); + switch (aElementTuple.mEntityType) { + case METHOD: + generatorInstance.generateMethod(aElementTuple); + break; + case FIELD: + generatorInstance.generateField(aElementTuple); + break; + case CONSTRUCTOR: + generatorInstance.generateConstructor(aElementTuple); + break; + } } + headerFile.append(generatorInstance.getHeaderFileContents()); + implementationFile.append(generatorInstance.getWrapperFileContents()); } - writeOutputFiles(generatorInstance); + implementationFile.append('\n'); + stubInitialiser.append("}"); + implementationFile.append(stubInitialiser); + + implementationFile.append("\n} /* android */\n" + + "} /* widget */\n" + + "} /* mozilla */\n"); + + headerFile.append("\n} /* android */\n" + + "} /* widget */\n" + + "} /* mozilla */\n" + + "#endif\n"); + + writeOutputFiles(headerFile, implementationFile); long e = System.currentTimeMillis(); System.out.println("Annotation processing complete in " + (e - s) + "ms"); } - private static void writeOutputFiles(CodeGenerator aGenerator) { + private static void writeOutputFiles(StringBuilder aHeaderFile, StringBuilder aImplementationFile) { + FileOutputStream headerStream = null; try { - FileOutputStream outStream = new FileOutputStream(OUTFILE); - outStream.write(aGenerator.getWrapperFileContents()); + headerStream = new FileOutputStream(OUTFILE); + headerStream.write(aImplementationFile.toString().getBytes()); } catch (IOException e) { System.err.println("Unable to write " + OUTFILE + ". Perhaps a permissions issue?"); e.printStackTrace(System.err); + } finally { + if (headerStream != null) { + try { + headerStream.close(); + } catch (IOException e) { + System.err.println("Unable to close headerStream due to "+e); + e.printStackTrace(System.err); + } + } } + FileOutputStream outStream = null; try { - FileOutputStream headerStream = new FileOutputStream(HEADERFILE); - headerStream.write(aGenerator.getHeaderFileContents()); + outStream = new FileOutputStream(HEADERFILE); + outStream.write(aHeaderFile.toString().getBytes()); } catch (IOException e) { - System.err.println("Unable to write " + OUTFILE + ". Perhaps a permissions issue?"); + System.err.println("Unable to write " + HEADERFILE + ". Perhaps a permissions issue?"); e.printStackTrace(System.err); + } finally { + if (outStream != null) { + try { + outStream.close(); + } catch (IOException e) { + System.err.println("Unable to close outStream due to "+e); + e.printStackTrace(System.err); + } + } } } } \ No newline at end of file diff --git a/build/annotationProcessors/CodeGenerator.java b/build/annotationProcessors/CodeGenerator.java index 68e9018ca1c9..33971fd0e1bf 100644 --- a/build/annotationProcessors/CodeGenerator.java +++ b/build/annotationProcessors/CodeGenerator.java @@ -4,82 +4,236 @@ package org.mozilla.gecko.annotationProcessors; +import org.mozilla.gecko.annotationProcessors.classloader.AnnotatableEntity; import org.mozilla.gecko.annotationProcessors.utils.Utils; +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.HashSet; public class CodeGenerator { + private static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; + private static final Annotation[][] GETTER_ARGUMENT_ANNOTATIONS = new Annotation[0][0]; + private static final Annotation[][] SETTER_ARGUMENT_ANNOTATIONS = new Annotation[1][0]; + // Buffers holding the strings to ultimately be written to the output files. + private final StringBuilder zeroingCode = new StringBuilder(); private final StringBuilder wrapperStartupCode = new StringBuilder(); private final StringBuilder wrapperMethodBodies = new StringBuilder(); - private final StringBuilder headerFields = new StringBuilder(); - private final StringBuilder headerMethods = new StringBuilder(); + private final StringBuilder headerPublic = new StringBuilder(); + private final StringBuilder headerProtected = new StringBuilder(); private final HashSet seenClasses = new HashSet(); - private final String GENERATED_COMMENT = "// GENERATED CODE\n" + - "// Generated by the Java program at /build/annotationProcessors at compile time from\n" + - "// annotations on Java methods. To update, change the annotations on the corresponding Java\n" + - "// methods and rerun the build. Manually updating this file will cause your build to fail.\n\n"; + private final String mCClassName; + + private final Class mClassToWrap; + + private boolean mHasEncounteredDefaultConstructor; + + // Used for creating unique names for method ID fields in the face of + private final HashMap mMembersToIds = new HashMap(); + private final HashSet mTakenMemberNames = new HashSet(); + private int mNameMunger; + + public CodeGenerator(Class aClass, String aGeneratedName) { + mClassToWrap = aClass; + mCClassName = aGeneratedName; - public CodeGenerator() { // Write the file header things. Includes and so forth. // GeneratedJNIWrappers.cpp is generated as the concatenation of wrapperStartupCode with - // wrapperMethodBodies. Similarly, GeneratedJNIWrappers.h is the concatenation of headerFields - // with headerMethods. - wrapperStartupCode.append(GENERATED_COMMENT); - wrapperStartupCode.append( - "#include \"nsXPCOMStrings.h\"\n" + - "#include \"AndroidBridge.h\"\n" + - "#include \"AndroidBridgeUtilities.h\"\n" + - "\n" + - "#ifdef DEBUG\n" + - "#define ALOG_BRIDGE(args...) ALOG(args)\n" + - "#else\n" + - "#define ALOG_BRIDGE(args...) ((void)0)\n" + - "#endif\n" + - "\n" + - "using namespace mozilla;\n" + - "void AndroidBridge::InitStubs(JNIEnv *jEnv) {\n" + - " initInit();\n"); - // Now we write the various GetStaticMethodID calls here... + // wrapperMethodBodies. Similarly, GeneratedJNIWrappers.h is the concatenation of headerPublic + // with headerProtected. + wrapperStartupCode.append("void ").append(mCClassName).append("::InitStubs(JNIEnv *jEnv) {\n" + + " initInit();\n"); - headerFields.append("protected:\n\n"); - headerMethods.append(GENERATED_COMMENT); - headerMethods.append("public:\n\n"); + // Now we write the various GetStaticMethodID calls here... + headerPublic.append("class ").append(mCClassName).append(" : public AutoGlobalWrappedJavaObject {\n" + + "public:\n" + + " static void InitStubs(JNIEnv *jEnv);\n"); + headerProtected.append("protected:"); + + generateWrapperMethod(); + } + + /** + * Emit a static method which takes an instance of the class being wrapped and returns an instance + * of the C++ wrapper class backed by that object. + */ + private void generateWrapperMethod() { + headerPublic.append(" static ").append(mCClassName).append("* Wrap(jobject obj);\n" + + " ").append(mCClassName).append("(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};\n"); + + wrapperMethodBodies.append("\n").append(mCClassName).append("* ").append(mCClassName).append("::Wrap(jobject obj) {\n" + + " JNIEnv *env = GetJNIForThread();\n\n" + + " if (!env) {\n" + + " ALOG_BRIDGE(\"Aborted: No env - %s\", __PRETTY_FUNCTION__);\n" + + " return NULL;\n" + + " }\n\n" + + " ").append(mCClassName).append("* ret = new ").append(mCClassName).append("(obj, env);\n" + + " env->DeleteLocalRef(obj);\n" + + " return ret;\n" + + "}\n"); + } + + private void generateMemberCommon(Member theMethod, String aCMethodName, Class aClass) { + ensureClassHeaderAndStartup(aClass); + writeMemberIdField(theMethod, aCMethodName); + writeStartupCode(theMethod); } /** * Append the appropriate generated code to the buffers for the method provided. * - * @param aMethodTuple The Java method, plus the name for the generated method. - * @param aClass The class to which the Java method belongs. + * @param aMethodTuple The Java method, plus annotation data. */ - public void generateMethod(MethodWithAnnotationInfo aMethodTuple, Class aClass) { + public void generateMethod(AnnotatableEntity aMethodTuple) { // Unpack the tuple and extract some useful fields from the Method.. - Method aMethod = aMethodTuple.method; - String CMethodName = aMethodTuple.wrapperName; + Method theMethod = aMethodTuple.getMethod(); - String javaMethodName = aMethod.getName(); + String CMethodName = aMethodTuple.mAnnotationInfo.wrapperName; - ensureClassHeaderAndStartup(aClass); + generateMemberCommon(theMethod, CMethodName, mClassToWrap); - writeHeaderField(CMethodName); - writeStartupCode(CMethodName, javaMethodName, aMethod, aClass); + boolean isFieldStatic = Utils.isMemberStatic(theMethod); + boolean shallGenerateStatic = isFieldStatic || aMethodTuple.mAnnotationInfo.isStatic; + + Class[] parameterTypes = theMethod.getParameterTypes(); + Class returnType = theMethod.getReturnType(); // Get the C++ method signature for this method. - String implementationSignature = Utils.getCImplementationMethodSignature(aMethod, CMethodName); - String headerSignature = Utils.getCHeaderMethodSignature(aMethod, CMethodName, aMethodTuple.isStatic); + String implementationSignature = Utils.getCImplementationMethodSignature(parameterTypes, returnType, CMethodName, mCClassName); + String headerSignature = Utils.getCHeaderMethodSignature(parameterTypes, theMethod.getParameterAnnotations(), returnType, CMethodName, mCClassName, shallGenerateStatic); // Add the header signature to the header file. - headerMethods.append(headerSignature); - headerMethods.append(";\n"); + writeSignatureToHeader(headerSignature); // Use the implementation signature to generate the method body... - writeMethodBody(implementationSignature, CMethodName, aMethod, aClass, aMethodTuple.isStatic, aMethodTuple.isMultithreaded); + writeMethodBody(implementationSignature, CMethodName, theMethod, mClassToWrap, aMethodTuple.mAnnotationInfo.isStatic, aMethodTuple.mAnnotationInfo.isMultithreaded); + } + + private void generateGetterOrSetterBody(Class aFieldType, String aFieldName, boolean aIsFieldStatic, boolean isSetter) { + StringBuilder argumentContent = null; + + if (isSetter) { + Class[] setterArguments = new Class[]{aFieldType}; + // Marshall the argument.. + argumentContent = getArgumentMarshalling(setterArguments); + } + + boolean isObjectReturningMethod = Utils.isObjectType(aFieldType); + wrapperMethodBodies.append(" "); + if (isSetter) { + wrapperMethodBodies.append("env->Set"); + } else { + wrapperMethodBodies.append("return "); + + if (isObjectReturningMethod) { + wrapperMethodBodies.append("static_cast<").append(Utils.getCReturnType(aFieldType)).append(">("); + } + + wrapperMethodBodies.append("env->Get"); + } + + if (aIsFieldStatic) { + wrapperMethodBodies.append("Static"); + } + wrapperMethodBodies.append(Utils.getFieldType(aFieldType)) + .append("Field("); + + // Static will require the class and the field id. Nonstatic, the object and the field id. + if (aIsFieldStatic) { + wrapperMethodBodies.append(Utils.getClassReferenceName(mClassToWrap)); + } else { + wrapperMethodBodies.append("wrapped_obj"); + } + wrapperMethodBodies.append(", j") + .append(aFieldName); + if (isSetter) { + wrapperMethodBodies.append(argumentContent); + } + + if (!isSetter && isObjectReturningMethod) { + wrapperMethodBodies.append(')'); + } + wrapperMethodBodies.append(");\n" + + "}\n"); + } + + public void generateField(AnnotatableEntity aFieldTuple) { + Field theField = aFieldTuple.getField(); + + // Handles a peculiar case when dealing with enum types. We don't care about this field. + // It just gets in the way and stops our code from compiling. + if (theField.getName().equals("$VALUES")) { + return; + } + + String CFieldName = aFieldTuple.mAnnotationInfo.wrapperName; + + Class fieldType = theField.getType(); + + generateMemberCommon(theField, CFieldName, mClassToWrap); + + boolean isFieldStatic = Utils.isMemberStatic(theField); + boolean isFieldFinal = Utils.isMemberFinal(theField); + boolean shallGenerateStatic = isFieldStatic || aFieldTuple.mAnnotationInfo.isStatic; + + String getterName = "get" + CFieldName; + String getterSignature = Utils.getCImplementationMethodSignature(EMPTY_CLASS_ARRAY, fieldType, getterName, mCClassName); + String getterHeaderSignature = Utils.getCHeaderMethodSignature(EMPTY_CLASS_ARRAY, GETTER_ARGUMENT_ANNOTATIONS, fieldType, getterName, mCClassName, shallGenerateStatic); + + writeSignatureToHeader(getterHeaderSignature); + + writeFunctionStartupBoilerPlate(getterSignature, fieldType, isFieldStatic, true); + + generateGetterOrSetterBody(fieldType, CFieldName, isFieldStatic, false); + + // If field not final, also generate a setter function. + if (!isFieldFinal) { + String setterName = "set" + CFieldName; + + Class[] setterArguments = new Class[]{fieldType}; + + String setterSignature = Utils.getCImplementationMethodSignature(setterArguments, Void.class, setterName, mCClassName); + String setterHeaderSignature = Utils.getCHeaderMethodSignature(setterArguments, SETTER_ARGUMENT_ANNOTATIONS, Void.class, setterName, mCClassName, shallGenerateStatic); + + writeSignatureToHeader(setterHeaderSignature); + + writeFunctionStartupBoilerPlate(setterSignature, Void.class, isFieldStatic, true); + + generateGetterOrSetterBody(fieldType, CFieldName, isFieldStatic, true); + } + } + + public void generateConstructor(AnnotatableEntity aCtorTuple) { + // Unpack the tuple and extract some useful fields from the Method.. + Constructor theCtor = aCtorTuple.getConstructor(); + String CMethodName = mCClassName; + + generateMemberCommon(theCtor, mCClassName, mClassToWrap); + + String implementationSignature = Utils.getCImplementationMethodSignature(theCtor.getParameterTypes(), Void.class, CMethodName, mCClassName); + String headerSignature = Utils.getCHeaderMethodSignature(theCtor.getParameterTypes(), theCtor.getParameterAnnotations(), Void.class, CMethodName, mCClassName, false); + + // Slice off the "void " from the start of the constructor declaration. + headerSignature = headerSignature.substring(5); + implementationSignature = implementationSignature.substring(5); + + // Add the header signatures to the header file. + writeSignatureToHeader(headerSignature); + + // Use the implementation signature to generate the method body... + writeCtorBody(implementationSignature, theCtor, aCtorTuple.mAnnotationInfo.isMultithreaded); + + if (theCtor.getParameterTypes().length == 0) { + mHasEncounteredDefaultConstructor = true; + } } /** @@ -94,18 +248,169 @@ public class CodeGenerator { return; } + zeroingCode.append("jclass ") + .append(mCClassName) + .append("::") + .append(Utils.getClassReferenceName(aClass)) + .append(" = 0;\n"); + // Add a field to hold the reference... - headerFields.append("\njclass "); - headerFields.append(Utils.getClassReferenceName(aClass)); - headerFields.append(";\n"); + headerProtected.append("\n static jclass ") + .append(Utils.getClassReferenceName(aClass)) + .append(";\n"); // Add startup code to populate it.. - wrapperStartupCode.append('\n'); - wrapperStartupCode.append(Utils.getStartupLineForClass(aClass)); + wrapperStartupCode.append('\n') + .append(Utils.getStartupLineForClass(aClass)); seenClasses.add(className); } + /** + * Write out the function startup boilerplate for the method described. Check for environment + * existence, + * @param methodSignature + * @param returnType + * @param aIsStatic + * @param aIsThreaded + */ + private void writeFunctionStartupBoilerPlate(String methodSignature, Class returnType, boolean aIsStatic, boolean aIsThreaded) { + // The start-of-function boilerplate. Does the bridge exist? Does the env exist? etc. + wrapperMethodBodies.append('\n') + .append(methodSignature) + .append(" {\n"); + + wrapperMethodBodies.append(" JNIEnv *env = "); + if (!aIsThreaded) { + wrapperMethodBodies.append("AndroidBridge::GetJNIEnv();\n"); + } else { + wrapperMethodBodies.append("GetJNIForThread();\n"); + } + wrapperMethodBodies.append(" if (!env) {\n" + + " ALOG_BRIDGE(\"Aborted: No env - %s\", __PRETTY_FUNCTION__);\n" + + " return").append(Utils.getFailureReturnForType(returnType)).append(";\n" + + " }\n\n"); + } + + /** + * Write out the appropriate JNI frame pushing boilerplate for a call to the member provided ( + * which must be a constructor or method). + * + * @param aMethod A constructor/method being wrapped. + * @param aIsObjectReturningMethod Does the method being wrapped return an object? + */ + private void writeFramePushBoilerplate(Member aMethod, boolean aIsObjectReturningMethod) { + if (aMethod instanceof Field) { + throw new IllegalArgumentException("Tried to push frame for a FIELD?!"); + } + + Method m; + Constructor c; + + Class returnType; + + int localReferencesNeeded; + if (aMethod instanceof Method) { + m = (Method) aMethod; + returnType = m.getReturnType(); + localReferencesNeeded = Utils.enumerateReferenceArguments(m.getParameterTypes()); + } else { + c = (Constructor) aMethod; + returnType = Void.class; + localReferencesNeeded = Utils.enumerateReferenceArguments(c.getParameterTypes()); + } + + // Determine the number of local refs required for our local frame.. + // AutoLocalJNIFrame is not applicable here due to it's inability to handle return values. + if (aIsObjectReturningMethod) { + localReferencesNeeded++; + } + wrapperMethodBodies.append(" if (env->PushLocalFrame(").append(localReferencesNeeded).append(") != 0) {\n" + + " ALOG_BRIDGE(\"Exceptional exit of: %s\", __PRETTY_FUNCTION__);\n" + + " env->ExceptionDescribe();\n"+ + " env->ExceptionClear();\n" + + " return").append(Utils.getFailureReturnForType(returnType)).append(";\n" + + " }\n\n"); + + } + + private StringBuilder getArgumentMarshalling(Class[] argumentTypes) { + StringBuilder argumentContent = new StringBuilder(); + + // If we have >2 arguments, use the jvalue[] calling approach. + argumentContent.append(", "); + if (argumentTypes.length > 2) { + wrapperMethodBodies.append(" jvalue args[").append(argumentTypes.length).append("];\n"); + for (int aT = 0; aT < argumentTypes.length; aT++) { + wrapperMethodBodies.append(" args[").append(aT).append("].") + .append(Utils.getArrayArgumentMashallingLine(argumentTypes[aT], "a" + aT)); + } + + // The only argument is the array of arguments. + argumentContent.append("args"); + wrapperMethodBodies.append('\n'); + } else { + // Otherwise, use the vanilla calling approach. + boolean needsNewline = false; + for (int aT = 0; aT < argumentTypes.length; aT++) { + // If the argument is a string-esque type, create a jstring from it, otherwise + // it can be passed directly. + if (Utils.isCharSequence(argumentTypes[aT])) { + wrapperMethodBodies.append(" jstring j").append(aT).append(" = AndroidBridge::NewJavaString(env, a").append(aT).append(");\n"); + needsNewline = true; + // Ensure we refer to the newly constructed Java string - not to the original + // parameter to the wrapper function. + argumentContent.append('j').append(aT); + } else { + argumentContent.append('a').append(aT); + } + if (aT != argumentTypes.length - 1) { + argumentContent.append(", "); + } + } + if (needsNewline) { + wrapperMethodBodies.append('\n'); + } + } + + return argumentContent; + } + + private void writeCtorBody(String implementationSignature, Constructor theCtor, boolean aIsThreaded) { + Class[] argumentTypes = theCtor.getParameterTypes(); + + writeFunctionStartupBoilerPlate(implementationSignature, Void.class, false, aIsThreaded); + + writeFramePushBoilerplate(theCtor, false); + + // Marshall arguments for this constructor, if any... + boolean hasArguments = argumentTypes.length != 0; + + StringBuilder argumentContent = new StringBuilder(); + if (hasArguments) { + argumentContent = getArgumentMarshalling(argumentTypes); + } + + // The call into Java + wrapperMethodBodies.append(" Init(env->NewObject"); + if (argumentTypes.length > 2) { + wrapperMethodBodies.append('A'); + } + + wrapperMethodBodies.append('('); + + + // Call takes class id, method id of constructor method, then arguments. + wrapperMethodBodies.append(Utils.getClassReferenceName(mClassToWrap)).append(", "); + + wrapperMethodBodies.append(mMembersToIds.get(theCtor)) + // Tack on the arguments, if any.. + .append(argumentContent) + .append("), env);\n" + + " env->PopLocalFrame(NULL);\n" + + "}\n"); + } + /** * Generates the method body of the C++ wrapper function for the Java method indicated. * @@ -119,44 +424,11 @@ public class CodeGenerator { Class[] argumentTypes = aMethod.getParameterTypes(); Class returnType = aMethod.getReturnType(); - // The start-of-function boilerplate. Does the bridge exist? Does the env exist? etc. - wrapperMethodBodies.append('\n'); - wrapperMethodBodies.append(methodSignature); + writeFunctionStartupBoilerPlate(methodSignature, returnType, aIsStaticBridgeMethod, aIsMultithreaded); - wrapperMethodBodies.append(" {\n"); + boolean isObjectReturningMethod = !returnType.getCanonicalName().equals("void") && Utils.isObjectType(returnType); - // Static stubs check the bridge instance has been created before trying to run. - if (aIsStaticBridgeMethod) { - wrapperMethodBodies.append(" if (!sBridge) {\n" + - " ALOG_BRIDGE(\"Aborted: No sBridge - %s\", __PRETTY_FUNCTION__);\n" + - " return").append(Utils.getFailureReturnForType(returnType)).append(";\n" + - " }\n\n"); - } - wrapperMethodBodies.append(" JNIEnv *env = "); - if (!aIsMultithreaded) { - wrapperMethodBodies.append("GetJNIEnv();\n"); - } else { - wrapperMethodBodies.append("GetJNIForThread();\n"); - } - wrapperMethodBodies.append(" if (!env) {\n" + - " ALOG_BRIDGE(\"Aborted: No env - %s\", __PRETTY_FUNCTION__);\n" + - " return").append(Utils.getFailureReturnForType(returnType)).append(";\n" + - " }\n\n"); - - boolean isObjectReturningMethod = !returnType.getCanonicalName().equals("void") && Utils.doesReturnObjectType(aMethod); - - // Determine the number of local refs required for our local frame.. - // AutoLocalJNIFrame is not applicable here due to it's inability to handle return values. - int localReferencesNeeded = Utils.enumerateReferenceArguments(aMethod); - if (isObjectReturningMethod) { - localReferencesNeeded++; - } - wrapperMethodBodies.append(" if (env->PushLocalFrame(").append(localReferencesNeeded).append(") != 0) {\n" + - " ALOG_BRIDGE(\"Exceptional exit of: %s\", __PRETTY_FUNCTION__);\n" + - " env->ExceptionDescribe();\n"+ - " env->ExceptionClear();\n" + - " return").append(Utils.getFailureReturnForType(returnType)).append(";\n" + - " }\n\n"); + writeFramePushBoilerplate(aMethod, isObjectReturningMethod); // Marshall arguments, if we have any. boolean hasArguments = argumentTypes.length != 0; @@ -168,43 +440,10 @@ public class CodeGenerator { // argumentContent). StringBuilder argumentContent = new StringBuilder(); if (hasArguments) { - argumentContent.append(", "); - // If we have >2 arguments, use the jvalue[] calling approach. - if (argumentTypes.length > 2) { - wrapperMethodBodies.append(" jvalue args[").append(argumentTypes.length).append("];\n"); - for (int aT = 0; aT < argumentTypes.length; aT++) { - wrapperMethodBodies.append(" args[").append(aT).append("]."); - wrapperMethodBodies.append(Utils.getArrayArgumentMashallingLine(argumentTypes[aT], "a" + aT)); - } - - // The only argument is the array of arguments. - argumentContent.append("args"); - wrapperMethodBodies.append('\n'); - } else { - // Otherwise, use the vanilla calling approach. - boolean needsNewline = false; - for (int aT = 0; aT < argumentTypes.length; aT++) { - // If the argument is a string-esque type, create a jstring from it, otherwise - // it can be passed directly. - if (Utils.isCharSequence(argumentTypes[aT])) { - wrapperMethodBodies.append(" jstring j").append(aT).append(" = NewJavaString(env, a").append(aT).append(");\n"); - needsNewline = true; - // Ensure we refer to the newly constructed Java string - not to the original - // parameter to the wrapper function. - argumentContent.append('j').append(aT); - } else { - argumentContent.append('a').append(aT); - } - if (aT != argumentTypes.length - 1) { - argumentContent.append(", "); - } - } - if (needsNewline) { - wrapperMethodBodies.append('\n'); - } - } + argumentContent = getArgumentMarshalling(argumentTypes); } + // Allocate a temporary variable to hold the return type from Java. wrapperMethodBodies.append(" "); if (!returnType.getCanonicalName().equals("void")) { if (isObjectReturningMethod) { @@ -215,11 +454,11 @@ public class CodeGenerator { wrapperMethodBodies.append(" temp = "); } - boolean isStaticJavaMethod = Utils.isMethodStatic(aMethod); + boolean isStaticJavaMethod = Utils.isMemberStatic(aMethod); // The call into Java - wrapperMethodBodies.append("env->"); - wrapperMethodBodies.append(Utils.getCallPrefix(returnType, isStaticJavaMethod)); + wrapperMethodBodies.append("env->") + .append(Utils.getCallPrefix(returnType, isStaticJavaMethod)); if (argumentTypes.length > 2) { wrapperMethodBodies.append('A'); } @@ -227,28 +466,18 @@ public class CodeGenerator { wrapperMethodBodies.append('('); // If the underlying Java method is nonstatic, we provide the target object to the JNI. if (!isStaticJavaMethod) { - wrapperMethodBodies.append("aTarget, "); + wrapperMethodBodies.append("wrapped_obj, "); } else { - // If the stub to be generated is static, we need to use the singleton to access the class - // reference. - if (aIsStaticBridgeMethod) { - wrapperMethodBodies.append("sBridge->"); - } - // If this is a static underlyin Java method, we need to use the class reference in our + // If this is a static underlying Java method, we need to use the class reference in our // call. wrapperMethodBodies.append(Utils.getClassReferenceName(aClass)).append(", "); } - // Write the method id out.. - if (aIsStaticBridgeMethod) { - wrapperMethodBodies.append("sBridge->"); - } - wrapperMethodBodies.append('j'); - wrapperMethodBodies.append(aCMethodName); + wrapperMethodBodies.append(mMembersToIds.get(aMethod)); // Tack on the arguments, if any.. - wrapperMethodBodies.append(argumentContent); - wrapperMethodBodies.append(");\n\n"); + wrapperMethodBodies.append(argumentContent) + .append(");\n\n"); // Check for exception and return the failure value.. wrapperMethodBodies.append(" if (env->ExceptionCheck()) {\n" + @@ -257,14 +486,14 @@ public class CodeGenerator { " env->ExceptionClear();\n" + " env->PopLocalFrame(NULL);\n" + " return").append(Utils.getFailureReturnForType(returnType)).append(";\n" + - " }\n"); + " }\n\n"); // If we're returning an object, pop the callee's stack frame extracting our ref as the return // value. if (isObjectReturningMethod) { - wrapperMethodBodies.append(" "); - wrapperMethodBodies.append(Utils.getCReturnType(returnType)); - wrapperMethodBodies.append(" ret = static_cast<").append(Utils.getCReturnType(returnType)).append(">(env->PopLocalFrame(temp));\n" + + wrapperMethodBodies.append(" ") + .append(Utils.getCReturnType(returnType)) + .append(" ret = static_cast<").append(Utils.getCReturnType(returnType)).append(">(env->PopLocalFrame(temp));\n" + " return ret;\n"); } else if (!returnType.getCanonicalName().equals("void")) { // If we're a primitive-returning function, just return the directly-obtained primative @@ -279,35 +508,83 @@ public class CodeGenerator { } /** - * Generates the code to get the method id of the given method on startup. + * Generates the code to get the id of the given member on startup. * - * @param aCMethodName The C method name of the method being generated. - * @param aJavaMethodName The name of the Java method being wrapped. - * @param aMethod The Java method being wrapped. + * @param aMember The Java member being wrapped. */ - private void writeStartupCode(String aCMethodName, String aJavaMethodName, Method aMethod, Class aClass) { - wrapperStartupCode.append(" j"); - wrapperStartupCode.append(aCMethodName); - wrapperStartupCode.append(" = get"); - if (Utils.isMethodStatic(aMethod)) { + private void writeStartupCode(Member aMember) { + wrapperStartupCode.append(" ") + .append(mMembersToIds.get(aMember)) + .append(" = get"); + if (Utils.isMemberStatic(aMember)) { wrapperStartupCode.append("Static"); } - wrapperStartupCode.append("Method(\""); - wrapperStartupCode.append(aJavaMethodName); - wrapperStartupCode.append("\", \""); - wrapperStartupCode.append(Utils.getTypeSignatureString(aMethod)); - wrapperStartupCode.append("\");\n"); + + boolean isField = aMember instanceof Field; + if (isField) { + wrapperStartupCode.append("Field(\""); + } else { + wrapperStartupCode.append("Method(\""); + } + if (aMember instanceof Constructor) { + wrapperStartupCode.append(""); + } else { + wrapperStartupCode.append(aMember.getName()); + } + + wrapperStartupCode.append("\", \"") + .append(Utils.getTypeSignatureStringForMember(aMember)) + .append("\");\n"); + } + + private void writeZeroingFor(Member aMember, final String aMemberName) { + if (aMember instanceof Field) { + zeroingCode.append("jfieldID "); + } else { + zeroingCode.append("jmethodID "); + } + zeroingCode.append(mCClassName) + .append("::") + .append(aMemberName) + .append(" = 0;\n"); } /** - * Create a method id field in the header file for the C method name provided. + * Write the field declaration for the C++ id field of the given member. * - * @param aMethodName C method name to generate a method id field for. + * @param aMember Member for which an id field needs to be generated. */ - private void writeHeaderField(String aMethodName) { - headerFields.append("jmethodID j"); - headerFields.append(aMethodName); - headerFields.append(";\n"); + private void writeMemberIdField(Member aMember, final String aCMethodName) { + String memberName = 'j'+ aCMethodName; + + if (aMember instanceof Field) { + headerProtected.append(" static jfieldID "); + } else { + headerProtected.append(" static jmethodID "); + } + + while(mTakenMemberNames.contains(memberName)) { + memberName = 'j' + aCMethodName + mNameMunger; + mNameMunger++; + } + + writeZeroingFor(aMember, memberName); + mMembersToIds.put(aMember, memberName); + mTakenMemberNames.add(memberName); + + headerProtected.append(memberName) + .append(";\n"); + } + + /** + * Helper function to add a provided method signature to the public section of the generated header. + * + * @param aSignature The header to add. + */ + private void writeSignatureToHeader(String aSignature) { + headerPublic.append(" ") + .append(aSignature) + .append(";\n"); } /** @@ -315,11 +592,13 @@ public class CodeGenerator { * * @return The bytes to be written to the wrappers file. */ - public byte[] getWrapperFileContents() { + public String getWrapperFileContents() { wrapperStartupCode.append("}\n"); - wrapperStartupCode.append(wrapperMethodBodies); + zeroingCode.append(wrapperStartupCode) + .append(wrapperMethodBodies); wrapperMethodBodies.setLength(0); - return wrapperStartupCode.toString().getBytes(); + wrapperStartupCode.setLength(0); + return zeroingCode.toString(); } /** @@ -327,10 +606,13 @@ public class CodeGenerator { * * @return The bytes to be written to the header file. */ - public byte[] getHeaderFileContents() { - headerFields.append('\n'); - headerFields.append(headerMethods); - headerMethods.setLength(0); - return headerFields.toString().getBytes(); + public String getHeaderFileContents() { + if (!mHasEncounteredDefaultConstructor) { + headerPublic.append(" ").append(mCClassName).append("() : AutoGlobalWrappedJavaObject() {};\n"); + } + headerProtected.append("};\n\n"); + headerPublic.append(headerProtected); + headerProtected.setLength(0); + return headerPublic.toString(); } } diff --git a/build/annotationProcessors/classloader/AnnotatableEntity.java b/build/annotationProcessors/classloader/AnnotatableEntity.java new file mode 100644 index 000000000000..fcb9595b193e --- /dev/null +++ b/build/annotationProcessors/classloader/AnnotatableEntity.java @@ -0,0 +1,57 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.gecko.annotationProcessors.classloader; + +import org.mozilla.gecko.annotationProcessors.AnnotationInfo; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Method; + +/** + * Union type to hold either a method, field, or ctor. Allows us to iterate "The generatable stuff", despite + * the fact that such things can be of either flavour. + */ +public class AnnotatableEntity { + public enum ENTITY_TYPE {METHOD, FIELD, CONSTRUCTOR} + + private final Member mMember; + public final ENTITY_TYPE mEntityType; + + public final AnnotationInfo mAnnotationInfo; + + public AnnotatableEntity(Member aObject, AnnotationInfo aAnnotationInfo) { + mMember = aObject; + mAnnotationInfo = aAnnotationInfo; + + if (aObject instanceof Method) { + mEntityType = ENTITY_TYPE.METHOD; + } else if (aObject instanceof Field) { + mEntityType = ENTITY_TYPE.FIELD; + } else { + mEntityType = ENTITY_TYPE.CONSTRUCTOR; + } + } + + public Method getMethod() { + if (mEntityType != ENTITY_TYPE.METHOD) { + throw new UnsupportedOperationException("Attempt to cast to unsupported member type."); + } + return (Method) mMember; + } + public Field getField() { + if (mEntityType != ENTITY_TYPE.FIELD) { + throw new UnsupportedOperationException("Attempt to cast to unsupported member type."); + } + return (Field) mMember; + } + public Constructor getConstructor() { + if (mEntityType != ENTITY_TYPE.CONSTRUCTOR) { + throw new UnsupportedOperationException("Attempt to cast to unsupported member type."); + } + return (Constructor) mMember; + } +} diff --git a/build/annotationProcessors/classloader/ClassWithOptions.java b/build/annotationProcessors/classloader/ClassWithOptions.java new file mode 100644 index 000000000000..070cff8b67cd --- /dev/null +++ b/build/annotationProcessors/classloader/ClassWithOptions.java @@ -0,0 +1,15 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.gecko.annotationProcessors.classloader; + +public class ClassWithOptions { + public final Class wrappedClass; + public final String generatedName; + + public ClassWithOptions(Class someClass, String name) { + wrappedClass = someClass; + generatedName = name; + } +} diff --git a/build/annotationProcessors/classloader/IterableJarLoadingURLClassLoader.java b/build/annotationProcessors/classloader/IterableJarLoadingURLClassLoader.java index 8f81e97d45c7..7e74399ca90b 100644 --- a/build/annotationProcessors/classloader/IterableJarLoadingURLClassLoader.java +++ b/build/annotationProcessors/classloader/IterableJarLoadingURLClassLoader.java @@ -21,8 +21,6 @@ import java.util.jar.JarFile; * classNames is kept sorted to ensure iteration order is consistent across program invocations. * Otherwise, we'd forever be reporting the outdatedness of the generated code as we permute its * contents. - * This classloader does not support inner classes. (You probably shouldn't be putting JNI entry - * points in inner classes anyway) */ public class IterableJarLoadingURLClassLoader extends URLClassLoader { LinkedList classNames = new LinkedList(); @@ -35,7 +33,7 @@ public class IterableJarLoadingURLClassLoader extends URLClassLoader { * @param args A list of jar file names an iterator over the classes of which is desired. * @return An iterator over the top level classes in the jar files provided, in arbitrary order. */ - public static Iterator> getIteratorOverJars(String[] args) { + public static Iterator getIteratorOverJars(String[] args) { URL[] urlArray = new URL[args.length]; LinkedList aClassNames = new LinkedList(); @@ -51,10 +49,7 @@ public class IterableJarLoadingURLClassLoader extends URLClassLoader { continue; } final String className = fName.substring(0, fName.length() - 6).replace('/', '.'); - // Inner classes are not supported. - if (className.contains("$")) { - continue; - } + aClassNames.add(className); } } catch (IOException e) { diff --git a/build/annotationProcessors/classloader/JarClassIterator.java b/build/annotationProcessors/classloader/JarClassIterator.java index c4f7f05e88ab..08a03ed4d912 100644 --- a/build/annotationProcessors/classloader/JarClassIterator.java +++ b/build/annotationProcessors/classloader/JarClassIterator.java @@ -4,12 +4,15 @@ package org.mozilla.gecko.annotationProcessors.classloader; +import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.Iterator; /** * Class for iterating over an IterableJarLoadingURLClassLoader's classes. */ -public class JarClassIterator implements Iterator> { +public class JarClassIterator implements Iterator { private IterableJarLoadingURLClassLoader mTarget; private Iterator mTargetClassListIterator; @@ -24,10 +27,44 @@ public class JarClassIterator implements Iterator> { } @Override - public Class next() { + public ClassWithOptions next() { String className = mTargetClassListIterator.next(); try { - return mTarget.loadClass(className); + Class ret = mTarget.loadClass(className); + if (ret.getCanonicalName() == null || "null".equals(ret.getCanonicalName())) { + // Anonymous inner class - unsupported. + return next(); + } else { + String generateName = null; + for (Annotation annotation : ret.getAnnotations()) { + Class annotationType = annotation.annotationType(); + if (annotationType.getCanonicalName().equals("org.mozilla.gecko.mozglue.generatorannotations.GeneratorOptions")) { + try { + // Determine the explicitly-given name of the stub to generate, if any. + final Method generateNameMethod = annotationType.getDeclaredMethod("generatedClassName"); + generateNameMethod.setAccessible(true); + generateName = (String) generateNameMethod.invoke(annotation); + break; + } catch (NoSuchMethodException e) { + System.err.println("Unable to find expected field on GeneratorOptions annotation. Did the signature change?"); + e.printStackTrace(System.err); + System.exit(3); + } catch (IllegalAccessException e) { + System.err.println("IllegalAccessException reading fields on GeneratorOptions annotation. Seems the semantics of Reflection have changed..."); + e.printStackTrace(System.err); + System.exit(4); + } catch (InvocationTargetException e) { + System.err.println("InvocationTargetException reading fields on GeneratorOptions annotation. This really shouldn't happen."); + e.printStackTrace(System.err); + System.exit(5); + } + } + } + if (generateName == null) { + generateName = ret.getSimpleName(); + } + return new ClassWithOptions(ret, generateName); + } } catch (ClassNotFoundException e) { System.err.println("Unable to enumerate class: " + className + ". Corrupted jar file?"); e.printStackTrace(); diff --git a/build/annotationProcessors/moz.build b/build/annotationProcessors/moz.build index 1d5abc06f2d4..1fbf9938518e 100644 --- a/build/annotationProcessors/moz.build +++ b/build/annotationProcessors/moz.build @@ -6,12 +6,14 @@ jar = add_java_jar('annotationProcessors') jar.sources += [ + 'AnnotationInfo.java', 'AnnotationProcessor.java', + 'classloader/AnnotatableEntity.java', + 'classloader/ClassWithOptions.java', 'classloader/IterableJarLoadingURLClassLoader.java', 'classloader/JarClassIterator.java', 'CodeGenerator.java', - 'MethodWithAnnotationInfo.java', - 'utils/AlphabeticMethodComparator.java', - 'utils/GeneratableEntryPointIterator.java', + 'utils/AlphabeticAnnotatableEntityComparator.java', + 'utils/GeneratableElementIterator.java', 'utils/Utils.java', ] diff --git a/build/annotationProcessors/utils/AlphabeticAnnotatableEntityComparator.java b/build/annotationProcessors/utils/AlphabeticAnnotatableEntityComparator.java new file mode 100644 index 000000000000..f280d4583f01 --- /dev/null +++ b/build/annotationProcessors/utils/AlphabeticAnnotatableEntityComparator.java @@ -0,0 +1,81 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.gecko.annotationProcessors.utils; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.util.Comparator; + +public class AlphabeticAnnotatableEntityComparator implements Comparator { + @Override + public int compare(T aLhs, T aRhs) { + // Constructors, Methods, Fields. + boolean lIsConstructor = aLhs instanceof Constructor; + boolean rIsConstructor = aRhs instanceof Constructor; + boolean lIsMethod = aLhs instanceof Method; + boolean rIsField = aRhs instanceof Field; + + if (lIsConstructor) { + if (!rIsConstructor) { + return -1; + } + } else if (lIsMethod) { + if (rIsConstructor) { + return 1; + } else if (rIsField) { + return -1; + } + } else { + if (!rIsField) { + return 1; + } + } + + // Verify these objects are the same type and cast them. + if (aLhs instanceof Method) { + return compare((Method) aLhs, (Method) aRhs); + } else if (aLhs instanceof Field) { + return compare((Field) aLhs, (Field) aRhs); + } else { + return compare((Constructor) aLhs, (Constructor) aRhs); + } + } + + // Alas, the type system fails us. + private static int compare(Method aLhs, Method aRhs) { + // Initially, attempt to differentiate the methods be name alone.. + String lName = aLhs.getName(); + String rName = aRhs.getName(); + + int ret = lName.compareTo(rName); + if (ret != 0) { + return ret; + } + + // The names were the same, so we need to compare signatures to find their uniqueness.. + lName = Utils.getTypeSignatureStringForMethod(aLhs); + rName = Utils.getTypeSignatureStringForMethod(aRhs); + + return lName.compareTo(rName); + } + + private static int compare(Constructor aLhs, Constructor aRhs) { + // The names will be the same, so we need to compare signatures to find their uniqueness.. + String lName = Utils.getTypeSignatureString(aLhs); + String rName = Utils.getTypeSignatureString(aRhs); + + return lName.compareTo(rName); + } + + private static int compare(Field aLhs, Field aRhs) { + // Compare field names.. + String lName = aLhs.getName(); + String rName = aRhs.getName(); + + return lName.compareTo(rName); + } +} diff --git a/build/annotationProcessors/utils/AlphabeticMethodComparator.java b/build/annotationProcessors/utils/AlphabeticMethodComparator.java deleted file mode 100644 index 990662e6a1b8..000000000000 --- a/build/annotationProcessors/utils/AlphabeticMethodComparator.java +++ /dev/null @@ -1,28 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.annotationProcessors.utils; - -import java.lang.reflect.Method; -import java.util.Comparator; - -public class AlphabeticMethodComparator implements Comparator { - @Override - public int compare(Method lhs, Method rhs) { - // Initially, attempt to differentiate the methods be name alone.. - String lName = lhs.getName(); - String rName = rhs.getName(); - - int ret = lName.compareTo(rName); - if (ret != 0) { - return ret; - } - - // The names were the same, so we need to compare signatures to find their uniqueness.. - lName = Utils.getTypeSignatureString(lhs); - rName = Utils.getTypeSignatureString(rhs); - - return lName.compareTo(rName); - } -} diff --git a/build/annotationProcessors/utils/GeneratableEntryPointIterator.java b/build/annotationProcessors/utils/GeneratableElementIterator.java similarity index 52% rename from build/annotationProcessors/utils/GeneratableEntryPointIterator.java rename to build/annotationProcessors/utils/GeneratableElementIterator.java index 39c3272f8f97..4dd7cbb7d8ac 100644 --- a/build/annotationProcessors/utils/GeneratableEntryPointIterator.java +++ b/build/annotationProcessors/utils/GeneratableElementIterator.java @@ -4,31 +4,57 @@ package org.mozilla.gecko.annotationProcessors.utils; -import org.mozilla.gecko.annotationProcessors.MethodWithAnnotationInfo; +import org.mozilla.gecko.annotationProcessors.AnnotationInfo; +import org.mozilla.gecko.annotationProcessors.classloader.AnnotatableEntity; import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Member; import java.lang.reflect.Method; import java.util.Arrays; -import java.util.Collections; import java.util.Iterator; -import java.util.List; /** - * Iterator over the methods in a given method list which have the GeneratableAndroidBridgeTarget + * Iterator over the methods in a given method list which have the WrappedJNIMethod * annotation. Returns an object containing both the annotation (Which may contain interesting * parameters) and the argument. */ -public class GeneratableEntryPointIterator implements Iterator { - private final Method[] mMethods; - private MethodWithAnnotationInfo mNextReturnValue; - private int mMethodIndex; +public class GeneratableElementIterator implements Iterator { + private final Member[] mObjects; + private AnnotatableEntity mNextReturnValue; + private int mElementIndex; - public GeneratableEntryPointIterator(Method[] aMethods) { - // Sort the methods into alphabetical order by name, to ensure we always iterate methods - // in the same order.. - Arrays.sort(aMethods, new AlphabeticMethodComparator()); - mMethods = aMethods; + private boolean mIterateEveryEntry; + + public GeneratableElementIterator(Class aClass) { + // Get all the elements of this class as AccessibleObjects. + Member[] aMethods = aClass.getDeclaredMethods(); + Member[] aFields = aClass.getDeclaredFields(); + Member[] aCtors = aClass.getConstructors(); + + // Shove them all into one buffer. + Member[] objs = new Member[aMethods.length + aFields.length + aCtors.length]; + + int offset = 0; + System.arraycopy(aMethods, 0, objs, 0, aMethods.length); + offset += aMethods.length; + System.arraycopy(aFields, 0, objs, offset, aFields.length); + offset += aFields.length; + System.arraycopy(aCtors, 0, objs, offset, aCtors.length); + + // Sort the elements to ensure determinism. + Arrays.sort(objs, new AlphabeticAnnotatableEntityComparator()); + mObjects = objs; + + // Check for "Wrap ALL the things" flag. + for (Annotation annotation : aClass.getDeclaredAnnotations()) { + final String annotationTypeName = annotation.annotationType().getName(); + if (annotationTypeName.equals("org.mozilla.gecko.mozglue.generatorannotations.WrapEntireClassForJNI")) { + mIterateEveryEntry = true; + break; + } + } findNextValue(); } @@ -38,15 +64,14 @@ public class GeneratableEntryPointIterator implements Iterator annotationType = annotation.annotationType(); final String annotationTypeName = annotationType.getName(); - - if (annotationTypeName.equals("org.mozilla.gecko.mozglue.GeneratableAndroidBridgeTarget")) { + if (annotationTypeName.equals("org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI")) { String stubName = null; boolean isStaticStub = false; boolean isMultithreadedStub = false; @@ -66,28 +91,38 @@ public class GeneratableEntryPointIterator implements Iterator sFieldTypes = new HashMap(); + + 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 sFailureReturns = new HashMap(); static { + sFailureReturns.put("java.lang.Void", ""); sFailureReturns.put("void", ""); sFailureReturns.put("int", " 0"); sFailureReturns.put("boolean", " false"); @@ -87,6 +104,7 @@ public class Utils { private static final HashMap sCanonicalSignatureParts = new HashMap(); static { + sCanonicalSignatureParts.put("java/lang/Void", "V"); sCanonicalSignatureParts.put("void", "V"); sCanonicalSignatureParts.put("int", "I"); sCanonicalSignatureParts.put("boolean", "Z"); @@ -164,7 +182,9 @@ public class Utils { * @return A string representation of the C++ return type. */ public static String getCReturnType(Class type) { - // Since there's only one thing we want to do differently... + if (type.getCanonicalName().equals("java.lang.Void")) { + return "void"; + } String cParameterType = getCParameterType(type); if (cParameterType.equals("const nsAString&")) { return "jstring"; @@ -173,6 +193,21 @@ public class Utils { } } + /** + * Gets the type-specific part of the JNI function to use to get or set a field of a given type. + * + * @param aFieldType The Java type of the field. + * @return A string representation of the JNI call function substring to use. + */ + public static String getFieldType(Class aFieldType) { + String name = aFieldType.getCanonicalName(); + + if (sFieldTypes.containsKey(name)) { + return sFieldTypes.get(name); + } + return "Object"; + } + /** * Gets the appropriate JNI call function to use to invoke a Java method with the given return * type. This, plus a call postfix (Such as "A") forms a complete JNI call function name. @@ -212,29 +247,91 @@ public class Utils { } /** - * Get the canonical JNI type signature for a method. + * 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) * - * @param aMethod The method to generate a signature for. - * @return The canonical JNI type signature for this method. + * @param arguments Argument types of the underlying method. + * @param returnType Return type of the underlying method. + * @return The canonical Java type string for the method. eg. (IIIIFZ)Lorg/mozilla/gecko/gfx/ViewTransform; */ - public static String getTypeSignatureString(Method aMethod) { - Class[] arguments = aMethod.getParameterTypes(); - Class returnType = aMethod.getReturnType(); - + 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(); } /** - * Helper method used by getTypeSignatureString to build the signature. Write the subsignature + * Get the canonical JNI type signature for a Field. + * + * @param aField The field to generate a signature for. + * @return The canonical JNI type signature for this method. + */ + protected static String getTypeSignatureStringForField(Field aField) { + StringBuilder sb = new StringBuilder(); + writeTypeSignature(sb, aField.getType()); + return sb.toString(); + } + + /** + * Get the canonical JNI type signature for a method. + * + * @param aMethod The method to generate a signature for. + * @return The canonical JNI type signature for this method. + */ + protected static String getTypeSignatureStringForMethod(Method aMethod) { + Class[] arguments = aMethod.getParameterTypes(); + Class returnType = aMethod.getReturnType(); + return getTypeSignatureInternal(arguments, returnType); + } + + /** + * Get the canonical JNI type signature for a Constructor. + * + * @param aConstructor The Constructor to generate a signature for. + * @return The canonical JNI type signature for this method. + */ + protected static String getTypeSignatureStringForConstructor(Constructor aConstructor) { + Class[] arguments = aConstructor.getParameterTypes(); + return getTypeSignatureInternal(arguments, Void.class); + } + + public static String getTypeSignatureStringForMember(Member aMember) { + if (aMember instanceof Method) { + return getTypeSignatureStringForMethod((Method) aMember); + } else if (aMember instanceof Field) { + return getTypeSignatureStringForField((Field) aMember); + } else { + return getTypeSignatureStringForConstructor((Constructor) aMember); + } + } + + public static String getTypeSignatureString(Constructor aConstructor) { + Class[] arguments = aConstructor.getParameterTypes(); + StringBuilder sb = new StringBuilder(); + sb.append('('); + + // For each argument, write its signature component to the buffer.. + for (int i = 0; i < arguments.length; i++) { + writeTypeSignature(sb, arguments[i]); + } + + // Constructors always return Void. + sb.append(")V"); + return sb.toString(); + } + + /** + * Helper method used by getTypeSignatureStringForMethod to build the signature. Write the subsignature * of a given type into the buffer. * * @param sb The buffer to write into. @@ -242,6 +339,7 @@ public class Utils { */ private static void writeTypeSignature(StringBuilder sb, Class c) { String name = c.getCanonicalName().replaceAll("\\.", "/"); + // Determine if this is an array type and, if so, peel away the array operators.. int len = name.length(); while (name.endsWith("[]")) { @@ -250,6 +348,17 @@ public class Utils { 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. @@ -266,38 +375,31 @@ public class Utils { * Produces a C method signature, sans semicolon, for the given Java Method. Useful for both * generating header files and method bodies. * - * @param aMethod The Java method to generate the corresponding wrapper signature for. - * @param aCMethodName The name of the generated method this is to be the signatgure for. - * @return The generated method signature. + * @param aArgumentTypes Argument types of the Java method being wrapped. + * @param 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(Method aMethod, String aCMethodName) { - Class[] argumentTypes = aMethod.getParameterTypes(); - Class returnType = aMethod.getReturnType(); - + public static String getCImplementationMethodSignature(Class[] aArgumentTypes, Class aReturnType, String aCMethodName, String aCClassName) { StringBuilder retBuffer = new StringBuilder(); - // Write return type.. - retBuffer.append(getCReturnType(returnType)); - retBuffer.append(" AndroidBridge::"); + + retBuffer.append(getCReturnType(aReturnType)); + retBuffer.append(' '); + retBuffer.append(aCClassName); + retBuffer.append("::"); retBuffer.append(aCMethodName); retBuffer.append('('); - // For an instance method, the first argument is the target object. - if (!isMethodStatic(aMethod)) { - retBuffer.append("jobject aTarget"); - if (argumentTypes.length > 0) { - retBuffer.append(", "); - } - } - // Write argument types... - for (int aT = 0; aT < argumentTypes.length; aT++) { - retBuffer.append(getCParameterType(argumentTypes[aT])); + for (int aT = 0; aT < aArgumentTypes.length; aT++) { + retBuffer.append(getCParameterType(aArgumentTypes[aT])); retBuffer.append(" a"); // We, imaginatively, call our arguments a1, a2, a3... // The only way to preserve the names from Java would be to parse the // Java source, which would be computationally hard. retBuffer.append(aT); - if (aT != argumentTypes.length - 1) { + if (aT != aArgumentTypes.length - 1) { retBuffer.append(", "); } } @@ -309,18 +411,16 @@ public class Utils { * Produces a C method signature, sans semicolon, for the given Java Method. Useful for both * generating header files and method bodies. * - * @param aMethod The Java method to generate the corresponding wrapper signature for. - * @param aCMethodName The name of the generated method this is to be the signatgure for. - * @return The generated method signature. + * @param aArgumentTypes Argument types of the Java method being wrapped. + * @param aArgumentAnnotations The annotations on the Java method arguments. Used to specify + * default values etc. + * @param aReturnType Return type of the Java method being wrapped. + * @param aCMethodName Name of the method to generate in the C++ class. + * @param aCClassName Name of the C++ class into which the method is declared.e + * @param aIsStaticStub true if the generated C++ method should be static, false otherwise. + * @return The generated C++ header method signature for the method described. */ - public static String getCHeaderMethodSignature(Method aMethod, String aCMethodName, boolean aIsStaticStub) { - Class[] argumentTypes = aMethod.getParameterTypes(); - - // The annotations on the parameters of this method, in declaration order. - // Importantly - the same order as those in argumentTypes. - Annotation[][] argumentAnnotations = aMethod.getParameterAnnotations(); - Class returnType = aMethod.getReturnType(); - + public static String getCHeaderMethodSignature(Class[] aArgumentTypes, Annotation[][] aArgumentAnnotations, Class aReturnType, String aCMethodName, String aCClassName, boolean aIsStaticStub) { StringBuilder retBuffer = new StringBuilder(); // Add the static keyword, if applicable. @@ -329,22 +429,14 @@ public class Utils { } // Write return type.. - retBuffer.append(getCReturnType(returnType)); + retBuffer.append(getCReturnType(aReturnType)); retBuffer.append(' '); retBuffer.append(aCMethodName); retBuffer.append('('); - // For an instance method, the first argument is the target object. - if (!isMethodStatic(aMethod)) { - retBuffer.append("jobject aTarget"); - if (argumentTypes.length > 0) { - retBuffer.append(", "); - } - } - // Write argument types... - for (int aT = 0; aT < argumentTypes.length; aT++) { - retBuffer.append(getCParameterType(argumentTypes[aT])); + for (int aT = 0; aT < aArgumentTypes.length; aT++) { + retBuffer.append(getCParameterType(aArgumentTypes[aT])); retBuffer.append(" a"); // We, imaginatively, call our arguments a1, a2, a3... // The only way to preserve the names from Java would be to parse the @@ -352,9 +444,9 @@ public class Utils { retBuffer.append(aT); // Append the default value, if there is one.. - retBuffer.append(getDefaultValueString(argumentTypes[aT], argumentAnnotations[aT])); + retBuffer.append(getDefaultValueString(aArgumentTypes[aT], aArgumentAnnotations[aT])); - if (aT != argumentTypes.length - 1) { + if (aT != aArgumentTypes.length - 1) { retBuffer.append(", "); } } @@ -376,7 +468,7 @@ public class Utils { for (int i = 0; i < aArgumentAnnotations.length; i++) { Class annotationType = aArgumentAnnotations[i].annotationType(); final String annotationTypeName = annotationType.getName(); - if (annotationTypeName.equals("org.mozilla.gecko.mozglue.OptionalGeneratedParameter")) { + if (annotationTypeName.equals("org.mozilla.gecko.mozglue.generatorannotations.OptionalGeneratedParameter")) { return " = " + getDefaultParameterValueForType(aArgumentType); } } @@ -406,14 +498,13 @@ public class Utils { /** * Helper method that returns the number of reference types in the arguments of m. * - * @param m The method to consider. + * @param aArgs The method arguments to consider. * @return How many of the arguments of m are nonprimitive. */ - public static int enumerateReferenceArguments(Method m) { + public static int enumerateReferenceArguments(Class[] aArgs) { int ret = 0; - Class[] args = m.getParameterTypes(); - for (int i = 0; i < args.length; i++) { - String name = args[i].getCanonicalName(); + for (int i = 0; i < aArgs.length; i++) { + String name = aArgs[i].getCanonicalName(); if (!sBasicCTypes.containsKey(name)) { ret++; } @@ -453,7 +544,7 @@ public class Utils { sb.append(" = ").append(argName).append(";\n"); } else { if (isCharSequence(type)) { - sb.append("l = NewJavaString(env, ").append(argName).append(");\n"); + sb.append("l = AndroidBridge::NewJavaString(env, ").append(argName).append(");\n"); } else { sb.append("l = ").append(argName).append(";\n"); } @@ -463,15 +554,13 @@ public class Utils { } /** - * Returns true if the method provided returns an object type. Returns false if it returns a - * primitive type. + * Returns true if the type provided is an object type. Returns false otherwise * - * @param aMethod The method to consider. - * @return true if the method provided returns an object type, false otherwise. + * @param aType The type to consider. + * @return true if the method provided is an object type, false otherwise. */ - public static boolean doesReturnObjectType(Method aMethod) { - Class returnType = aMethod.getReturnType(); - return !sBasicCTypes.containsKey(returnType.getCanonicalName()); + public static boolean isObjectType(Class aType) { + return !sBasicCTypes.containsKey(aType.getCanonicalName()); } /** @@ -496,7 +585,16 @@ public class Utils { sb.append(" "); sb.append(getClassReferenceName(aClass)); sb.append(" = getClassGlobalRef(\""); - sb.append(aClass.getCanonicalName().replaceAll("\\.", "/")); + + String name = aClass.getCanonicalName().replaceAll("\\.", "/"); + Class containerClass = aClass.getDeclaringClass(); + if (containerClass != null) { + // Is an inner class. Add the $ symbol. + final int lastSlash = name.lastIndexOf('/'); + name = name.substring(0, lastSlash) + '$' + name.substring(lastSlash+1); + } + + sb.append(name); sb.append("\");\n"); return sb.toString(); } @@ -521,11 +619,21 @@ public class Utils { /** * Helper method to read the modifier bits of the given method to determine if it is static. - * @param aMethod The Method to check. + * @param aMember The Member to check. * @return true of the method is declared static, false otherwise. */ - public static boolean isMethodStatic(Method aMethod) { - int aMethodModifiers = aMethod.getModifiers(); + 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); + } } diff --git a/configure.in b/configure.in index 247ffd69b06b..8ad62cf46897 100644 --- a/configure.in +++ b/configure.in @@ -368,6 +368,17 @@ if test -n "$GNU_CC" -a -z "$CLANG_CC" ; then fi fi +dnl ======================================================== +dnl Disable compiling sources in unified mode. +dnl ======================================================== + +MOZ_ARG_DISABLE_BOOL(unified-compilation, +[ --disable-unified-compilation + Disable unified compilation of some C/C++ sources], + MOZ_DISABLE_UNIFIED_COMPILATION=1, + MOZ_DISABLE_UNIFIED_COMPILATION=) +AC_SUBST(MOZ_DISABLE_UNIFIED_COMPILATION) + dnl ======================================================== dnl Special win32 checks dnl ======================================================== diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 596da8ed662f..0c0a79f0bdfd 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -1792,8 +1792,8 @@ ContentParent::RecvGetShowPasswordSetting(bool* showPassword) *showPassword = true; #ifdef MOZ_WIDGET_ANDROID NS_ASSERTION(AndroidBridge::Bridge() != nullptr, "AndroidBridge is not available"); - if (AndroidBridge::Bridge() != nullptr) - *showPassword = AndroidBridge::Bridge()->GetShowPasswordSetting(); + + *showPassword = GeckoAppShell::GetShowPasswordSetting(); #endif return true; } diff --git a/dom/plugins/base/nsNPAPIPlugin.cpp b/dom/plugins/base/nsNPAPIPlugin.cpp index fd6bd0ee0cfd..d9f979ad01ee 100644 --- a/dom/plugins/base/nsNPAPIPlugin.cpp +++ b/dom/plugins/base/nsNPAPIPlugin.cpp @@ -2262,11 +2262,7 @@ _getvalue(NPP npp, NPNVariable variable, void *result) } case kJavaContext_ANPGetValue: { - AndroidBridge *bridge = AndroidBridge::Bridge(); - if (!bridge) - return NPERR_GENERIC_ERROR; - - jobject ret = bridge->GetContext(); + jobject ret = GeckoAppShell::GetContext(); if (!ret) return NPERR_GENERIC_ERROR; diff --git a/dom/plugins/base/nsNPAPIPluginInstance.cpp b/dom/plugins/base/nsNPAPIPluginInstance.cpp index eff1eaa82163..f95c62bd4550 100644 --- a/dom/plugins/base/nsNPAPIPluginInstance.cpp +++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp @@ -868,7 +868,7 @@ void nsNPAPIPluginInstance::NotifyFullScreen(bool aFullScreen) SendLifecycleEvent(this, mFullScreen ? kEnterFullScreen_ANPLifecycleAction : kExitFullScreen_ANPLifecycleAction); if (mFullScreen && mFullScreenOrientation != dom::eScreenOrientation_None) { - AndroidBridge::Bridge()->LockScreenOrientation(mFullScreenOrientation); + GeckoAppShell::LockScreenOrientation(mFullScreenOrientation); } } @@ -925,11 +925,11 @@ void nsNPAPIPluginInstance::SetFullScreenOrientation(uint32_t orientation) // We're already fullscreen so immediately apply the orientation change if (mFullScreenOrientation != dom::eScreenOrientation_None) { - AndroidBridge::Bridge()->LockScreenOrientation(mFullScreenOrientation); + GeckoAppShell::LockScreenOrientation(mFullScreenOrientation); } else if (oldOrientation != dom::eScreenOrientation_None) { // We applied an orientation when we entered fullscreen, but // we don't want it anymore - AndroidBridge::Bridge()->UnlockScreenOrientation(); + GeckoAppShell::UnlockScreenOrientation(); } } } diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index 841e93a62f08..959d38f75755 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -1672,9 +1672,7 @@ void nsPluginInstanceOwner::RemovePluginView() if (!mInstance || !mJavaView) return; - if (AndroidBridge::Bridge()) - AndroidBridge::Bridge()->RemovePluginView((jobject)mJavaView, mFullScreen); - + GeckoAppShell::RemovePluginView((jobject)mJavaView, mFullScreen); AndroidBridge::GetJNIEnv()->DeleteGlobalRef((jobject)mJavaView); mJavaView = nullptr; diff --git a/dom/system/android/AndroidLocationProvider.cpp b/dom/system/android/AndroidLocationProvider.cpp index a4105577a2fb..e26204fb1448 100644 --- a/dom/system/android/AndroidLocationProvider.cpp +++ b/dom/system/android/AndroidLocationProvider.cpp @@ -26,9 +26,7 @@ AndroidLocationProvider::~AndroidLocationProvider() NS_IMETHODIMP AndroidLocationProvider::Startup() { - if (!AndroidBridge::Bridge()) - return NS_ERROR_NOT_IMPLEMENTED; - AndroidBridge::Bridge()->EnableLocation(true); + GeckoAppShell::EnableLocation(true); return NS_OK; } @@ -44,17 +42,13 @@ AndroidLocationProvider::Watch(nsIGeolocationUpdate* aCallback) NS_IMETHODIMP AndroidLocationProvider::Shutdown() { - if (!AndroidBridge::Bridge()) - return NS_ERROR_NOT_IMPLEMENTED; - AndroidBridge::Bridge()->EnableLocation(false); + GeckoAppShell::EnableLocation(false); return NS_OK; } NS_IMETHODIMP AndroidLocationProvider::SetHighAccuracy(bool enable) { - if (!AndroidBridge::Bridge()) - return NS_ERROR_NOT_IMPLEMENTED; - AndroidBridge::Bridge()->EnableLocationHighAccuracy(enable); + GeckoAppShell::EnableLocationHighAccuracy(enable); return NS_OK; } diff --git a/dom/system/android/nsHapticFeedback.cpp b/dom/system/android/nsHapticFeedback.cpp index c24e97b3f51f..4e0bba6aa223 100644 --- a/dom/system/android/nsHapticFeedback.cpp +++ b/dom/system/android/nsHapticFeedback.cpp @@ -14,10 +14,6 @@ NS_IMPL_ISUPPORTS1(nsHapticFeedback, nsIHapticFeedback) NS_IMETHODIMP nsHapticFeedback::PerformSimpleAction(int32_t aType) { - AndroidBridge* bridge = AndroidBridge::Bridge(); - if (bridge) { - bridge->PerformHapticFeedback(aType == LongPress); - return NS_OK; - } - return NS_ERROR_FAILURE; + GeckoAppShell::PerformHapticFeedback(aType == LongPress); + return NS_OK; } diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h index 916d367f0e54..bbd31183e9fc 100644 --- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -2515,7 +2515,7 @@ public: #endif virtual already_AddRefed - CreateDirectTextureImage(android::GraphicBuffer* aBuffer, GLenum aWrapMode) + CreateDirectTextureImage(::android::GraphicBuffer* aBuffer, GLenum aWrapMode) { return nullptr; } // Before reads from offscreen texture diff --git a/gfx/layers/Compositor.h b/gfx/layers/Compositor.h index 23c700c6d692..41f9edc62819 100644 --- a/gfx/layers/Compositor.h +++ b/gfx/layers/Compositor.h @@ -15,6 +15,7 @@ #include "mozilla/layers/CompositorTypes.h" // for DiagnosticTypes, etc #include "mozilla/layers/LayersTypes.h" // for LayersBackend #include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc +#include "nsRegion.h" /** * Different elements of a web pages are rendered into separate "layers" before @@ -291,16 +292,24 @@ public: /** * Start a new frame. + * + * aInvalidRect is the invalid region of the screen; it can be ignored for + * compositors where the performance for compositing the entire window is + * sufficient. + * * aClipRectIn is the clip rect for the window in window space (optional). * aTransform is the transform from user space to window space. * aRenderBounds bounding rect for rendering, in user space. + * * If aClipRectIn is null, this method sets *aClipRectOut to the clip rect * actually used for rendering (if aClipRectIn is non-null, we will use that * for the clip rect). + * * If aRenderBoundsOut is non-null, it will be set to the render bounds * actually used by the compositor in window space. */ - virtual void BeginFrame(const gfx::Rect* aClipRectIn, + virtual void BeginFrame(const nsIntRegion& aInvalidRegion, + const gfx::Rect* aClipRectIn, const gfxMatrix& aTransform, const gfx::Rect& aRenderBounds, gfx::Rect* aClipRectOut = nullptr, diff --git a/gfx/layers/LayerTreeInvalidation.cpp b/gfx/layers/LayerTreeInvalidation.cpp index a8f9bcba0e1b..152b001a3b92 100644 --- a/gfx/layers/LayerTreeInvalidation.cpp +++ b/gfx/layers/LayerTreeInvalidation.cpp @@ -110,6 +110,7 @@ struct LayerPropertiesBase : public LayerProperties : mLayer(aLayer) , mMaskLayer(nullptr) , mVisibleRegion(aLayer->GetVisibleRegion()) + , mInvalidRegion(aLayer->GetInvalidRegion()) , mTransform(aLayer->GetTransform()) , mOpacity(aLayer->GetOpacity()) , mUseClipRect(!!aLayer->GetClipRect()) @@ -201,6 +202,7 @@ struct LayerPropertiesBase : public LayerProperties nsRefPtr mLayer; nsAutoPtr mMaskLayer; nsIntRegion mVisibleRegion; + nsIntRegion mInvalidRegion; gfx3DMatrix mTransform; float mOpacity; nsIntRect mClipRect; @@ -320,7 +322,6 @@ struct ImageLayerProperties : public LayerPropertiesBase { ImageLayerProperties(ImageLayer* aImage) : LayerPropertiesBase(aImage) - , mVisibleRegion(aImage->GetVisibleRegion()) , mContainer(aImage->GetContainer()) , mFilter(aImage->GetFilter()) , mScaleToSize(aImage->GetScaleToSize()) @@ -348,7 +349,6 @@ struct ImageLayerProperties : public LayerPropertiesBase return nsIntRect(); } - nsIntRegion mVisibleRegion; nsRefPtr mContainer; GraphicsFilter mFilter; gfxIntSize mScaleToSize; diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index 66890aa27da1..acd2823ee8b2 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -1223,6 +1223,7 @@ public: * marked as needed to be recomposited. */ const nsIntRegion& GetInvalidRegion() { return mInvalidRegion; } + const void SetInvalidRegion(const nsIntRegion& aRect) { mInvalidRegion = aRect; } /** * Mark the entirety of the layer's visible region as being invalid. diff --git a/gfx/layers/basic/BasicCompositor.cpp b/gfx/layers/basic/BasicCompositor.cpp index 4c6071497efb..acdd5fce4280 100644 --- a/gfx/layers/basic/BasicCompositor.cpp +++ b/gfx/layers/basic/BasicCompositor.cpp @@ -418,9 +418,7 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect, gfx::Float aOpacity, const gfx::Matrix4x4 &aTransform) { - RefPtr buffer = mRenderTarget - ? mRenderTarget->mDrawTarget - : mDrawTarget; + RefPtr buffer = mRenderTarget->mDrawTarget; // For 2D drawing, |dest| and |buffer| are the same surface. For 3D drawing, // |dest| is a temporary surface. @@ -551,7 +549,8 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect, } void -BasicCompositor::BeginFrame(const gfx::Rect *aClipRectIn, +BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion, + const gfx::Rect *aClipRectIn, const gfxMatrix& aTransform, const gfx::Rect& aRenderBounds, gfx::Rect *aClipRectOut /* = nullptr */, @@ -562,6 +561,18 @@ BasicCompositor::BeginFrame(const gfx::Rect *aClipRectIn, Rect rect = Rect(0, 0, intRect.width, intRect.height); mWidgetSize = intRect.Size(); + nsIntRect invalidRect = aInvalidRegion.GetBounds(); + mInvalidRect = IntRect(invalidRect.x, invalidRect.y, invalidRect.width, invalidRect.height); + mInvalidRegion = aInvalidRegion; + + if (aRenderBoundsOut) { + *aRenderBoundsOut = Rect(); + } + + if (mInvalidRect.width <= 0 || mInvalidRect.height <= 0) { + return; + } + if (mCopyTarget) { // If we have a copy target, then we don't have a widget-provided mDrawTarget (currently). Create a dummy // placeholder so that CreateRenderTarget() works. @@ -570,17 +581,22 @@ BasicCompositor::BeginFrame(const gfx::Rect *aClipRectIn, mDrawTarget = mWidget->StartRemoteDrawing(); } if (!mDrawTarget) { - if (aRenderBoundsOut) { - *aRenderBoundsOut = Rect(); - } return; } // Setup an intermediate render target to buffer all compositing. We will // copy this into mDrawTarget (the widget), and/or mCopyTarget in EndFrame() - RefPtr target = CreateRenderTarget(IntRect(0, 0, intRect.width, intRect.height), INIT_MODE_CLEAR); + RefPtr target = CreateRenderTarget(mInvalidRect, INIT_MODE_CLEAR); SetRenderTarget(target); + // We only allocate a surface sized to the invalidated region, so we need to + // translate future coordinates. + Matrix transform; + transform.Translate(-invalidRect.x, -invalidRect.y); + mRenderTarget->mDrawTarget->SetTransform(transform); + + gfxUtils::ClipToRegion(mRenderTarget->mDrawTarget, aInvalidRegion); + if (aRenderBoundsOut) { *aRenderBoundsOut = rect; } @@ -599,20 +615,26 @@ void BasicCompositor::EndFrame() { mRenderTarget->mDrawTarget->PopClip(); + mRenderTarget->mDrawTarget->PopClip(); + // Note: Most platforms require us to buffer drawing to the widget surface. + // That's why we don't draw to mDrawTarget directly. RefPtr source = mRenderTarget->mDrawTarget->Snapshot(); - if (mCopyTarget) { - mCopyTarget->CopySurface(source, - IntRect(0, 0, mWidgetSize.width, mWidgetSize.height), - IntPoint(0, 0)); - } else { - // Most platforms require us to buffer drawing to the widget surface. - // That's why we don't draw to mDrawTarget directly. - mDrawTarget->CopySurface(source, - IntRect(0, 0, mWidgetSize.width, mWidgetSize.height), - IntPoint(0, 0)); + RefPtr dest(mCopyTarget ? mCopyTarget : mDrawTarget); + + // The source DrawTarget is clipped to the invalidation region, so we have + // to copy the individual rectangles in the region or else we'll draw blank + // pixels. + nsIntRegionRectIterator iter(mInvalidRegion); + for (const nsIntRect *r = iter.Next(); r; r = iter.Next()) { + dest->CopySurface(source, + IntRect(r->x - mInvalidRect.x, r->y - mInvalidRect.y, r->width, r->height), + IntPoint(r->x, r->y)); + } + if (!mCopyTarget) { mWidget->EndRemoteDrawing(); } + mDrawTarget = nullptr; mRenderTarget = nullptr; } @@ -620,6 +642,7 @@ BasicCompositor::EndFrame() void BasicCompositor::AbortFrame() { + mRenderTarget->mDrawTarget->PopClip(); mRenderTarget->mDrawTarget->PopClip(); mDrawTarget = nullptr; mRenderTarget = nullptr; diff --git a/gfx/layers/basic/BasicCompositor.h b/gfx/layers/basic/BasicCompositor.h index c3227b6faba5..ac969937cef0 100644 --- a/gfx/layers/basic/BasicCompositor.h +++ b/gfx/layers/basic/BasicCompositor.h @@ -84,7 +84,8 @@ public: gfx::Float aOpacity, const gfx::Matrix4x4 &aTransform) MOZ_OVERRIDE; - virtual void BeginFrame(const gfx::Rect *aClipRectIn, + virtual void BeginFrame(const nsIntRegion& aInvalidRegion, + const gfx::Rect *aClipRectIn, const gfxMatrix& aTransform, const gfx::Rect& aRenderBounds, gfx::Rect *aClipRectOut = nullptr, @@ -137,6 +138,9 @@ private: // An optional destination target to copy the results // to after drawing is completed. RefPtr mCopyTarget; + + gfx::IntRect mInvalidRect; + nsIntRegion mInvalidRegion; }; } // namespace layers diff --git a/gfx/layers/client/ClientLayerManager.cpp b/gfx/layers/client/ClientLayerManager.cpp index c38c97698f97..e3468678770a 100644 --- a/gfx/layers/client/ClientLayerManager.cpp +++ b/gfx/layers/client/ClientLayerManager.cpp @@ -294,6 +294,16 @@ ClientLayerManager::FlushRendering() } } +void +ClientLayerManager::SendInvalidRegion(const nsIntRegion& aRegion) +{ + if (mWidget) { + if (CompositorChild* remoteRenderer = mWidget->GetRemoteRenderer()) { + remoteRenderer->SendNotifyRegionInvalidated(aRegion); + } + } +} + void ClientLayerManager::ForwardTransaction() { diff --git a/gfx/layers/client/ClientLayerManager.h b/gfx/layers/client/ClientLayerManager.h index 241fc7ce8bbb..73a65613d615 100644 --- a/gfx/layers/client/ClientLayerManager.h +++ b/gfx/layers/client/ClientLayerManager.h @@ -79,6 +79,7 @@ public: } virtual void FlushRendering() MOZ_OVERRIDE; + void SendInvalidRegion(const nsIntRegion& aRegion); virtual bool NeedsWidgetInvalidation() MOZ_OVERRIDE { return false; } diff --git a/gfx/layers/composite/LayerManagerComposite.cpp b/gfx/layers/composite/LayerManagerComposite.cpp index cd4421f1cb97..add14f9b99ac 100644 --- a/gfx/layers/composite/LayerManagerComposite.cpp +++ b/gfx/layers/composite/LayerManagerComposite.cpp @@ -145,6 +145,9 @@ void LayerManagerComposite::BeginTransaction() { mInTransaction = true; + if (Compositor::GetBackend() == LAYERS_BASIC) { + mClonedLayerTreeProperties = LayerProperties::CloneFrom(GetRoot()); + } } void @@ -196,6 +199,15 @@ LayerManagerComposite::EndTransaction(DrawThebesLayerCallback aCallback, return; } + if (mRoot && mClonedLayerTreeProperties) { + nsIntRegion invalid = mClonedLayerTreeProperties->ComputeDifferences(mRoot, nullptr); + mClonedLayerTreeProperties = nullptr; + + mInvalidRegion.Or(mInvalidRegion, invalid); + } else { + mInvalidRegion.Or(mInvalidRegion, mRenderBounds); + } + if (mRoot && !(aFlags & END_NO_IMMEDIATE_REDRAW)) { if (aFlags & END_NO_COMPOSITE) { // Apply pending tree updates before recomputing effective @@ -343,13 +355,16 @@ LayerManagerComposite::Render() clipRect = *mRoot->GetClipRect(); WorldTransformRect(clipRect); Rect rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height); - mCompositor->BeginFrame(&rect, mWorldMatrix, bounds, nullptr, &actualBounds); + mCompositor->BeginFrame(mInvalidRegion, &rect, mWorldMatrix, bounds, nullptr, &actualBounds); } else { gfx::Rect rect; - mCompositor->BeginFrame(nullptr, mWorldMatrix, bounds, &rect, &actualBounds); + mCompositor->BeginFrame(mInvalidRegion, nullptr, mWorldMatrix, bounds, &rect, &actualBounds); clipRect = nsIntRect(rect.x, rect.y, rect.width, rect.height); } + // Reset the invalid region now that we've begun compositing. + mInvalidRegion.SetEmpty(); + if (actualBounds.IsEmpty()) { mCompositor->GetWidget()->PostRender(this); return; diff --git a/gfx/layers/composite/LayerManagerComposite.h b/gfx/layers/composite/LayerManagerComposite.h index 967ff532a84b..2812b2fd2c6a 100644 --- a/gfx/layers/composite/LayerManagerComposite.h +++ b/gfx/layers/composite/LayerManagerComposite.h @@ -28,6 +28,7 @@ #include "nsRect.h" // for nsIntRect #include "nsRegion.h" // for nsIntRegion #include "nscore.h" // for nsAString, etc +#include "LayerTreeInvalidation.h" class gfxASurface; class gfxContext; @@ -228,6 +229,11 @@ public: void SetCompositorID(uint32_t aID); + void AddInvalidRegion(const nsIntRegion& aRegion) + { + mInvalidRegion.Or(mInvalidRegion, aRegion); + } + Compositor* GetCompositor() const { return mCompositor; @@ -275,7 +281,10 @@ private: DrawThebesLayerCallback mThebesLayerCallback; void *mThebesLayerCallbackData; gfxMatrix mWorldMatrix; + bool mInTransaction; + nsIntRegion mInvalidRegion; + nsAutoPtr mClonedLayerTreeProperties; }; /** diff --git a/gfx/layers/d3d11/CompositorD3D11.cpp b/gfx/layers/d3d11/CompositorD3D11.cpp index 9ed4f8253832..054316163b1c 100644 --- a/gfx/layers/d3d11/CompositorD3D11.cpp +++ b/gfx/layers/d3d11/CompositorD3D11.cpp @@ -623,7 +623,8 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect, } void -CompositorD3D11::BeginFrame(const Rect* aClipRectIn, +CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion, + const Rect* aClipRectIn, const gfxMatrix& aTransform, const Rect& aRenderBounds, Rect* aClipRectOut, diff --git a/gfx/layers/d3d11/CompositorD3D11.h b/gfx/layers/d3d11/CompositorD3D11.h index fe2b2d33fd65..acd767c5d598 100644 --- a/gfx/layers/d3d11/CompositorD3D11.h +++ b/gfx/layers/d3d11/CompositorD3D11.h @@ -100,7 +100,8 @@ public: * Start a new frame. If aClipRectIn is null, sets *aClipRectOut to the * screen dimensions. */ - virtual void BeginFrame(const gfx::Rect *aClipRectIn, + virtual void BeginFrame(const nsIntRegion& aInvalidRegion, + const gfx::Rect *aClipRectIn, const gfxMatrix& aTransform, const gfx::Rect& aRenderBounds, gfx::Rect *aClipRectOut = nullptr, diff --git a/gfx/layers/d3d9/CompositorD3D9.cpp b/gfx/layers/d3d9/CompositorD3D9.cpp index 4bafe4844b8e..ee95797e6cde 100644 --- a/gfx/layers/d3d9/CompositorD3D9.cpp +++ b/gfx/layers/d3d9/CompositorD3D9.cpp @@ -439,7 +439,8 @@ CompositorD3D9::SetMask(const EffectChain &aEffectChain, uint32_t aMaskTexture) } void -CompositorD3D9::BeginFrame(const Rect *aClipRectIn, +CompositorD3D9::BeginFrame(const nsIntRegion& aInvalidRegion, + const Rect *aClipRectIn, const gfxMatrix& aTransform, const Rect& aRenderBounds, Rect *aClipRectOut, diff --git a/gfx/layers/d3d9/CompositorD3D9.h b/gfx/layers/d3d9/CompositorD3D9.h index f486487c28c9..3fd75ffc0561 100644 --- a/gfx/layers/d3d9/CompositorD3D9.h +++ b/gfx/layers/d3d9/CompositorD3D9.h @@ -61,7 +61,8 @@ public: gfx::Float aOpacity, const gfx::Matrix4x4 &aTransform) MOZ_OVERRIDE; - virtual void BeginFrame(const gfx::Rect *aClipRectIn, + virtual void BeginFrame(const nsIntRegion& aInvalidRegion, + const gfx::Rect *aClipRectIn, const gfxMatrix& aTransform, const gfx::Rect& aRenderBounds, gfx::Rect *aClipRectOut = nullptr, diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index 60e708fe3f5e..39eb880aedde 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -322,6 +322,15 @@ CompositorParent::RecvFlushRendering() return true; } +bool +CompositorParent::RecvNotifyRegionInvalidated(const nsIntRegion& aRegion) +{ + if (mLayerManager) { + mLayerManager->AddInvalidRegion(aRegion); + } + return true; +} + void CompositorParent::ActorDestroy(ActorDestroyReason why) { @@ -896,6 +905,7 @@ public: SurfaceDescriptor* aOutSnapshot) { return true; } virtual bool RecvFlushRendering() MOZ_OVERRIDE { return true; } + virtual bool RecvNotifyRegionInvalidated(const nsIntRegion& aRegion) { return true; } virtual PLayerTransactionParent* AllocPLayerTransactionParent(const nsTArray& aBackendHints, diff --git a/gfx/layers/ipc/CompositorParent.h b/gfx/layers/ipc/CompositorParent.h index 544500b8b720..8634fc31107d 100644 --- a/gfx/layers/ipc/CompositorParent.h +++ b/gfx/layers/ipc/CompositorParent.h @@ -88,6 +88,8 @@ public: SurfaceDescriptor* aOutSnapshot); virtual bool RecvFlushRendering() MOZ_OVERRIDE; + virtual bool RecvNotifyRegionInvalidated(const nsIntRegion& aRegion) MOZ_OVERRIDE; + virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE; virtual void ShadowLayersUpdated(LayerTransactionParent* aLayerTree, diff --git a/gfx/layers/ipc/LayerTransactionParent.cpp b/gfx/layers/ipc/LayerTransactionParent.cpp index dab2f3a19f77..94f7874f3e96 100644 --- a/gfx/layers/ipc/LayerTransactionParent.cpp +++ b/gfx/layers/ipc/LayerTransactionParent.cpp @@ -284,6 +284,7 @@ LayerTransactionParent::RecvUpdate(const InfallibleTArray& cset, layer->SetMaskLayer(nullptr); } layer->SetAnimations(common.animations()); + layer->SetInvalidRegion(common.invalidRegion()); typedef SpecificLayerAttributes Specific; const SpecificLayerAttributes& specific = attrs.specific(); diff --git a/gfx/layers/ipc/LayersMessages.ipdlh b/gfx/layers/ipc/LayersMessages.ipdlh index f02d1ae0ced3..4f0a374415a4 100644 --- a/gfx/layers/ipc/LayersMessages.ipdlh +++ b/gfx/layers/ipc/LayersMessages.ipdlh @@ -200,7 +200,8 @@ struct CommonLayerAttributes { nullable PLayer maskLayer; // Animated colors will only honored for ColorLayers. Animation[] animations; - }; + nsIntRegion invalidRegion; +}; struct ThebesLayerAttributes { nsIntRegion validRegion; diff --git a/gfx/layers/ipc/PCompositor.ipdl b/gfx/layers/ipc/PCompositor.ipdl index 637e6755713c..3b17d6937f6b 100644 --- a/gfx/layers/ipc/PCompositor.ipdl +++ b/gfx/layers/ipc/PCompositor.ipdl @@ -9,6 +9,7 @@ include LayersSurfaces; include protocol PGrallocBuffer; include protocol PLayerTransaction; include "mozilla/GfxMessageUtils.h"; +include "nsRegion.h"; using struct mozilla::null_t from "ipc/IPCMessageUtils.h"; using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h"; @@ -64,6 +65,9 @@ parent: // that hint is ignored. sync PLayerTransaction(LayersBackend[] layersBackendHints, uint64_t id) returns (TextureFactoryIdentifier textureFactoryIdentifier, bool success); + + // Notify the compositor that a region of the screen has been invalidated. + async NotifyRegionInvalidated(nsIntRegion region); }; } // layers diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index d8f25b4de061..6c9e44383537 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -536,6 +536,7 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray* aReplies, bool } common.maskLayerParent() = nullptr; common.animations() = mutant->GetAnimations(); + common.invalidRegion() = mutant->GetInvalidRegion(); attrs.specific() = null_t(); mutant->FillSpecificAttributes(attrs.specific()); diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index 4d8a100b1daf..fa396cd2336a 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -755,8 +755,11 @@ CalculatePOTSize(const IntSize& aSize, GLContext* gl) } void -CompositorOGL::BeginFrame(const Rect *aClipRectIn, const gfxMatrix& aTransform, - const Rect& aRenderBounds, Rect *aClipRectOut, +CompositorOGL::BeginFrame(const nsIntRegion& aInvalidRegion, + const Rect *aClipRectIn, + const gfxMatrix& aTransform, + const Rect& aRenderBounds, + Rect *aClipRectOut, Rect *aRenderBoundsOut) { PROFILER_LABEL("CompositorOGL", "BeginFrame"); diff --git a/gfx/layers/opengl/CompositorOGL.h b/gfx/layers/opengl/CompositorOGL.h index 3424edaa3c09..24d136a0262a 100644 --- a/gfx/layers/opengl/CompositorOGL.h +++ b/gfx/layers/opengl/CompositorOGL.h @@ -243,7 +243,8 @@ private: /* Start a new frame. If aClipRectIn is null and aClipRectOut is non-null, * sets *aClipRectOut to the screen dimensions. */ - virtual void BeginFrame(const gfx::Rect *aClipRectIn, + virtual void BeginFrame(const nsIntRegion& aInvalidRegion, + const gfx::Rect *aClipRectIn, const gfxMatrix& aTransform, const gfx::Rect& aRenderBounds, gfx::Rect *aClipRectOut = nullptr, diff --git a/gfx/thebes/nsSurfaceTexture.cpp b/gfx/thebes/nsSurfaceTexture.cpp index 84b1b959298f..83bb598be885 100644 --- a/gfx/thebes/nsSurfaceTexture.cpp +++ b/gfx/thebes/nsSurfaceTexture.cpp @@ -210,7 +210,7 @@ nsSurfaceTexture::~nsSurfaceTexture() return; if (mSurfaceTexture && env) { - AndroidBridge::Bridge()->UnregisterSurfaceTextureFrameListener(mSurfaceTexture); + GeckoAppShell::UnregisterSurfaceTextureFrameListener(mSurfaceTexture); env->DeleteGlobalRef(mSurfaceTexture); mSurfaceTexture = nullptr; @@ -239,9 +239,9 @@ void nsSurfaceTexture::SetFrameAvailableCallback(nsIRunnable* aRunnable) { if (aRunnable) - AndroidBridge::Bridge()->RegisterSurfaceTextureFrameListener(mSurfaceTexture, mID); + GeckoAppShell::RegisterSurfaceTextureFrameListener(mSurfaceTexture, mID); else - AndroidBridge::Bridge()->UnregisterSurfaceTextureFrameListener(mSurfaceTexture); + GeckoAppShell::UnregisterSurfaceTextureFrameListener(mSurfaceTexture); mFrameAvailableCallback = aRunnable; } diff --git a/hal/android/AndroidHal.cpp b/hal/android/AndroidHal.cpp index 932fd5f49a71..e97ff5b718bf 100644 --- a/hal/android/AndroidHal.cpp +++ b/hal/android/AndroidHal.cpp @@ -14,6 +14,7 @@ using namespace mozilla::dom; using namespace mozilla::hal; +using namespace mozilla::widget::android; namespace mozilla { namespace hal_impl { @@ -54,97 +55,55 @@ CancelVibrate(const WindowIdentifier &) { // Ignore WindowIdentifier parameter. - AndroidBridge* b = AndroidBridge::Bridge(); - if (b) - b->CancelVibrate(); + GeckoAppShell::CancelVibrate(); } void EnableBatteryNotifications() { - AndroidBridge* bridge = AndroidBridge::Bridge(); - if (!bridge) { - return; - } - - bridge->EnableBatteryNotifications(); + GeckoAppShell::EnableBatteryNotifications(); } void DisableBatteryNotifications() { - AndroidBridge* bridge = AndroidBridge::Bridge(); - if (!bridge) { - return; - } - - bridge->DisableBatteryNotifications(); + GeckoAppShell::DisableBatteryNotifications(); } void GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo) { - AndroidBridge* bridge = AndroidBridge::Bridge(); - if (!bridge) { - return; - } - - bridge->GetCurrentBatteryInformation(aBatteryInfo); + AndroidBridge::Bridge()->GetCurrentBatteryInformation(aBatteryInfo); } void EnableNetworkNotifications() { - AndroidBridge* bridge = AndroidBridge::Bridge(); - if (!bridge) { - return; - } - - bridge->EnableNetworkNotifications(); + GeckoAppShell::EnableNetworkNotifications(); } void DisableNetworkNotifications() { - AndroidBridge* bridge = AndroidBridge::Bridge(); - if (!bridge) { - return; - } - - bridge->DisableNetworkNotifications(); + GeckoAppShell::DisableNetworkNotifications(); } void GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInfo) { - AndroidBridge* bridge = AndroidBridge::Bridge(); - if (!bridge) { - return; - } - - bridge->GetCurrentNetworkInformation(aNetworkInfo); + AndroidBridge::Bridge()->GetCurrentNetworkInformation(aNetworkInfo); } void EnableScreenConfigurationNotifications() { - AndroidBridge* bridge = AndroidBridge::Bridge(); - if (!bridge) { - return; - } - - bridge->EnableScreenOrientationNotifications(); + GeckoAppShell::EnableScreenOrientationNotifications(); } void DisableScreenConfigurationNotifications() { - AndroidBridge* bridge = AndroidBridge::Bridge(); - if (!bridge) { - return; - } - - bridge->DisableScreenOrientationNotifications(); + GeckoAppShell::DisableScreenOrientationNotifications(); } void @@ -181,11 +140,6 @@ GetCurrentScreenConfiguration(ScreenConfiguration* aScreenConfiguration) bool LockScreenOrientation(const ScreenOrientation& aOrientation) { - AndroidBridge* bridge = AndroidBridge::Bridge(); - if (!bridge) { - return false; - } - switch (aOrientation) { // The Android backend only supports these orientations. case eScreenOrientation_PortraitPrimary: @@ -195,7 +149,7 @@ LockScreenOrientation(const ScreenOrientation& aOrientation) case eScreenOrientation_LandscapeSecondary: case eScreenOrientation_LandscapePrimary | eScreenOrientation_LandscapeSecondary: case eScreenOrientation_Default: - bridge->LockScreenOrientation(aOrientation); + GeckoAppShell::LockScreenOrientation(aOrientation); return true; default: return false; @@ -205,12 +159,7 @@ LockScreenOrientation(const ScreenOrientation& aOrientation) void UnlockScreenOrientation() { - AndroidBridge* bridge = AndroidBridge::Bridge(); - if (!bridge) { - return; - } - - bridge->UnlockScreenOrientation(); + GeckoAppShell::UnlockScreenOrientation(); } } // hal_impl diff --git a/hal/android/AndroidSensor.cpp b/hal/android/AndroidSensor.cpp index fd3c2d8ce679..3c88027a58ed 100644 --- a/hal/android/AndroidSensor.cpp +++ b/hal/android/AndroidSensor.cpp @@ -13,12 +13,12 @@ namespace hal_impl { void EnableSensorNotifications(SensorType aSensor) { - AndroidBridge::Bridge()->EnableSensor(aSensor); + GeckoAppShell::EnableSensor(aSensor); } void DisableSensorNotifications(SensorType aSensor) { - AndroidBridge::Bridge()->DisableSensor(aSensor); + GeckoAppShell::DisableSensor(aSensor); } } // hal_impl diff --git a/ipc/glue/MessagePump.cpp b/ipc/glue/MessagePump.cpp index 2d4d988516e2..39ecef4ba5e2 100644 --- a/ipc/glue/MessagePump.cpp +++ b/ipc/glue/MessagePump.cpp @@ -95,7 +95,7 @@ MessagePump::Run(MessagePump::Delegate* aDelegate) // This processes messages in the Android Looper. Note that we only // get here if the normal Gecko event loop has been awoken above. // Bug 750713 - did_work |= AndroidBridge::Bridge()->PumpMessageLoop(); + did_work |= GeckoAppShell::PumpMessageLoop(); #endif did_work |= aDelegate->DoDelayedWork(&delayed_work_time_); diff --git a/js/src/devtools/rootAnalysis/annotations.js b/js/src/devtools/rootAnalysis/annotations.js index 05de1e4f3239..1803eb87f5a2 100644 --- a/js/src/devtools/rootAnalysis/annotations.js +++ b/js/src/devtools/rootAnalysis/annotations.js @@ -162,6 +162,7 @@ var ignoreFunctions = { // Bug 940765 - fetching preferences should not GC "PrefHashEntry* pref_HashTableLookup(void*)": true, + "uint8 mozilla::Preferences::InitStaticMembers()": true, // Temporary, see bug 940765 // These are a little overzealous -- these destructors *can* GC if they end // up wrapping a pending exception. See bug 898815 for the heavyweight fix. diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp index c0fc473f71b5..cfcf1735ed97 100644 --- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -355,9 +355,7 @@ frontend::CompileScript(ExclusiveContext *cx, LifoAlloc *alloc, HandleObject sco if (!FoldConstants(cx, &pn, &parser)) return nullptr; - // Inferring names for functions in compiled scripts is currently only - // supported while on the main thread. See bug 895395. - if (cx->isJSContext() && !NameFunctions(cx->asJSContext(), pn)) + if (!NameFunctions(cx, pn)) return nullptr; if (!EmitTree(cx, &bce, pn)) diff --git a/js/src/frontend/NameFunctions.cpp b/js/src/frontend/NameFunctions.cpp index ab26b3fddd55..23805cace95e 100644 --- a/js/src/frontend/NameFunctions.cpp +++ b/js/src/frontend/NameFunctions.cpp @@ -23,7 +23,7 @@ class NameResolver { static const size_t MaxParents = 100; - JSContext *cx; + ExclusiveContext *cx; size_t nparents; /* number of parents in the parents array */ ParseNode *parents[MaxParents]; /* history of ParseNodes we've been looking at */ StringBuffer *buf; /* when resolving, buffer to append to */ @@ -262,7 +262,7 @@ class NameResolver } public: - explicit NameResolver(JSContext *cx) : cx(cx), nparents(0), buf(nullptr) {} + explicit NameResolver(ExclusiveContext *cx) : cx(cx), nparents(0), buf(nullptr) {} /* * Resolve all names for anonymous functions recursively within the @@ -331,7 +331,7 @@ class NameResolver } /* anonymous namespace */ bool -frontend::NameFunctions(JSContext *cx, ParseNode *pn) +frontend::NameFunctions(ExclusiveContext *cx, ParseNode *pn) { NameResolver nr(cx); nr.resolve(pn); diff --git a/js/src/frontend/NameFunctions.h b/js/src/frontend/NameFunctions.h index c6845c4cbfad..0f8717e74433 100644 --- a/js/src/frontend/NameFunctions.h +++ b/js/src/frontend/NameFunctions.h @@ -10,12 +10,15 @@ #include "js/TypeDecls.h" namespace js { + +class ExclusiveContext; + namespace frontend { class ParseNode; bool -NameFunctions(JSContext *cx, ParseNode *pn); +NameFunctions(ExclusiveContext *cx, ParseNode *pn); } /* namespace frontend */ } /* namespace js */ diff --git a/js/src/jit-test/tests/baseline/bug940972.js b/js/src/jit-test/tests/baseline/bug940972.js new file mode 100644 index 000000000000..3c837feba184 --- /dev/null +++ b/js/src/jit-test/tests/baseline/bug940972.js @@ -0,0 +1,5 @@ +setJitCompilerOption("baseline.usecount.trigger", 0); +var arr = new Uint8ClampedArray(1); +for (var i = 0; i < 2; ++i) + arr[0] = 4294967296; +assertEq(arr[0], 255); diff --git a/js/src/jit/AsmJSModule.h b/js/src/jit/AsmJSModule.h index 92ad99366295..b04e5e5f0b47 100644 --- a/js/src/jit/AsmJSModule.h +++ b/js/src/jit/AsmJSModule.h @@ -346,7 +346,7 @@ class AsmJSModule JS_ASSERT(name->isTenured()); } - ProfiledBlocksFunction(const ProfiledBlocksFunction ©) + ProfiledBlocksFunction(ProfiledBlocksFunction &©) : ProfiledFunction(copy.name, copy.startCodeOffset, copy.endCodeOffset), endInlineCodeOffset(copy.endInlineCodeOffset), blocks(mozilla::Move(copy.blocks)) { } @@ -566,7 +566,7 @@ class AsmJSModule bool trackPerfProfiledBlocks(JSAtom *name, unsigned startCodeOffset, unsigned endInlineCodeOffset, unsigned endCodeOffset, jit::BasicBlocksVector &basicBlocks) { ProfiledBlocksFunction func(name, startCodeOffset, endInlineCodeOffset, endCodeOffset, basicBlocks); - return perfProfiledBlocksFunctions_.append(func); + return perfProfiledBlocksFunctions_.append(mozilla::Move(func)); } unsigned numPerfBlocksFunctions() const { return perfProfiledBlocksFunctions_.length(); diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index 7c8c139d5002..c043aea68c06 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -1637,6 +1637,13 @@ IonCompile(JSContext *cx, JSScript *script, BaselineInspector inspector(script); + BaselineFrameInspector *baselineFrameInspector = nullptr; + if (baselineFrame) { + baselineFrameInspector = NewBaselineFrameInspector(temp, baselineFrame); + if (!baselineFrameInspector) + return AbortReason_Alloc; + } + AutoFlushCache afc("IonCompile", cx->runtime()->jitRuntime()); AutoTempAllocatorRooter root(cx, temp); @@ -1647,7 +1654,7 @@ IonCompile(JSContext *cx, JSScript *script, IonBuilder *builder = alloc->new_((JSContext *) nullptr, CompileCompartment::get(cx->compartment()), temp, graph, constraints, - &inspector, info, baselineFrame); + &inspector, info, baselineFrameInspector); if (!builder) return AbortReason_Alloc; diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 2b168130ce3a..edd67a7b0a1e 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -37,9 +37,73 @@ using namespace js::jit; using mozilla::DebugOnly; using mozilla::Maybe; +class jit::BaselineFrameInspector +{ + public: + types::Type thisType; + JSObject *singletonScopeChain; + + Vector argTypes; + Vector varTypes; + + BaselineFrameInspector(TempAllocator *temp) + : thisType(types::Type::UndefinedType()), + singletonScopeChain(nullptr), + argTypes(*temp), + varTypes(*temp) + {} +}; + +BaselineFrameInspector * +jit::NewBaselineFrameInspector(TempAllocator *temp, BaselineFrame *frame) +{ + JS_ASSERT(frame); + + BaselineFrameInspector *inspector = temp->lifoAlloc()->new_(temp); + if (!inspector) + return nullptr; + + // Note: copying the actual values into a temporary structure for use + // during compilation could capture nursery pointers, so the values' types + // are recorded instead. + + inspector->thisType = types::GetValueType(frame->thisValue()); + + if (frame->scopeChain()->hasSingletonType()) + inspector->singletonScopeChain = frame->scopeChain(); + + JSScript *script = frame->script(); + + if (script->function()) { + if (!inspector->argTypes.reserve(frame->numFormalArgs())) + return nullptr; + for (size_t i = 0; i < frame->numFormalArgs(); i++) { + if (script->formalIsAliased(i)) + inspector->argTypes.infallibleAppend(types::Type::UndefinedType()); + else if (!script->argsObjAliasesFormals()) + inspector->argTypes.infallibleAppend(types::GetValueType(frame->unaliasedFormal(i))); + else if (frame->hasArgsObj()) + inspector->argTypes.infallibleAppend(types::GetValueType(frame->argsObj().arg(i))); + else + inspector->argTypes.infallibleAppend(types::Type::UndefinedType()); + } + } + + if (!inspector->varTypes.reserve(frame->script()->nfixed)) + return nullptr; + for (size_t i = 0; i < frame->script()->nfixed; i++) { + if (script->varIsAliased(i)) + inspector->varTypes.infallibleAppend(types::Type::UndefinedType()); + else + inspector->varTypes.infallibleAppend(types::GetValueType(frame->unaliasedVar(i))); + } + + return inspector; +} + IonBuilder::IonBuilder(JSContext *analysisContext, CompileCompartment *comp, TempAllocator *temp, MIRGraph *graph, types::CompilerConstraintList *constraints, - BaselineInspector *inspector, CompileInfo *info, BaselineFrame *baselineFrame, + BaselineInspector *inspector, CompileInfo *info, BaselineFrameInspector *baselineFrame, size_t inliningDepth, uint32_t loopDepth) : MIRGenerator(comp, temp, graph, info), backgroundCodegen_(nullptr), @@ -859,7 +923,7 @@ IonBuilder::initParameters() // frame to determine possible initial types for 'this' and parameters. if (thisTypes->empty() && baselineFrame_) { - if (!thisTypes->addType(types::GetValueType(baselineFrame_->thisValue()), alloc_->lifoAlloc())) + if (!thisTypes->addType(baselineFrame_->thisType, alloc_->lifoAlloc())) return false; } @@ -872,7 +936,7 @@ IonBuilder::initParameters() if (types->empty() && baselineFrame_ && !script_->baselineScript()->modifiesArguments()) { - if (!types->addType(types::GetValueType(baselineFrame_->argv()[i]), alloc_->lifoAlloc())) + if (!types->addType(baselineFrame_->argTypes[i], alloc_->lifoAlloc())) return false; } @@ -5814,30 +5878,23 @@ IonBuilder::newPendingLoopHeader(MBasicBlock *predecessor, jsbytecode *pc, bool MPhi *phi = block->getSlot(i)->toPhi(); - // Get the value from the baseline frame. - Value existingValue; + // Get the type from the baseline frame. + types::Type existingType = types::Type::UndefinedType(); uint32_t arg = i - info().firstArgSlot(); uint32_t var = i - info().firstLocalSlot(); - if (info().fun() && i == info().thisSlot()) { - existingValue = baselineFrame_->thisValue(); - } else if (arg < info().nargs()) { - if (info().needsArgsObj()) - existingValue = baselineFrame_->argsObj().arg(arg); - else - existingValue = baselineFrame_->unaliasedFormal(arg); - } else { - existingValue = baselineFrame_->unaliasedVar(var); - } + if (info().fun() && i == info().thisSlot()) + existingType = baselineFrame_->thisType; + else if (arg < info().nargs()) + existingType = baselineFrame_->argTypes[arg]; + else + existingType = baselineFrame_->varTypes[var]; // Extract typeset from value. - MIRType type = existingValue.isDouble() - ? MIRType_Double - : MIRTypeFromValueType(existingValue.extractNonDoubleType()); - types::Type ntype = types::GetValueType(existingValue); types::TemporaryTypeSet *typeSet = - alloc_->lifoAlloc()->new_(ntype); + alloc_->lifoAlloc()->new_(existingType); if (!typeSet) return nullptr; + MIRType type = MIRTypeFromValueType(typeSet->getKnownTypeTag()); phi->addBackedgeType(type, typeSet); } } @@ -9110,7 +9167,7 @@ IonBuilder::jsop_this() } if (thisTypes->getKnownTypeTag() == JSVAL_TYPE_OBJECT || - (thisTypes->empty() && baselineFrame_ && baselineFrame_->thisValue().isObject())) + (thisTypes->empty() && baselineFrame_ && baselineFrame_->thisType.isSomeObject())) { // This is safe, because if the entry type of |this| is an object, it // will necessarily be an object throughout the entire function. OSR @@ -9294,12 +9351,13 @@ IonBuilder::hasStaticScopeObject(ScopeCoordinate sc, JSObject **pcall) // entering the Ion code a different call object will be created. if (script() == outerScript && baselineFrame_ && info().osrPc()) { - JSObject *scope = baselineFrame_->scopeChain(); - if (scope->is() && - scope->as().callee().nonLazyScript() == outerScript) + JSObject *singletonScope = baselineFrame_->singletonScopeChain; + if (singletonScope && + singletonScope->is() && + singletonScope->as().callee().nonLazyScript() == outerScript) { - JS_ASSERT(scope->hasSingletonType()); - *pcall = scope; + JS_ASSERT(singletonScope->hasSingletonType()); + *pcall = singletonScope; return true; } } diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index 7c44639f0504..3ee64f1b2ae0 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -24,6 +24,12 @@ namespace jit { class CodeGenerator; class CallInfo; class BaselineInspector; +class BaselineFrameInspector; + +// Records information about a baseline frame for compilation that is stable +// when later used off thread. +BaselineFrameInspector * +NewBaselineFrameInspector(TempAllocator *temp, BaselineFrame *frame); class IonBuilder : public MIRGenerator { @@ -207,7 +213,7 @@ class IonBuilder : public MIRGenerator public: IonBuilder(JSContext *analysisContext, CompileCompartment *comp, TempAllocator *temp, MIRGraph *graph, types::CompilerConstraintList *constraints, - BaselineInspector *inspector, CompileInfo *info, BaselineFrame *baselineFrame, + BaselineInspector *inspector, CompileInfo *info, BaselineFrameInspector *baselineFrame, size_t inliningDepth = 0, uint32_t loopDepth = 0); bool build(); @@ -745,7 +751,7 @@ class IonBuilder : public MIRGenerator bool init(); JSContext *analysisContext; - BaselineFrame *baselineFrame_; + BaselineFrameInspector *baselineFrame_; AbortReason abortReason_; TypeRepresentationSetHash *reprSetHash_; diff --git a/js/src/jit/IonMacroAssembler.cpp b/js/src/jit/IonMacroAssembler.cpp index 67fef6a9918a..059e7f72b8ce 100644 --- a/js/src/jit/IonMacroAssembler.cpp +++ b/js/src/jit/IonMacroAssembler.cpp @@ -605,7 +605,11 @@ MacroAssembler::clampDoubleToUint8(FloatRegister input, Register output) addDouble(ScratchFloatReg, input); Label outOfRange; - branchTruncateDouble(input, output, &outOfRange); + + // Truncate to int32 and ensure the result <= 255. This relies on the + // processor setting output to a value > 255 for doubles outside the int32 + // range (for instance 0x80000000). + cvttsd2si(input, output); branch32(Assembler::Above, output, Imm32(255), &outOfRange); { // Check if we had a tie. diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 581e08fee6e3..0790552aa065 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -5364,9 +5364,13 @@ JS::GetGCNumber() } JS::AutoAssertNoGC::AutoAssertNoGC() - : runtime(js::TlsPerThreadData.get()->runtimeFromMainThread()) + : runtime(nullptr) { - gcNumber = runtime->gcNumber; + js::PerThreadData *data = js::TlsPerThreadData.get(); + if (data) { + runtime = data->runtimeFromMainThread(); + gcNumber = runtime->gcNumber; + } } JS::AutoAssertNoGC::AutoAssertNoGC(JSRuntime *rt) @@ -5376,6 +5380,9 @@ JS::AutoAssertNoGC::AutoAssertNoGC(JSRuntime *rt) JS::AutoAssertNoGC::~AutoAssertNoGC() { - MOZ_ASSERT(gcNumber == runtime->gcNumber, "GC ran inside an AutoAssertNoGC scope."); + if (runtime) + MOZ_ASSERT(gcNumber == runtime->gcNumber, "GC ran inside an AutoAssertNoGC scope."); + else + MOZ_ASSERT(!js::TlsPerThreadData.get(), "Runtime created within AutoAssertNoGC scope?"); } #endif diff --git a/js/src/jsinfer.h b/js/src/jsinfer.h index c20fd739e78e..e10820bf6def 100644 --- a/js/src/jsinfer.h +++ b/js/src/jsinfer.h @@ -209,6 +209,10 @@ class Type return (JSValueType) data; } + bool isSomeObject() const { + return data == JSVAL_TYPE_OBJECT || data > JSVAL_TYPE_UNKNOWN; + } + bool isAnyObject() const { return data == JSVAL_TYPE_OBJECT; } diff --git a/js/src/vm/ObjectImpl.cpp b/js/src/vm/ObjectImpl.cpp index da57ba4a209e..05f355ba9564 100644 --- a/js/src/vm/ObjectImpl.cpp +++ b/js/src/vm/ObjectImpl.cpp @@ -346,7 +346,7 @@ js::ObjectImpl::numFixedSlotsForCompilation() const #ifdef JSGC_GENERATIONAL // The compiler does not have access to nursery things, so if this object // is in the nursery we can fall back to numFixedSlots(). - if (!isTenured()) + if (IsInsideNursery(GetGCThingRuntime(this), this)) return numFixedSlots(); #endif gc::AllocKind kind = tenuredGetAllocKind(); diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index f5b8e55c1434..b6886d43d11f 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -8111,6 +8111,9 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext, } else if (nsGkAtoms::legendFrame == frameType) { newFrame = NS_NewLegendFrame(shell, styleContext); newFrame->Init(content, aParentFrame, aFrame); + } else if (nsGkAtoms::flexContainerFrame == frameType) { + newFrame = NS_NewFlexContainerFrame(shell, styleContext); + newFrame->Init(content, aParentFrame, aFrame); } else { NS_RUNTIMEABORT("unexpected frame type"); } diff --git a/layout/generic/nsFlexContainerFrame.cpp b/layout/generic/nsFlexContainerFrame.cpp index eab611cdb0b7..235406f7bba3 100644 --- a/layout/generic/nsFlexContainerFrame.cpp +++ b/layout/generic/nsFlexContainerFrame.cpp @@ -515,6 +515,21 @@ protected: // in our constructor). }; +// Helper function to calculate the sum of our flex items' +// margin-box main sizes. +static nscoord +SumFlexItemMarginBoxMainSizes(const FlexboxAxisTracker& aAxisTracker, + const nsTArray& aItems) +{ + nscoord sum = 0; + for (uint32_t i = 0; i < aItems.Length(); ++i) { + const FlexItem& item = aItems[i]; + sum += item.GetMainSize() + + item.GetMarginBorderPaddingSizeInAxis(aAxisTracker.GetMainAxis()); + } + return sum; +} + // Helper-function to find the first non-anonymous-box descendent of aFrame. static nsIFrame* GetFirstNonAnonBoxDescendant(nsIFrame* aFrame) @@ -1987,7 +2002,9 @@ nscoord nsFlexContainerFrame::ComputeFlexContainerMainSize( const nsHTMLReflowState& aReflowState, const FlexboxAxisTracker& aAxisTracker, - const nsTArray& aItems) + const nsTArray& aItems, + nscoord aAvailableHeightForContent, + nsReflowStatus& aStatus) { if (IsAxisHorizontal(aAxisTracker.GetMainAxis())) { // Horizontal case is easy -- our main size is our computed width @@ -1995,23 +2012,96 @@ nsFlexContainerFrame::ComputeFlexContainerMainSize( return aReflowState.ComputedWidth(); } - // Vertical case, with non-auto-height: - if (aReflowState.ComputedHeight() != NS_AUTOHEIGHT) { - return aReflowState.ComputedHeight(); + nscoord effectiveComputedHeight = GetEffectiveComputedHeight(aReflowState); + if (effectiveComputedHeight != NS_INTRINSICSIZE) { + // Vertical case, with fixed height: + if (aAvailableHeightForContent == NS_UNCONSTRAINEDSIZE || + effectiveComputedHeight < aAvailableHeightForContent) { + // Not in a fragmenting context, OR no need to fragment because we have + // more available height than we need. Either way, just use our fixed + // height. (Note that the reflow state has already done the appropriate + // min/max-height clamping.) + return effectiveComputedHeight; + } + + // Fragmenting *and* our fixed height is too tall for available height: + // Mark incomplete so we get a next-in-flow, and take up all of the + // available height (or the amount of height required by our children, if + // that's larger; but of course not more than our own computed height). + // XXXdholbert For now, we don't support pushing children to our next + // continuation or splitting children, so "amount of height required by + // our children" is just the sum of our children's heights. + NS_FRAME_SET_INCOMPLETE(aStatus); + nscoord sumOfChildHeights = + SumFlexItemMarginBoxMainSizes(aAxisTracker, aItems); + if (sumOfChildHeights <= aAvailableHeightForContent) { + return aAvailableHeightForContent; + } + return std::min(effectiveComputedHeight, sumOfChildHeights); } // Vertical case, with auto-height: // Resolve auto-height to the sum of our items' hypothetical outer main // sizes (their outer heights), clamped to our computed min/max main-size // properties (min-height & max-height). - nscoord sumOfChildHeights = 0; - for (uint32_t i = 0; i < aItems.Length(); ++i) { - sumOfChildHeights += - aItems[i].GetMainSize() + - aItems[i].GetMarginBorderPaddingSizeInAxis(aAxisTracker.GetMainAxis()); + // XXXdholbert Handle constrained-aAvailableHeightForContent case here. + nscoord sumOfChildHeights = + SumFlexItemMarginBoxMainSizes(aAxisTracker, aItems); + return NS_CSS_MINMAX(sumOfChildHeights, + aReflowState.mComputedMinHeight, + aReflowState.mComputedMaxHeight); +} + +nscoord +nsFlexContainerFrame::ComputeFlexContainerCrossSize( + const nsHTMLReflowState& aReflowState, + const FlexboxAxisTracker& aAxisTracker, + nscoord aLineCrossSize, + nscoord aAvailableHeightForContent, + bool* aIsDefinite, + nsReflowStatus& aStatus) +{ + MOZ_ASSERT(aIsDefinite, "outparam pointer must be non-null"); + + if (IsAxisHorizontal(aAxisTracker.GetCrossAxis())) { + // Cross axis is horizontal: our cross size is our computed width + // (which is already resolved). + *aIsDefinite = true; + return aReflowState.ComputedWidth(); } - return NS_CSS_MINMAX(sumOfChildHeights, + nscoord effectiveComputedHeight = GetEffectiveComputedHeight(aReflowState); + if (effectiveComputedHeight != NS_INTRINSICSIZE) { + // Cross-axis is vertical, and we have a fixed height: + *aIsDefinite = true; + if (aAvailableHeightForContent == NS_UNCONSTRAINEDSIZE || + effectiveComputedHeight < aAvailableHeightForContent) { + // Not in a fragmenting context, OR no need to fragment because we have + // more available height than we need. Either way, just use our fixed + // height. (Note that the reflow state has already done the appropriate + // min/max-height clamping.) + return effectiveComputedHeight; + } + + // Fragmenting *and* our fixed height is too tall for available height: + // Mark incomplete so we get a next-in-flow, and take up all of the + // available height (or the amount of height required by our children, if + // that's larger; but of course not more than our own computed height). + // XXXdholbert For now, we don't support pushing children to our next + // continuation or splitting children, so "amount of height required by + // our children" is just our line-height. + NS_FRAME_SET_INCOMPLETE(aStatus); + if (aLineCrossSize <= aAvailableHeightForContent) { + return aAvailableHeightForContent; + } + return std::min(effectiveComputedHeight, aLineCrossSize); + } + + // Cross axis is vertical and we have auto-height: shrink-wrap our line(s), + // subject to our min-size / max-size constraints in that (vertical) axis. + // XXXdholbert Handle constrained-aAvailableHeightForContent case here. + *aIsDefinite = false; + return NS_CSS_MINMAX(aLineCrossSize, aReflowState.mComputedMinHeight, aReflowState.mComputedMaxHeight); } @@ -2229,8 +2319,21 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext, axisTracker, items); NS_ENSURE_SUCCESS(rv, rv); + // If we're being fragmented into a constrained height, subtract off + // borderpadding-top from it, to get the available height for our + // content box. (Don't subtract if we're skipping top border/padding, + // though.) + nscoord availableHeightForContent = aReflowState.availableHeight; + if (availableHeightForContent != NS_UNCONSTRAINEDSIZE && + !(GetSkipSides() & (1 << NS_SIDE_TOP))) { + availableHeightForContent -= aReflowState.mComputedBorderPadding.top; + // (Don't let that push availableHeightForContent below zero, though): + availableHeightForContent = std::max(availableHeightForContent, 0); + } + const nscoord contentBoxMainSize = - ComputeFlexContainerMainSize(aReflowState, axisTracker, items); + ComputeFlexContainerMainSize(aReflowState, axisTracker, items, + availableHeightForContent, aStatus); ResolveFlexibleLengths(axisTracker, contentBoxMainSize, items); @@ -2277,34 +2380,20 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext, // 'align-content' is 'stretch' -- if it is, we need to give each line an // additional share of our flex container's desired cross-size. (if it's // not NS_AUTOHEIGHT and there's any cross-size left over to distribute) + bool isCrossSizeDefinite; + const nscoord contentBoxCrossSize = + ComputeFlexContainerCrossSize(aReflowState, axisTracker, + lineCrossAxisPosnTracker.GetLineCrossSize(), + availableHeightForContent, + &isCrossSizeDefinite, aStatus); - // Calculate the content-box cross size of our flex container: - nscoord contentBoxCrossSize = - GET_CROSS_COMPONENT(axisTracker, - aReflowState.ComputedWidth(), - aReflowState.ComputedHeight()); - - if (contentBoxCrossSize == NS_AUTOHEIGHT) { - // Unconstrained 'auto' cross-size: shrink-wrap our line(s), subject - // to our min-size / max-size constraints in that axis. - nscoord minCrossSize = GET_CROSS_COMPONENT(axisTracker, - aReflowState.mComputedMinWidth, - aReflowState.mComputedMinHeight); - nscoord maxCrossSize = GET_CROSS_COMPONENT(axisTracker, - aReflowState.mComputedMaxWidth, - aReflowState.mComputedMaxHeight); - contentBoxCrossSize = - NS_CSS_MINMAX(lineCrossAxisPosnTracker.GetLineCrossSize(), - minCrossSize, maxCrossSize); - } - if (lineCrossAxisPosnTracker.GetLineCrossSize() != - contentBoxCrossSize) { + if (isCrossSizeDefinite) { // XXXdholbert When we support multi-line flex containers, we should // distribute any extra space among or between our lines here according // to 'align-content'. For now, we do the single-line special behavior: - // "If the flex container has only a single line (even if it's a - // multi-line flex container), the cross size of the flex line is the - // flex container's inner cross size." + // "If the flex container has only a single line (even if it's a multi-line + // flex container) and has a definite cross size, the cross size of the + // flex line is the flex container's inner cross size." lineCrossAxisPosnTracker.SetLineCrossSize(contentBoxCrossSize); } @@ -2461,8 +2550,9 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext, aDesiredSize.width = desiredContentBoxSize.width + containerBorderPadding.LeftRight(); + // Does *NOT* include bottom border/padding yet (we add that a bit lower down) aDesiredSize.height = desiredContentBoxSize.height + - containerBorderPadding.TopBottom(); + containerBorderPadding.top; if (flexContainerAscent == nscoord_MIN) { // Still don't have our baseline set -- this happens if we have no @@ -2473,12 +2563,36 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext, "Have flex items but didn't get an ascent - that's odd " "(or there are just gigantic sizes involved)"); // Per spec, just use the bottom of content-box. - flexContainerAscent = aDesiredSize.height - - aReflowState.mComputedBorderPadding.bottom; + flexContainerAscent = aDesiredSize.height; } - aDesiredSize.ascent = flexContainerAscent; + // Now: If we're complete, add bottom border/padding to desired height + // (unless that pushes us over available height, in which case we become + // incomplete (unless we already weren't asking for any height, in which case + // we stay complete to avoid looping forever)). + // NOTE: If we're auto-height, we allow our bottom border/padding to push us + // over the available height without requesting a continuation, for + // consistency with the behavior of "display:block" elements. + if (NS_FRAME_IS_COMPLETE(aStatus)) { + // NOTE: We can't use containerBorderPadding.bottom for this, because if + // we're auto-height, ApplySkipSides will have zeroed it (because it + // assumed we might get a continuation). We have the correct value in + // aReflowState.mComputedBorderPadding.bottom, though, so we use that. + nscoord desiredHeightWithBottomBP = + aDesiredSize.height + aReflowState.mComputedBorderPadding.bottom; + + if (aDesiredSize.height == 0 || + desiredHeightWithBottomBP <= aReflowState.availableHeight || + aReflowState.ComputedHeight() == NS_INTRINSICSIZE) { + // Update desired height to include bottom border/padding + aDesiredSize.height = desiredHeightWithBottomBP; + } else { + // We couldn't fit bottom border/padding, so we'll need a continuation. + NS_FRAME_SET_INCOMPLETE(aStatus); + } + } + // Overflow area = union(my overflow area, kids' overflow areas) aDesiredSize.SetOverflowAreasToDesiredBounds(); for (nsFrameList::Enumerator e(mFrames); !e.AtEnd(); e.Next()) { diff --git a/layout/generic/nsFlexContainerFrame.h b/layout/generic/nsFlexContainerFrame.h index 56b1134c1a22..0a371121ecc6 100644 --- a/layout/generic/nsFlexContainerFrame.h +++ b/layout/generic/nsFlexContainerFrame.h @@ -106,7 +106,16 @@ protected: nscoord ComputeFlexContainerMainSize(const nsHTMLReflowState& aReflowState, const FlexboxAxisTracker& aAxisTracker, - const nsTArray& aFlexItems); + const nsTArray& aFlexItems, + nscoord aAvailableHeightForContent, + nsReflowStatus& aStatus); + + nscoord ComputeFlexContainerCrossSize(const nsHTMLReflowState& aReflowState, + const FlexboxAxisTracker& aAxisTracker, + nscoord aLineCrossSize, + nscoord aAvailableHeightForContent, + bool* aIsDefinite, + nsReflowStatus& aStatus); void PositionItemInMainAxis(MainAxisPositionTracker& aMainAxisPosnTracker, FlexItem& aItem); diff --git a/layout/reftests/flexbox/pagination/flexbox-empty-1-ref.html b/layout/reftests/flexbox/pagination/flexbox-empty-1-ref.html new file mode 100644 index 000000000000..2f002b63b956 --- /dev/null +++ b/layout/reftests/flexbox/pagination/flexbox-empty-1-ref.html @@ -0,0 +1,99 @@ + + + + + + + + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + + diff --git a/layout/reftests/flexbox/pagination/flexbox-empty-1a.html b/layout/reftests/flexbox/pagination/flexbox-empty-1a.html new file mode 100644 index 000000000000..ae7297f59fa1 --- /dev/null +++ b/layout/reftests/flexbox/pagination/flexbox-empty-1a.html @@ -0,0 +1,105 @@ + + + + + + + + + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + + diff --git a/layout/reftests/flexbox/pagination/flexbox-empty-1b.html b/layout/reftests/flexbox/pagination/flexbox-empty-1b.html new file mode 100644 index 000000000000..40cdcbe4008d --- /dev/null +++ b/layout/reftests/flexbox/pagination/flexbox-empty-1b.html @@ -0,0 +1,105 @@ + + + + + + + + + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + + diff --git a/layout/reftests/flexbox/pagination/flexbox-empty-1c.html b/layout/reftests/flexbox/pagination/flexbox-empty-1c.html new file mode 100644 index 000000000000..16dd69748c6f --- /dev/null +++ b/layout/reftests/flexbox/pagination/flexbox-empty-1c.html @@ -0,0 +1,105 @@ + + + + + + + + + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + + diff --git a/layout/reftests/flexbox/pagination/flexbox-empty-1d.html b/layout/reftests/flexbox/pagination/flexbox-empty-1d.html new file mode 100644 index 000000000000..086b3b0068d3 --- /dev/null +++ b/layout/reftests/flexbox/pagination/flexbox-empty-1d.html @@ -0,0 +1,105 @@ + + + + + + + + + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + + diff --git a/layout/reftests/flexbox/pagination/flexbox-empty-1e.html b/layout/reftests/flexbox/pagination/flexbox-empty-1e.html new file mode 100644 index 000000000000..d631c1857f9d --- /dev/null +++ b/layout/reftests/flexbox/pagination/flexbox-empty-1e.html @@ -0,0 +1,109 @@ + + + + + + + + + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + + diff --git a/layout/reftests/flexbox/pagination/flexbox-empty-1f.html b/layout/reftests/flexbox/pagination/flexbox-empty-1f.html new file mode 100644 index 000000000000..4879d1527d19 --- /dev/null +++ b/layout/reftests/flexbox/pagination/flexbox-empty-1f.html @@ -0,0 +1,109 @@ + + + + + + + + + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + + diff --git a/layout/reftests/flexbox/pagination/flexbox-empty-1g.html b/layout/reftests/flexbox/pagination/flexbox-empty-1g.html new file mode 100644 index 000000000000..40b7a2ef8fcc --- /dev/null +++ b/layout/reftests/flexbox/pagination/flexbox-empty-1g.html @@ -0,0 +1,109 @@ + + + + + + + + + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + + diff --git a/layout/reftests/flexbox/pagination/flexbox-empty-1h.html b/layout/reftests/flexbox/pagination/flexbox-empty-1h.html new file mode 100644 index 000000000000..8d2be34b2356 --- /dev/null +++ b/layout/reftests/flexbox/pagination/flexbox-empty-1h.html @@ -0,0 +1,109 @@ + + + + + + + + + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + + diff --git a/layout/reftests/flexbox/pagination/flexbox-empty-2-ref.html b/layout/reftests/flexbox/pagination/flexbox-empty-2-ref.html new file mode 100644 index 000000000000..0697416b7f40 --- /dev/null +++ b/layout/reftests/flexbox/pagination/flexbox-empty-2-ref.html @@ -0,0 +1,136 @@ + + + + + + + + + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + + diff --git a/layout/reftests/flexbox/pagination/flexbox-empty-2a.html b/layout/reftests/flexbox/pagination/flexbox-empty-2a.html new file mode 100644 index 000000000000..31ee91cf3abc --- /dev/null +++ b/layout/reftests/flexbox/pagination/flexbox-empty-2a.html @@ -0,0 +1,138 @@ + + + + + + + + + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + + diff --git a/layout/reftests/flexbox/pagination/flexbox-empty-2b.html b/layout/reftests/flexbox/pagination/flexbox-empty-2b.html new file mode 100644 index 000000000000..10cd9b22d846 --- /dev/null +++ b/layout/reftests/flexbox/pagination/flexbox-empty-2b.html @@ -0,0 +1,138 @@ + + + + + + + + + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + + diff --git a/layout/reftests/flexbox/pagination/flexbox-empty-2c.html b/layout/reftests/flexbox/pagination/flexbox-empty-2c.html new file mode 100644 index 000000000000..3e606df23d1f --- /dev/null +++ b/layout/reftests/flexbox/pagination/flexbox-empty-2c.html @@ -0,0 +1,138 @@ + + + + + + + + + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + + diff --git a/layout/reftests/flexbox/pagination/flexbox-empty-2d.html b/layout/reftests/flexbox/pagination/flexbox-empty-2d.html new file mode 100644 index 000000000000..e45df0ffa374 --- /dev/null +++ b/layout/reftests/flexbox/pagination/flexbox-empty-2d.html @@ -0,0 +1,138 @@ + + + + + + + + + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + + diff --git a/layout/reftests/flexbox/pagination/flexbox-unbreakable-child-1-ref.html b/layout/reftests/flexbox/pagination/flexbox-unbreakable-child-1-ref.html new file mode 100644 index 000000000000..e1f4fe498119 --- /dev/null +++ b/layout/reftests/flexbox/pagination/flexbox-unbreakable-child-1-ref.html @@ -0,0 +1,62 @@ + + + + + + + + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + diff --git a/layout/reftests/flexbox/pagination/flexbox-unbreakable-child-1a.html b/layout/reftests/flexbox/pagination/flexbox-unbreakable-child-1a.html new file mode 100644 index 000000000000..5b36072b7dba --- /dev/null +++ b/layout/reftests/flexbox/pagination/flexbox-unbreakable-child-1a.html @@ -0,0 +1,66 @@ + + + + + + + + + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + diff --git a/layout/reftests/flexbox/pagination/flexbox-unbreakable-child-1b.html b/layout/reftests/flexbox/pagination/flexbox-unbreakable-child-1b.html new file mode 100644 index 000000000000..91a9fa788b00 --- /dev/null +++ b/layout/reftests/flexbox/pagination/flexbox-unbreakable-child-1b.html @@ -0,0 +1,66 @@ + + + + + + + + + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + diff --git a/layout/reftests/flexbox/pagination/flexbox-unbreakable-child-1c.html b/layout/reftests/flexbox/pagination/flexbox-unbreakable-child-1c.html new file mode 100644 index 000000000000..26123a5bfbf3 --- /dev/null +++ b/layout/reftests/flexbox/pagination/flexbox-unbreakable-child-1c.html @@ -0,0 +1,67 @@ + + + + + + + + + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + diff --git a/layout/reftests/flexbox/pagination/flexbox-unbreakable-child-1d.html b/layout/reftests/flexbox/pagination/flexbox-unbreakable-child-1d.html new file mode 100644 index 000000000000..ff8f86b6d5da --- /dev/null +++ b/layout/reftests/flexbox/pagination/flexbox-unbreakable-child-1d.html @@ -0,0 +1,68 @@ + + + + + + + + + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + diff --git a/layout/reftests/flexbox/pagination/reftest.list b/layout/reftests/flexbox/pagination/reftest.list new file mode 100644 index 000000000000..e35ea9c4a2f0 --- /dev/null +++ b/layout/reftests/flexbox/pagination/reftest.list @@ -0,0 +1,25 @@ +# Tests with an empty flex container being fragmented: +== flexbox-empty-1a.html flexbox-empty-1-ref.html +== flexbox-empty-1b.html flexbox-empty-1-ref.html +== flexbox-empty-1c.html flexbox-empty-1-ref.html +== flexbox-empty-1d.html flexbox-empty-1-ref.html + +# Tests with an empty flex container that overflows a short fixed-height block +# being fragmented: +== flexbox-empty-1e.html flexbox-empty-1-ref.html +== flexbox-empty-1f.html flexbox-empty-1-ref.html +== flexbox-empty-1g.html flexbox-empty-1-ref.html +== flexbox-empty-1h.html flexbox-empty-1-ref.html + +# Tests with an empty flex container being fragmented, with margin, border, +# and/or padding being taller than the available height: +== flexbox-empty-2a.html flexbox-empty-2-ref.html +== flexbox-empty-2b.html flexbox-empty-2-ref.html +== flexbox-empty-2c.html flexbox-empty-2-ref.html +== flexbox-empty-2d.html flexbox-empty-2-ref.html + +# Tests for how we fragment a flex container with one unbreakable child +== flexbox-unbreakable-child-1a.html flexbox-unbreakable-child-1-ref.html +== flexbox-unbreakable-child-1b.html flexbox-unbreakable-child-1-ref.html +== flexbox-unbreakable-child-1c.html flexbox-unbreakable-child-1-ref.html +== flexbox-unbreakable-child-1d.html flexbox-unbreakable-child-1-ref.html diff --git a/layout/reftests/flexbox/reftest.list b/layout/reftests/flexbox/reftest.list index 3c599e92f256..62a5fd053c8b 100644 --- a/layout/reftests/flexbox/reftest.list +++ b/layout/reftests/flexbox/reftest.list @@ -9,6 +9,9 @@ # tests over to the w3c-css directory, so that they can become part of the # W3C's test suite. +# SUBDIRECTORY: Reftests for paginated flex containers +include pagination/reftest.list + # Tests for cross-axis alignment (align-self / align-items properties) fails == flexbox-align-self-baseline-horiz-2.xhtml flexbox-align-self-baseline-horiz-2-ref.xhtml # bug 793456, and possibly others # This one fails on windows R (but not Ru, strangely). On Windows R, the diff --git a/memory/build/moz.build b/memory/build/moz.build index 034f261adfef..f933a886a9c4 100644 --- a/memory/build/moz.build +++ b/memory/build/moz.build @@ -14,18 +14,18 @@ if CONFIG['MOZ_REPLACE_MALLOC']: 'malloc_decls.h', 'replace_malloc.h', ] -UNIFIED_SOURCES += [ +SOURCES += [ 'jemalloc_config.c', 'mozmemory_wrap.c', ] if CONFIG['MOZ_JEMALLOC3']: - UNIFIED_SOURCES += [ + SOURCES += [ 'mozjemalloc_compat.c', ] if CONFIG['MOZ_REPLACE_MALLOC']: - UNIFIED_SOURCES += [ + SOURCES += [ 'replace_malloc.c', ] diff --git a/memory/jemalloc/moz.build b/memory/jemalloc/moz.build index b01ddbad646b..b40f981b4506 100644 --- a/memory/jemalloc/moz.build +++ b/memory/jemalloc/moz.build @@ -4,14 +4,8 @@ # 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/. -# These cannot be built unified because they both define static arena_purge -# functions with different types. SOURCES += [ 'src/src/arena.c', - 'src/src/ctl.c', -] - -UNIFIED_SOURCES += [ 'src/src/atomic.c', 'src/src/base.c', 'src/src/bitmap.c', @@ -19,6 +13,7 @@ UNIFIED_SOURCES += [ 'src/src/chunk_dss.c', 'src/src/chunk_mmap.c', 'src/src/ckh.c', + 'src/src/ctl.c', 'src/src/extent.c', 'src/src/hash.c', 'src/src/huge.c', @@ -37,7 +32,7 @@ UNIFIED_SOURCES += [ # Only OSX needs the zone allocation implementation, # but only if replace-malloc is not enabled. if CONFIG['OS_TARGET'] == 'Darwin' and not CONFIG['MOZ_REPLACE_MALLOC']: - UNIFIED_SOURCES += [ + SOURCES += [ 'src/src/zone.c', ] diff --git a/memory/mozalloc/moz.build b/memory/mozalloc/moz.build index 99cfff9630aa..0f20f6d51ace 100644 --- a/memory/mozalloc/moz.build +++ b/memory/mozalloc/moz.build @@ -32,7 +32,7 @@ if CONFIG['WRAP_STL_INCLUDES']: 'msvc_throw_wrapper.cpp', ] -UNIFIED_SOURCES += [ +SOURCES += [ 'mozalloc.cpp', 'mozalloc_abort.cpp', 'mozalloc_oom.cpp', diff --git a/mobile/android/base/GeckoAppShell.java b/mobile/android/base/GeckoAppShell.java index 7601d4fa466e..5aa3ab752972 100644 --- a/mobile/android/base/GeckoAppShell.java +++ b/mobile/android/base/GeckoAppShell.java @@ -10,10 +10,10 @@ import org.mozilla.gecko.gfx.BitmapUtils; import org.mozilla.gecko.gfx.GeckoLayerClient; import org.mozilla.gecko.gfx.LayerView; import org.mozilla.gecko.gfx.PanZoomController; +import org.mozilla.gecko.mozglue.generatorannotations.OptionalGeneratedParameter; +import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; import org.mozilla.gecko.prompts.PromptService; import org.mozilla.gecko.mozglue.GeckoLoader; -import org.mozilla.gecko.mozglue.GeneratableAndroidBridgeTarget; -import org.mozilla.gecko.mozglue.OptionalGeneratedParameter; import org.mozilla.gecko.util.EventDispatcher; import org.mozilla.gecko.util.GeckoEventListener; import org.mozilla.gecko.util.HardwareUtils; @@ -402,14 +402,14 @@ public class GeckoAppShell /* * The Gecko-side API: API methods that Gecko calls */ - @GeneratableAndroidBridgeTarget(generateStatic = true) + @WrapElementForJNI(generateStatic = true) public static void notifyIME(int type) { if (mEditableListener != null) { mEditableListener.notifyIME(type); } } - @GeneratableAndroidBridgeTarget(generateStatic = true) + @WrapElementForJNI(generateStatic = true) public static void notifyIMEContext(int state, String typeHint, String modeHint, String actionHint) { if (mEditableListener != null) { @@ -418,7 +418,7 @@ public class GeckoAppShell } } - @GeneratableAndroidBridgeTarget(generateStatic = true) + @WrapElementForJNI(generateStatic = true) public static void notifyIMEChange(String text, int start, int end, int newEnd) { if (newEnd < 0) { // Selection change mEditableListener.onSelectionChange(start, end); @@ -462,7 +462,7 @@ public class GeckoAppShell } // Signal the Java thread that it's time to wake up - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void acknowledgeEvent() { synchronized (sEventAckLock) { sWaitingForEventAck = false; @@ -501,7 +501,7 @@ public class GeckoAppShell return lastKnownLocation; } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void enableLocation(final boolean enable) { ThreadUtils.postToUiThread(new Runnable() { @Override @@ -557,12 +557,12 @@ public class GeckoAppShell } } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void enableLocationHighAccuracy(final boolean enable) { mLocationHighAccuracy = enable; } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void enableSensor(int aSensortype) { GeckoInterface gi = getGeckoInterface(); if (gi == null) @@ -617,7 +617,7 @@ public class GeckoAppShell } } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void disableSensor(int aSensortype) { GeckoInterface gi = getGeckoInterface(); if (gi == null) @@ -661,7 +661,7 @@ public class GeckoAppShell } } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void moveTaskToBack() { if (getGeckoInterface() != null) getGeckoInterface().getActivity().moveTaskToBack(true); @@ -672,7 +672,7 @@ public class GeckoAppShell // Native Fennec doesn't care because the Java code already knows the selection indexes. } - @GeneratableAndroidBridgeTarget(stubName = "NotifyXreExit") + @WrapElementForJNI(stubName = "NotifyXreExit") static void onXreExit() { // The launch state can only be Launched or GeckoRunning at this point GeckoThread.setLaunchState(GeckoThread.LaunchState.GeckoExiting); @@ -688,7 +688,7 @@ public class GeckoAppShell System.exit(0); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI static void scheduleRestart() { gRestartScheduled = true; } @@ -731,7 +731,7 @@ public class GeckoAppShell // "Installs" an application by creating a shortcut // This is the entry point from AndroidBridge.h - @GeneratableAndroidBridgeTarget + @WrapElementForJNI static void createShortcut(String aTitle, String aURI, String aIconData, String aType) { if ("webapp".equals(aType)) { Log.w(LOGTAG, "createShortcut with no unique URI should not be used for aType = webapp!"); @@ -926,7 +926,7 @@ public class GeckoAppShell return bitmap; } - @GeneratableAndroidBridgeTarget(stubName = "GetHandlersForMimeTypeWrapper") + @WrapElementForJNI(stubName = "GetHandlersForMimeTypeWrapper") static String[] getHandlersForMimeType(String aMimeType, String aAction) { Intent intent = getIntentForActionString(aAction); if (aMimeType != null && aMimeType.length() > 0) @@ -934,7 +934,7 @@ public class GeckoAppShell return getHandlersForIntent(intent); } - @GeneratableAndroidBridgeTarget(stubName = "GetHandlersForURLWrapper") + @WrapElementForJNI(stubName = "GetHandlersForURLWrapper") static String[] getHandlersForURL(String aURL, String aAction) { // aURL may contain the whole URL or just the protocol Uri uri = aURL.indexOf(':') >= 0 ? Uri.parse(aURL) : new Uri.Builder().scheme(aURL).build(); @@ -977,12 +977,12 @@ public class GeckoAppShell return new Intent(aAction); } - @GeneratableAndroidBridgeTarget(stubName = "GetExtensionFromMimeTypeWrapper") + @WrapElementForJNI(stubName = "GetExtensionFromMimeTypeWrapper") static String getExtensionFromMimeType(String aMimeType) { return MimeTypeMap.getSingleton().getExtensionFromMimeType(aMimeType); } - @GeneratableAndroidBridgeTarget(stubName = "GetMimeTypeFromExtensionsWrapper") + @WrapElementForJNI(stubName = "GetMimeTypeFromExtensionsWrapper") static String getMimeTypeFromExtensions(String aFileExt) { StringTokenizer st = new StringTokenizer(aFileExt, ".,; "); String type = null; @@ -1115,7 +1115,7 @@ public class GeckoAppShell * @param title the title to use in ACTION_SEND intents. * @return true if the activity started successfully; false otherwise. */ - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static boolean openUriExternal(String targetURI, String mimeType, @OptionalGeneratedParameter String packageName, @@ -1301,7 +1301,7 @@ public class GeckoAppShell } } - @GeneratableAndroidBridgeTarget(stubName = "ShowAlertNotificationWrapper") + @WrapElementForJNI(stubName = "ShowAlertNotificationWrapper") public static void showAlertNotification(String aImageUrl, String aAlertTitle, String aAlertText, String aAlertCookie, String aAlertName) { // The intent to launch when the user clicks the expanded notification @@ -1328,13 +1328,13 @@ public class GeckoAppShell sNotificationClient.add(notificationID, aImageUrl, aAlertTitle, aAlertText, contentIntent); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void alertsProgressListener_OnProgress(String aAlertName, long aProgress, long aProgressMax, String aAlertText) { int notificationID = aAlertName.hashCode(); sNotificationClient.update(notificationID, aProgress, aProgressMax, aAlertText); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void closeNotification(String aAlertName) { String alertCookie = mAlertCookies.get(aAlertName); if (alertCookie != null) { @@ -1362,7 +1362,7 @@ public class GeckoAppShell closeNotification(aAlertName); } - @GeneratableAndroidBridgeTarget(stubName = "GetDpiWrapper") + @WrapElementForJNI(stubName = "GetDpiWrapper") public static int getDpi() { if (sDensityDpi == 0) { sDensityDpi = getContext().getResources().getDisplayMetrics().densityDpi; @@ -1371,7 +1371,7 @@ public class GeckoAppShell return sDensityDpi; } - @GeneratableAndroidBridgeTarget() + @WrapElementForJNI public static float getDensity() { return getContext().getResources().getDisplayMetrics().density; } @@ -1406,7 +1406,7 @@ public class GeckoAppShell * Returns the colour depth of the default screen. This will either be * 24 or 16. */ - @GeneratableAndroidBridgeTarget(stubName = "GetScreenDepthWrapper") + @WrapElementForJNI(stubName = "GetScreenDepthWrapper") public static synchronized int getScreenDepth() { if (sScreenDepth == 0) { sScreenDepth = 16; @@ -1429,27 +1429,27 @@ public class GeckoAppShell sScreenDepth = aScreenDepth; } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void setFullScreen(boolean fullscreen) { if (getGeckoInterface() != null) getGeckoInterface().setFullScreen(fullscreen); } - @GeneratableAndroidBridgeTarget(stubName = "ShowFilePickerForExtensionsWrapper") + @WrapElementForJNI(stubName = "ShowFilePickerForExtensionsWrapper") public static String showFilePickerForExtensions(String aExtensions) { if (getGeckoInterface() != null) return sActivityHelper.showFilePicker(getGeckoInterface().getActivity(), getMimeTypeFromExtensions(aExtensions)); return ""; } - @GeneratableAndroidBridgeTarget(stubName = "ShowFilePickerForMimeTypeWrapper") + @WrapElementForJNI(stubName = "ShowFilePickerForMimeTypeWrapper") public static String showFilePickerForMimeType(String aMimeType) { if (getGeckoInterface() != null) return sActivityHelper.showFilePicker(getGeckoInterface().getActivity(), aMimeType); return ""; } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void performHapticFeedback(boolean aIsLongPress) { // Don't perform haptic feedback if a vibration is currently playing, // because the haptic feedback will nuke the vibration. @@ -1466,14 +1466,14 @@ public class GeckoAppShell return (Vibrator) layerView.getContext().getSystemService(Context.VIBRATOR_SERVICE); } - @GeneratableAndroidBridgeTarget(stubName = "Vibrate1") + @WrapElementForJNI(stubName = "Vibrate1") public static void vibrate(long milliseconds) { sVibrationEndTime = System.nanoTime() + milliseconds * 1000000; sVibrationMaybePlaying = true; vibrator().vibrate(milliseconds); } - @GeneratableAndroidBridgeTarget(stubName = "VibrateA") + @WrapElementForJNI(stubName = "VibrateA") public static void vibrate(long[] pattern, int repeat) { // If pattern.length is even, the last element in the pattern is a // meaningless delay, so don't include it in vibrationDuration. @@ -1488,21 +1488,21 @@ public class GeckoAppShell vibrator().vibrate(pattern, repeat); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void cancelVibrate() { sVibrationMaybePlaying = false; sVibrationEndTime = 0; vibrator().cancel(); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void showInputMethodPicker() { InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.showInputMethodPicker(); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void setKeepScreenOn(final boolean on) { ThreadUtils.postToUiThread(new Runnable() { @Override @@ -1512,7 +1512,7 @@ public class GeckoAppShell }); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void notifyDefaultPrevented(final boolean defaultPrevented) { ThreadUtils.postToUiThread(new Runnable() { @Override @@ -1526,7 +1526,7 @@ public class GeckoAppShell }); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static boolean isNetworkLinkUp() { ConnectivityManager cm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); @@ -1536,7 +1536,7 @@ public class GeckoAppShell return true; } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static boolean isNetworkLinkKnown() { ConnectivityManager cm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); @@ -1545,7 +1545,7 @@ public class GeckoAppShell return true; } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static int networkLinkType() { ConnectivityManager cm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); @@ -1604,7 +1604,7 @@ public class GeckoAppShell } } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void setSelectedLocale(String localeCode) { /* Bug 713464: This method is still called from Gecko side. Earlier we had an option to run Firefox in a language other than system's language. @@ -1643,7 +1643,7 @@ public class GeckoAppShell } - @GeneratableAndroidBridgeTarget(stubName = "GetSystemColoursWrapper") + @WrapElementForJNI(stubName = "GetSystemColoursWrapper") public static int[] getSystemColors() { // attrsAppearance[] must correspond to AndroidSystemColors structure in android/AndroidBridge.h final int[] attrsAppearance = { @@ -1680,7 +1680,7 @@ public class GeckoAppShell return result; } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void killAnyZombies() { GeckoProcessesVisitor visitor = new GeckoProcessesVisitor() { @Override @@ -1836,7 +1836,7 @@ public class GeckoAppShell } catch (Exception e) { } } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void scanMedia(String aFile, String aMimeType) { // If the platform didn't give us a mimetype, try to guess one from the filename if (TextUtils.isEmpty(aMimeType)) { @@ -1850,7 +1850,7 @@ public class GeckoAppShell GeckoMediaScannerClient.startScan(context, aFile, aMimeType); } - @GeneratableAndroidBridgeTarget(stubName = "GetIconForExtensionWrapper") + @WrapElementForJNI(stubName = "GetIconForExtensionWrapper") public static byte[] getIconForExtension(String aExt, int iconSize) { try { if (iconSize <= 0) @@ -1908,7 +1908,7 @@ public class GeckoAppShell return activityInfo.loadIcon(pm); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static boolean getShowPasswordSetting() { try { int showPassword = @@ -1921,7 +1921,7 @@ public class GeckoAppShell } } - @GeneratableAndroidBridgeTarget(stubName = "AddPluginViewWrapper") + @WrapElementForJNI(stubName = "AddPluginViewWrapper") public static void addPluginView(View view, float x, float y, float w, float h, @@ -1930,7 +1930,7 @@ public class GeckoAppShell getGeckoInterface().addPluginView(view, new RectF(x, y, x + w, y + h), isFullScreen); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void removePluginView(View view, boolean isFullScreen) { if (getGeckoInterface() != null) getGeckoInterface().removePluginView(view, isFullScreen); @@ -2154,7 +2154,7 @@ public class GeckoAppShell private static ContextGetter sContextGetter; - @GeneratableAndroidBridgeTarget(allowMultithread = true) + @WrapElementForJNI(allowMultithread = true) public static Context getContext() { return sContextGetter.getContext(); } @@ -2212,7 +2212,7 @@ public class GeckoAppShell static byte[] sCameraBuffer = null; - @GeneratableAndroidBridgeTarget(stubName = "InitCameraWrapper") + @WrapElementForJNI(stubName = "InitCameraWrapper") static int[] initCamera(String aContentType, int aCamera, int aWidth, int aHeight) { ThreadUtils.postToUiThread(new Runnable() { @Override @@ -2313,7 +2313,7 @@ public class GeckoAppShell return result; } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI static synchronized void closeCamera() { ThreadUtils.postToUiThread(new Runnable() { @Override @@ -2365,32 +2365,32 @@ public class GeckoAppShell /* * Battery API related methods. */ - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void enableBatteryNotifications() { GeckoBatteryManager.enableNotifications(); } - @GeneratableAndroidBridgeTarget(stubName = "HandleGeckoMessageWrapper") + @WrapElementForJNI(stubName = "HandleGeckoMessageWrapper") public static String handleGeckoMessage(String message) { return sEventDispatcher.dispatchEvent(message); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void disableBatteryNotifications() { GeckoBatteryManager.disableNotifications(); } - @GeneratableAndroidBridgeTarget(stubName = "GetCurrentBatteryInformationWrapper") + @WrapElementForJNI(stubName = "GetCurrentBatteryInformationWrapper") public static double[] getCurrentBatteryInformation() { return GeckoBatteryManager.getCurrentInformation(); } - @GeneratableAndroidBridgeTarget(stubName = "CheckURIVisited") + @WrapElementForJNI(stubName = "CheckURIVisited") static void checkUriVisited(String uri) { GlobalHistory.getInstance().checkUriVisited(uri); } - @GeneratableAndroidBridgeTarget(stubName = "MarkURIVisited") + @WrapElementForJNI(stubName = "MarkURIVisited") static void markUriVisited(final String uri) { ThreadUtils.postToBackgroundThread(new Runnable() { @Override @@ -2400,7 +2400,7 @@ public class GeckoAppShell }); } - @GeneratableAndroidBridgeTarget(stubName = "SetURITitle") + @WrapElementForJNI(stubName = "SetURITitle") static void setUriTitle(final String uri, final String title) { ThreadUtils.postToBackgroundThread(new Runnable() { @Override @@ -2410,7 +2410,7 @@ public class GeckoAppShell }); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI static void hideProgressDialog() { // unused stub } @@ -2418,7 +2418,7 @@ public class GeckoAppShell /* * WebSMS related methods. */ - @GeneratableAndroidBridgeTarget(stubName = "SendMessageWrapper") + @WrapElementForJNI(stubName = "SendMessageWrapper") public static void sendMessage(String aNumber, String aMessage, int aRequestId) { if (SmsManager.getInstance() == null) { return; @@ -2427,7 +2427,7 @@ public class GeckoAppShell SmsManager.getInstance().send(aNumber, aMessage, aRequestId); } - @GeneratableAndroidBridgeTarget(stubName = "GetMessageWrapper") + @WrapElementForJNI(stubName = "GetMessageWrapper") public static void getMessage(int aMessageId, int aRequestId) { if (SmsManager.getInstance() == null) { return; @@ -2436,7 +2436,7 @@ public class GeckoAppShell SmsManager.getInstance().getMessage(aMessageId, aRequestId); } - @GeneratableAndroidBridgeTarget(stubName = "DeleteMessageWrapper") + @WrapElementForJNI(stubName = "DeleteMessageWrapper") public static void deleteMessage(int aMessageId, int aRequestId) { if (SmsManager.getInstance() == null) { return; @@ -2445,7 +2445,7 @@ public class GeckoAppShell SmsManager.getInstance().deleteMessage(aMessageId, aRequestId); } - @GeneratableAndroidBridgeTarget(stubName = "CreateMessageListWrapper") + @WrapElementForJNI(stubName = "CreateMessageListWrapper") public static void createMessageList(long aStartDate, long aEndDate, String[] aNumbers, int aNumbersCount, int aDeliveryState, boolean aReverse, int aRequestId) { if (SmsManager.getInstance() == null) { return; @@ -2454,7 +2454,7 @@ public class GeckoAppShell SmsManager.getInstance().createMessageList(aStartDate, aEndDate, aNumbers, aNumbersCount, aDeliveryState, aReverse, aRequestId); } - @GeneratableAndroidBridgeTarget(stubName = "GetNextMessageInListWrapper") + @WrapElementForJNI(stubName = "GetNextMessageInListWrapper") public static void getNextMessageInList(int aListId, int aRequestId) { if (SmsManager.getInstance() == null) { return; @@ -2463,7 +2463,7 @@ public class GeckoAppShell SmsManager.getInstance().getNextMessageInList(aListId, aRequestId); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void clearMessageList(int aListId) { if (SmsManager.getInstance() == null) { return; @@ -2473,7 +2473,7 @@ public class GeckoAppShell } /* Called by JNI from AndroidBridge, and by reflection from tests/BaseTest.java.in */ - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static boolean isTablet() { return HardwareUtils.isTablet(); } @@ -2486,17 +2486,17 @@ public class GeckoAppShell } } - @GeneratableAndroidBridgeTarget(stubName = "GetCurrentNetworkInformationWrapper") + @WrapElementForJNI(stubName = "GetCurrentNetworkInformationWrapper") public static double[] getCurrentNetworkInformation() { return GeckoNetworkManager.getInstance().getCurrentInformation(); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void enableNetworkNotifications() { GeckoNetworkManager.getInstance().enableNotifications(); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void disableNetworkNotifications() { GeckoNetworkManager.getInstance().disableNotifications(); } @@ -2610,32 +2610,32 @@ public class GeckoAppShell return decodeBase64(s.getBytes(), flags); } - @GeneratableAndroidBridgeTarget(stubName = "GetScreenOrientationWrapper") + @WrapElementForJNI(stubName = "GetScreenOrientationWrapper") public static short getScreenOrientation() { return GeckoScreenOrientationListener.getInstance().getScreenOrientation(); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void enableScreenOrientationNotifications() { GeckoScreenOrientationListener.getInstance().enableNotifications(); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void disableScreenOrientationNotifications() { GeckoScreenOrientationListener.getInstance().disableNotifications(); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void lockScreenOrientation(int aOrientation) { GeckoScreenOrientationListener.getInstance().lockScreenOrientation(aOrientation); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void unlockScreenOrientation() { GeckoScreenOrientationListener.getInstance().unlockScreenOrientation(); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static boolean pumpMessageLoop() { Handler geckoHandler = ThreadUtils.sGeckoHandler; Message msg = getNextMessageFromQueue(ThreadUtils.sGeckoQueue); @@ -2657,7 +2657,7 @@ public class GeckoAppShell static native void notifyFilePickerResult(String filePath, long id); - @GeneratableAndroidBridgeTarget(stubName = "ShowFilePickerAsyncWrapper") + @WrapElementForJNI(stubName = "ShowFilePickerAsyncWrapper") public static void showFilePickerAsync(String aMimeType, final long id) { sActivityHelper.showFilePickerAsync(getGeckoInterface().getActivity(), aMimeType, new ActivityHandlerHelper.FileResultHandler() { public void gotFile(String filename) { @@ -2666,13 +2666,13 @@ public class GeckoAppShell }); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void notifyWakeLockChanged(String topic, String state) { if (getGeckoInterface() != null) getGeckoInterface().notifyWakeLockChanged(topic, state); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static void registerSurfaceTextureFrameListener(Object surfaceTexture, final int id) { ((SurfaceTexture)surfaceTexture).setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() { @Override @@ -2682,12 +2682,12 @@ public class GeckoAppShell }); } - @GeneratableAndroidBridgeTarget(allowMultithread = true) + @WrapElementForJNI(allowMultithread = true) public static void unregisterSurfaceTextureFrameListener(Object surfaceTexture) { ((SurfaceTexture)surfaceTexture).setOnFrameAvailableListener(null); } - @GeneratableAndroidBridgeTarget + @WrapElementForJNI public static boolean unlockProfile() { // Try to kill any zombie Fennec's that might be running GeckoAppShell.killAnyZombies(); @@ -2701,7 +2701,7 @@ public class GeckoAppShell return false; } - @GeneratableAndroidBridgeTarget(stubName = "GetProxyForURIWrapper") + @WrapElementForJNI(stubName = "GetProxyForURIWrapper") public static String getProxyForURI(String spec, String scheme, String host, int port) { URI uri = null; try { diff --git a/mobile/android/base/GeckoEvent.java b/mobile/android/base/GeckoEvent.java index 3ed9310ddb89..3c671d94d8fb 100644 --- a/mobile/android/base/GeckoEvent.java +++ b/mobile/android/base/GeckoEvent.java @@ -7,6 +7,8 @@ package org.mozilla.gecko; import org.mozilla.gecko.gfx.DisplayPortMetrics; import org.mozilla.gecko.gfx.ImmutableViewportMetrics; +import org.mozilla.gecko.mozglue.generatorannotations.GeneratorOptions; +import org.mozilla.gecko.mozglue.generatorannotations.WrapEntireClassForJNI; import android.content.res.Resources; import android.graphics.Point; @@ -83,6 +85,8 @@ public class GeckoEvent { * The DomKeyLocation enum encapsulates the DOM KeyboardEvent's constants. * @see https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent#Key_location_constants */ + @GeneratorOptions(generatedClassName = "JavaDomKeyLocation") + @WrapEntireClassForJNI public enum DomKeyLocation { DOM_KEY_LOCATION_STANDARD(0), DOM_KEY_LOCATION_LEFT(1), diff --git a/mobile/android/base/GeckoJavaSampler.java b/mobile/android/base/GeckoJavaSampler.java index f1ae7897d89a..051d70ad3f9b 100644 --- a/mobile/android/base/GeckoJavaSampler.java +++ b/mobile/android/base/GeckoJavaSampler.java @@ -8,7 +8,7 @@ package org.mozilla.gecko; import android.os.SystemClock; import android.util.Log; -import org.mozilla.gecko.mozglue.GeneratableAndroidBridgeTarget; +import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; import java.lang.Thread; import java.util.HashMap; @@ -126,7 +126,7 @@ public class GeckoJavaSampler { } - @GeneratableAndroidBridgeTarget(allowMultithread = true, stubName = "GetThreadNameJavaProfilingWrapper") + @WrapElementForJNI(allowMultithread = true, stubName = "GetThreadNameJavaProfilingWrapper") public synchronized static String getThreadName(int aThreadId) { if (aThreadId == 0 && sMainThread != null) { return sMainThread.getName(); @@ -138,7 +138,7 @@ public class GeckoJavaSampler { return sSamplingRunnable.getSample(aThreadId, aSampleId); } - @GeneratableAndroidBridgeTarget(allowMultithread = true, stubName = "GetSampleTimeJavaProfiling") + @WrapElementForJNI(allowMultithread = true, stubName = "GetSampleTimeJavaProfiling") public synchronized static double getSampleTime(int aThreadId, int aSampleId) { Sample sample = getSample(aThreadId, aSampleId); if (sample != null) { @@ -152,7 +152,7 @@ public class GeckoJavaSampler { return 0; } - @GeneratableAndroidBridgeTarget(allowMultithread = true, stubName = "GetFrameNameJavaProfilingWrapper") + @WrapElementForJNI(allowMultithread = true, stubName = "GetFrameNameJavaProfilingWrapper") public synchronized static String getFrameName(int aThreadId, int aSampleId, int aFrameId) { Sample sample = getSample(aThreadId, aSampleId); if (sample != null && aFrameId < sample.mFrames.length) { @@ -165,7 +165,7 @@ public class GeckoJavaSampler { return null; } - @GeneratableAndroidBridgeTarget(allowMultithread = true, stubName = "StartJavaProfiling") + @WrapElementForJNI(allowMultithread = true, stubName = "StartJavaProfiling") public static void start(int aInterval, int aSamples) { synchronized (GeckoJavaSampler.class) { if (sSamplingRunnable != null) { @@ -177,21 +177,21 @@ public class GeckoJavaSampler { } } - @GeneratableAndroidBridgeTarget(allowMultithread = true, stubName = "PauseJavaProfiling") + @WrapElementForJNI(allowMultithread = true, stubName = "PauseJavaProfiling") public static void pause() { synchronized (GeckoJavaSampler.class) { sSamplingRunnable.mPauseSampler = true; } } - @GeneratableAndroidBridgeTarget(allowMultithread = true, stubName = "UnpauseJavaProfiling") + @WrapElementForJNI(allowMultithread = true, stubName = "UnpauseJavaProfiling") public static void unpause() { synchronized (GeckoJavaSampler.class) { sSamplingRunnable.mPauseSampler = false; } } - @GeneratableAndroidBridgeTarget(allowMultithread = true, stubName = "StopJavaProfiling") + @WrapElementForJNI(allowMultithread = true, stubName = "StopJavaProfiling") public static void stop() { synchronized (GeckoJavaSampler.class) { if (sSamplingThread == null) { diff --git a/mobile/android/base/Makefile.in b/mobile/android/base/Makefile.in index 392e4005cdb4..6ed09e96bab4 100644 --- a/mobile/android/base/Makefile.in +++ b/mobile/android/base/Makefile.in @@ -151,7 +151,7 @@ ANNOTATION_PROCESSOR_JAR_FILES := $(DEPTH)/build/annotationProcessors/annotation GeneratedJNIWrappers.cpp: $(ANNOTATION_PROCESSOR_JAR_FILES) GeneratedJNIWrappers.cpp: $(ALL_JARS) - $(JAVA) -classpath $(JAVA_BOOTCLASSPATH):$(ANNOTATION_PROCESSOR_JAR_FILES) org.mozilla.gecko.annotationProcessors.AnnotationProcessor $(ALL_JARS) + $(JAVA) -classpath gecko-mozglue.jar:$(JAVA_BOOTCLASSPATH):$(ANNOTATION_PROCESSOR_JAR_FILES) org.mozilla.gecko.annotationProcessors.AnnotationProcessor $(ALL_JARS) gecko_package_dir = generated/org/mozilla/gecko # Like generated/org/mozilla/fennec_$USERID. diff --git a/mobile/android/base/SurfaceBits.java b/mobile/android/base/SurfaceBits.java index 52370b24ad83..5d481e1fb3df 100644 --- a/mobile/android/base/SurfaceBits.java +++ b/mobile/android/base/SurfaceBits.java @@ -4,8 +4,11 @@ package org.mozilla.gecko; +import org.mozilla.gecko.mozglue.generatorannotations.WrapEntireClassForJNI; + import java.nio.ByteBuffer; +@WrapEntireClassForJNI public class SurfaceBits { public int width; public int height; diff --git a/mobile/android/base/ThumbnailHelper.java b/mobile/android/base/ThumbnailHelper.java index dbc6afeb5be8..bc079152905a 100644 --- a/mobile/android/base/ThumbnailHelper.java +++ b/mobile/android/base/ThumbnailHelper.java @@ -9,7 +9,7 @@ import org.mozilla.gecko.db.BrowserDB; import org.mozilla.gecko.gfx.BitmapUtils; import org.mozilla.gecko.gfx.IntSize; import org.mozilla.gecko.mozglue.DirectBufferAllocator; -import org.mozilla.gecko.mozglue.GeneratableAndroidBridgeTarget; +import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; import android.graphics.Bitmap; import android.util.Log; @@ -151,7 +151,7 @@ public final class ThumbnailHelper { } /* This method is invoked by JNI once the thumbnail data is ready. */ - @GeneratableAndroidBridgeTarget(stubName = "SendThumbnail") + @WrapElementForJNI(stubName = "SendThumbnail") public static void notifyThumbnail(ByteBuffer data, int tabId, boolean success) { Tab tab = Tabs.getInstance().getTab(tabId); ThumbnailHelper helper = ThumbnailHelper.getInstance(); diff --git a/mobile/android/base/db/LocalBrowserDB.java b/mobile/android/base/db/LocalBrowserDB.java index 28da909f6e9b..e3cad0ce564e 100644 --- a/mobile/android/base/db/LocalBrowserDB.java +++ b/mobile/android/base/db/LocalBrowserDB.java @@ -402,10 +402,11 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface { c = cr.query(mBookmarksUriWithProfile, DEFAULT_BOOKMARK_COLUMNS, Bookmarks.PARENT + " = ? AND " + - "(" + Bookmarks.TYPE + " = ? OR " + Bookmarks.TYPE + " = ?)", + "(" + Bookmarks.TYPE + " = ? OR " + + "(" + Bookmarks.TYPE + " = ? AND " + Bookmarks.URL + " IS NOT NULL))", new String[] { String.valueOf(folderId), - String.valueOf(Bookmarks.TYPE_BOOKMARK), - String.valueOf(Bookmarks.TYPE_FOLDER) }, + String.valueOf(Bookmarks.TYPE_FOLDER), + String.valueOf(Bookmarks.TYPE_BOOKMARK) }, null); } diff --git a/mobile/android/base/gfx/DisplayPortMetrics.java b/mobile/android/base/gfx/DisplayPortMetrics.java index 91f8d05f001c..4bb5e8de8018 100644 --- a/mobile/android/base/gfx/DisplayPortMetrics.java +++ b/mobile/android/base/gfx/DisplayPortMetrics.java @@ -5,6 +5,7 @@ package org.mozilla.gecko.gfx; +import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; import org.mozilla.gecko.util.FloatUtils; import android.graphics.RectF; @@ -18,13 +19,16 @@ import android.graphics.RectF; * subsection of that with compositor scaling. */ public final class DisplayPortMetrics { + @WrapElementForJNI public final float resolution; + @WrapElementForJNI private final RectF mPosition; public DisplayPortMetrics() { this(0, 0, 0, 0, 1); } + @WrapElementForJNI public DisplayPortMetrics(float left, float top, float right, float bottom, float resolution) { this.resolution = resolution; mPosition = new RectF(left, top, right, bottom); diff --git a/mobile/android/base/gfx/GLController.java b/mobile/android/base/gfx/GLController.java index 780faa6d3244..6c2b7b122152 100644 --- a/mobile/android/base/gfx/GLController.java +++ b/mobile/android/base/gfx/GLController.java @@ -8,7 +8,7 @@ package org.mozilla.gecko.gfx; import org.mozilla.gecko.GeckoAppShell; import org.mozilla.gecko.GeckoEvent; import org.mozilla.gecko.GeckoThread; -import org.mozilla.gecko.mozglue.GeneratableAndroidBridgeTarget; +import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; import org.mozilla.gecko.util.ThreadUtils; import android.util.Log; @@ -215,7 +215,7 @@ public class GLController { throw new GLControllerException("No suitable EGL configuration found"); } - @GeneratableAndroidBridgeTarget(allowMultithread = true, stubName = "CreateEGLSurfaceForCompositorWrapper") + @WrapElementForJNI(allowMultithread = true, stubName = "CreateEGLSurfaceForCompositorWrapper") private EGLSurface createEGLSurfaceForCompositor() { initEGL(); return mEGL.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, mView.getNativeWindow(), null); diff --git a/mobile/android/base/gfx/GeckoLayerClient.java b/mobile/android/base/gfx/GeckoLayerClient.java index a37c90749a2f..5a0177680c54 100644 --- a/mobile/android/base/gfx/GeckoLayerClient.java +++ b/mobile/android/base/gfx/GeckoLayerClient.java @@ -11,6 +11,7 @@ import org.mozilla.gecko.GeckoEvent; import org.mozilla.gecko.Tab; import org.mozilla.gecko.Tabs; import org.mozilla.gecko.ZoomConstraints; +import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; import org.mozilla.gecko.util.EventDispatcher; import org.mozilla.gecko.util.FloatUtils; import org.mozilla.gecko.util.ThreadUtils; @@ -413,7 +414,7 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget return mDisplayPort; } - /* This is invoked by JNI on the gecko thread */ + @WrapElementForJNI DisplayPortMetrics getDisplayPort(boolean pageSizeUpdate, boolean isBrowserContentDisplayed, int tabId, ImmutableViewportMetrics metrics) { Tabs tabs = Tabs.getInstance(); if (isBrowserContentDisplayed && tabs.isSelectedTabId(tabId)) { @@ -430,12 +431,12 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget } } - /* This is invoked by JNI on the gecko thread */ + @WrapElementForJNI void contentDocumentChanged() { mContentDocumentIsDisplayed = false; } - /* This is invoked by JNI on the gecko thread */ + @WrapElementForJNI boolean isContentDocumentDisplayed() { return mContentDocumentIsDisplayed; } @@ -445,6 +446,7 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget // to abort the current update and continue with any subsequent ones. This // is useful for slow-to-render pages when the display-port starts lagging // behind enough that continuing to draw it is wasted effort. + @WrapElementForJNI(allowMultithread = true) public ProgressiveUpdateData progressiveUpdateCallback(boolean aHasPendingNewThebesContent, float x, float y, float width, float height, float resolution, boolean lowPrecision) { @@ -552,13 +554,13 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget } } - /** This function is invoked by Gecko via JNI; be careful when modifying signature. - * The compositor invokes this function just before compositing a frame where the document + /** The compositor invokes this function just before compositing a frame where the document * is different from the document composited on the last frame. In these cases, the viewport * information we have in Java is no longer valid and needs to be replaced with the new * viewport information provided. setPageRect will never be invoked on the same frame that * this function is invoked on; and this function will always be called prior to syncViewportInfo. */ + @WrapElementForJNI(allowMultithread = true) public void setFirstPaintViewport(float offsetX, float offsetY, float zoom, float cssPageLeft, float cssPageTop, float cssPageRight, float cssPageBottom) { synchronized (getLock()) { @@ -611,12 +613,12 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget mContentDocumentIsDisplayed = true; } - /** This function is invoked by Gecko via JNI; be careful when modifying signature. - * The compositor invokes this function whenever it determines that the page rect + /** The compositor invokes this function whenever it determines that the page rect * has changed (based on the information it gets from layout). If setFirstPaintViewport * is invoked on a frame, then this function will not be. For any given frame, this * function will be invoked before syncViewportInfo. */ + @WrapElementForJNI(allowMultithread = true) public void setPageRect(float cssPageLeft, float cssPageTop, float cssPageRight, float cssPageBottom) { synchronized (getLock()) { RectF cssPageRect = new RectF(cssPageLeft, cssPageTop, cssPageRight, cssPageBottom); @@ -629,8 +631,7 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget } } - /** This function is invoked by Gecko via JNI; be careful when modifying signature. - * The compositor invokes this function on every frame to figure out what part of the + /** The compositor invokes this function on every frame to figure out what part of the * page to display, and to inform Java of the current display port. Since it is called * on every frame, it needs to be ultra-fast. * It avoids taking any locks or allocating any objects. We keep around a @@ -638,6 +639,7 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget * everytime we're called. NOTE: we might be able to return a ImmutableViewportMetrics * which would avoid the copy into mCurrentViewTransform. */ + @WrapElementForJNI(allowMultithread = true) public ViewTransform syncViewportInfo(int x, int y, int width, int height, float resolution, boolean layersUpdated) { // getViewportMetrics is thread safe so we don't need to synchronize. // We save the viewport metrics here, so we later use it later in @@ -691,7 +693,7 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget return mCurrentViewTransform; } - /* Invoked by JNI from the compositor thread */ + @WrapElementForJNI(allowMultithread = true) public ViewTransform syncFrameMetrics(float offsetX, float offsetY, float zoom, float cssPageLeft, float cssPageTop, float cssPageRight, float cssPageBottom, boolean layersUpdated, int x, int y, int width, int height, float resolution, @@ -705,7 +707,7 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget return syncViewportInfo(x, y, width, height, resolution, layersUpdated); } - /** This function is invoked by Gecko via JNI; be careful when modifying signature. */ + @WrapElementForJNI(allowMultithread = true) public LayerRenderer.Frame createFrame() { // Create the shaders and textures if necessary. if (!mLayerRendererInitialized) { @@ -717,12 +719,12 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget return mLayerRenderer.createFrame(mFrameMetrics); } - /** This function is invoked by Gecko via JNI; be careful when modifying signature. */ + @WrapElementForJNI(allowMultithread = true) public void activateProgram() { mLayerRenderer.activateDefaultProgram(); } - /** This function is invoked by Gecko via JNI; be careful when modifying signature. */ + @WrapElementForJNI(allowMultithread = true) public void deactivateProgram() { mLayerRenderer.deactivateDefaultProgram(); } diff --git a/mobile/android/base/gfx/ImmutableViewportMetrics.java b/mobile/android/base/gfx/ImmutableViewportMetrics.java index 1b1c25a7320d..817190c6c45f 100644 --- a/mobile/android/base/gfx/ImmutableViewportMetrics.java +++ b/mobile/android/base/gfx/ImmutableViewportMetrics.java @@ -5,6 +5,7 @@ package org.mozilla.gecko.gfx; +import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; import org.mozilla.gecko.util.FloatUtils; import android.graphics.PointF; @@ -52,7 +53,8 @@ public class ImmutableViewportMetrics { /** This constructor is used by native code in AndroidJavaWrappers.cpp, be * careful when modifying the signature. */ - private ImmutableViewportMetrics(float aPageRectLeft, float aPageRectTop, + @WrapElementForJNI(allowMultithread = true) + public ImmutableViewportMetrics(float aPageRectLeft, float aPageRectTop, float aPageRectRight, float aPageRectBottom, float aCssPageRectLeft, float aCssPageRectTop, float aCssPageRectRight, float aCssPageRectBottom, float aViewportRectLeft, float aViewportRectTop, float aViewportRectRight, diff --git a/mobile/android/base/gfx/LayerRenderer.java b/mobile/android/base/gfx/LayerRenderer.java index ecaadc775878..e4070e66959d 100644 --- a/mobile/android/base/gfx/LayerRenderer.java +++ b/mobile/android/base/gfx/LayerRenderer.java @@ -19,7 +19,6 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; -import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; diff --git a/mobile/android/base/gfx/LayerView.java b/mobile/android/base/gfx/LayerView.java index 862c48f44cc8..455f50e5db28 100644 --- a/mobile/android/base/gfx/LayerView.java +++ b/mobile/android/base/gfx/LayerView.java @@ -14,7 +14,7 @@ import org.mozilla.gecko.Tab; import org.mozilla.gecko.Tabs; import org.mozilla.gecko.TouchEventInterceptor; import org.mozilla.gecko.ZoomConstraints; -import org.mozilla.gecko.mozglue.GeneratableAndroidBridgeTarget; +import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; import org.mozilla.gecko.util.EventDispatcher; import android.content.Context; @@ -562,7 +562,7 @@ public class LayerView extends FrameLayout implements Tabs.OnTabsChangedListener return mTextureView.getSurfaceTexture(); } - @GeneratableAndroidBridgeTarget(allowMultithread = true, stubName = "RegisterCompositorWrapper") + @WrapElementForJNI(allowMultithread = true, stubName = "RegisterCompositorWrapper") public static GLController registerCxxCompositor() { try { LayerView layerView = GeckoAppShell.getLayerView(); diff --git a/mobile/android/base/gfx/NativePanZoomController.java b/mobile/android/base/gfx/NativePanZoomController.java index 27fddad0f260..22da11f5fa69 100644 --- a/mobile/android/base/gfx/NativePanZoomController.java +++ b/mobile/android/base/gfx/NativePanZoomController.java @@ -7,7 +7,7 @@ package org.mozilla.gecko.gfx; import org.mozilla.gecko.GeckoEvent; import org.mozilla.gecko.GeckoThread; -import org.mozilla.gecko.mozglue.GeneratableAndroidBridgeTarget; +import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; import org.mozilla.gecko.util.EventDispatcher; import org.mozilla.gecko.util.GeckoEventListener; @@ -83,12 +83,12 @@ class NativePanZoomController implements PanZoomController, GeckoEventListener { public native void setOverScrollMode(int overscrollMode); public native int getOverScrollMode(); - @GeneratableAndroidBridgeTarget(allowMultithread = true, stubName = "RequestContentRepaintWrapper") + @WrapElementForJNI(allowMultithread = true, stubName = "RequestContentRepaintWrapper") private void requestContentRepaint(float x, float y, float width, float height, float resolution) { mTarget.forceRedraw(new DisplayPortMetrics(x, y, x + width, y + height, resolution)); } - @GeneratableAndroidBridgeTarget(allowMultithread = true, stubName = "PostDelayedCallbackWrapper") + @WrapElementForJNI(allowMultithread = true, stubName = "PostDelayedCallbackWrapper") private void postDelayedCallback(long delay) { mTarget.postDelayed(mCallbackRunnable, delay); } diff --git a/mobile/android/base/gfx/ProgressiveUpdateData.java b/mobile/android/base/gfx/ProgressiveUpdateData.java index 187dad74568d..7571658803d7 100644 --- a/mobile/android/base/gfx/ProgressiveUpdateData.java +++ b/mobile/android/base/gfx/ProgressiveUpdateData.java @@ -5,12 +5,15 @@ package org.mozilla.gecko.gfx; +import org.mozilla.gecko.mozglue.generatorannotations.WrapEntireClassForJNI; + /** * This is the data structure that's returned by the progressive tile update * callback function. It encompasses the current viewport and a boolean value * representing whether the front-end is interested in the current progressive * update continuing. */ +@WrapEntireClassForJNI public class ProgressiveUpdateData { public float x; public float y; diff --git a/mobile/android/base/gfx/ViewTransform.java b/mobile/android/base/gfx/ViewTransform.java index d9ec62528821..7243aef6dc92 100644 --- a/mobile/android/base/gfx/ViewTransform.java +++ b/mobile/android/base/gfx/ViewTransform.java @@ -5,6 +5,9 @@ package org.mozilla.gecko.gfx; +import org.mozilla.gecko.mozglue.generatorannotations.WrapEntireClassForJNI; + +@WrapEntireClassForJNI public class ViewTransform { public float x; public float y; diff --git a/mobile/android/base/moz.build b/mobile/android/base/moz.build index 8df9e4c0948d..7a219a2d0cab 100644 --- a/mobile/android/base/moz.build +++ b/mobile/android/base/moz.build @@ -14,10 +14,12 @@ mgjar = add_java_jar('gecko-mozglue') mgjar.sources += [ 'mozglue/ByteBufferInputStream.java', 'mozglue/DirectBufferAllocator.java', - 'mozglue/GeneratableAndroidBridgeTarget.java', + 'mozglue/generatorannotations/GeneratorOptions.java', + 'mozglue/generatorannotations/OptionalGeneratedParameter.java', + 'mozglue/generatorannotations/WrapElementForJNI.java', + 'mozglue/generatorannotations/WrapEntireClassForJNI.java', 'mozglue/NativeReference.java', 'mozglue/NativeZip.java', - 'mozglue/OptionalGeneratedParameter.java', ] mgjar.generated_sources += [ 'org/mozilla/gecko/mozglue/GeckoLoader.java', diff --git a/mobile/android/base/mozglue/NativeZip.java b/mobile/android/base/mozglue/NativeZip.java index a8c0ce855313..74a3a03d3044 100644 --- a/mobile/android/base/mozglue/NativeZip.java +++ b/mobile/android/base/mozglue/NativeZip.java @@ -5,6 +5,8 @@ package org.mozilla.gecko.mozglue; +import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; + import java.io.InputStream; import java.nio.ByteBuffer; import java.util.zip.Inflater; @@ -68,6 +70,7 @@ public class NativeZip implements NativeReference { private static native void _release(long obj); private native InputStream _getInputStream(long obj, String path); + @WrapElementForJNI private InputStream createInputStream(ByteBuffer buffer, int compression) { if (compression != STORE && compression != DEFLATE) { throw new IllegalArgumentException("Unexpected compression: " + compression); diff --git a/mobile/android/base/mozglue/generatorannotations/GeneratorOptions.java b/mobile/android/base/mozglue/generatorannotations/GeneratorOptions.java new file mode 100644 index 000000000000..c9d4f9c5b820 --- /dev/null +++ b/mobile/android/base/mozglue/generatorannotations/GeneratorOptions.java @@ -0,0 +1,14 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.gecko.mozglue.generatorannotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface GeneratorOptions { + // Specifies a custom name for the generated C++ class. If left empty, is AndroidJavaClassName. + String generatedClassName() default ""; +} \ No newline at end of file diff --git a/mobile/android/base/mozglue/OptionalGeneratedParameter.java b/mobile/android/base/mozglue/generatorannotations/OptionalGeneratedParameter.java similarity index 93% rename from mobile/android/base/mozglue/OptionalGeneratedParameter.java rename to mobile/android/base/mozglue/generatorannotations/OptionalGeneratedParameter.java index 8e32b7df0796..6c649ee37384 100644 --- a/mobile/android/base/mozglue/OptionalGeneratedParameter.java +++ b/mobile/android/base/mozglue/generatorannotations/OptionalGeneratedParameter.java @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.mozilla.gecko.mozglue; +package org.mozilla.gecko.mozglue.generatorannotations; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/mobile/android/base/mozglue/GeneratableAndroidBridgeTarget.java b/mobile/android/base/mozglue/generatorannotations/WrapElementForJNI.java similarity index 95% rename from mobile/android/base/mozglue/GeneratableAndroidBridgeTarget.java rename to mobile/android/base/mozglue/generatorannotations/WrapElementForJNI.java index b1ff16a8461f..626e730b9164 100644 --- a/mobile/android/base/mozglue/GeneratableAndroidBridgeTarget.java +++ b/mobile/android/base/mozglue/generatorannotations/WrapElementForJNI.java @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.mozilla.gecko.mozglue; +package org.mozilla.gecko.mozglue.generatorannotations; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -21,7 +21,7 @@ import java.lang.annotation.RetentionPolicy; * and may lead to subtle bugs. */ @Retention(RetentionPolicy.RUNTIME) -public @interface GeneratableAndroidBridgeTarget { +public @interface WrapElementForJNI { // Optional parameter specifying the name of the generated method stub. If omitted, the name // of the Java method will be used. String stubName() default ""; diff --git a/mobile/android/base/mozglue/generatorannotations/WrapEntireClassForJNI.java b/mobile/android/base/mozglue/generatorannotations/WrapEntireClassForJNI.java new file mode 100644 index 000000000000..2b5d733a21fc --- /dev/null +++ b/mobile/android/base/mozglue/generatorannotations/WrapEntireClassForJNI.java @@ -0,0 +1,15 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.gecko.mozglue.generatorannotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Handy shortcut annotation. Functionally equivalent to tagging every member individually with default + * settings. + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface WrapEntireClassForJNI {} diff --git a/mobile/android/base/sqlite/MatrixBlobCursor.java b/mobile/android/base/sqlite/MatrixBlobCursor.java index 1c6618054a3d..daddade82503 100644 --- a/mobile/android/base/sqlite/MatrixBlobCursor.java +++ b/mobile/android/base/sqlite/MatrixBlobCursor.java @@ -17,6 +17,8 @@ package org.mozilla.gecko.sqlite; +import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; + import android.database.AbstractCursor; import android.database.CursorIndexOutOfBoundsException; @@ -50,6 +52,7 @@ public class MatrixBlobCursor extends AbstractCursor { * determines column ordering elsewhere in this cursor * @param initialCapacity in rows */ + @WrapElementForJNI public MatrixBlobCursor(String[] columnNames, int initialCapacity) { this.columnNames = columnNames; this.columnCount = columnNames.length; @@ -67,6 +70,7 @@ public class MatrixBlobCursor extends AbstractCursor { * @param columnNames names of the columns, the ordering of which * determines column ordering elsewhere in this cursor */ + @WrapElementForJNI public MatrixBlobCursor(String[] columnNames) { this(columnNames, 16); } @@ -112,6 +116,7 @@ public class MatrixBlobCursor extends AbstractCursor { * @param columnValues in the same order as the the column names specified * at cursor construction time */ + @WrapElementForJNI public void addRow(Object[] columnValues) { if (columnValues.length != columnCount) { throw new IllegalArgumentException("columnNames.length = " @@ -133,6 +138,7 @@ public class MatrixBlobCursor extends AbstractCursor { * @param columnValues in the same order as the the column names specified * at cursor construction time */ + @WrapElementForJNI public void addRow(Iterable columnValues) { int start = rowCount * columnCount; int end = start + columnCount; @@ -165,6 +171,7 @@ public class MatrixBlobCursor extends AbstractCursor { } /** Optimization for {@link ArrayList}. */ + @WrapElementForJNI private void addRow(ArrayList columnValues, int start) { int size = columnValues.size(); if (size != columnCount) { diff --git a/mobile/android/base/sqlite/SQLiteBridgeException.java b/mobile/android/base/sqlite/SQLiteBridgeException.java index c4e558055480..e7deca1da5cf 100644 --- a/mobile/android/base/sqlite/SQLiteBridgeException.java +++ b/mobile/android/base/sqlite/SQLiteBridgeException.java @@ -5,6 +5,9 @@ package org.mozilla.gecko.sqlite; +import org.mozilla.gecko.mozglue.generatorannotations.WrapEntireClassForJNI; + +@WrapEntireClassForJNI public class SQLiteBridgeException extends RuntimeException { static final long serialVersionUID = 1L; diff --git a/mobile/android/base/util/Clipboard.java b/mobile/android/base/util/Clipboard.java index ef4b4155643e..4ea6db056974 100644 --- a/mobile/android/base/util/Clipboard.java +++ b/mobile/android/base/util/Clipboard.java @@ -9,7 +9,7 @@ import android.content.Context; import android.os.Build; import android.util.Log; -import org.mozilla.gecko.mozglue.GeneratableAndroidBridgeTarget; +import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; import java.util.concurrent.SynchronousQueue; @@ -29,7 +29,7 @@ public final class Clipboard { mContext = c; } - @GeneratableAndroidBridgeTarget(stubName = "GetClipboardTextWrapper") + @WrapElementForJNI(stubName = "GetClipboardTextWrapper") public static String getText() { // If we're on the UI thread or the background thread, we have a looper on the thread // and can just call this directly. For any other threads, post the call to the @@ -55,7 +55,7 @@ public final class Clipboard { } } - @GeneratableAndroidBridgeTarget(stubName = "SetClipboardText") + @WrapElementForJNI(stubName = "SetClipboardText") public static void setText(final CharSequence text) { ThreadUtils.postToBackgroundThread(new Runnable() { @Override @@ -79,6 +79,25 @@ public final class Clipboard { }); } + /** + * Returns true if the clipboard is nonempty, false otherwise. + * + * @return true if the clipboard is nonempty, false otherwise. + */ + @WrapElementForJNI + public static boolean hasText() { + String text = getText(); + return text != null; + } + + /** + * Deletes all text from the clipboard. + */ + @WrapElementForJNI + public static void clearText() { + setText(null); + } + private static android.content.ClipboardManager getClipboardManager11(Context context) { // In API Level 11 and above, CLIPBOARD_SERVICE returns android.content.ClipboardManager, // which is a subclass of android.text.ClipboardManager. diff --git a/mobile/android/components/build/nsAndroidHistory.cpp b/mobile/android/components/build/nsAndroidHistory.cpp index fc5da6140887..d5909c5f6c12 100644 --- a/mobile/android/components/build/nsAndroidHistory.cpp +++ b/mobile/android/components/build/nsAndroidHistory.cpp @@ -50,10 +50,7 @@ nsAndroidHistory::RegisterVisitedCallback(nsIURI *aURI, Link *aContent) } list->AppendElement(aContent); - AndroidBridge *bridge = AndroidBridge::Bridge(); - if (bridge) { - bridge->CheckURIVisited(uriString); - } + GeckoAppShell::CheckURIVisited(uriString); return NS_OK; } @@ -96,27 +93,23 @@ nsAndroidHistory::VisitURI(nsIURI *aURI, nsIURI *aLastVisitedURI, uint32_t aFlag if (aFlags & VisitFlags::UNRECOVERABLE_ERROR) return NS_OK; - AndroidBridge *bridge = AndroidBridge::Bridge(); - if (bridge) { - nsAutoCString uri; - nsresult rv = aURI->GetSpec(uri); - if (NS_FAILED(rv)) return rv; - NS_ConvertUTF8toUTF16 uriString(uri); - bridge->MarkURIVisited(uriString); - } + nsAutoCString uri; + nsresult rv = aURI->GetSpec(uri); + if (NS_FAILED(rv)) return rv; + NS_ConvertUTF8toUTF16 uriString(uri); + GeckoAppShell::MarkURIVisited(uriString); return NS_OK; } NS_IMETHODIMP nsAndroidHistory::SetURITitle(nsIURI *aURI, const nsAString& aTitle) { - AndroidBridge *bridge = AndroidBridge::Bridge(); - if (bridge) { + if (AndroidBridge::Bridge()) { nsAutoCString uri; nsresult rv = aURI->GetSpec(uri); if (NS_FAILED(rv)) return rv; NS_ConvertUTF8toUTF16 uriString(uri); - bridge->SetURITitle(uriString, aTitle); + GeckoAppShell::SetURITitle(uriString, aTitle); } return NS_OK; } diff --git a/mobile/android/components/build/nsShellService.cpp b/mobile/android/components/build/nsShellService.cpp index 306bf81d9ac7..0c9d915c8174 100644 --- a/mobile/android/components/build/nsShellService.cpp +++ b/mobile/android/components/build/nsShellService.cpp @@ -8,6 +8,8 @@ #include "AndroidBridge.h" +using namespace mozilla::widget::android; + NS_IMPL_ISUPPORTS1(nsShellService, nsIShellService) NS_IMETHODIMP @@ -22,6 +24,6 @@ nsShellService::CreateShortcut(const nsAString& aTitle, const nsAString& aURI, c if (!aTitle.Length() || !aURI.Length() || !aIconData.Length()) return NS_ERROR_FAILURE; - mozilla::AndroidBridge::Bridge()->CreateShortcut(aTitle, aURI, aIconData, aIntent); + GeckoAppShell::CreateShortcut(aTitle, aURI, aIconData, aIntent); return NS_OK; } diff --git a/netwerk/base/src/Tickler.cpp b/netwerk/base/src/Tickler.cpp index 1a86262c2c15..1d78c6ecfcba 100644 --- a/netwerk/base/src/Tickler.cpp +++ b/netwerk/base/src/Tickler.cpp @@ -80,7 +80,7 @@ Tickler::Init() MOZ_ASSERT(!mThread); MOZ_ASSERT(!mFD); - AndroidBridge::Bridge()->EnableNetworkNotifications(); + GeckoAppShell::EnableNetworkNotifications(); mFD = PR_OpenUDPSocket(PR_AF_INET); if (!mFD) diff --git a/netwerk/protocol/device/CameraStreamImpl.cpp b/netwerk/protocol/device/CameraStreamImpl.cpp index 7c38d4a2d1cf..2d51be4f182f 100644 --- a/netwerk/protocol/device/CameraStreamImpl.cpp +++ b/netwerk/protocol/device/CameraStreamImpl.cpp @@ -90,7 +90,7 @@ bool CameraStreamImpl::Init(const nsCString& contentType, const uint32_t& camera } void CameraStreamImpl::Close() { - AndroidBridge::Bridge()->CloseCamera(); + GeckoAppShell::CloseCamera(); mCallback = nullptr; } diff --git a/netwerk/system/android/nsAndroidNetworkLinkService.cpp b/netwerk/system/android/nsAndroidNetworkLinkService.cpp index 01ed147847c0..2365d081094b 100644 --- a/netwerk/system/android/nsAndroidNetworkLinkService.cpp +++ b/netwerk/system/android/nsAndroidNetworkLinkService.cpp @@ -10,6 +10,8 @@ #include "AndroidBridge.h" +using namespace mozilla::widget::android; + NS_IMPL_ISUPPORTS1(nsAndroidNetworkLinkService, nsINetworkLinkService) @@ -31,7 +33,7 @@ nsAndroidNetworkLinkService::GetIsLinkUp(bool *aIsUp) return NS_OK; } - *aIsUp = mozilla::AndroidBridge::Bridge()->IsNetworkLinkUp(); + *aIsUp = GeckoAppShell::IsNetworkLinkUp(); return NS_OK; } @@ -40,7 +42,7 @@ nsAndroidNetworkLinkService::GetLinkStatusKnown(bool *aIsKnown) { NS_ENSURE_TRUE(mozilla::AndroidBridge::Bridge(), NS_ERROR_NOT_IMPLEMENTED); - *aIsKnown = mozilla::AndroidBridge::Bridge()->IsNetworkLinkKnown(); + *aIsKnown = GeckoAppShell::IsNetworkLinkKnown(); return NS_OK; } @@ -56,6 +58,6 @@ nsAndroidNetworkLinkService::GetLinkType(uint32_t *aLinkType) return NS_OK; } - *aLinkType = mozilla::AndroidBridge::Bridge()->NetworkLinkType(); + *aLinkType = GeckoAppShell::NetworkLinkType(); return NS_OK; } diff --git a/python/mozbuild/mozbuild/backend/recursivemake.py b/python/mozbuild/mozbuild/backend/recursivemake.py index 3ed3746ef748..a1a6630090e6 100644 --- a/python/mozbuild/mozbuild/backend/recursivemake.py +++ b/python/mozbuild/mozbuild/backend/recursivemake.py @@ -353,18 +353,24 @@ class RecursiveMakeBackend(CommonBackend): UNIFIED_CMMSRCS='mm', UNIFIED_CPPSRCS='cpp', ) + do_unify = not self.environment.substs.get( + 'MOZ_DISABLE_UNIFIED_COMPILATION') # Sorted so output is consistent and we don't bump mtimes. for k, v in sorted(obj.variables.items()): - if k in unified_suffixes.keys(): - self._add_unified_build_rules(backend_file, v, - backend_file.objdir, - unified_prefix='Unified_%s_%s' % - (unified_suffixes[k], - backend_file.relobjdir.replace('/', '_')), - unified_suffix=unified_suffixes[k], - unified_files_makefile_variable=k, - include_curdir_build_rules=False) - backend_file.write('%s += $(%s)\n' % (k[len('UNIFIED_'):], k)) + if k in unified_suffixes: + if do_unify: + self._add_unified_build_rules(backend_file, v, + backend_file.objdir, + unified_prefix='Unified_%s_%s' % ( + unified_suffixes[k], + backend_file.relobjdir.replace('/', '_')), + unified_suffix=unified_suffixes[k], + unified_files_makefile_variable=k, + include_curdir_build_rules=False) + backend_file.write('%s += $(%s)\n' % (k[len('UNIFIED_'):], k)) + else: + backend_file.write('%s += %s\n' % ( + k[len('UNIFIED_'):], ' '.join(sorted(v)))) elif isinstance(v, list): for item in v: backend_file.write('%s += %s\n' % (k, item)) diff --git a/python/mozbuild/mozbuild/preprocessor.py b/python/mozbuild/mozbuild/preprocessor.py index 4d79cf0d73d3..02691690116a 100644 --- a/python/mozbuild/mozbuild/preprocessor.py +++ b/python/mozbuild/mozbuild/preprocessor.py @@ -1,3 +1,6 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. """ This is a very primitive line based preprocessor, for times when using a C preprocessor isn't an option. @@ -19,10 +22,6 @@ value : | \w+ # string identifier or value; """ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - import sys import os import os.path @@ -33,9 +32,9 @@ import errno # hack around win32 mangling our line endings # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65443 if sys.platform == "win32": - import msvcrt - msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) - os.linesep = '\n' + import msvcrt + msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) + os.linesep = '\n' __all__ = [ @@ -47,711 +46,711 @@ __all__ = [ class Expression: - def __init__(self, expression_string): - """ - Create a new expression with this string. - The expression will already be parsed into an Abstract Syntax Tree. - """ - self.content = expression_string - self.offset = 0 - self.__ignore_whitespace() - self.e = self.__get_logical_or() - if self.content: - raise Expression.ParseError, self + def __init__(self, expression_string): + """ + Create a new expression with this string. + The expression will already be parsed into an Abstract Syntax Tree. + """ + self.content = expression_string + self.offset = 0 + self.__ignore_whitespace() + self.e = self.__get_logical_or() + if self.content: + raise Expression.ParseError, self - def __get_logical_or(self): - """ - Production: and_cond ( '||' expression ) ? - """ - if not len(self.content): - return None - rv = Expression.__AST("logical_op") - # test - rv.append(self.__get_logical_and()) - self.__ignore_whitespace() - if self.content[:2] != '||': - # no logical op needed, short cut to our prime element - return rv[0] - # append operator - rv.append(Expression.__ASTLeaf('op', self.content[:2])) - self.__strip(2) - self.__ignore_whitespace() - rv.append(self.__get_logical_or()) - self.__ignore_whitespace() - return rv + def __get_logical_or(self): + """ + Production: and_cond ( '||' expression ) ? + """ + if not len(self.content): + return None + rv = Expression.__AST("logical_op") + # test + rv.append(self.__get_logical_and()) + self.__ignore_whitespace() + if self.content[:2] != '||': + # no logical op needed, short cut to our prime element + return rv[0] + # append operator + rv.append(Expression.__ASTLeaf('op', self.content[:2])) + self.__strip(2) + self.__ignore_whitespace() + rv.append(self.__get_logical_or()) + self.__ignore_whitespace() + return rv - def __get_logical_and(self): - """ - Production: test ( '&&' and_cond ) ? - """ - if not len(self.content): - return None - rv = Expression.__AST("logical_op") - # test - rv.append(self.__get_equality()) - self.__ignore_whitespace() - if self.content[:2] != '&&': - # no logical op needed, short cut to our prime element - return rv[0] - # append operator - rv.append(Expression.__ASTLeaf('op', self.content[:2])) - self.__strip(2) - self.__ignore_whitespace() - rv.append(self.__get_logical_and()) - self.__ignore_whitespace() - return rv + def __get_logical_and(self): + """ + Production: test ( '&&' and_cond ) ? + """ + if not len(self.content): + return None + rv = Expression.__AST("logical_op") + # test + rv.append(self.__get_equality()) + self.__ignore_whitespace() + if self.content[:2] != '&&': + # no logical op needed, short cut to our prime element + return rv[0] + # append operator + rv.append(Expression.__ASTLeaf('op', self.content[:2])) + self.__strip(2) + self.__ignore_whitespace() + rv.append(self.__get_logical_and()) + self.__ignore_whitespace() + return rv - def __get_equality(self): - """ - Production: unary ( ( '==' | '!=' ) unary ) ? - """ - if not len(self.content): - return None - rv = Expression.__AST("equality") - # unary - rv.append(self.__get_unary()) - self.__ignore_whitespace() - if not re.match('[=!]=', self.content): - # no equality needed, short cut to our prime unary - return rv[0] - # append operator - rv.append(Expression.__ASTLeaf('op', self.content[:2])) - self.__strip(2) - self.__ignore_whitespace() - rv.append(self.__get_unary()) - self.__ignore_whitespace() - return rv + def __get_equality(self): + """ + Production: unary ( ( '==' | '!=' ) unary ) ? + """ + if not len(self.content): + return None + rv = Expression.__AST("equality") + # unary + rv.append(self.__get_unary()) + self.__ignore_whitespace() + if not re.match('[=!]=', self.content): + # no equality needed, short cut to our prime unary + return rv[0] + # append operator + rv.append(Expression.__ASTLeaf('op', self.content[:2])) + self.__strip(2) + self.__ignore_whitespace() + rv.append(self.__get_unary()) + self.__ignore_whitespace() + return rv - def __get_unary(self): - """ - Production: '!'? value - """ - # eat whitespace right away, too - not_ws = re.match('!\s*', self.content) - if not not_ws: - return self.__get_value() - rv = Expression.__AST('not') - self.__strip(not_ws.end()) - rv.append(self.__get_value()) - self.__ignore_whitespace() - return rv + def __get_unary(self): + """ + Production: '!'? value + """ + # eat whitespace right away, too + not_ws = re.match('!\s*', self.content) + if not not_ws: + return self.__get_value() + rv = Expression.__AST('not') + self.__strip(not_ws.end()) + rv.append(self.__get_value()) + self.__ignore_whitespace() + return rv - def __get_value(self): - """ - Production: ( [0-9]+ | 'defined(' \w+ ')' | \w+ ) - Note that the order is important, and the expression is kind-of - ambiguous as \w includes 0-9. One could make it unambiguous by - removing 0-9 from the first char of a string literal. - """ - rv = None - m = re.match('defined\s*\(\s*(\w+)\s*\)', self.content) - if m: - word_len = m.end() - rv = Expression.__ASTLeaf('defined', m.group(1)) - else: - word_len = re.match('[0-9]*', self.content).end() - if word_len: - value = int(self.content[:word_len]) - rv = Expression.__ASTLeaf('int', value) - else: - word_len = re.match('\w*', self.content).end() - if word_len: - rv = Expression.__ASTLeaf('string', self.content[:word_len]) + def __get_value(self): + """ + Production: ( [0-9]+ | 'defined(' \w+ ')' | \w+ ) + Note that the order is important, and the expression is kind-of + ambiguous as \w includes 0-9. One could make it unambiguous by + removing 0-9 from the first char of a string literal. + """ + rv = None + m = re.match('defined\s*\(\s*(\w+)\s*\)', self.content) + if m: + word_len = m.end() + rv = Expression.__ASTLeaf('defined', m.group(1)) else: - raise Expression.ParseError, self - self.__strip(word_len) - self.__ignore_whitespace() - return rv + word_len = re.match('[0-9]*', self.content).end() + if word_len: + value = int(self.content[:word_len]) + rv = Expression.__ASTLeaf('int', value) + else: + word_len = re.match('\w*', self.content).end() + if word_len: + rv = Expression.__ASTLeaf('string', self.content[:word_len]) + else: + raise Expression.ParseError, self + self.__strip(word_len) + self.__ignore_whitespace() + return rv - def __ignore_whitespace(self): - ws_len = re.match('\s*', self.content).end() - self.__strip(ws_len) - return + def __ignore_whitespace(self): + ws_len = re.match('\s*', self.content).end() + self.__strip(ws_len) + return - def __strip(self, length): - """ - Remove a given amount of chars from the input and update - the offset. - """ - self.content = self.content[length:] - self.offset += length + def __strip(self, length): + """ + Remove a given amount of chars from the input and update + the offset. + """ + self.content = self.content[length:] + self.offset += length - def evaluate(self, context): - """ - Evaluate the expression with the given context - """ + def evaluate(self, context): + """ + Evaluate the expression with the given context + """ - # Helper function to evaluate __get_equality results - def eval_equality(tok): - left = opmap[tok[0].type](tok[0]) - right = opmap[tok[2].type](tok[2]) - rv = left == right - if tok[1].value == '!=': - rv = not rv - return rv - # Helper function to evaluate __get_logical_and and __get_logical_or results - def eval_logical_op(tok): - left = opmap[tok[0].type](tok[0]) - right = opmap[tok[2].type](tok[2]) - if tok[1].value == '&&': - return left and right - elif tok[1].value == '||': - return left or right - raise Expression.ParseError, self + # Helper function to evaluate __get_equality results + def eval_equality(tok): + left = opmap[tok[0].type](tok[0]) + right = opmap[tok[2].type](tok[2]) + rv = left == right + if tok[1].value == '!=': + rv = not rv + return rv + # Helper function to evaluate __get_logical_and and __get_logical_or results + def eval_logical_op(tok): + left = opmap[tok[0].type](tok[0]) + right = opmap[tok[2].type](tok[2]) + if tok[1].value == '&&': + return left and right + elif tok[1].value == '||': + return left or right + raise Expression.ParseError, self - # Mapping from token types to evaluator functions - # Apart from (non-)equality, all these can be simple lambda forms. - opmap = { - 'logical_op': eval_logical_op, - 'equality': eval_equality, - 'not': lambda tok: not opmap[tok[0].type](tok[0]), - 'string': lambda tok: context[tok.value], - 'defined': lambda tok: tok.value in context, - 'int': lambda tok: tok.value} + # Mapping from token types to evaluator functions + # Apart from (non-)equality, all these can be simple lambda forms. + opmap = { + 'logical_op': eval_logical_op, + 'equality': eval_equality, + 'not': lambda tok: not opmap[tok[0].type](tok[0]), + 'string': lambda tok: context[tok.value], + 'defined': lambda tok: tok.value in context, + 'int': lambda tok: tok.value} - return opmap[self.e.type](self.e); + return opmap[self.e.type](self.e); - class __AST(list): - """ - Internal class implementing Abstract Syntax Tree nodes - """ - def __init__(self, type): - self.type = type - super(self.__class__, self).__init__(self) + class __AST(list): + """ + Internal class implementing Abstract Syntax Tree nodes + """ + def __init__(self, type): + self.type = type + super(self.__class__, self).__init__(self) - class __ASTLeaf: - """ - Internal class implementing Abstract Syntax Tree leafs - """ - def __init__(self, type, value): - self.value = value - self.type = type - def __str__(self): - return self.value.__str__() - def __repr__(self): - return self.value.__repr__() + class __ASTLeaf: + """ + Internal class implementing Abstract Syntax Tree leafs + """ + def __init__(self, type, value): + self.value = value + self.type = type + def __str__(self): + return self.value.__str__() + def __repr__(self): + return self.value.__repr__() - class ParseError(StandardError): - """ - Error raised when parsing fails. - It has two members, offset and content, which give the offset of the - error and the offending content. - """ - def __init__(self, expression): - self.offset = expression.offset - self.content = expression.content[:3] - def __str__(self): - return 'Unexpected content at offset {0}, "{1}"'.format(self.offset, - self.content) + class ParseError(StandardError): + """ + Error raised when parsing fails. + It has two members, offset and content, which give the offset of the + error and the offending content. + """ + def __init__(self, expression): + self.offset = expression.offset + self.content = expression.content[:3] + def __str__(self): + return 'Unexpected content at offset {0}, "{1}"'.format(self.offset, + self.content) class Context(dict): - """ - This class holds variable values by subclassing dict, and while it - truthfully reports True and False on + """ + This class holds variable values by subclassing dict, and while it + truthfully reports True and False on - name in context + name in context - it returns the variable name itself on + it returns the variable name itself on - context["name"] + context["name"] - to reflect the ambiguity between string literals and preprocessor - variables. - """ - def __getitem__(self, key): - if key in self: - return super(self.__class__, self).__getitem__(key) - return key + to reflect the ambiguity between string literals and preprocessor + variables. + """ + def __getitem__(self, key): + if key in self: + return super(self.__class__, self).__getitem__(key) + return key class Preprocessor: - """ - Class for preprocessing text files. - """ - class Error(RuntimeError): - def __init__(self, cpp, MSG, context): - self.file = cpp.context['FILE'] - self.line = cpp.context['LINE'] - self.key = MSG - RuntimeError.__init__(self, (self.file, self.line, self.key, context)) - def __init__(self): - self.context = Context() - for k,v in {'FILE': '', - 'LINE': 0, - 'DIRECTORY': os.path.abspath('.')}.iteritems(): - self.context[k] = v - self.actionLevel = 0 - self.disableLevel = 0 - # ifStates can be - # 0: hadTrue - # 1: wantsTrue - # 2: #else found - self.ifStates = [] - self.checkLineNumbers = False - self.writtenLines = 0 - self.filters = [] - self.cmds = {} - for cmd, level in {'define': 0, - 'undef': 0, - 'if': sys.maxint, - 'ifdef': sys.maxint, - 'ifndef': sys.maxint, - 'else': 1, - 'elif': 1, - 'elifdef': 1, - 'elifndef': 1, - 'endif': sys.maxint, - 'expand': 0, - 'literal': 0, - 'filter': 0, - 'unfilter': 0, - 'include': 0, - 'includesubst': 0, - 'error': 0}.iteritems(): - self.cmds[cmd] = (level, getattr(self, 'do_' + cmd)) - self.out = sys.stdout - self.setMarker('#') - self.LE = '\n' - self.varsubst = re.compile('@(?P\w+)@', re.U) - self.depfile = None - self.includes = set() + """ + Class for preprocessing text files. + """ + class Error(RuntimeError): + def __init__(self, cpp, MSG, context): + self.file = cpp.context['FILE'] + self.line = cpp.context['LINE'] + self.key = MSG + RuntimeError.__init__(self, (self.file, self.line, self.key, context)) + def __init__(self): + self.context = Context() + for k,v in {'FILE': '', + 'LINE': 0, + 'DIRECTORY': os.path.abspath('.')}.iteritems(): + self.context[k] = v + self.actionLevel = 0 + self.disableLevel = 0 + # ifStates can be + # 0: hadTrue + # 1: wantsTrue + # 2: #else found + self.ifStates = [] + self.checkLineNumbers = False + self.writtenLines = 0 + self.filters = [] + self.cmds = {} + for cmd, level in {'define': 0, + 'undef': 0, + 'if': sys.maxint, + 'ifdef': sys.maxint, + 'ifndef': sys.maxint, + 'else': 1, + 'elif': 1, + 'elifdef': 1, + 'elifndef': 1, + 'endif': sys.maxint, + 'expand': 0, + 'literal': 0, + 'filter': 0, + 'unfilter': 0, + 'include': 0, + 'includesubst': 0, + 'error': 0}.iteritems(): + self.cmds[cmd] = (level, getattr(self, 'do_' + cmd)) + self.out = sys.stdout + self.setMarker('#') + self.LE = '\n' + self.varsubst = re.compile('@(?P\w+)@', re.U) + self.depfile = None + self.includes = set() - def warnUnused(self, file): - if self.actionLevel == 0: - sys.stderr.write('{0}: WARNING: no preprocessor directives found\n'.format(file)) - elif self.actionLevel == 1: - sys.stderr.write('{0}: WARNING: no useful preprocessor directives found\n'.format(file)) - pass + def warnUnused(self, file): + if self.actionLevel == 0: + sys.stderr.write('{0}: WARNING: no preprocessor directives found\n'.format(file)) + elif self.actionLevel == 1: + sys.stderr.write('{0}: WARNING: no useful preprocessor directives found\n'.format(file)) + pass - def setLineEndings(self, aLE): - """ - Set the line endings to be used for output. - """ - self.LE = {'cr': '\x0D', 'lf': '\x0A', 'crlf': '\x0D\x0A'}[aLE] + def setLineEndings(self, aLE): + """ + Set the line endings to be used for output. + """ + self.LE = {'cr': '\x0D', 'lf': '\x0A', 'crlf': '\x0D\x0A'}[aLE] - def setMarker(self, aMarker): - """ - Set the marker to be used for processing directives. - Used for handling CSS files, with pp.setMarker('%'), for example. - The given marker may be None, in which case no markers are processed. - """ - self.marker = aMarker - if aMarker: - self.instruction = re.compile('{0}(?P[a-z]+)(?:\s(?P.*))?$' - .format(aMarker), - re.U) - self.comment = re.compile(aMarker, re.U) - else: - class NoMatch(object): - def match(self, *args): - return False - self.instruction = self.comment = NoMatch() + def setMarker(self, aMarker): + """ + Set the marker to be used for processing directives. + Used for handling CSS files, with pp.setMarker('%'), for example. + The given marker may be None, in which case no markers are processed. + """ + self.marker = aMarker + if aMarker: + self.instruction = re.compile('{0}(?P[a-z]+)(?:\s(?P.*))?$' + .format(aMarker), + re.U) + self.comment = re.compile(aMarker, re.U) + else: + class NoMatch(object): + def match(self, *args): + return False + self.instruction = self.comment = NoMatch() - def clone(self): - """ - Create a clone of the current processor, including line ending - settings, marker, variable definitions, output stream. - """ - rv = Preprocessor() - rv.context.update(self.context) - rv.setMarker(self.marker) - rv.LE = self.LE - rv.out = self.out - return rv + def clone(self): + """ + Create a clone of the current processor, including line ending + settings, marker, variable definitions, output stream. + """ + rv = Preprocessor() + rv.context.update(self.context) + rv.setMarker(self.marker) + rv.LE = self.LE + rv.out = self.out + return rv - def applyFilters(self, aLine): - for f in self.filters: - aLine = f[1](aLine) - return aLine + def applyFilters(self, aLine): + for f in self.filters: + aLine = f[1](aLine) + return aLine - def write(self, aLine): - """ - Internal method for handling output. - """ - if self.checkLineNumbers: - self.writtenLines += 1 - ln = self.context['LINE'] - if self.writtenLines != ln: - self.out.write('//@line {line} "{file}"{le}'.format(line=ln, - file=self.context['FILE'], - le=self.LE)) - self.writtenLines = ln - filteredLine = self.applyFilters(aLine) - if filteredLine != aLine: - self.actionLevel = 2 - # ensure our line ending. Only need to handle \n, as we're reading - # with universal line ending support, at least for files. - filteredLine = re.sub('\n', self.LE, filteredLine) - self.out.write(filteredLine) + def write(self, aLine): + """ + Internal method for handling output. + """ + if self.checkLineNumbers: + self.writtenLines += 1 + ln = self.context['LINE'] + if self.writtenLines != ln: + self.out.write('//@line {line} "{file}"{le}'.format(line=ln, + file=self.context['FILE'], + le=self.LE)) + self.writtenLines = ln + filteredLine = self.applyFilters(aLine) + if filteredLine != aLine: + self.actionLevel = 2 + # ensure our line ending. Only need to handle \n, as we're reading + # with universal line ending support, at least for files. + filteredLine = re.sub('\n', self.LE, filteredLine) + self.out.write(filteredLine) - def handleCommandLine(self, args, defaultToStdin = False): - """ - Parse a commandline into this parser. - Uses OptionParser internally, no args mean sys.argv[1:]. - """ - def get_output_file(path): - dir = os.path.dirname(path) - if dir and not os.path.exists(dir): + def handleCommandLine(self, args, defaultToStdin = False): + """ + Parse a commandline into this parser. + Uses OptionParser internally, no args mean sys.argv[1:]. + """ + def get_output_file(path): + dir = os.path.dirname(path) + if dir and not os.path.exists(dir): + try: + os.makedirs(dir) + except OSError as error: + if error.errno != errno.EEXIST: + raise + return open(path, 'wb') + + p = self.getCommandLineParser() + options, args = p.parse_args(args=args) + includes = options.I + if options.output: + self.out = get_output_file(options.output) + if defaultToStdin and len(args) == 0: + args = [sys.stdin] + if options.depend: + raise Preprocessor.Error(self, "--depend doesn't work with stdin", + None) + if options.depend: + if not options.output: + raise Preprocessor.Error(self, "--depend doesn't work with stdout", + None) + try: + from makeutil import Makefile + except: + raise Preprocessor.Error(self, "--depend requires the " + "mozbuild.makeutil module", None) + self.depfile = get_output_file(options.depend) + includes.extend(args) + if includes: + for f in includes: + self.do_include(f, False) + self.warnUnused(f) + if self.depfile: + mk = Makefile() + mk.create_rule([options.output]).add_dependencies(self.includes) + mk.dump(self.depfile) + self.depfile.close() + if options.output: + self.out.close() + + def getCommandLineParser(self, unescapeDefines = False): + escapedValue = re.compile('".*"$') + numberValue = re.compile('\d+$') + def handleE(option, opt, value, parser): + for k,v in os.environ.iteritems(): + self.context[k] = v + def handleD(option, opt, value, parser): + vals = value.split('=', 1) + if len(vals) == 1: + vals.append(1) + elif unescapeDefines and escapedValue.match(vals[1]): + # strip escaped string values + vals[1] = vals[1][1:-1] + elif numberValue.match(vals[1]): + vals[1] = int(vals[1]) + self.context[vals[0]] = vals[1] + def handleU(option, opt, value, parser): + del self.context[value] + def handleF(option, opt, value, parser): + self.do_filter(value) + def handleLE(option, opt, value, parser): + self.setLineEndings(value) + def handleMarker(option, opt, value, parser): + self.setMarker(value) + p = OptionParser() + p.add_option('-I', action='append', type="string", default = [], + metavar="FILENAME", help='Include file') + p.add_option('-E', action='callback', callback=handleE, + help='Import the environment into the defined variables') + p.add_option('-D', action='callback', callback=handleD, type="string", + metavar="VAR[=VAL]", help='Define a variable') + p.add_option('-U', action='callback', callback=handleU, type="string", + metavar="VAR", help='Undefine a variable') + p.add_option('-F', action='callback', callback=handleF, type="string", + metavar="FILTER", help='Enable the specified filter') + p.add_option('-o', '--output', type="string", default=None, + metavar="FILENAME", help='Output to the specified file '+ + 'instead of stdout') + p.add_option('--depend', type="string", default=None, metavar="FILENAME", + help='Generate dependencies in the given file') + p.add_option('--line-endings', action='callback', callback=handleLE, + type="string", metavar="[cr|lr|crlf]", + help='Use the specified line endings [Default: OS dependent]') + p.add_option('--marker', action='callback', callback=handleMarker, + type="string", + help='Use the specified marker instead of #') + return p + + def handleLine(self, aLine): + """ + Handle a single line of input (internal). + """ + if self.actionLevel == 0 and self.comment.match(aLine): + self.actionLevel = 1 + m = self.instruction.match(aLine) + if m: + args = None + cmd = m.group('cmd') + try: + args = m.group('args') + except IndexError: + pass + if cmd not in self.cmds: + raise Preprocessor.Error(self, 'INVALID_CMD', aLine) + level, cmd = self.cmds[cmd] + if (level >= self.disableLevel): + cmd(args) + if cmd != 'literal': + self.actionLevel = 2 + elif self.disableLevel == 0 and not self.comment.match(aLine): + self.write(aLine) + pass + + # Instruction handlers + # These are named do_'instruction name' and take one argument + + # Variables + def do_define(self, args): + m = re.match('(?P\w+)(?:\s(?P.*))?', args, re.U) + if not m: + raise Preprocessor.Error(self, 'SYNTAX_DEF', args) + val = 1 + if m.group('value'): + val = self.applyFilters(m.group('value')) + try: + val = int(val) + except: + pass + self.context[m.group('name')] = val + def do_undef(self, args): + m = re.match('(?P\w+)$', args, re.U) + if not m: + raise Preprocessor.Error(self, 'SYNTAX_DEF', args) + if args in self.context: + del self.context[args] + # Logic + def ensure_not_else(self): + if len(self.ifStates) == 0 or self.ifStates[-1] == 2: + sys.stderr.write('WARNING: bad nesting of #else\n') + def do_if(self, args, replace=False): + if self.disableLevel and not replace: + self.disableLevel += 1 + return + val = None try: - os.makedirs(dir) - except OSError as error: - if error.errno != errno.EEXIST: - raise - return open(path, 'wb') - - p = self.getCommandLineParser() - options, args = p.parse_args(args=args) - includes = options.I - if options.output: - self.out = get_output_file(options.output) - if defaultToStdin and len(args) == 0: - args = [sys.stdin] - if options.depend: - raise Preprocessor.Error(self, "--depend doesn't work with stdin", - None) - if options.depend: - if not options.output: - raise Preprocessor.Error(self, "--depend doesn't work with stdout", - None) - try: - from makeutil import Makefile - except: - raise Preprocessor.Error(self, "--depend requires the " - "mozbuild.makeutil module", None) - self.depfile = get_output_file(options.depend) - includes.extend(args) - if includes: - for f in includes: - self.do_include(f, False) - self.warnUnused(f) - if self.depfile: - mk = Makefile() - mk.create_rule([options.output]).add_dependencies(self.includes) - mk.dump(self.depfile) - self.depfile.close() - if options.output: - self.out.close() - - def getCommandLineParser(self, unescapeDefines = False): - escapedValue = re.compile('".*"$') - numberValue = re.compile('\d+$') - def handleE(option, opt, value, parser): - for k,v in os.environ.iteritems(): - self.context[k] = v - def handleD(option, opt, value, parser): - vals = value.split('=', 1) - if len(vals) == 1: - vals.append(1) - elif unescapeDefines and escapedValue.match(vals[1]): - # strip escaped string values - vals[1] = vals[1][1:-1] - elif numberValue.match(vals[1]): - vals[1] = int(vals[1]) - self.context[vals[0]] = vals[1] - def handleU(option, opt, value, parser): - del self.context[value] - def handleF(option, opt, value, parser): - self.do_filter(value) - def handleLE(option, opt, value, parser): - self.setLineEndings(value) - def handleMarker(option, opt, value, parser): - self.setMarker(value) - p = OptionParser() - p.add_option('-I', action='append', type="string", default = [], - metavar="FILENAME", help='Include file') - p.add_option('-E', action='callback', callback=handleE, - help='Import the environment into the defined variables') - p.add_option('-D', action='callback', callback=handleD, type="string", - metavar="VAR[=VAL]", help='Define a variable') - p.add_option('-U', action='callback', callback=handleU, type="string", - metavar="VAR", help='Undefine a variable') - p.add_option('-F', action='callback', callback=handleF, type="string", - metavar="FILTER", help='Enable the specified filter') - p.add_option('-o', '--output', type="string", default=None, - metavar="FILENAME", help='Output to the specified file '+ - 'instead of stdout') - p.add_option('--depend', type="string", default=None, metavar="FILENAME", - help='Generate dependencies in the given file') - p.add_option('--line-endings', action='callback', callback=handleLE, - type="string", metavar="[cr|lr|crlf]", - help='Use the specified line endings [Default: OS dependent]') - p.add_option('--marker', action='callback', callback=handleMarker, - type="string", - help='Use the specified marker instead of #') - return p - - def handleLine(self, aLine): - """ - Handle a single line of input (internal). - """ - if self.actionLevel == 0 and self.comment.match(aLine): - self.actionLevel = 1 - m = self.instruction.match(aLine) - if m: - args = None - cmd = m.group('cmd') - try: - args = m.group('args') - except IndexError: + e = Expression(args) + val = e.evaluate(self.context) + except Exception: + # XXX do real error reporting + raise Preprocessor.Error(self, 'SYNTAX_ERR', args) + if type(val) == str: + # we're looking for a number value, strings are false + val = False + if not val: + self.disableLevel = 1 + if replace: + if val: + self.disableLevel = 0 + self.ifStates[-1] = self.disableLevel + else: + self.ifStates.append(self.disableLevel) pass - if cmd not in self.cmds: - raise Preprocessor.Error(self, 'INVALID_CMD', aLine) - level, cmd = self.cmds[cmd] - if (level >= self.disableLevel): - cmd(args) - if cmd != 'literal': - self.actionLevel = 2 - elif self.disableLevel == 0 and not self.comment.match(aLine): - self.write(aLine) - pass - - # Instruction handlers - # These are named do_'instruction name' and take one argument - - # Variables - def do_define(self, args): - m = re.match('(?P\w+)(?:\s(?P.*))?', args, re.U) - if not m: - raise Preprocessor.Error(self, 'SYNTAX_DEF', args) - val = 1 - if m.group('value'): - val = self.applyFilters(m.group('value')) - try: - val = int(val) - except: + def do_ifdef(self, args, replace=False): + if self.disableLevel and not replace: + self.disableLevel += 1 + return + if re.match('\W', args, re.U): + raise Preprocessor.Error(self, 'INVALID_VAR', args) + if args not in self.context: + self.disableLevel = 1 + if replace: + if args in self.context: + self.disableLevel = 0 + self.ifStates[-1] = self.disableLevel + else: + self.ifStates.append(self.disableLevel) pass - self.context[m.group('name')] = val - def do_undef(self, args): - m = re.match('(?P\w+)$', args, re.U) - if not m: - raise Preprocessor.Error(self, 'SYNTAX_DEF', args) - if args in self.context: - del self.context[args] - # Logic - def ensure_not_else(self): - if len(self.ifStates) == 0 or self.ifStates[-1] == 2: - sys.stderr.write('WARNING: bad nesting of #else\n') - def do_if(self, args, replace=False): - if self.disableLevel and not replace: - self.disableLevel += 1 - return - val = None - try: - e = Expression(args) - val = e.evaluate(self.context) - except Exception: - # XXX do real error reporting - raise Preprocessor.Error(self, 'SYNTAX_ERR', args) - if type(val) == str: - # we're looking for a number value, strings are false - val = False - if not val: - self.disableLevel = 1 - if replace: - if val: + def do_ifndef(self, args, replace=False): + if self.disableLevel and not replace: + self.disableLevel += 1 + return + if re.match('\W', args, re.U): + raise Preprocessor.Error(self, 'INVALID_VAR', args) + if args in self.context: + self.disableLevel = 1 + if replace: + if args not in self.context: + self.disableLevel = 0 + self.ifStates[-1] = self.disableLevel + else: + self.ifStates.append(self.disableLevel) + pass + def do_else(self, args, ifState = 2): + self.ensure_not_else() + hadTrue = self.ifStates[-1] == 0 + self.ifStates[-1] = ifState # in-else + if hadTrue: + self.disableLevel = 1 + return self.disableLevel = 0 - self.ifStates[-1] = self.disableLevel - else: - self.ifStates.append(self.disableLevel) - pass - def do_ifdef(self, args, replace=False): - if self.disableLevel and not replace: - self.disableLevel += 1 - return - if re.match('\W', args, re.U): - raise Preprocessor.Error(self, 'INVALID_VAR', args) - if args not in self.context: - self.disableLevel = 1 - if replace: - if args in self.context: - self.disableLevel = 0 - self.ifStates[-1] = self.disableLevel - else: - self.ifStates.append(self.disableLevel) - pass - def do_ifndef(self, args, replace=False): - if self.disableLevel and not replace: - self.disableLevel += 1 - return - if re.match('\W', args, re.U): - raise Preprocessor.Error(self, 'INVALID_VAR', args) - if args in self.context: - self.disableLevel = 1 - if replace: - if args not in self.context: - self.disableLevel = 0 - self.ifStates[-1] = self.disableLevel - else: - self.ifStates.append(self.disableLevel) - pass - def do_else(self, args, ifState = 2): - self.ensure_not_else() - hadTrue = self.ifStates[-1] == 0 - self.ifStates[-1] = ifState # in-else - if hadTrue: - self.disableLevel = 1 - return - self.disableLevel = 0 - def do_elif(self, args): - if self.disableLevel == 1: - if self.ifStates[-1] == 1: - self.do_if(args, replace=True) - else: - self.do_else(None, self.ifStates[-1]) - def do_elifdef(self, args): - if self.disableLevel == 1: - if self.ifStates[-1] == 1: - self.do_ifdef(args, replace=True) - else: - self.do_else(None, self.ifStates[-1]) - def do_elifndef(self, args): - if self.disableLevel == 1: - if self.ifStates[-1] == 1: - self.do_ifndef(args, replace=True) - else: - self.do_else(None, self.ifStates[-1]) - def do_endif(self, args): - if self.disableLevel > 0: - self.disableLevel -= 1 - if self.disableLevel == 0: - self.ifStates.pop() - # output processing - def do_expand(self, args): - lst = re.split('__(\w+)__', args, re.U) - do_replace = False - def vsubst(v): - if v in self.context: - return str(self.context[v]) - return '' - for i in range(1, len(lst), 2): - lst[i] = vsubst(lst[i]) - lst.append('\n') # add back the newline - self.write(reduce(lambda x, y: x+y, lst, '')) - def do_literal(self, args): - self.write(args + self.LE) - def do_filter(self, args): - filters = [f for f in args.split(' ') if hasattr(self, 'filter_' + f)] - if len(filters) == 0: - return - current = dict(self.filters) - for f in filters: - current[f] = getattr(self, 'filter_' + f) - filterNames = current.keys() - filterNames.sort() - self.filters = [(fn, current[fn]) for fn in filterNames] - return - def do_unfilter(self, args): - filters = args.split(' ') - current = dict(self.filters) - for f in filters: - if f in current: - del current[f] - filterNames = current.keys() - filterNames.sort() - self.filters = [(fn, current[fn]) for fn in filterNames] - return - # Filters - # - # emptyLines - # Strips blank lines from the output. - def filter_emptyLines(self, aLine): - if aLine == '\n': - return '' - return aLine - # slashslash - # Strips everything after // - def filter_slashslash(self, aLine): - if (aLine.find('//') == -1): - return aLine - [aLine, rest] = aLine.split('//', 1) - if rest: - aLine += '\n' - return aLine - # spaces - # Collapses sequences of spaces into a single space - def filter_spaces(self, aLine): - return re.sub(' +', ' ', aLine).strip(' ') - # substition - # helper to be used by both substition and attemptSubstitution - def filter_substitution(self, aLine, fatal=True): - def repl(matchobj): - varname = matchobj.group('VAR') - if varname in self.context: - return str(self.context[varname]) - if fatal: - raise Preprocessor.Error(self, 'UNDEFINED_VAR', varname) - return matchobj.group(0) - return self.varsubst.sub(repl, aLine) - def filter_attemptSubstitution(self, aLine): - return self.filter_substitution(aLine, fatal=False) - # File ops - def do_include(self, args, filters=True): - """ - Preprocess a given file. - args can either be a file name, or a file-like object. - Files should be opened, and will be closed after processing. - """ - isName = type(args) == str or type(args) == unicode - oldWrittenLines = self.writtenLines - oldCheckLineNumbers = self.checkLineNumbers - self.checkLineNumbers = False - if isName: - try: - args = str(args) - if filters: - args = self.applyFilters(args) - if not os.path.isabs(args): - args = os.path.join(self.context['DIRECTORY'], args) - args = open(args, 'rU') - except Preprocessor.Error: - raise - except: - raise Preprocessor.Error(self, 'FILE_NOT_FOUND', str(args)) - self.checkLineNumbers = bool(re.search('\.(js|jsm|java)(?:\.in)?$', args.name)) - oldFile = self.context['FILE'] - oldLine = self.context['LINE'] - oldDir = self.context['DIRECTORY'] - if args.isatty(): - # we're stdin, use '-' and '' for file and dir - self.context['FILE'] = '-' - self.context['DIRECTORY'] = '' - else: - abspath = os.path.abspath(args.name) - if self.depfile: - self.includes.add(abspath) - self.context['FILE'] = abspath - self.context['DIRECTORY'] = os.path.dirname(abspath) - self.context['LINE'] = 0 - self.writtenLines = 0 - for l in args: - self.context['LINE'] += 1 - self.handleLine(l) - args.close() - self.context['FILE'] = oldFile - self.checkLineNumbers = oldCheckLineNumbers - self.writtenLines = oldWrittenLines - self.context['LINE'] = oldLine - self.context['DIRECTORY'] = oldDir - def do_includesubst(self, args): - args = self.filter_substitution(args) - self.do_include(args) - def do_error(self, args): - raise Preprocessor.Error(self, 'Error: ', str(args)) + def do_elif(self, args): + if self.disableLevel == 1: + if self.ifStates[-1] == 1: + self.do_if(args, replace=True) + else: + self.do_else(None, self.ifStates[-1]) + def do_elifdef(self, args): + if self.disableLevel == 1: + if self.ifStates[-1] == 1: + self.do_ifdef(args, replace=True) + else: + self.do_else(None, self.ifStates[-1]) + def do_elifndef(self, args): + if self.disableLevel == 1: + if self.ifStates[-1] == 1: + self.do_ifndef(args, replace=True) + else: + self.do_else(None, self.ifStates[-1]) + def do_endif(self, args): + if self.disableLevel > 0: + self.disableLevel -= 1 + if self.disableLevel == 0: + self.ifStates.pop() + # output processing + def do_expand(self, args): + lst = re.split('__(\w+)__', args, re.U) + do_replace = False + def vsubst(v): + if v in self.context: + return str(self.context[v]) + return '' + for i in range(1, len(lst), 2): + lst[i] = vsubst(lst[i]) + lst.append('\n') # add back the newline + self.write(reduce(lambda x, y: x+y, lst, '')) + def do_literal(self, args): + self.write(args + self.LE) + def do_filter(self, args): + filters = [f for f in args.split(' ') if hasattr(self, 'filter_' + f)] + if len(filters) == 0: + return + current = dict(self.filters) + for f in filters: + current[f] = getattr(self, 'filter_' + f) + filterNames = current.keys() + filterNames.sort() + self.filters = [(fn, current[fn]) for fn in filterNames] + return + def do_unfilter(self, args): + filters = args.split(' ') + current = dict(self.filters) + for f in filters: + if f in current: + del current[f] + filterNames = current.keys() + filterNames.sort() + self.filters = [(fn, current[fn]) for fn in filterNames] + return + # Filters + # + # emptyLines + # Strips blank lines from the output. + def filter_emptyLines(self, aLine): + if aLine == '\n': + return '' + return aLine + # slashslash + # Strips everything after // + def filter_slashslash(self, aLine): + if (aLine.find('//') == -1): + return aLine + [aLine, rest] = aLine.split('//', 1) + if rest: + aLine += '\n' + return aLine + # spaces + # Collapses sequences of spaces into a single space + def filter_spaces(self, aLine): + return re.sub(' +', ' ', aLine).strip(' ') + # substition + # helper to be used by both substition and attemptSubstitution + def filter_substitution(self, aLine, fatal=True): + def repl(matchobj): + varname = matchobj.group('VAR') + if varname in self.context: + return str(self.context[varname]) + if fatal: + raise Preprocessor.Error(self, 'UNDEFINED_VAR', varname) + return matchobj.group(0) + return self.varsubst.sub(repl, aLine) + def filter_attemptSubstitution(self, aLine): + return self.filter_substitution(aLine, fatal=False) + # File ops + def do_include(self, args, filters=True): + """ + Preprocess a given file. + args can either be a file name, or a file-like object. + Files should be opened, and will be closed after processing. + """ + isName = type(args) == str or type(args) == unicode + oldWrittenLines = self.writtenLines + oldCheckLineNumbers = self.checkLineNumbers + self.checkLineNumbers = False + if isName: + try: + args = str(args) + if filters: + args = self.applyFilters(args) + if not os.path.isabs(args): + args = os.path.join(self.context['DIRECTORY'], args) + args = open(args, 'rU') + except Preprocessor.Error: + raise + except: + raise Preprocessor.Error(self, 'FILE_NOT_FOUND', str(args)) + self.checkLineNumbers = bool(re.search('\.(js|jsm|java)(?:\.in)?$', args.name)) + oldFile = self.context['FILE'] + oldLine = self.context['LINE'] + oldDir = self.context['DIRECTORY'] + if args.isatty(): + # we're stdin, use '-' and '' for file and dir + self.context['FILE'] = '-' + self.context['DIRECTORY'] = '' + else: + abspath = os.path.abspath(args.name) + if self.depfile: + self.includes.add(abspath) + self.context['FILE'] = abspath + self.context['DIRECTORY'] = os.path.dirname(abspath) + self.context['LINE'] = 0 + self.writtenLines = 0 + for l in args: + self.context['LINE'] += 1 + self.handleLine(l) + args.close() + self.context['FILE'] = oldFile + self.checkLineNumbers = oldCheckLineNumbers + self.writtenLines = oldWrittenLines + self.context['LINE'] = oldLine + self.context['DIRECTORY'] = oldDir + def do_includesubst(self, args): + args = self.filter_substitution(args) + self.do_include(args) + def do_error(self, args): + raise Preprocessor.Error(self, 'Error: ', str(args)) def preprocess(includes=[sys.stdin], defines={}, output = sys.stdout, line_endings='\n', marker='#'): - pp = Preprocessor() - pp.context.update(defines) - pp.setLineEndings(line_endings) - pp.setMarker(marker) - pp.out = output - for f in includes: - pp.do_include(f, False) + pp = Preprocessor() + pp.context.update(defines) + pp.setLineEndings(line_endings) + pp.setMarker(marker) + pp.out = output + for f in includes: + pp.do_include(f, False) # Keep this module independently executable. if __name__ == "__main__": - pp = Preprocessor() - pp.handleCommandLine(None, True) + pp = Preprocessor() + pp.handleCommandLine(None, True) diff --git a/services/datareporting/DataReportingService.js b/services/datareporting/DataReportingService.js index f7e3db0a2e26..9672c0bd6540 100644 --- a/services/datareporting/DataReportingService.js +++ b/services/datareporting/DataReportingService.js @@ -108,24 +108,29 @@ DataReportingService.prototype = Object.freeze({ case "profile-after-change": this._os.removeObserver(this, "profile-after-change"); - this._os.addObserver(this, "sessionstore-windows-restored", true); - this._prefs = new Preferences(HEALTHREPORT_BRANCH); + try { + this._prefs = new Preferences(HEALTHREPORT_BRANCH); - // We don't initialize the sessions recorder unless Health Report is - // around to provide pruning of data. - // - // FUTURE consider having the SessionsRecorder always enabled and/or - // living in its own XPCOM service. - if (this._prefs.get("service.enabled", true)) { - this.sessionRecorder = new SessionRecorder(SESSIONS_BRANCH); - this.sessionRecorder.onStartup(); + // We don't initialize the sessions recorder unless Health Report is + // around to provide pruning of data. + // + // FUTURE consider having the SessionsRecorder always enabled and/or + // living in its own XPCOM service. + if (this._prefs.get("service.enabled", true)) { + this.sessionRecorder = new SessionRecorder(SESSIONS_BRANCH); + this.sessionRecorder.onStartup(); + } + + // We can't interact with prefs until after the profile is present. + let policyPrefs = new Preferences(POLICY_BRANCH); + this.policy = new DataReportingPolicy(policyPrefs, this._prefs, this); + + this._os.addObserver(this, "sessionstore-windows-restored", true); + } catch (ex) { + Cu.reportError("Exception when initializing data reporting service: " + + CommonUtils.exceptionStr(ex)); } - - // We can't interact with prefs until after the profile is present. - let policyPrefs = new Preferences(POLICY_BRANCH); - this.policy = new DataReportingPolicy(policyPrefs, this._prefs, this); - break; case "sessionstore-windows-restored": @@ -187,7 +192,9 @@ DataReportingService.prototype = Object.freeze({ this.timer.cancel(); } - this.policy.stopPolling(); + if (this.policy) { + this.policy.stopPolling(); + } break; } }, @@ -220,6 +227,11 @@ DataReportingService.prototype = Object.freeze({ }, _loadHealthReporter: function () { + // This should never happen. It was added to help trace down bug 924307. + if (!this.policy) { + throw new Error("this.policy not set."); + } + let ns = {}; // Lazy import so application startup isn't adversely affected. diff --git a/toolkit/components/alerts/nsAlertsService.cpp b/toolkit/components/alerts/nsAlertsService.cpp index 5cc3b0099608..6ca303d3970f 100644 --- a/toolkit/components/alerts/nsAlertsService.cpp +++ b/toolkit/components/alerts/nsAlertsService.cpp @@ -11,6 +11,7 @@ #ifdef MOZ_WIDGET_ANDROID #include "AndroidBridge.h" +using namespace mozilla::widget::android; #else #include "nsXPCOM.h" @@ -127,7 +128,7 @@ NS_IMETHODIMP nsAlertsService::CloseAlert(const nsAString& aAlertName, } #ifdef MOZ_WIDGET_ANDROID - mozilla::AndroidBridge::Bridge()->CloseNotification(aAlertName); + GeckoAppShell::CloseNotification(aAlertName); return NS_OK; #else @@ -148,7 +149,7 @@ NS_IMETHODIMP nsAlertsService::OnProgress(const nsAString & aAlertName, const nsAString & aAlertText) { #ifdef MOZ_WIDGET_ANDROID - mozilla::AndroidBridge::Bridge()->AlertsProgressListener_OnProgress(aAlertName, aProgress, aProgressMax, aAlertText); + GeckoAppShell::AlertsProgressListener_OnProgress(aAlertName, aProgress, aProgressMax, aAlertText); return NS_OK; #else return NS_ERROR_NOT_IMPLEMENTED; @@ -158,7 +159,7 @@ NS_IMETHODIMP nsAlertsService::OnProgress(const nsAString & aAlertName, NS_IMETHODIMP nsAlertsService::OnCancel(const nsAString & aAlertName) { #ifdef MOZ_WIDGET_ANDROID - mozilla::AndroidBridge::Bridge()->CloseNotification(aAlertName); + GeckoAppShell::CloseNotification(aAlertName); return NS_OK; #else return NS_ERROR_NOT_IMPLEMENTED; diff --git a/toolkit/components/downloads/nsDownloadManager.cpp b/toolkit/components/downloads/nsDownloadManager.cpp index c18afc870538..e3f6abc709cd 100644 --- a/toolkit/components/downloads/nsDownloadManager.cpp +++ b/toolkit/components/downloads/nsDownloadManager.cpp @@ -52,6 +52,7 @@ #ifdef MOZ_WIDGET_ANDROID #include "AndroidBridge.h" +using namespace mozilla::widget::android; #endif #ifdef MOZ_WIDGET_GTK @@ -2797,7 +2798,7 @@ nsDownload::SetState(DownloadState aState) if (mimeInfo) mimeInfo->GetMIMEType(contentType); - mozilla::AndroidBridge::Bridge()->ScanMedia(path, NS_ConvertUTF8toUTF16(contentType)); + GeckoAppShell::ScanMedia(path, NS_ConvertUTF8toUTF16(contentType)); #endif } diff --git a/toolkit/components/jsdownloads/src/DownloadPlatform.cpp b/toolkit/components/jsdownloads/src/DownloadPlatform.cpp index 1ece7ddbac37..c1807e13a8f7 100644 --- a/toolkit/components/jsdownloads/src/DownloadPlatform.cpp +++ b/toolkit/components/jsdownloads/src/DownloadPlatform.cpp @@ -118,7 +118,7 @@ nsresult DownloadPlatform::DownloadDone(nsIURI* aSource, nsIFile* aTarget, #endif #ifdef MOZ_WIDGET_ANDROID if (!aContentType.IsEmpty()) { - mozilla::AndroidBridge::Bridge()->ScanMedia(path, NS_ConvertUTF8toUTF16(aContentType)); + mozilla::widget::android::GeckoAppShell::ScanMedia(path, NS_ConvertUTF8toUTF16(aContentType)); } #endif } diff --git a/toolkit/content/browser-child.js b/toolkit/content/browser-child.js index 35fa00eb389d..d08bfdb92504 100644 --- a/toolkit/content/browser-child.js +++ b/toolkit/content/browser-child.js @@ -10,6 +10,22 @@ Cu.import("resource://gre/modules/Services.jsm"); Cu.import('resource://gre/modules/XPCOMUtils.jsm'); Cu.import("resource://gre/modules/RemoteAddonsChild.jsm"); +let SyncHandler = { + init: function() { + sendAsyncMessage("SetSyncHandler", {}, {handler: this}); + }, + + getFocusedElementAndWindow: function() { + let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager); + + let focusedWindow = {}; + let elt = fm.getFocusedElementForWindow(content, true, focusedWindow); + return [elt, focusedWindow.value]; + }, +}; + +SyncHandler.init(); + let WebProgressListener = { init: function() { let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor) @@ -33,10 +49,8 @@ let WebProgressListener = { }, _setupObjects: function setupObjects(aWebProgress) { - let win = docShell.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindow); return { - contentWindow: win, + contentWindow: content, // DOMWindow is not necessarily the content-window with subframes. DOMWindow: aWebProgress.DOMWindow }; diff --git a/toolkit/content/widgets/findbar.xml b/toolkit/content/widgets/findbar.xml index 649716d1550f..973c688e4d5f 100644 --- a/toolkit/content/widgets/findbar.xml +++ b/toolkit/content/widgets/findbar.xml @@ -679,11 +679,15 @@ return false; let elt = document.commandDispatcher.focusedElement; + let win = document.commandDispatcher.focusedWindow; // Temporary fix for e10s. - if (elt instanceof XULElement && elt.tagName == "xul:browser" && + const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; + if (elt instanceof XULElement && + elt.localName == "browser" && + elt.namespaceURI == XUL_NS && elt.getAttribute("remote")) { - elt = elt.contentDocument.activeElement; + [elt, win] = elt.syncHandler.getFocusedElementAndWindow(); } if (elt) { @@ -697,7 +701,6 @@ return false; } - let win = document.commandDispatcher.focusedWindow; if (win && !this._mimeTypeIsTextBased(win.document.contentType)) return false; diff --git a/toolkit/content/widgets/remote-browser.xml b/toolkit/content/widgets/remote-browser.xml index c66d5b8026d8..1b9930333f4d 100644 --- a/toolkit/content/widgets/remote-browser.xml +++ b/toolkit/content/widgets/remote-browser.xml @@ -107,6 +107,12 @@ onget="return this.contentWindow ? this.contentWindow.document : null" readonly="true"/> + null + + + null 0) { + let matched = null; + + // Prevent this loop from slowing down the browser with too + // many nodes being appended into output. In practice it is very unlikely + // that this will ever happen. + i++; + if (i > MAX_ITERATIONS) { + this._appendTextNode(text); + text = ""; + break; + } + matched = text.match(REGEX_QUOTES); if (matched) { let match = matched[0]; - trimMatchFromStart(match); + + text = this._trimMatchFromStart(text, match); this._appendTextNode(match); + continue; } matched = text.match(REGEX_WHITESPACE); if (matched) { let match = matched[0]; - trimMatchFromStart(match); + + text = this._trimMatchFromStart(text, match); this._appendTextNode(match); + continue; } matched = text.match(REGEX_URL); if (matched) { let [match, url] = matched; - trimMatchFromStart(match); + + text = this._trimMatchFromStart(text, match); this._appendURL(match, url, options); + continue; } matched = text.match(REGEX_ALL_CSS_PROPERTIES); if (matched) { let [match] = matched; - trimMatchFromStart(match); + + text = this._trimMatchFromStart(text, match); this._appendTextNode(match); - dirty = true; + if (options.isHTMLAttribute) { + [text] = this._appendColorOnMatch(text, options); + } + continue; } - matched = text.match(REGEX_ALL_COLORS); + if (!options.isHTMLAttribute) { + let dirty; + + [text, dirty] = this._appendColorOnMatch(text, options); + + if (dirty) { + continue; + } + } + + // This test must always be last as it indicates use of an unknown + // character that needs to be removed to prevent infinite loops. + matched = text.match(REGEX_FIRST_WORD_OR_CHAR); if (matched) { let match = matched[0]; - if (this._appendColor(match, options)) { - trimMatchFromStart(match); - } - } - if (!dirty) { - // This test must always be last as it indicates use of an unknown - // character that needs to be removed to prevent infinite loops. - matched = text.match(REGEX_FIRST_WORD_OR_CHAR); - if (matched) { - let match = matched[0]; - trimMatchFromStart(match); - this._appendTextNode(match); - } - } - - dirty = false; - - // Prevent this loop from slowing down the browser with too - // many nodes being appended into output. - i++; - if (i > MAX_ITERATIONS) { - trimMatchFromStart(text); - this._appendTextNode(text); + text = this._trimMatchFromStart(text, match); + this._appendTextNode(match); } } return this._toDOM(); }, + /** + * Convenience function to make the parser a little more readable. + * + * @param {String} text + * Main text + * @param {String} match + * Text to remove from the beginning + * + * @return {String} + * The string passed as 'text' with 'match' stripped from the start. + */ + _trimMatchFromStart: function(text, match) { + return text.substr(match.length); + }, + + /** + * Check if there is a color match and append it if it is valid. + * + * @param {String} text + * Main text + * @param {Object} options + * Options object. For valid options and default values see + * _mergeOptions(). + * + * @return {Array} + * An array containing the remaining text and a dirty flag. This array + * is designed for deconstruction using [text, dirty]. + */ + _appendColorOnMatch: function(text, options) { + let dirty; + let matched = text.match(REGEX_ALL_COLORS); + + if (matched) { + let match = matched[0]; + if (this._appendColor(match, options)) { + text = this._trimMatchFromStart(text, match); + dirty = true; + } + } else { + dirty = false; + } + + return [text, dirty]; + }, + /** * Check if a CSS property supports a specific value. * @@ -332,7 +383,7 @@ OutputParser.prototype = { _appendTextNode: function(text) { let lastItem = this.parsed[this.parsed.length - 1]; if (typeof lastItem === "string") { - this.parsed[this.parsed.length - 1] = lastItem + text + this.parsed[this.parsed.length - 1] = lastItem + text; } else { this.parsed.push(text); } @@ -371,6 +422,13 @@ OutputParser.prototype = { * - defaultColorType: true // Convert colors to the default type * // selected in the options panel. * - colorSwatchClass: "" // The class to use for color swatches. + * - isHTMLAttribute: false // This property indicates whether we + * // are parsing an HTML attribute value. + * // When the value is passed in from an + * // HTML attribute we need to check that + * // any CSS property values are supported + * // by the property name before + * // processing the property value. * - urlClass: "" // The class to be used for url() links. * - baseURI: "" // A string or nsIURI used to resolve * // relative links. @@ -381,6 +439,7 @@ OutputParser.prototype = { let defaults = { defaultColorType: true, colorSwatchClass: "", + isHTMLAttribute: false, urlClass: "", baseURI: "" }; diff --git a/toolkit/mozapps/extensions/XPIProvider.jsm b/toolkit/mozapps/extensions/XPIProvider.jsm index 8a9d3b5e9ee0..c4fef5e99ccf 100644 --- a/toolkit/mozapps/extensions/XPIProvider.jsm +++ b/toolkit/mozapps/extensions/XPIProvider.jsm @@ -3308,7 +3308,7 @@ var XPIProvider = { locMigrateData = XPIDatabase.migrateData[installLocation.name]; for (let id in addonStates) { changed = addMetadata(installLocation, id, addonStates[id], - locMigrateData[id]) || changed; + locMigrateData[id] || null) || changed; } } @@ -6923,7 +6923,7 @@ DirectoryInstallLocation.prototype = { recursiveRemove(file); } - if (this.stagingDirLock > 0) + if (this._stagingDirLock > 0) return; let dirEntries = dir.directoryEntries.QueryInterface(Ci.nsIDirectoryEnumerator); diff --git a/toolkit/xre/nsAndroidStartup.cpp b/toolkit/xre/nsAndroidStartup.cpp index aefe006749a6..278c5591f429 100644 --- a/toolkit/xre/nsAndroidStartup.cpp +++ b/toolkit/xre/nsAndroidStartup.cpp @@ -75,7 +75,7 @@ GeckoStart(void *data, const nsXREAppData *appData) if (result) LOG("XRE_main returned %d", result); - mozilla::AndroidBridge::Bridge()->NotifyXreExit(); + mozilla::widget::android::GeckoAppShell::NotifyXreExit(); free(targs[0]); nsMemory::Free(data); diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index db09d987556c..893e6ee58de6 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -1649,7 +1649,7 @@ static nsresult LaunchChild(nsINativeAppSupport* aNative, SaveToEnv("MOZ_LAUNCHED_CHILD=1"); #if defined(MOZ_WIDGET_ANDROID) - mozilla::AndroidBridge::Bridge()->ScheduleRestart(); + mozilla::widget::android::GeckoAppShell::ScheduleRestart(); #else #if defined(XP_MACOSX) CommandLineServiceMac::SetupMacCommandLine(gRestartArgc, gRestartArgv, true); @@ -1761,7 +1761,7 @@ ProfileLockedDialog(nsIFile* aProfileDir, nsIFile* aProfileLocalDir, if (aUnlocker) { int32_t button; #ifdef MOZ_WIDGET_ANDROID - mozilla::AndroidBridge::Bridge()->KillAnyZombies(); + mozilla::widget::android::GeckoAppShell::KillAnyZombies(); button = 1; #else const uint32_t flags = @@ -1788,7 +1788,7 @@ ProfileLockedDialog(nsIFile* aProfileDir, nsIFile* aProfileLocalDir, } } else { #ifdef MOZ_WIDGET_ANDROID - if (mozilla::AndroidBridge::Bridge()->UnlockProfile()) { + if (mozilla::widget::android::GeckoAppShell::UnlockProfile()) { return NS_LockProfilePath(aProfileDir, aProfileLocalDir, nullptr, aResult); } diff --git a/tools/profiler/TableTicker.cpp b/tools/profiler/TableTicker.cpp index 930fee528918..2f497c8766b9 100644 --- a/tools/profiler/TableTicker.cpp +++ b/tools/profiler/TableTicker.cpp @@ -230,7 +230,7 @@ typename Builder::Object BuildJavaThreadJSObject(Builder& b) b.DefineProperty(sample, "frames", frames); b.ArrayPush(samples, sample); - double sampleTime = AndroidBridge::Bridge()->GetSampleTimeJavaProfiling(0, sampleId); + double sampleTime = GeckoJavaSampler::GetSampleTimeJavaProfiling(0, sampleId); b.DefineProperty(sample, "time", sampleTime); } typename Builder::RootedObject frame(b.context(), b.CreateObject()); @@ -282,12 +282,12 @@ void TableTicker::BuildJSObject(Builder& b, typename Builder::ObjectHandle profi #if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK) if (ProfileJava()) { - AndroidBridge::Bridge()->PauseJavaProfiling(); + GeckoJavaSampler::PauseJavaProfiling(); typename Builder::RootedObject javaThread(b.context(), BuildJavaThreadJSObject(b)); b.ArrayPush(threads, javaThread); - AndroidBridge::Bridge()->UnpauseJavaProfiling(); + GeckoJavaSampler::UnpauseJavaProfiling(); } #endif diff --git a/tools/profiler/platform.cpp b/tools/profiler/platform.cpp index 6faa21e50170..5448c5b28fb5 100644 --- a/tools/profiler/platform.cpp +++ b/tools/profiler/platform.cpp @@ -28,6 +28,7 @@ #if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK) #include "AndroidBridge.h" + using namespace mozilla::widget::android; #endif mozilla::ThreadLocal tlsPseudoStack; @@ -675,7 +676,7 @@ void mozilla_sampler_start(int aProfileEntries, double aInterval, if (javaInterval < 10) { aInterval = 10; } - mozilla::AndroidBridge::Bridge()->StartJavaProfiling(javaInterval, 1000); + GeckoJavaSampler::StartJavaProfiling(javaInterval, 1000); } #endif diff --git a/uriloader/exthandler/android/nsAndroidHandlerApp.cpp b/uriloader/exthandler/android/nsAndroidHandlerApp.cpp index 46a10ab09787..007378e5f893 100644 --- a/uriloader/exthandler/android/nsAndroidHandlerApp.cpp +++ b/uriloader/exthandler/android/nsAndroidHandlerApp.cpp @@ -6,6 +6,8 @@ #include "nsAndroidHandlerApp.h" #include "AndroidBridge.h" +using namespace mozilla::widget::android; + NS_IMPL_ISUPPORTS2(nsAndroidHandlerApp, nsIHandlerApp, nsISharingHandlerApp) @@ -65,24 +67,16 @@ nsAndroidHandlerApp::Equals(nsIHandlerApp *aHandlerApp, bool *aRetval) NS_IMETHODIMP nsAndroidHandlerApp::LaunchWithURI(nsIURI *aURI, nsIInterfaceRequestor *aWindowContext) { - if (!mozilla::AndroidBridge::Bridge()) - return NS_ERROR_FAILURE; - nsCString uriSpec; aURI->GetSpec(uriSpec); - return mozilla::AndroidBridge::Bridge()-> - OpenUriExternal(NS_ConvertUTF8toUTF16(uriSpec), NS_ConvertUTF8toUTF16(mMimeType), mPackageName, mClassName, mAction) ? + return GeckoAppShell::OpenUriExternal(NS_ConvertUTF8toUTF16(uriSpec), NS_ConvertUTF8toUTF16(mMimeType), mPackageName, mClassName, mAction) ? NS_OK : NS_ERROR_FAILURE; } NS_IMETHODIMP nsAndroidHandlerApp::Share(const nsAString & data, const nsAString & title) { - if (!mozilla::AndroidBridge::Bridge()) - return NS_ERROR_FAILURE; - - return mozilla::AndroidBridge::Bridge()-> - OpenUriExternal(data, NS_ConvertUTF8toUTF16(mMimeType), mPackageName, + return GeckoAppShell::OpenUriExternal(data, NS_ConvertUTF8toUTF16(mMimeType), mPackageName, mClassName, mAction) ? NS_OK : NS_ERROR_FAILURE; } diff --git a/uriloader/exthandler/android/nsExternalSharingAppService.cpp b/uriloader/exthandler/android/nsExternalSharingAppService.cpp index fb2d7e489806..058f810414cd 100644 --- a/uriloader/exthandler/android/nsExternalSharingAppService.cpp +++ b/uriloader/exthandler/android/nsExternalSharingAppService.cpp @@ -31,12 +31,7 @@ nsExternalSharingAppService::ShareWithDefault(const nsAString & data, { NS_NAMED_LITERAL_STRING(sendAction, "android.intent.action.SEND"); const nsString emptyString = EmptyString(); - if (AndroidBridge::Bridge()) - return AndroidBridge::Bridge()-> - OpenUriExternal(data, mime, - emptyString,emptyString, sendAction, title) ? NS_OK : NS_ERROR_FAILURE; - - return NS_ERROR_FAILURE; + return GeckoAppShell::OpenUriExternal(data, mime, emptyString,emptyString, sendAction, title) ? NS_OK : NS_ERROR_FAILURE; } NS_IMETHODIMP diff --git a/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp b/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp index 475a2e884f8d..d0d2127a921d 100644 --- a/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp +++ b/uriloader/exthandler/android/nsMIMEInfoAndroid.cpp @@ -10,6 +10,8 @@ #include "nsStringEnumerator.h" #include "nsNetUtil.h" +using namespace mozilla::widget::android; + NS_IMPL_ISUPPORTS2(nsMIMEInfoAndroid, nsIMIMEInfo, nsIHandlerInfo) NS_IMETHODIMP @@ -28,11 +30,7 @@ nsMIMEInfoAndroid::LoadUriInternal(nsIURI * aURI) nsCString uriScheme; aURI->GetScheme(uriScheme); - if (mozilla::AndroidBridge::Bridge()) - return mozilla::AndroidBridge::Bridge()-> - OpenUriExternal(NS_ConvertUTF8toUTF16(uriSpec), (mType.Equals(uriScheme) || mType.Equals(uriSpec)) ? EmptyString() : NS_ConvertUTF8toUTF16(mType)) ? NS_OK : NS_ERROR_FAILURE; - - return NS_ERROR_FAILURE; + return GeckoAppShell::OpenUriExternal(NS_ConvertUTF8toUTF16(uriSpec), (mType.Equals(uriScheme) || mType.Equals(uriSpec)) ? EmptyString() : NS_ConvertUTF8toUTF16(mType)) ? NS_OK : NS_ERROR_FAILURE; } diff --git a/widget/android/AndroidBridge.cpp b/widget/android/AndroidBridge.cpp index efe2cf200da0..96e0ccf9e073 100644 --- a/widget/android/AndroidBridge.cpp +++ b/widget/android/AndroidBridge.cpp @@ -39,13 +39,8 @@ #include "mozilla/ClearOnShutdown.h" #include "nsPrintfCString.h" -#ifdef DEBUG -#define ALOG_BRIDGE(args...) ALOG(args) -#else -#define ALOG_BRIDGE(args...) ((void)0) -#endif - using namespace mozilla; +using namespace mozilla::widget::android; using namespace mozilla::gfx; NS_IMPL_ISUPPORTS0(nsFilePickerCallback) @@ -170,14 +165,13 @@ AndroidBridge::Init(JNIEnv *jEnv) mJNIEnv = nullptr; mThread = -1; - mGLControllerObj = nullptr; + mGLControllerObj = NULL; mOpenedGraphicsLibraries = false; mHasNativeBitmapAccess = false; mHasNativeWindowAccess = false; mHasNativeWindowFallback = false; initInit(); - InitStubs(jEnv); #ifdef MOZ_WEBSMS_BACKEND mAndroidSmsMessageClass = getClassGlobalRef("android/telephony/SmsMessage"); @@ -272,6 +266,52 @@ jstring AndroidBridge::NewJavaString(AutoLocalJNIFrame* frame, const nsACString& return NewJavaString(frame, NS_ConvertUTF8toUTF16(string)); } +extern "C" { + __attribute__ ((visibility("default"))) + JNIEnv * GetJNIForThread() + { + JNIEnv *jEnv = NULL; + JavaVM *jVm = mozilla::AndroidBridge::GetVM(); + if (!jVm) { + __android_log_print(ANDROID_LOG_INFO, "GetJNIForThread", "Returned a null VM"); + return NULL; + } + jEnv = static_cast(PR_GetThreadPrivate(sJavaEnvThreadIndex)); + + if (jEnv) + return jEnv; + + int status = jVm->GetEnv((void**) &jEnv, JNI_VERSION_1_2); + if (status) { + + status = jVm->AttachCurrentThread(&jEnv, NULL); + if (status) { + __android_log_print(ANDROID_LOG_INFO, "GetJNIForThread", "Could not attach"); + return NULL; + } + + PR_SetThreadPrivate(sJavaEnvThreadIndex, jEnv); + } + if (!jEnv) { + __android_log_print(ANDROID_LOG_INFO, "GetJNIForThread", "returning NULL"); + } + return jEnv; + } +} + +void AutoGlobalWrappedJavaObject::Dispose() { + if (isNull()) { + return; + } + + GetJNIForThread()->DeleteGlobalRef(wrapped_obj); + wrapped_obj = NULL; +} + +AutoGlobalWrappedJavaObject::~AutoGlobalWrappedJavaObject() { + Dispose(); +} + static void getHandlersFromStringArray(JNIEnv *aJNIEnv, jobjectArray jArr, jsize aLen, nsIMutableArray *aHandlersArray, @@ -311,7 +351,7 @@ AndroidBridge::GetHandlersForMimeType(const nsAString& aMimeType, if (!env) return false; - jobjectArray arr = GetHandlersForMimeTypeWrapper(aMimeType, aAction); + jobjectArray arr = GeckoAppShell::GetHandlersForMimeTypeWrapper(aMimeType, aAction); if (!arr) return false; @@ -340,7 +380,7 @@ AndroidBridge::GetHandlersForURL(const nsAString& aURL, if (!env) return false; - jobjectArray arr = GetHandlersForURLWrapper(aURL, aAction); + jobjectArray arr = GeckoAppShell::GetHandlersForURLWrapper(aURL, aAction); if (!arr) return false; @@ -365,7 +405,7 @@ AndroidBridge::GetMimeTypeFromExtensions(const nsACString& aFileExt, nsCString& if (!env) return; - jstring jstrType = GetMimeTypeFromExtensionsWrapper(NS_ConvertUTF8toUTF16(aFileExt)); + jstring jstrType = GeckoAppShell::GetMimeTypeFromExtensionsWrapper(NS_ConvertUTF8toUTF16(aFileExt)); if (!jstrType) { return; } @@ -384,7 +424,7 @@ AndroidBridge::GetExtensionFromMimeType(const nsACString& aMimeType, nsACString& if (!env) return; - jstring jstrExt = GetExtensionFromMimeTypeWrapper(NS_ConvertUTF8toUTF16(aMimeType)); + jstring jstrExt = GeckoAppShell::GetExtensionFromMimeTypeWrapper(NS_ConvertUTF8toUTF16(aMimeType)); if (!jstrExt) { return; } @@ -403,7 +443,7 @@ AndroidBridge::GetClipboardText(nsAString& aText) if (!env) return false; - jstring result = GetClipboardTextWrapper(); + jstring result = Clipboard::GetClipboardTextWrapper(); if (!result) return false; @@ -414,36 +454,6 @@ AndroidBridge::GetClipboardText(nsAString& aText) return true; } -bool -AndroidBridge::ClipboardHasText() -{ - ALOG_BRIDGE("AndroidBridge::ClipboardHasText"); - - JNIEnv *env = GetJNIEnv(); - if (!env) - return false; - - AutoLocalJNIFrame jniFrame(env); - - jstring jStr = GetClipboardTextWrapper(); - bool ret = jStr; - - return ret; -} - -void -AndroidBridge::EmptyClipboard() -{ - ALOG_BRIDGE("AndroidBridge::EmptyClipboard"); - - JNIEnv *env = GetJNIEnv(); - if (!env) - return; - - AutoLocalJNIFrame jniFrame(env, 0); - env->CallStaticVoidMethod(mClipboardClass, jSetClipboardText, nullptr); -} - void AndroidBridge::ShowAlertNotification(const nsAString& aImageUrl, const nsAString& aAlertTitle, @@ -457,7 +467,7 @@ AndroidBridge::ShowAlertNotification(const nsAString& aImageUrl, nsAppShell::gAppShell->PostEvent(AndroidGeckoEvent::MakeAddObserver(aAlertName, aAlertListener)); } - ShowAlertNotificationWrapper(aImageUrl, aAlertTitle, aAlertText, aAlertCookie, aAlertName); + GeckoAppShell::ShowAlertNotificationWrapper(aImageUrl, aAlertTitle, aAlertText, aAlertCookie, aAlertName); } int @@ -469,7 +479,7 @@ AndroidBridge::GetDPI() const int DEFAULT_DPI = 160; - sDPI = GetDpiWrapper(); + sDPI = GeckoAppShell::GetDpiWrapper(); if (!sDPI) { return DEFAULT_DPI; } @@ -488,7 +498,7 @@ AndroidBridge::GetScreenDepth() const int DEFAULT_DEPTH = 16; - sDepth = GetScreenDepthWrapper(); + sDepth = GeckoAppShell::GetScreenDepthWrapper(); if (!sDepth) return DEFAULT_DEPTH; @@ -502,7 +512,7 @@ AndroidBridge::ShowFilePickerForExtensions(nsAString& aFilePath, const nsAString if (!env) return; - jstring jstr = ShowFilePickerForExtensionsWrapper(aExtensions); + jstring jstr = GeckoAppShell::ShowFilePickerForExtensionsWrapper(aExtensions); if (jstr == nullptr) { return; } @@ -518,7 +528,7 @@ AndroidBridge::ShowFilePickerForMimeType(nsAString& aFilePath, const nsAString& if (!env) return; - jstring jstr = ShowFilePickerForMimeTypeWrapper(aMimeType); + jstring jstr = GeckoAppShell::ShowFilePickerForMimeTypeWrapper(aMimeType); if (jstr == nullptr) { return; } @@ -531,19 +541,7 @@ void AndroidBridge::ShowFilePickerAsync(const nsAString& aMimeType, nsFilePickerCallback* callback) { callback->AddRef(); - ShowFilePickerAsyncWrapper(aMimeType, (int64_t) callback); -} - -void -AndroidBridge::HideProgressDialogOnce() -{ - static bool once = false; - if (once) - return; - - HideProgressDialog(); - - once = true; + GeckoAppShell::ShowFilePickerAsyncWrapper(aMimeType, (int64_t) callback); } void @@ -571,7 +569,7 @@ AndroidBridge::Vibrate(const nsTArray& aPattern) ALOG_BRIDGE(" invalid vibration duration < 0"); return; } - Vibrate1(d); + GeckoAppShell::Vibrate1(d); return; } @@ -597,7 +595,7 @@ AndroidBridge::Vibrate(const nsTArray& aPattern) } env->ReleaseLongArrayElements(array, elts, 0); - VibrateA(array, -1/*don't repeat*/); + GeckoAppShell::VibrateA(array, -1/*don't repeat*/); } void @@ -614,7 +612,7 @@ AndroidBridge::GetSystemColors(AndroidSystemColors *aColors) AutoLocalJNIFrame jniFrame(env); - jintArray arr = GetSystemColoursWrapper(); + jintArray arr = GeckoAppShell::GetSystemColoursWrapper(); if (!arr) return; @@ -652,7 +650,7 @@ AndroidBridge::GetIconForExtension(const nsACString& aFileExt, uint32_t aIconSiz AutoLocalJNIFrame jniFrame(env); - jbyteArray arr = GetIconForExtensionWrapper(NS_ConvertUTF8toUTF16(aFileExt), aIconSize); + jbyteArray arr = GeckoAppShell::GetIconForExtensionWrapper(NS_ConvertUTF8toUTF16(aFileExt), aIconSize); NS_ASSERTION(arr != nullptr, "AndroidBridge::GetIconForExtension: Returned pixels array is null!"); if (!arr) @@ -680,14 +678,11 @@ AndroidBridge::SetLayerClient(JNIEnv* env, jobject jobj) if (resetting) { // clear out the old layer client - env->DeleteGlobalRef(mLayerClient->wrappedObject()); delete mLayerClient; mLayerClient = nullptr; } - AndroidGeckoLayerClient *client = new AndroidGeckoLayerClient(); - client->Init(env->NewGlobalRef(jobj)); - mLayerClient = client; + mLayerClient = GeckoLayerClient::Wrap(jobj); if (resetting) { // since we are re-linking the new java objects to Gecko, we need to get @@ -700,26 +695,17 @@ AndroidBridge::SetLayerClient(JNIEnv* env, jobject jobj) void AndroidBridge::RegisterCompositor(JNIEnv *env) { - ALOG_BRIDGE("AndroidBridge::RegisterCompositor"); - if (mGLControllerObj) { + if (mGLControllerObj != NULL && !mGLControllerObj->isNull()) { // we already have this set up, no need to do it again return; } - if (!env) { - env = GetJNIForThread(); // called on the compositor thread - } - if (!env) { - return; - } - - jobject glController = RegisterCompositorWrapper(); + jobject glController = LayerView::RegisterCompositorWrapper(); if (!glController) { return; } - mGLControllerObj = env->NewGlobalRef(glController); - env->DeleteLocalRef(glController); + mGLControllerObj = GLController::Wrap(glController); } EGLSurface @@ -735,7 +721,7 @@ AndroidBridge::CreateEGLSurfaceForCompositor() return nullptr; } - jobject eglSurface = CreateEGLSurfaceForCompositorWrapper(mGLControllerObj); + jobject eglSurface = mGLControllerObj->CreateEGLSurfaceForCompositorWrapper(); if (!eglSurface) return nullptr; @@ -807,11 +793,6 @@ mozilla_AndroidBridge_SetMainThread(pthread_t thr) return AndroidBridge::Bridge()->SetMainThread(thr); } -jclass GetGeckoAppShellClass() -{ - return mozilla::AndroidBridge::GetGeckoAppShellClass(); -} - void* AndroidBridge::GetNativeSurface(JNIEnv* env, jobject surface) { if (!env || !mHasNativeWindowFallback || !jSurfacePointerField) @@ -1008,7 +989,7 @@ AndroidBridge::InitCamera(const nsCString& contentType, uint32_t camera, uint32_ return false; AutoLocalJNIFrame jniFrame(env); - jintArray arr = InitCameraWrapper(NS_ConvertUTF8toUTF16(contentType), (int32_t) camera, (int32_t) width, (int32_t) height); + jintArray arr = GeckoAppShell::InitCameraWrapper(NS_ConvertUTF8toUTF16(contentType), (int32_t) camera, (int32_t) width, (int32_t) height); if (!arr) return false; @@ -1039,7 +1020,7 @@ AndroidBridge::GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInf // To prevent calling too many methods through JNI, the Java method returns // an array of double even if we actually want a double and a boolean. - jdoubleArray arr = GetCurrentBatteryInformationWrapper(); + jdoubleArray arr = GeckoAppShell::GetCurrentBatteryInformationWrapper(); if (!arr || env->GetArrayLength(arr) != 3) { return; } @@ -1063,7 +1044,7 @@ AndroidBridge::HandleGeckoMessage(const nsAString &aMessage, nsAString &aRet) return; AutoLocalJNIFrame jniFrame(env); - jstring returnMessage = HandleGeckoMessageWrapper(aMessage); + jstring returnMessage = GeckoAppShell::HandleGeckoMessageWrapper(aMessage); if (!returnMessage) return; @@ -1130,7 +1111,7 @@ AndroidBridge::SendMessage(const nsAString& aNumber, if (!QueueSmsRequest(aRequest, &requestId)) return; - SendMessageWrapper(aNumber, aMessage, requestId); + GeckoAppShell::SendMessageWrapper(aNumber, aMessage, requestId); } void @@ -1142,7 +1123,7 @@ AndroidBridge::GetMessage(int32_t aMessageId, nsIMobileMessageCallback* aRequest if (!QueueSmsRequest(aRequest, &requestId)) return; - GetMessageWrapper(aMessageId, requestId); + GeckoAppShell::GetMessageWrapper(aMessageId, requestId); } void @@ -1154,7 +1135,7 @@ AndroidBridge::DeleteMessage(int32_t aMessageId, nsIMobileMessageCallback* aRequ if (!QueueSmsRequest(aRequest, &requestId)) return; - DeleteMessageWrapper(aMessageId, requestId); + GeckoAppShell::DeleteMessageWrapper(aMessageId, requestId); } void @@ -1183,7 +1164,7 @@ AndroidBridge::CreateMessageList(const dom::mobilemessage::SmsFilterData& aFilte NewJavaString(&jniFrame, aFilter.numbers()[i])); } - CreateMessageListWrapper(aFilter.startDate(), aFilter.endDate(), + GeckoAppShell::CreateMessageListWrapper(aFilter.startDate(), aFilter.endDate(), numbers, aFilter.numbers().Length(), aFilter.delivery(), aReverse, requestId); } @@ -1197,7 +1178,7 @@ AndroidBridge::GetNextMessageInList(int32_t aListId, nsIMobileMessageCallback* a if (!QueueSmsRequest(aRequest, &requestId)) return; - GetNextMessageInListWrapper(aListId, requestId); + GeckoAppShell::GetNextMessageInListWrapper(aListId, requestId); } bool @@ -1249,7 +1230,7 @@ AndroidBridge::GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInf // To prevent calling too many methods through JNI, the Java method returns // an array of double even if we actually want a double, two booleans, and an integer. - jdoubleArray arr = GetCurrentNetworkInformationWrapper(); + jdoubleArray arr = GeckoAppShell::GetCurrentNetworkInformationWrapper(); if (!arr || env->GetArrayLength(arr) != 4) { return; } @@ -1442,7 +1423,7 @@ AndroidBridge::GetGlobalContextRef() { AutoLocalJNIFrame jniFrame(env, 4); - jobject context = GetContext(); + jobject context = GeckoAppShell::GetContext(); if (!context) { ALOG_BRIDGE("%s: Could not GetContext()", __FUNCTION__); return 0; @@ -1493,21 +1474,22 @@ AndroidBridge::UnlockWindow(void* window) void AndroidBridge::SetFirstPaintViewport(const LayerIntPoint& aOffset, const CSSToLayerScale& aZoom, const CSSRect& aCssPageRect) { - AndroidGeckoLayerClient *client = mLayerClient; + GeckoLayerClient *client = mLayerClient; if (!client) return; - client->SetFirstPaintViewport(aOffset, aZoom, aCssPageRect); + client->SetFirstPaintViewport((float)aOffset.x, (float)aOffset.y, aZoom.scale, + aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost()); } void AndroidBridge::SetPageRect(const CSSRect& aCssPageRect) { - AndroidGeckoLayerClient *client = mLayerClient; + GeckoLayerClient *client = mLayerClient; if (!client) return; - client->SetPageRect(aCssPageRect); + client->SetPageRect(aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost()); } void @@ -1515,26 +1497,68 @@ AndroidBridge::SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLay bool aLayersUpdated, ScreenPoint& aScrollOffset, CSSToScreenScale& aScale, LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset) { - AndroidGeckoLayerClient *client = mLayerClient; - if (!client) + GeckoLayerClient *client = mLayerClient; + if (!client) { + ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__); return; + } - client->SyncViewportInfo(aDisplayPort, aDisplayResolution, aLayersUpdated, - aScrollOffset, aScale, aFixedLayerMargins, - aOffset); + jobject viewTransformJObj = client->SyncViewportInfo(aDisplayPort.x, aDisplayPort.y, + aDisplayPort.width, aDisplayPort.height, + aDisplayResolution.scale, aLayersUpdated); + NS_ABORT_IF_FALSE(viewTransformJObj, "No view transform object!"); + + if (!viewTransformJObj) { + return; + } + + ViewTransform* viewTransform = ViewTransform::Wrap(viewTransformJObj); + aScrollOffset = ScreenPoint(viewTransform->getx(), viewTransform->gety()); + aScale.scale = viewTransform->getscale(); + aFixedLayerMargins.top = viewTransform->getfixedLayerMarginTop(); + aFixedLayerMargins.right = viewTransform->getfixedLayerMarginRight(); + aFixedLayerMargins.bottom = viewTransform->getfixedLayerMarginBottom(); + aFixedLayerMargins.left = viewTransform->getfixedLayerMarginLeft(); + aOffset.x = viewTransform->getoffsetX(); + aOffset.y = viewTransform->getoffsetY(); + delete viewTransform; } void AndroidBridge::SyncFrameMetrics(const ScreenPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect, bool aLayersUpdated, const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution, bool aIsFirstPaint, LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset) { - AndroidGeckoLayerClient *client = mLayerClient; - if (!client) + GeckoLayerClient *client = mLayerClient; + if (!client) { + ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__); return; + } - client->SyncFrameMetrics(aScrollOffset, aZoom, aCssPageRect, - aLayersUpdated, aDisplayPort, aDisplayResolution, - aIsFirstPaint, aFixedLayerMargins, aOffset); + // convert the displayport rect from scroll-relative CSS pixels to document-relative device pixels + LayerRect dpUnrounded = aDisplayPort * aDisplayResolution; + dpUnrounded += LayerPoint::FromUnknownPoint(aScrollOffset.ToUnknownPoint()); + LayerIntRect dp = gfx::RoundedToInt(dpUnrounded); + + jobject viewTransformJObj = client->SyncFrameMetrics(aScrollOffset.x, aScrollOffset.y, aZoom, + aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost(), + aLayersUpdated, dp.x, dp.y, dp.width, dp.height, aDisplayResolution.scale, + aIsFirstPaint); + + NS_ABORT_IF_FALSE(viewTransformJObj, "No view transform object!"); + if (!viewTransformJObj) { + return; + } + ViewTransform* viewTransform = ViewTransform::Wrap(viewTransformJObj); + + aFixedLayerMargins.top = viewTransform->getfixedLayerMarginTop(); + aFixedLayerMargins.right = viewTransform->getfixedLayerMarginRight(); + aFixedLayerMargins.bottom = viewTransform->getfixedLayerMarginBottom(); + aFixedLayerMargins.left = viewTransform->getfixedLayerMarginLeft(); + + aOffset.x = viewTransform->getoffsetX(); + aOffset.y = viewTransform->getoffsetY(); + + delete viewTransform; } AndroidBridge::AndroidBridge() @@ -1599,45 +1623,12 @@ JavaThreadDetachFunc(void *arg) vm->DetachCurrentThread(); } -extern "C" { - __attribute__ ((visibility("default"))) - JNIEnv * GetJNIForThread() - { - JNIEnv *jEnv = nullptr; - JavaVM *jVm = mozilla::AndroidBridge::GetVM(); - if (!jVm) { - __android_log_print(ANDROID_LOG_INFO, "GetJNIForThread", "Returned a null VM"); - return nullptr; - } - jEnv = static_cast(PR_GetThreadPrivate(sJavaEnvThreadIndex)); - - if (jEnv) - return jEnv; - - int status = jVm->GetEnv((void**) &jEnv, JNI_VERSION_1_2); - if (status) { - - status = jVm->AttachCurrentThread(&jEnv, nullptr); - if (status) { - __android_log_print(ANDROID_LOG_INFO, "GetJNIForThread", "Could not attach"); - return nullptr; - } - - PR_SetThreadPrivate(sJavaEnvThreadIndex, jEnv); - } - if (!jEnv) { - __android_log_print(ANDROID_LOG_INFO, "GetJNIForThread", "returning NULL"); - } - return jEnv; - } -} - uint32_t AndroidBridge::GetScreenOrientation() { ALOG_BRIDGE("AndroidBridge::GetScreenOrientation"); - int16_t orientation = GetScreenOrientationWrapper(); + int16_t orientation = GeckoAppShell::GetScreenOrientationWrapper(); if (!orientation) return dom::eScreenOrientation_None; @@ -1663,7 +1654,7 @@ AndroidBridge::GetProxyForURI(const nsACString & aSpec, return NS_ERROR_FAILURE; AutoLocalJNIFrame jniFrame(env); - jstring jstrRet = GetProxyForURIWrapper(NS_ConvertUTF8toUTF16(aSpec), + jstring jstrRet = GeckoAppShell::GetProxyForURIWrapper(NS_ConvertUTF8toUTF16(aSpec), NS_ConvertUTF8toUTF16(aScheme), NS_ConvertUTF8toUTF16(aHost), aPort); @@ -1699,7 +1690,7 @@ AndroidBridge::AddPluginView(jobject view, const LayoutDeviceRect& rect, bool is return; CSSRect cssRect = rect / win->GetDefaultScale(); - AddPluginViewWrapper(view, cssRect.x, cssRect.y, cssRect.width, cssRect.height, isFullScreen); + GeckoAppShell::AddPluginViewWrapper(view, cssRect.x, cssRect.y, cssRect.width, cssRect.height, isFullScreen); } extern "C" @@ -1716,7 +1707,7 @@ AndroidBridge::GetThreadNameJavaProfiling(uint32_t aThreadId, nsCString & aResul AutoLocalJNIFrame jniFrame(env); - jstring jstrThreadName = GetThreadNameJavaProfilingWrapper(aThreadId); + jstring jstrThreadName = GeckoJavaSampler::GetThreadNameJavaProfilingWrapper(aThreadId); if (!jstrThreadName) return false; @@ -1736,7 +1727,7 @@ AndroidBridge::GetFrameNameJavaProfiling(uint32_t aThreadId, uint32_t aSampleId, AutoLocalJNIFrame jniFrame(env); - jstring jstrSampleName = GetFrameNameJavaProfilingWrapper(aThreadId, aSampleId, aFrameId); + jstring jstrSampleName = GeckoJavaSampler::GetFrameNameJavaProfilingWrapper(aThreadId, aSampleId, aFrameId); if (!jstrSampleName) return false; @@ -1857,21 +1848,72 @@ nsresult AndroidBridge::CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int void AndroidBridge::GetDisplayPort(bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort) { + + ALOG_BRIDGE("Enter: %s", __PRETTY_FUNCTION__); JNIEnv* env = GetJNIEnv(); - if (!env || !mLayerClient) + if (!env || !mLayerClient || mLayerClient->isNull()) { + + ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__); return; + } AutoLocalJNIFrame jniFrame(env, 0); - mLayerClient->GetDisplayPort(&jniFrame, aPageSizeUpdate, aIsBrowserContentDisplayed, tabId, metrics, displayPort); + + float x, y, width, height, + pageLeft, pageTop, pageRight, pageBottom, + cssPageLeft, cssPageTop, cssPageRight, cssPageBottom, + zoom; + metrics->GetX(&x); + metrics->GetY(&y); + metrics->GetWidth(&width); + metrics->GetHeight(&height); + metrics->GetPageLeft(&pageLeft); + metrics->GetPageTop(&pageTop); + metrics->GetPageRight(&pageRight); + metrics->GetPageBottom(&pageBottom); + metrics->GetCssPageLeft(&cssPageLeft); + metrics->GetCssPageTop(&cssPageTop); + metrics->GetCssPageRight(&cssPageRight); + metrics->GetCssPageBottom(&cssPageBottom); + metrics->GetZoom(&zoom); + + ImmutableViewportMetrics jmetrics = ImmutableViewportMetrics(pageLeft, pageTop, pageRight, pageBottom, + cssPageLeft, cssPageTop, cssPageRight, cssPageBottom, + x, y, x + width, y + height, + zoom); + + jobject jobj = mLayerClient->GetDisplayPort(aPageSizeUpdate, aIsBrowserContentDisplayed, tabId, jmetrics.wrappedObject()); + if (!jobj) { + ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__); + return; + } + DisplayPortMetrics* displayPortMetrics = DisplayPortMetrics::Wrap(jobj); + + AndroidRectF rect(env, displayPortMetrics->getMPosition()); + if (jniFrame.CheckForException()) { + ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__); + return; + } + + float resolution = displayPortMetrics->getResolution(); + if (jniFrame.CheckForException()) { + ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__); + return; + } + + *displayPort = new nsAndroidDisplayport(rect, resolution); + (*displayPort)->AddRef(); + + delete displayPortMetrics; + ALOG_BRIDGE("Exit: %s", __PRETTY_FUNCTION__); } void AndroidBridge::ContentDocumentChanged() { - JNIEnv* env = GetJNIEnv(); - if (!env || !mLayerClient) + if (!mLayerClient) { return; - AutoLocalJNIFrame jniFrame(env, 0); - mLayerClient->ContentDocumentChanged(&jniFrame); + } + mLayerClient->ContentDocumentChanged(); } bool @@ -1880,25 +1922,48 @@ AndroidBridge::IsContentDocumentDisplayed() JNIEnv* env = GetJNIEnv(); if (!env || !mLayerClient) return false; - AutoLocalJNIFrame jniFrame(env, 0); - return mLayerClient->IsContentDocumentDisplayed(&jniFrame); + + return mLayerClient->IsContentDocumentDisplayed(); } bool AndroidBridge::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const LayerRect& aDisplayPort, float aDisplayResolution, bool aDrawingCritical, gfx::Rect& aViewport, float& aScaleX, float& aScaleY) { - AndroidGeckoLayerClient *client = mLayerClient; - if (!client) + GeckoLayerClient *client = mLayerClient; + if (!client) { + ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__); return false; + } - return client->ProgressiveUpdateCallback(aHasPendingNewThebesContent, aDisplayPort, aDisplayResolution, aDrawingCritical, aViewport, aScaleX, aScaleY); + jobject progressiveUpdateDataJObj = client->ProgressiveUpdateCallback(aHasPendingNewThebesContent, + (float)aDisplayPort.x, + (float)aDisplayPort.y, + (float)aDisplayPort.width, + (float)aDisplayPort.height, + aDisplayResolution, + !aDrawingCritical); + + NS_ABORT_IF_FALSE(progressiveUpdateDataJObj, "No progressive update data!"); + + ProgressiveUpdateData* progressiveUpdateData = ProgressiveUpdateData::Wrap(progressiveUpdateDataJObj); + + aViewport.x = progressiveUpdateData->getx(); + aViewport.y = progressiveUpdateData->gety(); + aViewport.width = progressiveUpdateData->getwidth(); + aViewport.height = progressiveUpdateData->getheight(); + aScaleX = aScaleY = progressiveUpdateData->getscale(); + + bool ret = progressiveUpdateData->getabort(); + delete progressiveUpdateData; + + return ret; } -jobject +NativePanZoomController* AndroidBridge::SetNativePanZoomController(jobject obj) { - jobject old = mNativePanZoomController; - mNativePanZoomController = obj; + NativePanZoomController* old = mNativePanZoomController; + mNativePanZoomController = NativePanZoomController::Wrap(obj); return old; } @@ -1910,8 +1975,7 @@ AndroidBridge::RequestContentRepaint(const mozilla::layers::FrameMetrics& aFrame CSSToScreenScale resolution = aFrameMetrics.mZoom; ScreenRect dp = (aFrameMetrics.mDisplayPort + aFrameMetrics.mScrollOffset) * resolution; - RequestContentRepaintWrapper(mNativePanZoomController, - dp.x, dp.y, dp.width, dp.height, resolution.scale); + mNativePanZoomController->RequestContentRepaintWrapper(dp.x, dp.y, dp.width, dp.height, resolution.scale); } void @@ -1968,7 +2032,7 @@ AndroidBridge::PostDelayedTask(Task* aTask, int aDelayMs) // if we're inserting it at the head of the queue, notify Java because // we need to get a callback at an earlier time than the last scheduled // callback - PostDelayedCallbackWrapper(mNativePanZoomController, (int64_t)aDelayMs); + mNativePanZoomController->PostDelayedCallbackWrapper((int64_t)aDelayMs); } } diff --git a/widget/android/AndroidBridge.h b/widget/android/AndroidBridge.h index 7136afcf88a5..1f9bc9b70c96 100644 --- a/widget/android/AndroidBridge.h +++ b/widget/android/AndroidBridge.h @@ -14,7 +14,7 @@ #include "nsCOMPtr.h" #include "nsCOMArray.h" -#include "AndroidJavaWrappers.h" +#include "GeneratedJNIWrappers.h" #include "nsIMutableArray.h" #include "nsIMIMEInfo.h" @@ -41,7 +41,6 @@ class nsIObserver; extern "C" JNIEnv * GetJNIForThread(); extern bool mozilla_AndroidBridge_SetMainThread(pthread_t); -extern jclass GetGeckoAppShellClass(); namespace base { class Thread; @@ -49,6 +48,8 @@ class Thread; typedef void* EGLSurface; +using namespace mozilla::widget::android; + namespace mozilla { namespace hal { @@ -160,10 +161,6 @@ public: return nullptr; } - static jclass GetGeckoAppShellClass() { - return sBridge->mGeckoAppShellClass; - } - // The bridge needs to be constructed via ConstructBridge first, // and then once the Gecko main thread is spun up (Gecko side), // SetMainThread should be called which will create the JNIEnv for @@ -183,7 +180,7 @@ public: bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const LayerRect& aDisplayPort, float aDisplayResolution, bool aDrawingCritical, gfx::Rect& aViewport, float& aScaleX, float& aScaleY); void SetLayerClient(JNIEnv* env, jobject jobj); - AndroidGeckoLayerClient &GetLayerClient() { return *mLayerClient; } + GeckoLayerClient* GetLayerClient() { return mLayerClient; } bool GetHandlersForURL(const nsAString& aURL, nsIMutableArray* handlersArray = nullptr, @@ -199,10 +196,6 @@ public: void GetExtensionFromMimeType(const nsACString& aMimeType, nsACString& aFileExt); bool GetClipboardText(nsAString& aText); - - void EmptyClipboard(); - - bool ClipboardHasText(); void ShowAlertNotification(const nsAString& aImageUrl, const nsAString& aAlertTitle, @@ -220,8 +213,6 @@ public: void Vibrate(const nsTArray& aPattern); - void HideProgressDialogOnce(); - void GetSystemColors(AndroidSystemColors *aColors); void GetIconForExtension(const nsACString& aFileExt, uint32_t aIconSize, uint8_t * const aBuf); @@ -340,7 +331,7 @@ protected: JNIEnv *mJNIEnv; pthread_t mThread; - AndroidGeckoLayerClient *mLayerClient; + GeckoLayerClient *mLayerClient = NULL; // the android.telephony.SmsMessage class jclass mAndroidSmsMessageClass; @@ -381,7 +372,7 @@ protected: jclass jLayerView; jfieldID jEGLSurfacePointerField; - jobject mGLControllerObj; + GLController *mGLControllerObj; // some convinient types to have around jclass jStringClass; @@ -405,15 +396,14 @@ protected: void (* Region_set)(void* region, void* rect); private: - jobject mNativePanZoomController; + NativePanZoomController* mNativePanZoomController; // This will always be accessed from one thread (the APZC "controller" // thread, which is the Java UI thread), so we don't need to do locking // to touch it nsTArray mDelayedTaskQueue; public: - #include "GeneratedJNIWrappers.h" - jobject SetNativePanZoomController(jobject obj); + NativePanZoomController* SetNativePanZoomController(jobject obj); // GeckoContentController methods void RequestContentRepaint(const mozilla::layers::FrameMetrics& aFrameMetrics) MOZ_OVERRIDE; void HandleDoubleTap(const CSSIntPoint& aPoint) MOZ_OVERRIDE; diff --git a/widget/android/AndroidBridgeUtilities.h b/widget/android/AndroidBridgeUtilities.h index 6a3fc4cee3ab..88ddc40ff1c4 100644 --- a/widget/android/AndroidBridgeUtilities.h +++ b/widget/android/AndroidBridgeUtilities.h @@ -17,3 +17,17 @@ #define getStaticMethod(fname, ftype) \ AndroidBridge::GetStaticMethodID(jEnv, jClass, fname, ftype) + +#ifndef ALOG +#if defined(DEBUG) || defined(FORCE_ALOG) +#define ALOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gecko" , ## args) +#else +#define ALOG(args...) ((void)0) +#endif +#endif + +#ifdef DEBUG +#define ALOG_BRIDGE(args...) ALOG(args) +#else +#define ALOG_BRIDGE(args...) ((void)0) +#endif diff --git a/widget/android/AndroidJNI.cpp b/widget/android/AndroidJNI.cpp index bf0cf0a9e750..70ccd708e5b5 100644 --- a/widget/android/AndroidJNI.cpp +++ b/widget/android/AndroidJNI.cpp @@ -862,10 +862,10 @@ Java_org_mozilla_gecko_gfx_NativePanZoomController_init(JNIEnv* env, jobject ins return; } - jobject oldRef = AndroidBridge::Bridge()->SetNativePanZoomController(env->NewGlobalRef(instance)); - if (oldRef) { + NativePanZoomController* oldRef = AndroidBridge::Bridge()->SetNativePanZoomController(instance); + if (oldRef && !oldRef->isNull()) { MOZ_ASSERT(false, "Registering a new NPZC when we already have one"); - env->DeleteGlobalRef(oldRef); + delete oldRef; } } @@ -906,11 +906,11 @@ Java_org_mozilla_gecko_gfx_NativePanZoomController_destroy(JNIEnv* env, jobject return; } - jobject oldRef = AndroidBridge::Bridge()->SetNativePanZoomController(nullptr); - if (!oldRef) { + NativePanZoomController* oldRef = AndroidBridge::Bridge()->SetNativePanZoomController(NULL); + if (!oldRef || oldRef->isNull()) { MOZ_ASSERT(false, "Clearing a non-existent NPZC"); } else { - env->DeleteGlobalRef(oldRef); + delete oldRef; } } diff --git a/widget/android/AndroidJNIWrapper.cpp b/widget/android/AndroidJNIWrapper.cpp index b0398cee10c4..9c9c825bb651 100644 --- a/widget/android/AndroidJNIWrapper.cpp +++ b/widget/android/AndroidJNIWrapper.cpp @@ -14,12 +14,6 @@ #include "nsThreadUtils.h" #include "AndroidBridge.h" -#ifdef DEBUG -#define ALOG_BRIDGE(args...) ALOG(args) -#else -#define ALOG_BRIDGE(args...) -#endif - extern "C" { jclass __jsjni_GetGlobalClassRef(const char *className); } diff --git a/widget/android/AndroidJavaWrappers.cpp b/widget/android/AndroidJavaWrappers.cpp index 3a25845750f4..9ae62d93e53d 100644 --- a/widget/android/AndroidJavaWrappers.cpp +++ b/widget/android/AndroidJavaWrappers.cpp @@ -6,13 +6,13 @@ #include "AndroidJavaWrappers.h" #include "AndroidBridge.h" #include "AndroidBridgeUtilities.h" -#include "nsIAndroidBridge.h" #include "nsIDOMKeyEvent.h" #include "nsIWidget.h" #include "mozilla/TouchEvents.h" using namespace mozilla; using namespace mozilla::dom; +using namespace mozilla::widget::android; jclass AndroidGeckoEvent::jGeckoEventClass = 0; jfieldID AndroidGeckoEvent::jActionField = 0; @@ -91,49 +91,12 @@ jmethodID AndroidLocation::jGetBearingMethod = 0; jmethodID AndroidLocation::jGetSpeedMethod = 0; jmethodID AndroidLocation::jGetTimeMethod = 0; -jclass AndroidGeckoLayerClient::jGeckoLayerClientClass = 0; -jclass AndroidGeckoLayerClient::jViewportClass = 0; -jclass AndroidGeckoLayerClient::jDisplayportClass = 0; -jmethodID AndroidGeckoLayerClient::jSetFirstPaintViewport = 0; -jmethodID AndroidGeckoLayerClient::jSetPageRect = 0; -jmethodID AndroidGeckoLayerClient::jSyncViewportInfoMethod = 0; -jmethodID AndroidGeckoLayerClient::jSyncFrameMetricsMethod = 0; -jmethodID AndroidGeckoLayerClient::jCreateFrameMethod = 0; -jmethodID AndroidGeckoLayerClient::jActivateProgramMethod = 0; -jmethodID AndroidGeckoLayerClient::jDeactivateProgramMethod = 0; -jmethodID AndroidGeckoLayerClient::jGetDisplayPort = 0; -jmethodID AndroidGeckoLayerClient::jContentDocumentChanged = 0; -jmethodID AndroidGeckoLayerClient::jIsContentDocumentDisplayed = 0; -jmethodID AndroidGeckoLayerClient::jViewportCtor = 0; -jfieldID AndroidGeckoLayerClient::jDisplayportPosition = 0; -jfieldID AndroidGeckoLayerClient::jDisplayportResolution = 0; -jmethodID AndroidGeckoLayerClient::jProgressiveUpdateCallbackMethod = 0; - jclass AndroidLayerRendererFrame::jLayerRendererFrameClass = 0; jmethodID AndroidLayerRendererFrame::jBeginDrawingMethod = 0; jmethodID AndroidLayerRendererFrame::jDrawBackgroundMethod = 0; jmethodID AndroidLayerRendererFrame::jDrawForegroundMethod = 0; jmethodID AndroidLayerRendererFrame::jEndDrawingMethod = 0; -jclass AndroidViewTransform::jViewTransformClass = 0; -jfieldID AndroidViewTransform::jXField = 0; -jfieldID AndroidViewTransform::jYField = 0; -jfieldID AndroidViewTransform::jScaleField = 0; -jfieldID AndroidViewTransform::jFixedLayerMarginLeft = 0; -jfieldID AndroidViewTransform::jFixedLayerMarginTop = 0; -jfieldID AndroidViewTransform::jFixedLayerMarginRight = 0; -jfieldID AndroidViewTransform::jFixedLayerMarginBottom = 0; -jfieldID AndroidViewTransform::jOffsetXField = 0; -jfieldID AndroidViewTransform::jOffsetYField = 0; - -jclass AndroidProgressiveUpdateData::jProgressiveUpdateDataClass = 0; -jfieldID AndroidProgressiveUpdateData::jXField = 0; -jfieldID AndroidProgressiveUpdateData::jYField = 0; -jfieldID AndroidProgressiveUpdateData::jWidthField = 0; -jfieldID AndroidProgressiveUpdateData::jHeightField = 0; -jfieldID AndroidProgressiveUpdateData::jScaleField = 0; -jfieldID AndroidProgressiveUpdateData::jShouldAbortField = 0; - RefCountedJavaObject::~RefCountedJavaObject() { if (mObject) GetJNIForThread()->DeleteGlobalRef(mObject); @@ -148,10 +111,8 @@ mozilla::InitAndroidJavaWrappers(JNIEnv *jEnv) AndroidLocation::InitLocationClass(jEnv); AndroidRect::InitRectClass(jEnv); AndroidRectF::InitRectFClass(jEnv); - AndroidGeckoLayerClient::InitGeckoLayerClientClass(jEnv); AndroidLayerRendererFrame::InitLayerRendererFrameClass(jEnv); - AndroidViewTransform::InitViewTransformClass(jEnv); - AndroidProgressiveUpdateData::InitProgressiveUpdateDataClass(jEnv); + InitStubs(jEnv); } void @@ -290,36 +251,6 @@ AndroidRectF::InitRectFClass(JNIEnv *jEnv) jRightField = getField("right", "F"); } -void -AndroidGeckoLayerClient::InitGeckoLayerClientClass(JNIEnv *jEnv) -{ - initInit(); - - jGeckoLayerClientClass = getClassGlobalRef("org/mozilla/gecko/gfx/GeckoLayerClient"); - - jProgressiveUpdateCallbackMethod = getMethod("progressiveUpdateCallback", - "(ZFFFFFZ)Lorg/mozilla/gecko/gfx/ProgressiveUpdateData;"); - jSetFirstPaintViewport = getMethod("setFirstPaintViewport", "(FFFFFFF)V"); - jSetPageRect = getMethod("setPageRect", "(FFFF)V"); - jSyncViewportInfoMethod = getMethod("syncViewportInfo", - "(IIIIFZ)Lorg/mozilla/gecko/gfx/ViewTransform;"); - jSyncFrameMetricsMethod = getMethod("syncFrameMetrics", - "(FFFFFFFZIIIIFZ)Lorg/mozilla/gecko/gfx/ViewTransform;"); - jCreateFrameMethod = getMethod("createFrame", "()Lorg/mozilla/gecko/gfx/LayerRenderer$Frame;"); - jActivateProgramMethod = getMethod("activateProgram", "()V"); - jDeactivateProgramMethod = getMethod("deactivateProgram", "()V"); - jGetDisplayPort = getMethod("getDisplayPort", "(ZZILorg/mozilla/gecko/gfx/ImmutableViewportMetrics;)Lorg/mozilla/gecko/gfx/DisplayPortMetrics;"); - jContentDocumentChanged = getMethod("contentDocumentChanged", "()V"); - jIsContentDocumentDisplayed = getMethod("isContentDocumentDisplayed", "()Z"); - - jViewportClass = getClassGlobalRef("org/mozilla/gecko/gfx/ImmutableViewportMetrics"); - jViewportCtor = getMethod("", "(FFFFFFFFFFFFF)V"); - - jDisplayportClass = getClassGlobalRef("org/mozilla/gecko/gfx/DisplayPortMetrics"); - jDisplayportPosition = getField("mPosition", "Landroid/graphics/RectF;"); - jDisplayportResolution = getField("resolution", "F"); -} - void AndroidLayerRendererFrame::InitLayerRendererFrameClass(JNIEnv *jEnv) { @@ -333,39 +264,6 @@ AndroidLayerRendererFrame::InitLayerRendererFrameClass(JNIEnv *jEnv) jEndDrawingMethod = getMethod("endDrawing", "()V"); } -void -AndroidViewTransform::InitViewTransformClass(JNIEnv *jEnv) -{ - initInit(); - - jViewTransformClass = getClassGlobalRef("org/mozilla/gecko/gfx/ViewTransform"); - - jXField = getField("x", "F"); - jYField = getField("y", "F"); - jScaleField = getField("scale", "F"); - jFixedLayerMarginLeft = getField("fixedLayerMarginLeft", "F"); - jFixedLayerMarginTop = getField("fixedLayerMarginTop", "F"); - jFixedLayerMarginRight = getField("fixedLayerMarginRight", "F"); - jFixedLayerMarginBottom = getField("fixedLayerMarginBottom", "F"); - jOffsetXField = getField("offsetX", "F"); - jOffsetYField = getField("offsetY", "F"); -} - -void -AndroidProgressiveUpdateData::InitProgressiveUpdateDataClass(JNIEnv *jEnv) -{ - initInit(); - - jProgressiveUpdateDataClass = getClassGlobalRef("org/mozilla/gecko/gfx/ProgressiveUpdateData"); - - jXField = getField("x", "F"); - jYField = getField("y", "F"); - jWidthField = getField("width", "F"); - jHeightField = getField("height", "F"); - jScaleField = getField("scale", "F"); - jShouldAbortField = getField("abort", "Z"); -} - #undef initInit #undef initClassGlobalRef #undef getField @@ -892,13 +790,6 @@ AndroidPoint::Init(JNIEnv *jenv, jobject jobj) } } -void -AndroidGeckoLayerClient::Init(jobject jobj) -{ - NS_ASSERTION(wrapped_obj == nullptr, "Init called on non-null wrapped_obj!"); - wrapped_obj = jobj; -} - void AndroidLayerRendererFrame::Init(JNIEnv *env, jobject jobj) { @@ -920,281 +811,8 @@ AndroidLayerRendererFrame::Dispose(JNIEnv *env) wrapped_obj = 0; } -void -AndroidViewTransform::Init(jobject jobj) -{ - NS_ABORT_IF_FALSE(wrapped_obj == nullptr, "Init called on non-null wrapped_obj!"); - wrapped_obj = jobj; -} - -void -AndroidProgressiveUpdateData::Init(jobject jobj) -{ - NS_ABORT_IF_FALSE(wrapped_obj == nullptr, "Init called on non-null wrapped_obj!"); - wrapped_obj = jobj; -} - -void -AndroidGeckoLayerClient::SetFirstPaintViewport(const LayerIntPoint& aOffset, const CSSToLayerScale& aZoom, const CSSRect& aCssPageRect) -{ - NS_ASSERTION(!isNull(), "SetFirstPaintViewport called on null layer client!"); - JNIEnv *env = GetJNIForThread(); // this is called on the compositor thread - if (!env) - return; - - AutoLocalJNIFrame jniFrame(env, 0); - return env->CallVoidMethod(wrapped_obj, jSetFirstPaintViewport, (float)aOffset.x, (float)aOffset.y, aZoom.scale, - aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost()); -} - -void -AndroidGeckoLayerClient::SetPageRect(const CSSRect& aCssPageRect) -{ - NS_ASSERTION(!isNull(), "SetPageRect called on null layer client!"); - JNIEnv *env = GetJNIForThread(); // this is called on the compositor thread - if (!env) - return; - - AutoLocalJNIFrame jniFrame(env, 0); - return env->CallVoidMethod(wrapped_obj, jSetPageRect, - aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost()); -} - -void -AndroidGeckoLayerClient::SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution, - bool aLayersUpdated, ScreenPoint& aScrollOffset, CSSToScreenScale& aScale, - LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset) -{ - NS_ASSERTION(!isNull(), "SyncViewportInfo called on null layer client!"); - JNIEnv *env = GetJNIForThread(); // this is called on the compositor thread - if (!env) - return; - - AutoLocalJNIFrame jniFrame(env); - - jobject viewTransformJObj = env->CallObjectMethod(wrapped_obj, jSyncViewportInfoMethod, - aDisplayPort.x, aDisplayPort.y, - aDisplayPort.width, aDisplayPort.height, - aDisplayResolution.scale, aLayersUpdated); - if (jniFrame.CheckForException()) - return; - - NS_ABORT_IF_FALSE(viewTransformJObj, "No view transform object!"); - - AndroidViewTransform viewTransform; - viewTransform.Init(viewTransformJObj); - - aScrollOffset = ScreenPoint(viewTransform.GetX(env), viewTransform.GetY(env)); - aScale.scale = viewTransform.GetScale(env); - viewTransform.GetFixedLayerMargins(env, aFixedLayerMargins); - - aOffset.x = viewTransform.GetOffsetX(env); - aOffset.y = viewTransform.GetOffsetY(env); -} - -void -AndroidGeckoLayerClient::SyncFrameMetrics(const ScreenPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect, - bool aLayersUpdated, const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution, - bool aIsFirstPaint, LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset) -{ - NS_ASSERTION(!isNull(), "SyncFrameMetrics called on null layer client!"); - JNIEnv *env = GetJNIForThread(); // this is called on the compositor thread - if (!env) - return; - - AutoLocalJNIFrame jniFrame(env); - - // convert the displayport rect from scroll-relative CSS pixels to document-relative device pixels - LayerRect dpUnrounded = aDisplayPort * aDisplayResolution; - dpUnrounded += LayerPoint::FromUnknownPoint(aScrollOffset.ToUnknownPoint()); - LayerIntRect dp = gfx::RoundedToInt(dpUnrounded); - - jobject viewTransformJObj = env->CallObjectMethod(wrapped_obj, jSyncFrameMetricsMethod, - aScrollOffset.x, aScrollOffset.y, aZoom, - aCssPageRect.x, aCssPageRect.y, aCssPageRect.XMost(), aCssPageRect.YMost(), - aLayersUpdated, dp.x, dp.y, dp.width, dp.height, aDisplayResolution.scale, - aIsFirstPaint); - - if (jniFrame.CheckForException()) - return; - - NS_ABORT_IF_FALSE(viewTransformJObj, "No view transform object!"); - - AndroidViewTransform viewTransform; - viewTransform.Init(viewTransformJObj); - viewTransform.GetFixedLayerMargins(env, aFixedLayerMargins); - aOffset.x = viewTransform.GetOffsetX(env); - aOffset.y = viewTransform.GetOffsetY(env); -} - -bool -AndroidGeckoLayerClient::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, - const LayerRect& aDisplayPort, - float aDisplayResolution, - bool aDrawingCritical, - gfx::Rect& aViewport, - float& aScaleX, - float& aScaleY) -{ - JNIEnv *env = AndroidBridge::GetJNIEnv(); - if (!env) - return false; - - AutoJObject progressiveUpdateDataJObj(env, env->CallObjectMethod(wrapped_obj, - jProgressiveUpdateCallbackMethod, - aHasPendingNewThebesContent, - (float)aDisplayPort.x, - (float)aDisplayPort.y, - (float)aDisplayPort.width, - (float)aDisplayPort.height, - aDisplayResolution, - !aDrawingCritical)); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - env->ExceptionClear(); - return false; - } - - NS_ABORT_IF_FALSE(progressiveUpdateDataJObj, "No progressive update data!"); - - AndroidProgressiveUpdateData progressiveUpdateData(progressiveUpdateDataJObj); - - aViewport.x = progressiveUpdateData.GetX(env); - aViewport.y = progressiveUpdateData.GetY(env); - aViewport.width = progressiveUpdateData.GetWidth(env); - aViewport.height = progressiveUpdateData.GetHeight(env); - aScaleX = aScaleY = progressiveUpdateData.GetScale(env); - - return progressiveUpdateData.GetShouldAbort(env); -} - -jobject ConvertToJavaViewportMetrics(JNIEnv* env, nsIAndroidViewport* metrics) { - float x, y, width, height, - pageLeft, pageTop, pageRight, pageBottom, - cssPageLeft, cssPageTop, cssPageRight, cssPageBottom, - zoom; - metrics->GetX(&x); - metrics->GetY(&y); - metrics->GetWidth(&width); - metrics->GetHeight(&height); - metrics->GetPageLeft(&pageLeft); - metrics->GetPageTop(&pageTop); - metrics->GetPageRight(&pageRight); - metrics->GetPageBottom(&pageBottom); - metrics->GetCssPageLeft(&cssPageLeft); - metrics->GetCssPageTop(&cssPageTop); - metrics->GetCssPageRight(&cssPageRight); - metrics->GetCssPageBottom(&cssPageBottom); - metrics->GetZoom(&zoom); - - jobject jobj = env->NewObject(AndroidGeckoLayerClient::jViewportClass, AndroidGeckoLayerClient::jViewportCtor, - pageLeft, pageTop, pageRight, pageBottom, - cssPageLeft, cssPageTop, cssPageRight, cssPageBottom, - x, y, x + width, y + height, - zoom); - return jobj; -} - -class nsAndroidDisplayport MOZ_FINAL : public nsIAndroidDisplayport -{ -public: - NS_DECL_ISUPPORTS - virtual nsresult GetLeft(float *aLeft) { *aLeft = mLeft; return NS_OK; } - virtual nsresult GetTop(float *aTop) { *aTop = mTop; return NS_OK; } - virtual nsresult GetRight(float *aRight) { *aRight = mRight; return NS_OK; } - virtual nsresult GetBottom(float *aBottom) { *aBottom = mBottom; return NS_OK; } - virtual nsresult GetResolution(float *aResolution) { *aResolution = mResolution; return NS_OK; } - virtual nsresult SetLeft(float aLeft) { mLeft = aLeft; return NS_OK; } - virtual nsresult SetTop(float aTop) { mTop = aTop; return NS_OK; } - virtual nsresult SetRight(float aRight) { mRight = aRight; return NS_OK; } - virtual nsresult SetBottom(float aBottom) { mBottom = aBottom; return NS_OK; } - virtual nsresult SetResolution(float aResolution) { mResolution = aResolution; return NS_OK; } - - nsAndroidDisplayport(AndroidRectF aRect, float aResolution): - mLeft(aRect.Left()), mTop(aRect.Top()), mRight(aRect.Right()), mBottom(aRect.Bottom()), mResolution(aResolution) {} - -private: - ~nsAndroidDisplayport() {} - float mLeft, mTop, mRight, mBottom, mResolution; -}; - NS_IMPL_ISUPPORTS1(nsAndroidDisplayport, nsIAndroidDisplayport) -void createDisplayPort(AutoLocalJNIFrame *jniFrame, jobject jobj, nsIAndroidDisplayport** displayPort) { - JNIEnv* env = jniFrame->GetEnv(); - AndroidRectF rect(env, env->GetObjectField(jobj, AndroidGeckoLayerClient::jDisplayportPosition)); - if (jniFrame->CheckForException()) return; - float resolution = env->GetFloatField(jobj, AndroidGeckoLayerClient::jDisplayportResolution); - if (jniFrame->CheckForException()) return; - *displayPort = new nsAndroidDisplayport(rect, resolution); -} - -void -AndroidGeckoLayerClient::GetDisplayPort(AutoLocalJNIFrame *jniFrame, bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort) -{ - jobject jmetrics = ConvertToJavaViewportMetrics(jniFrame->GetEnv(), metrics); - if (jniFrame->CheckForException()) return; - if (!jmetrics) - return; - jobject jobj = jniFrame->GetEnv()->CallObjectMethod(wrapped_obj, jGetDisplayPort, aPageSizeUpdate, aIsBrowserContentDisplayed, tabId, jmetrics); - if (jniFrame->CheckForException()) return; - createDisplayPort(jniFrame, jobj, displayPort); - (*displayPort)->AddRef(); -} - -void -AndroidGeckoLayerClient::ContentDocumentChanged(AutoLocalJNIFrame *jniFrame) -{ - jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jContentDocumentChanged); -} - -bool -AndroidGeckoLayerClient::IsContentDocumentDisplayed(AutoLocalJNIFrame *jniFrame) -{ - return jniFrame->GetEnv()->CallBooleanMethod(wrapped_obj, jIsContentDocumentDisplayed); -} - -bool -AndroidGeckoLayerClient::CreateFrame(AutoLocalJNIFrame *jniFrame, AndroidLayerRendererFrame& aFrame) -{ - if (!jniFrame || !jniFrame->GetEnv()) - return false; - - jobject frameJObj = jniFrame->GetEnv()->CallObjectMethod(wrapped_obj, jCreateFrameMethod); - if (jniFrame->CheckForException()) - return false; - NS_ABORT_IF_FALSE(frameJObj, "No frame object!"); - - aFrame.Init(jniFrame->GetEnv(), frameJObj); - return true; -} - -bool -AndroidGeckoLayerClient::ActivateProgram(AutoLocalJNIFrame *jniFrame) -{ - if (!jniFrame || !jniFrame->GetEnv()) - return false; - - jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jActivateProgramMethod); - if (jniFrame->CheckForException()) - return false; - - return true; -} - -bool -AndroidGeckoLayerClient::DeactivateProgram(AutoLocalJNIFrame *jniFrame) -{ - if (!jniFrame || !jniFrame->GetEnv()) - return false; - - jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jDeactivateProgramMethod); - if (jniFrame->CheckForException()) - return false; - - return true; -} - bool AndroidLayerRendererFrame::BeginDrawing(AutoLocalJNIFrame *jniFrame) { @@ -1247,106 +865,6 @@ AndroidLayerRendererFrame::EndDrawing(AutoLocalJNIFrame *jniFrame) return true; } -float -AndroidViewTransform::GetX(JNIEnv *env) -{ - if (!env) - return 0.0f; - return env->GetFloatField(wrapped_obj, jXField); -} - -float -AndroidViewTransform::GetY(JNIEnv *env) -{ - if (!env) - return 0.0f; - return env->GetFloatField(wrapped_obj, jYField); -} - -float -AndroidViewTransform::GetScale(JNIEnv *env) -{ - if (!env) - return 0.0f; - return env->GetFloatField(wrapped_obj, jScaleField); -} - -void -AndroidViewTransform::GetFixedLayerMargins(JNIEnv *env, LayerMargin &aFixedLayerMargins) -{ - if (!env) - return; - - aFixedLayerMargins.top = env->GetFloatField(wrapped_obj, jFixedLayerMarginTop); - aFixedLayerMargins.right = env->GetFloatField(wrapped_obj, jFixedLayerMarginRight); - aFixedLayerMargins.bottom = env->GetFloatField(wrapped_obj, jFixedLayerMarginBottom); - aFixedLayerMargins.left = env->GetFloatField(wrapped_obj, jFixedLayerMarginLeft); -} - -float -AndroidViewTransform::GetOffsetX(JNIEnv *env) -{ - if (!env) - return 0.0f; - return env->GetFloatField(wrapped_obj, jOffsetXField); -} - -float -AndroidViewTransform::GetOffsetY(JNIEnv *env) -{ - if (!env) - return 0.0f; - return env->GetFloatField(wrapped_obj, jOffsetYField); -} - -float -AndroidProgressiveUpdateData::GetX(JNIEnv *env) -{ - if (!env) - return 0.0f; - return env->GetFloatField(wrapped_obj, jXField); -} - -float -AndroidProgressiveUpdateData::GetY(JNIEnv *env) -{ - if (!env) - return 0.0f; - return env->GetFloatField(wrapped_obj, jYField); -} - -float -AndroidProgressiveUpdateData::GetWidth(JNIEnv *env) -{ - if (!env) - return 0.0f; - return env->GetFloatField(wrapped_obj, jWidthField); -} - -float -AndroidProgressiveUpdateData::GetHeight(JNIEnv *env) -{ - if (!env) - return 0.0f; - return env->GetFloatField(wrapped_obj, jHeightField); -} - -float -AndroidProgressiveUpdateData::GetScale(JNIEnv *env) -{ - if (!env) - return 0.0f; - return env->GetFloatField(wrapped_obj, jScaleField); -} - -bool -AndroidProgressiveUpdateData::GetShouldAbort(JNIEnv *env) -{ - if (!env) - return false; - return env->GetBooleanField(wrapped_obj, jShouldAbortField); -} - void AndroidRect::Init(JNIEnv *jenv, jobject jobj) { diff --git a/widget/android/AndroidJavaWrappers.h b/widget/android/AndroidJavaWrappers.h index 12d1754e8209..f0f26c6030f2 100644 --- a/widget/android/AndroidJavaWrappers.h +++ b/widget/android/AndroidJavaWrappers.h @@ -15,6 +15,7 @@ #include "nsString.h" #include "nsTArray.h" #include "nsIObserver.h" +#include "nsIAndroidBridge.h" #include "mozilla/gfx/Rect.h" #include "mozilla/dom/Touch.h" #include "mozilla/EventForwards.h" @@ -23,21 +24,12 @@ //#define FORCE_ALOG 1 -#ifndef ALOG -#if defined(DEBUG) || defined(FORCE_ALOG) -#define ALOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gecko" , ## args) -#else -#define ALOG(args...) ((void)0) -#endif -#endif - class nsIAndroidDisplayport; class nsIAndroidViewport; class nsIWidget; namespace mozilla { -class AndroidGeckoLayerClient; class AutoLocalJNIFrame; void InitAndroidJavaWrappers(JNIEnv *jEnv); @@ -75,10 +67,10 @@ private: class WrappedJavaObject { public: WrappedJavaObject() : - wrapped_obj(0) + wrapped_obj(NULL) { } - WrappedJavaObject(jobject jobj) { + WrappedJavaObject(jobject jobj) : wrapped_obj(NULL) { Init(jobj); } @@ -87,7 +79,39 @@ public: } bool isNull() const { - return wrapped_obj == 0; + return wrapped_obj == NULL; + } + + jobject wrappedObject() const { + return wrapped_obj; + } + +protected: + jobject wrapped_obj; +}; + +class AutoGlobalWrappedJavaObject : protected WrappedJavaObject{ +public: + AutoGlobalWrappedJavaObject() : + wrapped_obj(NULL) + { } + + AutoGlobalWrappedJavaObject(jobject jobj, JNIEnv* env) : wrapped_obj(NULL) { + Init(jobj, env); + } + + virtual ~AutoGlobalWrappedJavaObject(); + void Dispose(); + + void Init(jobject jobj, JNIEnv* env) { + if (!isNull()) { + env->DeleteGlobalRef(wrapped_obj); + } + wrapped_obj = env->NewGlobalRef(jobj); + } + + bool isNull() const { + return wrapped_obj == NULL; } jobject wrappedObject() const { @@ -186,61 +210,6 @@ protected: static jfieldID jTopField; }; -class AndroidViewTransform : public WrappedJavaObject { -public: - static void InitViewTransformClass(JNIEnv *jEnv); - - void Init(jobject jobj); - - AndroidViewTransform() {} - AndroidViewTransform(jobject jobj) { Init(jobj); } - - float GetX(JNIEnv *env); - float GetY(JNIEnv *env); - float GetScale(JNIEnv *env); - void GetFixedLayerMargins(JNIEnv *env, LayerMargin &aFixedLayerMargins); - float GetOffsetX(JNIEnv *env); - float GetOffsetY(JNIEnv *env); - -private: - static jclass jViewTransformClass; - static jfieldID jXField; - static jfieldID jYField; - static jfieldID jScaleField; - static jfieldID jFixedLayerMarginLeft; - static jfieldID jFixedLayerMarginTop; - static jfieldID jFixedLayerMarginRight; - static jfieldID jFixedLayerMarginBottom; - static jfieldID jOffsetXField; - static jfieldID jOffsetYField; -}; - -class AndroidProgressiveUpdateData : public WrappedJavaObject { -public: - static void InitProgressiveUpdateDataClass(JNIEnv *jEnv); - - void Init(jobject jobj); - - AndroidProgressiveUpdateData() {} - AndroidProgressiveUpdateData(jobject jobj) { Init(jobj); } - - float GetX(JNIEnv *env); - float GetY(JNIEnv *env); - float GetWidth(JNIEnv *env); - float GetHeight(JNIEnv *env); - float GetScale(JNIEnv *env); - bool GetShouldAbort(JNIEnv *env); - -private: - static jclass jProgressiveUpdateDataClass; - static jfieldID jXField; - static jfieldID jYField; - static jfieldID jWidthField; - static jfieldID jHeightField; - static jfieldID jScaleField; - static jfieldID jShouldAbortField; -}; - class AndroidLayerRendererFrame : public WrappedJavaObject { public: static void InitLayerRendererFrameClass(JNIEnv *jEnv); @@ -261,53 +230,6 @@ private: static jmethodID jEndDrawingMethod; }; -class AndroidGeckoLayerClient : public WrappedJavaObject { -public: - static void InitGeckoLayerClientClass(JNIEnv *jEnv); - - void Init(jobject jobj); - - AndroidGeckoLayerClient() {} - AndroidGeckoLayerClient(jobject jobj) { Init(jobj); } - - void SetFirstPaintViewport(const LayerIntPoint& aOffset, const CSSToLayerScale& aZoom, const CSSRect& aCssPageRect); - void SetPageRect(const CSSRect& aCssPageRect); - void SyncViewportInfo(const LayerIntRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution, - bool aLayersUpdated, ScreenPoint& aScrollOffset, CSSToScreenScale& aScale, - LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset); - void SyncFrameMetrics(const ScreenPoint& aScrollOffset, float aZoom, const CSSRect& aCssPageRect, - bool aLayersUpdated, const CSSRect& aDisplayPort, const CSSToLayerScale& aDisplayResolution, - bool aIsFirstPaint, LayerMargin& aFixedLayerMargins, ScreenPoint& aOffset); - bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const LayerRect& aDisplayPort, float aDisplayResolution, bool aDrawingCritical, gfx::Rect& aViewport, float& aScaleX, float& aScaleY); - bool CreateFrame(AutoLocalJNIFrame *jniFrame, AndroidLayerRendererFrame& aFrame); - bool ActivateProgram(AutoLocalJNIFrame *jniFrame); - bool DeactivateProgram(AutoLocalJNIFrame *jniFrame); - void GetDisplayPort(AutoLocalJNIFrame *jniFrame, bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort); - void ContentDocumentChanged(AutoLocalJNIFrame *jniFrame); - bool IsContentDocumentDisplayed(AutoLocalJNIFrame *jniFrame); - -protected: - static jclass jGeckoLayerClientClass; - static jmethodID jSetFirstPaintViewport; - static jmethodID jSetPageRect; - static jmethodID jSyncViewportInfoMethod; - static jmethodID jSyncFrameMetricsMethod; - static jmethodID jCreateFrameMethod; - static jmethodID jActivateProgramMethod; - static jmethodID jDeactivateProgramMethod; - static jmethodID jGetDisplayPort; - static jmethodID jContentDocumentChanged; - static jmethodID jIsContentDocumentDisplayed; - static jmethodID jProgressiveUpdateCallbackMethod; - -public: - static jclass jViewportClass; - static jclass jDisplayportClass; - static jmethodID jViewportCtor; - static jfieldID jDisplayportPosition; - static jfieldID jDisplayportResolution; -}; - enum { // These keycode masks are not defined in android/keycodes.h: AKEYCODE_ESCAPE = 111, @@ -433,6 +355,29 @@ enum { AMETA_SHIFT_MASK = AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON | AMETA_SHIFT_ON, }; +class nsAndroidDisplayport MOZ_FINAL : public nsIAndroidDisplayport +{ +public: + NS_DECL_ISUPPORTS + virtual nsresult GetLeft(float *aLeft) { *aLeft = mLeft; return NS_OK; } + virtual nsresult GetTop(float *aTop) { *aTop = mTop; return NS_OK; } + virtual nsresult GetRight(float *aRight) { *aRight = mRight; return NS_OK; } + virtual nsresult GetBottom(float *aBottom) { *aBottom = mBottom; return NS_OK; } + virtual nsresult GetResolution(float *aResolution) { *aResolution = mResolution; return NS_OK; } + virtual nsresult SetLeft(float aLeft) { mLeft = aLeft; return NS_OK; } + virtual nsresult SetTop(float aTop) { mTop = aTop; return NS_OK; } + virtual nsresult SetRight(float aRight) { mRight = aRight; return NS_OK; } + virtual nsresult SetBottom(float aBottom) { mBottom = aBottom; return NS_OK; } + virtual nsresult SetResolution(float aResolution) { mResolution = aResolution; return NS_OK; } + + nsAndroidDisplayport(AndroidRectF aRect, float aResolution): + mLeft(aRect.Left()), mTop(aRect.Top()), mRight(aRect.Right()), mBottom(aRect.Bottom()), mResolution(aResolution) {} + +private: + ~nsAndroidDisplayport() {} + float mLeft, mTop, mRight, mBottom, mResolution; +}; + class AndroidMotionEvent { public: diff --git a/widget/android/GeneratedJNIWrappers.cpp b/widget/android/GeneratedJNIWrappers.cpp index 27d1ca4d4fba..0aa701fd0913 100644 --- a/widget/android/GeneratedJNIWrappers.cpp +++ b/widget/android/GeneratedJNIWrappers.cpp @@ -3,18 +3,93 @@ // annotations on Java methods. To update, change the annotations on the corresponding Java // methods and rerun the build. Manually updating this file will cause your build to fail. +#include "GeneratedJNIWrappers.h" +#include "AndroidBridgeUtilities.h" #include "nsXPCOMStrings.h" #include "AndroidBridge.h" -#include "AndroidBridgeUtilities.h" -#ifdef DEBUG -#define ALOG_BRIDGE(args...) ALOG(args) -#else -#define ALOG_BRIDGE(args...) ((void)0) -#endif - -using namespace mozilla; -void AndroidBridge::InitStubs(JNIEnv *jEnv) { +namespace mozilla { +namespace widget { +namespace android { +jclass GeckoAppShell::mGeckoAppShellClass = 0; +jmethodID GeckoAppShell::jAcknowledgeEvent = 0; +jmethodID GeckoAppShell::jAddPluginViewWrapper = 0; +jmethodID GeckoAppShell::jAlertsProgressListener_OnProgress = 0; +jmethodID GeckoAppShell::jCancelVibrate = 0; +jmethodID GeckoAppShell::jCheckURIVisited = 0; +jmethodID GeckoAppShell::jClearMessageList = 0; +jmethodID GeckoAppShell::jCloseCamera = 0; +jmethodID GeckoAppShell::jCloseNotification = 0; +jmethodID GeckoAppShell::jCreateMessageListWrapper = 0; +jmethodID GeckoAppShell::jCreateShortcut = 0; +jmethodID GeckoAppShell::jDeleteMessageWrapper = 0; +jmethodID GeckoAppShell::jDisableBatteryNotifications = 0; +jmethodID GeckoAppShell::jDisableNetworkNotifications = 0; +jmethodID GeckoAppShell::jDisableScreenOrientationNotifications = 0; +jmethodID GeckoAppShell::jDisableSensor = 0; +jmethodID GeckoAppShell::jEnableBatteryNotifications = 0; +jmethodID GeckoAppShell::jEnableLocation = 0; +jmethodID GeckoAppShell::jEnableLocationHighAccuracy = 0; +jmethodID GeckoAppShell::jEnableNetworkNotifications = 0; +jmethodID GeckoAppShell::jEnableScreenOrientationNotifications = 0; +jmethodID GeckoAppShell::jEnableSensor = 0; +jmethodID GeckoAppShell::jGetContext = 0; +jmethodID GeckoAppShell::jGetCurrentBatteryInformationWrapper = 0; +jmethodID GeckoAppShell::jGetCurrentNetworkInformationWrapper = 0; +jmethodID GeckoAppShell::jGetDensity = 0; +jmethodID GeckoAppShell::jGetDpiWrapper = 0; +jmethodID GeckoAppShell::jGetExtensionFromMimeTypeWrapper = 0; +jmethodID GeckoAppShell::jGetHandlersForMimeTypeWrapper = 0; +jmethodID GeckoAppShell::jGetHandlersForURLWrapper = 0; +jmethodID GeckoAppShell::jGetIconForExtensionWrapper = 0; +jmethodID GeckoAppShell::jGetMessageWrapper = 0; +jmethodID GeckoAppShell::jGetMimeTypeFromExtensionsWrapper = 0; +jmethodID GeckoAppShell::jGetNextMessageInListWrapper = 0; +jmethodID GeckoAppShell::jGetProxyForURIWrapper = 0; +jmethodID GeckoAppShell::jGetScreenDepthWrapper = 0; +jmethodID GeckoAppShell::jGetScreenOrientationWrapper = 0; +jmethodID GeckoAppShell::jGetShowPasswordSetting = 0; +jmethodID GeckoAppShell::jGetSystemColoursWrapper = 0; +jmethodID GeckoAppShell::jHandleGeckoMessageWrapper = 0; +jmethodID GeckoAppShell::jHideProgressDialog = 0; +jmethodID GeckoAppShell::jInitCameraWrapper = 0; +jmethodID GeckoAppShell::jIsNetworkLinkKnown = 0; +jmethodID GeckoAppShell::jIsNetworkLinkUp = 0; +jmethodID GeckoAppShell::jIsTablet = 0; +jmethodID GeckoAppShell::jKillAnyZombies = 0; +jmethodID GeckoAppShell::jLockScreenOrientation = 0; +jmethodID GeckoAppShell::jMarkURIVisited = 0; +jmethodID GeckoAppShell::jMoveTaskToBack = 0; +jmethodID GeckoAppShell::jNetworkLinkType = 0; +jmethodID GeckoAppShell::jNotifyDefaultPrevented = 0; +jmethodID GeckoAppShell::jNotifyIME = 0; +jmethodID GeckoAppShell::jNotifyIMEChange = 0; +jmethodID GeckoAppShell::jNotifyIMEContext = 0; +jmethodID GeckoAppShell::jNotifyWakeLockChanged = 0; +jmethodID GeckoAppShell::jNotifyXreExit = 0; +jmethodID GeckoAppShell::jOpenUriExternal = 0; +jmethodID GeckoAppShell::jPerformHapticFeedback = 0; +jmethodID GeckoAppShell::jPumpMessageLoop = 0; +jmethodID GeckoAppShell::jRegisterSurfaceTextureFrameListener = 0; +jmethodID GeckoAppShell::jRemovePluginView = 0; +jmethodID GeckoAppShell::jScanMedia = 0; +jmethodID GeckoAppShell::jScheduleRestart = 0; +jmethodID GeckoAppShell::jSendMessageWrapper = 0; +jmethodID GeckoAppShell::jSetFullScreen = 0; +jmethodID GeckoAppShell::jSetKeepScreenOn = 0; +jmethodID GeckoAppShell::jSetSelectedLocale = 0; +jmethodID GeckoAppShell::jSetURITitle = 0; +jmethodID GeckoAppShell::jShowAlertNotificationWrapper = 0; +jmethodID GeckoAppShell::jShowFilePickerAsyncWrapper = 0; +jmethodID GeckoAppShell::jShowFilePickerForExtensionsWrapper = 0; +jmethodID GeckoAppShell::jShowFilePickerForMimeTypeWrapper = 0; +jmethodID GeckoAppShell::jShowInputMethodPicker = 0; +jmethodID GeckoAppShell::jUnlockProfile = 0; +jmethodID GeckoAppShell::jUnlockScreenOrientation = 0; +jmethodID GeckoAppShell::jUnregisterSurfaceTextureFrameListener = 0; +jmethodID GeckoAppShell::jVibrate1 = 0; +jmethodID GeckoAppShell::jVibrateA = 0; +void GeckoAppShell::InitStubs(JNIEnv *jEnv) { initInit(); mGeckoAppShellClass = getClassGlobalRef("org/mozilla/gecko/GeckoAppShell"); @@ -95,36 +170,23 @@ void AndroidBridge::InitStubs(JNIEnv *jEnv) { jUnregisterSurfaceTextureFrameListener = getStaticMethod("unregisterSurfaceTextureFrameListener", "(Ljava/lang/Object;)V"); jVibrate1 = getStaticMethod("vibrate", "(J)V"); jVibrateA = getStaticMethod("vibrate", "([JI)V"); - - mGeckoJavaSamplerClass = getClassGlobalRef("org/mozilla/gecko/GeckoJavaSampler"); - jGetFrameNameJavaProfilingWrapper = getStaticMethod("getFrameName", "(III)Ljava/lang/String;"); - jGetSampleTimeJavaProfiling = getStaticMethod("getSampleTime", "(II)D"); - jGetThreadNameJavaProfilingWrapper = getStaticMethod("getThreadName", "(I)Ljava/lang/String;"); - jPauseJavaProfiling = getStaticMethod("pause", "()V"); - jStartJavaProfiling = getStaticMethod("start", "(II)V"); - jStopJavaProfiling = getStaticMethod("stop", "()V"); - jUnpauseJavaProfiling = getStaticMethod("unpause", "()V"); - - mThumbnailHelperClass = getClassGlobalRef("org/mozilla/gecko/ThumbnailHelper"); - jSendThumbnail = getStaticMethod("notifyThumbnail", "(Ljava/nio/ByteBuffer;IZ)V"); - - mGLControllerClass = getClassGlobalRef("org/mozilla/gecko/gfx/GLController"); - jCreateEGLSurfaceForCompositorWrapper = getMethod("createEGLSurfaceForCompositor", "()Ljavax/microedition/khronos/egl/EGLSurface;"); - - mLayerViewClass = getClassGlobalRef("org/mozilla/gecko/gfx/LayerView"); - jRegisterCompositorWrapper = getStaticMethod("registerCxxCompositor", "()Lorg/mozilla/gecko/gfx/GLController;"); - - mNativePanZoomControllerClass = getClassGlobalRef("org/mozilla/gecko/gfx/NativePanZoomController"); - jPostDelayedCallbackWrapper = getMethod("postDelayedCallback", "(J)V"); - jRequestContentRepaintWrapper = getMethod("requestContentRepaint", "(FFFFF)V"); - - mClipboardClass = getClassGlobalRef("org/mozilla/gecko/util/Clipboard"); - jGetClipboardTextWrapper = getStaticMethod("getText", "()Ljava/lang/String;"); - jSetClipboardText = getStaticMethod("setText", "(Ljava/lang/CharSequence;)V"); } -void AndroidBridge::AcknowledgeEvent() { - JNIEnv *env = GetJNIEnv(); +GeckoAppShell* GeckoAppShell::Wrap(jobject obj) { + JNIEnv *env = GetJNIForThread(); + + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return NULL; + } + + GeckoAppShell* ret = new GeckoAppShell(obj, env); + env->DeleteLocalRef(obj); + return ret; +} + +void GeckoAppShell::AcknowledgeEvent() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -146,11 +208,12 @@ void AndroidBridge::AcknowledgeEvent() { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::AddPluginViewWrapper(jobject a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4, bool a5) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::AddPluginViewWrapper(jobject a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4, bool a5) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -180,11 +243,12 @@ void AndroidBridge::AddPluginViewWrapper(jobject a0, jfloat a1, jfloat a2, jfloa env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::AlertsProgressListener_OnProgress(const nsAString& a0, int64_t a1, int64_t a2, const nsAString& a3) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::AlertsProgressListener_OnProgress(const nsAString& a0, int64_t a1, int64_t a2, const nsAString& a3) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -198,10 +262,10 @@ void AndroidBridge::AlertsProgressListener_OnProgress(const nsAString& a0, int64 } jvalue args[4]; - args[0].l = NewJavaString(env, a0); + args[0].l = AndroidBridge::NewJavaString(env, a0); args[1].j = a1; args[2].j = a2; - args[3].l = NewJavaString(env, a3); + args[3].l = AndroidBridge::NewJavaString(env, a3); env->CallStaticVoidMethodA(mGeckoAppShellClass, jAlertsProgressListener_OnProgress, args); @@ -212,11 +276,12 @@ void AndroidBridge::AlertsProgressListener_OnProgress(const nsAString& a0, int64 env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::CancelVibrate() { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::CancelVibrate() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -238,11 +303,12 @@ void AndroidBridge::CancelVibrate() { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::CheckURIVisited(const nsAString& a0) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::CheckURIVisited(const nsAString& a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -255,7 +321,7 @@ void AndroidBridge::CheckURIVisited(const nsAString& a0) { return; } - jstring j0 = NewJavaString(env, a0); + jstring j0 = AndroidBridge::NewJavaString(env, a0); env->CallStaticVoidMethod(mGeckoAppShellClass, jCheckURIVisited, j0); @@ -266,11 +332,12 @@ void AndroidBridge::CheckURIVisited(const nsAString& a0) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::ClearMessageList(int32_t a0) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::ClearMessageList(int32_t a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -292,11 +359,12 @@ void AndroidBridge::ClearMessageList(int32_t a0) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::CloseCamera() { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::CloseCamera() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -318,11 +386,12 @@ void AndroidBridge::CloseCamera() { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::CloseNotification(const nsAString& a0) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::CloseNotification(const nsAString& a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -335,7 +404,7 @@ void AndroidBridge::CloseNotification(const nsAString& a0) { return; } - jstring j0 = NewJavaString(env, a0); + jstring j0 = AndroidBridge::NewJavaString(env, a0); env->CallStaticVoidMethod(mGeckoAppShellClass, jCloseNotification, j0); @@ -346,11 +415,12 @@ void AndroidBridge::CloseNotification(const nsAString& a0) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::CreateMessageListWrapper(int64_t a0, int64_t a1, jobjectArray a2, int32_t a3, int32_t a4, bool a5, int32_t a6) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::CreateMessageListWrapper(int64_t a0, int64_t a1, jobjectArray a2, int32_t a3, int32_t a4, bool a5, int32_t a6) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -381,11 +451,12 @@ void AndroidBridge::CreateMessageListWrapper(int64_t a0, int64_t a1, jobjectArra env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::CreateShortcut(const nsAString& a0, const nsAString& a1, const nsAString& a2, const nsAString& a3) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::CreateShortcut(const nsAString& a0, const nsAString& a1, const nsAString& a2, const nsAString& a3) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -399,10 +470,10 @@ void AndroidBridge::CreateShortcut(const nsAString& a0, const nsAString& a1, con } jvalue args[4]; - args[0].l = NewJavaString(env, a0); - args[1].l = NewJavaString(env, a1); - args[2].l = NewJavaString(env, a2); - args[3].l = NewJavaString(env, a3); + args[0].l = AndroidBridge::NewJavaString(env, a0); + args[1].l = AndroidBridge::NewJavaString(env, a1); + args[2].l = AndroidBridge::NewJavaString(env, a2); + args[3].l = AndroidBridge::NewJavaString(env, a3); env->CallStaticVoidMethodA(mGeckoAppShellClass, jCreateShortcut, args); @@ -413,11 +484,12 @@ void AndroidBridge::CreateShortcut(const nsAString& a0, const nsAString& a1, con env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::DeleteMessageWrapper(int32_t a0, int32_t a1) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::DeleteMessageWrapper(int32_t a0, int32_t a1) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -439,11 +511,12 @@ void AndroidBridge::DeleteMessageWrapper(int32_t a0, int32_t a1) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::DisableBatteryNotifications() { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::DisableBatteryNotifications() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -465,11 +538,12 @@ void AndroidBridge::DisableBatteryNotifications() { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::DisableNetworkNotifications() { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::DisableNetworkNotifications() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -491,11 +565,12 @@ void AndroidBridge::DisableNetworkNotifications() { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::DisableScreenOrientationNotifications() { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::DisableScreenOrientationNotifications() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -517,11 +592,12 @@ void AndroidBridge::DisableScreenOrientationNotifications() { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::DisableSensor(int32_t a0) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::DisableSensor(int32_t a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -543,11 +619,12 @@ void AndroidBridge::DisableSensor(int32_t a0) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::EnableBatteryNotifications() { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::EnableBatteryNotifications() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -569,11 +646,12 @@ void AndroidBridge::EnableBatteryNotifications() { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::EnableLocation(bool a0) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::EnableLocation(bool a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -595,11 +673,12 @@ void AndroidBridge::EnableLocation(bool a0) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::EnableLocationHighAccuracy(bool a0) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::EnableLocationHighAccuracy(bool a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -621,11 +700,12 @@ void AndroidBridge::EnableLocationHighAccuracy(bool a0) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::EnableNetworkNotifications() { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::EnableNetworkNotifications() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -647,11 +727,12 @@ void AndroidBridge::EnableNetworkNotifications() { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::EnableScreenOrientationNotifications() { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::EnableScreenOrientationNotifications() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -673,11 +754,12 @@ void AndroidBridge::EnableScreenOrientationNotifications() { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::EnableSensor(int32_t a0) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::EnableSensor(int32_t a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -699,10 +781,11 @@ void AndroidBridge::EnableSensor(int32_t a0) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -jobject AndroidBridge::GetContext() { +jobject GeckoAppShell::GetContext() { JNIEnv *env = GetJNIForThread(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); @@ -725,12 +808,13 @@ jobject AndroidBridge::GetContext() { env->PopLocalFrame(NULL); return nullptr; } + jobject ret = static_cast(env->PopLocalFrame(temp)); return ret; } -jdoubleArray AndroidBridge::GetCurrentBatteryInformationWrapper() { - JNIEnv *env = GetJNIEnv(); +jdoubleArray GeckoAppShell::GetCurrentBatteryInformationWrapper() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; @@ -752,12 +836,13 @@ jdoubleArray AndroidBridge::GetCurrentBatteryInformationWrapper() { env->PopLocalFrame(NULL); return nullptr; } + jdoubleArray ret = static_cast(env->PopLocalFrame(temp)); return ret; } -jdoubleArray AndroidBridge::GetCurrentNetworkInformationWrapper() { - JNIEnv *env = GetJNIEnv(); +jdoubleArray GeckoAppShell::GetCurrentNetworkInformationWrapper() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; @@ -779,12 +864,13 @@ jdoubleArray AndroidBridge::GetCurrentNetworkInformationWrapper() { env->PopLocalFrame(NULL); return nullptr; } + jdoubleArray ret = static_cast(env->PopLocalFrame(temp)); return ret; } -jfloat AndroidBridge::GetDensity() { - JNIEnv *env = GetJNIEnv(); +jfloat GeckoAppShell::GetDensity() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return 0.0; @@ -806,12 +892,13 @@ jfloat AndroidBridge::GetDensity() { env->PopLocalFrame(NULL); return 0.0; } + env->PopLocalFrame(NULL); return temp; } -int32_t AndroidBridge::GetDpiWrapper() { - JNIEnv *env = GetJNIEnv(); +int32_t GeckoAppShell::GetDpiWrapper() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return 0; @@ -833,12 +920,13 @@ int32_t AndroidBridge::GetDpiWrapper() { env->PopLocalFrame(NULL); return 0; } + env->PopLocalFrame(NULL); return temp; } -jstring AndroidBridge::GetExtensionFromMimeTypeWrapper(const nsAString& a0) { - JNIEnv *env = GetJNIEnv(); +jstring GeckoAppShell::GetExtensionFromMimeTypeWrapper(const nsAString& a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; @@ -851,7 +939,7 @@ jstring AndroidBridge::GetExtensionFromMimeTypeWrapper(const nsAString& a0) { return nullptr; } - jstring j0 = NewJavaString(env, a0); + jstring j0 = AndroidBridge::NewJavaString(env, a0); jobject temp = env->CallStaticObjectMethod(mGeckoAppShellClass, jGetExtensionFromMimeTypeWrapper, j0); @@ -862,12 +950,13 @@ jstring AndroidBridge::GetExtensionFromMimeTypeWrapper(const nsAString& a0) { env->PopLocalFrame(NULL); return nullptr; } + jstring ret = static_cast(env->PopLocalFrame(temp)); return ret; } -jobjectArray AndroidBridge::GetHandlersForMimeTypeWrapper(const nsAString& a0, const nsAString& a1) { - JNIEnv *env = GetJNIEnv(); +jobjectArray GeckoAppShell::GetHandlersForMimeTypeWrapper(const nsAString& a0, const nsAString& a1) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; @@ -880,8 +969,8 @@ jobjectArray AndroidBridge::GetHandlersForMimeTypeWrapper(const nsAString& a0, c return nullptr; } - jstring j0 = NewJavaString(env, a0); - jstring j1 = NewJavaString(env, a1); + jstring j0 = AndroidBridge::NewJavaString(env, a0); + jstring j1 = AndroidBridge::NewJavaString(env, a1); jobject temp = env->CallStaticObjectMethod(mGeckoAppShellClass, jGetHandlersForMimeTypeWrapper, j0, j1); @@ -892,12 +981,13 @@ jobjectArray AndroidBridge::GetHandlersForMimeTypeWrapper(const nsAString& a0, c env->PopLocalFrame(NULL); return nullptr; } + jobjectArray ret = static_cast(env->PopLocalFrame(temp)); return ret; } -jobjectArray AndroidBridge::GetHandlersForURLWrapper(const nsAString& a0, const nsAString& a1) { - JNIEnv *env = GetJNIEnv(); +jobjectArray GeckoAppShell::GetHandlersForURLWrapper(const nsAString& a0, const nsAString& a1) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; @@ -910,8 +1000,8 @@ jobjectArray AndroidBridge::GetHandlersForURLWrapper(const nsAString& a0, const return nullptr; } - jstring j0 = NewJavaString(env, a0); - jstring j1 = NewJavaString(env, a1); + jstring j0 = AndroidBridge::NewJavaString(env, a0); + jstring j1 = AndroidBridge::NewJavaString(env, a1); jobject temp = env->CallStaticObjectMethod(mGeckoAppShellClass, jGetHandlersForURLWrapper, j0, j1); @@ -922,12 +1012,13 @@ jobjectArray AndroidBridge::GetHandlersForURLWrapper(const nsAString& a0, const env->PopLocalFrame(NULL); return nullptr; } + jobjectArray ret = static_cast(env->PopLocalFrame(temp)); return ret; } -jbyteArray AndroidBridge::GetIconForExtensionWrapper(const nsAString& a0, int32_t a1) { - JNIEnv *env = GetJNIEnv(); +jbyteArray GeckoAppShell::GetIconForExtensionWrapper(const nsAString& a0, int32_t a1) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; @@ -940,7 +1031,7 @@ jbyteArray AndroidBridge::GetIconForExtensionWrapper(const nsAString& a0, int32_ return nullptr; } - jstring j0 = NewJavaString(env, a0); + jstring j0 = AndroidBridge::NewJavaString(env, a0); jobject temp = env->CallStaticObjectMethod(mGeckoAppShellClass, jGetIconForExtensionWrapper, j0, a1); @@ -951,12 +1042,13 @@ jbyteArray AndroidBridge::GetIconForExtensionWrapper(const nsAString& a0, int32_ env->PopLocalFrame(NULL); return nullptr; } + jbyteArray ret = static_cast(env->PopLocalFrame(temp)); return ret; } -void AndroidBridge::GetMessageWrapper(int32_t a0, int32_t a1) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::GetMessageWrapper(int32_t a0, int32_t a1) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -978,11 +1070,12 @@ void AndroidBridge::GetMessageWrapper(int32_t a0, int32_t a1) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -jstring AndroidBridge::GetMimeTypeFromExtensionsWrapper(const nsAString& a0) { - JNIEnv *env = GetJNIEnv(); +jstring GeckoAppShell::GetMimeTypeFromExtensionsWrapper(const nsAString& a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; @@ -995,7 +1088,7 @@ jstring AndroidBridge::GetMimeTypeFromExtensionsWrapper(const nsAString& a0) { return nullptr; } - jstring j0 = NewJavaString(env, a0); + jstring j0 = AndroidBridge::NewJavaString(env, a0); jobject temp = env->CallStaticObjectMethod(mGeckoAppShellClass, jGetMimeTypeFromExtensionsWrapper, j0); @@ -1006,12 +1099,13 @@ jstring AndroidBridge::GetMimeTypeFromExtensionsWrapper(const nsAString& a0) { env->PopLocalFrame(NULL); return nullptr; } + jstring ret = static_cast(env->PopLocalFrame(temp)); return ret; } -void AndroidBridge::GetNextMessageInListWrapper(int32_t a0, int32_t a1) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::GetNextMessageInListWrapper(int32_t a0, int32_t a1) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -1033,11 +1127,12 @@ void AndroidBridge::GetNextMessageInListWrapper(int32_t a0, int32_t a1) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -jstring AndroidBridge::GetProxyForURIWrapper(const nsAString& a0, const nsAString& a1, const nsAString& a2, int32_t a3) { - JNIEnv *env = GetJNIEnv(); +jstring GeckoAppShell::GetProxyForURIWrapper(const nsAString& a0, const nsAString& a1, const nsAString& a2, int32_t a3) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; @@ -1051,9 +1146,9 @@ jstring AndroidBridge::GetProxyForURIWrapper(const nsAString& a0, const nsAStrin } jvalue args[4]; - args[0].l = NewJavaString(env, a0); - args[1].l = NewJavaString(env, a1); - args[2].l = NewJavaString(env, a2); + args[0].l = AndroidBridge::NewJavaString(env, a0); + args[1].l = AndroidBridge::NewJavaString(env, a1); + args[2].l = AndroidBridge::NewJavaString(env, a2); args[3].i = a3; jobject temp = env->CallStaticObjectMethodA(mGeckoAppShellClass, jGetProxyForURIWrapper, args); @@ -1065,12 +1160,13 @@ jstring AndroidBridge::GetProxyForURIWrapper(const nsAString& a0, const nsAStrin env->PopLocalFrame(NULL); return nullptr; } + jstring ret = static_cast(env->PopLocalFrame(temp)); return ret; } -int32_t AndroidBridge::GetScreenDepthWrapper() { - JNIEnv *env = GetJNIEnv(); +int32_t GeckoAppShell::GetScreenDepthWrapper() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return 0; @@ -1092,12 +1188,13 @@ int32_t AndroidBridge::GetScreenDepthWrapper() { env->PopLocalFrame(NULL); return 0; } + env->PopLocalFrame(NULL); return temp; } -int16_t AndroidBridge::GetScreenOrientationWrapper() { - JNIEnv *env = GetJNIEnv(); +int16_t GeckoAppShell::GetScreenOrientationWrapper() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return 0; @@ -1119,12 +1216,13 @@ int16_t AndroidBridge::GetScreenOrientationWrapper() { env->PopLocalFrame(NULL); return 0; } + env->PopLocalFrame(NULL); return temp; } -bool AndroidBridge::GetShowPasswordSetting() { - JNIEnv *env = GetJNIEnv(); +bool GeckoAppShell::GetShowPasswordSetting() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return false; @@ -1146,12 +1244,13 @@ bool AndroidBridge::GetShowPasswordSetting() { env->PopLocalFrame(NULL); return false; } + env->PopLocalFrame(NULL); return temp; } -jintArray AndroidBridge::GetSystemColoursWrapper() { - JNIEnv *env = GetJNIEnv(); +jintArray GeckoAppShell::GetSystemColoursWrapper() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; @@ -1173,12 +1272,13 @@ jintArray AndroidBridge::GetSystemColoursWrapper() { env->PopLocalFrame(NULL); return nullptr; } + jintArray ret = static_cast(env->PopLocalFrame(temp)); return ret; } -jstring AndroidBridge::HandleGeckoMessageWrapper(const nsAString& a0) { - JNIEnv *env = GetJNIEnv(); +jstring GeckoAppShell::HandleGeckoMessageWrapper(const nsAString& a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; @@ -1191,7 +1291,7 @@ jstring AndroidBridge::HandleGeckoMessageWrapper(const nsAString& a0) { return nullptr; } - jstring j0 = NewJavaString(env, a0); + jstring j0 = AndroidBridge::NewJavaString(env, a0); jobject temp = env->CallStaticObjectMethod(mGeckoAppShellClass, jHandleGeckoMessageWrapper, j0); @@ -1202,12 +1302,13 @@ jstring AndroidBridge::HandleGeckoMessageWrapper(const nsAString& a0) { env->PopLocalFrame(NULL); return nullptr; } + jstring ret = static_cast(env->PopLocalFrame(temp)); return ret; } -void AndroidBridge::HideProgressDialog() { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::HideProgressDialog() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -1229,11 +1330,12 @@ void AndroidBridge::HideProgressDialog() { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -jintArray AndroidBridge::InitCameraWrapper(const nsAString& a0, int32_t a1, int32_t a2, int32_t a3) { - JNIEnv *env = GetJNIEnv(); +jintArray GeckoAppShell::InitCameraWrapper(const nsAString& a0, int32_t a1, int32_t a2, int32_t a3) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; @@ -1247,7 +1349,7 @@ jintArray AndroidBridge::InitCameraWrapper(const nsAString& a0, int32_t a1, int3 } jvalue args[4]; - args[0].l = NewJavaString(env, a0); + args[0].l = AndroidBridge::NewJavaString(env, a0); args[1].i = a1; args[2].i = a2; args[3].i = a3; @@ -1261,12 +1363,13 @@ jintArray AndroidBridge::InitCameraWrapper(const nsAString& a0, int32_t a1, int3 env->PopLocalFrame(NULL); return nullptr; } + jintArray ret = static_cast(env->PopLocalFrame(temp)); return ret; } -bool AndroidBridge::IsNetworkLinkKnown() { - JNIEnv *env = GetJNIEnv(); +bool GeckoAppShell::IsNetworkLinkKnown() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return false; @@ -1288,12 +1391,13 @@ bool AndroidBridge::IsNetworkLinkKnown() { env->PopLocalFrame(NULL); return false; } + env->PopLocalFrame(NULL); return temp; } -bool AndroidBridge::IsNetworkLinkUp() { - JNIEnv *env = GetJNIEnv(); +bool GeckoAppShell::IsNetworkLinkUp() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return false; @@ -1315,12 +1419,13 @@ bool AndroidBridge::IsNetworkLinkUp() { env->PopLocalFrame(NULL); return false; } + env->PopLocalFrame(NULL); return temp; } -bool AndroidBridge::IsTablet() { - JNIEnv *env = GetJNIEnv(); +bool GeckoAppShell::IsTablet() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return false; @@ -1342,12 +1447,13 @@ bool AndroidBridge::IsTablet() { env->PopLocalFrame(NULL); return false; } + env->PopLocalFrame(NULL); return temp; } -void AndroidBridge::KillAnyZombies() { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::KillAnyZombies() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -1369,11 +1475,12 @@ void AndroidBridge::KillAnyZombies() { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::LockScreenOrientation(int32_t a0) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::LockScreenOrientation(int32_t a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -1395,11 +1502,12 @@ void AndroidBridge::LockScreenOrientation(int32_t a0) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::MarkURIVisited(const nsAString& a0) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::MarkURIVisited(const nsAString& a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -1412,7 +1520,7 @@ void AndroidBridge::MarkURIVisited(const nsAString& a0) { return; } - jstring j0 = NewJavaString(env, a0); + jstring j0 = AndroidBridge::NewJavaString(env, a0); env->CallStaticVoidMethod(mGeckoAppShellClass, jMarkURIVisited, j0); @@ -1423,11 +1531,12 @@ void AndroidBridge::MarkURIVisited(const nsAString& a0) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::MoveTaskToBack() { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::MoveTaskToBack() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -1449,11 +1558,12 @@ void AndroidBridge::MoveTaskToBack() { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -int32_t AndroidBridge::NetworkLinkType() { - JNIEnv *env = GetJNIEnv(); +int32_t GeckoAppShell::NetworkLinkType() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return 0; @@ -1475,12 +1585,13 @@ int32_t AndroidBridge::NetworkLinkType() { env->PopLocalFrame(NULL); return 0; } + env->PopLocalFrame(NULL); return temp; } -void AndroidBridge::NotifyDefaultPrevented(bool a0) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::NotifyDefaultPrevented(bool a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -1502,16 +1613,12 @@ void AndroidBridge::NotifyDefaultPrevented(bool a0) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::NotifyIME(int32_t a0) { - if (!sBridge) { - ALOG_BRIDGE("Aborted: No sBridge - %s", __PRETTY_FUNCTION__); - return; - } - - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::NotifyIME(int32_t a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -1524,7 +1631,7 @@ void AndroidBridge::NotifyIME(int32_t a0) { return; } - env->CallStaticVoidMethod(sBridge->mGeckoAppShellClass, sBridge->jNotifyIME, a0); + env->CallStaticVoidMethod(mGeckoAppShellClass, jNotifyIME, a0); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); @@ -1533,16 +1640,12 @@ void AndroidBridge::NotifyIME(int32_t a0) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::NotifyIMEChange(const nsAString& a0, int32_t a1, int32_t a2, int32_t a3) { - if (!sBridge) { - ALOG_BRIDGE("Aborted: No sBridge - %s", __PRETTY_FUNCTION__); - return; - } - - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::NotifyIMEChange(const nsAString& a0, int32_t a1, int32_t a2, int32_t a3) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -1556,12 +1659,12 @@ void AndroidBridge::NotifyIMEChange(const nsAString& a0, int32_t a1, int32_t a2, } jvalue args[4]; - args[0].l = NewJavaString(env, a0); + args[0].l = AndroidBridge::NewJavaString(env, a0); args[1].i = a1; args[2].i = a2; args[3].i = a3; - env->CallStaticVoidMethodA(sBridge->mGeckoAppShellClass, sBridge->jNotifyIMEChange, args); + env->CallStaticVoidMethodA(mGeckoAppShellClass, jNotifyIMEChange, args); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); @@ -1570,16 +1673,12 @@ void AndroidBridge::NotifyIMEChange(const nsAString& a0, int32_t a1, int32_t a2, env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::NotifyIMEContext(int32_t a0, const nsAString& a1, const nsAString& a2, const nsAString& a3) { - if (!sBridge) { - ALOG_BRIDGE("Aborted: No sBridge - %s", __PRETTY_FUNCTION__); - return; - } - - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::NotifyIMEContext(int32_t a0, const nsAString& a1, const nsAString& a2, const nsAString& a3) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -1594,11 +1693,11 @@ void AndroidBridge::NotifyIMEContext(int32_t a0, const nsAString& a1, const nsAS jvalue args[4]; args[0].i = a0; - args[1].l = NewJavaString(env, a1); - args[2].l = NewJavaString(env, a2); - args[3].l = NewJavaString(env, a3); + args[1].l = AndroidBridge::NewJavaString(env, a1); + args[2].l = AndroidBridge::NewJavaString(env, a2); + args[3].l = AndroidBridge::NewJavaString(env, a3); - env->CallStaticVoidMethodA(sBridge->mGeckoAppShellClass, sBridge->jNotifyIMEContext, args); + env->CallStaticVoidMethodA(mGeckoAppShellClass, jNotifyIMEContext, args); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); @@ -1607,11 +1706,12 @@ void AndroidBridge::NotifyIMEContext(int32_t a0, const nsAString& a1, const nsAS env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::NotifyWakeLockChanged(const nsAString& a0, const nsAString& a1) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::NotifyWakeLockChanged(const nsAString& a0, const nsAString& a1) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -1624,8 +1724,8 @@ void AndroidBridge::NotifyWakeLockChanged(const nsAString& a0, const nsAString& return; } - jstring j0 = NewJavaString(env, a0); - jstring j1 = NewJavaString(env, a1); + jstring j0 = AndroidBridge::NewJavaString(env, a0); + jstring j1 = AndroidBridge::NewJavaString(env, a1); env->CallStaticVoidMethod(mGeckoAppShellClass, jNotifyWakeLockChanged, j0, j1); @@ -1636,11 +1736,12 @@ void AndroidBridge::NotifyWakeLockChanged(const nsAString& a0, const nsAString& env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::NotifyXreExit() { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::NotifyXreExit() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -1662,11 +1763,12 @@ void AndroidBridge::NotifyXreExit() { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -bool AndroidBridge::OpenUriExternal(const nsAString& a0, const nsAString& a1, const nsAString& a2, const nsAString& a3, const nsAString& a4, const nsAString& a5) { - JNIEnv *env = GetJNIEnv(); +bool GeckoAppShell::OpenUriExternal(const nsAString& a0, const nsAString& a1, const nsAString& a2, const nsAString& a3, const nsAString& a4, const nsAString& a5) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return false; @@ -1680,12 +1782,12 @@ bool AndroidBridge::OpenUriExternal(const nsAString& a0, const nsAString& a1, co } jvalue args[6]; - args[0].l = NewJavaString(env, a0); - args[1].l = NewJavaString(env, a1); - args[2].l = NewJavaString(env, a2); - args[3].l = NewJavaString(env, a3); - args[4].l = NewJavaString(env, a4); - args[5].l = NewJavaString(env, a5); + args[0].l = AndroidBridge::NewJavaString(env, a0); + args[1].l = AndroidBridge::NewJavaString(env, a1); + args[2].l = AndroidBridge::NewJavaString(env, a2); + args[3].l = AndroidBridge::NewJavaString(env, a3); + args[4].l = AndroidBridge::NewJavaString(env, a4); + args[5].l = AndroidBridge::NewJavaString(env, a5); bool temp = env->CallStaticBooleanMethodA(mGeckoAppShellClass, jOpenUriExternal, args); @@ -1696,12 +1798,13 @@ bool AndroidBridge::OpenUriExternal(const nsAString& a0, const nsAString& a1, co env->PopLocalFrame(NULL); return false; } + env->PopLocalFrame(NULL); return temp; } -void AndroidBridge::PerformHapticFeedback(bool a0) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::PerformHapticFeedback(bool a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -1723,11 +1826,12 @@ void AndroidBridge::PerformHapticFeedback(bool a0) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -bool AndroidBridge::PumpMessageLoop() { - JNIEnv *env = GetJNIEnv(); +bool GeckoAppShell::PumpMessageLoop() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return false; @@ -1749,12 +1853,13 @@ bool AndroidBridge::PumpMessageLoop() { env->PopLocalFrame(NULL); return false; } + env->PopLocalFrame(NULL); return temp; } -void AndroidBridge::RegisterSurfaceTextureFrameListener(jobject a0, int32_t a1) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::RegisterSurfaceTextureFrameListener(jobject a0, int32_t a1) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -1776,11 +1881,12 @@ void AndroidBridge::RegisterSurfaceTextureFrameListener(jobject a0, int32_t a1) env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::RemovePluginView(jobject a0, bool a1) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::RemovePluginView(jobject a0, bool a1) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -1802,11 +1908,12 @@ void AndroidBridge::RemovePluginView(jobject a0, bool a1) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::ScanMedia(const nsAString& a0, const nsAString& a1) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::ScanMedia(const nsAString& a0, const nsAString& a1) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -1819,8 +1926,8 @@ void AndroidBridge::ScanMedia(const nsAString& a0, const nsAString& a1) { return; } - jstring j0 = NewJavaString(env, a0); - jstring j1 = NewJavaString(env, a1); + jstring j0 = AndroidBridge::NewJavaString(env, a0); + jstring j1 = AndroidBridge::NewJavaString(env, a1); env->CallStaticVoidMethod(mGeckoAppShellClass, jScanMedia, j0, j1); @@ -1831,11 +1938,12 @@ void AndroidBridge::ScanMedia(const nsAString& a0, const nsAString& a1) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::ScheduleRestart() { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::ScheduleRestart() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -1857,11 +1965,12 @@ void AndroidBridge::ScheduleRestart() { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::SendMessageWrapper(const nsAString& a0, const nsAString& a1, int32_t a2) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::SendMessageWrapper(const nsAString& a0, const nsAString& a1, int32_t a2) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -1875,8 +1984,8 @@ void AndroidBridge::SendMessageWrapper(const nsAString& a0, const nsAString& a1, } jvalue args[3]; - args[0].l = NewJavaString(env, a0); - args[1].l = NewJavaString(env, a1); + args[0].l = AndroidBridge::NewJavaString(env, a0); + args[1].l = AndroidBridge::NewJavaString(env, a1); args[2].i = a2; env->CallStaticVoidMethodA(mGeckoAppShellClass, jSendMessageWrapper, args); @@ -1888,11 +1997,12 @@ void AndroidBridge::SendMessageWrapper(const nsAString& a0, const nsAString& a1, env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::SetFullScreen(bool a0) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::SetFullScreen(bool a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -1914,11 +2024,12 @@ void AndroidBridge::SetFullScreen(bool a0) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::SetKeepScreenOn(bool a0) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::SetKeepScreenOn(bool a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -1940,11 +2051,12 @@ void AndroidBridge::SetKeepScreenOn(bool a0) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::SetSelectedLocale(const nsAString& a0) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::SetSelectedLocale(const nsAString& a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -1957,7 +2069,7 @@ void AndroidBridge::SetSelectedLocale(const nsAString& a0) { return; } - jstring j0 = NewJavaString(env, a0); + jstring j0 = AndroidBridge::NewJavaString(env, a0); env->CallStaticVoidMethod(mGeckoAppShellClass, jSetSelectedLocale, j0); @@ -1968,11 +2080,12 @@ void AndroidBridge::SetSelectedLocale(const nsAString& a0) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::SetURITitle(const nsAString& a0, const nsAString& a1) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::SetURITitle(const nsAString& a0, const nsAString& a1) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -1985,8 +2098,8 @@ void AndroidBridge::SetURITitle(const nsAString& a0, const nsAString& a1) { return; } - jstring j0 = NewJavaString(env, a0); - jstring j1 = NewJavaString(env, a1); + jstring j0 = AndroidBridge::NewJavaString(env, a0); + jstring j1 = AndroidBridge::NewJavaString(env, a1); env->CallStaticVoidMethod(mGeckoAppShellClass, jSetURITitle, j0, j1); @@ -1997,11 +2110,12 @@ void AndroidBridge::SetURITitle(const nsAString& a0, const nsAString& a1) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::ShowAlertNotificationWrapper(const nsAString& a0, const nsAString& a1, const nsAString& a2, const nsAString& a3, const nsAString& a4) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::ShowAlertNotificationWrapper(const nsAString& a0, const nsAString& a1, const nsAString& a2, const nsAString& a3, const nsAString& a4) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -2015,11 +2129,11 @@ void AndroidBridge::ShowAlertNotificationWrapper(const nsAString& a0, const nsAS } jvalue args[5]; - args[0].l = NewJavaString(env, a0); - args[1].l = NewJavaString(env, a1); - args[2].l = NewJavaString(env, a2); - args[3].l = NewJavaString(env, a3); - args[4].l = NewJavaString(env, a4); + args[0].l = AndroidBridge::NewJavaString(env, a0); + args[1].l = AndroidBridge::NewJavaString(env, a1); + args[2].l = AndroidBridge::NewJavaString(env, a2); + args[3].l = AndroidBridge::NewJavaString(env, a3); + args[4].l = AndroidBridge::NewJavaString(env, a4); env->CallStaticVoidMethodA(mGeckoAppShellClass, jShowAlertNotificationWrapper, args); @@ -2030,11 +2144,12 @@ void AndroidBridge::ShowAlertNotificationWrapper(const nsAString& a0, const nsAS env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::ShowFilePickerAsyncWrapper(const nsAString& a0, int64_t a1) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::ShowFilePickerAsyncWrapper(const nsAString& a0, int64_t a1) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -2047,7 +2162,7 @@ void AndroidBridge::ShowFilePickerAsyncWrapper(const nsAString& a0, int64_t a1) return; } - jstring j0 = NewJavaString(env, a0); + jstring j0 = AndroidBridge::NewJavaString(env, a0); env->CallStaticVoidMethod(mGeckoAppShellClass, jShowFilePickerAsyncWrapper, j0, a1); @@ -2058,11 +2173,12 @@ void AndroidBridge::ShowFilePickerAsyncWrapper(const nsAString& a0, int64_t a1) env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -jstring AndroidBridge::ShowFilePickerForExtensionsWrapper(const nsAString& a0) { - JNIEnv *env = GetJNIEnv(); +jstring GeckoAppShell::ShowFilePickerForExtensionsWrapper(const nsAString& a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; @@ -2075,7 +2191,7 @@ jstring AndroidBridge::ShowFilePickerForExtensionsWrapper(const nsAString& a0) { return nullptr; } - jstring j0 = NewJavaString(env, a0); + jstring j0 = AndroidBridge::NewJavaString(env, a0); jobject temp = env->CallStaticObjectMethod(mGeckoAppShellClass, jShowFilePickerForExtensionsWrapper, j0); @@ -2086,12 +2202,13 @@ jstring AndroidBridge::ShowFilePickerForExtensionsWrapper(const nsAString& a0) { env->PopLocalFrame(NULL); return nullptr; } + jstring ret = static_cast(env->PopLocalFrame(temp)); return ret; } -jstring AndroidBridge::ShowFilePickerForMimeTypeWrapper(const nsAString& a0) { - JNIEnv *env = GetJNIEnv(); +jstring GeckoAppShell::ShowFilePickerForMimeTypeWrapper(const nsAString& a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; @@ -2104,7 +2221,7 @@ jstring AndroidBridge::ShowFilePickerForMimeTypeWrapper(const nsAString& a0) { return nullptr; } - jstring j0 = NewJavaString(env, a0); + jstring j0 = AndroidBridge::NewJavaString(env, a0); jobject temp = env->CallStaticObjectMethod(mGeckoAppShellClass, jShowFilePickerForMimeTypeWrapper, j0); @@ -2115,12 +2232,13 @@ jstring AndroidBridge::ShowFilePickerForMimeTypeWrapper(const nsAString& a0) { env->PopLocalFrame(NULL); return nullptr; } + jstring ret = static_cast(env->PopLocalFrame(temp)); return ret; } -void AndroidBridge::ShowInputMethodPicker() { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::ShowInputMethodPicker() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -2142,11 +2260,12 @@ void AndroidBridge::ShowInputMethodPicker() { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -bool AndroidBridge::UnlockProfile() { - JNIEnv *env = GetJNIEnv(); +bool GeckoAppShell::UnlockProfile() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return false; @@ -2168,12 +2287,13 @@ bool AndroidBridge::UnlockProfile() { env->PopLocalFrame(NULL); return false; } + env->PopLocalFrame(NULL); return temp; } -void AndroidBridge::UnlockScreenOrientation() { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::UnlockScreenOrientation() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -2195,10 +2315,11 @@ void AndroidBridge::UnlockScreenOrientation() { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::UnregisterSurfaceTextureFrameListener(jobject a0) { +void GeckoAppShell::UnregisterSurfaceTextureFrameListener(jobject a0) { JNIEnv *env = GetJNIForThread(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); @@ -2221,11 +2342,12 @@ void AndroidBridge::UnregisterSurfaceTextureFrameListener(jobject a0) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::Vibrate1(int64_t a0) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::Vibrate1(int64_t a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -2247,11 +2369,12 @@ void AndroidBridge::Vibrate1(int64_t a0) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::VibrateA(jlongArray a0, int32_t a1) { - JNIEnv *env = GetJNIEnv(); +void GeckoAppShell::VibrateA(jlongArray a0, int32_t a1) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -2273,10 +2396,209 @@ void AndroidBridge::VibrateA(jlongArray a0, int32_t a1) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } +jclass JavaDomKeyLocation::mDomKeyLocationClass = 0; +jmethodID JavaDomKeyLocation::jvalueOf = 0; +jmethodID JavaDomKeyLocation::jvalues = 0; +jfieldID JavaDomKeyLocation::jDOM_KEY_LOCATION_JOYSTICK = 0; +jfieldID JavaDomKeyLocation::jDOM_KEY_LOCATION_LEFT = 0; +jfieldID JavaDomKeyLocation::jDOM_KEY_LOCATION_MOBILE = 0; +jfieldID JavaDomKeyLocation::jDOM_KEY_LOCATION_NUMPAD = 0; +jfieldID JavaDomKeyLocation::jDOM_KEY_LOCATION_RIGHT = 0; +jfieldID JavaDomKeyLocation::jDOM_KEY_LOCATION_STANDARD = 0; +jfieldID JavaDomKeyLocation::jvalue = 0; +void JavaDomKeyLocation::InitStubs(JNIEnv *jEnv) { + initInit(); -jstring AndroidBridge::GetFrameNameJavaProfilingWrapper(int32_t a0, int32_t a1, int32_t a2) { + mDomKeyLocationClass = getClassGlobalRef("org/mozilla/gecko/GeckoEvent$DomKeyLocation"); + jvalueOf = getStaticMethod("valueOf", "(Ljava/lang/String;)Lorg/mozilla/gecko/GeckoEvent$DomKeyLocation;"); + jvalues = getStaticMethod("values", "()[Lorg/mozilla/gecko/GeckoEvent$DomKeyLocation;"); + jDOM_KEY_LOCATION_JOYSTICK = getStaticField("DOM_KEY_LOCATION_JOYSTICK", "Lorg/mozilla/gecko/GeckoEvent$DomKeyLocation;"); + jDOM_KEY_LOCATION_LEFT = getStaticField("DOM_KEY_LOCATION_LEFT", "Lorg/mozilla/gecko/GeckoEvent$DomKeyLocation;"); + jDOM_KEY_LOCATION_MOBILE = getStaticField("DOM_KEY_LOCATION_MOBILE", "Lorg/mozilla/gecko/GeckoEvent$DomKeyLocation;"); + jDOM_KEY_LOCATION_NUMPAD = getStaticField("DOM_KEY_LOCATION_NUMPAD", "Lorg/mozilla/gecko/GeckoEvent$DomKeyLocation;"); + jDOM_KEY_LOCATION_RIGHT = getStaticField("DOM_KEY_LOCATION_RIGHT", "Lorg/mozilla/gecko/GeckoEvent$DomKeyLocation;"); + jDOM_KEY_LOCATION_STANDARD = getStaticField("DOM_KEY_LOCATION_STANDARD", "Lorg/mozilla/gecko/GeckoEvent$DomKeyLocation;"); + jvalue = getField("value", "I"); +} + +JavaDomKeyLocation* JavaDomKeyLocation::Wrap(jobject obj) { + JNIEnv *env = GetJNIForThread(); + + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return NULL; + } + + JavaDomKeyLocation* ret = new JavaDomKeyLocation(obj, env); + env->DeleteLocalRef(obj); + return ret; +} + +jobject JavaDomKeyLocation::valueOf(const nsAString& a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return nullptr; + } + + if (env->PushLocalFrame(2) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return nullptr; + } + + jstring j0 = AndroidBridge::NewJavaString(env, a0); + + jobject temp = env->CallStaticObjectMethod(mDomKeyLocationClass, jvalueOf, j0); + + if (env->ExceptionCheck()) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + env->PopLocalFrame(NULL); + return nullptr; + } + + jobject ret = static_cast(env->PopLocalFrame(temp)); + return ret; +} + +jobjectArray JavaDomKeyLocation::values() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return nullptr; + } + + if (env->PushLocalFrame(1) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return nullptr; + } + + jobject temp = env->CallStaticObjectMethod(mDomKeyLocationClass, jvalues); + + if (env->ExceptionCheck()) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + env->PopLocalFrame(NULL); + return nullptr; + } + + jobjectArray ret = static_cast(env->PopLocalFrame(temp)); + return ret; +} + +jobject JavaDomKeyLocation::getDOM_KEY_LOCATION_JOYSTICK() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return nullptr; + } + + return static_cast(env->GetStaticObjectField(mDomKeyLocationClass, jDOM_KEY_LOCATION_JOYSTICK)); +} + +jobject JavaDomKeyLocation::getDOM_KEY_LOCATION_LEFT() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return nullptr; + } + + return static_cast(env->GetStaticObjectField(mDomKeyLocationClass, jDOM_KEY_LOCATION_LEFT)); +} + +jobject JavaDomKeyLocation::getDOM_KEY_LOCATION_MOBILE() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return nullptr; + } + + return static_cast(env->GetStaticObjectField(mDomKeyLocationClass, jDOM_KEY_LOCATION_MOBILE)); +} + +jobject JavaDomKeyLocation::getDOM_KEY_LOCATION_NUMPAD() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return nullptr; + } + + return static_cast(env->GetStaticObjectField(mDomKeyLocationClass, jDOM_KEY_LOCATION_NUMPAD)); +} + +jobject JavaDomKeyLocation::getDOM_KEY_LOCATION_RIGHT() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return nullptr; + } + + return static_cast(env->GetStaticObjectField(mDomKeyLocationClass, jDOM_KEY_LOCATION_RIGHT)); +} + +jobject JavaDomKeyLocation::getDOM_KEY_LOCATION_STANDARD() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return nullptr; + } + + return static_cast(env->GetStaticObjectField(mDomKeyLocationClass, jDOM_KEY_LOCATION_STANDARD)); +} + +int32_t JavaDomKeyLocation::getvalue() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return 0; + } + + return env->GetIntField(wrapped_obj, jvalue); +} +jclass GeckoJavaSampler::mGeckoJavaSamplerClass = 0; +jmethodID GeckoJavaSampler::jGetFrameNameJavaProfilingWrapper = 0; +jmethodID GeckoJavaSampler::jGetSampleTimeJavaProfiling = 0; +jmethodID GeckoJavaSampler::jGetThreadNameJavaProfilingWrapper = 0; +jmethodID GeckoJavaSampler::jPauseJavaProfiling = 0; +jmethodID GeckoJavaSampler::jStartJavaProfiling = 0; +jmethodID GeckoJavaSampler::jStopJavaProfiling = 0; +jmethodID GeckoJavaSampler::jUnpauseJavaProfiling = 0; +void GeckoJavaSampler::InitStubs(JNIEnv *jEnv) { + initInit(); + + mGeckoJavaSamplerClass = getClassGlobalRef("org/mozilla/gecko/GeckoJavaSampler"); + jGetFrameNameJavaProfilingWrapper = getStaticMethod("getFrameName", "(III)Ljava/lang/String;"); + jGetSampleTimeJavaProfiling = getStaticMethod("getSampleTime", "(II)D"); + jGetThreadNameJavaProfilingWrapper = getStaticMethod("getThreadName", "(I)Ljava/lang/String;"); + jPauseJavaProfiling = getStaticMethod("pause", "()V"); + jStartJavaProfiling = getStaticMethod("start", "(II)V"); + jStopJavaProfiling = getStaticMethod("stop", "()V"); + jUnpauseJavaProfiling = getStaticMethod("unpause", "()V"); +} + +GeckoJavaSampler* GeckoJavaSampler::Wrap(jobject obj) { + JNIEnv *env = GetJNIForThread(); + + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return NULL; + } + + GeckoJavaSampler* ret = new GeckoJavaSampler(obj, env); + env->DeleteLocalRef(obj); + return ret; +} + +jstring GeckoJavaSampler::GetFrameNameJavaProfilingWrapper(int32_t a0, int32_t a1, int32_t a2) { JNIEnv *env = GetJNIForThread(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); @@ -2304,11 +2626,12 @@ jstring AndroidBridge::GetFrameNameJavaProfilingWrapper(int32_t a0, int32_t a1, env->PopLocalFrame(NULL); return nullptr; } + jstring ret = static_cast(env->PopLocalFrame(temp)); return ret; } -jdouble AndroidBridge::GetSampleTimeJavaProfiling(int32_t a0, int32_t a1) { +jdouble GeckoJavaSampler::GetSampleTimeJavaProfiling(int32_t a0, int32_t a1) { JNIEnv *env = GetJNIForThread(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); @@ -2331,11 +2654,12 @@ jdouble AndroidBridge::GetSampleTimeJavaProfiling(int32_t a0, int32_t a1) { env->PopLocalFrame(NULL); return 0.0; } + env->PopLocalFrame(NULL); return temp; } -jstring AndroidBridge::GetThreadNameJavaProfilingWrapper(int32_t a0) { +jstring GeckoJavaSampler::GetThreadNameJavaProfilingWrapper(int32_t a0) { JNIEnv *env = GetJNIForThread(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); @@ -2358,11 +2682,12 @@ jstring AndroidBridge::GetThreadNameJavaProfilingWrapper(int32_t a0) { env->PopLocalFrame(NULL); return nullptr; } + jstring ret = static_cast(env->PopLocalFrame(temp)); return ret; } -void AndroidBridge::PauseJavaProfiling() { +void GeckoJavaSampler::PauseJavaProfiling() { JNIEnv *env = GetJNIForThread(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); @@ -2385,10 +2710,11 @@ void AndroidBridge::PauseJavaProfiling() { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::StartJavaProfiling(int32_t a0, int32_t a1) { +void GeckoJavaSampler::StartJavaProfiling(int32_t a0, int32_t a1) { JNIEnv *env = GetJNIForThread(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); @@ -2411,10 +2737,11 @@ void AndroidBridge::StartJavaProfiling(int32_t a0, int32_t a1) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::StopJavaProfiling() { +void GeckoJavaSampler::StopJavaProfiling() { JNIEnv *env = GetJNIForThread(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); @@ -2437,10 +2764,11 @@ void AndroidBridge::StopJavaProfiling() { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::UnpauseJavaProfiling() { +void GeckoJavaSampler::UnpauseJavaProfiling() { JNIEnv *env = GetJNIForThread(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); @@ -2463,11 +2791,160 @@ void AndroidBridge::UnpauseJavaProfiling() { env->PopLocalFrame(NULL); return; } + + env->PopLocalFrame(NULL); +} +jclass SurfaceBits::mSurfaceBitsClass = 0; +jmethodID SurfaceBits::jSurfaceBits = 0; +jfieldID SurfaceBits::jbuffer = 0; +jfieldID SurfaceBits::jformat = 0; +jfieldID SurfaceBits::jheight = 0; +jfieldID SurfaceBits::jwidth = 0; +void SurfaceBits::InitStubs(JNIEnv *jEnv) { + initInit(); + + mSurfaceBitsClass = getClassGlobalRef("org/mozilla/gecko/SurfaceBits"); + jSurfaceBits = getMethod("", "()V"); + jbuffer = getField("buffer", "Ljava/nio/ByteBuffer;"); + jformat = getField("format", "I"); + jheight = getField("height", "I"); + jwidth = getField("width", "I"); +} + +SurfaceBits* SurfaceBits::Wrap(jobject obj) { + JNIEnv *env = GetJNIForThread(); + + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return NULL; + } + + SurfaceBits* ret = new SurfaceBits(obj, env); + env->DeleteLocalRef(obj); + return ret; +} + +SurfaceBits::SurfaceBits() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + if (env->PushLocalFrame(0) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return; + } + + Init(env->NewObject(mSurfaceBitsClass, jSurfaceBits), env); env->PopLocalFrame(NULL); } -void AndroidBridge::SendThumbnail(jobject a0, int32_t a1, bool a2) { - JNIEnv *env = GetJNIEnv(); +jobject SurfaceBits::getbuffer() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return nullptr; + } + + return static_cast(env->GetObjectField(wrapped_obj, jbuffer)); +} + +void SurfaceBits::setbuffer(jobject a0) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + env->SetObjectField(wrapped_obj, jbuffer, a0); +} + +int32_t SurfaceBits::getformat() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return 0; + } + + return env->GetIntField(wrapped_obj, jformat); +} + +void SurfaceBits::setformat(int32_t a0) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + env->SetIntField(wrapped_obj, jformat, a0); +} + +int32_t SurfaceBits::getheight() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return 0; + } + + return env->GetIntField(wrapped_obj, jheight); +} + +void SurfaceBits::setheight(int32_t a0) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + env->SetIntField(wrapped_obj, jheight, a0); +} + +int32_t SurfaceBits::getwidth() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return 0; + } + + return env->GetIntField(wrapped_obj, jwidth); +} + +void SurfaceBits::setwidth(int32_t a0) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + env->SetIntField(wrapped_obj, jwidth, a0); +} +jclass ThumbnailHelper::mThumbnailHelperClass = 0; +jmethodID ThumbnailHelper::jSendThumbnail = 0; +void ThumbnailHelper::InitStubs(JNIEnv *jEnv) { + initInit(); + + mThumbnailHelperClass = getClassGlobalRef("org/mozilla/gecko/ThumbnailHelper"); + jSendThumbnail = getStaticMethod("notifyThumbnail", "(Ljava/nio/ByteBuffer;IZ)V"); +} + +ThumbnailHelper* ThumbnailHelper::Wrap(jobject obj) { + JNIEnv *env = GetJNIForThread(); + + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return NULL; + } + + ThumbnailHelper* ret = new ThumbnailHelper(obj, env); + env->DeleteLocalRef(obj); + return ret; +} + +void ThumbnailHelper::SendThumbnail(jobject a0, int32_t a1, bool a2) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -2494,10 +2971,102 @@ void AndroidBridge::SendThumbnail(jobject a0, int32_t a1, bool a2) { env->PopLocalFrame(NULL); return; } + + env->PopLocalFrame(NULL); +} +jclass DisplayPortMetrics::mDisplayPortMetricsClass = 0; +jmethodID DisplayPortMetrics::jDisplayPortMetrics = 0; +jfieldID DisplayPortMetrics::jMPosition = 0; +jfieldID DisplayPortMetrics::jResolution = 0; +void DisplayPortMetrics::InitStubs(JNIEnv *jEnv) { + initInit(); + + mDisplayPortMetricsClass = getClassGlobalRef("org/mozilla/gecko/gfx/DisplayPortMetrics"); + jDisplayPortMetrics = getMethod("", "(FFFFF)V"); + jMPosition = getField("mPosition", "Landroid/graphics/RectF;"); + jResolution = getField("resolution", "F"); +} + +DisplayPortMetrics* DisplayPortMetrics::Wrap(jobject obj) { + JNIEnv *env = GetJNIForThread(); + + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return NULL; + } + + DisplayPortMetrics* ret = new DisplayPortMetrics(obj, env); + env->DeleteLocalRef(obj); + return ret; +} + +DisplayPortMetrics::DisplayPortMetrics(jfloat a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + if (env->PushLocalFrame(0) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return; + } + + jvalue args[5]; + args[0].f = a0; + args[1].f = a1; + args[2].f = a2; + args[3].f = a3; + args[4].f = a4; + + Init(env->NewObjectA(mDisplayPortMetricsClass, jDisplayPortMetrics, args), env); env->PopLocalFrame(NULL); } -jobject AndroidBridge::CreateEGLSurfaceForCompositorWrapper(jobject aTarget) { +jobject DisplayPortMetrics::getMPosition() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return nullptr; + } + + return static_cast(env->GetObjectField(wrapped_obj, jMPosition)); +} + +jfloat DisplayPortMetrics::getResolution() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return 0.0; + } + + return env->GetFloatField(wrapped_obj, jResolution); +} +jclass GLController::mGLControllerClass = 0; +jmethodID GLController::jCreateEGLSurfaceForCompositorWrapper = 0; +void GLController::InitStubs(JNIEnv *jEnv) { + initInit(); + + mGLControllerClass = getClassGlobalRef("org/mozilla/gecko/gfx/GLController"); + jCreateEGLSurfaceForCompositorWrapper = getMethod("createEGLSurfaceForCompositor", "()Ljavax/microedition/khronos/egl/EGLSurface;"); +} + +GLController* GLController::Wrap(jobject obj) { + JNIEnv *env = GetJNIForThread(); + + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return NULL; + } + + GLController* ret = new GLController(obj, env); + env->DeleteLocalRef(obj); + return ret; +} + +jobject GLController::CreateEGLSurfaceForCompositorWrapper() { JNIEnv *env = GetJNIForThread(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); @@ -2511,7 +3080,7 @@ jobject AndroidBridge::CreateEGLSurfaceForCompositorWrapper(jobject aTarget) { return nullptr; } - jobject temp = env->CallObjectMethod(aTarget, jCreateEGLSurfaceForCompositorWrapper); + jobject temp = env->CallObjectMethod(wrapped_obj, jCreateEGLSurfaceForCompositorWrapper); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); @@ -2520,11 +3089,485 @@ jobject AndroidBridge::CreateEGLSurfaceForCompositorWrapper(jobject aTarget) { env->PopLocalFrame(NULL); return nullptr; } + + jobject ret = static_cast(env->PopLocalFrame(temp)); + return ret; +} +jclass GeckoLayerClient::mGeckoLayerClientClass = 0; +jmethodID GeckoLayerClient::jActivateProgram = 0; +jmethodID GeckoLayerClient::jContentDocumentChanged = 0; +jmethodID GeckoLayerClient::jCreateFrame = 0; +jmethodID GeckoLayerClient::jDeactivateProgram = 0; +jmethodID GeckoLayerClient::jGetDisplayPort = 0; +jmethodID GeckoLayerClient::jIsContentDocumentDisplayed = 0; +jmethodID GeckoLayerClient::jProgressiveUpdateCallback = 0; +jmethodID GeckoLayerClient::jSetFirstPaintViewport = 0; +jmethodID GeckoLayerClient::jSetPageRect = 0; +jmethodID GeckoLayerClient::jSyncFrameMetrics = 0; +jmethodID GeckoLayerClient::jSyncViewportInfo = 0; +void GeckoLayerClient::InitStubs(JNIEnv *jEnv) { + initInit(); + + mGeckoLayerClientClass = getClassGlobalRef("org/mozilla/gecko/gfx/GeckoLayerClient"); + jActivateProgram = getMethod("activateProgram", "()V"); + jContentDocumentChanged = getMethod("contentDocumentChanged", "()V"); + jCreateFrame = getMethod("createFrame", "()Lorg/mozilla/gecko/gfx/LayerRenderer$Frame;"); + jDeactivateProgram = getMethod("deactivateProgram", "()V"); + jGetDisplayPort = getMethod("getDisplayPort", "(ZZILorg/mozilla/gecko/gfx/ImmutableViewportMetrics;)Lorg/mozilla/gecko/gfx/DisplayPortMetrics;"); + jIsContentDocumentDisplayed = getMethod("isContentDocumentDisplayed", "()Z"); + jProgressiveUpdateCallback = getMethod("progressiveUpdateCallback", "(ZFFFFFZ)Lorg/mozilla/gecko/gfx/ProgressiveUpdateData;"); + jSetFirstPaintViewport = getMethod("setFirstPaintViewport", "(FFFFFFF)V"); + jSetPageRect = getMethod("setPageRect", "(FFFF)V"); + jSyncFrameMetrics = getMethod("syncFrameMetrics", "(FFFFFFFZIIIIFZ)Lorg/mozilla/gecko/gfx/ViewTransform;"); + jSyncViewportInfo = getMethod("syncViewportInfo", "(IIIIFZ)Lorg/mozilla/gecko/gfx/ViewTransform;"); +} + +GeckoLayerClient* GeckoLayerClient::Wrap(jobject obj) { + JNIEnv *env = GetJNIForThread(); + + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return NULL; + } + + GeckoLayerClient* ret = new GeckoLayerClient(obj, env); + env->DeleteLocalRef(obj); + return ret; +} + +void GeckoLayerClient::ActivateProgram() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + if (env->PushLocalFrame(0) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return; + } + + env->CallVoidMethod(wrapped_obj, jActivateProgram); + + if (env->ExceptionCheck()) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + env->PopLocalFrame(NULL); + return; + } + + env->PopLocalFrame(NULL); +} + +void GeckoLayerClient::ContentDocumentChanged() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + if (env->PushLocalFrame(0) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return; + } + + env->CallVoidMethod(wrapped_obj, jContentDocumentChanged); + + if (env->ExceptionCheck()) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + env->PopLocalFrame(NULL); + return; + } + + env->PopLocalFrame(NULL); +} + +jobject GeckoLayerClient::CreateFrame() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return nullptr; + } + + if (env->PushLocalFrame(1) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return nullptr; + } + + jobject temp = env->CallObjectMethod(wrapped_obj, jCreateFrame); + + if (env->ExceptionCheck()) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + env->PopLocalFrame(NULL); + return nullptr; + } + jobject ret = static_cast(env->PopLocalFrame(temp)); return ret; } -jobject AndroidBridge::RegisterCompositorWrapper() { +void GeckoLayerClient::DeactivateProgram() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + if (env->PushLocalFrame(0) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return; + } + + env->CallVoidMethod(wrapped_obj, jDeactivateProgram); + + if (env->ExceptionCheck()) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + env->PopLocalFrame(NULL); + return; + } + + env->PopLocalFrame(NULL); +} + +jobject GeckoLayerClient::GetDisplayPort(bool a0, bool a1, int32_t a2, jobject a3) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return nullptr; + } + + if (env->PushLocalFrame(2) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return nullptr; + } + + jvalue args[4]; + args[0].z = a0; + args[1].z = a1; + args[2].i = a2; + args[3].l = a3; + + jobject temp = env->CallObjectMethodA(wrapped_obj, jGetDisplayPort, args); + + if (env->ExceptionCheck()) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + env->PopLocalFrame(NULL); + return nullptr; + } + + jobject ret = static_cast(env->PopLocalFrame(temp)); + return ret; +} + +bool GeckoLayerClient::IsContentDocumentDisplayed() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return false; + } + + if (env->PushLocalFrame(0) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return false; + } + + bool temp = env->CallBooleanMethod(wrapped_obj, jIsContentDocumentDisplayed); + + if (env->ExceptionCheck()) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + env->PopLocalFrame(NULL); + return false; + } + + env->PopLocalFrame(NULL); + return temp; +} + +jobject GeckoLayerClient::ProgressiveUpdateCallback(bool a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4, jfloat a5, bool a6) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return nullptr; + } + + if (env->PushLocalFrame(1) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return nullptr; + } + + jvalue args[7]; + args[0].z = a0; + args[1].f = a1; + args[2].f = a2; + args[3].f = a3; + args[4].f = a4; + args[5].f = a5; + args[6].z = a6; + + jobject temp = env->CallObjectMethodA(wrapped_obj, jProgressiveUpdateCallback, args); + + if (env->ExceptionCheck()) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + env->PopLocalFrame(NULL); + return nullptr; + } + + jobject ret = static_cast(env->PopLocalFrame(temp)); + return ret; +} + +void GeckoLayerClient::SetFirstPaintViewport(jfloat a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4, jfloat a5, jfloat a6) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + if (env->PushLocalFrame(0) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return; + } + + jvalue args[7]; + args[0].f = a0; + args[1].f = a1; + args[2].f = a2; + args[3].f = a3; + args[4].f = a4; + args[5].f = a5; + args[6].f = a6; + + env->CallVoidMethodA(wrapped_obj, jSetFirstPaintViewport, args); + + if (env->ExceptionCheck()) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + env->PopLocalFrame(NULL); + return; + } + + env->PopLocalFrame(NULL); +} + +void GeckoLayerClient::SetPageRect(jfloat a0, jfloat a1, jfloat a2, jfloat a3) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + if (env->PushLocalFrame(0) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return; + } + + jvalue args[4]; + args[0].f = a0; + args[1].f = a1; + args[2].f = a2; + args[3].f = a3; + + env->CallVoidMethodA(wrapped_obj, jSetPageRect, args); + + if (env->ExceptionCheck()) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + env->PopLocalFrame(NULL); + return; + } + + env->PopLocalFrame(NULL); +} + +jobject GeckoLayerClient::SyncFrameMetrics(jfloat a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4, jfloat a5, jfloat a6, bool a7, int32_t a8, int32_t a9, int32_t a10, int32_t a11, jfloat a12, bool a13) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return nullptr; + } + + if (env->PushLocalFrame(1) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return nullptr; + } + + jvalue args[14]; + args[0].f = a0; + args[1].f = a1; + args[2].f = a2; + args[3].f = a3; + args[4].f = a4; + args[5].f = a5; + args[6].f = a6; + args[7].z = a7; + args[8].i = a8; + args[9].i = a9; + args[10].i = a10; + args[11].i = a11; + args[12].f = a12; + args[13].z = a13; + + jobject temp = env->CallObjectMethodA(wrapped_obj, jSyncFrameMetrics, args); + + if (env->ExceptionCheck()) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + env->PopLocalFrame(NULL); + return nullptr; + } + + jobject ret = static_cast(env->PopLocalFrame(temp)); + return ret; +} + +jobject GeckoLayerClient::SyncViewportInfo(int32_t a0, int32_t a1, int32_t a2, int32_t a3, jfloat a4, bool a5) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return nullptr; + } + + if (env->PushLocalFrame(1) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return nullptr; + } + + jvalue args[6]; + args[0].i = a0; + args[1].i = a1; + args[2].i = a2; + args[3].i = a3; + args[4].f = a4; + args[5].z = a5; + + jobject temp = env->CallObjectMethodA(wrapped_obj, jSyncViewportInfo, args); + + if (env->ExceptionCheck()) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + env->PopLocalFrame(NULL); + return nullptr; + } + + jobject ret = static_cast(env->PopLocalFrame(temp)); + return ret; +} +jclass ImmutableViewportMetrics::mImmutableViewportMetricsClass = 0; +jmethodID ImmutableViewportMetrics::jImmutableViewportMetrics = 0; +void ImmutableViewportMetrics::InitStubs(JNIEnv *jEnv) { + initInit(); + + mImmutableViewportMetricsClass = getClassGlobalRef("org/mozilla/gecko/gfx/ImmutableViewportMetrics"); + jImmutableViewportMetrics = getMethod("", "(FFFFFFFFFFFFF)V"); +} + +ImmutableViewportMetrics* ImmutableViewportMetrics::Wrap(jobject obj) { + JNIEnv *env = GetJNIForThread(); + + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return NULL; + } + + ImmutableViewportMetrics* ret = new ImmutableViewportMetrics(obj, env); + env->DeleteLocalRef(obj); + return ret; +} + +ImmutableViewportMetrics::ImmutableViewportMetrics(jfloat a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4, jfloat a5, jfloat a6, jfloat a7, jfloat a8, jfloat a9, jfloat a10, jfloat a11, jfloat a12) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + if (env->PushLocalFrame(0) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return; + } + + jvalue args[13]; + args[0].f = a0; + args[1].f = a1; + args[2].f = a2; + args[3].f = a3; + args[4].f = a4; + args[5].f = a5; + args[6].f = a6; + args[7].f = a7; + args[8].f = a8; + args[9].f = a9; + args[10].f = a10; + args[11].f = a11; + args[12].f = a12; + + Init(env->NewObjectA(mImmutableViewportMetricsClass, jImmutableViewportMetrics, args), env); + env->PopLocalFrame(NULL); +} +jclass LayerView::mLayerViewClass = 0; +jmethodID LayerView::jRegisterCompositorWrapper = 0; +void LayerView::InitStubs(JNIEnv *jEnv) { + initInit(); + + mLayerViewClass = getClassGlobalRef("org/mozilla/gecko/gfx/LayerView"); + jRegisterCompositorWrapper = getStaticMethod("registerCxxCompositor", "()Lorg/mozilla/gecko/gfx/GLController;"); +} + +LayerView* LayerView::Wrap(jobject obj) { + JNIEnv *env = GetJNIForThread(); + + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return NULL; + } + + LayerView* ret = new LayerView(obj, env); + env->DeleteLocalRef(obj); + return ret; +} + +jobject LayerView::RegisterCompositorWrapper() { JNIEnv *env = GetJNIForThread(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); @@ -2547,11 +3590,35 @@ jobject AndroidBridge::RegisterCompositorWrapper() { env->PopLocalFrame(NULL); return nullptr; } + jobject ret = static_cast(env->PopLocalFrame(temp)); return ret; } +jclass NativePanZoomController::mNativePanZoomControllerClass = 0; +jmethodID NativePanZoomController::jPostDelayedCallbackWrapper = 0; +jmethodID NativePanZoomController::jRequestContentRepaintWrapper = 0; +void NativePanZoomController::InitStubs(JNIEnv *jEnv) { + initInit(); -void AndroidBridge::PostDelayedCallbackWrapper(jobject aTarget, int64_t a0) { + mNativePanZoomControllerClass = getClassGlobalRef("org/mozilla/gecko/gfx/NativePanZoomController"); + jPostDelayedCallbackWrapper = getMethod("postDelayedCallback", "(J)V"); + jRequestContentRepaintWrapper = getMethod("requestContentRepaint", "(FFFFF)V"); +} + +NativePanZoomController* NativePanZoomController::Wrap(jobject obj) { + JNIEnv *env = GetJNIForThread(); + + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return NULL; + } + + NativePanZoomController* ret = new NativePanZoomController(obj, env); + env->DeleteLocalRef(obj); + return ret; +} + +void NativePanZoomController::PostDelayedCallbackWrapper(int64_t a0) { JNIEnv *env = GetJNIForThread(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); @@ -2565,7 +3632,7 @@ void AndroidBridge::PostDelayedCallbackWrapper(jobject aTarget, int64_t a0) { return; } - env->CallVoidMethod(aTarget, jPostDelayedCallbackWrapper, a0); + env->CallVoidMethod(wrapped_obj, jPostDelayedCallbackWrapper, a0); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); @@ -2574,10 +3641,11 @@ void AndroidBridge::PostDelayedCallbackWrapper(jobject aTarget, int64_t a0) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } -void AndroidBridge::RequestContentRepaintWrapper(jobject aTarget, jfloat a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4) { +void NativePanZoomController::RequestContentRepaintWrapper(jfloat a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4) { JNIEnv *env = GetJNIForThread(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); @@ -2598,7 +3666,7 @@ void AndroidBridge::RequestContentRepaintWrapper(jobject aTarget, jfloat a0, jfl args[3].f = a3; args[4].f = a4; - env->CallVoidMethodA(aTarget, jRequestContentRepaintWrapper, args); + env->CallVoidMethodA(wrapped_obj, jRequestContentRepaintWrapper, args); if (env->ExceptionCheck()) { ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); @@ -2607,11 +3675,776 @@ void AndroidBridge::RequestContentRepaintWrapper(jobject aTarget, jfloat a0, jfl env->PopLocalFrame(NULL); return; } + + env->PopLocalFrame(NULL); +} +jclass ProgressiveUpdateData::mProgressiveUpdateDataClass = 0; +jmethodID ProgressiveUpdateData::jProgressiveUpdateData = 0; +jmethodID ProgressiveUpdateData::jsetViewport = 0; +jfieldID ProgressiveUpdateData::jabort = 0; +jfieldID ProgressiveUpdateData::jheight = 0; +jfieldID ProgressiveUpdateData::jscale = 0; +jfieldID ProgressiveUpdateData::jwidth = 0; +jfieldID ProgressiveUpdateData::jx = 0; +jfieldID ProgressiveUpdateData::jy = 0; +void ProgressiveUpdateData::InitStubs(JNIEnv *jEnv) { + initInit(); + + mProgressiveUpdateDataClass = getClassGlobalRef("org/mozilla/gecko/gfx/ProgressiveUpdateData"); + jProgressiveUpdateData = getMethod("", "()V"); + jsetViewport = getMethod("setViewport", "(Lorg/mozilla/gecko/gfx/ImmutableViewportMetrics;)V"); + jabort = getField("abort", "Z"); + jheight = getField("height", "F"); + jscale = getField("scale", "F"); + jwidth = getField("width", "F"); + jx = getField("x", "F"); + jy = getField("y", "F"); +} + +ProgressiveUpdateData* ProgressiveUpdateData::Wrap(jobject obj) { + JNIEnv *env = GetJNIForThread(); + + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return NULL; + } + + ProgressiveUpdateData* ret = new ProgressiveUpdateData(obj, env); + env->DeleteLocalRef(obj); + return ret; +} + +ProgressiveUpdateData::ProgressiveUpdateData() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + if (env->PushLocalFrame(0) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return; + } + + Init(env->NewObject(mProgressiveUpdateDataClass, jProgressiveUpdateData), env); env->PopLocalFrame(NULL); } -jstring AndroidBridge::GetClipboardTextWrapper() { - JNIEnv *env = GetJNIEnv(); +void ProgressiveUpdateData::setViewport(jobject a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + if (env->PushLocalFrame(1) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return; + } + + env->CallVoidMethod(wrapped_obj, jsetViewport, a0); + + if (env->ExceptionCheck()) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + env->PopLocalFrame(NULL); + return; + } + + env->PopLocalFrame(NULL); +} + +bool ProgressiveUpdateData::getabort() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return false; + } + + return env->GetBooleanField(wrapped_obj, jabort); +} + +void ProgressiveUpdateData::setabort(bool a0) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + env->SetBooleanField(wrapped_obj, jabort, a0); +} + +jfloat ProgressiveUpdateData::getheight() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return 0.0; + } + + return env->GetFloatField(wrapped_obj, jheight); +} + +void ProgressiveUpdateData::setheight(jfloat a0) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + env->SetFloatField(wrapped_obj, jheight, a0); +} + +jfloat ProgressiveUpdateData::getscale() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return 0.0; + } + + return env->GetFloatField(wrapped_obj, jscale); +} + +void ProgressiveUpdateData::setscale(jfloat a0) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + env->SetFloatField(wrapped_obj, jscale, a0); +} + +jfloat ProgressiveUpdateData::getwidth() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return 0.0; + } + + return env->GetFloatField(wrapped_obj, jwidth); +} + +void ProgressiveUpdateData::setwidth(jfloat a0) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + env->SetFloatField(wrapped_obj, jwidth, a0); +} + +jfloat ProgressiveUpdateData::getx() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return 0.0; + } + + return env->GetFloatField(wrapped_obj, jx); +} + +void ProgressiveUpdateData::setx(jfloat a0) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + env->SetFloatField(wrapped_obj, jx, a0); +} + +jfloat ProgressiveUpdateData::gety() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return 0.0; + } + + return env->GetFloatField(wrapped_obj, jy); +} + +void ProgressiveUpdateData::sety(jfloat a0) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + env->SetFloatField(wrapped_obj, jy, a0); +} +jclass ViewTransform::mViewTransformClass = 0; +jmethodID ViewTransform::jViewTransform = 0; +jfieldID ViewTransform::jfixedLayerMarginBottom = 0; +jfieldID ViewTransform::jfixedLayerMarginLeft = 0; +jfieldID ViewTransform::jfixedLayerMarginRight = 0; +jfieldID ViewTransform::jfixedLayerMarginTop = 0; +jfieldID ViewTransform::joffsetX = 0; +jfieldID ViewTransform::joffsetY = 0; +jfieldID ViewTransform::jscale = 0; +jfieldID ViewTransform::jx = 0; +jfieldID ViewTransform::jy = 0; +void ViewTransform::InitStubs(JNIEnv *jEnv) { + initInit(); + + mViewTransformClass = getClassGlobalRef("org/mozilla/gecko/gfx/ViewTransform"); + jViewTransform = getMethod("", "(FFF)V"); + jfixedLayerMarginBottom = getField("fixedLayerMarginBottom", "F"); + jfixedLayerMarginLeft = getField("fixedLayerMarginLeft", "F"); + jfixedLayerMarginRight = getField("fixedLayerMarginRight", "F"); + jfixedLayerMarginTop = getField("fixedLayerMarginTop", "F"); + joffsetX = getField("offsetX", "F"); + joffsetY = getField("offsetY", "F"); + jscale = getField("scale", "F"); + jx = getField("x", "F"); + jy = getField("y", "F"); +} + +ViewTransform* ViewTransform::Wrap(jobject obj) { + JNIEnv *env = GetJNIForThread(); + + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return NULL; + } + + ViewTransform* ret = new ViewTransform(obj, env); + env->DeleteLocalRef(obj); + return ret; +} + +ViewTransform::ViewTransform(jfloat a0, jfloat a1, jfloat a2) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + if (env->PushLocalFrame(0) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return; + } + + jvalue args[3]; + args[0].f = a0; + args[1].f = a1; + args[2].f = a2; + + Init(env->NewObjectA(mViewTransformClass, jViewTransform, args), env); + env->PopLocalFrame(NULL); +} + +jfloat ViewTransform::getfixedLayerMarginBottom() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return 0.0; + } + + return env->GetFloatField(wrapped_obj, jfixedLayerMarginBottom); +} + +void ViewTransform::setfixedLayerMarginBottom(jfloat a0) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + env->SetFloatField(wrapped_obj, jfixedLayerMarginBottom, a0); +} + +jfloat ViewTransform::getfixedLayerMarginLeft() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return 0.0; + } + + return env->GetFloatField(wrapped_obj, jfixedLayerMarginLeft); +} + +void ViewTransform::setfixedLayerMarginLeft(jfloat a0) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + env->SetFloatField(wrapped_obj, jfixedLayerMarginLeft, a0); +} + +jfloat ViewTransform::getfixedLayerMarginRight() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return 0.0; + } + + return env->GetFloatField(wrapped_obj, jfixedLayerMarginRight); +} + +void ViewTransform::setfixedLayerMarginRight(jfloat a0) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + env->SetFloatField(wrapped_obj, jfixedLayerMarginRight, a0); +} + +jfloat ViewTransform::getfixedLayerMarginTop() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return 0.0; + } + + return env->GetFloatField(wrapped_obj, jfixedLayerMarginTop); +} + +void ViewTransform::setfixedLayerMarginTop(jfloat a0) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + env->SetFloatField(wrapped_obj, jfixedLayerMarginTop, a0); +} + +jfloat ViewTransform::getoffsetX() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return 0.0; + } + + return env->GetFloatField(wrapped_obj, joffsetX); +} + +void ViewTransform::setoffsetX(jfloat a0) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + env->SetFloatField(wrapped_obj, joffsetX, a0); +} + +jfloat ViewTransform::getoffsetY() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return 0.0; + } + + return env->GetFloatField(wrapped_obj, joffsetY); +} + +void ViewTransform::setoffsetY(jfloat a0) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + env->SetFloatField(wrapped_obj, joffsetY, a0); +} + +jfloat ViewTransform::getscale() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return 0.0; + } + + return env->GetFloatField(wrapped_obj, jscale); +} + +void ViewTransform::setscale(jfloat a0) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + env->SetFloatField(wrapped_obj, jscale, a0); +} + +jfloat ViewTransform::getx() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return 0.0; + } + + return env->GetFloatField(wrapped_obj, jx); +} + +void ViewTransform::setx(jfloat a0) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + env->SetFloatField(wrapped_obj, jx, a0); +} + +jfloat ViewTransform::gety() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return 0.0; + } + + return env->GetFloatField(wrapped_obj, jy); +} + +void ViewTransform::sety(jfloat a0) { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + env->SetFloatField(wrapped_obj, jy, a0); +} +jclass NativeZip::mNativeZipClass = 0; +jmethodID NativeZip::jCreateInputStream = 0; +void NativeZip::InitStubs(JNIEnv *jEnv) { + initInit(); + + mNativeZipClass = getClassGlobalRef("org/mozilla/gecko/mozglue/NativeZip"); + jCreateInputStream = getMethod("createInputStream", "(Ljava/nio/ByteBuffer;I)Ljava/io/InputStream;"); +} + +NativeZip* NativeZip::Wrap(jobject obj) { + JNIEnv *env = GetJNIForThread(); + + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return NULL; + } + + NativeZip* ret = new NativeZip(obj, env); + env->DeleteLocalRef(obj); + return ret; +} + +jobject NativeZip::CreateInputStream(jobject a0, int32_t a1) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return nullptr; + } + + if (env->PushLocalFrame(2) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return nullptr; + } + + jobject temp = env->CallObjectMethod(wrapped_obj, jCreateInputStream, a0, a1); + + if (env->ExceptionCheck()) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + env->PopLocalFrame(NULL); + return nullptr; + } + + jobject ret = static_cast(env->PopLocalFrame(temp)); + return ret; +} +jclass MatrixBlobCursor::mMatrixBlobCursorClass = 0; +jmethodID MatrixBlobCursor::jMatrixBlobCursor = 0; +jmethodID MatrixBlobCursor::jMatrixBlobCursor0 = 0; +jmethodID MatrixBlobCursor::jAddRow = 0; +jmethodID MatrixBlobCursor::jAddRow1 = 0; +jmethodID MatrixBlobCursor::jAddRow2 = 0; +void MatrixBlobCursor::InitStubs(JNIEnv *jEnv) { + initInit(); + + mMatrixBlobCursorClass = getClassGlobalRef("org/mozilla/gecko/sqlite/MatrixBlobCursor"); + jMatrixBlobCursor = getMethod("", "([Ljava/lang/String;)V"); + jMatrixBlobCursor0 = getMethod("", "([Ljava/lang/String;I)V"); + jAddRow = getMethod("addRow", "(Ljava/lang/Iterable;)V"); + jAddRow1 = getMethod("addRow", "(Ljava/util/ArrayList;I)V"); + jAddRow2 = getMethod("addRow", "([Ljava/lang/Object;)V"); +} + +MatrixBlobCursor* MatrixBlobCursor::Wrap(jobject obj) { + JNIEnv *env = GetJNIForThread(); + + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return NULL; + } + + MatrixBlobCursor* ret = new MatrixBlobCursor(obj, env); + env->DeleteLocalRef(obj); + return ret; +} + +MatrixBlobCursor::MatrixBlobCursor(jobjectArray a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + if (env->PushLocalFrame(1) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return; + } + + Init(env->NewObject(mMatrixBlobCursorClass, jMatrixBlobCursor, a0), env); + env->PopLocalFrame(NULL); +} + +MatrixBlobCursor::MatrixBlobCursor(jobjectArray a0, int32_t a1) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + if (env->PushLocalFrame(1) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return; + } + + Init(env->NewObject(mMatrixBlobCursorClass, jMatrixBlobCursor0, a0, a1), env); + env->PopLocalFrame(NULL); +} + +void MatrixBlobCursor::AddRow(jobject a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + if (env->PushLocalFrame(1) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return; + } + + env->CallVoidMethod(wrapped_obj, jAddRow, a0); + + if (env->ExceptionCheck()) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + env->PopLocalFrame(NULL); + return; + } + + env->PopLocalFrame(NULL); +} + +void MatrixBlobCursor::AddRow(jobject a0, int32_t a1) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + if (env->PushLocalFrame(1) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return; + } + + env->CallVoidMethod(wrapped_obj, jAddRow1, a0, a1); + + if (env->ExceptionCheck()) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + env->PopLocalFrame(NULL); + return; + } + + env->PopLocalFrame(NULL); +} + +void MatrixBlobCursor::AddRow(jobjectArray a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + if (env->PushLocalFrame(1) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return; + } + + env->CallVoidMethod(wrapped_obj, jAddRow2, a0); + + if (env->ExceptionCheck()) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + env->PopLocalFrame(NULL); + return; + } + + env->PopLocalFrame(NULL); +} +jclass SQLiteBridgeException::mSQLiteBridgeExceptionClass = 0; +jmethodID SQLiteBridgeException::jSQLiteBridgeException = 0; +jmethodID SQLiteBridgeException::jSQLiteBridgeException0 = 0; +jfieldID SQLiteBridgeException::jserialVersionUID = 0; +void SQLiteBridgeException::InitStubs(JNIEnv *jEnv) { + initInit(); + + mSQLiteBridgeExceptionClass = getClassGlobalRef("org/mozilla/gecko/sqlite/SQLiteBridgeException"); + jSQLiteBridgeException = getMethod("", "()V"); + jSQLiteBridgeException0 = getMethod("", "(Ljava/lang/String;)V"); + jserialVersionUID = getStaticField("serialVersionUID", "J"); +} + +SQLiteBridgeException* SQLiteBridgeException::Wrap(jobject obj) { + JNIEnv *env = GetJNIForThread(); + + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return NULL; + } + + SQLiteBridgeException* ret = new SQLiteBridgeException(obj, env); + env->DeleteLocalRef(obj); + return ret; +} + +SQLiteBridgeException::SQLiteBridgeException() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + if (env->PushLocalFrame(0) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return; + } + + Init(env->NewObject(mSQLiteBridgeExceptionClass, jSQLiteBridgeException), env); + env->PopLocalFrame(NULL); +} + +SQLiteBridgeException::SQLiteBridgeException(const nsAString& a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + if (env->PushLocalFrame(1) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return; + } + + jstring j0 = AndroidBridge::NewJavaString(env, a0); + + Init(env->NewObject(mSQLiteBridgeExceptionClass, jSQLiteBridgeException0, j0), env); + env->PopLocalFrame(NULL); +} + +int64_t SQLiteBridgeException::getserialVersionUID() { + JNIEnv *env = GetJNIForThread(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return 0; + } + + return env->GetStaticLongField(mSQLiteBridgeExceptionClass, jserialVersionUID); +} +jclass Clipboard::mClipboardClass = 0; +jmethodID Clipboard::jClearText = 0; +jmethodID Clipboard::jGetClipboardTextWrapper = 0; +jmethodID Clipboard::jHasText = 0; +jmethodID Clipboard::jSetClipboardText = 0; +void Clipboard::InitStubs(JNIEnv *jEnv) { + initInit(); + + mClipboardClass = getClassGlobalRef("org/mozilla/gecko/util/Clipboard"); + jClearText = getStaticMethod("clearText", "()V"); + jGetClipboardTextWrapper = getStaticMethod("getText", "()Ljava/lang/String;"); + jHasText = getStaticMethod("hasText", "()Z"); + jSetClipboardText = getStaticMethod("setText", "(Ljava/lang/CharSequence;)V"); +} + +Clipboard* Clipboard::Wrap(jobject obj) { + JNIEnv *env = GetJNIForThread(); + + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return NULL; + } + + Clipboard* ret = new Clipboard(obj, env); + env->DeleteLocalRef(obj); + return ret; +} + +void Clipboard::ClearText() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return; + } + + if (env->PushLocalFrame(0) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return; + } + + env->CallStaticVoidMethod(mClipboardClass, jClearText); + + if (env->ExceptionCheck()) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + env->PopLocalFrame(NULL); + return; + } + + env->PopLocalFrame(NULL); +} + +jstring Clipboard::GetClipboardTextWrapper() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return nullptr; @@ -2633,12 +4466,41 @@ jstring AndroidBridge::GetClipboardTextWrapper() { env->PopLocalFrame(NULL); return nullptr; } + jstring ret = static_cast(env->PopLocalFrame(temp)); return ret; } -void AndroidBridge::SetClipboardText(const nsAString& a0) { - JNIEnv *env = GetJNIEnv(); +bool Clipboard::HasText() { + JNIEnv *env = AndroidBridge::GetJNIEnv(); + if (!env) { + ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); + return false; + } + + if (env->PushLocalFrame(0) != 0) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + return false; + } + + bool temp = env->CallStaticBooleanMethod(mClipboardClass, jHasText); + + if (env->ExceptionCheck()) { + ALOG_BRIDGE("Exceptional exit of: %s", __PRETTY_FUNCTION__); + env->ExceptionDescribe(); + env->ExceptionClear(); + env->PopLocalFrame(NULL); + return false; + } + + env->PopLocalFrame(NULL); + return temp; +} + +void Clipboard::SetClipboardText(const nsAString& a0) { + JNIEnv *env = AndroidBridge::GetJNIEnv(); if (!env) { ALOG_BRIDGE("Aborted: No env - %s", __PRETTY_FUNCTION__); return; @@ -2651,7 +4513,7 @@ void AndroidBridge::SetClipboardText(const nsAString& a0) { return; } - jstring j0 = NewJavaString(env, a0); + jstring j0 = AndroidBridge::NewJavaString(env, a0); env->CallStaticVoidMethod(mClipboardClass, jSetClipboardText, j0); @@ -2662,5 +4524,29 @@ void AndroidBridge::SetClipboardText(const nsAString& a0) { env->PopLocalFrame(NULL); return; } + env->PopLocalFrame(NULL); } + +void InitStubs(JNIEnv *jEnv) { + GeckoAppShell::InitStubs(jEnv); + JavaDomKeyLocation::InitStubs(jEnv); + GeckoJavaSampler::InitStubs(jEnv); + SurfaceBits::InitStubs(jEnv); + ThumbnailHelper::InitStubs(jEnv); + DisplayPortMetrics::InitStubs(jEnv); + GLController::InitStubs(jEnv); + GeckoLayerClient::InitStubs(jEnv); + ImmutableViewportMetrics::InitStubs(jEnv); + LayerView::InitStubs(jEnv); + NativePanZoomController::InitStubs(jEnv); + ProgressiveUpdateData::InitStubs(jEnv); + ViewTransform::InitStubs(jEnv); + NativeZip::InitStubs(jEnv); + MatrixBlobCursor::InitStubs(jEnv); + SQLiteBridgeException::InitStubs(jEnv); + Clipboard::InitStubs(jEnv); +} +} /* android */ +} /* widget */ +} /* mozilla */ diff --git a/widget/android/GeneratedJNIWrappers.h b/widget/android/GeneratedJNIWrappers.h index c755afbe9234..3f0ad5e4647f 100644 --- a/widget/android/GeneratedJNIWrappers.h +++ b/widget/android/GeneratedJNIWrappers.h @@ -1,206 +1,505 @@ -protected: - - -jclass mGeckoAppShellClass; -jmethodID jAcknowledgeEvent; -jmethodID jAddPluginViewWrapper; -jmethodID jAlertsProgressListener_OnProgress; -jmethodID jCancelVibrate; -jmethodID jCheckURIVisited; -jmethodID jClearMessageList; -jmethodID jCloseCamera; -jmethodID jCloseNotification; -jmethodID jCreateMessageListWrapper; -jmethodID jCreateShortcut; -jmethodID jDeleteMessageWrapper; -jmethodID jDisableBatteryNotifications; -jmethodID jDisableNetworkNotifications; -jmethodID jDisableScreenOrientationNotifications; -jmethodID jDisableSensor; -jmethodID jEnableBatteryNotifications; -jmethodID jEnableLocation; -jmethodID jEnableLocationHighAccuracy; -jmethodID jEnableNetworkNotifications; -jmethodID jEnableScreenOrientationNotifications; -jmethodID jEnableSensor; -jmethodID jGetContext; -jmethodID jGetCurrentBatteryInformationWrapper; -jmethodID jGetCurrentNetworkInformationWrapper; -jmethodID jGetDensity; -jmethodID jGetDpiWrapper; -jmethodID jGetExtensionFromMimeTypeWrapper; -jmethodID jGetHandlersForMimeTypeWrapper; -jmethodID jGetHandlersForURLWrapper; -jmethodID jGetIconForExtensionWrapper; -jmethodID jGetMessageWrapper; -jmethodID jGetMimeTypeFromExtensionsWrapper; -jmethodID jGetNextMessageInListWrapper; -jmethodID jGetProxyForURIWrapper; -jmethodID jGetScreenDepthWrapper; -jmethodID jGetScreenOrientationWrapper; -jmethodID jGetShowPasswordSetting; -jmethodID jGetSystemColoursWrapper; -jmethodID jHandleGeckoMessageWrapper; -jmethodID jHideProgressDialog; -jmethodID jInitCameraWrapper; -jmethodID jIsNetworkLinkKnown; -jmethodID jIsNetworkLinkUp; -jmethodID jIsTablet; -jmethodID jKillAnyZombies; -jmethodID jLockScreenOrientation; -jmethodID jMarkURIVisited; -jmethodID jMoveTaskToBack; -jmethodID jNetworkLinkType; -jmethodID jNotifyDefaultPrevented; -jmethodID jNotifyIME; -jmethodID jNotifyIMEChange; -jmethodID jNotifyIMEContext; -jmethodID jNotifyWakeLockChanged; -jmethodID jNotifyXreExit; -jmethodID jOpenUriExternal; -jmethodID jPerformHapticFeedback; -jmethodID jPumpMessageLoop; -jmethodID jRegisterSurfaceTextureFrameListener; -jmethodID jRemovePluginView; -jmethodID jScanMedia; -jmethodID jScheduleRestart; -jmethodID jSendMessageWrapper; -jmethodID jSetFullScreen; -jmethodID jSetKeepScreenOn; -jmethodID jSetSelectedLocale; -jmethodID jSetURITitle; -jmethodID jShowAlertNotificationWrapper; -jmethodID jShowFilePickerAsyncWrapper; -jmethodID jShowFilePickerForExtensionsWrapper; -jmethodID jShowFilePickerForMimeTypeWrapper; -jmethodID jShowInputMethodPicker; -jmethodID jUnlockProfile; -jmethodID jUnlockScreenOrientation; -jmethodID jUnregisterSurfaceTextureFrameListener; -jmethodID jVibrate1; -jmethodID jVibrateA; - -jclass mGeckoJavaSamplerClass; -jmethodID jGetFrameNameJavaProfilingWrapper; -jmethodID jGetSampleTimeJavaProfiling; -jmethodID jGetThreadNameJavaProfilingWrapper; -jmethodID jPauseJavaProfiling; -jmethodID jStartJavaProfiling; -jmethodID jStopJavaProfiling; -jmethodID jUnpauseJavaProfiling; - -jclass mThumbnailHelperClass; -jmethodID jSendThumbnail; - -jclass mGLControllerClass; -jmethodID jCreateEGLSurfaceForCompositorWrapper; - -jclass mLayerViewClass; -jmethodID jRegisterCompositorWrapper; - -jclass mNativePanZoomControllerClass; -jmethodID jPostDelayedCallbackWrapper; -jmethodID jRequestContentRepaintWrapper; - -jclass mClipboardClass; -jmethodID jGetClipboardTextWrapper; -jmethodID jSetClipboardText; - // GENERATED CODE // Generated by the Java program at /build/annotationProcessors at compile time from // annotations on Java methods. To update, change the annotations on the corresponding Java // methods and rerun the build. Manually updating this file will cause your build to fail. -public: +#ifndef GeneratedJNIWrappers_h__ +#define GeneratedJNIWrappers_h__ -void AcknowledgeEvent(); -void AddPluginViewWrapper(jobject a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4, bool a5); -void AlertsProgressListener_OnProgress(const nsAString& a0, int64_t a1, int64_t a2, const nsAString& a3); -void CancelVibrate(); -void CheckURIVisited(const nsAString& a0); -void ClearMessageList(int32_t a0); -void CloseCamera(); -void CloseNotification(const nsAString& a0); -void CreateMessageListWrapper(int64_t a0, int64_t a1, jobjectArray a2, int32_t a3, int32_t a4, bool a5, int32_t a6); -void CreateShortcut(const nsAString& a0, const nsAString& a1, const nsAString& a2, const nsAString& a3); -void DeleteMessageWrapper(int32_t a0, int32_t a1); -void DisableBatteryNotifications(); -void DisableNetworkNotifications(); -void DisableScreenOrientationNotifications(); -void DisableSensor(int32_t a0); -void EnableBatteryNotifications(); -void EnableLocation(bool a0); -void EnableLocationHighAccuracy(bool a0); -void EnableNetworkNotifications(); -void EnableScreenOrientationNotifications(); -void EnableSensor(int32_t a0); -jobject GetContext(); -jdoubleArray GetCurrentBatteryInformationWrapper(); -jdoubleArray GetCurrentNetworkInformationWrapper(); -jfloat GetDensity(); -int32_t GetDpiWrapper(); -jstring GetExtensionFromMimeTypeWrapper(const nsAString& a0); -jobjectArray GetHandlersForMimeTypeWrapper(const nsAString& a0, const nsAString& a1); -jobjectArray GetHandlersForURLWrapper(const nsAString& a0, const nsAString& a1); -jbyteArray GetIconForExtensionWrapper(const nsAString& a0, int32_t a1); -void GetMessageWrapper(int32_t a0, int32_t a1); -jstring GetMimeTypeFromExtensionsWrapper(const nsAString& a0); -void GetNextMessageInListWrapper(int32_t a0, int32_t a1); -jstring GetProxyForURIWrapper(const nsAString& a0, const nsAString& a1, const nsAString& a2, int32_t a3); -int32_t GetScreenDepthWrapper(); -int16_t GetScreenOrientationWrapper(); -bool GetShowPasswordSetting(); -jintArray GetSystemColoursWrapper(); -jstring HandleGeckoMessageWrapper(const nsAString& a0); -void HideProgressDialog(); -jintArray InitCameraWrapper(const nsAString& a0, int32_t a1, int32_t a2, int32_t a3); -bool IsNetworkLinkKnown(); -bool IsNetworkLinkUp(); -bool IsTablet(); -void KillAnyZombies(); -void LockScreenOrientation(int32_t a0); -void MarkURIVisited(const nsAString& a0); -void MoveTaskToBack(); -int32_t NetworkLinkType(); -void NotifyDefaultPrevented(bool a0); -static void NotifyIME(int32_t a0); -static void NotifyIMEChange(const nsAString& a0, int32_t a1, int32_t a2, int32_t a3); -static void NotifyIMEContext(int32_t a0, const nsAString& a1, const nsAString& a2, const nsAString& a3); -void NotifyWakeLockChanged(const nsAString& a0, const nsAString& a1); -void NotifyXreExit(); -bool OpenUriExternal(const nsAString& a0, const nsAString& a1, const nsAString& a2 = EmptyString(), const nsAString& a3 = EmptyString(), const nsAString& a4 = EmptyString(), const nsAString& a5 = EmptyString()); -void PerformHapticFeedback(bool a0); -bool PumpMessageLoop(); -void RegisterSurfaceTextureFrameListener(jobject a0, int32_t a1); -void RemovePluginView(jobject a0, bool a1); -void ScanMedia(const nsAString& a0, const nsAString& a1); -void ScheduleRestart(); -void SendMessageWrapper(const nsAString& a0, const nsAString& a1, int32_t a2); -void SetFullScreen(bool a0); -void SetKeepScreenOn(bool a0); -void SetSelectedLocale(const nsAString& a0); -void SetURITitle(const nsAString& a0, const nsAString& a1); -void ShowAlertNotificationWrapper(const nsAString& a0, const nsAString& a1, const nsAString& a2, const nsAString& a3, const nsAString& a4); -void ShowFilePickerAsyncWrapper(const nsAString& a0, int64_t a1); -jstring ShowFilePickerForExtensionsWrapper(const nsAString& a0); -jstring ShowFilePickerForMimeTypeWrapper(const nsAString& a0); -void ShowInputMethodPicker(); -bool UnlockProfile(); -void UnlockScreenOrientation(); -void UnregisterSurfaceTextureFrameListener(jobject a0); -void Vibrate1(int64_t a0); -void VibrateA(jlongArray a0, int32_t a1); -jstring GetFrameNameJavaProfilingWrapper(int32_t a0, int32_t a1, int32_t a2); -jdouble GetSampleTimeJavaProfiling(int32_t a0, int32_t a1); -jstring GetThreadNameJavaProfilingWrapper(int32_t a0); -void PauseJavaProfiling(); -void StartJavaProfiling(int32_t a0, int32_t a1); -void StopJavaProfiling(); -void UnpauseJavaProfiling(); -void SendThumbnail(jobject a0, int32_t a1, bool a2); -jobject CreateEGLSurfaceForCompositorWrapper(jobject aTarget); -jobject RegisterCompositorWrapper(); -void PostDelayedCallbackWrapper(jobject aTarget, int64_t a0); -void RequestContentRepaintWrapper(jobject aTarget, jfloat a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4); -jstring GetClipboardTextWrapper(); -void SetClipboardText(const nsAString& a0); +#include "nsXPCOMStrings.h" +#include "AndroidJavaWrappers.h" + +namespace mozilla { +namespace widget { +namespace android { +void InitStubs(JNIEnv *jEnv); + +class GeckoAppShell : public AutoGlobalWrappedJavaObject { +public: + static void InitStubs(JNIEnv *jEnv); + static GeckoAppShell* Wrap(jobject obj); + GeckoAppShell(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {}; + static void AcknowledgeEvent(); + static void AddPluginViewWrapper(jobject a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4, bool a5); + static void AlertsProgressListener_OnProgress(const nsAString& a0, int64_t a1, int64_t a2, const nsAString& a3); + static void CancelVibrate(); + static void CheckURIVisited(const nsAString& a0); + static void ClearMessageList(int32_t a0); + static void CloseCamera(); + static void CloseNotification(const nsAString& a0); + static void CreateMessageListWrapper(int64_t a0, int64_t a1, jobjectArray a2, int32_t a3, int32_t a4, bool a5, int32_t a6); + static void CreateShortcut(const nsAString& a0, const nsAString& a1, const nsAString& a2, const nsAString& a3); + static void DeleteMessageWrapper(int32_t a0, int32_t a1); + static void DisableBatteryNotifications(); + static void DisableNetworkNotifications(); + static void DisableScreenOrientationNotifications(); + static void DisableSensor(int32_t a0); + static void EnableBatteryNotifications(); + static void EnableLocation(bool a0); + static void EnableLocationHighAccuracy(bool a0); + static void EnableNetworkNotifications(); + static void EnableScreenOrientationNotifications(); + static void EnableSensor(int32_t a0); + static jobject GetContext(); + static jdoubleArray GetCurrentBatteryInformationWrapper(); + static jdoubleArray GetCurrentNetworkInformationWrapper(); + static jfloat GetDensity(); + static int32_t GetDpiWrapper(); + static jstring GetExtensionFromMimeTypeWrapper(const nsAString& a0); + static jobjectArray GetHandlersForMimeTypeWrapper(const nsAString& a0, const nsAString& a1); + static jobjectArray GetHandlersForURLWrapper(const nsAString& a0, const nsAString& a1); + static jbyteArray GetIconForExtensionWrapper(const nsAString& a0, int32_t a1); + static void GetMessageWrapper(int32_t a0, int32_t a1); + static jstring GetMimeTypeFromExtensionsWrapper(const nsAString& a0); + static void GetNextMessageInListWrapper(int32_t a0, int32_t a1); + static jstring GetProxyForURIWrapper(const nsAString& a0, const nsAString& a1, const nsAString& a2, int32_t a3); + static int32_t GetScreenDepthWrapper(); + static int16_t GetScreenOrientationWrapper(); + static bool GetShowPasswordSetting(); + static jintArray GetSystemColoursWrapper(); + static jstring HandleGeckoMessageWrapper(const nsAString& a0); + static void HideProgressDialog(); + static jintArray InitCameraWrapper(const nsAString& a0, int32_t a1, int32_t a2, int32_t a3); + static bool IsNetworkLinkKnown(); + static bool IsNetworkLinkUp(); + static bool IsTablet(); + static void KillAnyZombies(); + static void LockScreenOrientation(int32_t a0); + static void MarkURIVisited(const nsAString& a0); + static void MoveTaskToBack(); + static int32_t NetworkLinkType(); + static void NotifyDefaultPrevented(bool a0); + static void NotifyIME(int32_t a0); + static void NotifyIMEChange(const nsAString& a0, int32_t a1, int32_t a2, int32_t a3); + static void NotifyIMEContext(int32_t a0, const nsAString& a1, const nsAString& a2, const nsAString& a3); + static void NotifyWakeLockChanged(const nsAString& a0, const nsAString& a1); + static void NotifyXreExit(); + static bool OpenUriExternal(const nsAString& a0, const nsAString& a1, const nsAString& a2 = EmptyString(), const nsAString& a3 = EmptyString(), const nsAString& a4 = EmptyString(), const nsAString& a5 = EmptyString()); + static void PerformHapticFeedback(bool a0); + static bool PumpMessageLoop(); + static void RegisterSurfaceTextureFrameListener(jobject a0, int32_t a1); + static void RemovePluginView(jobject a0, bool a1); + static void ScanMedia(const nsAString& a0, const nsAString& a1); + static void ScheduleRestart(); + static void SendMessageWrapper(const nsAString& a0, const nsAString& a1, int32_t a2); + static void SetFullScreen(bool a0); + static void SetKeepScreenOn(bool a0); + static void SetSelectedLocale(const nsAString& a0); + static void SetURITitle(const nsAString& a0, const nsAString& a1); + static void ShowAlertNotificationWrapper(const nsAString& a0, const nsAString& a1, const nsAString& a2, const nsAString& a3, const nsAString& a4); + static void ShowFilePickerAsyncWrapper(const nsAString& a0, int64_t a1); + static jstring ShowFilePickerForExtensionsWrapper(const nsAString& a0); + static jstring ShowFilePickerForMimeTypeWrapper(const nsAString& a0); + static void ShowInputMethodPicker(); + static bool UnlockProfile(); + static void UnlockScreenOrientation(); + static void UnregisterSurfaceTextureFrameListener(jobject a0); + static void Vibrate1(int64_t a0); + static void VibrateA(jlongArray a0, int32_t a1); + GeckoAppShell() : AutoGlobalWrappedJavaObject() {}; +protected: + static jclass mGeckoAppShellClass; + static jmethodID jAcknowledgeEvent; + static jmethodID jAddPluginViewWrapper; + static jmethodID jAlertsProgressListener_OnProgress; + static jmethodID jCancelVibrate; + static jmethodID jCheckURIVisited; + static jmethodID jClearMessageList; + static jmethodID jCloseCamera; + static jmethodID jCloseNotification; + static jmethodID jCreateMessageListWrapper; + static jmethodID jCreateShortcut; + static jmethodID jDeleteMessageWrapper; + static jmethodID jDisableBatteryNotifications; + static jmethodID jDisableNetworkNotifications; + static jmethodID jDisableScreenOrientationNotifications; + static jmethodID jDisableSensor; + static jmethodID jEnableBatteryNotifications; + static jmethodID jEnableLocation; + static jmethodID jEnableLocationHighAccuracy; + static jmethodID jEnableNetworkNotifications; + static jmethodID jEnableScreenOrientationNotifications; + static jmethodID jEnableSensor; + static jmethodID jGetContext; + static jmethodID jGetCurrentBatteryInformationWrapper; + static jmethodID jGetCurrentNetworkInformationWrapper; + static jmethodID jGetDensity; + static jmethodID jGetDpiWrapper; + static jmethodID jGetExtensionFromMimeTypeWrapper; + static jmethodID jGetHandlersForMimeTypeWrapper; + static jmethodID jGetHandlersForURLWrapper; + static jmethodID jGetIconForExtensionWrapper; + static jmethodID jGetMessageWrapper; + static jmethodID jGetMimeTypeFromExtensionsWrapper; + static jmethodID jGetNextMessageInListWrapper; + static jmethodID jGetProxyForURIWrapper; + static jmethodID jGetScreenDepthWrapper; + static jmethodID jGetScreenOrientationWrapper; + static jmethodID jGetShowPasswordSetting; + static jmethodID jGetSystemColoursWrapper; + static jmethodID jHandleGeckoMessageWrapper; + static jmethodID jHideProgressDialog; + static jmethodID jInitCameraWrapper; + static jmethodID jIsNetworkLinkKnown; + static jmethodID jIsNetworkLinkUp; + static jmethodID jIsTablet; + static jmethodID jKillAnyZombies; + static jmethodID jLockScreenOrientation; + static jmethodID jMarkURIVisited; + static jmethodID jMoveTaskToBack; + static jmethodID jNetworkLinkType; + static jmethodID jNotifyDefaultPrevented; + static jmethodID jNotifyIME; + static jmethodID jNotifyIMEChange; + static jmethodID jNotifyIMEContext; + static jmethodID jNotifyWakeLockChanged; + static jmethodID jNotifyXreExit; + static jmethodID jOpenUriExternal; + static jmethodID jPerformHapticFeedback; + static jmethodID jPumpMessageLoop; + static jmethodID jRegisterSurfaceTextureFrameListener; + static jmethodID jRemovePluginView; + static jmethodID jScanMedia; + static jmethodID jScheduleRestart; + static jmethodID jSendMessageWrapper; + static jmethodID jSetFullScreen; + static jmethodID jSetKeepScreenOn; + static jmethodID jSetSelectedLocale; + static jmethodID jSetURITitle; + static jmethodID jShowAlertNotificationWrapper; + static jmethodID jShowFilePickerAsyncWrapper; + static jmethodID jShowFilePickerForExtensionsWrapper; + static jmethodID jShowFilePickerForMimeTypeWrapper; + static jmethodID jShowInputMethodPicker; + static jmethodID jUnlockProfile; + static jmethodID jUnlockScreenOrientation; + static jmethodID jUnregisterSurfaceTextureFrameListener; + static jmethodID jVibrate1; + static jmethodID jVibrateA; +}; + +class JavaDomKeyLocation : public AutoGlobalWrappedJavaObject { +public: + static void InitStubs(JNIEnv *jEnv); + static JavaDomKeyLocation* Wrap(jobject obj); + JavaDomKeyLocation(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {}; + static jobject valueOf(const nsAString& a0); + static jobjectArray values(); + static jobject getDOM_KEY_LOCATION_JOYSTICK(); + static jobject getDOM_KEY_LOCATION_LEFT(); + static jobject getDOM_KEY_LOCATION_MOBILE(); + static jobject getDOM_KEY_LOCATION_NUMPAD(); + static jobject getDOM_KEY_LOCATION_RIGHT(); + static jobject getDOM_KEY_LOCATION_STANDARD(); + int32_t getvalue(); + JavaDomKeyLocation() : AutoGlobalWrappedJavaObject() {}; +protected: + static jclass mDomKeyLocationClass; + static jmethodID jvalueOf; + static jmethodID jvalues; + static jfieldID jDOM_KEY_LOCATION_JOYSTICK; + static jfieldID jDOM_KEY_LOCATION_LEFT; + static jfieldID jDOM_KEY_LOCATION_MOBILE; + static jfieldID jDOM_KEY_LOCATION_NUMPAD; + static jfieldID jDOM_KEY_LOCATION_RIGHT; + static jfieldID jDOM_KEY_LOCATION_STANDARD; + static jfieldID jvalue; +}; + +class GeckoJavaSampler : public AutoGlobalWrappedJavaObject { +public: + static void InitStubs(JNIEnv *jEnv); + static GeckoJavaSampler* Wrap(jobject obj); + GeckoJavaSampler(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {}; + static jstring GetFrameNameJavaProfilingWrapper(int32_t a0, int32_t a1, int32_t a2); + static jdouble GetSampleTimeJavaProfiling(int32_t a0, int32_t a1); + static jstring GetThreadNameJavaProfilingWrapper(int32_t a0); + static void PauseJavaProfiling(); + static void StartJavaProfiling(int32_t a0, int32_t a1); + static void StopJavaProfiling(); + static void UnpauseJavaProfiling(); + GeckoJavaSampler() : AutoGlobalWrappedJavaObject() {}; +protected: + static jclass mGeckoJavaSamplerClass; + static jmethodID jGetFrameNameJavaProfilingWrapper; + static jmethodID jGetSampleTimeJavaProfiling; + static jmethodID jGetThreadNameJavaProfilingWrapper; + static jmethodID jPauseJavaProfiling; + static jmethodID jStartJavaProfiling; + static jmethodID jStopJavaProfiling; + static jmethodID jUnpauseJavaProfiling; +}; + +class SurfaceBits : public AutoGlobalWrappedJavaObject { +public: + static void InitStubs(JNIEnv *jEnv); + static SurfaceBits* Wrap(jobject obj); + SurfaceBits(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {}; + SurfaceBits(); + jobject getbuffer(); + void setbuffer(jobject a0); + int32_t getformat(); + void setformat(int32_t a0); + int32_t getheight(); + void setheight(int32_t a0); + int32_t getwidth(); + void setwidth(int32_t a0); +protected: + static jclass mSurfaceBitsClass; + static jmethodID jSurfaceBits; + static jfieldID jbuffer; + static jfieldID jformat; + static jfieldID jheight; + static jfieldID jwidth; +}; + +class ThumbnailHelper : public AutoGlobalWrappedJavaObject { +public: + static void InitStubs(JNIEnv *jEnv); + static ThumbnailHelper* Wrap(jobject obj); + ThumbnailHelper(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {}; + static void SendThumbnail(jobject a0, int32_t a1, bool a2); + ThumbnailHelper() : AutoGlobalWrappedJavaObject() {}; +protected: + static jclass mThumbnailHelperClass; + static jmethodID jSendThumbnail; +}; + +class DisplayPortMetrics : public AutoGlobalWrappedJavaObject { +public: + static void InitStubs(JNIEnv *jEnv); + static DisplayPortMetrics* Wrap(jobject obj); + DisplayPortMetrics(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {}; + DisplayPortMetrics(jfloat a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4); + jobject getMPosition(); + jfloat getResolution(); + DisplayPortMetrics() : AutoGlobalWrappedJavaObject() {}; +protected: + static jclass mDisplayPortMetricsClass; + static jmethodID jDisplayPortMetrics; + static jfieldID jMPosition; + static jfieldID jResolution; +}; + +class GLController : public AutoGlobalWrappedJavaObject { +public: + static void InitStubs(JNIEnv *jEnv); + static GLController* Wrap(jobject obj); + GLController(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {}; + jobject CreateEGLSurfaceForCompositorWrapper(); + GLController() : AutoGlobalWrappedJavaObject() {}; +protected: + static jclass mGLControllerClass; + static jmethodID jCreateEGLSurfaceForCompositorWrapper; +}; + +class GeckoLayerClient : public AutoGlobalWrappedJavaObject { +public: + static void InitStubs(JNIEnv *jEnv); + static GeckoLayerClient* Wrap(jobject obj); + GeckoLayerClient(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {}; + void ActivateProgram(); + void ContentDocumentChanged(); + jobject CreateFrame(); + void DeactivateProgram(); + jobject GetDisplayPort(bool a0, bool a1, int32_t a2, jobject a3); + bool IsContentDocumentDisplayed(); + jobject ProgressiveUpdateCallback(bool a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4, jfloat a5, bool a6); + void SetFirstPaintViewport(jfloat a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4, jfloat a5, jfloat a6); + void SetPageRect(jfloat a0, jfloat a1, jfloat a2, jfloat a3); + jobject SyncFrameMetrics(jfloat a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4, jfloat a5, jfloat a6, bool a7, int32_t a8, int32_t a9, int32_t a10, int32_t a11, jfloat a12, bool a13); + jobject SyncViewportInfo(int32_t a0, int32_t a1, int32_t a2, int32_t a3, jfloat a4, bool a5); + GeckoLayerClient() : AutoGlobalWrappedJavaObject() {}; +protected: + static jclass mGeckoLayerClientClass; + static jmethodID jActivateProgram; + static jmethodID jContentDocumentChanged; + static jmethodID jCreateFrame; + static jmethodID jDeactivateProgram; + static jmethodID jGetDisplayPort; + static jmethodID jIsContentDocumentDisplayed; + static jmethodID jProgressiveUpdateCallback; + static jmethodID jSetFirstPaintViewport; + static jmethodID jSetPageRect; + static jmethodID jSyncFrameMetrics; + static jmethodID jSyncViewportInfo; +}; + +class ImmutableViewportMetrics : public AutoGlobalWrappedJavaObject { +public: + static void InitStubs(JNIEnv *jEnv); + static ImmutableViewportMetrics* Wrap(jobject obj); + ImmutableViewportMetrics(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {}; + ImmutableViewportMetrics(jfloat a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4, jfloat a5, jfloat a6, jfloat a7, jfloat a8, jfloat a9, jfloat a10, jfloat a11, jfloat a12); + ImmutableViewportMetrics() : AutoGlobalWrappedJavaObject() {}; +protected: + static jclass mImmutableViewportMetricsClass; + static jmethodID jImmutableViewportMetrics; +}; + +class LayerView : public AutoGlobalWrappedJavaObject { +public: + static void InitStubs(JNIEnv *jEnv); + static LayerView* Wrap(jobject obj); + LayerView(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {}; + static jobject RegisterCompositorWrapper(); + LayerView() : AutoGlobalWrappedJavaObject() {}; +protected: + static jclass mLayerViewClass; + static jmethodID jRegisterCompositorWrapper; +}; + +class NativePanZoomController : public AutoGlobalWrappedJavaObject { +public: + static void InitStubs(JNIEnv *jEnv); + static NativePanZoomController* Wrap(jobject obj); + NativePanZoomController(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {}; + void PostDelayedCallbackWrapper(int64_t a0); + void RequestContentRepaintWrapper(jfloat a0, jfloat a1, jfloat a2, jfloat a3, jfloat a4); + NativePanZoomController() : AutoGlobalWrappedJavaObject() {}; +protected: + static jclass mNativePanZoomControllerClass; + static jmethodID jPostDelayedCallbackWrapper; + static jmethodID jRequestContentRepaintWrapper; +}; + +class ProgressiveUpdateData : public AutoGlobalWrappedJavaObject { +public: + static void InitStubs(JNIEnv *jEnv); + static ProgressiveUpdateData* Wrap(jobject obj); + ProgressiveUpdateData(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {}; + ProgressiveUpdateData(); + void setViewport(jobject a0); + bool getabort(); + void setabort(bool a0); + jfloat getheight(); + void setheight(jfloat a0); + jfloat getscale(); + void setscale(jfloat a0); + jfloat getwidth(); + void setwidth(jfloat a0); + jfloat getx(); + void setx(jfloat a0); + jfloat gety(); + void sety(jfloat a0); +protected: + static jclass mProgressiveUpdateDataClass; + static jmethodID jProgressiveUpdateData; + static jmethodID jsetViewport; + static jfieldID jabort; + static jfieldID jheight; + static jfieldID jscale; + static jfieldID jwidth; + static jfieldID jx; + static jfieldID jy; +}; + +class ViewTransform : public AutoGlobalWrappedJavaObject { +public: + static void InitStubs(JNIEnv *jEnv); + static ViewTransform* Wrap(jobject obj); + ViewTransform(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {}; + ViewTransform(jfloat a0, jfloat a1, jfloat a2); + jfloat getfixedLayerMarginBottom(); + void setfixedLayerMarginBottom(jfloat a0); + jfloat getfixedLayerMarginLeft(); + void setfixedLayerMarginLeft(jfloat a0); + jfloat getfixedLayerMarginRight(); + void setfixedLayerMarginRight(jfloat a0); + jfloat getfixedLayerMarginTop(); + void setfixedLayerMarginTop(jfloat a0); + jfloat getoffsetX(); + void setoffsetX(jfloat a0); + jfloat getoffsetY(); + void setoffsetY(jfloat a0); + jfloat getscale(); + void setscale(jfloat a0); + jfloat getx(); + void setx(jfloat a0); + jfloat gety(); + void sety(jfloat a0); + ViewTransform() : AutoGlobalWrappedJavaObject() {}; +protected: + static jclass mViewTransformClass; + static jmethodID jViewTransform; + static jfieldID jfixedLayerMarginBottom; + static jfieldID jfixedLayerMarginLeft; + static jfieldID jfixedLayerMarginRight; + static jfieldID jfixedLayerMarginTop; + static jfieldID joffsetX; + static jfieldID joffsetY; + static jfieldID jscale; + static jfieldID jx; + static jfieldID jy; +}; + +class NativeZip : public AutoGlobalWrappedJavaObject { +public: + static void InitStubs(JNIEnv *jEnv); + static NativeZip* Wrap(jobject obj); + NativeZip(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {}; + jobject CreateInputStream(jobject a0, int32_t a1); + NativeZip() : AutoGlobalWrappedJavaObject() {}; +protected: + static jclass mNativeZipClass; + static jmethodID jCreateInputStream; +}; + +class MatrixBlobCursor : public AutoGlobalWrappedJavaObject { +public: + static void InitStubs(JNIEnv *jEnv); + static MatrixBlobCursor* Wrap(jobject obj); + MatrixBlobCursor(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {}; + MatrixBlobCursor(jobjectArray a0); + MatrixBlobCursor(jobjectArray a0, int32_t a1); + void AddRow(jobject a0); + void AddRow(jobject a0, int32_t a1); + void AddRow(jobjectArray a0); + MatrixBlobCursor() : AutoGlobalWrappedJavaObject() {}; +protected: + static jclass mMatrixBlobCursorClass; + static jmethodID jMatrixBlobCursor; + static jmethodID jMatrixBlobCursor0; + static jmethodID jAddRow; + static jmethodID jAddRow1; + static jmethodID jAddRow2; +}; + +class SQLiteBridgeException : public AutoGlobalWrappedJavaObject { +public: + static void InitStubs(JNIEnv *jEnv); + static SQLiteBridgeException* Wrap(jobject obj); + SQLiteBridgeException(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {}; + SQLiteBridgeException(); + SQLiteBridgeException(const nsAString& a0); + static int64_t getserialVersionUID(); +protected: + static jclass mSQLiteBridgeExceptionClass; + static jmethodID jSQLiteBridgeException; + static jmethodID jSQLiteBridgeException0; + static jfieldID jserialVersionUID; +}; + +class Clipboard : public AutoGlobalWrappedJavaObject { +public: + static void InitStubs(JNIEnv *jEnv); + static Clipboard* Wrap(jobject obj); + Clipboard(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {}; + static void ClearText(); + static jstring GetClipboardTextWrapper(); + static bool HasText(); + static void SetClipboardText(const nsAString& a0); + Clipboard() : AutoGlobalWrappedJavaObject() {}; +protected: + static jclass mClipboardClass; + static jmethodID jClearText; + static jmethodID jGetClipboardTextWrapper; + static jmethodID jHasText; + static jmethodID jSetClipboardText; +}; + + +} /* android */ +} /* widget */ +} /* mozilla */ +#endif diff --git a/widget/android/nsAppShell.cpp b/widget/android/nsAppShell.cpp index 65f3c4571141..27e8a3a1dd2e 100644 --- a/widget/android/nsAppShell.cpp +++ b/widget/android/nsAppShell.cpp @@ -34,6 +34,7 @@ #include "prenv.h" #include "AndroidBridge.h" +#include "AndroidBridgeUtilities.h" #include #include #include @@ -82,20 +83,20 @@ public: nsCOMPtr tab; mBrowserApp->GetBrowserTab(mTabId, getter_AddRefs(tab)); if (!tab) { - AndroidBridge::Bridge()->SendThumbnail(buffer, mTabId, false); + ThumbnailHelper::SendThumbnail(buffer, mTabId, false); return NS_ERROR_FAILURE; } tab->GetWindow(getter_AddRefs(domWindow)); if (!domWindow) { - AndroidBridge::Bridge()->SendThumbnail(buffer, mTabId, false); + ThumbnailHelper::SendThumbnail(buffer, mTabId, false); return NS_ERROR_FAILURE; } NS_ASSERTION(mPoints.Length() == 1, "Thumbnail event does not have enough coordinates"); nsresult rv = AndroidBridge::Bridge()->CaptureThumbnail(domWindow, mPoints[0].x, mPoints[0].y, mTabId, buffer); - AndroidBridge::Bridge()->SendThumbnail(buffer, mTabId, NS_SUCCEEDED(rv)); + ThumbnailHelper::SendThumbnail(buffer, mTabId, NS_SUCCEEDED(rv)); return rv; } private: @@ -110,7 +111,7 @@ class WakeLockListener MOZ_FINAL : public nsIDOMMozWakeLockListener { NS_DECL_ISUPPORTS; nsresult Callback(const nsAString& topic, const nsAString& state) { - AndroidBridge::Bridge()->NotifyWakeLockChanged(topic, state); + GeckoAppShell::NotifyWakeLockChanged(topic, state); return NS_OK; } }; @@ -202,7 +203,7 @@ nsAppShell::Init() NS_ENSURE_SUCCESS(rv, rv); if (match) { - bridge->SetSelectedLocale(EmptyString()); + GeckoAppShell::SetSelectedLocale(EmptyString()); return NS_OK; } @@ -212,7 +213,7 @@ nsAppShell::Init() rv = Preferences::GetString(PREFNAME_UA_LOCALE, &locale); } - bridge->SetSelectedLocale(locale); + GeckoAppShell::SetSelectedLocale(locale); mAllowCoalescingTouches = Preferences::GetBool(PREFNAME_COALESCE_TOUCHES, true); return rv; } @@ -234,17 +235,12 @@ nsAppShell::Observe(nsISupports* aSubject, NS_LITERAL_STRING(PREFNAME_COALESCE_TOUCHES)) || nsDependentString(aData).Equals( NS_LITERAL_STRING(PREFNAME_MATCH_OS)))) { - AndroidBridge* bridge = AndroidBridge::Bridge(); - if (!bridge) { - return NS_OK; - } - bool match; nsresult rv = Preferences::GetBool(PREFNAME_MATCH_OS, &match); NS_ENSURE_SUCCESS(rv, rv); if (match) { - bridge->SetSelectedLocale(EmptyString()); + GeckoAppShell::SetSelectedLocale(EmptyString()); return NS_OK; } @@ -254,7 +250,7 @@ nsAppShell::Observe(nsISupports* aSubject, locale = Preferences::GetString(PREFNAME_UA_LOCALE); } - bridge->SetSelectedLocale(locale); + GeckoAppShell::SetSelectedLocale(locale); mAllowCoalescingTouches = Preferences::GetBool(PREFNAME_COALESCE_TOUCHES, true); return NS_OK; @@ -405,10 +401,6 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait) if (!mBrowserApp) break; - AndroidBridge* bridge = AndroidBridge::Bridge(); - if (!bridge) - break; - int32_t tabId = curEvent->MetaState(); const nsTArray& points = curEvent->Points(); RefCountedJavaObject* buffer = curEvent->ByteBuffer(); @@ -600,7 +592,7 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait) } if (curEvent->AckNeeded()) { - AndroidBridge::Bridge()->AcknowledgeEvent(); + GeckoAppShell::AcknowledgeEvent(); } EVLOG("nsAppShell: -- done event %p %d", (void*)curEvent.get(), curEvent->Type()); diff --git a/widget/android/nsClipboard.cpp b/widget/android/nsClipboard.cpp index 8cd8db92078f..93f2d416c625 100644 --- a/widget/android/nsClipboard.cpp +++ b/widget/android/nsClipboard.cpp @@ -44,11 +44,7 @@ nsClipboard::SetData(nsITransferable *aTransferable, supportsString->GetData(buffer); if (XRE_GetProcessType() == GeckoProcessType_Default) { - if (AndroidBridge::Bridge()) - AndroidBridge::Bridge()->SetClipboardText(buffer); - else - return NS_ERROR_NOT_IMPLEMENTED; - + Clipboard::SetClipboardText(buffer); } else { bool isPrivateData = false; aTransferable->GetIsPrivateData(&isPrivateData); @@ -101,8 +97,7 @@ nsClipboard::EmptyClipboard(int32_t aWhichClipboard) if (aWhichClipboard != kGlobalClipboard) return NS_ERROR_NOT_IMPLEMENTED; if (XRE_GetProcessType() == GeckoProcessType_Default) { - if (AndroidBridge::Bridge()) - AndroidBridge::Bridge()->EmptyClipboard(); + Clipboard::ClearText(); } else { ContentChild::GetSingleton()->SendEmptyClipboard(); } @@ -119,8 +114,7 @@ nsClipboard::HasDataMatchingFlavors(const char **aFlavorList, if (aWhichClipboard != kGlobalClipboard) return NS_ERROR_NOT_IMPLEMENTED; if (XRE_GetProcessType() == GeckoProcessType_Default) { - if (AndroidBridge::Bridge()) - *aHasText = AndroidBridge::Bridge()->ClipboardHasText(); + *aHasText = Clipboard::HasText(); } else { ContentChild::GetSingleton()->SendClipboardHasText(aHasText); } diff --git a/widget/android/nsIMEPicker.cpp b/widget/android/nsIMEPicker.cpp index 6b7255dcd51d..ac7f58f5d490 100644 --- a/widget/android/nsIMEPicker.cpp +++ b/widget/android/nsIMEPicker.cpp @@ -22,6 +22,6 @@ nsIMEPicker::~nsIMEPicker() /* void show (); */ NS_IMETHODIMP nsIMEPicker::Show() { - AndroidBridge::Bridge()->ShowInputMethodPicker(); + GeckoAppShell::ShowInputMethodPicker(); return NS_OK; } diff --git a/widget/android/nsLookAndFeel.cpp b/widget/android/nsLookAndFeel.cpp index 97b78ab53b6a..d1c8c958a0ce 100644 --- a/widget/android/nsLookAndFeel.cpp +++ b/widget/android/nsLookAndFeel.cpp @@ -466,10 +466,7 @@ nsLookAndFeel::GetEchoPasswordImpl() { if (!mInitializedShowPassword) { if (XRE_GetProcessType() == GeckoProcessType_Default) { - if (AndroidBridge::Bridge()) - mShowPassword = AndroidBridge::Bridge()->GetShowPasswordSetting(); - else - NS_ASSERTION(AndroidBridge::Bridge() != nullptr, "AndroidBridge is not available!"); + mShowPassword = GeckoAppShell::GetShowPasswordSetting(); } else { ContentChild::GetSingleton()->SendGetShowPasswordSetting(&mShowPassword); } diff --git a/widget/android/nsScreenManagerAndroid.cpp b/widget/android/nsScreenManagerAndroid.cpp index 95facf8d39a5..b892e5be8b6c 100644 --- a/widget/android/nsScreenManagerAndroid.cpp +++ b/widget/android/nsScreenManagerAndroid.cpp @@ -59,7 +59,7 @@ nsScreenAndroid::GetColorDepth(int32_t *aColorDepth) void nsScreenAndroid::ApplyMinimumBrightness(uint32_t aBrightness) { - AndroidBridge::Bridge()->SetKeepScreenOn(aBrightness == BRIGHTNESS_FULL); + GeckoAppShell::SetKeepScreenOn(aBrightness == BRIGHTNESS_FULL); } NS_IMPL_ISUPPORTS1(nsScreenManagerAndroid, nsIScreenManager) diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index ec52628b7072..a078bf1dd662 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -52,6 +52,7 @@ using mozilla::unused; #include "nsTArray.h" #include "AndroidBridge.h" +#include "AndroidBridgeUtilities.h" #include "android_npapi.h" #include "imgIEncoder.h" @@ -209,11 +210,6 @@ nsWindow::Create(nsIWidget *aParent, { ALOG("nsWindow[%p]::Create %p [%d %d %d %d]", (void*)this, (void*)aParent, aRect.x, aRect.y, aRect.width, aRect.height); nsWindow *parent = (nsWindow*) aParent; - - if (!AndroidBridge::Bridge()) { - aNativeParent = nullptr; - } - if (aNativeParent) { if (parent) { ALOG("Ignoring native parent on Android window [%p], since parent was specified (%p %p)", (void*)this, (void*)aNativeParent, (void*)aParent); @@ -353,9 +349,7 @@ nsWindow::GetDefaultScaleInternal() return density; } - if (AndroidBridge::Bridge()) { - density = AndroidBridge::Bridge()->GetDensity(); - } + density = GeckoAppShell::GetDensity(); if (!density) { density = 1.0; @@ -519,7 +513,7 @@ nsWindow::SetSizeMode(int32_t aMode) { switch (aMode) { case nsSizeMode_Minimized: - AndroidBridge::Bridge()->MoveTaskToBack(); + GeckoAppShell::MoveTaskToBack(); break; case nsSizeMode_Fullscreen: MakeFullScreen(true); @@ -571,9 +565,6 @@ nsWindow::SetFocus(bool aRaise) ALOG("nsWindow::SetFocus: can't set focus without raising, ignoring aRaise = false!"); } - if (!AndroidBridge::Bridge()) - return NS_OK; - nsWindow *top = FindTopLevel(); top->mFocus = this; top->BringToFront(); @@ -700,7 +691,7 @@ nsWindow::DispatchEvent(WidgetGUIEvent* aEvent) NS_IMETHODIMP nsWindow::MakeFullScreen(bool aFullScreen) { - AndroidBridge::Bridge()->SetFullScreen(aFullScreen); + GeckoAppShell::SetFullScreen(aFullScreen); return NS_OK; } @@ -769,9 +760,6 @@ nsWindow::CreateLayerManager(int aCompositorWidth, int aCompositorHeight) void nsWindow::OnGlobalAndroidEvent(AndroidGeckoEvent *ae) { - if (!AndroidBridge::Bridge()) - return; - nsWindow *win = TopWindow(); if (!win) return; @@ -949,9 +937,6 @@ nsWindow::OnGlobalAndroidEvent(AndroidGeckoEvent *ae) void nsWindow::OnAndroidEvent(AndroidGeckoEvent *ae) { - if (!AndroidBridge::Bridge()) - return; - switch (ae->Type()) { case AndroidGeckoEvent::DRAW: OnDraw(ae); @@ -1217,7 +1202,7 @@ bool nsWindow::OnMultitouchEvent(AndroidGeckoEvent *ae) // if this event is a down event, that means it's the start of a new block, and the // previous block should not be default-prevented bool defaultPrevented = isDownEvent ? false : preventDefaultActions; - AndroidBridge::Bridge()->NotifyDefaultPrevented(defaultPrevented); + GeckoAppShell::NotifyDefaultPrevented(defaultPrevented); sDefaultPreventedNotified = true; } @@ -1226,7 +1211,7 @@ bool nsWindow::OnMultitouchEvent(AndroidGeckoEvent *ae) // for the next event. if (isDownEvent) { if (preventDefaultActions) { - AndroidBridge::Bridge()->NotifyDefaultPrevented(true); + GeckoAppShell::NotifyDefaultPrevented(true); sDefaultPreventedNotified = true; } else { sDefaultPreventedNotified = false; @@ -1835,10 +1820,10 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *ae) NotifyIMEOfTextChange(0, INT32_MAX / 2, INT32_MAX / 2); FlushIMEChanges(); } - AndroidBridge::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT); + GeckoAppShell::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT); return; } else if (ae->Action() == AndroidGeckoEvent::IME_UPDATE_CONTEXT) { - AndroidBridge::NotifyIMEContext(mInputContext.mIMEState.mEnabled, + GeckoAppShell::NotifyIMEContext(mInputContext.mIMEState.mEnabled, mInputContext.mHTMLInputType, mInputContext.mHTMLInputInputmode, mInputContext.mActionHint); @@ -1849,7 +1834,7 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *ae) // Still reply to events, but don't do anything else if (ae->Action() == AndroidGeckoEvent::IME_SYNCHRONIZE || ae->Action() == AndroidGeckoEvent::IME_REPLACE_TEXT) { - AndroidBridge::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT); + GeckoAppShell::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT); } return; } @@ -1862,7 +1847,7 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *ae) case AndroidGeckoEvent::IME_SYNCHRONIZE: { FlushIMEChanges(); - AndroidBridge::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT); + GeckoAppShell::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT); } break; case AndroidGeckoEvent::IME_REPLACE_TEXT: @@ -1894,7 +1879,7 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *ae) } mIMEKeyEvents.Clear(); FlushIMEChanges(); - AndroidBridge::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT); + GeckoAppShell::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT); break; } @@ -1916,7 +1901,7 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *ae) DispatchEvent(&event); } FlushIMEChanges(); - AndroidBridge::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT); + GeckoAppShell::NotifyIME(AndroidBridge::NOTIFY_IME_REPLY_EVENT); } break; case AndroidGeckoEvent::IME_SET_SELECTION: @@ -2096,7 +2081,7 @@ nsWindow::NotifyIME(NotificationToIME aNotification) case REQUEST_TO_COMMIT_COMPOSITION: //ALOGIME("IME: REQUEST_TO_COMMIT_COMPOSITION: s=%d", aState); RemoveIMEComposition(); - AndroidBridge::NotifyIME(REQUEST_TO_COMMIT_COMPOSITION); + GeckoAppShell::NotifyIME(REQUEST_TO_COMMIT_COMPOSITION); return NS_OK; case REQUEST_TO_CANCEL_COMPOSITION: ALOGIME("IME: REQUEST_TO_CANCEL_COMPOSITION"); @@ -2115,11 +2100,11 @@ nsWindow::NotifyIME(NotificationToIME aNotification) DispatchEvent(&compEvent); } - AndroidBridge::NotifyIME(REQUEST_TO_CANCEL_COMPOSITION); + GeckoAppShell::NotifyIME(REQUEST_TO_CANCEL_COMPOSITION); return NS_OK; case NOTIFY_IME_OF_FOCUS: ALOGIME("IME: NOTIFY_IME_OF_FOCUS"); - AndroidBridge::NotifyIME(NOTIFY_IME_OF_FOCUS); + GeckoAppShell::NotifyIME(NOTIFY_IME_OF_FOCUS); return NS_OK; case NOTIFY_IME_OF_BLUR: ALOGIME("IME: NOTIFY_IME_OF_BLUR"); @@ -2131,7 +2116,7 @@ nsWindow::NotifyIME(NotificationToIME aNotification) mIMEComposing = false; mIMEComposingText.Truncate(); - AndroidBridge::NotifyIME(NOTIFY_IME_OF_BLUR); + GeckoAppShell::NotifyIME(NOTIFY_IME_OF_BLUR); return NS_OK; case NOTIFY_IME_OF_SELECTION_CHANGE: if (mIMEMaskSelectionUpdate) { @@ -2191,7 +2176,7 @@ nsWindow::SetInputContext(const InputContext& aContext, if (enabled == IMEState::ENABLED && aAction.UserMightRequestOpenVKB()) { // Don't reset keyboard when we should simply open the vkb - AndroidBridge::NotifyIME(AndroidBridge::NOTIFY_IME_OPEN_VKB); + GeckoAppShell::NotifyIME(AndroidBridge::NOTIFY_IME_OPEN_VKB); return; } @@ -2247,7 +2232,7 @@ nsWindow::FlushIMEChanges() if (!event.mSucceeded) return; - AndroidBridge::NotifyIMEChange(event.mReply.mString, + GeckoAppShell::NotifyIMEChange(event.mReply.mString, change.mStart, change.mOldEnd, change.mNewEnd); @@ -2262,7 +2247,7 @@ nsWindow::FlushIMEChanges() if (!event.mSucceeded) return; - AndroidBridge::NotifyIMEChange(EmptyString(), + GeckoAppShell::NotifyIMEChange(EmptyString(), (int32_t) event.GetSelectionStart(), (int32_t) event.GetSelectionEnd(), -1); mIMESelectionChanged = false; @@ -2362,16 +2347,28 @@ nsWindow::DrawWindowUnderlay(LayerManager* aManager, nsIntRect aRect) AutoLocalJNIFrame jniFrame(env); - AndroidGeckoLayerClient& client = AndroidBridge::Bridge()->GetLayerClient(); - if (!client.CreateFrame(&jniFrame, mLayerRendererFrame)) return; - - if (!WidgetPaintsBackground()) + GeckoLayerClient* client = AndroidBridge::Bridge()->GetLayerClient(); + if (!client || client->isNull()) { + ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__); return; + } - if (!client.ActivateProgram(&jniFrame)) return; + jobject frameObj = client->CreateFrame(); + NS_ABORT_IF_FALSE(frameObj, "No frame object!"); + if (!frameObj) { + ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__); + return; + } + + mLayerRendererFrame.Init(env, frameObj); + if (!WidgetPaintsBackground()) { + return; + } + + client->ActivateProgram(); if (!mLayerRendererFrame.BeginDrawing(&jniFrame)) return; if (!mLayerRendererFrame.DrawBackground(&jniFrame)) return; - if (!client.DeactivateProgram(&jniFrame)) return; // redundant, but in case somebody adds code after this... + client->DeactivateProgram(); // redundant, but in case somebody adds code after this... } void @@ -2388,12 +2385,12 @@ nsWindow::DrawWindowOverlay(LayerManager* aManager, nsIntRect aRect) NS_ABORT_IF_FALSE(!mLayerRendererFrame.isNull(), "Frame should have been created in DrawWindowUnderlay()!"); - AndroidGeckoLayerClient& client = AndroidBridge::Bridge()->GetLayerClient(); + GeckoLayerClient* client = AndroidBridge::Bridge()->GetLayerClient(); - if (!client.ActivateProgram(&jniFrame)) return; + client->ActivateProgram(); if (!mLayerRendererFrame.DrawForeground(&jniFrame)) return; if (!mLayerRendererFrame.EndDrawing(&jniFrame)) return; - if (!client.DeactivateProgram(&jniFrame)) return; + client->DeactivateProgram(); mLayerRendererFrame.Dispose(env); } diff --git a/widget/android/nsWindow.h b/widget/android/nsWindow.h index 0baddd5ae3f1..1a84c79bf445 100644 --- a/widget/android/nsWindow.h +++ b/widget/android/nsWindow.h @@ -11,6 +11,7 @@ #include "nsIIdleServiceInternal.h" #include "nsTArray.h" #include "AndroidJavaWrappers.h" +#include "GeneratedJNIWrappers.h" #include "mozilla/EventForwards.h" #include "mozilla/StaticPtr.h" #include "mozilla/TextRange.h" diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index f08f4030ba5d..57c0f5121255 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -1959,6 +1959,71 @@ gdk_window_flash(GdkWindow * aGdkWindow, #endif // DEBUG #endif +struct ExposeRegion +{ + nsIntRegion mRegion; + +#if (MOZ_WIDGET_GTK == 2) + GdkRectangle *mRects; + GdkRectangle *mRectsEnd; + + ExposeRegion() : mRects(nullptr) + { + } + ~ExposeRegion() + { + g_free(mRects); + } + bool Init(GdkEventExpose *aEvent) + { + gint nrects; + gdk_region_get_rectangles(aEvent->region, &mRects, &nrects); + + if (nrects > MAX_RECTS_IN_REGION) { + // Just use the bounding box + mRects[0] = aEvent->area; + nrects = 1; + } + + mRectsEnd = mRects + nrects; + + for (GdkRectangle *r = mRects; r < mRectsEnd; r++) { + mRegion.Or(mRegion, nsIntRect(r->x, r->y, r->width, r->height)); + LOGDRAW(("\t%d %d %d %d\n", r->x, r->y, r->width, r->height)); + } + return true; + } + +#else +# ifdef cairo_copy_clip_rectangle_list +# error "Looks like we're including Mozilla's cairo instead of system cairo" +# endif + cairo_rectangle_list_t *mRects; + + ExposeRegion() : mRects(nullptr) + { + } + ~ExposeRegion() + { + cairo_rectangle_list_destroy(mRects); + } + bool Init(cairo_t* cr) + { + if (mRects->status != CAIRO_STATUS_SUCCESS) { + NS_WARNING("Failed to obtain cairo rectangle list."); + return false; + } + + for (int i = 0; i < mRects->num_rectangles; i++) { + const cairo_rectangle_t& r = mRects->rectangles[i]; + mRegion.Or(mRegion, nsIntRect(r.x, r.y, r.width, r.height)); + LOGDRAW(("\t%d %d %d %d\n", r.x, r.y, r.width, r.height)); + } + return true; + } +#endif +}; + #if (MOZ_WIDGET_GTK == 2) gboolean nsWindow::OnExposeEvent(GdkEventExpose *aEvent) @@ -1980,6 +2045,17 @@ nsWindow::OnExposeEvent(cairo_t *cr) if (!listener) return FALSE; + ExposeRegion exposeRegion; +#if (MOZ_WIDGET_GTK == 2) + if (!exposeRegion.Init(aEvent)) { +#else + if (!exposeRegion.Init(cr)) { +#endif + return FALSE; + } + + nsIntRegion ®ion = exposeRegion.mRegion; + ClientLayerManager *clientLayers = (GetLayerManager()->GetBackendType() == LAYERS_CLIENT) ? static_cast(GetLayerManager()) @@ -1991,6 +2067,7 @@ nsWindow::OnExposeEvent(cairo_t *cr) // We need to paint to the screen even if nothing changed, since if we // don't have a compositing window manager, our pixels could be stale. clientLayers->SetNeedsComposite(true); + clientLayers->SendInvalidRegion(region); } // Dispatch WillPaintWindow notification to allow scripts etc. to run @@ -2016,52 +2093,10 @@ nsWindow::OnExposeEvent(cairo_t *cr) clientLayers->SetNeedsComposite(false); } -#if (MOZ_WIDGET_GTK == 2) - GdkRectangle *rects; - gint nrects; - gdk_region_get_rectangles(aEvent->region, &rects, &nrects); - if (MOZ_UNLIKELY(!rects)) // OOM - return FALSE; -#else -#ifdef cairo_copy_clip_rectangle_list -#error "Looks like we're including Mozilla's cairo instead of system cairo" -#else - cairo_rectangle_list_t *rects; - rects = cairo_copy_clip_rectangle_list(cr); - if (MOZ_UNLIKELY(rects->status != CAIRO_STATUS_SUCCESS)) { - NS_WARNING("Failed to obtain cairo rectangle list."); - return FALSE; - } -#endif -#endif - -// GTK3 TODO? -#if (MOZ_WIDGET_GTK == 2) - if (nrects > MAX_RECTS_IN_REGION) { - // Just use the bounding box - rects[0] = aEvent->area; - nrects = 1; - } -#endif - LOGDRAW(("sending expose event [%p] %p 0x%lx (rects follow):\n", (void *)this, (void *)mGdkWindow, gdk_x11_window_get_xid(mGdkWindow))); - nsIntRegion region; - -#if (MOZ_WIDGET_GTK == 2) - GdkRectangle *r = rects; - GdkRectangle *r_end = rects + nrects; -#else - cairo_rectangle_t *r = rects->rectangles; - cairo_rectangle_t *r_end = r + rects->num_rectangles; -#endif - for (; r < r_end; ++r) { - region.Or(region, nsIntRect(r->x, r->y, r->width, r->height)); - LOGDRAW(("\t%d %d %d %d\n", r->x, r->y, r->width, r->height)); - } - // Our bounds may have changed after calling WillPaintWindow. Clip // to the new bounds here. The region is relative to this // window. @@ -2103,19 +2138,13 @@ nsWindow::OnExposeEvent(cairo_t *cr) } if (region.IsEmpty()) { -#if (MOZ_WIDGET_GTK == 2) - g_free(rects); -#else - cairo_rectangle_list_destroy(rects); -#endif return TRUE; } + // If this widget uses OMTC... if (GetLayerManager()->GetBackendType() == LAYERS_CLIENT) { listener->PaintWindow(this, region); listener->DidPaintWindow(); - - g_free(rects); return TRUE; } else if (GetLayerManager()->GetBackendType() == mozilla::layers::LAYERS_OPENGL) { LayerManagerOGL *manager = static_cast(GetLayerManager()); @@ -2123,8 +2152,6 @@ nsWindow::OnExposeEvent(cairo_t *cr) listener->PaintWindow(this, region); listener->DidPaintWindow(); - - g_free(rects); return TRUE; } @@ -2227,20 +2254,14 @@ nsWindow::OnExposeEvent(cairo_t *cr) # ifdef MOZ_HAVE_SHMIMAGE if (nsShmImage::UseShm() && MOZ_LIKELY(!mIsDestroyed)) { #if (MOZ_WIDGET_GTK == 2) - mShmImage->Put(mGdkWindow, rects, r_end); + mShmImage->Put(mGdkWindow, exposeRegion.mRects, exposeRegion.mRectsEnd); #else - mShmImage->Put(mGdkWindow, rects); + mShmImage->Put(mGdkWindow, exposeRegion.mRects); #endif } # endif // MOZ_HAVE_SHMIMAGE #endif // MOZ_X11 -#if (MOZ_WIDGET_GTK == 2) - g_free(rects); -#else - cairo_rectangle_list_destroy(rects); -#endif - listener->DidPaintWindow(); // Synchronously flush any new dirty areas @@ -5971,7 +5992,6 @@ nsWindow::GetSurfaceForGdkDrawable(GdkDrawable* aDrawable, } #endif -#if (MOZ_WIDGET_GTK == 2) TemporaryRef nsWindow::StartRemoteDrawing() { @@ -5987,7 +6007,6 @@ nsWindow::StartRemoteDrawing() return gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(surf, size); } -#endif // return the gfxASurface for rendering to this widget gfxASurface* diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h index 0b92bfa97d38..61dbe1a9f469 100644 --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -197,9 +197,7 @@ public: guint aTime, gpointer aData); -#if (MOZ_WIDGET_GTK == 2) mozilla::TemporaryRef StartRemoteDrawing() MOZ_OVERRIDE; -#endif private: void UpdateAlpha(gfxPattern* aPattern, nsIntRect aBoundsRect); diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h index 6258238eb3a0..697fc6990e5b 100644 --- a/widget/windows/nsWindow.h +++ b/widget/windows/nsWindow.h @@ -528,6 +528,8 @@ protected: HDC mPaintDC; // only set during painting HDC mCompositeDC; // only set during StartRemoteDrawing + nsIntRect mLastPaintBounds; + #ifdef CAIRO_HAS_D2D_SURFACE nsRefPtr mD2DWindowSurface; // Surface for this window. #endif diff --git a/widget/windows/nsWindowGfx.cpp b/widget/windows/nsWindowGfx.cpp index 17ccde5918a6..c1fe476dbb89 100644 --- a/widget/windows/nsWindowGfx.cpp +++ b/widget/windows/nsWindowGfx.cpp @@ -45,6 +45,7 @@ using mozilla::plugins::PluginInstanceParent; #include "LayerManagerD3D10.h" #endif #include "mozilla/layers/CompositorParent.h" +#include "ClientLayerManager.h" #include "nsUXThemeData.h" #include "nsUXThemeConstants.h" @@ -213,23 +214,20 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t aNestingLevel) return true; } - // Do an early async composite so that we at least have something on screen - // in the right place, even if the content is out of date. - if (GetLayerManager()->GetBackendType() == LAYERS_CLIENT && - mCompositorParent) { + ClientLayerManager *clientLayerManager = + (GetLayerManager()->GetBackendType() == LAYERS_CLIENT) + ? static_cast(GetLayerManager()) + : nullptr; + + if (clientLayerManager && mCompositorParent && + !mBounds.IsEqualEdges(mLastPaintBounds)) + { + // Do an early async composite so that we at least have something on the + // screen in the right place, even if the content is out of date. mCompositorParent->ScheduleRenderOnCompositorThread(); } + mLastPaintBounds = mBounds; - nsIWidgetListener* listener = GetPaintListener(); - if (listener) { - listener->WillPaintWindow(this); - } - // Re-get the listener since the will paint notification may have killed it. - listener = GetPaintListener(); - if (!listener) - return false; - - bool result = true; PAINTSTRUCT ps; #ifdef MOZ_XUL @@ -273,6 +271,30 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t aNestingLevel) bool forceRepaint = nullptr != aDC; #endif nsIntRegion region = GetRegionToPaint(forceRepaint, ps, hDC); + + if (clientLayerManager && mCompositorParent) { + // We need to paint to the screen even if nothing changed, since if we + // don't have a compositing window manager, our pixels could be stale. + clientLayerManager->SetNeedsComposite(true); + clientLayerManager->SendInvalidRegion(region); + } + + nsIWidgetListener* listener = GetPaintListener(); + if (listener) { + listener->WillPaintWindow(this); + } + // Re-get the listener since the will paint notification may have killed it. + listener = GetPaintListener(); + if (!listener) { + return false; + } + + if (clientLayerManager && mCompositorParent && clientLayerManager->NeedsComposite()) { + mCompositorParent->ScheduleRenderOnCompositorThread(); + clientLayerManager->SetNeedsComposite(false); + } + + bool result = true; if (!region.IsEmpty() && listener) { // Should probably pass in a real region here, using GetRandomRgn diff --git a/xpcom/base/nsDebugImpl.cpp b/xpcom/base/nsDebugImpl.cpp index 3cb01f4432a2..d663fcb7b517 100644 --- a/xpcom/base/nsDebugImpl.cpp +++ b/xpcom/base/nsDebugImpl.cpp @@ -77,7 +77,6 @@ Break(const char *aMsg); using namespace mozilla; -static bool sIsMultiprocess = false; static const char *sMultiprocessDescription = nullptr; static Atomic gAssertionCount; @@ -180,7 +179,6 @@ nsDebugImpl::GetIsDebuggerAttached(bool* aResult) /* static */ void nsDebugImpl::SetMultiprocessMode(const char *aDesc) { - sIsMultiprocess = true; sMultiprocessDescription = aDesc; } @@ -315,15 +313,12 @@ NS_DebugBreak(uint32_t aSeverity, const char *aStr, const char *aExpr, # define PrintToBuffer(...) PR_sxprintf(StuffFixedBuffer, &buf, __VA_ARGS__) - // If we're multiprocess, print "[PID]" or "[Desc PID]" at the beginning of - // the message. - if (sIsMultiprocess) { - PrintToBuffer("["); - if (sMultiprocessDescription) { - PrintToBuffer("%s ", sMultiprocessDescription); - } - PrintToBuffer("%d] ", base::GetCurrentProcId()); + // Print "[PID]" or "[Desc PID]" at the beginning of the message. + PrintToBuffer("["); + if (sMultiprocessDescription) { + PrintToBuffer("%s ", sMultiprocessDescription); } + PrintToBuffer("%d] ", base::GetCurrentProcId()); PrintToBuffer("%s: ", sevString); diff --git a/xpcom/base/nsSystemInfo.cpp b/xpcom/base/nsSystemInfo.cpp index 0c32ac7901a5..69a43e178e5b 100644 --- a/xpcom/base/nsSystemInfo.cpp +++ b/xpcom/base/nsSystemInfo.cpp @@ -26,6 +26,7 @@ #ifdef MOZ_WIDGET_ANDROID #include "AndroidBridge.h" +using namespace mozilla::widget::android; #endif #ifdef MOZ_WIDGET_GONK @@ -233,7 +234,7 @@ nsSystemInfo::Init() android_sdk_version = version; if (version >= 8 && mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "HARDWARE", str)) SetPropertyAsAString(NS_LITERAL_STRING("hardware"), str); - bool isTablet = mozilla::AndroidBridge::Bridge()->IsTablet(); + bool isTablet = GeckoAppShell::IsTablet(); SetPropertyAsBool(NS_LITERAL_STRING("tablet"), isTablet); // NSPR "version" is the kernel version. For Android we want the Android version. // Rename SDK version to version and put the kernel version into kernel_version. diff --git a/xpcom/components/ManifestParser.cpp b/xpcom/components/ManifestParser.cpp index 86ab14feef32..9cff5a4352e5 100644 --- a/xpcom/components/ManifestParser.cpp +++ b/xpcom/components/ManifestParser.cpp @@ -472,7 +472,7 @@ ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOn bool isTablet = false; if (mozilla::AndroidBridge::Bridge()) { mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build$VERSION", "RELEASE", osVersion); - isTablet = mozilla::AndroidBridge::Bridge()->IsTablet(); + isTablet = mozilla::widget::android::GeckoAppShell::IsTablet(); } #endif diff --git a/xpcom/io/nsLocalFileUnix.cpp b/xpcom/io/nsLocalFileUnix.cpp index c0127e80949b..ed137c29d197 100644 --- a/xpcom/io/nsLocalFileUnix.cpp +++ b/xpcom/io/nsLocalFileUnix.cpp @@ -1894,8 +1894,7 @@ nsLocalFile::Launch() nsDependentCString fileUri = NS_LITERAL_CSTRING("file://"); fileUri.Append(mPath); - mozilla::AndroidBridge* bridge = mozilla::AndroidBridge::Bridge(); - return bridge->OpenUriExternal(NS_ConvertUTF8toUTF16(fileUri), NS_ConvertUTF8toUTF16(type)) ? NS_OK : NS_ERROR_FAILURE; + return GeckoAppShell::OpenUriExternal(NS_ConvertUTF8toUTF16(fileUri), NS_ConvertUTF8toUTF16(type)) ? NS_OK : NS_ERROR_FAILURE; #elif defined(MOZ_WIDGET_COCOA) CFURLRef url; if (NS_SUCCEEDED(GetCFURL(&url))) { diff --git a/xpcom/string/src/nsSubstring.cpp b/xpcom/string/src/nsSubstring.cpp index 7a9df8b3e1c3..115efbef25a5 100644 --- a/xpcom/string/src/nsSubstring.cpp +++ b/xpcom/string/src/nsSubstring.cpp @@ -25,6 +25,17 @@ #include "nsStaticAtom.h" #include "nsCOMPtr.h" +#include "mozilla/IntegerPrintfMacros.h" +#ifdef XP_WIN +#include +#include +#define getpid() _getpid() +#define pthread_self() GetCurrentThreadId() +#else +#include +#include +#endif + using mozilla::Atomic; // --------------------------------------------------------------------------- @@ -66,6 +77,8 @@ class nsStringStats printf(" -- LEAKED %d !!!\n", mAdoptCount - mAdoptFreeCount); else printf("\n"); + printf(" => Process ID: %" PRIuPTR ", Thread ID: %" PRIuPTR "\n", + uintptr_t(getpid()), uintptr_t(pthread_self())); } Atomic mAllocCount;