Merge latest green inbound changeset and mozilla-central

This commit is contained in:
Ed Morley 2013-10-14 17:39:02 +01:00
commit d9879cd4ec
47 changed files with 791 additions and 387 deletions

View File

@ -1,4 +1,4 @@
{
"revision": "47d1ef9819810cecf9ce8cdcfd7f211530e43668",
"revision": "4cdfe9307db3882da00e49361aa2f6788c9efe54",
"repo_path": "/integration/gaia-central"
}

View File

@ -24,9 +24,17 @@ let WebrtcIndicator = {
fillPopup: function (aPopup) {
this._menuitemData = new WeakMap;
for (let streamData of this.UIModule.activeStreams) {
let pageURI = Services.io.newURI(streamData.uri, null, null);
let menuitem = document.createElement("menuitem");
menuitem.setAttribute("label", streamData.uri);
menuitem.setAttribute("class", "menuitem-iconic");
menuitem.setAttribute("label", streamData.browser.contentTitle || streamData.uri);
menuitem.setAttribute("tooltiptext", streamData.uri);
PlacesUtils.favicons.getFaviconURLForPage(pageURI, function (aURI) {
if (aURI) {
let iconURL = PlacesUtils.favicons.getFaviconLinkForIcon(aURI).spec;
menuitem.setAttribute("image", iconURL);
}
});
this._menuitemData.set(menuitem, streamData);

View File

@ -94,6 +94,7 @@ function cleanup() {
Services.obs.removeObserver(obs_DESTROYING, DESTROYING);
Services.obs.removeObserver(obs_BEFORE_DESTROYED, BEFORE_DESTROYED);
Services.obs.removeObserver(obs_DESTROYED, DESTROYED);
Services.obs.removeObserver(obs_STARTUP, STARTUP);
gBrowser.removeCurrentTab();
finish();

View File

@ -118,6 +118,7 @@ function cleanup() {
Services.obs.removeObserver(tab_DESTROYING, DESTROYING);
Services.obs.removeObserver(tab_SHOWN, SHOWN);
Services.obs.removeObserver(tab_HIDDEN, HIDDEN);
Services.obs.removeObserver(tab_STARTUP, STARTUP);
gBrowser.tabContainer.removeEventListener("TabSelect", tabSelect);
gBrowser.removeCurrentTab();

View File

@ -282,13 +282,6 @@ public:
uint16_t ReadyState();
// request
void Open(const nsACString& aMethod, const nsAString& aUrl, ErrorResult& aRv)
{
Open(aMethod, aUrl, true,
mozilla::dom::Optional<nsAString>(),
mozilla::dom::Optional<nsAString>(),
aRv);
}
void Open(const nsACString& aMethod, const nsAString& aUrl, bool aAsync,
const mozilla::dom::Optional<nsAString>& aUser,
const mozilla::dom::Optional<nsAString>& aPassword,

View File

@ -27,15 +27,11 @@ function checkDoc(title, expectedtitle, normalizedtitle) {
is(doc.doctype.internalSubset, null, "internalSubset should be null!");
isElement(doc.documentElement, "html");
isElement(doc.documentElement.firstChild, "head");
if (title !== undefined) {
is(doc.documentElement.firstChild.childNodes.length, 1);
isElement(doc.documentElement.firstChild.firstChild, "title");
// Doesn't always work out in WebKit.
ok(doc.documentElement.firstChild.firstChild.firstChild, "Need a text node.");
is(doc.documentElement.firstChild.firstChild.firstChild.data, expectedtitle);
} else {
is(doc.documentElement.firstChild.childNodes.length, 0);
}
is(doc.documentElement.firstChild.childNodes.length, 1);
isElement(doc.documentElement.firstChild.firstChild, "title");
// Doesn't always work out in WebKit.
ok(doc.documentElement.firstChild.firstChild.firstChild, "Need a text node.");
is(doc.documentElement.firstChild.firstChild.firstChild.data, expectedtitle);
isElement(doc.documentElement.lastChild, "body");
is(doc.documentElement.lastChild.childNodes.length, 0);
((!title || title.indexOf("\f") === -1) ? is : todo_is)
@ -45,7 +41,7 @@ function checkDoc(title, expectedtitle, normalizedtitle) {
}
checkDoc("", "", "");
checkDoc(null, "null", "null");
checkDoc(undefined, "", "");
checkDoc(undefined, "undefined", "undefined");
checkDoc("foo bar baz", "foo bar baz", "foo bar baz");
checkDoc("foo\t\tbar baz", "foo\t\tbar baz", "foo bar baz");
checkDoc("foo\n\nbar baz", "foo\n\nbar baz", "foo bar baz");

View File

@ -447,6 +447,8 @@ public:
virtual bool IsDormantNeeded() { return false; }
// Release media resources they should be released in dormant state
virtual void ReleaseMediaResources() {};
// Release the decoder during shutdown
virtual void ReleaseDecoder() {};
// Resets all state related to decoding, emptying all buffers etc.
virtual nsresult ResetDecode();

View File

@ -320,7 +320,13 @@ public:
void SetFragmentEndTime(int64_t aEndTime);
// Drop reference to decoder. Only called during shutdown dance.
void ReleaseDecoder() { mDecoder = nullptr; }
void ReleaseDecoder() {
MOZ_ASSERT(mReader);
if (mReader) {
mReader->ReleaseDecoder();
}
mDecoder = nullptr;
}
// Called when a "MozAudioAvailable" event listener is added to the media
// element. Called on the main thread.

View File

@ -69,6 +69,13 @@ void MediaOmxReader::ReleaseMediaResources()
}
}
void MediaOmxReader::ReleaseDecoder()
{
if (mOmxDecoder.get()) {
mOmxDecoder->ReleaseDecoder();
}
}
nsresult MediaOmxReader::ReadMetadata(MediaInfo* aInfo,
MetadataTags** aTags)
{

View File

@ -62,6 +62,8 @@ public:
virtual bool IsDormantNeeded();
virtual void ReleaseMediaResources();
virtual void ReleaseDecoder() MOZ_OVERRIDE;
virtual nsresult ReadMetadata(MediaInfo* aInfo,
MetadataTags** aTags);
virtual nsresult Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime);

View File

@ -62,8 +62,8 @@ private:
};
// When loading an MP3 stream from a file, we need to parse the file's
// content to find its duration. Reading files of 100 Mib or more can
// delay the player app noticably, so the file os read and decoded in
// content to find its duration. Reading files of 100 MiB or more can
// delay the player app noticably, so the file is read and decoded in
// smaller chunks.
//
// We first read on the decode thread, but parsing must be done on the
@ -79,7 +79,9 @@ private:
class OmxDecoderNotifyDataArrivedRunnable : public nsRunnable
{
public:
OmxDecoderNotifyDataArrivedRunnable(android::OmxDecoder* aOmxDecoder, const char* aBuffer, uint64_t aLength, int64_t aOffset, uint64_t aFullLength)
OmxDecoderNotifyDataArrivedRunnable(android::OmxDecoder* aOmxDecoder,
const char* aBuffer, uint64_t aLength,
int64_t aOffset, uint64_t aFullLength)
: mOmxDecoder(aOmxDecoder),
mBuffer(aBuffer),
mLength(aLength),
@ -96,24 +98,7 @@ public:
{
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
const char* buffer = mBuffer.get();
while (mLength) {
uint32_t length = std::min<uint64_t>(mLength, UINT32_MAX);
mOmxDecoder->NotifyDataArrived(mBuffer.get(), mLength, mOffset);
buffer += length;
mLength -= length;
mOffset += length;
}
if (mOffset < mFullLength) {
// We cannot read data in the main thread because it
// might block for too long. Instead we post an IO task
// to the IO thread if there is more data available.
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new OmxDecoderProcessCachedDataTask(mOmxDecoder.get(), mOffset));
}
NotifyDataArrived();
Completed();
return NS_OK;
@ -130,6 +115,32 @@ public:
}
private:
void NotifyDataArrived()
{
const char* buffer = mBuffer.get();
while (mLength) {
uint32_t length = std::min<uint64_t>(mLength, UINT32_MAX);
bool success = mOmxDecoder->NotifyDataArrived(buffer, mLength,
mOffset);
if (!success) {
return;
}
buffer += length;
mLength -= length;
mOffset += length;
}
if (mOffset < mFullLength) {
// We cannot read data in the main thread because it
// might block for too long. Instead we post an IO task
// to the IO thread if there is more data available.
XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
new OmxDecoderProcessCachedDataTask(mOmxDecoder.get(), mOffset));
}
}
// Call this function at the end of Run() to notify waiting
// threads.
void Completed()
@ -400,7 +411,7 @@ bool OmxDecoder::TryLoad() {
const char* audioMime;
sp<MetaData> meta = mAudioTrack->getFormat();
if (meta->findCString(kKeyMIMEType, &audioMime) && !strcasecmp(audioMime, AUDIO_MP3)) {
if (mIsMp3) {
// Feed MP3 parser with cached data. Local files will be fully
// cached already, network streams will update with sucessive
// calls to NotifyDataArrived.
@ -628,10 +639,15 @@ bool OmxDecoder::SetAudioFormat() {
return true;
}
void OmxDecoder::NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset)
void OmxDecoder::ReleaseDecoder()
{
if (!mAudioTrack.get() || !mIsMp3 || !mMP3FrameParser.IsMP3()) {
return;
mDecoder = nullptr;
}
bool OmxDecoder::NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset)
{
if (!mAudioTrack.get() || !mIsMp3 || !mMP3FrameParser.IsMP3() || !mDecoder) {
return false;
}
mMP3FrameParser.Parse(aBuffer, aLength, aOffset);
@ -645,6 +661,8 @@ void OmxDecoder::NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
mDecoder->UpdateEstimatedMediaDuration(mDurationUs);
}
return true;
}
void OmxDecoder::ReleaseVideoBuffer() {

View File

@ -181,7 +181,9 @@ public:
bool SetVideoFormat();
bool SetAudioFormat();
void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset);
void ReleaseDecoder();
bool NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset);
void GetDuration(int64_t *durationUs) {
*durationUs = mDurationUs;

View File

@ -998,34 +998,8 @@ nsXBLPrototypeBinding::Read(nsIObjectInputStream* aStream,
previousHandler = handler;
} while (1);
if (mBinding) {
while (true) {
XBLBindingSerializeDetails type;
rv = aStream->Read8(&type);
NS_ENSURE_SUCCESS(rv, rv);
if (type != XBLBinding_Serialize_Attribute) {
break;
}
int32_t attrNamespace;
rv = ReadNamespace(aStream, attrNamespace);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString attrName, attrValue;
rv = aStream->ReadString(attrName);
NS_ENSURE_SUCCESS(rv, rv);
rv = aStream->ReadString(attrValue);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIAtom> atomName = do_GetAtom(attrName);
mBinding->SetAttr(attrNamespace, atomName, attrValue, false);
}
}
// Finally, read in the resources.
while (true) {
do {
XBLBindingSerializeDetails type;
rv = aStream->Read8(&type);
NS_ENSURE_SUCCESS(rv, rv);
@ -1042,7 +1016,7 @@ nsXBLPrototypeBinding::Read(nsIObjectInputStream* aStream,
AddResource(type == XBLBinding_Serialize_Stylesheet ? nsGkAtoms::stylesheet :
nsGkAtoms::image, src);
}
} while (1);
if (isFirstBinding) {
aDocInfo->SetFirstPrototypeBinding(this);
@ -1152,30 +1126,6 @@ nsXBLPrototypeBinding::Write(nsIObjectOutputStream* aStream)
aStream->Write8(XBLBinding_Serialize_NoMoreItems);
NS_ENSURE_SUCCESS(rv, rv);
if (mBinding) {
uint32_t attributes = mBinding->GetAttrCount();
nsAutoString attrValue;
for (uint32_t i = 0; i < attributes; ++i) {
const nsAttrName* attr = mBinding->GetAttrNameAt(i);
nsDependentAtomString attrName = attr->Atom();
mBinding->GetAttr(attr->NamespaceID(), attr->Atom(), attrValue);
rv = aStream->Write8(XBLBinding_Serialize_Attribute);
NS_ENSURE_SUCCESS(rv, rv);
rv = WriteNamespace(aStream, attr->NamespaceID());
NS_ENSURE_SUCCESS(rv, rv);
rv = aStream->WriteWStringZ(attrName.get());
NS_ENSURE_SUCCESS(rv, rv);
rv = aStream->WriteWStringZ(attrValue.get());
NS_ENSURE_SUCCESS(rv, rv);
}
}
aStream->Write8(XBLBinding_Serialize_NoMoreItems);
NS_ENSURE_SUCCESS(rv, rv);
// Write out the resources
if (mResources) {
rv = mResources->Write(aStream);

View File

@ -15,7 +15,7 @@ typedef uint8_t XBLBindingSerializeDetails;
// A version number to ensure we don't load cached data in a different
// file format.
#define XBLBinding_Serialize_Version 0x00000003
#define XBLBinding_Serialize_Version 0x00000002
// Set for the first binding in a document
#define XBLBinding_Serialize_IsFirstBinding 1
@ -45,7 +45,6 @@ typedef uint8_t XBLBindingSerializeDetails;
#define XBLBinding_Serialize_Handler 8
#define XBLBinding_Serialize_Image 9
#define XBLBinding_Serialize_Stylesheet 10
#define XBLBinding_Serialize_Attribute 0xA
#define XBLBinding_Serialize_Mask 0x0F
#define XBLBinding_Serialize_ReadOnly 0x80

View File

@ -703,8 +703,13 @@ AudioChannelService::Observe(nsISupports* aSubject, const char* aTopic, const PR
audioManager->SetAudioChannelVolume(AUDIO_CHANNEL_ALARM, index);
} else if (keyStr.EqualsLiteral("audio.volume.telephony")) {
audioManager->SetAudioChannelVolume(AUDIO_CHANNEL_TELEPHONY, index);
} else {
MOZ_ASSUME_UNREACHABLE("unexpected audio channel for volume control");
} else if (!keyStr.EqualsLiteral("audio.volume.bt_sco")) {
// bt_sco is not a valid audio channel so we manipulate it in
// AudioManager.cpp. And the others should not be used.
// We didn't use MOZ_ASSUME_UNREACHABLE here because any web content who
// has permission of mozSettings can set any names then it can be easy to
// crash the B2G.
NS_WARNING("unexpected audio channel for volume control");
}
}
#endif

View File

@ -2714,7 +2714,8 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
# A helper function for wrapping up the template body for
# possibly-nullable objecty stuff
def wrapObjectTemplate(templateBody, type, codeToSetNull, failureCode=None):
if isNullOrUndefined and type.nullable():
if isNullOrUndefined:
assert type.nullable()
# Just ignore templateBody and set ourselves to null.
# Note that we don't have to worry about default values
# here either, since we already examined this value.
@ -3331,6 +3332,9 @@ for (uint32_t i = 0; i < length; ++i) {
"Default": "eStringify",
"EmptyString": "eEmpty",
"Null": "eNull",
# For Missing it doesn't matter what we use here, since we'll never
# call ConvertJSValueToString on undefined in that case.
"Missing": "eStringify"
}
if type.nullable():
# For nullable strings null becomes a null string.
@ -3850,8 +3854,11 @@ class CGArgumentConverter(CGThing):
"args[${index}]"
).substitute(replacer)
self.replacementVariables["mutableVal"] = self.replacementVariables["val"]
haveValueCheck = string.Template(
"args.hasDefined(${index})").substitute(replacer)
if argument.treatUndefinedAs == "Missing":
haveValueCheck = "args.hasDefined(${index})"
else:
haveValueCheck = "${index} < args.length()"
haveValueCheck = string.Template(haveValueCheck).substitute(replacer)
self.replacementVariables["haveValue"] = haveValueCheck
self.descriptorProvider = descriptorProvider
if self.argument.optional and not self.argument.defaultValue:
@ -4992,6 +4999,15 @@ class CGMethodCall(CGThing):
CGWrapper(CGIndenter(CGGeneric(code)), pre="\n", post="\n"))
return
# We don't handle [TreatUndefinedAs=Missing] arguments in overload
# resolution yet.
for (_, sigArgs) in signatures:
for arg in sigArgs:
if arg.treatUndefinedAs == "Missing":
raise TypeError("No support for [TreatUndefinedAs=Missing] "
"handling in overload resolution yet: %s" %
arg.location)
# Need to find the right overload
maxArgCount = method.maxArgCount
allowedArgCounts = method.allowedArgCounts
@ -5081,30 +5097,22 @@ class CGMethodCall(CGThing):
else:
failureCode = None
type = distinguishingType(signature)
# The argument at index distinguishingIndex can't possibly be
# unset here, because we've already checked that argc is large
# enough that we can examine this argument. But note that we
# still want to claim that optional arguments are optional, in
# case undefined was passed in.
argIsOptional = (distinguishingArgument(signature).optional and
not distinguishingArgument(signature).defaultValue)
# The argument at index distinguishingIndex can't possibly
# be unset here, because we've already checked that argc is
# large enough that we can examine this argument.
testCode = instantiateJSToNativeConversion(
getJSToNativeConversionInfo(type, descriptor,
failureCode=failureCode,
isDefinitelyObject=isDefinitelyObject,
isNullOrUndefined=isNullOrUndefined,
isOptional=argIsOptional,
sourceDescription=(argDesc % (distinguishingIndex + 1))),
{
"declName" : "arg%d" % distinguishingIndex,
"holderName" : ("arg%d" % distinguishingIndex) + "_holder",
"val" : distinguishingArg,
"mutableVal" : distinguishingArg,
"obj" : "obj",
"haveValue": "args.hasDefined(%d)" % distinguishingIndex
},
checkForValue=argIsOptional
)
"obj" : "obj"
})
caseBody.append(CGIndenter(testCode, indent));
# If we got this far, we know we unwrapped to the right
# C++ type, so just do the call. Start conversion with
@ -5114,76 +5122,24 @@ class CGMethodCall(CGThing):
getPerSignatureCall(signature, distinguishingIndex + 1),
indent))
def hasConditionalConversion(type):
"""
Return whether the argument conversion for this type will be
conditional on the type of incoming JS value. For example, for
interface types the conversion is conditional on the incoming
value being isObject().
For the types for which this returns false, we do not have to
output extra isUndefined() or isNullOrUndefined() cases, because
null/undefined values will just fall through into our
unconditional conversion.
"""
if type.isString() or type.isEnum():
return False
if type.isBoolean():
distinguishingTypes = (distinguishingType(s) for s in
possibleSignatures)
return any(t.isString() or t.isEnum() or t.isNumeric()
for t in distinguishingTypes)
if type.isNumeric():
distinguishingTypes = (distinguishingType(s) for s in
possibleSignatures)
return any(t.isString() or t.isEnum()
for t in distinguishingTypes)
return True
def needsNullOrUndefinedCase(type):
"""
Return true if the type needs a special isNullOrUndefined() case
"""
return ((type.nullable() and
hasConditionalConversion(type)) or
type.isDictionary())
# First check for undefined and optional distinguishing arguments
# and output a special branch for that case. Note that we don't
# use distinguishingArgument here because we actualy want to
# exclude variadic arguments. Also note that we skip this check if
# we plan to output a isNullOrUndefined() special case for this
# argument anyway, since that will subsume our isUndefined() check.
# This is safe, because there can be at most one nullable
# distinguishing argument, so if we're it we'll definitely get
# picked up by the nullable handling. Also, we can skip this check
# if the argument has an unconditional conversion later on.
undefSigs = [s for s in possibleSignatures if
distinguishingIndex < len(s[1]) and
s[1][distinguishingIndex].optional and
hasConditionalConversion(s[1][distinguishingIndex].type) and
not needsNullOrUndefinedCase(s[1][distinguishingIndex].type)]
# Can't have multiple signatures with an optional argument at the
# same index.
assert len(undefSigs) < 2
if len(undefSigs) > 0:
caseBody.append(CGGeneric("if (%s.isUndefined()) {" %
distinguishingArg))
tryCall(undefSigs[0], 2, isNullOrUndefined=True)
caseBody.append(CGGeneric("}"))
# Next, check for null or undefined. That means looking for
# First check for null or undefined. That means looking for
# nullable arguments at the distinguishing index and outputting a
# separate branch for them. But if the nullable argument has an
# unconditional conversion, we don't need to do that. The reason
# separate branch for them. But if the nullable argument is a
# primitive, string, or enum, we don't need to do that. The reason
# for that is that at most one argument at the distinguishing index
# is nullable (since two nullable arguments are not
# distinguishable), and null/undefined values will always fall
# through to the unconditional conversion we have, if any, since
# they will fail whatever the conditions on the input value are for
# our other conversions.
# distinguishable), and all the argument types other than
# primitive/string/enum end up inside isObject() checks. So if our
# nullable is a primitive/string/enum it's safe to not output the
# extra branch: we'll fall through to conversion for those types,
# which correctly handles null as needed, because isObject() will be
# false for null and undefined.
nullOrUndefSigs = [s for s in possibleSignatures
if needsNullOrUndefinedCase(distinguishingType(s))]
if ((distinguishingType(s).nullable() and not
distinguishingType(s).isString() and not
distinguishingType(s).isEnum() and not
distinguishingType(s).isPrimitive()) or
distinguishingType(s).isDictionary())]
# Can't have multiple nullable types here
assert len(nullOrUndefSigs) < 2
if len(nullOrUndefSigs) > 0:

