From 5544291d84d20f4cb701b89fce76197e69246322 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 13 Jun 2013 01:12:26 -0400 Subject: [PATCH 01/20] Bug 880367 part 1. Change the "enabled" callback for WebIDL constructors to take a JSContext* and the object the constructor will be defined on. r=smaug,bholley --- content/html/content/src/HTMLTrackElement.cpp | 3 +- dom/base/nsDOMClassInfo.cpp | 32 +++++++++++------ dom/base/nsScriptNameSpaceManager.cpp | 8 ++--- dom/base/nsScriptNameSpaceManager.h | 10 ++++-- dom/bindings/Codegen.py | 34 ++++++++++++------- js/xpconnect/src/xpcpublic.h | 8 ++++- 6 files changed, 62 insertions(+), 33 deletions(-) diff --git a/content/html/content/src/HTMLTrackElement.cpp b/content/html/content/src/HTMLTrackElement.cpp index 7d0c82dac4b..f848ae4e75e 100644 --- a/content/html/content/src/HTMLTrackElement.cpp +++ b/content/html/content/src/HTMLTrackElement.cpp @@ -114,7 +114,8 @@ HTMLTrackElement::WrapNode(JSContext* aCx, JS::Handle aScope) bool HTMLTrackElement::IsWebVTTEnabled() { - return HTMLTrackElementBinding::PrefEnabled(); + // Our callee does not use its arguments. + return HTMLTrackElementBinding::ConstructorEnabled(nullptr, JS::NullPtr()); } TextTrack* diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index a62b2c29315..dca001c3c7f 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -3934,7 +3934,8 @@ ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindow *aWin, JSContext *cx, } static bool -ConstructorEnabled(const nsGlobalNameStruct *aStruct, nsGlobalWindow *aWin) +OldBindingConstructorEnabled(const nsGlobalNameStruct *aStruct, + nsGlobalWindow *aWin) { MOZ_ASSERT(aStruct->mType == nsGlobalNameStruct::eTypeClassConstructor || aStruct->mType == nsGlobalNameStruct::eTypeExternalClassInfo); @@ -3998,11 +3999,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx, name_struct->mDefineDOMInterface; if (define) { if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor && - !ConstructorEnabled(name_struct, aWin)) { - return NS_OK; - } - - if (name_struct->mPrefEnabled && !(*name_struct->mPrefEnabled)()) { + !OldBindingConstructorEnabled(name_struct, aWin)) { return NS_OK; } @@ -4019,6 +4016,14 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx, global = obj; } + // Check whether our constructor is enabled after we unwrap Xrays, since + // we don't want to define an interface on the Xray if it's disabled in + // the target global, even if it's enabled in the Xray's global. + if (name_struct->mConstructorEnabled && + !(*name_struct->mConstructorEnabled)(cx, global)) { + return NS_OK; + } + bool enabled; JS::Rooted interfaceObject(cx, define(cx, global, id, &enabled)); if (enabled) { @@ -4081,7 +4086,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx, if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor || name_struct->mType == nsGlobalNameStruct::eTypeExternalClassInfo) { - if (!ConstructorEnabled(name_struct, aWin)) { + if (!OldBindingConstructorEnabled(name_struct, aWin)) { return NS_OK; } @@ -4888,16 +4893,21 @@ nsNavigatorSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, mozilla::dom::ConstructNavigatorProperty construct = name_struct->mConstructNavigatorProperty; MOZ_ASSERT(construct); - if (name_struct->mPrefEnabled && !(*name_struct->mPrefEnabled)()) { - return NS_OK; - } - JS::Rooted naviObj(cx, js::CheckedUnwrap(obj, /* stopAtOuter = */ false)); NS_ENSURE_TRUE(naviObj, NS_ERROR_DOM_SECURITY_ERR); JS::Rooted domObject(cx); { JSAutoCompartment ac(cx, naviObj); + + // Check whether our constructor is enabled after we unwrap Xrays, since + // we don't want to define an interface on the Xray if it's disabled in + // the target global, even if it's enabled in the Xray's global. + if (name_struct->mConstructorEnabled && + !(*name_struct->mConstructorEnabled)(cx, naviObj)) { + return NS_OK; + } + domObject = construct(cx, naviObj); if (!domObject) { return NS_ERROR_FAILURE; diff --git a/dom/base/nsScriptNameSpaceManager.cpp b/dom/base/nsScriptNameSpaceManager.cpp index 29162f99a4e..ac32f4cd188 100644 --- a/dom/base/nsScriptNameSpaceManager.cpp +++ b/dom/base/nsScriptNameSpaceManager.cpp @@ -825,7 +825,7 @@ nsScriptNameSpaceManager::Observe(nsISupports* aSubject, const char* aTopic, void nsScriptNameSpaceManager::RegisterDefineDOMInterface(const nsAFlatString& aName, mozilla::dom::DefineInterface aDefineDOMInterface, - mozilla::dom::PrefEnabled aPrefEnabled) + mozilla::dom::ConstructorEnabled* aConstructorEnabled) { nsGlobalNameStruct *s = AddToHash(&mGlobalNames, &aName); if (s) { @@ -833,7 +833,7 @@ nsScriptNameSpaceManager::RegisterDefineDOMInterface(const nsAFlatString& aName, s->mType = nsGlobalNameStruct::eTypeNewDOMBinding; } s->mDefineDOMInterface = aDefineDOMInterface; - s->mPrefEnabled = aPrefEnabled; + s->mConstructorEnabled = aConstructorEnabled; } } @@ -841,7 +841,7 @@ void nsScriptNameSpaceManager::RegisterNavigatorDOMConstructor( const nsAFlatString& aName, mozilla::dom::ConstructNavigatorProperty aNavConstructor, - mozilla::dom::PrefEnabled aPrefEnabled) + mozilla::dom::ConstructorEnabled* aConstructorEnabled) { nsGlobalNameStruct *s = AddToHash(&mNavigatorNames, &aName); if (s) { @@ -849,7 +849,7 @@ nsScriptNameSpaceManager::RegisterNavigatorDOMConstructor( s->mType = nsGlobalNameStruct::eTypeNewDOMBinding; } s->mConstructNavigatorProperty = aNavConstructor; - s->mPrefEnabled = aPrefEnabled; + s->mConstructorEnabled = aConstructorEnabled; } } diff --git a/dom/base/nsScriptNameSpaceManager.h b/dom/base/nsScriptNameSpaceManager.h index beae88aa635..a8adc4fbdfb 100644 --- a/dom/base/nsScriptNameSpaceManager.h +++ b/dom/base/nsScriptNameSpaceManager.h @@ -55,6 +55,9 @@ struct nsGlobalNameStruct eTypeExternalConstructorAlias } mType; + // mChromeOnly is only used for structs that define non-WebIDL things + // (possibly in addition to WebIDL ones). In particular, it's not even + // initialized for eTypeNewDOMBinding structs. bool mChromeOnly; bool mDisabled; @@ -71,7 +74,8 @@ struct nsGlobalNameStruct mozilla::dom::DefineInterface mDefineDOMInterface; // for window mozilla::dom::ConstructNavigatorProperty mConstructNavigatorProperty; // for navigator }; - mozilla::dom::PrefEnabled mPrefEnabled; // May be null if not pref controlled + // May be null if enabled unconditionally + mozilla::dom::ConstructorEnabled* mConstructorEnabled; }; @@ -140,11 +144,11 @@ public: void RegisterDefineDOMInterface(const nsAFlatString& aName, mozilla::dom::DefineInterface aDefineDOMInterface, - mozilla::dom::PrefEnabled aPrefEnabled); + mozilla::dom::ConstructorEnabled* aConstructorEnabled); void RegisterNavigatorDOMConstructor(const nsAFlatString& aName, mozilla::dom::ConstructNavigatorProperty aNavConstructor, - mozilla::dom::PrefEnabled aPrefEnabled); + mozilla::dom::ConstructorEnabled* aConstructorEnabled); typedef PLDHashOperator (* GlobalNameEnumerator)(const nsAString& aGlobalName, void* aClosure); diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index a5d339ef22a..317aa96f1f4 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -1978,7 +1978,11 @@ class CGPrefEnabledNative(CGAbstractMethod): if the method returns true. """ def __init__(self, descriptor): - CGAbstractMethod.__init__(self, descriptor, 'PrefEnabled', 'bool', []) + CGAbstractMethod.__init__(self, descriptor, + 'ConstructorEnabled', 'bool', + [Argument("JSContext*", "/* unused */"), + Argument("JS::Handle", + "/* unused */")]) def definition_body(self): return " return %s::PrefEnabled();" % self.descriptor.nativeType @@ -1991,7 +1995,11 @@ class CGPrefEnabled(CGAbstractMethod): on the global if the pref is true. """ def __init__(self, descriptor): - CGAbstractMethod.__init__(self, descriptor, 'PrefEnabled', 'bool', []) + CGAbstractMethod.__init__(self, descriptor, + 'ConstructorEnabled', 'bool', + [Argument("JSContext*", "/* unused */"), + Argument("JS::Handle", + "/* unused */")]) def definition_body(self): pref = self.descriptor.interface.getExtendedAttribute("Pref") @@ -8027,12 +8035,12 @@ class CGRegisterProtos(CGAbstractMethod): def _defineMacro(self): return """ -#define REGISTER_PROTO(_dom_class, _pref_check) \\ - aNameSpaceManager->RegisterDefineDOMInterface(NS_LITERAL_STRING(#_dom_class), _dom_class##Binding::DefineDOMInterface, _pref_check); -#define REGISTER_CONSTRUCTOR(_dom_constructor, _dom_class, _pref_check) \\ - aNameSpaceManager->RegisterDefineDOMInterface(NS_LITERAL_STRING(#_dom_constructor), _dom_class##Binding::DefineDOMInterface, _pref_check); -#define REGISTER_NAVIGATOR_CONSTRUCTOR(_prop, _dom_class, _pref_check) \\ - aNameSpaceManager->RegisterNavigatorDOMConstructor(NS_LITERAL_STRING(_prop), _dom_class##Binding::ConstructNavigatorObject, _pref_check); +#define REGISTER_PROTO(_dom_class, _ctor_check) \\ + aNameSpaceManager->RegisterDefineDOMInterface(NS_LITERAL_STRING(#_dom_class), _dom_class##Binding::DefineDOMInterface, _ctor_check); +#define REGISTER_CONSTRUCTOR(_dom_constructor, _dom_class, _ctor_check) \\ + aNameSpaceManager->RegisterDefineDOMInterface(NS_LITERAL_STRING(#_dom_constructor), _dom_class##Binding::DefineDOMInterface, _ctor_check); +#define REGISTER_NAVIGATOR_CONSTRUCTOR(_prop, _dom_class, _ctor_check) \\ + aNameSpaceManager->RegisterNavigatorDOMConstructor(NS_LITERAL_STRING(_prop), _dom_class##Binding::ConstructNavigatorObject, _ctor_check); """ def _undefineMacro(self): @@ -8041,23 +8049,23 @@ class CGRegisterProtos(CGAbstractMethod): #undef REGISTER_PROTO #undef REGISTER_NAVIGATOR_CONSTRUCTOR""" def _registerProtos(self): - def getPrefCheck(desc): + def getCheck(desc): if (desc.interface.getExtendedAttribute("PrefControlled") is None and desc.interface.getExtendedAttribute("Pref") is None): return "nullptr" - return "%sBinding::PrefEnabled" % desc.name + return "%sBinding::ConstructorEnabled" % desc.name lines = [] for desc in self.config.getDescriptors(hasInterfaceObject=True, isExternal=False, workers=False, register=True): - lines.append("REGISTER_PROTO(%s, %s);" % (desc.name, getPrefCheck(desc))) - lines.extend("REGISTER_CONSTRUCTOR(%s, %s, %s);" % (n.identifier.name, desc.name, getPrefCheck(desc)) + lines.append("REGISTER_PROTO(%s, %s);" % (desc.name, getCheck(desc))) + lines.extend("REGISTER_CONSTRUCTOR(%s, %s, %s);" % (n.identifier.name, desc.name, getCheck(desc)) for n in desc.interface.namedConstructors) for desc in self.config.getDescriptors(isNavigatorProperty=True, register=True): propName = desc.interface.getNavigatorProperty() assert propName - lines.append('REGISTER_NAVIGATOR_CONSTRUCTOR("%s", %s, %s);' % (propName, desc.name, getPrefCheck(desc))) + lines.append('REGISTER_NAVIGATOR_CONSTRUCTOR("%s", %s, %s);' % (propName, desc.name, getCheck(desc))) return '\n'.join(lines) + '\n' def definition_body(self): return self._defineMacro() + self._registerProtos() + self._undefineMacro() diff --git a/js/xpconnect/src/xpcpublic.h b/js/xpconnect/src/xpcpublic.h index 5c04f36dc88..1ce3db287c8 100644 --- a/js/xpconnect/src/xpcpublic.h +++ b/js/xpconnect/src/xpcpublic.h @@ -479,8 +479,14 @@ typedef JSObject* typedef JSObject* (*ConstructNavigatorProperty)(JSContext *cx, JS::Handle naviObj); +// Check whether a constructor should be enabled for the given object. +// Note that the object should NOT be an Xray, since Xrays will end up +// defining constructors on the underlying object. +// This is a typedef for the function type itself, not the function +// pointer, so it's more obvious that pointers to a ConstructorEnabled +// can be null. typedef bool -(*PrefEnabled)(); +(ConstructorEnabled)(JSContext* cx, JS::Handle obj); extern bool DefineStaticJSVals(JSContext *cx); From 8fe36056f19b082d784b1c91b0ea1ecd9904be70 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 13 Jun 2013 01:12:33 -0400 Subject: [PATCH 02/20] Bug 880367 part 2. Make ordering of named constructors in codegen deterministic. r=smaug I ran into this when looking at the diff in codegen from part 1. --- dom/bindings/parser/WebIDL.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dom/bindings/parser/WebIDL.py b/dom/bindings/parser/WebIDL.py index 151d6ea7c0f..2f26482e6f9 100644 --- a/dom/bindings/parser/WebIDL.py +++ b/dom/bindings/parser/WebIDL.py @@ -508,7 +508,10 @@ class IDLInterface(IDLObjectWithScope): self._callback = False self._finished = False self.members = [] - self.namedConstructors = set() + # namedConstructors needs deterministic ordering because bindings code + # outputs the constructs in the order that namedConstructors enumerates + # them. + self.namedConstructors = list() self.implementedInterfaces = set() self._consequential = False self._isPartial = True @@ -903,7 +906,7 @@ class IDLInterface(IDLObjectWithScope): # NamedConstructors. newMethod = self.parentScope.lookupIdentifier(method.identifier) if newMethod == method: - self.namedConstructors.add(method) + self.namedConstructors.append(method) elif not newMethod in self.namedConstructors: raise WebIDLError("NamedConstructor conflicts with a NamedConstructor of a different interface", [method.location, newMethod.location]) From 738009a34fbb8a8e10e69b22fda7d2b232b61e4c Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 13 Jun 2013 01:12:37 -0400 Subject: [PATCH 03/20] Bug 880367 part 3. Add support for [ChromeOnly] on interface objects. r=smaug --- dom/bindings/Codegen.py | 33 ++++++++++++++++++++++++++++++--- dom/bindings/parser/WebIDL.py | 3 ++- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 317aa96f1f4..34a6c898981 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -2006,6 +2006,22 @@ class CGPrefEnabled(CGAbstractMethod): assert isinstance(pref, list) and len(pref) == 1 return " return Preferences::GetBool(\"%s\");" % pref[0] +class CGConstructorEnabledChromeOnly(CGAbstractMethod): + """ + A method for testing whether the object we're going to be defined + on is chrome so we can decide whether our constructor should be + enabled. + """ + def __init__(self, descriptor): + assert descriptor.interface.getExtendedAttribute("ChromeOnly") + CGAbstractMethod.__init__(self, descriptor, + 'ConstructorEnabled', 'bool', + [Argument("JSContext*", "aCx"), + Argument("JS::Handle", "aObj")]) + + def definition_body(self): + return " return %s;" % GetAccessCheck(self.descriptor, "aObj") + class CGIsMethod(CGAbstractMethod): def __init__(self, descriptor): args = [Argument('JSObject*', 'obj')] @@ -7518,10 +7534,20 @@ class CGDescriptor(CGThing): not descriptor.interface.isExternal() and # Workers stuff is never pref-controlled not descriptor.workers): - if descriptor.interface.getExtendedAttribute("PrefControlled") is not None: + prefControlled = descriptor.interface.getExtendedAttribute("PrefControlled") + havePref = descriptor.interface.getExtendedAttribute("Pref") + haveChromeOnly = descriptor.interface.getExtendedAttribute("ChromeOnly") + # Make sure at most one of those is set + if bool(prefControlled) + bool(havePref) + bool(haveChromeOnly) > 1: + raise TypeError("Interface %s has more than one of " + "'PrefControlled', 'Pref', and 'ChomeOnly' " + "specified", descriptor.name) + if prefControlled is not None: cgThings.append(CGPrefEnabledNative(descriptor)) - elif descriptor.interface.getExtendedAttribute("Pref") is not None: + elif havePref is not None: cgThings.append(CGPrefEnabled(descriptor)) + elif haveChromeOnly is not None: + cgThings.append(CGConstructorEnabledChromeOnly(descriptor)) if descriptor.concrete: if descriptor.proxy: @@ -8051,7 +8077,8 @@ class CGRegisterProtos(CGAbstractMethod): def _registerProtos(self): def getCheck(desc): if (desc.interface.getExtendedAttribute("PrefControlled") is None and - desc.interface.getExtendedAttribute("Pref") is None): + desc.interface.getExtendedAttribute("Pref") is None and + desc.interface.getExtendedAttribute("ChromeOnly") is None): return "nullptr" return "%sBinding::ConstructorEnabled" % desc.name lines = [] diff --git a/dom/bindings/parser/WebIDL.py b/dom/bindings/parser/WebIDL.py index 2f26482e6f9..03f0b131159 100644 --- a/dom/bindings/parser/WebIDL.py +++ b/dom/bindings/parser/WebIDL.py @@ -916,7 +916,8 @@ class IDLInterface(IDLObjectWithScope): identifier == "JSImplementation" or identifier == "HeaderFile" or identifier == "NavigatorProperty" or - identifier == "OverrideBuiltins"): + identifier == "OverrideBuiltins" or + identifier == "ChromeOnly"): # Known attributes that we don't need to do anything with here pass else: From 244464efdedc65bea33065f38fe1c903cf770f2a Mon Sep 17 00:00:00 2001 From: James Kitchener Date: Thu, 13 Jun 2013 01:15:35 -0400 Subject: [PATCH 04/20] Bug 796850 - Implement WebIDL parser support for Bytestring r=bz --- dom/bindings/parser/WebIDL.py | 67 ++++++++++++++++-- dom/bindings/parser/tests/test_bytestring.py | 72 ++++++++++++++++++++ dom/bindings/parser/tests/test_union.py | 1 + 3 files changed, 135 insertions(+), 5 deletions(-) create mode 100644 dom/bindings/parser/tests/test_bytestring.py diff --git a/dom/bindings/parser/WebIDL.py b/dom/bindings/parser/WebIDL.py index 03f0b131159..9adc1c781e4 100644 --- a/dom/bindings/parser/WebIDL.py +++ b/dom/bindings/parser/WebIDL.py @@ -384,7 +384,7 @@ class IDLObjectWithIdentifier(IDLObject): identifier = attr.identifier() value = attr.value() if identifier == "TreatNullAs": - if not self.type.isString() or self.type.nullable(): + if not self.type.isDOMString() or self.type.nullable(): raise WebIDLError("[TreatNullAs] is only allowed on " "arguments or attributes whose type is " "DOMString", @@ -407,7 +407,7 @@ class IDLObjectWithIdentifier(IDLObject): "allowed on optional arguments", [self.location]) elif value == 'Null': - if not self.type.isString(): + if not self.type.isDOMString(): raise WebIDLError("[TreatUndefinedAs=Null] is only " "allowed on arguments or " "attributes whose type is " @@ -418,7 +418,7 @@ class IDLObjectWithIdentifier(IDLObject): "allowed on arguments whose type " "is DOMString?", [self.location]) elif value == 'EmptyString': - if not self.type.isString(): + if not self.type.isDOMString(): raise WebIDLError("[TreatUndefinedAs=EmptyString] " "is only allowed on arguments or " "attributes whose type is " @@ -1217,6 +1217,7 @@ class IDLType(IDLObject): # Other types 'any', 'domstring', + 'bytestring', 'object', 'date', 'void', @@ -1256,6 +1257,12 @@ class IDLType(IDLObject): def isString(self): return False + def isByteString(self): + return False + + def isDOMString(self): + return False + def isVoid(self): return self.name == "Void" @@ -1404,6 +1411,12 @@ class IDLNullableType(IDLType): def isString(self): return self.inner.isString() + def isByteString(self): + return self.inner.isByteString() + + def isDOMString(self): + return self.inner.isDOMString() + def isFloat(self): return self.inner.isFloat() @@ -1513,6 +1526,12 @@ class IDLSequenceType(IDLType): def isString(self): return False; + def isByteString(self): + return False + + def isDOMString(self): + return False + def isVoid(self): return False @@ -1697,6 +1716,12 @@ class IDLArrayType(IDLType): def isString(self): return False + def isByteString(self): + return False + + def isDOMString(self): + return False + def isVoid(self): return False @@ -1780,6 +1805,12 @@ class IDLTypedefType(IDLType, IDLObjectWithIdentifier): def isString(self): return self.inner.isString() + def isByteString(self): + return self.inner.isByteString() + + def isDOMString(self): + return self.inner.isDOMString() + def isVoid(self): return self.inner.isVoid() @@ -1867,6 +1898,12 @@ class IDLWrapperType(IDLType): def isString(self): return False + def isByteString(self): + return False + + def isDOMString(self): + return False + def isVoid(self): return False @@ -1985,6 +2022,7 @@ class IDLBuiltinType(IDLType): # Other types 'any', 'domstring', + 'bytestring', 'object', 'date', 'void', @@ -2018,6 +2056,7 @@ class IDLBuiltinType(IDLType): Types.double: IDLType.Tags.double, Types.any: IDLType.Tags.any, Types.domstring: IDLType.Tags.domstring, + Types.bytestring: IDLType.Tags.bytestring, Types.object: IDLType.Tags.object, Types.date: IDLType.Tags.date, Types.void: IDLType.Tags.void, @@ -2043,6 +2082,13 @@ class IDLBuiltinType(IDLType): return self._typeTag <= IDLBuiltinType.Types.double def isString(self): + return self._typeTag == IDLBuiltinType.Types.domstring or \ + self._typeTag == IDLBuiltinType.Types.bytestring + + def isByteString(self): + return self._typeTag == IDLBuiltinType.Types.bytestring + + def isDOMString(self): return self._typeTag == IDLBuiltinType.Types.domstring def isInteger(self): @@ -2177,6 +2223,9 @@ BuiltinTypes = { IDLBuiltinType.Types.domstring: IDLBuiltinType(BuiltinLocation(""), "String", IDLBuiltinType.Types.domstring), + IDLBuiltinType.Types.bytestring: + IDLBuiltinType(BuiltinLocation(""), "ByteString", + IDLBuiltinType.Types.bytestring), IDLBuiltinType.Types.object: IDLBuiltinType(BuiltinLocation(""), "Object", IDLBuiltinType.Types.object), @@ -3260,6 +3309,7 @@ class Tokenizer(object): "::": "SCOPE", "Date": "DATE", "DOMString": "DOMSTRING", + "ByteString": "BYTESTRING", "any": "ANY", "boolean": "BOOLEAN", "byte": "BYTE", @@ -3817,8 +3867,8 @@ class Parser(Tokenizer): if len(arguments) != 0: raise WebIDLError("stringifier has wrong number of arguments", [self.getLocation(p, 2)]) - if not returnType.isString(): - raise WebIDLError("stringifier must have string return type", + if not returnType.isDOMString(): + raise WebIDLError("stringifier must have DOMString return type", [self.getLocation(p, 2)]) inOptionalArguments = False @@ -4127,6 +4177,7 @@ class Parser(Tokenizer): | QUESTIONMARK | DATE | DOMSTRING + | BYTESTRING | ANY | ATTRIBUTE | BOOLEAN @@ -4362,6 +4413,12 @@ class Parser(Tokenizer): """ p[0] = IDLBuiltinType.Types.domstring + def p_PrimitiveOrStringTypeBytestring(self, p): + """ + PrimitiveOrStringType : BYTESTRING + """ + p[0] = IDLBuiltinType.Types.bytestring + def p_UnsignedIntegerTypeUnsigned(self, p): """ UnsignedIntegerType : UNSIGNED IntegerType diff --git a/dom/bindings/parser/tests/test_bytestring.py b/dom/bindings/parser/tests/test_bytestring.py new file mode 100644 index 00000000000..d73455f8812 --- /dev/null +++ b/dom/bindings/parser/tests/test_bytestring.py @@ -0,0 +1,72 @@ +# -*- coding: UTF-8 -*- + +import WebIDL + +def WebIDLTest(parser, harness): + parser.parse(""" + interface TestByteString { + attribute ByteString bs; + attribute DOMString ds; + }; + """) + + results = parser.finish(); + + harness.ok(True, "TestByteString interface parsed without error.") + + harness.check(len(results), 1, "Should be one production") + harness.ok(isinstance(results[0], WebIDL.IDLInterface), + "Should be an IDLInterface") + iface = results[0] + harness.check(iface.identifier.QName(), "::TestByteString", "Interface has the right QName") + harness.check(iface.identifier.name, "TestByteString", "Interface has the right name") + harness.check(iface.parent, None, "Interface has no parent") + + members = iface.members + harness.check(len(members), 2, "Should be two productions") + + attr = members[0] + harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute") + harness.check(attr.identifier.QName(), "::TestByteString::bs", "Attr has correct QName") + harness.check(attr.identifier.name, "bs", "Attr has correct name") + harness.check(str(attr.type), "ByteString", "Attr type is the correct name") + harness.ok(attr.type.isByteString(), "Should be ByteString type") + harness.ok(attr.type.isString(), "Should be String collective type") + harness.ok(not attr.type.isDOMString(), "Should be not be DOMString type") + + # now check we haven't broken DOMStrings in the process. + attr = members[1] + harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute") + harness.check(attr.identifier.QName(), "::TestByteString::ds", "Attr has correct QName") + harness.check(attr.identifier.name, "ds", "Attr has correct name") + harness.check(str(attr.type), "String", "Attr type is the correct name") + harness.ok(attr.type.isDOMString(), "Should be DOMString type") + harness.ok(attr.type.isString(), "Should be String collective type") + harness.ok(not attr.type.isByteString(), "Should be not be ByteString type") + + # Cannot represent constant ByteString in IDL. + threw = False + try: + parser.parse(""" + interface ConstByteString { + const ByteString foo = "hello" + }; + """) + except WebIDL.WebIDLError: + threw = True + harness.ok(threw, "Should have thrown a WebIDL error") + + # Cannot have optional ByteStrings with default values + threw = False + try: + parser.parse(""" + interface OptionalByteString { + void passByteString(optional ByteString arg = "hello"); + }; + """) + results2 = parser.finish(); + except WebIDL.WebIDLError: + threw = True + + harness.ok(threw, "Should have thrown a WebIDL error") + diff --git a/dom/bindings/parser/tests/test_union.py b/dom/bindings/parser/tests/test_union.py index 68c2bcade8c..998afbc7f1d 100644 --- a/dom/bindings/parser/tests/test_union.py +++ b/dom/bindings/parser/tests/test_union.py @@ -62,6 +62,7 @@ def WebIDLTest(parser, harness): "byte", "octet", "DOMString", + "ByteString", #"sequence", "object", "ArrayBuffer", From 411a37e6e92b99252bd8df596b67b7502f2d687e Mon Sep 17 00:00:00 2001 From: James Kitchener Date: Thu, 13 Jun 2013 01:18:35 -0400 Subject: [PATCH 05/20] Bug 796850 - Implement Code Generation for Bytestring in WebIDL bindings r=bz --- dom/bindings/BindingUtils.cpp | 80 +++++++++++++++++++++++++ dom/bindings/BindingUtils.h | 23 +++++++ dom/bindings/Codegen.py | 57 +++++++++++++++--- dom/bindings/Errors.msg | 2 + dom/bindings/test/TestBindingHeader.h | 23 ++++++- dom/bindings/test/TestCodeGen.webidl | 12 +++- dom/bindings/test/TestExampleGen.webidl | 12 +++- dom/bindings/test/TestJSImplGen.webidl | 10 +++- 8 files changed, 207 insertions(+), 12 deletions(-) diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp index 2148db4ee70..2a421d821c3 100644 --- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -7,8 +7,10 @@ #include #include +#include "prprf.h" #include "mozilla/DebugOnly.h" #include "mozilla/FloatingPoint.h" +#include "mozilla/Assertions.h" #include "BindingUtils.h" @@ -1899,5 +1901,83 @@ ConstructJSImplementation(JSContext* aCx, const char* aContractId, return window.forget(); } +bool +NonVoidByteStringToJsval(JSContext *cx, const nsACString &str, + JS::MutableHandle rval) +{ + if (str.IsEmpty()) { + rval.set(JS_GetEmptyStringValue(cx)); + return true; + } + + // ByteStrings are not UTF-8 encoded. + JSString* jsStr = JS_NewStringCopyN(cx, str.Data(), str.Length()); + + if (!jsStr) + return false; + + rval.setString(jsStr); + return true; +} + +bool +ConvertJSValueToByteString(JSContext* cx, JS::Handle v, + JS::MutableHandle pval, bool nullable, + nsACString& result) +{ + JSString *s; + if (v.isString()) { + s = v.toString(); + } else { + + if (nullable && v.isNullOrUndefined()) { + result.SetIsVoid(true); + return true; + } + + s = JS_ValueToString(cx, v); + if (!s) { + return false; + } + pval.set(JS::StringValue(s)); // Root the new string. + } + + size_t length; + const jschar *chars = JS_GetStringCharsZAndLength(cx, s, &length); + if (!chars) { + return false; + } + + // Conversion from Javascript string to ByteString is only valid if all + // characters < 256. + for (size_t i = 0; i < length; i++) { + if (chars[i] > 255) { + // The largest unsigned 64 bit number (18,446,744,073,709,551,615) has + // 20 digits, plus one more for the null terminator. + char index[21]; + MOZ_STATIC_ASSERT(sizeof(size_t) <= 8, "index array too small"); + PR_snprintf(index, sizeof(index), "%d", i); + // A jschar is 16 bits long. The biggest unsigned 16 bit + // number (65,535) has 5 digits, plus one more for the null + // terminator. + char badChar[6]; + MOZ_STATIC_ASSERT(sizeof(jschar) <= 2, "badChar array too small"); + PR_snprintf(badChar, sizeof(badChar), "%d", chars[i]); + ThrowErrorMessage(cx, MSG_INVALID_BYTESTRING, index, badChar); + return false; + } + } + + if (length >= UINT32_MAX) { + return false; + } + result.SetCapacity(length+1); + JS_EncodeStringToBuffer(cx, s, result.BeginWriting(), length); + result.BeginWriting()[length] = '\0'; + result.SetLength(length); + + return true; +} + } // namespace dom } // namespace mozilla diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h index 3336a7af239..25fa820284e 100644 --- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -1582,6 +1582,11 @@ ConvertJSValueToString(JSContext* cx, JS::Handle v, return true; } +bool +ConvertJSValueToByteString(JSContext* cx, JS::Handle v, + JS::MutableHandle pval, bool nullable, + nsACString& result); + // Class for holding the type of members of a union. The union type has an enum // to keep track of which of its UnionMembers has been constructed. template @@ -2057,6 +2062,24 @@ bool RegisterForDeferredFinalization(DeferredFinalizeStartFunction start, DeferredFinalizeFunction run); +/** + * Convert an nsCString to jsval, returning true on success. + * These functions are intended for ByteString implementations. + * As such, the string is not UTF-8 encoded. Any UTF8 strings passed to these + * methods will be mangled. + */ +bool NonVoidByteStringToJsval(JSContext *cx, const nsACString &str, + JS::MutableHandle rval); +inline bool ByteStringToJsval(JSContext *cx, const nsACString &str, + JS::MutableHandle rval) +{ + if (str.IsVoid()) { + rval.setNull(); + return true; + } + return NonVoidByteStringToJsval(cx, str, rval); +} + } // namespace dom } // namespace mozilla diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 34a6c898981..623f82711e9 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -3213,7 +3213,7 @@ for (uint32_t i = 0; i < length; ++i) { declType=CGGeneric(declType), holderType=holderType) - if type.isString(): + if type.isDOMString(): assert not isEnforceRange and not isClamp treatAs = { @@ -3279,6 +3279,24 @@ for (uint32_t i = 0; i < length; ++i) { declType=CGGeneric(declType), holderType=CGGeneric("FakeDependentString")) + if type.isByteString(): + assert not isEnforceRange and not isClamp + + nullable = toStringBool(type.nullable()) + + conversionCode = ( + "if (!ConvertJSValueToByteString(cx, ${val}, ${mutableVal}," + " %s, ${declName})) {\n" + "%s\n" + "}" % (nullable, exceptionCodeIndented.define())) + # ByteString arguments cannot have a default value. + assert defaultValue is None + + return JSToNativeConversionInfo( + conversionCode, + declType=CGGeneric("nsCString"), + dealWithOptional=isOptional) + if type.isEnum(): assert not isEnforceRange and not isClamp @@ -3982,12 +4000,18 @@ if (!returnArray) { wrappingCode += wrapAndSetPtr(wrap, failed) return (wrappingCode, False) - if type.isString(): + if type.isDOMString(): if type.nullable(): return (wrapAndSetPtr("xpc::StringToJsval(cx, %s, ${jsvalRef}.address())" % result), False) else: return (wrapAndSetPtr("xpc::NonVoidStringToJsval(cx, %s, ${jsvalRef}.address())" % result), False) + if type.isByteString(): + if type.nullable(): + return (wrapAndSetPtr("ByteStringToJsval(cx, %s, ${jsvalHandle})" % result), False) + else: + return (wrapAndSetPtr("NonVoidByteStringToJsval(cx, %s, ${jsvalHandle})" % result), False) + if type.isEnum(): if type.nullable(): resultLoc = "%s.Value()" % result @@ -4203,10 +4227,12 @@ def getRetvalDeclarationForType(returnType, descriptorProvider, if returnType.nullable(): result = CGTemplatedType("Nullable", result) return result, False, None, None - if returnType.isString(): + if returnType.isDOMString(): if isMember: return CGGeneric("nsString"), True, None, None return CGGeneric("DOMString"), True, None, None + if returnType.isByteString(): + return CGGeneric("nsCString"), True, None, None if returnType.isEnum(): result = CGGeneric(returnType.unroll().inner.identifier.name) if returnType.nullable(): @@ -5679,9 +5705,12 @@ def getUnionAccessorSignatureType(type, descriptorProvider): typeName = CGWrapper(typeName, post="&") return typeName - if type.isString(): + if type.isDOMString(): return CGGeneric("const nsAString&") + if type.isByteString(): + return CGGeneric("const nsCString&") + if type.isEnum(): if type.nullable(): raise TypeError("We don't support nullable enumerated arguments or " @@ -8483,12 +8512,18 @@ class CGNativeMember(ClassMethod): return (result.define(), "%s(%s)" % (result.define(), defaultReturnArg), "return ${declName};") - if type.isString(): + if type.isDOMString(): if isMember: # No need for a third element in the isMember case return "nsString", None, None # Outparam return "void", "", "retval = ${declName};" + if type.isByteString(): + if isMember: + # No need for a third element in the isMember case + return "nsCString", None, None + # Outparam + return "void", "", "retval = ${declName};" if type.isEnum(): enumName = type.unroll().inner.identifier.name if type.nullable(): @@ -8567,8 +8602,10 @@ class CGNativeMember(ClassMethod): def getArgs(self, returnType, argList): args = [self.getArg(arg) for arg in argList] # Now the outparams - if returnType.isString(): + if returnType.isDOMString(): args.append(Argument("nsString&", "retval")) + if returnType.isByteString(): + args.append(Argument("nsCString&", "retval")) elif returnType.isSequence(): nullable = returnType.nullable() if nullable: @@ -8662,13 +8699,17 @@ class CGNativeMember(ClassMethod): typeDecl = typeDecl % type.name return typeDecl, False, False - if type.isString(): + if type.isDOMString(): if isMember: declType = "nsString" else: declType = "nsAString" return declType, True, False + if type.isByteString(): + declType = "nsCString" + return declType, True, False + if type.isEnum(): return type.unroll().inner.identifier.name, False, True @@ -9535,7 +9576,7 @@ class CallbackMember(CGNativeMember): jsvalIndex = "%d" % i if arg.optional and not arg.defaultValue: argval += ".Value()" - if arg.type.isString(): + if arg.type.isDOMString(): # XPConnect string-to-JS conversion wants to mutate the string. So # let's give it a string it can mutate # XXXbz if we try to do a sequence of strings, this will kinda fail. diff --git a/dom/bindings/Errors.msg b/dom/bindings/Errors.msg index 339f7a0d07e..9038834a93c 100644 --- a/dom/bindings/Errors.msg +++ b/dom/bindings/Errors.msg @@ -37,4 +37,6 @@ MSG_DEF(MSG_ENCODING_NOT_SUPPORTED, 1, "The given encoding '{0}' is not supporte MSG_DEF(MSG_DOM_ENCODING_NOT_UTF, 0, "The encoding must be utf-8, utf-16, or utf-16be.") MSG_DEF(MSG_NOT_FINITE, 0, "Floating-point value is not finite.") MSG_DEF(MSG_INVALID_VERSION, 0, "0 (Zero) is not a valid database version.") +MSG_DEF(MSG_INVALID_BYTESTRING, 2, "Cannot convert string to ByteString because the character" + " at index {0} has value {1} which is greater than 255.") MSG_DEF(MSG_NOT_DATE, 0, "Value is not a date.") diff --git a/dom/bindings/test/TestBindingHeader.h b/dom/bindings/test/TestBindingHeader.h index 66cb4e3fcf4..94410d079ba 100644 --- a/dom/bindings/test/TestBindingHeader.h +++ b/dom/bindings/test/TestBindingHeader.h @@ -137,6 +137,10 @@ public: already_AddRefed Test(const GlobalObject&, const nsAString&, ErrorResult&); static + already_AddRefed Test(const GlobalObject&, const nsACString&, + ErrorResult&); + + static already_AddRefed Test2(const GlobalObject&, JSContext*, const DictForConstructor&, @@ -370,6 +374,9 @@ public: void ReceiveStringSequence(nsTArray&); void PassStringSequence(const Sequence&); + void ReceiveByteStringSequence(nsTArray&); + void PassByteStringSequence(const Sequence&); + void ReceiveAnySequence(JSContext*, nsTArray&); void ReceiveNullableAnySequence(JSContext*, Nullable >&); void ReceiveAnySequenceSequence(JSContext*, nsTArray >&); @@ -398,7 +405,7 @@ public: void PassFloat64Array(Float64Array&); JSObject* ReceiveUint8Array(JSContext*); - // String types + // DOMString types void PassString(const nsAString&); void PassNullableString(const nsAString&); void PassOptionalString(const Optional&); @@ -409,6 +416,13 @@ public: void PassOptionalNullableStringWithDefaultValue(const nsAString&); void PassVariadicString(const Sequence&); + // ByteString types + void PassByteString(const nsCString&); + void PassNullableByteString(const nsCString&); + void PassOptionalByteString(const Optional&); + void PassOptionalNullableByteString(const Optional&); + void PassVariadicByteString(const Sequence&); + // Enumerated types void PassEnum(TestEnum); void PassNullableEnum(const Nullable&); @@ -753,6 +767,13 @@ private: void PassOptionalNullableStringWithDefaultValue(nsAString&) MOZ_DELETE; void PassVariadicString(Sequence&) MOZ_DELETE; + // cstrings should be const as well + void PassByteString(nsCString&) MOZ_DELETE; + void PassNullableByteString(nsCString&) MOZ_DELETE; + void PassOptionalByteString(Optional&) MOZ_DELETE; + void PassOptionalNullableByteString(Optional&) MOZ_DELETE; + void PassVariadicByteString(Sequence&) MOZ_DELETE; + // Make sure dictionary arguments are always const void PassDictionary(JSContext*, Dict&) MOZ_DELETE; void PassOtherDictionary(GrandparentDict&) MOZ_DELETE; diff --git a/dom/bindings/test/TestCodeGen.webidl b/dom/bindings/test/TestCodeGen.webidl index 222ce939df5..3d66ac63894 100644 --- a/dom/bindings/test/TestCodeGen.webidl +++ b/dom/bindings/test/TestCodeGen.webidl @@ -338,6 +338,9 @@ interface TestInterface { sequence receiveStringSequence(); void passStringSequence(sequence arg); + sequence receiveByteStringSequence(); + void passByteStringSequence(sequence arg); + sequence receiveAnySequence(); sequence? receiveNullableAnySequence(); sequence> receiveAnySequenceSequence(); @@ -366,7 +369,7 @@ interface TestInterface { void passFloat64Array(Float64Array arg); Uint8Array receiveUint8Array(); - // String types + // DOMString types void passString(DOMString arg); void passNullableString(DOMString? arg); void passOptionalString(optional DOMString arg); @@ -377,6 +380,13 @@ interface TestInterface { void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null); void passVariadicString(DOMString... arg); + // ByteString types + void passByteString(ByteString arg); + void passNullableByteString(ByteString? arg); + void passOptionalByteString(optional ByteString arg); + void passOptionalNullableByteString(optional ByteString? arg); + void passVariadicByteString(ByteString... arg); + // Enumerated types void passEnum(TestEnum arg); void passNullableEnum(TestEnum? arg); diff --git a/dom/bindings/test/TestExampleGen.webidl b/dom/bindings/test/TestExampleGen.webidl index ead8c634d71..3174440dc1d 100644 --- a/dom/bindings/test/TestExampleGen.webidl +++ b/dom/bindings/test/TestExampleGen.webidl @@ -234,6 +234,9 @@ interface TestExampleInterface { sequence receiveStringSequence(); void passStringSequence(sequence arg); + sequence receiveByteStringSequence(); + void passByteStringSequence(sequence arg); + sequence receiveAnySequence(); sequence? receiveNullableAnySequence(); //XXXbz No support for sequence of sequence return values yet. @@ -264,7 +267,7 @@ interface TestExampleInterface { void passFloat64Array(Float64Array arg); Uint8Array receiveUint8Array(); - // String types + // DOMString types void passString(DOMString arg); void passNullableString(DOMString? arg); void passOptionalString(optional DOMString arg); @@ -275,6 +278,13 @@ interface TestExampleInterface { void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null); void passVariadicString(DOMString... arg); + // ByteString types + void passByteString(ByteString arg); + void passNullableByteString(ByteString? arg); + void passOptionalByteString(optional ByteString arg); + void passOptionalNullableByteString(optional ByteString? arg); + void passVariadicByteString(ByteString... arg); + // Enumerated types void passEnum(TestEnum arg); void passNullableEnum(TestEnum? arg); diff --git a/dom/bindings/test/TestJSImplGen.webidl b/dom/bindings/test/TestJSImplGen.webidl index 3fd57f04483..1b575c38ad6 100644 --- a/dom/bindings/test/TestJSImplGen.webidl +++ b/dom/bindings/test/TestJSImplGen.webidl @@ -252,6 +252,7 @@ interface TestJSImplInterface { void passNullableExternalInterfaceSequence(sequence arg); sequence receiveStringSequence(); + sequence receiveByteStringSequence(); // Callback interface problem. See bug 843261. //void passStringSequence(sequence arg); sequence receiveAnySequence(); @@ -287,7 +288,7 @@ interface TestJSImplInterface { //void passFloat64Array(Float64Array arg); //Uint8Array receiveUint8Array(); - // String types + // DOMString types void passString(DOMString arg); void passNullableString(DOMString? arg); void passOptionalString(optional DOMString arg); @@ -298,6 +299,13 @@ interface TestJSImplInterface { void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null); void passVariadicString(DOMString... arg); + // ByteString types + void passByteString(ByteString arg); + void passNullableByteString(ByteString? arg); + void passOptionalByteString(optional ByteString arg); + void passOptionalNullableByteString(optional ByteString? arg); + void passVariadicByteString(ByteString... arg); + // Enumerated types void passEnum(MyTestEnum arg); void passNullableEnum(MyTestEnum? arg); From 41dd9cfa20f61c100e7470b1038c931fa89dfbf1 Mon Sep 17 00:00:00 2001 From: James Kitchener Date: Thu, 13 Jun 2013 01:20:10 -0400 Subject: [PATCH 06/20] Bug 796850 - Change XMLHttpRequest interface to support ByteString r=bz --- content/base/public/nsIXMLHttpRequest.idl | 12 +++---- content/base/src/nsXMLHttpRequest.cpp | 37 ++++++++------------ content/base/src/nsXMLHttpRequest.h | 13 ++++--- content/base/test/test_bug638112.html | 10 ++++-- dom/bindings/test/Makefile.in | 1 + dom/bindings/test/test_ByteString.html | 32 ++++++++++++++++++ dom/webidl/XMLHttpRequest.webidl | 10 +++--- dom/workers/XMLHttpRequest.cpp | 41 +++++++++++------------ dom/workers/XMLHttpRequest.h | 12 +++---- 9 files changed, 96 insertions(+), 72 deletions(-) create mode 100644 dom/bindings/test/test_ByteString.html diff --git a/content/base/public/nsIXMLHttpRequest.idl b/content/base/public/nsIXMLHttpRequest.idl index 42271d0360f..139493301d3 100644 --- a/content/base/public/nsIXMLHttpRequest.idl +++ b/content/base/public/nsIXMLHttpRequest.idl @@ -21,7 +21,7 @@ interface nsIDOMBlob; #include "jsapi.h" %} -[scriptable, builtinclass, uuid(5bc978f2-41e5-4349-a12d-b018092271f7)] +[scriptable, builtinclass, uuid(ac97e161-9f1d-4163-adc9-e9a59e18682c)] interface nsIXMLHttpRequestEventTarget : nsIDOMEventTarget { // event handler attributes [implicit_jscontext] attribute jsval onabort; @@ -133,7 +133,7 @@ interface nsIXMLHttpRequest : nsISupports * The string representing the status of the response for * HTTP requests. */ - readonly attribute DOMString statusText; + readonly attribute ACString statusText; /** * If the request has been sent already, this method will @@ -148,7 +148,7 @@ interface nsIXMLHttpRequest : nsISupports * @returns A string containing all of the response headers. * The empty string if the response has not yet been received. */ - DOMString getAllResponseHeaders(); + ACString getAllResponseHeaders(); /** * Returns the text of the header with the specified name for @@ -159,7 +159,7 @@ interface nsIXMLHttpRequest : nsISupports * NULL if the response has not yet been received or the * header does not exist in the response. */ - ACString getResponseHeader(in AUTF8String header); + ACString getResponseHeader(in ACString header); %{C++ // note this is NOT virtual so this won't muck with the vtable! @@ -189,7 +189,7 @@ interface nsIXMLHttpRequest : nsISupports * @param password (optional) A password for authentication if necessary. * The default value is the empty string */ - [optional_argc] void open(in AUTF8String method, in AUTF8String url, + [optional_argc] void open(in ACString method, in AUTF8String url, [optional] in boolean async, [optional,Undefined(Empty)] in DOMString user, [optional,Undefined(Empty)] in DOMString password); @@ -237,7 +237,7 @@ interface nsIXMLHttpRequest : nsISupports * @param header The name of the header to set in the request. * @param value The body of the header. */ - void setRequestHeader(in AUTF8String header, in AUTF8String value); + void setRequestHeader(in ACString header, in ACString value); /** * The amount of milliseconds a request can take before being terminated. diff --git a/content/base/src/nsXMLHttpRequest.cpp b/content/base/src/nsXMLHttpRequest.cpp index 45fd22b2e58..b9522c9151a 100644 --- a/content/base/src/nsXMLHttpRequest.cpp +++ b/content/base/src/nsXMLHttpRequest.cpp @@ -139,11 +139,11 @@ using namespace mozilla::dom; #define NS_PROGRESS_EVENT_INTERVAL 50 -#define IMPL_STRING_GETTER(_name) \ +#define IMPL_CSTRING_GETTER(_name) \ NS_IMETHODIMP \ - nsXMLHttpRequest::_name(nsAString& aOut) \ + nsXMLHttpRequest::_name(nsACString& aOut) \ { \ - nsString tmp; \ + nsCString tmp; \ _name(tmp); \ aOut = tmp; \ return NS_OK; \ @@ -1128,9 +1128,9 @@ nsXMLHttpRequest::Status() return status; } -IMPL_STRING_GETTER(GetStatusText) +IMPL_CSTRING_GETTER(GetStatusText) void -nsXMLHttpRequest::GetStatusText(nsString& aStatusText) +nsXMLHttpRequest::GetStatusText(nsCString& aStatusText) { nsCOMPtr httpChannel = GetCurrentHttpChannel(); @@ -1152,17 +1152,8 @@ nsXMLHttpRequest::GetStatusText(nsString& aStatusText) } } - nsCString statusText; - httpChannel->GetResponseStatusText(statusText); - if (statusText.IsVoid()) { - aStatusText.SetIsVoid(true); - } else { - // We use UTF8ToNewUnicode here because it truncates after invalid UTF-8 - // characters, CopyUTF8toUTF16 just doesn't copy in that case. - uint32_t length; - PRUnichar* chars = UTF8ToNewUnicode(statusText, &length); - aStatusText.Adopt(chars, length); - } + httpChannel->GetResponseStatusText(aStatusText); + } void @@ -1286,10 +1277,10 @@ nsXMLHttpRequest::IsSafeHeader(const nsACString& header, nsIHttpChannel* httpCha return isSafe; } -/* DOMString getAllResponseHeaders(); */ -IMPL_STRING_GETTER(GetAllResponseHeaders) +/* ByteString getAllResponseHeaders(); */ +IMPL_CSTRING_GETTER(GetAllResponseHeaders) void -nsXMLHttpRequest::GetAllResponseHeaders(nsString& aResponseHeaders) +nsXMLHttpRequest::GetAllResponseHeaders(nsCString& aResponseHeaders) { aResponseHeaders.Truncate(); @@ -1303,7 +1294,7 @@ nsXMLHttpRequest::GetAllResponseHeaders(nsString& aResponseHeaders) if (nsCOMPtr httpChannel = GetCurrentHttpChannel()) { nsRefPtr visitor = new nsHeaderVisitor(this, httpChannel); if (NS_SUCCEEDED(httpChannel->VisitResponseHeaders(visitor))) { - CopyASCIItoUTF16(visitor->Headers(), aResponseHeaders); + aResponseHeaders = visitor->Headers(); } return; } @@ -1316,10 +1307,10 @@ nsXMLHttpRequest::GetAllResponseHeaders(nsString& aResponseHeaders) nsAutoCString value; if (NS_SUCCEEDED(mChannel->GetContentType(value))) { aResponseHeaders.AppendLiteral("Content-Type: "); - AppendASCIItoUTF16(value, aResponseHeaders); + aResponseHeaders.Append(value); if (NS_SUCCEEDED(mChannel->GetContentCharset(value)) && !value.IsEmpty()) { aResponseHeaders.AppendLiteral(";charset="); - AppendASCIItoUTF16(value, aResponseHeaders); + aResponseHeaders.Append(value); } aResponseHeaders.AppendLiteral("\r\n"); } @@ -2950,7 +2941,7 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable& aBody) return rv; } -/* void setRequestHeader (in AUTF8String header, in AUTF8String value); */ +/* void setRequestHeader (in ByteString header, in ByteString value); */ // http://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#dom-xmlhttprequest-setrequestheader NS_IMETHODIMP nsXMLHttpRequest::SetRequestHeader(const nsACString& header, diff --git a/content/base/src/nsXMLHttpRequest.h b/content/base/src/nsXMLHttpRequest.h index 35833522f65..0cf38e57d67 100644 --- a/content/base/src/nsXMLHttpRequest.h +++ b/content/base/src/nsXMLHttpRequest.h @@ -242,19 +242,18 @@ public: uint16_t ReadyState(); // request - void Open(const nsAString& aMethod, const nsAString& aUrl, bool aAsync, + void Open(const nsACString& aMethod, const nsAString& aUrl, bool aAsync, const mozilla::dom::Optional& aUser, const mozilla::dom::Optional& aPassword, ErrorResult& aRv) { - aRv = Open(NS_ConvertUTF16toUTF8(aMethod), NS_ConvertUTF16toUTF8(aUrl), + aRv = Open(aMethod, NS_ConvertUTF16toUTF8(aUrl), aAsync, aUser, aPassword); } - void SetRequestHeader(const nsAString& aHeader, const nsAString& aValue, + void SetRequestHeader(const nsACString& aHeader, const nsACString& aValue, ErrorResult& aRv) { - aRv = SetRequestHeader(NS_ConvertUTF16toUTF8(aHeader), - NS_ConvertUTF16toUTF8(aValue)); + aRv = SetRequestHeader(aHeader, aValue); } uint32_t Timeout() { @@ -400,7 +399,7 @@ public: // response uint32_t Status(); - void GetStatusText(nsString& aStatusText); + void GetStatusText(nsCString& aStatusText); void GetResponseHeader(const nsACString& aHeader, nsACString& aResult, ErrorResult& aRv); void GetResponseHeader(const nsAString& aHeader, nsString& aResult, @@ -416,7 +415,7 @@ public: CopyASCIItoUTF16(result, aResult); } } - void GetAllResponseHeaders(nsString& aResponseHeaders); + void GetAllResponseHeaders(nsCString& aResponseHeaders); bool IsSafeHeader(const nsACString& aHeaderName, nsIHttpChannel* aHttpChannel); void OverrideMimeType(const nsAString& aMimeType) { diff --git a/content/base/test/test_bug638112.html b/content/base/test/test_bug638112.html index b6be27dae90..4f6741ed04c 100644 --- a/content/base/test/test_bug638112.html +++ b/content/base/test/test_bug638112.html @@ -2,6 +2,7 @@ Test for Bug 638112 @@ -10,15 +11,18 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=638112 Mozilla Bug 638112 +Mozilla Bug 796850

 
+  
+
+
+Mozilla Bug 796850
+

+
+
+
+ + diff --git a/dom/webidl/XMLHttpRequest.webidl b/dom/webidl/XMLHttpRequest.webidl index e3a09983f65..d5e4459b5b0 100644 --- a/dom/webidl/XMLHttpRequest.webidl +++ b/dom/webidl/XMLHttpRequest.webidl @@ -71,10 +71,10 @@ interface XMLHttpRequest : XMLHttpRequestEventTarget { // request [Throws] - void open(DOMString method, DOMString url, optional boolean async = true, + void open(ByteString method, DOMString url, optional boolean async = true, optional DOMString? user, optional DOMString? password); [Throws] - void setRequestHeader(DOMString header, DOMString value); + void setRequestHeader(ByteString header, ByteString value); [SetterThrows] attribute unsigned long timeout; @@ -109,12 +109,12 @@ interface XMLHttpRequest : XMLHttpRequestEventTarget { [Throws=Workers] readonly attribute unsigned short status; - readonly attribute DOMString statusText; + readonly attribute ByteString statusText; [Throws] - DOMString? getResponseHeader(DOMString header); + ByteString? getResponseHeader(ByteString header); [Throws=Workers] - DOMString getAllResponseHeaders(); + ByteString getAllResponseHeaders(); [Throws=Workers] void overrideMimeType(DOMString mime); diff --git a/dom/workers/XMLHttpRequest.cpp b/dom/workers/XMLHttpRequest.cpp index 63c5f5a4d66..9299cadad7e 100644 --- a/dom/workers/XMLHttpRequest.cpp +++ b/dom/workers/XMLHttpRequest.cpp @@ -523,7 +523,7 @@ class EventRunnable : public MainThreadProxyRunnable nsTArray > mClonedObjects; jsval mResponse; nsString mResponseText; - nsString mStatusText; + nsCString mStatusText; uint64_t mLoaded; uint64_t mTotal; uint32_t mEventStreamId; @@ -970,11 +970,11 @@ public: class GetAllResponseHeadersRunnable : public WorkerThreadProxySyncRunnable { - nsString& mResponseHeaders; + nsCString& mResponseHeaders; public: GetAllResponseHeadersRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy, - nsString& aResponseHeaders) + nsCString& aResponseHeaders) : WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mResponseHeaders(aResponseHeaders) { } @@ -994,7 +994,7 @@ class GetResponseHeaderRunnable : public WorkerThreadProxySyncRunnable public: GetResponseHeaderRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy, - const nsCString& aHeader, nsCString& aValue) + const nsACString& aHeader, nsCString& aValue) : WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mHeader(aHeader), mValue(aValue) { } @@ -1008,7 +1008,7 @@ public: class OpenRunnable : public WorkerThreadProxySyncRunnable { - nsString mMethod; + nsCString mMethod; nsString mURL; Optional mUser; nsString mUserStr; @@ -1020,7 +1020,7 @@ class OpenRunnable : public WorkerThreadProxySyncRunnable public: OpenRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy, - const nsAString& aMethod, const nsAString& aURL, + const nsACString& aMethod, const nsAString& aURL, const Optional& aUser, const Optional& aPassword, bool aBackgroundRequest, bool aWithCredentials, @@ -1201,7 +1201,7 @@ class SetRequestHeaderRunnable : public WorkerThreadProxySyncRunnable public: SetRequestHeaderRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy, - const nsCString& aHeader, const nsCString& aValue) + const nsACString& aHeader, const nsACString& aValue) : WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mHeader(aHeader), mValue(aValue) { } @@ -1716,7 +1716,7 @@ XMLHttpRequest::Notify(JSContext* aCx, Status aStatus) } void -XMLHttpRequest::Open(const nsAString& aMethod, const nsAString& aUrl, +XMLHttpRequest::Open(const nsACString& aMethod, const nsAString& aUrl, bool aAsync, const Optional& aUser, const Optional& aPassword, ErrorResult& aRv) { @@ -1754,8 +1754,8 @@ XMLHttpRequest::Open(const nsAString& aMethod, const nsAString& aUrl, } void -XMLHttpRequest::SetRequestHeader(const nsAString& aHeader, - const nsAString& aValue, ErrorResult& aRv) +XMLHttpRequest::SetRequestHeader(const nsACString& aHeader, + const nsACString& aValue, ErrorResult& aRv) { mWorkerPrivate->AssertIsOnWorkerThread(); @@ -1770,9 +1770,7 @@ XMLHttpRequest::SetRequestHeader(const nsAString& aHeader, } nsRefPtr runnable = - new SetRequestHeaderRunnable(mWorkerPrivate, mProxy, - NS_ConvertUTF16toUTF8(aHeader), - NS_ConvertUTF16toUTF8(aValue)); + new SetRequestHeaderRunnable(mWorkerPrivate, mProxy, aHeader, aValue); if (!runnable->Dispatch(GetJSContext())) { aRv.Throw(NS_ERROR_FAILURE); return; @@ -2012,8 +2010,8 @@ XMLHttpRequest::Abort(ErrorResult& aRv) } void -XMLHttpRequest::GetResponseHeader(const nsAString& aHeader, - nsAString& aResponseHeader, ErrorResult& aRv) +XMLHttpRequest::GetResponseHeader(const nsACString& aHeader, + nsACString& aResponseHeader, ErrorResult& aRv) { mWorkerPrivate->AssertIsOnWorkerThread(); @@ -2027,20 +2025,19 @@ XMLHttpRequest::GetResponseHeader(const nsAString& aHeader, return; } - nsCString value; + nsCString responseHeader; nsRefPtr runnable = - new GetResponseHeaderRunnable(mWorkerPrivate, mProxy, - NS_ConvertUTF16toUTF8(aHeader), value); + new GetResponseHeaderRunnable(mWorkerPrivate, mProxy, aHeader, + responseHeader); if (!runnable->Dispatch(GetJSContext())) { aRv.Throw(NS_ERROR_FAILURE); return; } - - aResponseHeader = NS_ConvertUTF8toUTF16(value); + aResponseHeader = responseHeader; } void -XMLHttpRequest::GetAllResponseHeaders(nsAString& aResponseHeaders, +XMLHttpRequest::GetAllResponseHeaders(nsACString& aResponseHeaders, ErrorResult& aRv) { mWorkerPrivate->AssertIsOnWorkerThread(); @@ -2055,7 +2052,7 @@ XMLHttpRequest::GetAllResponseHeaders(nsAString& aResponseHeaders, return; } - nsString responseHeaders; + nsCString responseHeaders; nsRefPtr runnable = new GetAllResponseHeadersRunnable(mWorkerPrivate, mProxy, responseHeaders); if (!runnable->Dispatch(GetJSContext())) { diff --git a/dom/workers/XMLHttpRequest.h b/dom/workers/XMLHttpRequest.h index b5b575aab76..1ce15261e4d 100644 --- a/dom/workers/XMLHttpRequest.h +++ b/dom/workers/XMLHttpRequest.h @@ -29,7 +29,7 @@ public: { nsString mResponseText; uint32_t mStatus; - nsString mStatusText; + nsCString mStatusText; uint16_t mReadyState; jsval mResponse; nsresult mResponseTextResult; @@ -122,12 +122,12 @@ public: } void - Open(const nsAString& aMethod, const nsAString& aUrl, bool aAsync, + Open(const nsACString& aMethod, const nsAString& aUrl, bool aAsync, const Optional& aUser, const Optional& aPassword, ErrorResult& aRv); void - SetRequestHeader(const nsAString& aHeader, const nsAString& aValue, + SetRequestHeader(const nsACString& aHeader, const nsACString& aValue, ErrorResult& aRv); uint32_t @@ -199,17 +199,17 @@ public: } void - GetStatusText(nsAString& aStatusText) const + GetStatusText(nsACString& aStatusText) const { aStatusText = mStateData.mStatusText; } void - GetResponseHeader(const nsAString& aHeader, nsAString& aResponseHeader, + GetResponseHeader(const nsACString& aHeader, nsACString& aResponseHeader, ErrorResult& aRv); void - GetAllResponseHeaders(nsAString& aResponseHeaders, ErrorResult& aRv); + GetAllResponseHeaders(nsACString& aResponseHeaders, ErrorResult& aRv); void OverrideMimeType(const nsAString& aMimeType, ErrorResult& aRv); From a3760474ad362e28917aaeb6824a63de7b31ae34 Mon Sep 17 00:00:00 2001 From: Jesse Ruderman Date: Wed, 12 Jun 2013 22:24:06 -0700 Subject: [PATCH 07/20] Bug 882037 - Fix incorrectly escaped %, and use semicolons after comma-separated lists. r=luke --- js/src/ion/AsmJS.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/src/ion/AsmJS.cpp b/js/src/ion/AsmJS.cpp index 7197bc978e4..43f198fd04f 100644 --- a/js/src/ion/AsmJS.cpp +++ b/js/src/ion/AsmJS.cpp @@ -3991,7 +3991,7 @@ CheckDivOrMod(FunctionCompiler &f, ParseNode *expr, MDefinition **def, Type *typ return true; } - return f.failf(expr, "arguments to / or &% must both be double, signed, or unsigned, " + return f.failf(expr, "arguments to / or %% must both be double, signed, or unsigned; " "%s and %s are given", lhsType.toChars(), rhsType.toChars()); } @@ -4025,7 +4025,7 @@ CheckComparison(FunctionCompiler &f, ParseNode *comp, MDefinition **def, Type *t return true; } - return f.failf(comp, "arguments to a comparison must both be signed, unsigned or doubles, " + return f.failf(comp, "arguments to a comparison must both be signed, unsigned or doubles; " "%s and %s are given", lhsType.toChars(), rhsType.toChars()); } From b6f7390e8e2950de889a343c78e59ac854e0c049 Mon Sep 17 00:00:00 2001 From: Jonathan Wilde Date: Wed, 12 Jun 2013 17:55:49 -0700 Subject: [PATCH 08/20] Bug 874963 - Work - popups don't move when scrolling. r=fryn --- browser/metro/base/content/helperui/MenuUI.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/browser/metro/base/content/helperui/MenuUI.js b/browser/metro/base/content/helperui/MenuUI.js index a937544b9cb..74012e3cf5e 100644 --- a/browser/metro/base/content/helperui/MenuUI.js +++ b/browser/metro/base/content/helperui/MenuUI.js @@ -352,6 +352,7 @@ MenuPopup.prototype = { window.addEventListener("keypress", this, true); window.addEventListener("mousedown", this, true); Elements.stack.addEventListener("PopupChanged", this, false); + Elements.browsers.addEventListener("PanBegin", this, false); this._panel.hidden = false; this._position(aPositionOptions || {}); @@ -382,6 +383,7 @@ MenuPopup.prototype = { window.removeEventListener("keypress", this, true); window.removeEventListener("mousedown", this, true); Elements.stack.removeEventListener("PopupChanged", this, false); + Elements.browsers.removeEventListener("PanBegin", this, false); let self = this; this._panel.addEventListener("transitionend", function () { @@ -497,6 +499,9 @@ MenuPopup.prototype = { this.hide(); } break; + case "PanBegin": + this.hide(); + break; } } }; From da695125a0e4dfcf60a6d2d3e477dc5f89c33f7d Mon Sep 17 00:00:00 2001 From: Mark Capella Date: Thu, 13 Jun 2013 02:58:59 -0400 Subject: [PATCH 09/20] Bug 868222 - Tab increment animation displays an artifact, r=wesj --- mobile/android/base/TabCounter.java | 33 +++++++++++++++++++---------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/mobile/android/base/TabCounter.java b/mobile/android/base/TabCounter.java index d6b984f8cbf..6b670d8a21e 100644 --- a/mobile/android/base/TabCounter.java +++ b/mobile/android/base/TabCounter.java @@ -66,21 +66,32 @@ public class TabCounter extends GeckoTextSwitcher } public void setCountWithAnimation(int count) { - if (mCount == count) - return; - // Don't animate from initial state - if (mCount != 0) { - if (count < mCount) { - setInAnimation(mFlipInBackward); - setOutAnimation(mFlipOutForward); - } else if (count > mCount) { - setInAnimation(mFlipInForward); - setOutAnimation(mFlipOutBackward); - } + if (mCount == 0) { + setCount(count); + return; } + if (mCount == count) { + return; + } + + if (count < mCount) { + setInAnimation(mFlipInBackward); + setOutAnimation(mFlipOutForward); + } else { + setInAnimation(mFlipInForward); + setOutAnimation(mFlipOutBackward); + } + + // Eliminate screen artifact. Set explicit In/Out animation pair order. This will always + // animate pair in In->Out child order, prevent alternating use of the Out->In case. + setDisplayedChild(0); + + // Set In value, trigger animation to Out value + setCurrentText(String.valueOf(mCount)); setText(String.valueOf(count)); + mCount = count; } From 668fb2a3fc4c95c7060accb080012739903491c6 Mon Sep 17 00:00:00 2001 From: Landry Breuil Date: Thu, 13 Jun 2013 08:41:49 +0200 Subject: [PATCH 10/20] Bug 807492 Part 3 - Backport chunk of upstream gtest r629 to fix detection on BSDs with old libstdc++, not breaking it on MacOSX r=upstream --- .../testing/gtest/include/gtest/internal/gtest-port.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/media/webrtc/trunk/testing/gtest/include/gtest/internal/gtest-port.h b/media/webrtc/trunk/testing/gtest/include/gtest/internal/gtest-port.h index 2432fd62433..3a595f40355 100644 --- a/media/webrtc/trunk/testing/gtest/include/gtest/internal/gtest-port.h +++ b/media/webrtc/trunk/testing/gtest/include/gtest/internal/gtest-port.h @@ -490,10 +490,10 @@ # define GTEST_ENV_HAS_TR1_TUPLE_ 1 # endif -// C++11 specifies that provides std::tuple. Users can't use -// gtest in C++11 mode until their standard library is at least that -// compliant. -# if GTEST_LANG_CXX11 +// C++11 specifies that provides std::tuple. Use that if gtest is used +// in C++11 mode and libstdc++ isn't very old (binaries targeting OS X 10.6 +// can build with clang but need to use gcc4.2's libstdc++). +# if GTEST_LANG_CXX11 && (!defined(__GLIBCXX__) || __GLIBCXX__ > 20110325) # define GTEST_ENV_HAS_STD_TUPLE_ 1 # endif From d46d33b5061197f5e4e42257361bfeb6c7587979 Mon Sep 17 00:00:00 2001 From: Landry Breuil Date: Thu, 13 Jun 2013 08:41:54 +0200 Subject: [PATCH 11/20] Bug 804792 Part 4: Select alsa/pulse/v4l depending on the OS, define WEBRTC_POSIX on BSD r=jesup --- media/webrtc/trunk/webrtc/build/common.gypi | 27 +++++++++++++++++++++ media/webrtc/trunk/webrtc/typedefs.h | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/media/webrtc/trunk/webrtc/build/common.gypi b/media/webrtc/trunk/webrtc/build/common.gypi index bee0432b8c5..a086d3fdac0 100644 --- a/media/webrtc/trunk/webrtc/build/common.gypi +++ b/media/webrtc/trunk/webrtc/build/common.gypi @@ -124,6 +124,21 @@ # and Java Implementation 'enable_android_opensl%': 0, }], + ['OS=="linux"', { + 'include_alsa_audio%': 1, + }, { + 'include_alsa_audio%': 0, + }], + ['OS=="solaris" or os_bsd==1', { + 'include_pulse_audio%': 1, + }, { + 'include_pulse_audio%': 0, + }], + ['OS=="linux" or OS=="solaris" or os_bsd==1', { + 'include_v4l2_video_capture%': 1, + }, { + 'include_v4l2_video_capture%': 0, + }], ['OS=="ios"', { 'enable_video%': 0, 'enable_protobuf%': 0, @@ -215,6 +230,18 @@ }], ], }], + ['os_bsd==1', { + 'defines': [ + 'WEBRTC_BSD', + 'WEBRTC_THREAD_RR', + ], + }], + ['OS=="dragonfly" or OS=="netbsd"', { + 'defines': [ + # doesn't support pthread_condattr_setclock + 'WEBRTC_CLOCK_TYPE_REALTIME', + ], + }], ['OS=="ios"', { 'defines': [ 'WEBRTC_MAC', diff --git a/media/webrtc/trunk/webrtc/typedefs.h b/media/webrtc/trunk/webrtc/typedefs.h index e82bbefe9cc..fec664dc120 100644 --- a/media/webrtc/trunk/webrtc/typedefs.h +++ b/media/webrtc/trunk/webrtc/typedefs.h @@ -21,7 +21,7 @@ // For access to standard POSIXish features, use WEBRTC_POSIX instead of a // more specific macro. #if defined(WEBRTC_MAC) || defined(WEBRTC_LINUX) || \ - defined(WEBRTC_ANDROID) + defined(WEBRTC_ANDROID) || defined(WEBRTC_BSD) #define WEBRTC_POSIX #endif From 8b2632fb5015353f8e8842a34fdc5ad4b5356286 Mon Sep 17 00:00:00 2001 From: Landry Breuil Date: Thu, 13 Jun 2013 08:41:59 +0200 Subject: [PATCH 12/20] Bug 807492 Part 5 - Use the linux codepaths on BSD in audio_device r=jesup Also open libpulse.so on OpenBSD, different versionning scheme. --- .../modules/audio_device/audio_device_utility.cc | 4 ++-- .../linux/latebindingsymboltable_linux.cc | 12 ++++++------ .../linux/latebindingsymboltable_linux.h | 2 +- .../linux/pulseaudiosymboltable_linux.cc | 4 ++++ 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/media/webrtc/trunk/webrtc/modules/audio_device/audio_device_utility.cc b/media/webrtc/trunk/webrtc/modules/audio_device/audio_device_utility.cc index 203f09a0de0..0b0b70e2faa 100644 --- a/media/webrtc/trunk/webrtc/modules/audio_device/audio_device_utility.cc +++ b/media/webrtc/trunk/webrtc/modules/audio_device/audio_device_utility.cc @@ -46,7 +46,7 @@ bool AudioDeviceUtility::StringCompare( } // namespace webrtc -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || defined(WEBRTC_MAC) // ============================================================================ // Linux & Mac @@ -109,6 +109,6 @@ bool AudioDeviceUtility::StringCompare( } // namespace webrtc -#endif // defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) +#endif // defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || defined(WEBRTC_MAC) diff --git a/media/webrtc/trunk/webrtc/modules/audio_device/linux/latebindingsymboltable_linux.cc b/media/webrtc/trunk/webrtc/modules/audio_device/linux/latebindingsymboltable_linux.cc index 8f3c7c8d4d5..7c934214ab2 100644 --- a/media/webrtc/trunk/webrtc/modules/audio_device/linux/latebindingsymboltable_linux.cc +++ b/media/webrtc/trunk/webrtc/modules/audio_device/linux/latebindingsymboltable_linux.cc @@ -27,7 +27,7 @@ #include "latebindingsymboltable_linux.h" -#ifdef WEBRTC_LINUX +#if defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) #include #endif @@ -37,7 +37,7 @@ using namespace webrtc; namespace webrtc_adm_linux { inline static const char *GetDllError() { -#ifdef WEBRTC_LINUX +#if defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) char *err = dlerror(); if (err) { return err; @@ -50,7 +50,7 @@ inline static const char *GetDllError() { } DllHandle InternalLoadDll(const char dll_name[]) { -#ifdef WEBRTC_LINUX +#if defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) DllHandle handle = dlopen(dll_name, RTLD_NOW); #else #error Not implemented @@ -63,7 +63,7 @@ DllHandle InternalLoadDll(const char dll_name[]) { } void InternalUnloadDll(DllHandle handle) { -#ifdef WEBRTC_LINUX +#if defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) if (dlclose(handle) != 0) { WEBRTC_TRACE(kTraceError, kTraceAudioDevice, -1, "%d", GetDllError()); @@ -76,7 +76,7 @@ void InternalUnloadDll(DllHandle handle) { static bool LoadSymbol(DllHandle handle, const char *symbol_name, void **symbol) { -#ifdef WEBRTC_LINUX +#if defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) *symbol = dlsym(handle, symbol_name); char *err = dlerror(); if (err) { @@ -101,7 +101,7 @@ bool InternalLoadSymbols(DllHandle handle, int num_symbols, const char *const symbol_names[], void *symbols[]) { -#ifdef WEBRTC_LINUX +#if defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) // Clear any old errors. dlerror(); #endif diff --git a/media/webrtc/trunk/webrtc/modules/audio_device/linux/latebindingsymboltable_linux.h b/media/webrtc/trunk/webrtc/modules/audio_device/linux/latebindingsymboltable_linux.h index 91d25aa2dc8..c32e21187e1 100644 --- a/media/webrtc/trunk/webrtc/modules/audio_device/linux/latebindingsymboltable_linux.h +++ b/media/webrtc/trunk/webrtc/modules/audio_device/linux/latebindingsymboltable_linux.h @@ -42,7 +42,7 @@ namespace webrtc_adm_linux { -#ifdef WEBRTC_LINUX +#if defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) typedef void *DllHandle; const DllHandle kInvalidDllHandle = NULL; diff --git a/media/webrtc/trunk/webrtc/modules/audio_device/linux/pulseaudiosymboltable_linux.cc b/media/webrtc/trunk/webrtc/modules/audio_device/linux/pulseaudiosymboltable_linux.cc index ae663f700d3..7d41a9a712b 100644 --- a/media/webrtc/trunk/webrtc/modules/audio_device/linux/pulseaudiosymboltable_linux.cc +++ b/media/webrtc/trunk/webrtc/modules/audio_device/linux/pulseaudiosymboltable_linux.cc @@ -29,7 +29,11 @@ namespace webrtc_adm_linux_pulse { +#ifdef __OpenBSD__ +LATE_BINDING_SYMBOL_TABLE_DEFINE_BEGIN(PulseAudioSymbolTable, "libpulse.so") +#else LATE_BINDING_SYMBOL_TABLE_DEFINE_BEGIN(PulseAudioSymbolTable, "libpulse.so.0") +#endif #define X(sym) \ LATE_BINDING_SYMBOL_TABLE_DEFINE_ENTRY(PulseAudioSymbolTable, sym) PULSE_AUDIO_SYMBOLS_LIST From 502ec9b29a66207a8431bc0e40efcbb90d06dc38 Mon Sep 17 00:00:00 2001 From: Landry Breuil Date: Thu, 13 Jun 2013 08:42:03 +0200 Subject: [PATCH 13/20] Bug 807492 Part 6 - Use linux codepaths on BSD in video_capture, uses v4l2 compatible API r=jesup --- .../webrtc/modules/video_capture/device_info_impl.cc | 6 +++--- .../modules/video_capture/linux/device_info_linux.cc | 6 ++++++ .../video_capture/linux/video_capture_linux.cc | 10 +++++++++- .../webrtc/modules/video_capture/video_capture.gypi | 12 ++++++++---- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/media/webrtc/trunk/webrtc/modules/video_capture/device_info_impl.cc b/media/webrtc/trunk/webrtc/modules/video_capture/device_info_impl.cc index e0d5e7ea34a..b26a7e05a42 100644 --- a/media/webrtc/trunk/webrtc/modules/video_capture/device_info_impl.cc +++ b/media/webrtc/trunk/webrtc/modules/video_capture/device_info_impl.cc @@ -54,7 +54,7 @@ WebRtc_Word32 DeviceInfoImpl::NumberOfCapabilities( if (_lastUsedDeviceNameLength == strlen((char*) deviceUniqueIdUTF8)) { // Is it the same device that is asked for again. -#if defined(WEBRTC_MAC) || defined(WEBRTC_LINUX) +#if defined(WEBRTC_MAC) || defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) if(strncasecmp((char*)_lastUsedDeviceName, (char*) deviceUniqueIdUTF8, _lastUsedDeviceNameLength)==0) @@ -91,7 +91,7 @@ WebRtc_Word32 DeviceInfoImpl::GetCapability(const char* deviceUniqueIdUTF8, ReadLockScoped cs(_apiLock); if ((_lastUsedDeviceNameLength != strlen((char*) deviceUniqueIdUTF8)) -#if defined(WEBRTC_MAC) || defined(WEBRTC_LINUX) +#if defined(WEBRTC_MAC) || defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || (strncasecmp((char*)_lastUsedDeviceName, (char*) deviceUniqueIdUTF8, _lastUsedDeviceNameLength)!=0)) @@ -155,7 +155,7 @@ WebRtc_Word32 DeviceInfoImpl::GetBestMatchedCapability( ReadLockScoped cs(_apiLock); if ((_lastUsedDeviceNameLength != strlen((char*) deviceUniqueIdUTF8)) -#if defined(WEBRTC_MAC) || defined(WEBRTC_LINUX) +#if defined(WEBRTC_MAC) || defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || (strncasecmp((char*)_lastUsedDeviceName, (char*) deviceUniqueIdUTF8, _lastUsedDeviceNameLength)!=0)) diff --git a/media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.cc b/media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.cc index 9300dc2859c..6ecbd5932a9 100644 --- a/media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.cc +++ b/media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.cc @@ -19,7 +19,13 @@ #include //v4l includes +#if defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__) +#include +#elif defined(__sun) +#include +#else #include +#endif #include "ref_count.h" #include "trace.h" diff --git a/media/webrtc/trunk/webrtc/modules/video_capture/linux/video_capture_linux.cc b/media/webrtc/trunk/webrtc/modules/video_capture/linux/video_capture_linux.cc index 61837003cea..8eca2884f6b 100644 --- a/media/webrtc/trunk/webrtc/modules/video_capture/linux/video_capture_linux.cc +++ b/media/webrtc/trunk/webrtc/modules/video_capture/linux/video_capture_linux.cc @@ -12,12 +12,20 @@ #include #include #include -#include #include #include #include #include +//v4l includes +#if defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__) +#include +#elif defined(__sun) +#include +#else +#include +#endif + #include #include "ref_count.h" diff --git a/media/webrtc/trunk/webrtc/modules/video_capture/video_capture.gypi b/media/webrtc/trunk/webrtc/modules/video_capture/video_capture.gypi index d46b5aa4869..b3d7e2aa5d9 100644 --- a/media/webrtc/trunk/webrtc/modules/video_capture/video_capture.gypi +++ b/media/webrtc/trunk/webrtc/modules/video_capture/video_capture.gypi @@ -48,7 +48,7 @@ ], }, { # include_internal_video_capture == 1 'conditions': [ - ['OS=="linux"', { + ['include_v4l2_video_capture==1', { 'include_dirs': [ 'linux', ], @@ -157,7 +157,7 @@ 'test/video_capture_main_mac.mm', ], 'conditions': [ - ['OS=="mac" or OS=="linux"', { + ['OS!="win" and OS!="android"', { 'cflags': [ '-Wno-write-strings', ], @@ -165,11 +165,15 @@ '-lpthread -lm', ], }], + ['include_v4l2_video_capture==1', { + 'libraries': [ + '-lXext', + '-lX11', + ], + }], ['OS=="linux"', { 'libraries': [ '-lrt', - '-lXext', - '-lX11', ], }], ['OS=="mac"', { From f9d0f3c54af261e482997c0a3304f58d311ba866 Mon Sep 17 00:00:00 2001 From: Landry Breuil Date: Thu, 13 Jun 2013 08:44:53 +0200 Subject: [PATCH 14/20] Bug 807492 Part 7 - use linux codepath on BSD in video_engine r=jesup --- media/webrtc/trunk/webrtc/video_engine/vie_defines.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/webrtc/trunk/webrtc/video_engine/vie_defines.h b/media/webrtc/trunk/webrtc/video_engine/vie_defines.h index 42c91b56163..bed9a06ce92 100644 --- a/media/webrtc/trunk/webrtc/video_engine/vie_defines.h +++ b/media/webrtc/trunk/webrtc/video_engine/vie_defines.h @@ -173,7 +173,7 @@ inline int ChannelId(const int moduleId) { // Linux specific. #ifndef WEBRTC_ANDROID -#ifdef WEBRTC_LINUX +#if defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) // Build information macros. #if defined(_DEBUG) #define BUILDMODE "d" From 8aec3fbb94ddf880691de378473e809ec6adead1 Mon Sep 17 00:00:00 2001 From: Landry Breuil Date: Thu, 13 Jun 2013 08:44:58 +0200 Subject: [PATCH 15/20] Bug 804792 Part 8 - Use the MacOSX codepath on BSD in voice_engine r=jesup --- media/webrtc/trunk/webrtc/voice_engine/voe_network_impl.cc | 6 +++--- .../webrtc/trunk/webrtc/voice_engine/voice_engine_defines.h | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/media/webrtc/trunk/webrtc/voice_engine/voe_network_impl.cc b/media/webrtc/trunk/webrtc/voice_engine/voe_network_impl.cc index d0b9895c701..f6a7f94de10 100644 --- a/media/webrtc/trunk/webrtc/voice_engine/voe_network_impl.cc +++ b/media/webrtc/trunk/webrtc/voice_engine/voe_network_impl.cc @@ -472,7 +472,7 @@ int VoENetworkImpl::SetSendTOS(int channel, "SetSendTOS(channel=%d, DSCP=%d, useSetSockopt=%d)", channel, DSCP, useSetSockopt); -#if !defined(_WIN32) && !defined(WEBRTC_LINUX) && !defined(WEBRTC_MAC) +#if !defined(_WIN32) && !defined(WEBRTC_LINUX) && !defined(WEBRTC_BSD) && !defined(WEBRTC_MAC) _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceWarning, "SetSendTOS() is not supported on this platform"); return -1; @@ -528,7 +528,7 @@ int VoENetworkImpl::SetSendTOS(int channel, "SetSendTOS() external transport is enabled"); return -1; } -#if defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) +#if defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || defined(WEBRTC_MAC) useSetSockopt = true; WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_shared->instance_id(), -1), " force useSetSockopt=true since there is no alternative" @@ -551,7 +551,7 @@ int VoENetworkImpl::GetSendTOS(int channel, WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), "GetSendTOS(channel=%d)", channel); -#if !defined(_WIN32) && !defined(WEBRTC_LINUX) && !defined(WEBRTC_MAC) +#if !defined(_WIN32) && !defined(WEBRTC_LINUX) && !defined(WEBRTC_BSD) && !defined(WEBRTC_MAC) _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceWarning, "GetSendTOS() is not supported on this platform"); return -1; diff --git a/media/webrtc/trunk/webrtc/voice_engine/voice_engine_defines.h b/media/webrtc/trunk/webrtc/voice_engine/voice_engine_defines.h index 88fdc7e50bc..3b63a3bca88 100644 --- a/media/webrtc/trunk/webrtc/voice_engine/voice_engine_defines.h +++ b/media/webrtc/trunk/webrtc/voice_engine/voice_engine_defines.h @@ -414,7 +414,7 @@ namespace webrtc // *** WEBRTC_MAC *** // including iPhone -#ifdef WEBRTC_MAC +#if defined(WEBRTC_BSD) || defined(WEBRTC_MAC) #include #include @@ -431,6 +431,7 @@ namespace webrtc #include #include #include +#if !defined(WEBRTC_BSD) #include #if !defined(WEBRTC_IOS) #include @@ -439,6 +440,7 @@ namespace webrtc #include #include #endif +#endif #define DWORD unsigned long int #define WINAPI @@ -531,7 +533,7 @@ namespace webrtc #else #define IPHONE_NOT_SUPPORTED(stat) -#endif // #ifdef WEBRTC_MAC +#endif // #if defined(WEBRTC_BSD) || defined(WEBRTC_MAC) From 273fce0b8157b16f1ef75b0c3ce87e439f92a43b Mon Sep 17 00:00:00 2001 From: Landry Breuil Date: Thu, 13 Jun 2013 08:46:14 +0200 Subject: [PATCH 16/20] Bug 807492 Part 9 - support WebRTC on BSD in system_wrappers/ r=jesup Remove inclusion in webrtc/system_wrappers/source/atomic32_posix.cc, it breaks on FreeBSD --- .../system_wrappers/interface/asm_defines.h | 2 +- .../system_wrappers/interface/tick_util.h | 14 +++--- .../system_wrappers/source/atomic32_posix.cc | 1 - .../source/condition_variable.cc | 8 ++-- .../source/condition_variable_posix.cc | 2 +- .../webrtc/system_wrappers/source/cpu.cc | 4 +- .../webrtc/system_wrappers/source/cpu_info.cc | 21 ++++++--- .../system_wrappers/source/thread_posix.cc | 43 +++++++++++++++++-- .../system_wrappers/source/trace_posix.cc | 2 +- 9 files changed, 72 insertions(+), 25 deletions(-) diff --git a/media/webrtc/trunk/webrtc/system_wrappers/interface/asm_defines.h b/media/webrtc/trunk/webrtc/system_wrappers/interface/asm_defines.h index c9f99b74f4c..55afc4ff58b 100644 --- a/media/webrtc/trunk/webrtc/system_wrappers/interface/asm_defines.h +++ b/media/webrtc/trunk/webrtc/system_wrappers/interface/asm_defines.h @@ -11,7 +11,7 @@ #ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ASM_DEFINES_H_ #define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ASM_DEFINES_H_ -#if defined(__linux__) && defined(__ELF__) +#if (defined(__linux__) || defined(__FreeBSD__)) && defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif diff --git a/media/webrtc/trunk/webrtc/system_wrappers/interface/tick_util.h b/media/webrtc/trunk/webrtc/system_wrappers/interface/tick_util.h index acd16a523b7..a8102a0f947 100644 --- a/media/webrtc/trunk/webrtc/system_wrappers/interface/tick_util.h +++ b/media/webrtc/trunk/webrtc/system_wrappers/interface/tick_util.h @@ -194,7 +194,7 @@ inline WebRtc_Word64 TickTime::QueryOsForTicks() { } result.ticks_ = now + (num_wrap_time_get_time << 32); #endif -#elif defined(WEBRTC_LINUX) +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) struct timespec ts; // TODO(wu): Remove CLOCK_REALTIME implementation. #ifdef WEBRTC_CLOCK_TYPE_REALTIME @@ -241,7 +241,7 @@ inline WebRtc_Word64 TickTime::MillisecondTimestamp() { #else return ticks; #endif -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || defined(WEBRTC_MAC) return ticks / 1000000LL; #else return ticks / 1000LL; @@ -258,7 +258,7 @@ inline WebRtc_Word64 TickTime::MicrosecondTimestamp() { #else return ticks * 1000LL; #endif -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || defined(WEBRTC_MAC) return ticks / 1000LL; #else return ticks; @@ -278,7 +278,7 @@ inline WebRtc_Word64 TickTime::MillisecondsToTicks(const WebRtc_Word64 ms) { #else return ms; #endif -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || defined(WEBRTC_MAC) return ms * 1000000LL; #else return ms * 1000LL; @@ -294,7 +294,7 @@ inline WebRtc_Word64 TickTime::TicksToMilliseconds(const WebRtc_Word64 ticks) { #else return ticks; #endif -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || defined(WEBRTC_MAC) return ticks / 1000000LL; #else return ticks / 1000LL; @@ -323,7 +323,7 @@ inline WebRtc_Word64 TickInterval::Milliseconds() const { // interval_ is in ms return interval_; #endif -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || defined(WEBRTC_MAC) // interval_ is in ns return interval_ / 1000000; #else @@ -342,7 +342,7 @@ inline WebRtc_Word64 TickInterval::Microseconds() const { // interval_ is in ms return interval_ * 1000LL; #endif -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || defined(WEBRTC_MAC) // interval_ is in ns return interval_ / 1000; #else diff --git a/media/webrtc/trunk/webrtc/system_wrappers/source/atomic32_posix.cc b/media/webrtc/trunk/webrtc/system_wrappers/source/atomic32_posix.cc index 8a52617efea..d0e542e3b5a 100644 --- a/media/webrtc/trunk/webrtc/system_wrappers/source/atomic32_posix.cc +++ b/media/webrtc/trunk/webrtc/system_wrappers/source/atomic32_posix.cc @@ -12,7 +12,6 @@ #include #include -#include #include "common_types.h" diff --git a/media/webrtc/trunk/webrtc/system_wrappers/source/condition_variable.cc b/media/webrtc/trunk/webrtc/system_wrappers/source/condition_variable.cc index d97f1d7c7f6..54b40149eb6 100644 --- a/media/webrtc/trunk/webrtc/system_wrappers/source/condition_variable.cc +++ b/media/webrtc/trunk/webrtc/system_wrappers/source/condition_variable.cc @@ -8,14 +8,14 @@ * be found in the AUTHORS file in the root of the source tree. */ +#include "condition_variable_wrapper.h" + #if defined(_WIN32) #include #include "condition_variable_win.h" -#include "condition_variable_wrapper.h" -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || defined(WEBRTC_MAC) #include #include "condition_variable_posix.h" -#include "condition_variable_wrapper.h" #endif namespace webrtc { @@ -23,7 +23,7 @@ namespace webrtc { ConditionVariableWrapper* ConditionVariableWrapper::CreateConditionVariable() { #if defined(_WIN32) return new ConditionVariableWindows; -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || defined(WEBRTC_MAC) return ConditionVariablePosix::Create(); #else return NULL; diff --git a/media/webrtc/trunk/webrtc/system_wrappers/source/condition_variable_posix.cc b/media/webrtc/trunk/webrtc/system_wrappers/source/condition_variable_posix.cc index a5df728ba61..c62206c01cc 100644 --- a/media/webrtc/trunk/webrtc/system_wrappers/source/condition_variable_posix.cc +++ b/media/webrtc/trunk/webrtc/system_wrappers/source/condition_variable_posix.cc @@ -79,7 +79,7 @@ bool ConditionVariablePosix::SleepCS(CriticalSectionWrapper& crit_sect, unsigned long max_time_inMS) { const unsigned long INFINITE = 0xFFFFFFFF; const int MILLISECONDS_PER_SECOND = 1000; -#ifndef WEBRTC_LINUX +#if !defined(WEBRTC_LINUX) && !defined(WEBRTC_BSD) const int MICROSECONDS_PER_MILLISECOND = 1000; #endif const int NANOSECONDS_PER_SECOND = 1000000000; diff --git a/media/webrtc/trunk/webrtc/system_wrappers/source/cpu.cc b/media/webrtc/trunk/webrtc/system_wrappers/source/cpu.cc index d81f0153175..3a3c74f825f 100644 --- a/media/webrtc/trunk/webrtc/system_wrappers/source/cpu.cc +++ b/media/webrtc/trunk/webrtc/system_wrappers/source/cpu.cc @@ -14,7 +14,7 @@ #include "cpu_win.h" #elif defined(WEBRTC_MAC) #include "cpu_mac.h" -#elif defined(WEBRTC_ANDROID) +#elif defined(WEBRTC_ANDROID) || defined(WEBRTC_BSD) // Not implemented yet, might be possible to use Linux implementation #else // defined(WEBRTC_LINUX) #include "cpu_linux.h" @@ -26,7 +26,7 @@ CpuWrapper* CpuWrapper::CreateCpu() { return new CpuWindows(); #elif defined(WEBRTC_MAC) return new CpuWrapperMac(); -#elif defined(WEBRTC_ANDROID) +#elif defined(WEBRTC_ANDROID) || defined(WEBRTC_BSD) return 0; #else return new CpuLinux(); diff --git a/media/webrtc/trunk/webrtc/system_wrappers/source/cpu_info.cc b/media/webrtc/trunk/webrtc/system_wrappers/source/cpu_info.cc index a4fd1b1b24d..cede9d0f2b2 100644 --- a/media/webrtc/trunk/webrtc/system_wrappers/source/cpu_info.cc +++ b/media/webrtc/trunk/webrtc/system_wrappers/source/cpu_info.cc @@ -12,13 +12,15 @@ #if defined(_WIN32) #include -#elif defined(WEBRTC_MAC) -#include +#elif defined(WEBRTC_BSD) || defined(WEBRTC_MAC) #include +#include #elif defined(WEBRTC_ANDROID) // Not implemented yet, might be possible to use Linux implementation -#else // defined(WEBRTC_LINUX) +#elif defined(WEBRTC_LINUX) #include +#else // defined(_SC_NPROCESSORS_ONLN) +#include #endif #include "trace.h" @@ -41,8 +43,15 @@ WebRtc_UWord32 CpuInfo::DetectNumberOfCores() { WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, "Available number of cores:%d", number_of_cores_); -#elif defined(WEBRTC_MAC) - int name[] = {CTL_HW, HW_AVAILCPU}; +#elif defined(WEBRTC_BSD) || defined(WEBRTC_MAC) + int name[] = { + CTL_HW, +#ifdef HW_AVAILCPU + HW_AVAILCPU, +#else + HW_NCPU, +#endif + }; int ncpu; size_t size = sizeof(ncpu); if (0 == sysctl(name, 2, &ncpu, &size, NULL, 0)) { @@ -54,6 +63,8 @@ WebRtc_UWord32 CpuInfo::DetectNumberOfCores() { "Failed to get number of cores"); number_of_cores_ = 1; } +#elif defined(_SC_NPROCESSORS_ONLN) + _numberOfCores = sysconf(_SC_NPROCESSORS_ONLN); #else WEBRTC_TRACE(kTraceWarning, kTraceUtility, -1, "No function to get number of cores"); diff --git a/media/webrtc/trunk/webrtc/system_wrappers/source/thread_posix.cc b/media/webrtc/trunk/webrtc/system_wrappers/source/thread_posix.cc index fc6ef99478d..12b4af5a7aa 100644 --- a/media/webrtc/trunk/webrtc/system_wrappers/source/thread_posix.cc +++ b/media/webrtc/trunk/webrtc/system_wrappers/source/thread_posix.cc @@ -59,6 +59,17 @@ #include #endif +#if defined(__NetBSD__) +#include +#elif defined(__FreeBSD__) +#include +#include +#endif + +#if defined(WEBRTC_BSD) && !defined(__NetBSD__) +#include +#endif + #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" #include "webrtc/system_wrappers/interface/event_wrapper.h" #include "webrtc/system_wrappers/interface/trace.h" @@ -141,6 +152,20 @@ uint32_t ThreadWrapper::GetThreadId() { return static_cast(syscall(__NR_gettid)); #elif defined(WEBRTC_MAC) || defined(WEBRTC_IOS) return pthread_mach_thread_np(pthread_self()); +#elif defined(__NetBSD__) + return _lwp_self(); +#elif defined(__DragonFly__) + return lwp_gettid(); +#elif defined(__OpenBSD__) + return reinterpret_cast (pthread_self()); +#elif defined(__FreeBSD__) +# if __FreeBSD_version > 900030 + return pthread_getthreadid_np(); +# else + long lwpid; + thr_self(&lwpid); + return lwpid; +# endif #else return reinterpret_cast(pthread_self()); #endif @@ -172,7 +197,7 @@ ThreadPosix::~ThreadPosix() { delete crit_state_; } -#define HAS_THREAD_ID !defined(WEBRTC_IOS) && !defined(WEBRTC_MAC) +#define HAS_THREAD_ID !defined(WEBRTC_IOS) && !defined(WEBRTC_MAC) && !defined(WEBRTC_BSD) bool ThreadPosix::Start(unsigned int& thread_id) { @@ -237,13 +262,17 @@ bool ThreadPosix::Start(unsigned int& thread_id) // CPU_ZERO and CPU_SET are not available in NDK r7, so disable // SetAffinity on Android for now. -#if (defined(WEBRTC_LINUX) && (!defined(WEBRTC_ANDROID)) && (!defined(WEBRTC_GONK))) +#if defined(__FreeBSD__) || (defined(WEBRTC_LINUX) && (!defined(WEBRTC_ANDROID)) && (!defined(WEBRTC_GONK))) bool ThreadPosix::SetAffinity(const int* processor_numbers, const unsigned int amount_of_processors) { if (!processor_numbers || (amount_of_processors == 0)) { return false; } +#if defined(__FreeBSD__) + cpuset_t mask; +#else cpu_set_t mask; +#endif CPU_ZERO(&mask); for (unsigned int processor = 0; @@ -251,7 +280,11 @@ bool ThreadPosix::SetAffinity(const int* processor_numbers, ++processor) { CPU_SET(processor_numbers[processor], &mask); } -#if defined(WEBRTC_ANDROID) || defined(WEBRTC_GONK) +#if defined(__FreeBSD__) + const int result = pthread_setaffinity_np(thread_, + sizeof(mask), + &mask); +#elif defined(WEBRTC_ANDROID) || defined(WEBRTC_GONK) // Android. const int result = syscall(__NR_sched_setaffinity, pid_, @@ -325,6 +358,10 @@ void ThreadPosix::Run() { if (set_thread_name_) { #ifdef WEBRTC_LINUX prctl(PR_SET_NAME, (unsigned long)name_, 0, 0, 0); +#elif defined(__NetBSD__) + pthread_setname_np(pthread_self(), "%s", (void *)name_); +#elif defined(WEBRTC_BSD) + pthread_set_name_np(pthread_self(), name_); #endif WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1, "Thread with name:%s started ", name_); diff --git a/media/webrtc/trunk/webrtc/system_wrappers/source/trace_posix.cc b/media/webrtc/trunk/webrtc/system_wrappers/source/trace_posix.cc index 2c7e59a891d..6f23fcb3724 100644 --- a/media/webrtc/trunk/webrtc/system_wrappers/source/trace_posix.cc +++ b/media/webrtc/trunk/webrtc/system_wrappers/source/trace_posix.cc @@ -54,7 +54,7 @@ WebRtc_Word32 TracePosix::AddTime(char* trace_message, } struct tm buffer; const struct tm* system_time = - localtime_r(&system_time_high_res.tv_sec, &buffer); + localtime_r((const time_t *)(&system_time_high_res.tv_sec), &buffer); const WebRtc_UWord32 ms_time = system_time_high_res.tv_usec / 1000; WebRtc_UWord32 prev_tickCount = 0; From 33ab75941e8aa33bbc0eaa62b95e9e21ae0f58a0 Mon Sep 17 00:00:00 2001 From: Landry Breuil Date: Thu, 13 Jun 2013 08:54:44 +0200 Subject: [PATCH 17/20] Bug 807492 Part 10 - Add err.h and xlocale.h to system-headers for WebRTC on BSD r=ted --- config/system-headers | 2 ++ js/src/config/system-headers | 2 ++ 2 files changed, 4 insertions(+) diff --git a/config/system-headers b/config/system-headers index 7cf7c67e1f5..1035130f6a7 100644 --- a/config/system-headers +++ b/config/system-headers @@ -1128,3 +1128,5 @@ sys/thr.h sys/user.h kvm.h spawn.h +err.h +xlocale.h diff --git a/js/src/config/system-headers b/js/src/config/system-headers index 7cf7c67e1f5..1035130f6a7 100644 --- a/js/src/config/system-headers +++ b/js/src/config/system-headers @@ -1128,3 +1128,5 @@ sys/thr.h sys/user.h kvm.h spawn.h +err.h +xlocale.h From 065d62f295bd14987d687f9ed6d0c864c08c20c6 Mon Sep 17 00:00:00 2001 From: Landry Breuil Date: Thu, 13 Jun 2013 08:54:56 +0200 Subject: [PATCH 18/20] Bug 807492 Part 11 - Support WebRTC on BSD in network modules rtp/udp r=jesup --- .../source/forward_error_correction.cc | 1 + .../modules/rtp_rtcp/source/rtp_utility.cc | 10 +++++----- .../source/udp_transport_impl.cc | 20 ++++++++++--------- .../modules/utility/source/rtp_dump_impl.cc | 4 ++-- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc index bdad224ee5f..39e113281c9 100644 --- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc +++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc @@ -12,6 +12,7 @@ #include #include +#include // for abs() #include #include diff --git a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_utility.cc b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_utility.cc index efc985cd160..d1d81a76ec4 100644 --- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_utility.cc +++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_utility.cc @@ -18,7 +18,7 @@ #include // FILETIME #include // timeval #include // timeGetTime -#elif ((defined WEBRTC_LINUX) || (defined WEBRTC_MAC)) +#elif ((defined WEBRTC_LINUX) || (defined WEBRTC_BSD) || (defined WEBRTC_MAC)) #include // gettimeofday #include #endif @@ -156,7 +156,7 @@ void get_time(WindowsHelpTimer* help_timer, FILETIME& current_time) { WindowsHelpTimer* _helpTimer; }; -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || defined(WEBRTC_MAC) // A clock reading times from the POSIX API. class UnixSystemClock : public RtpRtcpClock { @@ -214,7 +214,7 @@ void WindowsSystemClock::CurrentNTP(WebRtc_UWord32& secs, frac = (WebRtc_UWord32)dtemp; } -#elif ((defined WEBRTC_LINUX) || (defined WEBRTC_MAC)) +#elif ((defined WEBRTC_LINUX) || (defined WEBRTC_BSD) || (defined WEBRTC_MAC)) WebRtc_Word64 UnixSystemClock::GetTimeInMS() { return TickTime::MillisecondTimestamp(); @@ -253,7 +253,7 @@ static WindowsHelpTimer global_help_timer = {0, 0, {{ 0, 0}, 0}, 0}; RtpRtcpClock* GetSystemClock() { #if defined(_WIN32) return new WindowsSystemClock(&global_help_timer); -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || defined(WEBRTC_MAC) return new UnixSystemClock(); #else return NULL; @@ -330,7 +330,7 @@ bool StringCompare(const char* str1, const char* str2, const WebRtc_UWord32 length) { return (_strnicmp(str1, str2, length) == 0) ? true : false; } -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || defined(WEBRTC_MAC) bool StringCompare(const char* str1, const char* str2, const WebRtc_UWord32 length) { return (strncasecmp(str1, str2, length) == 0) ? true : false; diff --git a/media/webrtc/trunk/webrtc/modules/udp_transport/source/udp_transport_impl.cc b/media/webrtc/trunk/webrtc/modules/udp_transport/source/udp_transport_impl.cc index b4c927947f9..183e9646b9f 100644 --- a/media/webrtc/trunk/webrtc/modules/udp_transport/source/udp_transport_impl.cc +++ b/media/webrtc/trunk/webrtc/modules/udp_transport/source/udp_transport_impl.cc @@ -18,16 +18,16 @@ #if defined(_WIN32) #include #include -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || defined(WEBRTC_MAC) #include #include #include #include +#include #include #include #include #include -#include #include #include #ifndef WEBRTC_IOS @@ -36,9 +36,11 @@ #endif // defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) #if defined(WEBRTC_MAC) -#include #include #endif +#if defined(WEBRTC_BSD) || defined(WEBRTC_MAC) +#include +#endif #if defined(WEBRTC_LINUX) #include #include @@ -51,7 +53,7 @@ #include "typedefs.h" #include "udp_socket_manager_wrapper.h" -#if defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) +#if defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || defined(WEBRTC_MAC) #define GetLastError() errno #define IFRSIZE ((int)(size * sizeof (struct ifreq))) @@ -61,7 +63,7 @@ (int)(nlh)->nlmsg_len >= (int)sizeof(struct nlmsghdr) && \ (int)(nlh)->nlmsg_len <= (len)) -#endif // defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) +#endif // defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || defined(WEBRTC_MAC) namespace webrtc { @@ -2371,7 +2373,7 @@ WebRtc_Word32 UdpTransport::InetPresentationToNumeric(WebRtc_Word32 af, const char* src, void* dst) { -#if defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) +#if defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || defined(WEBRTC_MAC) const WebRtc_Word32 result = inet_pton(af, src, dst); return result > 0 ? 0 : -1; @@ -2493,7 +2495,7 @@ WebRtc_Word32 UdpTransport::LocalHostAddressIPV6(char n_localIP[16]) "getaddrinfo failed to find address"); return -1; -#elif defined(WEBRTC_MAC) +#elif defined(WEBRTC_BSD) || defined(WEBRTC_MAC) struct ifaddrs* ptrIfAddrs = NULL; struct ifaddrs* ptrIfAddrsStart = NULL; @@ -2685,7 +2687,7 @@ WebRtc_Word32 UdpTransport::LocalHostAddress(WebRtc_UWord32& localIP) "gethostbyname failed, error:%d", error); return -1; } -#elif (defined(WEBRTC_MAC)) +#elif (defined(WEBRTC_BSD) || defined(WEBRTC_MAC)) char localname[255]; if (gethostname(localname, 255) != -1) { @@ -2824,7 +2826,7 @@ WebRtc_Word32 UdpTransport::IPAddress(const SocketAddress& address, sourcePort = htons(source_port); return 0; - #elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) + #elif defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || defined(WEBRTC_MAC) WebRtc_Word32 ipFamily = address._sockaddr_storage.sin_family; const void* ptrNumericIP = NULL; diff --git a/media/webrtc/trunk/webrtc/modules/utility/source/rtp_dump_impl.cc b/media/webrtc/trunk/webrtc/modules/utility/source/rtp_dump_impl.cc index 69a52ecc578..7ac226c7035 100644 --- a/media/webrtc/trunk/webrtc/modules/utility/source/rtp_dump_impl.cc +++ b/media/webrtc/trunk/webrtc/modules/utility/source/rtp_dump_impl.cc @@ -19,7 +19,7 @@ #if defined(_WIN32) #include #include -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || defined(WEBRTC_MAC) #include #include #include @@ -238,7 +238,7 @@ inline WebRtc_UWord32 RtpDumpImpl::GetTimeInMS() const { #if defined(_WIN32) return timeGetTime(); -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) +#elif defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) || defined(WEBRTC_MAC) struct timeval tv; struct timezone tz; unsigned long val; From 35dc379fd805d3fc1a7d694fbc3e1ca69633a7c5 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Thu, 13 Jun 2013 00:47:26 -0700 Subject: [PATCH 19/20] Bug 600207 (Part 1) - Avoid fuzzy SVGs on the tiling path by matrix twiddling. r=dholbert --- image/src/VectorImage.cpp | 45 ++++++++++++++----- .../backgrounds/vector/empty/reftest.list | 15 ++----- .../reftests/backgrounds/vector/reftest.list | 10 +---- layout/reftests/svg/as-image/reftest.list | 2 +- layout/svg/nsSVGImageFrame.cpp | 15 ++++--- 5 files changed, 48 insertions(+), 39 deletions(-) diff --git a/image/src/VectorImage.cpp b/image/src/VectorImage.cpp index 26c60135ad4..46849453a55 100644 --- a/image/src/VectorImage.cpp +++ b/image/src/VectorImage.cpp @@ -690,29 +690,50 @@ VectorImage::Draw(gfxContext* aContext, AutoSVGRenderingState autoSVGState(aSVGContext, time, mSVGDocumentWrapper->GetRootSVGElem()); - mSVGDocumentWrapper->UpdateViewportBounds(aViewportSize); + + // gfxUtils::DrawPixelSnapped may rasterize this image to a temporary surface + // if we hit the tiling path. Unfortunately, the temporary surface isn't + // created at the size at which we'll ultimately draw, causing fuzzy output. + // To fix this we pre-apply the transform's scaling to the drawing parameters + // and then remove the scaling from the transform, so the fact that temporary + // surfaces won't take the scaling into account doesn't matter. (Bug 600207.) + gfxSize scale(aUserSpaceToImageSpace.ScaleFactors(true)); + gfxPoint translation(aUserSpaceToImageSpace.GetTranslation()); + + // Rescale everything. + nsIntSize scaledViewport(aViewportSize.width / scale.width, + aViewportSize.height / scale.height); + gfxIntSize scaledViewportGfx(scaledViewport.width, scaledViewport.height); + nsIntRect scaledSubimage(aSubimage); + scaledSubimage.ScaleRoundOut(1.0 / scale.width, 1.0 / scale.height); + + // Remove the scaling from the transform. + gfxMatrix unscale; + unscale.Translate(gfxPoint(translation.x / scale.width, + translation.y / scale.height)); + unscale.Scale(1.0 / scale.width, 1.0 / scale.height); + unscale.Translate(-translation); + gfxMatrix unscaledTransform(aUserSpaceToImageSpace * unscale); + + mSVGDocumentWrapper->UpdateViewportBounds(scaledViewport); mSVGDocumentWrapper->FlushImageTransformInvalidation(); - // XXXdholbert Do we need to convert image size from - // CSS pixels to dev pixels here? (is gfxCallbackDrawable's 2nd arg in dev - // pixels?) - gfxIntSize imageSizeGfx(aViewportSize.width, aViewportSize.height); - // Based on imgFrame::Draw - gfxRect sourceRect = aUserSpaceToImageSpace.Transform(aFill); - gfxRect imageRect(0, 0, aViewportSize.width, aViewportSize.height); - gfxRect subimage(aSubimage.x, aSubimage.y, aSubimage.width, aSubimage.height); + gfxRect sourceRect = unscaledTransform.Transform(aFill); + gfxRect imageRect(0, 0, scaledViewport.width, scaledViewport.height); + gfxRect subimage(scaledSubimage.x, scaledSubimage.y, + scaledSubimage.width, scaledSubimage.height); nsRefPtr cb = new SVGDrawingCallback(mSVGDocumentWrapper, - nsIntRect(nsIntPoint(0, 0), aViewportSize), + nsIntRect(nsIntPoint(0, 0), scaledViewport), aFlags); - nsRefPtr drawable = new gfxCallbackDrawable(cb, imageSizeGfx); + nsRefPtr drawable = new gfxCallbackDrawable(cb, scaledViewportGfx); gfxUtils::DrawPixelSnapped(aContext, drawable, - aUserSpaceToImageSpace, + unscaledTransform, subimage, sourceRect, imageRect, aFill, gfxASurface::ImageFormatARGB32, aFilter, aFlags); diff --git a/layout/reftests/backgrounds/vector/empty/reftest.list b/layout/reftests/backgrounds/vector/empty/reftest.list index a7be83c9905..1a7af876cdc 100644 --- a/layout/reftests/backgrounds/vector/empty/reftest.list +++ b/layout/reftests/backgrounds/vector/empty/reftest.list @@ -2,17 +2,10 @@ == tall--contain--width.html ref-tall-empty.html == wide--contain--height.html ref-wide-empty.html == wide--contain--width.html ref-wide-empty.html - -# We don't really care about the failures for this -# extreme edge case (the test exists more to test for safety against division by -# zero), so there is no bug has been filed to fix it, although a patch would -# probably be accepted. -# They're still marked as failing though, rather than 'load', since -# we want to know if they start working when we upgrade to Azure. -fails == tall--cover--height.html ref-tall-lime.html -fails == tall--cover--width.html ref-tall-lime.html -fails == wide--cover--height.html ref-wide-lime.html -fails == wide--cover--width.html ref-wide-lime.html +== tall--cover--height.html ref-tall-lime.html +== tall--cover--width.html ref-tall-lime.html +== wide--cover--height.html ref-wide-lime.html +== wide--cover--width.html ref-wide-lime.html == zero-height-ratio-contain.html ref-tall-empty.html == zero-height-ratio-cover.html ref-tall-empty.html diff --git a/layout/reftests/backgrounds/vector/reftest.list b/layout/reftests/backgrounds/vector/reftest.list index 3ace266a19f..2e538ab1653 100644 --- a/layout/reftests/backgrounds/vector/reftest.list +++ b/layout/reftests/backgrounds/vector/reftest.list @@ -84,16 +84,10 @@ skip-if(B2G) == tall--contain--nonpercent-width-omitted-height-viewbox.html ref- == tall--contain--percent-width-omitted-height-viewbox.html ref-tall-lime48x384-aqua48x384.html == tall--contain--percent-width-percent-height.html ref-tall-lime256x384-aqua256x384.html == tall--contain--percent-width-percent-height-viewbox.html ref-tall-lime48x384-aqua48x384.html - -# We smear the background image when scaling it in these two tests... -# Android uses FILTER_NEAREST for background images so the smear doesn't occur -fails-if(!(Android||B2G)) == tall--cover--nonpercent-width-nonpercent-height.html ref-tall-lime256x512-aqua256x256.html -fails-if(!(Android||B2G)) == tall--cover--nonpercent-width-nonpercent-height-viewbox.html ref-tall-lime256x512-aqua256x256.html - -# ...but we don't in identical tests with image-rendering: -moz-crisp-edges. +== tall--cover--nonpercent-width-nonpercent-height.html ref-tall-lime256x512-aqua256x256.html +== tall--cover--nonpercent-width-nonpercent-height-viewbox.html ref-tall-lime256x512-aqua256x256.html == tall--cover--nonpercent-width-nonpercent-height--crisp.html ref-tall-lime256x512-aqua256x256.html == tall--cover--nonpercent-width-nonpercent-height-viewbox--crisp.html ref-tall-lime256x512-aqua256x256.html - == tall--cover--nonpercent-width-omitted-height.html ref-tall-lime256x384-aqua256x384.html == tall--cover--nonpercent-width-omitted-height-viewbox.html ref-tall-lime256x768.html == tall--cover--nonpercent-width-percent-height.html ref-tall-lime256x384-aqua256x384.html diff --git a/layout/reftests/svg/as-image/reftest.list b/layout/reftests/svg/as-image/reftest.list index 229396ddc55..6ebd927f4bb 100644 --- a/layout/reftests/svg/as-image/reftest.list +++ b/layout/reftests/svg/as-image/reftest.list @@ -154,4 +154,4 @@ HTTP == svg-stylesheet-external-1.html blue100x100.svg # XXXseth: The underlying problems also apply to media fragments, # but the test case would be much simpler. This should be switched # over to use media fragments once bug 790640 lands. -skip-if(B2G) == svg-border-image-repaint-1.html svg-border-image-repaint-1-ref.html +skip-if(B2G) fuzzy(2,1) == svg-border-image-repaint-1.html svg-border-image-repaint-1-ref.html diff --git a/layout/svg/nsSVGImageFrame.cpp b/layout/svg/nsSVGImageFrame.cpp index 01d0bce01e5..3f3721604ed 100644 --- a/layout/svg/nsSVGImageFrame.cpp +++ b/layout/svg/nsSVGImageFrame.cpp @@ -248,19 +248,20 @@ nsSVGImageFrame::TransformContextForPainting(gfxContext* aGfxContext) } imageTransform = GetRasterImageTransform(nativeWidth, nativeHeight, FOR_PAINTING); + + // NOTE: We need to cancel out the effects of Full-Page-Zoom, or else + // it'll get applied an extra time by DrawSingleUnscaledImage. + nscoord appUnitsPerDevPx = PresContext()->AppUnitsPerDevPixel(); + gfxFloat pageZoomFactor = + nsPresContext::AppUnitsToFloatCSSPixels(appUnitsPerDevPx); + imageTransform.Scale(pageZoomFactor, pageZoomFactor); } if (imageTransform.IsSingular()) { return false; } - // NOTE: We need to cancel out the effects of Full-Page-Zoom, or else - // it'll get applied an extra time by DrawSingleUnscaledImage. - nscoord appUnitsPerDevPx = PresContext()->AppUnitsPerDevPixel(); - gfxFloat pageZoomFactor = - nsPresContext::AppUnitsToFloatCSSPixels(appUnitsPerDevPx); - aGfxContext->Multiply(imageTransform.Scale(pageZoomFactor, pageZoomFactor)); - + aGfxContext->Multiply(imageTransform); return true; } From f91fd6f29e3511c60c6dd01583b28a54da5808fc Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Thu, 13 Jun 2013 00:47:30 -0700 Subject: [PATCH 20/20] Bug 600207 (Part 2) - Tests for SVG image scaling in the presence of page zoom. r=dholbert --- .../svg/as-image/zoom/circle-large.svg | 3 ++ .../svg/as-image/zoom/circle-small.svg | 3 ++ .../zoom/img-fuzzy-transform-zoomIn-1.html | 29 +++++++++++++++++++ .../zoom/img-fuzzy-transform-zoomOut-1.html | 29 +++++++++++++++++++ .../as-image/zoom/img-fuzzy-zoomIn-1-ref.html | 27 +++++++++++++++++ .../svg/as-image/zoom/img-fuzzy-zoomIn-1.html | 27 +++++++++++++++++ .../zoom/img-fuzzy-zoomOut-1-ref.html | 27 +++++++++++++++++ .../as-image/zoom/img-fuzzy-zoomOut-1.html | 27 +++++++++++++++++ .../reftests/svg/as-image/zoom/reftest.list | 6 ++++ 9 files changed, 178 insertions(+) create mode 100644 layout/reftests/svg/as-image/zoom/circle-large.svg create mode 100644 layout/reftests/svg/as-image/zoom/circle-small.svg create mode 100644 layout/reftests/svg/as-image/zoom/img-fuzzy-transform-zoomIn-1.html create mode 100644 layout/reftests/svg/as-image/zoom/img-fuzzy-transform-zoomOut-1.html create mode 100644 layout/reftests/svg/as-image/zoom/img-fuzzy-zoomIn-1-ref.html create mode 100644 layout/reftests/svg/as-image/zoom/img-fuzzy-zoomIn-1.html create mode 100644 layout/reftests/svg/as-image/zoom/img-fuzzy-zoomOut-1-ref.html create mode 100644 layout/reftests/svg/as-image/zoom/img-fuzzy-zoomOut-1.html diff --git a/layout/reftests/svg/as-image/zoom/circle-large.svg b/layout/reftests/svg/as-image/zoom/circle-large.svg new file mode 100644 index 00000000000..a097f3c666b --- /dev/null +++ b/layout/reftests/svg/as-image/zoom/circle-large.svg @@ -0,0 +1,3 @@ + + + diff --git a/layout/reftests/svg/as-image/zoom/circle-small.svg b/layout/reftests/svg/as-image/zoom/circle-small.svg new file mode 100644 index 00000000000..b0cba24a65d --- /dev/null +++ b/layout/reftests/svg/as-image/zoom/circle-small.svg @@ -0,0 +1,3 @@ + + + diff --git a/layout/reftests/svg/as-image/zoom/img-fuzzy-transform-zoomIn-1.html b/layout/reftests/svg/as-image/zoom/img-fuzzy-transform-zoomIn-1.html new file mode 100644 index 00000000000..b4eadba92e0 --- /dev/null +++ b/layout/reftests/svg/as-image/zoom/img-fuzzy-transform-zoomIn-1.html @@ -0,0 +1,29 @@ + + + + + + + +
+ + diff --git a/layout/reftests/svg/as-image/zoom/img-fuzzy-transform-zoomOut-1.html b/layout/reftests/svg/as-image/zoom/img-fuzzy-transform-zoomOut-1.html new file mode 100644 index 00000000000..db0e6c06b9a --- /dev/null +++ b/layout/reftests/svg/as-image/zoom/img-fuzzy-transform-zoomOut-1.html @@ -0,0 +1,29 @@ + + + + + + + +
+ + diff --git a/layout/reftests/svg/as-image/zoom/img-fuzzy-zoomIn-1-ref.html b/layout/reftests/svg/as-image/zoom/img-fuzzy-zoomIn-1-ref.html new file mode 100644 index 00000000000..81e6011e629 --- /dev/null +++ b/layout/reftests/svg/as-image/zoom/img-fuzzy-zoomIn-1-ref.html @@ -0,0 +1,27 @@ + + + + + + + +
+ + diff --git a/layout/reftests/svg/as-image/zoom/img-fuzzy-zoomIn-1.html b/layout/reftests/svg/as-image/zoom/img-fuzzy-zoomIn-1.html new file mode 100644 index 00000000000..de39990b954 --- /dev/null +++ b/layout/reftests/svg/as-image/zoom/img-fuzzy-zoomIn-1.html @@ -0,0 +1,27 @@ + + + + + + + +
+ + diff --git a/layout/reftests/svg/as-image/zoom/img-fuzzy-zoomOut-1-ref.html b/layout/reftests/svg/as-image/zoom/img-fuzzy-zoomOut-1-ref.html new file mode 100644 index 00000000000..48f2d05ff7e --- /dev/null +++ b/layout/reftests/svg/as-image/zoom/img-fuzzy-zoomOut-1-ref.html @@ -0,0 +1,27 @@ + + + + + + + +
+ + diff --git a/layout/reftests/svg/as-image/zoom/img-fuzzy-zoomOut-1.html b/layout/reftests/svg/as-image/zoom/img-fuzzy-zoomOut-1.html new file mode 100644 index 00000000000..75cd1d61af4 --- /dev/null +++ b/layout/reftests/svg/as-image/zoom/img-fuzzy-zoomOut-1.html @@ -0,0 +1,27 @@ + + + + + + + +
+ + diff --git a/layout/reftests/svg/as-image/zoom/reftest.list b/layout/reftests/svg/as-image/zoom/reftest.list index 3c11dfa8f7a..035d39c51c0 100644 --- a/layout/reftests/svg/as-image/zoom/reftest.list +++ b/layout/reftests/svg/as-image/zoom/reftest.list @@ -4,3 +4,9 @@ == img-zoomIn-1.html squaredCircle-150x150-ref.html == img-zoomOut-1.html squaredCircle-50x50-ref.html + +# Ensure that scaled SVG images aren't fuzzy when tiled. +== img-fuzzy-zoomOut-1.html img-fuzzy-zoomOut-1-ref.html +== img-fuzzy-zoomIn-1.html img-fuzzy-zoomIn-1-ref.html +== img-fuzzy-transform-zoomOut-1.html img-fuzzy-zoomOut-1-ref.html +== img-fuzzy-transform-zoomIn-1.html img-fuzzy-zoomIn-1-ref.html