View File

@ -81,6 +81,11 @@ public:
return !Equals(aOtherNullable);
}
operator bool() const
{
return !mIsNull;
}
// Make it possible to use a const Nullable of an array type with other
// array types.
template<typename U>

View File

@ -401,7 +401,12 @@ class IDLObjectWithIdentifier(IDLObject):
if isDictionaryMember:
raise WebIDLError("[TreatUndefinedAs] is not allowed for "
"dictionary members", [self.location])
if value == 'Null':
if value == 'Missing':
if not isOptional:
raise WebIDLError("[TreatUndefinedAs=Missing] is only "
"allowed on optional arguments",
[self.location])
elif value == 'Null':
if not self.type.isDOMString():
raise WebIDLError("[TreatUndefinedAs=Null] is only "
"allowed on arguments or "
@ -421,8 +426,8 @@ class IDLObjectWithIdentifier(IDLObject):
[self.location])
else:
raise WebIDLError("[TreatUndefinedAs] must take the "
"identifiers EmptyString or Null",
[self.location])
"identifiers EmptyString or Null or "
"Missing", [self.location])
self.treatUndefinedAs = value
else:
unhandledAttrs.append(attr)
@ -3138,12 +3143,15 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
def finish(self, scope):
for overload in self._overloads:
inOptionalArguments = False
variadicArgument = None
arguments = overload.arguments
for (idx, argument) in enumerate(arguments):
if not argument.isComplete():
argument.complete(scope)
if argument.isComplete():
continue
argument.complete(scope)
assert argument.type.isComplete()
if (argument.type.isDictionary() or
@ -3153,7 +3161,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
# end of the list or followed by optional arguments must be
# optional.
if (not argument.optional and
all(arg.optional for arg in arguments[idx+1:])):
(idx == len(arguments) - 1 or arguments[idx+1].optional)):
raise WebIDLError("Dictionary argument or union "
"argument containing a dictionary "
"not followed by a required argument "
@ -3171,6 +3179,13 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
if variadicArgument:
raise WebIDLError("Variadic argument is not last argument",
[variadicArgument.location])
# Once we see an optional argument, there can't be any non-optional
# arguments.
if inOptionalArguments and not argument.optional:
raise WebIDLError("Non-optional argument after optional "
"arguments",
[argument.location])
inOptionalArguments = argument.optional
if argument.variadic:
variadicArgument = argument
@ -3215,7 +3230,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
return [overload for overload in self._overloads if
len(overload.arguments) == argc or
(len(overload.arguments) > argc and
all(arg.optional for arg in overload.arguments[argc:])) or
overload.arguments[argc].optional) or
(len(overload.arguments) < argc and
len(overload.arguments) > 0 and
overload.arguments[-1].variadic)]
@ -4045,6 +4060,21 @@ class Parser(Tokenizer):
raise WebIDLError("stringifier must have DOMString return type",
[self.getLocation(p, 2)])
inOptionalArguments = False
variadicArgument = False
for argument in arguments:
# Only the last argument can be variadic
if variadicArgument:
raise WebIDLError("Only the last argument can be variadic",
[variadicArgument.location])
# Once we see an optional argument, there can't be any non-optional
# arguments.
if inOptionalArguments and not argument.optional:
raise WebIDLError("Cannot have a non-optional argument following an optional argument",
[argument.location])
inOptionalArguments = argument.optional
variadicArgument = argument if argument.variadic else None
# identifier might be None. This is only permitted for special methods.
if not identifier:
if not getter and not setter and not creator and \

View File

@ -171,23 +171,6 @@ def WebIDLTest(parser, harness):
harness.ok(threw, "Dictionary arg followed by optional arg must be optional")
parser = parser.reset()
threw = False
try:
parser.parse("""
dictionary A {
};
interface X {
void doFoo(A arg1, optional long arg2, long arg3);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(not threw,
"Dictionary arg followed by non-optional arg doesn't have to be optional")
parser = parser.reset()
threw = False
try:

View File

@ -11,9 +11,9 @@ def WebIDLTest(parser, harness):
except:
threw = True
harness.ok(not threw,
"Should not have thrown on non-optional argument following "
"optional argument.")
harness.ok(threw,
"Should have thrown on non-optional argument following optional "
"argument.")
parser = parser.reset()
parser.parse("""

View File

@ -11,8 +11,6 @@ def WebIDLTest(parser, harness):
void withVariadics(long... numbers);
void withVariadics(TestOverloads iface);
void withVariadics(long num, TestOverloads iface);
void optionalTest();
void optionalTest(optional long num1, long num2);
};
""")
@ -25,7 +23,7 @@ def WebIDLTest(parser, harness):
"Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestOverloads", "Interface has the right QName")
harness.check(iface.identifier.name, "TestOverloads", "Interface has the right name")
harness.check(len(iface.members), 4, "Expect %s members" % 4)
harness.check(len(iface.members), 3, "Expect %s members" % 3)
member = iface.members[0]
harness.check(member.identifier.QName(), "::TestOverloads::basic", "Method has the right QName")
@ -50,11 +48,3 @@ def WebIDLTest(parser, harness):
harness.check(argument.identifier.QName(), "::TestOverloads::basic::arg1", "Argument has the right QName")
harness.check(argument.identifier.name, "arg1", "Argument has the right name")
harness.check(str(argument.type), "Long", "Argument has the right type")
member = iface.members[3]
harness.check(len(member.overloadsForArgCount(0)), 1,
"Only one overload for no args")
harness.check(len(member.overloadsForArgCount(1)), 0,
"No overloads for one arg")
harness.check(len(member.overloadsForArgCount(2)), 1,
"Only one overload for two args")

View File

@ -1,62 +1,51 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
results = parser.parse("""
interface VariadicConstraints1 {
void foo(byte... arg1, byte arg2);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"Should have thrown on variadic argument followed by required "
"argument.")
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse("""
results = parser.parse("""
interface VariadicConstraints2 {
void foo(byte... arg1, optional byte arg2);
};
""")
results = parser.finish();
except:
threw = True
harness.ok(threw,
"Should have thrown on variadic argument followed by optional "
"argument.")
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse("""
results = parser.parse("""
interface VariadicConstraints3 {
void foo(optional byte... arg1);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"Should have thrown on variadic argument explicitly flagged as "
"optional.")
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse("""
results = parser.parse("""
interface VariadicConstraints4 {
void foo(byte... arg1 = 0);
};
""")
results = parser.finish()
except:
threw = True

View File

@ -162,9 +162,9 @@ public:
void PassByte(int8_t);
int8_t ReceiveByte();
void PassOptionalByte(const Optional<int8_t>&);
void PassOptionalByteBeforeRequired(const Optional<int8_t>&, int8_t);
void PassOptionalUndefinedMissingByte(const Optional<int8_t>&);
void PassOptionalByteWithDefault(int8_t);
void PassOptionalByteWithDefaultBeforeRequired(int8_t, int8_t);
void PassOptionalUndefinedMissingByteWithDefault(int8_t);
void PassNullableByte(const Nullable<int8_t>&);
void PassOptionalNullableByte(const Optional< Nullable<int8_t> >&);
void PassVariadicByte(const Sequence<int8_t>&);
@ -411,7 +411,9 @@ public:
void PassString(const nsAString&);
void PassNullableString(const nsAString&);
void PassOptionalString(const Optional<nsAString>&);
void PassOptionalUndefinedMissingString(const Optional<nsAString>&);
void PassOptionalStringWithDefaultValue(const nsAString&);
void PassOptionalUndefinedMissingStringWithDefaultValue(const nsAString&);
void PassOptionalNullableString(const Optional<nsAString>&);
void PassOptionalNullableStringWithDefaultValue(const nsAString&);
void PassVariadicString(const Sequence<nsString>&);
@ -630,22 +632,6 @@ public:
void Overload7(const nsCString&);
void Overload8(int32_t);
void Overload8(TestInterface&);
void Overload9(const Nullable<int32_t>&);
void Overload9(const nsAString&);
void Overload10(const Nullable<int32_t>&);
void Overload10(JSContext*, JS::Handle<JSObject*>);
void Overload11(int32_t);
void Overload11(const nsAString&);
void Overload12(int32_t);
void Overload12(const Nullable<bool>&);
void Overload13(const Nullable<int32_t>&);
void Overload13(bool);
void Overload14(const Optional<int32_t>&);
void Overload14(TestInterface&);
void Overload15(int32_t);
void Overload15(const Optional<NonNull<TestInterface> >&);
void Overload16(int32_t);
void Overload16(const Optional<TestInterface*>&);
// Variadic handling
void PassVariadicThirdArg(const nsAString&, int32_t,

View File

@ -118,9 +118,9 @@ interface TestInterface {
void passByte(byte arg);
byte receiveByte();
void passOptionalByte(optional byte arg);
void passOptionalByteBeforeRequired(optional byte arg1, byte arg2);
void passOptionalUndefinedMissingByte([TreatUndefinedAs=Missing] optional byte arg);
void passOptionalByteWithDefault(optional byte arg = 0);
void passOptionalByteWithDefaultBeforeRequired(optional byte arg1 = 0, byte arg2);
void passOptionalUndefinedMissingByteWithDefault([TreatUndefinedAs=Missing] optional byte arg = 0);
void passNullableByte(byte? arg);
void passOptionalNullableByte(optional byte? arg);
void passVariadicByte(byte... arg);
@ -365,7 +365,9 @@ interface TestInterface {
void passString(DOMString arg);
void passNullableString(DOMString? arg);
void passOptionalString(optional DOMString arg);
void passOptionalUndefinedMissingString([TreatUndefinedAs=Missing] optional DOMString arg);
void passOptionalStringWithDefaultValue(optional DOMString arg = "abc");
void passOptionalUndefinedMissingStringWithDefaultValue([TreatUndefinedAs=Missing] optional DOMString arg = "abc");
void passOptionalNullableString(optional DOMString? arg);
void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
void passVariadicString(DOMString... arg);
@ -579,22 +581,6 @@ interface TestInterface {
void overload7(ByteString arg);
void overload8(long arg);
void overload8(TestInterface arg);
void overload9(long? arg);
void overload9(DOMString arg);
void overload10(long? arg);
void overload10(object arg);
void overload11(long arg);
void overload11(DOMString? arg);
void overload12(long arg);
void overload12(boolean? arg);
void overload13(long? arg);
void overload13(boolean arg);
void overload14(optional long arg);
void overload14(TestInterface arg);
void overload15(long arg);
void overload15(optional TestInterface arg);
void overload16(long arg);
void overload16(optional TestInterface? arg);
// Variadic handling
void passVariadicThirdArg(DOMString arg1, long arg2, TestInterface... arg3);

View File

@ -23,9 +23,9 @@ interface TestExampleInterface {
void passByte(byte arg);
byte receiveByte();
void passOptionalByte(optional byte arg);
void passOptionalByteBeforeRequired(optional byte arg1, byte arg2);
void passOptionalUndefinedMissingByte([TreatUndefinedAs=Missing] optional byte arg);
void passOptionalByteWithDefault(optional byte arg = 0);
void passOptionalByteWithDefaultBeforeRequired(optional byte arg1 = 0, byte arg2);
void passOptionalUndefinedMissingByteWithDefault([TreatUndefinedAs=Missing] optional byte arg = 0);
void passNullableByte(byte? arg);
void passOptionalNullableByte(optional byte? arg);
void passVariadicByte(byte... arg);
@ -263,7 +263,9 @@ interface TestExampleInterface {
void passString(DOMString arg);
void passNullableString(DOMString? arg);
void passOptionalString(optional DOMString arg);
void passOptionalUndefinedMissingString([TreatUndefinedAs=Missing] optional DOMString arg);
void passOptionalStringWithDefaultValue(optional DOMString arg = "abc");
void passOptionalUndefinedMissingStringWithDefaultValue([TreatUndefinedAs=Missing] optional DOMString arg = "abc");
void passOptionalNullableString(optional DOMString? arg);
void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
void passVariadicString(DOMString... arg);
@ -476,22 +478,6 @@ interface TestExampleInterface {
void overload7(ByteString arg);
void overload8(long arg);
void overload8(TestInterface arg);
void overload9(long? arg);
void overload9(DOMString arg);
void overload10(long? arg);
void overload10(object arg);
void overload11(long arg);
void overload11(DOMString? arg);
void overload12(long arg);
void overload12(boolean? arg);
void overload13(long? arg);
void overload13(boolean arg);
void overload14(optional long arg);
void overload14(TestInterface arg);
void overload15(long arg);
void overload15(optional TestInterface arg);
void overload16(long arg);
void overload16(optional TestInterface? arg);
// Variadic handling
void passVariadicThirdArg(DOMString arg1, long arg2, TestInterface... arg3);

View File

@ -35,9 +35,9 @@ interface TestJSImplInterface {
void passByte(byte arg);
byte receiveByte();
void passOptionalByte(optional byte arg);
void passOptionalByteBeforeRequired(optional byte arg1, byte arg2);
void passOptionalUndefinedMissingByte([TreatUndefinedAs=Missing] optional byte arg);
void passOptionalByteWithDefault(optional byte arg = 0);
void passOptionalByteWithDefaultBeforeRequired(optional byte arg1 = 0, byte arg2);
void passOptionalUndefinedMissingByteWithDefault([TreatUndefinedAs=Missing] optional byte arg = 0);
void passNullableByte(byte? arg);
void passOptionalNullableByte(optional byte? arg);
void passVariadicByte(byte... arg);
@ -285,7 +285,9 @@ interface TestJSImplInterface {
void passString(DOMString arg);
void passNullableString(DOMString? arg);
void passOptionalString(optional DOMString arg);
void passOptionalUndefinedMissingString([TreatUndefinedAs=Missing] optional DOMString arg);
void passOptionalStringWithDefaultValue(optional DOMString arg = "abc");
void passOptionalUndefinedMissingStringWithDefaultValue([TreatUndefinedAs=Missing] optional DOMString arg = "abc");
void passOptionalNullableString(optional DOMString? arg);
void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
void passVariadicString(DOMString... arg);
@ -504,22 +506,6 @@ interface TestJSImplInterface {
void overload7(ByteString arg);
void overload8(long arg);
void overload8(TestJSImplInterface arg);
void overload9(long? arg);
void overload9(DOMString arg);
void overload10(long? arg);
void overload10(object arg);
void overload11(long arg);
void overload11(DOMString? arg);
void overload12(long arg);
void overload12(boolean? arg);
void overload13(long? arg);
void overload13(boolean arg);
void overload14(optional long arg);
void overload14(TestInterface arg);
void overload15(long arg);
void overload15(optional TestInterface arg);
void overload16(long arg);
void overload16(optional TestInterface? arg);
// Variadic handling
void passVariadicThirdArg(DOMString arg1, long arg2, TestJSImplInterface... arg3);

View File

@ -989,18 +989,11 @@ BluetoothHfpManager::Connect(const nsAString& aDeviceAddress,
return;
}
mNeedsUpdatingSdpRecords = true;
mIsHandsfree = !IS_HEADSET(aController->GetCod());
nsString uuid;
if (mIsHandsfree) {
BluetoothUuidHelper::GetString(BluetoothServiceClass::HANDSFREE, uuid);
} else {
BluetoothUuidHelper::GetString(BluetoothServiceClass::HEADSET, uuid);
}
BluetoothUuidHelper::GetString(BluetoothServiceClass::HANDSFREE, uuid);
if (NS_FAILED(bs->GetServiceChannel(aDeviceAddress, uuid, this))) {
aController->OnConnect(NS_LITERAL_STRING(ERR_SERVICE_CHANNEL_NOT_FOUND));
aController->OnConnect(NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
return;
}
@ -1509,25 +1502,9 @@ BluetoothHfpManager::OnSocketDisconnect(BluetoothSocket* aSocket)
void
BluetoothHfpManager::OnUpdateSdpRecords(const nsAString& aDeviceAddress)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!aDeviceAddress.IsEmpty());
MOZ_ASSERT(mRunnable);
BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE_VOID(bs);
nsString uuid;
if (mIsHandsfree) {
BluetoothUuidHelper::GetString(BluetoothServiceClass::HANDSFREE, uuid);
} else {
BluetoothUuidHelper::GetString(BluetoothServiceClass::HEADSET, uuid);
}
// Since we have updated SDP records of the target device, we should
// try to get the channel of target service again.
if (NS_FAILED(bs->GetServiceChannel(aDeviceAddress, uuid, this))) {
OnConnect(NS_LITERAL_STRING(ERR_SERVICE_CHANNEL_NOT_FOUND));
}
// UpdateSdpRecord() is not called so this callback function should not
// be invoked.
MOZ_ASSUME_UNREACHABLE("UpdateSdpRecords() should be called somewhere");
}
void
@ -1541,14 +1518,17 @@ BluetoothHfpManager::OnGetServiceChannel(const nsAString& aDeviceAddress,
BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE_VOID(bs);
BluetoothValue v;
if (aChannel < 0) {
if (mNeedsUpdatingSdpRecords) {
mNeedsUpdatingSdpRecords = false;
bs->UpdateSdpRecords(aDeviceAddress, this);
} else {
// If we can't find Handsfree server channel number on the remote device,
// try to create HSP connection instead.
nsString hspUuid;
BluetoothUuidHelper::GetString(BluetoothServiceClass::HEADSET, hspUuid);
if (aServiceUuid.Equals(hspUuid)) {
OnConnect(NS_LITERAL_STRING(ERR_SERVICE_CHANNEL_NOT_FOUND));
} else if (NS_FAILED(bs->GetServiceChannel(aDeviceAddress,
hspUuid, this))) {
OnConnect(NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
}
return;

View File

@ -147,8 +147,6 @@ private:
int mNetworkSelectionMode;
bool mReceiveVgsFlag;
bool mDialingRequestProcessed;
bool mIsHandsfree;
bool mNeedsUpdatingSdpRecords;
nsString mDeviceAddress;
nsString mMsisdn;
nsString mOperatorName;

View File

@ -46,11 +46,6 @@ BEGIN_BLUETOOTH_NAMESPACE
// Major device class = 0xA, Peripheral
#define IS_PERIPHERAL(cod) (GET_MAJOR_DEVICE_CLASS(cod) == 0xa)
// Major device class = 0x4, Audio/Video
// Minor device class = 0x1, Wearable Headset device
#define IS_HEADSET(cod) ((GET_MAJOR_DEVICE_CLASS(cod) == 0x4) && \
(GET_MINOR_DEVICE_CLASS(cod) == 0x1))
class BluetoothProfileManagerBase;
class BluetoothReplyRunnable;
typedef void (*BluetoothProfileControllerCallback)();

View File

@ -18,21 +18,17 @@ function checkDoc(title, expectedtitle, normalizedtitle) {
assert_equals(doc.doctype.systemId, "")
assert_equals(doc.documentElement.localName, "html")
assert_equals(doc.documentElement.firstChild.localName, "head")
if (title !== undefined) {
assert_equals(doc.documentElement.firstChild.childNodes.length, 1)
assert_equals(doc.documentElement.firstChild.firstChild.localName, "title")
assert_equals(doc.documentElement.firstChild.firstChild.firstChild.data,
expectedtitle)
} else {
assert_equals(doc.documentElement.firstChild.childNodes.length, 0)
}
assert_equals(doc.documentElement.firstChild.childNodes.length, 1)
assert_equals(doc.documentElement.firstChild.firstChild.localName, "title")
assert_equals(doc.documentElement.firstChild.firstChild.firstChild.data,
expectedtitle)
assert_equals(doc.documentElement.lastChild.localName, "body")
assert_equals(doc.documentElement.lastChild.childNodes.length, 0)
})
}
checkDoc("", "", "")
checkDoc(null, "null", "null")
checkDoc(undefined, "", "")
checkDoc(undefined, "undefined", "undefined")
checkDoc("foo bar baz", "foo bar baz", "foo bar baz")
checkDoc("foo\t\tbar baz", "foo\t\tbar baz", "foo bar baz")
checkDoc("foo\n\nbar baz", "foo\n\nbar baz", "foo bar baz")

View File

@ -12,7 +12,7 @@ function checkDoc(title, expectedtitle, normalizedtitle) {
}
checkDoc("", "", "")
checkDoc(null, "null", "null")
checkDoc(undefined, "", "")
checkDoc(undefined, "undefined", "undefined")
checkDoc("foo bar baz", "foo bar baz", "foo bar baz")
checkDoc("foo\t\tbar baz", "foo\t\tbar baz", "foo bar baz")
checkDoc("foo\n\nbar baz", "foo\n\nbar baz", "foo bar baz")

View File

@ -2802,7 +2802,7 @@ QuotaManager::FindSynchronizedOp(const nsACString& aPattern,
for (uint32_t index = 0; index < mSynchronizedOps.Length(); index++) {
const nsAutoPtr<SynchronizedOp>& currentOp = mSynchronizedOps[index];
if (PatternMatchesOrigin(aPattern, currentOp->mOriginOrPattern) &&
(currentOp->mPersistenceType.IsNull() ||
(!currentOp->mPersistenceType ||
currentOp->mPersistenceType == aPersistenceType) &&
(!currentOp->mId || currentOp->mId == aId)) {
return currentOp;
@ -3067,7 +3067,7 @@ QuotaManager::CollectOriginsForEviction(uint64_t aMinSizeToBeFreed,
uint32_t index;
for (index = 0; index < mSynchronizedOps.Length(); index++) {
nsAutoPtr<SynchronizedOp>& op = mSynchronizedOps[index];
if (op->mPersistenceType.IsNull() ||
if (!op->mPersistenceType ||
op->mPersistenceType.Value() == PERSISTENCE_TYPE_TEMPORARY) {
if (op->mOriginOrPattern.IsPattern() &&
!originCollection.ContainsPattern(op->mOriginOrPattern)) {
@ -3078,7 +3078,7 @@ QuotaManager::CollectOriginsForEviction(uint64_t aMinSizeToBeFreed,
for (index = 0; index < mSynchronizedOps.Length(); index++) {
nsAutoPtr<SynchronizedOp>& op = mSynchronizedOps[index];
if (op->mPersistenceType.IsNull() ||
if (!op->mPersistenceType ||
op->mPersistenceType.Value() == PERSISTENCE_TYPE_TEMPORARY) {
if (op->mOriginOrPattern.IsOrigin() &&
!originCollection.ContainsOrigin(op->mOriginOrPattern)) {

View File

@ -138,7 +138,8 @@ public:
static_cast<AudioManager *>(audioManager.get())->SetStreamVolumeIndex(
AUDIO_STREAM_BLUETOOTH_SCO, volIndex);
} else {
MOZ_ASSUME_UNREACHABLE("unexpected audio channel for volume control");
MOZ_ASSUME_UNREACHABLE("unexpected audio channel for initializing "
"volume control");
}
return NS_OK;
@ -314,7 +315,7 @@ AudioManager::Observe(nsISupports* aSubject,
return NS_OK;
}
nsDependentJSString keyStr;
if (!keyStr.init(cx, jsKey) || keyStr.EqualsLiteral("audio.volume.bt_sco")) {
if (!keyStr.init(cx, jsKey) || !keyStr.EqualsLiteral("audio.volume.bt_sco")) {
return NS_OK;
}

View File

@ -31,6 +31,7 @@
#include "AudioManager.h"
#endif
#include "mozilla/ipc/Ril.h"
#include "mozilla/ipc/KeyStore.h"
#include "nsIObserverService.h"
#include "nsCxPusher.h"
#include "nsServiceManagerUtils.h"
@ -341,6 +342,8 @@ SystemWorkerManager::Init()
return rv;
}
InitKeyStore(cx);
#ifdef MOZ_WIDGET_GONK
InitAutoMounter();
InitializeTimeZoneSettingObserver();
@ -545,6 +548,13 @@ SystemWorkerManager::InitWifi(JSContext *cx)
return NS_OK;
}
nsresult
SystemWorkerManager::InitKeyStore(JSContext *cx)
{
mKeyStore = new KeyStore();
return NS_OK;
}
NS_IMPL_ISUPPORTS3(SystemWorkerManager,
nsIObserver,
nsIInterfaceRequestor,

View File

@ -35,6 +35,7 @@ namespace mozilla {
namespace ipc {
class RilConsumer;
class UnixSocketRawData;
class KeyStore;
}
namespace dom {
@ -70,6 +71,7 @@ private:
nsresult InitNetd(JSContext *cx);
#endif
nsresult InitWifi(JSContext *cx);
nsresult InitKeyStore(JSContext *cx);
#ifdef MOZ_WIDGET_GONK
nsCOMPtr<nsIWorkerHolder> mNetdWorker;
@ -77,6 +79,7 @@ private:
nsCOMPtr<nsIWorkerHolder> mWifiWorker;
nsTArray<nsRefPtr<ipc::RilConsumer> > mRilConsumers;
nsRefPtr<ipc::KeyStore> mKeyStore;
bool mShutdown;
};

View File

@ -7,3 +7,4 @@ qemu = true
disabled = Bug 808783
[test_fakevolume.js]
[test_ril_code_quality.py]
[test_screen_state.js]

View File

@ -74,7 +74,7 @@ interface CanvasRenderingContext2D {
// path API (see also CanvasPathMethods)
void beginPath();
void fill(optional CanvasWindingRule winding = "nonzero");
void fill([TreatUndefinedAs=Missing] optional CanvasWindingRule winding = "nonzero");
// NOT IMPLEMENTED void fill(Path path);
void stroke();
// NOT IMPLEMENTED void stroke(Path path);
@ -84,10 +84,10 @@ interface CanvasRenderingContext2D {
// NOT IMPLEMENTED boolean drawCustomFocusRing(Path path, Element element);
// NOT IMPLEMENTED void scrollPathIntoView();
// NOT IMPLEMENTED void scrollPathIntoView(Path path);
void clip(optional CanvasWindingRule winding = "nonzero");
void clip([TreatUndefinedAs=Missing] optional CanvasWindingRule winding = "nonzero");
// NOT IMPLEMENTED void clip(Path path);
// NOT IMPLEMENTED void resetClip();
boolean isPointInPath(unrestricted double x, unrestricted double y, optional CanvasWindingRule winding = "nonzero");
boolean isPointInPath(unrestricted double x, unrestricted double y, [TreatUndefinedAs=Missing] optional CanvasWindingRule winding = "nonzero");
// NOT IMPLEMENTED boolean isPointInPath(Path path, unrestricted double x, unrestricted double y);
boolean isPointInStroke(double x, double y);

View File

@ -28,9 +28,9 @@ interface Promise {
static Promise reject(any value);
[Creator]
Promise then(optional AnyCallback fulfillCallback,
optional AnyCallback rejectCallback);
Promise then([TreatUndefinedAs=Missing] optional AnyCallback fulfillCallback,
[TreatUndefinedAs=Missing] optional AnyCallback rejectCallback);
[Creator]
Promise catch(optional AnyCallback rejectCallback);
Promise catch([TreatUndefinedAs=Missing] optional AnyCallback rejectCallback);
};

View File

@ -71,9 +71,7 @@ interface XMLHttpRequest : XMLHttpRequestEventTarget {
// request
[Throws]
void open(ByteString method, DOMString url);
[Throws]
void open(ByteString method, DOMString url, boolean async,
void open(ByteString method, DOMString url, optional boolean async = true,
optional DOMString? user, optional DOMString? password);
[Throws]
void setRequestHeader(ByteString header, ByteString value);

View File

@ -121,11 +121,6 @@ public:
return mStateData.mReadyState;
}
void Open(const nsACString& aMethod, const nsAString& aUrl, ErrorResult& aRv)
{
Open(aMethod, aUrl, true, Optional<nsAString>(),
Optional<nsAString>(), aRv);
}
void
Open(const nsACString& aMethod, const nsAString& aUrl, bool aAsync,
const Optional<nsAString>& aUser, const Optional<nsAString>& aPassword,

381
ipc/keystore/KeyStore.cpp Normal file
View File

@ -0,0 +1,381 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set sw=4 ts=8 et ft=cpp: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <fcntl.h>
#include <sys/stat.h>
#undef LOG
#if defined(MOZ_WIDGET_GONK)
#include <android/log.h>
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
#else
#define LOG(args...) printf(args);
#endif
#include "KeyStore.h"
#include "jsfriendapi.h"
#include "MainThreadUtils.h" // For NS_IsMainThread.
#include "plbase64.h"
#include "certdb.h"
using namespace mozilla::ipc;
namespace mozilla {
namespace ipc {
static const char* KEYSTORE_SOCKET_NAME = "keystore";
static const char* KEYSTORE_SOCKET_PATH = "/dev/socket/keystore";
int
KeyStoreConnector::Create()
{
MOZ_ASSERT(!NS_IsMainThread());
int fd;
unlink(KEYSTORE_SOCKET_PATH);
fd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (fd < 0) {
NS_WARNING("Could not open keystore socket!");
return -1;
}
// Allow access of wpa_supplicant(different user, differnt group)
chmod(KEYSTORE_SOCKET_PATH, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
return fd;
}
bool
KeyStoreConnector::CreateAddr(bool aIsServer,
socklen_t& aAddrSize,
sockaddr_any& aAddr,
const char* aAddress)
{
// Keystore socket must be server
MOZ_ASSERT(aIsServer);
aAddr.un.sun_family = AF_LOCAL;
if(strlen(KEYSTORE_SOCKET_PATH) > sizeof(aAddr.un.sun_path)) {
NS_WARNING("Address too long for socket struct!");
return false;
}
strcpy((char*)&aAddr.un.sun_path, KEYSTORE_SOCKET_PATH);
aAddrSize = strlen(KEYSTORE_SOCKET_PATH) + offsetof(struct sockaddr_un, sun_path) + 1;
return true;
}
bool
KeyStoreConnector::SetUp(int aFd)
{
return true;
}
void
KeyStoreConnector::GetSocketAddr(const sockaddr_any& aAddr,
nsAString& aAddrStr)
{
// Unused.
MOZ_CRASH("This should never be called!");
}
static char *
get_cert_db_filename(void *arg, int vers)
{
static char keystoreDbPath[] = "/data/misc/wifi/keystore";
return keystoreDbPath;
}
KeyStore::KeyStore()
{
// Initial NSS
certdb = CERT_GetDefaultCertDB();
Listen();
}
void
KeyStore::Shutdown()
{
mShutdown = true;
CloseSocket();
}
void
KeyStore::Listen()
{
ListenSocket(new KeyStoreConnector());
ResetHandlerInfo();
}
void
KeyStore::ResetHandlerInfo()
{
mHandlerInfo.state = STATE_IDLE;
mHandlerInfo.command = 0;
mHandlerInfo.paramCount = 0;
mHandlerInfo.commandPattern = NULL;
for (int i = 0; i < MAX_PARAM; i++) {
mHandlerInfo.param[i].length = 0;
memset(mHandlerInfo.param[i].data, 0, VALUE_SIZE);
}
}
bool
KeyStore::CheckSize(UnixSocketRawData *aMessage, size_t aExpectSize)
{
return (aMessage->mSize - aMessage->mCurrentWriteOffset >= aExpectSize) ?
true : false;
}
bool
KeyStore::ReadCommand(UnixSocketRawData *aMessage)
{
if (mHandlerInfo.state != STATE_IDLE) {
NS_WARNING("Wrong state in ReadCommand()!");
return false;
}
if (!CheckSize(aMessage, 1)) {
NS_WARNING("Data size error in ReadCommand()!");
return false;
}
mHandlerInfo.command = aMessage->mData[aMessage->mCurrentWriteOffset];
aMessage->mCurrentWriteOffset++;
// Find corrsponding command pattern
const struct ProtocolCommand *command = commands;
while (command->command && command->command != mHandlerInfo.command) {
command++;
}
if (!command->command) {
NS_WARNING("Unsupported command!");
return false;
}
// Get command pattern.
mHandlerInfo.commandPattern = command;
if (command->paramNum) {
// Read command parameter if needed.
mHandlerInfo.state = STATE_READ_PARAM_LEN;
} else {
mHandlerInfo.state = STATE_PROCESSING;
}
return true;
}
bool
KeyStore::ReadLength(UnixSocketRawData *aMessage)
{
if (mHandlerInfo.state != STATE_READ_PARAM_LEN) {
NS_WARNING("Wrong state in ReadLength()!");
return false;
}
if (!CheckSize(aMessage, 2)) {
NS_WARNING("Data size error in ReadLength()!");
return false;
}
// Read length of command parameter.
unsigned short dataLength;
memcpy(&dataLength, &aMessage->mData[aMessage->mCurrentWriteOffset], 2);
aMessage->mCurrentWriteOffset += 2;
mHandlerInfo.param[mHandlerInfo.paramCount].length = ntohs(dataLength);
mHandlerInfo.state = STATE_READ_PARAM_DATA;
return true;
}
bool
KeyStore::ReadData(UnixSocketRawData *aMessage)
{
if (mHandlerInfo.state != STATE_READ_PARAM_DATA) {
NS_WARNING("Wrong state in ReadData()!");
return false;
}
if (!CheckSize(aMessage, mHandlerInfo.param[mHandlerInfo.paramCount].length)) {
NS_WARNING("Data size error in ReadData()!");
return false;
}
// Read command parameter.
memcpy(mHandlerInfo.param[mHandlerInfo.paramCount].data,
&aMessage->mData[aMessage->mCurrentWriteOffset],
mHandlerInfo.param[mHandlerInfo.paramCount].length);
aMessage->mCurrentWriteOffset += mHandlerInfo.param[mHandlerInfo.paramCount].length;
mHandlerInfo.paramCount++;
if (mHandlerInfo.paramCount == mHandlerInfo.commandPattern->paramNum) {
mHandlerInfo.state = STATE_PROCESSING;
} else {
mHandlerInfo.state = STATE_READ_PARAM_LEN;
}
return true;
}
// Transform base64 certification data into DER format
void
KeyStore::FormatCaData(const uint8_t *aCaData, int aCaDataLength,
const char *aName, const uint8_t **aFormatData,
int &aFormatDataLength)
{
int bufSize = strlen(CA_BEGIN) + strlen(CA_END) + strlen(CA_TAILER) * 2 +
strlen(aName) * 2 + aCaDataLength + aCaDataLength/CA_LINE_SIZE + 2;
char *buf = (char *)malloc(bufSize);
aFormatDataLength = bufSize;
*aFormatData = (const uint8_t *)buf;
char *ptr = buf;
int len;
// Create DER header.
len = snprintf(ptr, bufSize, "%s%s%s", CA_BEGIN, aName, CA_TAILER);
ptr += len;
bufSize -= len;
// Split base64 data in lines.
int copySize;
while (aCaDataLength > 0) {
copySize = (aCaDataLength > CA_LINE_SIZE) ? CA_LINE_SIZE : aCaDataLength;
memcpy(ptr, aCaData, copySize);
ptr += copySize;
aCaData += copySize;
aCaDataLength -= copySize;
bufSize -= copySize;
*ptr = '\n';
ptr++;
bufSize--;
}
// Create DEA tailer.
snprintf(ptr, bufSize, "%s%s%s", CA_END, aName, CA_TAILER);
}
// Status response
void
KeyStore::SendResponse(ResponseCode aResponse)
{
if (aResponse == NO_RESPONSE)
return;
uint8_t response = (uint8_t)aResponse;
UnixSocketRawData* data = new UnixSocketRawData((const void *)&response, 1);
SendSocketData(data);
}
// Data response
void
KeyStore::SendData(const uint8_t *aData, int aLength)
{
unsigned short dataLength = htons(aLength);
UnixSocketRawData* length = new UnixSocketRawData((const void *)&dataLength, 2);
SendSocketData(length);
UnixSocketRawData* data = new UnixSocketRawData((const void *)aData, aLength);
SendSocketData(data);
}
void
KeyStore::ReceiveSocketData(nsAutoPtr<UnixSocketRawData>& aMessage)
{
MOZ_ASSERT(NS_IsMainThread());
bool success = true;
while (aMessage->mCurrentWriteOffset < aMessage->mSize ||
mHandlerInfo.state == STATE_PROCESSING) {
switch (mHandlerInfo.state) {
case STATE_IDLE:
success = ReadCommand(aMessage);
break;
case STATE_READ_PARAM_LEN:
success = ReadLength(aMessage);
break;
case STATE_READ_PARAM_DATA:
success = ReadData(aMessage);
break;
case STATE_PROCESSING:
success = false;
if (mHandlerInfo.command == 'g') {
// Get CA
const uint8_t *certData;
int certDataLength;
const char *certName = (const char *)mHandlerInfo.param[0].data;
// Get cert from NSS by name
CERTCertificate *cert = CERT_FindCertByNickname(certdb, certName);
if (!cert) {
break;
}
char *certDER = PL_Base64Encode((const char *)cert->derCert.data,
cert->derCert.len, nullptr);
if (!certDER) {
break;
}
FormatCaData((const uint8_t *)certDER, strlen(certDER), "CERTIFICATE",
&certData, certDataLength);
PL_strfree(certDER);
SendResponse(SUCCESS);
SendData(certData, certDataLength);
success = true;
free((void *)certData);
}
ResetHandlerInfo();
break;
}
if (!success) {
SendResponse(PROTOCOL_ERROR);
ResetHandlerInfo();
return;
}
}
}
void
KeyStore::OnConnectSuccess()
{
mShutdown = false;
}
void
KeyStore::OnConnectError()
{
if (!mShutdown) {
Listen();
}
}
void
KeyStore::OnDisconnect()
{
if (!mShutdown) {
Listen();
}
}
} // namespace ipc
} // namespace mozilla

131
ipc/keystore/KeyStore.h Normal file
View File

@ -0,0 +1,131 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et ft=cpp: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ipc_KeyStore_h
#define mozilla_ipc_KeyStore_h 1
#include "mozilla/ipc/UnixSocket.h"
#include <sys/socket.h>
#include <sys/un.h>
#include "cert.h"
namespace mozilla {
namespace ipc {
enum ResponseCode {
SUCCESS = 1,
LOCKED = 2,
UNINITIALIZED = 3,
SYSTEM_ERROR = 4,
PROTOCOL_ERROR = 5,
PERMISSION_DENIED = 6,
KEY_NOT_FOUND = 7,
VALUE_CORRUPTED = 8,
UNDEFINED_ACTION = 9,
WRONG_PASSWORD_0 = 10,
WRONG_PASSWORD_1 = 11,
WRONG_PASSWORD_2 = 12,
WRONG_PASSWORD_3 = 13, // MAX_RETRY = 4
NO_RESPONSE
};
static const int MAX_PARAM = 2;
static const int KEY_SIZE = ((NAME_MAX - 15) / 2);
static const int VALUE_SIZE = 32768;
static const int PASSWORD_SIZE = VALUE_SIZE;
static const char *CA_BEGIN = "-----BEGIN ",
*CA_END = "-----END ",
*CA_TAILER = "-----\n";
static const int CA_LINE_SIZE = 64;
struct ProtocolCommand {
int8_t command;
int paramNum;
};
static const struct ProtocolCommand commands[] = {
{'g', 1}, // Get CA, command "g CERT_NAME"
{ 0, 0}
};
struct ProtocolParam{
uint length;
int8_t data[VALUE_SIZE];
};
typedef enum {
STATE_IDLE,
STATE_READ_PARAM_LEN,
STATE_READ_PARAM_DATA,
STATE_PROCESSING
} ProtocolHandlerState;
class KeyStoreConnector : public mozilla::ipc::UnixSocketConnector
{
public:
KeyStoreConnector()
{}
virtual ~KeyStoreConnector()
{}
virtual int Create();
virtual bool CreateAddr(bool aIsServer,
socklen_t& aAddrSize,
sockaddr_any& aAddr,
const char* aAddress);
virtual bool SetUp(int aFd);
virtual void GetSocketAddr(const sockaddr_any& aAddr,
nsAString& aAddrStr);
};
class KeyStore : public mozilla::ipc::UnixSocketConsumer
{
public:
KeyStore();
virtual ~KeyStore() {}
void Shutdown();
private:
virtual void ReceiveSocketData(nsAutoPtr<UnixSocketRawData>& aMessage);
virtual void OnConnectSuccess();
virtual void OnConnectError();
virtual void OnDisconnect();
private:
struct {
ProtocolHandlerState state;
uint8_t command;
struct ProtocolParam param[MAX_PARAM];
int paramCount;
const struct ProtocolCommand *commandPattern;
} mHandlerInfo;
void ResetHandlerInfo();
void Listen();
void FormatCaData(const uint8_t *caData, int caDataLength, const char *name,
const uint8_t **formatData, int &formatDataLength);
bool CheckSize(UnixSocketRawData *aMessage, size_t aExpectSize);
bool ReadCommand(UnixSocketRawData *aMessage);
bool ReadLength(UnixSocketRawData *aMessage);
bool ReadData(UnixSocketRawData *aMessage);
void SendResponse(ResponseCode response);
void SendData(const uint8_t *data, int length);
bool mShutdown;
CERTCertDBHandle *certdb;
};
} // namespace ipc
} // namespace mozilla
#endif // mozilla_ipc_KeyStore_h

7
ipc/keystore/Makefile.in Normal file
View File

@ -0,0 +1,7 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORT_LIBRARY = 1
include $(topsrcdir)/config/rules.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk

21
ipc/keystore/moz.build Normal file
View File

@ -0,0 +1,21 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
MODULE = 'ipc'
EXPORTS.mozilla.ipc += [
'KeyStore.h'
]
CPP_SOURCES += [
'KeyStore.cpp'
]
FAIL_ON_WARNINGS = True
LIBXUL_LIBRARY = True
LIBRARY_NAME = 'mozkeystore_s'

View File

@ -18,7 +18,7 @@ if CONFIG['MOZ_B2G_BT']:
DIRS += ['dbus']
if CONFIG['MOZ_B2G_RIL'] or CONFIG['MOZ_B2G_BT']:
DIRS += ['unixsocket']
DIRS += ['unixsocket', 'keystore']
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
DIRS += ['netd']

View File

@ -52,7 +52,7 @@ function run_test()
// Test sync XHR sending
cu.evalInSandbox('var createXHR = ' + createXHR.toString(), sb);
var res = cu.evalInSandbox('var sync = createXHR("4444/simple"); sync.send(null); sync', sb);
do_check_true(checkResults(res));
checkResults(res);
// negative test sync XHR sending (to ensure that the xhr do not have chrome caps, see bug 779821)
try {

View File

@ -97,7 +97,7 @@ endif
endif #}
ifneq ($(strip $(MOZ_B2G_RIL)$(MOZ_B2G_BT)),) #{
STATIC_LIBS += mozipcunixsocket_s
STATIC_LIBS += mozipcunixsocket_s mozkeystore_s
endif #}
ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))