зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to fx-team. a=merge
This commit is contained in:
Коммит
66cd1029eb
|
@ -425,7 +425,12 @@ this.ContentControl.prototype = {
|
|||
|
||||
let sentToChild = this.sendToChild(vc, {
|
||||
name: 'AccessFu:AutoMove',
|
||||
json: aOptions
|
||||
json: {
|
||||
moveMethod: aOptions.moveMethod,
|
||||
moveToFocused: aOptions.moveToFocused,
|
||||
noOpIfOnScreen: true,
|
||||
forcePresent: true
|
||||
}
|
||||
});
|
||||
|
||||
if (!moved && !sentToChild) {
|
||||
|
|
|
@ -279,8 +279,10 @@ this.EventManager.prototype = {
|
|||
// Put vc where the focus is at
|
||||
let acc = aEvent.accessible;
|
||||
let doc = aEvent.accessibleDocument;
|
||||
if (acc.role != Roles.DOCUMENT && doc.role != Roles.CHROME_WINDOW) {
|
||||
this.contentControl.autoMove(acc);
|
||||
if ([Roles.CHROME_WINDOW,
|
||||
Roles.DOCUMENT,
|
||||
Roles.APPLICATION].indexOf(acc.role) < 0) {
|
||||
this.contentControl.autoMove(acc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -228,7 +228,7 @@ this.GestureTracker = { // jshint ignore:line
|
|||
* @param {Number} aTimeStamp A new pointer event timeStamp.
|
||||
*/
|
||||
handle: function GestureTracker_handle(aDetail, aTimeStamp) {
|
||||
Logger.debug(() => {
|
||||
Logger.gesture(() => {
|
||||
return ['Pointer event', aDetail.type, 'at:', aTimeStamp,
|
||||
JSON.stringify(aDetail.points)];
|
||||
});
|
||||
|
@ -332,7 +332,7 @@ function compileDetail(aType, aPoints, keyMap = {x: 'startX', y: 'startY'}) {
|
|||
*/
|
||||
function Gesture(aTimeStamp, aPoints = {}, aLastEvent = undefined) {
|
||||
this.startTime = Date.now();
|
||||
Logger.debug('Creating', this.id, 'gesture.');
|
||||
Logger.gesture('Creating', this.id, 'gesture.');
|
||||
this.points = aPoints;
|
||||
this.lastEvent = aLastEvent;
|
||||
this._deferred = Promise.defer();
|
||||
|
@ -509,7 +509,7 @@ Gesture.prototype = {
|
|||
if (this.isComplete) {
|
||||
return;
|
||||
}
|
||||
Logger.debug('Resolving', this.id, 'gesture.');
|
||||
Logger.gesture('Resolving', this.id, 'gesture.');
|
||||
this.isComplete = true;
|
||||
let detail = this.compile();
|
||||
if (detail) {
|
||||
|
@ -533,7 +533,7 @@ Gesture.prototype = {
|
|||
if (this.isComplete) {
|
||||
return;
|
||||
}
|
||||
Logger.debug('Rejecting', this.id, 'gesture.');
|
||||
Logger.gesture('Rejecting', this.id, 'gesture.');
|
||||
this.isComplete = true;
|
||||
return {
|
||||
id: this.id,
|
||||
|
|
|
@ -473,11 +473,12 @@ State.prototype = {
|
|||
};
|
||||
|
||||
this.Logger = { // jshint ignore:line
|
||||
GESTURE: -1,
|
||||
DEBUG: 0,
|
||||
INFO: 1,
|
||||
WARNING: 2,
|
||||
ERROR: 3,
|
||||
_LEVEL_NAMES: ['DEBUG', 'INFO', 'WARNING', 'ERROR'],
|
||||
_LEVEL_NAMES: ['GESTURE', 'DEBUG', 'INFO', 'WARNING', 'ERROR'],
|
||||
|
||||
logLevel: 1, // INFO;
|
||||
|
||||
|
@ -490,7 +491,7 @@ this.Logger = { // jshint ignore:line
|
|||
|
||||
let args = Array.prototype.slice.call(arguments, 1);
|
||||
let message = (typeof(args[0]) === 'function' ? args[0]() : args).join(' ');
|
||||
message = '[' + Utils.ScriptName + '] ' + this._LEVEL_NAMES[aLogLevel] +
|
||||
message = '[' + Utils.ScriptName + '] ' + this._LEVEL_NAMES[aLogLevel + 1] +
|
||||
' ' + message + '\n';
|
||||
dump(message);
|
||||
// Note: used for testing purposes. If |this.test| is true, also log to
|
||||
|
@ -509,6 +510,11 @@ this.Logger = { // jshint ignore:line
|
|||
this, [this.INFO].concat(Array.prototype.slice.call(arguments)));
|
||||
},
|
||||
|
||||
gesture: function gesture() {
|
||||
this.log.apply(
|
||||
this, [this.GESTURE].concat(Array.prototype.slice.call(arguments)));
|
||||
},
|
||||
|
||||
debug: function debug() {
|
||||
this.log.apply(
|
||||
this, [this.DEBUG].concat(Array.prototype.slice.call(arguments)));
|
||||
|
@ -552,14 +558,16 @@ this.Logger = { // jshint ignore:line
|
|||
},
|
||||
|
||||
accessibleToString: function accessibleToString(aAccessible) {
|
||||
let str = '[ defunct ]';
|
||||
try {
|
||||
str = '[ ' + Utils.AccRetrieval.getStringRole(aAccessible.role) +
|
||||
' | ' + aAccessible.name + ' ]';
|
||||
} catch (x) {
|
||||
if (!aAccessible) {
|
||||
return '[ null ]';
|
||||
}
|
||||
|
||||
return str;
|
||||
try {
|
||||
return'[ ' + Utils.AccRetrieval.getStringRole(aAccessible.role) +
|
||||
' | ' + aAccessible.name + ' ]';
|
||||
} catch (x) {
|
||||
return '[ defunct ]';
|
||||
}
|
||||
},
|
||||
|
||||
eventToString: function eventToString(aEvent) {
|
||||
|
|
|
@ -255,7 +255,7 @@ AccessFuContentTest.prototype = {
|
|||
this.currentPair = this.queue.shift();
|
||||
|
||||
if (this.currentPair) {
|
||||
if (this.currentPair[0] instanceof Function) {
|
||||
if (typeof this.currentPair[0] === 'function') {
|
||||
this.currentPair[0](this.mms[0]);
|
||||
} else if (this.currentPair[0]) {
|
||||
this.mms[0].sendAsyncMessage(this.currentPair[0].name,
|
||||
|
@ -290,7 +290,11 @@ AccessFuContentTest.prototype = {
|
|||
if (expected.speak) {
|
||||
var checkFunc = SimpleTest[expected.speak_checkFunc] || isDeeply;
|
||||
checkFunc.apply(SimpleTest, [speech, expected.speak,
|
||||
'"' + JSON.stringify(speech) + '" spoken']);
|
||||
'spoken: ' + JSON.stringify(speech) +
|
||||
' expected: ' + JSON.stringify(expected.speak) +
|
||||
' after: ' + (typeof this.currentPair[0] === 'function' ?
|
||||
this.currentPair[0].toString() :
|
||||
JSON.stringify(this.currentPair[0]))]);
|
||||
}
|
||||
|
||||
if (expected.android) {
|
||||
|
|
|
@ -136,8 +136,8 @@
|
|||
speak: ['wow', {'string': 'headingLevel', 'args': [1]}, 'such app']
|
||||
}],
|
||||
[ContentMessages.focusSelector('button#home', false), {
|
||||
speak: ['Home button']
|
||||
}]
|
||||
speak: ['Home', {'string': 'pushbutton'}]
|
||||
}],
|
||||
|
||||
// Blur button and reset cursor
|
||||
[ContentMessages.focusSelector('button#home', true), null],
|
||||
|
@ -152,13 +152,13 @@
|
|||
speak: ['Phone status bar', 'Traversal Rule test document']
|
||||
}],
|
||||
[doc.defaultView.showAlert, {
|
||||
speak: ['This is an alert! heading level 1 dialog']
|
||||
speak: ['This is an alert!',
|
||||
{'string': 'headingLevel', 'args': [1]},
|
||||
{'string': 'dialog'}]
|
||||
}],
|
||||
|
||||
[function() {
|
||||
doc.defaultView.hideAlert()
|
||||
}, {
|
||||
speak: ['wow', {'string': 'headingLevel', 'args': [1]}, 'such app']
|
||||
[doc.defaultView.hideAlert, {
|
||||
speak: ["wow", {"string": "headingLevel","args": [1]}, "such app"],
|
||||
}],
|
||||
|
||||
[ContentMessages.clearCursor, 'AccessFu:CursorCleared'],
|
||||
|
@ -171,12 +171,14 @@
|
|||
speak: ['wow', {'string': 'headingLevel', 'args': [1]}, 'such app']
|
||||
}],
|
||||
[doc.defaultView.showAlert, {
|
||||
speak: ['This is an alert! heading level 1 dialog']
|
||||
speak: ['This is an alert!',
|
||||
{'string': 'headingLevel', 'args': [1]},
|
||||
{'string': 'dialog'}]
|
||||
}],
|
||||
|
||||
// XXX: Place cursor back where it was.
|
||||
[doc.defaultView.hideAlert, {
|
||||
speak: ['many option not checked check button such app']
|
||||
speak: ['wow', {'string': 'headingLevel', 'args': [1]}, 'such app'],
|
||||
}],
|
||||
|
||||
[ContentMessages.clearCursor, 'AccessFu:CursorCleared'],
|
||||
|
@ -186,7 +188,9 @@
|
|||
speak: ['Phone status bar', 'Traversal Rule test document']
|
||||
}],
|
||||
[doc.defaultView.showAlert, {
|
||||
speak: ['This is an alert! heading level 1 dialog']
|
||||
speak: ['This is an alert!',
|
||||
{'string': 'headingLevel', 'args': [1]},
|
||||
{'string': 'dialog'}]
|
||||
}],
|
||||
|
||||
[function() {
|
||||
|
|
|
@ -522,8 +522,8 @@ var shell = {
|
|||
// based on tab's coordinate. So get the actual offsets between shell and evt.target.
|
||||
let elt = evt.target;
|
||||
let win = elt.ownerDocument.defaultView;
|
||||
let offsetX = win.mozInnerScreenX;
|
||||
let offsetY = win.mozInnerScreenY;
|
||||
let offsetX = win.mozInnerScreenX - window.mozInnerScreenX;
|
||||
let offsetY = win.mozInnerScreenY - window.mozInnerScreenY;
|
||||
|
||||
let rect = elt.getBoundingClientRect();
|
||||
offsetX += rect.left;
|
||||
|
|
|
@ -19,13 +19,13 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="5e074831f9ddacdf6f622a6dffaecb626f740be8"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c7f8938522a18454809fb6ea0fd3eddef10a73ea"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3bb61a27cd2941b2ba9b616a11aaa44269210396"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="f0592d4814d738e3f8d840915ef799c13601bdef"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0296e3a38710494ec87c3da936b276afa1555afa"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="88261785a21d8a50b848180228af72a1505a173d"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
|
||||
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5e074831f9ddacdf6f622a6dffaecb626f740be8"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c7f8938522a18454809fb6ea0fd3eddef10a73ea"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3bb61a27cd2941b2ba9b616a11aaa44269210396"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0296e3a38710494ec87c3da936b276afa1555afa"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="88261785a21d8a50b848180228af72a1505a173d"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="7945ca73e687be5edbc7b928dc7fe3a208242144">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5e074831f9ddacdf6f622a6dffaecb626f740be8"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c7f8938522a18454809fb6ea0fd3eddef10a73ea"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3bb61a27cd2941b2ba9b616a11aaa44269210396"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -23,7 +23,7 @@
|
|||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0296e3a38710494ec87c3da936b276afa1555afa"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="88261785a21d8a50b848180228af72a1505a173d"/>
|
||||
<!-- Stock Android things -->
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
|
||||
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>
|
||||
|
|
|
@ -19,13 +19,13 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="5e074831f9ddacdf6f622a6dffaecb626f740be8"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c7f8938522a18454809fb6ea0fd3eddef10a73ea"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3bb61a27cd2941b2ba9b616a11aaa44269210396"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="f0592d4814d738e3f8d840915ef799c13601bdef"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0296e3a38710494ec87c3da936b276afa1555afa"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="88261785a21d8a50b848180228af72a1505a173d"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
|
||||
<project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
</project>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5e074831f9ddacdf6f622a6dffaecb626f740be8"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c7f8938522a18454809fb6ea0fd3eddef10a73ea"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3bb61a27cd2941b2ba9b616a11aaa44269210396"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0296e3a38710494ec87c3da936b276afa1555afa"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="88261785a21d8a50b848180228af72a1505a173d"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "2fb6119da922ebdab70c79e7f515f49fa582b2c5",
|
||||
"revision": "a5d998cfe7cd004c7967e40efaaad0ccb829ecc4",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="5e074831f9ddacdf6f622a6dffaecb626f740be8"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c7f8938522a18454809fb6ea0fd3eddef10a73ea"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3bb61a27cd2941b2ba9b616a11aaa44269210396"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0296e3a38710494ec87c3da936b276afa1555afa"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="88261785a21d8a50b848180228af72a1505a173d"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
|
||||
<project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="5e074831f9ddacdf6f622a6dffaecb626f740be8"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c7f8938522a18454809fb6ea0fd3eddef10a73ea"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3bb61a27cd2941b2ba9b616a11aaa44269210396"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5e074831f9ddacdf6f622a6dffaecb626f740be8"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c7f8938522a18454809fb6ea0fd3eddef10a73ea"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3bb61a27cd2941b2ba9b616a11aaa44269210396"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0296e3a38710494ec87c3da936b276afa1555afa"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="88261785a21d8a50b848180228af72a1505a173d"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
|
||||
<!-- Stock Android things -->
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="5e074831f9ddacdf6f622a6dffaecb626f740be8"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c7f8938522a18454809fb6ea0fd3eddef10a73ea"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3bb61a27cd2941b2ba9b616a11aaa44269210396"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0296e3a38710494ec87c3da936b276afa1555afa"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="88261785a21d8a50b848180228af72a1505a173d"/>
|
||||
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
|
||||
<!-- Stock Android things -->
|
||||
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
|
||||
|
|
|
@ -23,7 +23,7 @@ MOZ_SERVICES_METRICS=1
|
|||
MOZ_CAPTIVEDETECT=1
|
||||
|
||||
MOZ_WEBSMS_BACKEND=1
|
||||
MOZ_DISABLE_CRYPTOLEGACY=1
|
||||
MOZ_NO_SMART_CARDS=1
|
||||
MOZ_APP_STATIC_INI=1
|
||||
NSS_NO_LIBPKIX=1
|
||||
NSS_DISABLE_DBM=1
|
||||
|
|
|
@ -17,24 +17,24 @@ a {
|
|||
|
||||
.message {
|
||||
display: flex;
|
||||
flex: 0 0 main-size;
|
||||
flex: none;
|
||||
padding: 0 7px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.message > .timestamp {
|
||||
flex: 0 0 main-size;
|
||||
flex: none;
|
||||
color: GrayText;
|
||||
margin: 4px 6px 0 0;
|
||||
}
|
||||
|
||||
.message > .indent {
|
||||
flex: 0 0 main-size;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.message > .icon {
|
||||
flex: 0 0 main-size;
|
||||
flex: none;
|
||||
margin: 3px 6px 0 0;
|
||||
padding: 0 4px;
|
||||
height: 1em;
|
||||
|
@ -66,7 +66,7 @@ a {
|
|||
/* The red bubble that shows the number of times a message is repeated */
|
||||
.message-repeats {
|
||||
-moz-user-select: none;
|
||||
flex: 0 0 main-size;
|
||||
flex: none;
|
||||
margin: 2px 6px;
|
||||
padding: 0 6px;
|
||||
height: 1.25em;
|
||||
|
@ -84,7 +84,7 @@ a {
|
|||
|
||||
.message-location {
|
||||
display: flex;
|
||||
flex: 0 0 main-size;
|
||||
flex: none;
|
||||
align-self: flex-start;
|
||||
justify-content: flex-end;
|
||||
width: 10em;
|
||||
|
@ -106,7 +106,7 @@ a {
|
|||
}
|
||||
|
||||
.message-location > .line-number {
|
||||
flex: 0 0 main-size;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.message-flex-body {
|
||||
|
@ -236,7 +236,7 @@ a {
|
|||
}
|
||||
|
||||
.message[category=network] .method {
|
||||
flex: 0 0 main-size;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.message[category=network]:not(.navigation-marker) .url {
|
||||
|
@ -250,7 +250,7 @@ a {
|
|||
}
|
||||
|
||||
.message[category=network] .status {
|
||||
flex: 0 0 main-size;
|
||||
flex: none;
|
||||
-moz-margin-start: 6px;
|
||||
}
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@ if test -z "$BUILDING_JS" -o -n "$JS_STANDALONE"; then
|
|||
|
||||
# --with-cross-build requires absolute path
|
||||
ICU_HOST_PATH=`cd $_objdir/intl/icu/host && pwd`
|
||||
ICU_CROSS_BUILD_OPT="--with-cross-build=$ICU_HOST_PATH"
|
||||
ICU_CROSS_BUILD_OPT="--with-cross-build=$ICU_HOST_PATH --disable-tools"
|
||||
ICU_TARGET_OPT="--build=$build --host=$target"
|
||||
else
|
||||
# CROSS_COMPILE isn't set build and target are i386 and x86-64.
|
||||
|
|
|
@ -1395,7 +1395,7 @@ sub readZipCRCs($) {
|
|||
if ($$this{'magicInit'}) {
|
||||
if (defined($$this{'magicErrno'})) {
|
||||
if (defined($$this{'magicErrMsg'})) {
|
||||
complain(1, 'FileAttrCache::magic: '.$$this{'magicErrMsg'}.' for:',
|
||||
main::complain(1, 'FileAttrCache::magic: '.$$this{'magicErrMsg'}.' for:',
|
||||
$$this{'path'});
|
||||
}
|
||||
$! = $$this{'magicErrno'};
|
||||
|
@ -1409,7 +1409,7 @@ sub readZipCRCs($) {
|
|||
if (!sysopen($fh, $$this{'path'}, O_RDONLY)) {
|
||||
$$this{'magicErrno'} = $!;
|
||||
$$this{'magicErrMsg'} = 'open "'.$$this{'path'}.'": '.$!;
|
||||
complain(1, 'FileAttrCache::magic: '.$$this{'magicErrMsg'}.' for:',
|
||||
main::complain(1, 'FileAttrCache::magic: '.$$this{'magicErrMsg'}.' for:',
|
||||
$$this{'path'});
|
||||
return undef;
|
||||
}
|
||||
|
@ -1419,7 +1419,7 @@ sub readZipCRCs($) {
|
|||
if (!defined($bytes = sysread($fh, $magic, 4))) {
|
||||
$$this{'magicErrno'} = $!;
|
||||
$$this{'magicErrMsg'} = 'read "'.$$this{'path'}.'": '.$!;
|
||||
complain(1, 'FileAttrCache::magic: '.$$this{'magicErrMsg'}.' for:',
|
||||
main::complain(1, 'FileAttrCache::magic: '.$$this{'magicErrMsg'}.' for:',
|
||||
$$this{'path'});
|
||||
close($fh);
|
||||
return undef;
|
||||
|
|
|
@ -8,7 +8,7 @@ LIBRARY_NAME = 'crmf'
|
|||
|
||||
if CONFIG['MOZ_NATIVE_NSS']:
|
||||
OS_LIBS += [l for l in CONFIG['NSS_LIBS'] if l.startswith('-L')]
|
||||
OS_LIBS += '-lcrmf'
|
||||
OS_LIBS += ['-lcrmf']
|
||||
else:
|
||||
USE_LIBS += [
|
||||
# The dependency on nss is not real, but is required to force the
|
||||
|
|
22
configure.in
22
configure.in
|
@ -1992,7 +1992,10 @@ ia64*-hpux*)
|
|||
TARGET_NSPR_MDCPUCFG='\"md/_linux.cfg\"'
|
||||
|
||||
MOZ_GFX_OPTIMIZE_MOBILE=1
|
||||
MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks -fno-reorder-functions"
|
||||
MOZ_OPTIMIZE_FLAGS="-Os -fno-reorder-functions"
|
||||
if test -z "$CLANG_CC"; then
|
||||
MOZ_OPTIMIZE_FLAGS="-freorder-blocks $MOZ_OPTIMIZE_FLAGS"
|
||||
fi
|
||||
;;
|
||||
|
||||
*-*linux*)
|
||||
|
@ -2009,7 +2012,10 @@ ia64*-hpux*)
|
|||
MOZ_OPTIMIZE_SIZE_TWEAK="-finline-limit=50"
|
||||
esac
|
||||
MOZ_PGO_OPTIMIZE_FLAGS="-O3"
|
||||
MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks $MOZ_OPTIMIZE_SIZE_TWEAK"
|
||||
MOZ_OPTIMIZE_FLAGS="-Os $MOZ_OPTIMIZE_SIZE_TWEAK"
|
||||
if test -z "$CLANG_CC"; then
|
||||
MOZ_OPTIMIZE_FLAGS="-freorder-blocks $MOZ_OPTIMIZE_FLAGS"
|
||||
fi
|
||||
fi
|
||||
|
||||
TARGET_NSPR_MDCPUCFG='\"md/_linux.cfg\"'
|
||||
|
@ -3779,7 +3785,7 @@ MOZ_WMF=
|
|||
if test -n "$MOZ_FMP4"; then
|
||||
MOZ_FMP4=1
|
||||
else
|
||||
MOZ_FMP4 =
|
||||
MOZ_FMP4=
|
||||
fi
|
||||
MOZ_EME=1
|
||||
MOZ_FFMPEG=
|
||||
|
@ -3826,7 +3832,7 @@ MOZ_XUL=1
|
|||
MOZ_ZIPWRITER=1
|
||||
NS_PRINTING=1
|
||||
MOZ_PDF_PRINTING=
|
||||
MOZ_DISABLE_CRYPTOLEGACY=
|
||||
MOZ_NO_SMART_CARDS=
|
||||
NSS_DISABLE_DBM=
|
||||
NECKO_COOKIES=1
|
||||
NECKO_PROTOCOLS_DEFAULT="about app data file ftp http res viewsource websocket wyciwyg device"
|
||||
|
@ -6342,12 +6348,12 @@ fi
|
|||
AC_SUBST(MOZ_DISABLE_PARENTAL_CONTROLS)
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Disable DOMCrypto
|
||||
dnl = Disable smartcard support
|
||||
dnl ========================================================
|
||||
if test -n "$MOZ_DISABLE_CRYPTOLEGACY"; then
|
||||
AC_DEFINE(MOZ_DISABLE_CRYPTOLEGACY)
|
||||
if test -n "$MOZ_NO_SMART_CARDS"; then
|
||||
AC_DEFINE(MOZ_NO_SMART_CARDS)
|
||||
fi
|
||||
AC_SUBST(MOZ_DISABLE_CRYPTOLEGACY)
|
||||
AC_SUBST(MOZ_NO_SMART_CARDS)
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Disable EV certificate verification
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>CSP eval script tests</title>
|
||||
<script type="application/javascript"
|
||||
src="file_CSP_evalscript_main_allowed_getCRMFRequest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Foo.
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,2 +0,0 @@
|
|||
Cache-Control: no-cache
|
||||
Content-Security-Policy: default-src 'self' ; script-src 'self' 'unsafe-eval'
|
|
@ -1,42 +0,0 @@
|
|||
// some javascript for the CSP eval() tests
|
||||
// all of these evals should succeed, as the document loading this script
|
||||
// has script-src 'self' 'unsafe-eval'
|
||||
|
||||
function logResult(str, passed) {
|
||||
var elt = document.createElement('div');
|
||||
var color = passed ? "#cfc;" : "#fcc";
|
||||
elt.setAttribute('style', 'background-color:' + color + '; width:100%; border:1px solid black; padding:3px; margin:4px;');
|
||||
elt.innerHTML = str;
|
||||
document.body.appendChild(elt);
|
||||
}
|
||||
|
||||
// callback for when stuff is allowed by CSP
|
||||
var onevalexecuted = (function(window) {
|
||||
return function(shouldrun, what, data) {
|
||||
window.parent.scriptRan(shouldrun, what, data);
|
||||
logResult((shouldrun ? "PASS: " : "FAIL: ") + what + " : " + data, shouldrun);
|
||||
};})(window);
|
||||
|
||||
// callback for when stuff is blocked
|
||||
var onevalblocked = (function(window) {
|
||||
return function(shouldrun, what, data) {
|
||||
window.parent.scriptBlocked(shouldrun, what, data);
|
||||
logResult((shouldrun ? "FAIL: " : "PASS: ") + what + " : " + data, !shouldrun);
|
||||
};})(window);
|
||||
|
||||
|
||||
// Defer until document is loaded so that we can write the pretty result boxes
|
||||
// out.
|
||||
addEventListener('load', function() {
|
||||
// test that allows crypto.generateCRMFRequest eval to run
|
||||
try {
|
||||
var script =
|
||||
'console.log("dynamic script passed to crypto.generateCRMFRequest should execute")';
|
||||
crypto.generateCRMFRequest('CN=0', 0, 0, null, script, 384, null, 'rsa-dual-use');
|
||||
onevalexecuted(true, "eval(script) inside crypto.generateCRMFRequest",
|
||||
"eval executed during crypto.generateCRMFRequest");
|
||||
} catch (e) {
|
||||
onevalblocked(true, "eval(script) inside crypto.generateCRMFRequest",
|
||||
"eval was blocked during crypto.generateCRMFRequest");
|
||||
}
|
||||
}, false);
|
|
@ -1,12 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>CSP eval script tests</title>
|
||||
<script type="application/javascript"
|
||||
src="file_CSP_evalscript_main_getCRMFRequest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Foo.
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,2 +0,0 @@
|
|||
Cache-Control: no-cache
|
||||
Content-Security-Policy: default-src 'self'
|
|
@ -1,48 +0,0 @@
|
|||
// some javascript for the CSP eval() tests
|
||||
|
||||
function logResult(str, passed) {
|
||||
var elt = document.createElement('div');
|
||||
var color = passed ? "#cfc;" : "#fcc";
|
||||
elt.setAttribute('style', 'background-color:' + color + '; width:100%; border:1px solid black; padding:3px; margin:4px;');
|
||||
elt.innerHTML = str;
|
||||
document.body.appendChild(elt);
|
||||
}
|
||||
|
||||
window._testResults = {};
|
||||
|
||||
// callback for when stuff is allowed by CSP
|
||||
var onevalexecuted = (function(window) {
|
||||
return function(shouldrun, what, data) {
|
||||
window._testResults[what] = "ran";
|
||||
window.parent.scriptRan(shouldrun, what, data);
|
||||
logResult((shouldrun ? "PASS: " : "FAIL: ") + what + " : " + data, shouldrun);
|
||||
};})(window);
|
||||
|
||||
// callback for when stuff is blocked
|
||||
var onevalblocked = (function(window) {
|
||||
return function(shouldrun, what, data) {
|
||||
window._testResults[what] = "blocked";
|
||||
window.parent.scriptBlocked(shouldrun, what, data);
|
||||
logResult((shouldrun ? "FAIL: " : "PASS: ") + what + " : " + data, !shouldrun);
|
||||
};})(window);
|
||||
|
||||
|
||||
// Defer until document is loaded so that we can write the pretty result boxes
|
||||
// out.
|
||||
addEventListener('load', function() {
|
||||
// generateCRMFRequest test -- make sure we cannot eval the callback if CSP is in effect
|
||||
try {
|
||||
var script = 'console.log("dynamic script eval\'d in crypto.generateCRMFRequest should be disallowed")';
|
||||
crypto.generateCRMFRequest('CN=0', 0, 0, null, script, 384, null, 'rsa-dual-use');
|
||||
onevalexecuted(false, "crypto.generateCRMFRequest()",
|
||||
"crypto.generateCRMFRequest() should not run!");
|
||||
} catch (e) {
|
||||
onevalblocked(false, "eval(script) inside crypto.generateCRMFRequest",
|
||||
"eval was blocked during crypto.generateCRMFRequest");
|
||||
}
|
||||
|
||||
|
||||
}, false);
|
||||
|
||||
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>CSP eval script tests: no CSP specified</title>
|
||||
<script type="application/javascript"
|
||||
src="file_CSP_evalscript_no_CSP_at_all.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Foo. See bug 824652
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1 +0,0 @@
|
|||
Cache-Control: no-cache
|
|
@ -1,42 +0,0 @@
|
|||
// some javascript for the CSP eval() tests
|
||||
// all of these evals should succeed, as the document loading this script
|
||||
// has script-src 'self' 'unsafe-eval'
|
||||
|
||||
function logResult(str, passed) {
|
||||
var elt = document.createElement('div');
|
||||
var color = passed ? "#cfc;" : "#fcc";
|
||||
elt.setAttribute('style', 'background-color:' + color + '; width:100%; border:1px solid black; padding:3px; margin:4px;');
|
||||
elt.innerHTML = str;
|
||||
document.body.appendChild(elt);
|
||||
}
|
||||
|
||||
// callback for when stuff is allowed by CSP
|
||||
var onevalexecuted = (function(window) {
|
||||
return function(shouldrun, what, data) {
|
||||
window.parent.scriptRan(shouldrun, what, data);
|
||||
logResult((shouldrun ? "PASS: " : "FAIL: ") + what + " : " + data, shouldrun);
|
||||
};})(window);
|
||||
|
||||
// callback for when stuff is blocked
|
||||
var onevalblocked = (function(window) {
|
||||
return function(shouldrun, what, data) {
|
||||
window.parent.scriptBlocked(shouldrun, what, data);
|
||||
logResult((shouldrun ? "FAIL: " : "PASS: ") + what + " : " + data, !shouldrun);
|
||||
};})(window);
|
||||
|
||||
|
||||
// Defer until document is loaded so that we can write the pretty result boxes
|
||||
// out.
|
||||
addEventListener('load', function() {
|
||||
// test that allows crypto.generateCRMFRequest eval to run when there is no CSP at all in place
|
||||
try {
|
||||
var script =
|
||||
'console.log("dynamic script passed to crypto.generateCRMFRequest should execute")';
|
||||
crypto.generateCRMFRequest('CN=0', 0, 0, null, script, 384, null, 'rsa-dual-use');
|
||||
onevalexecuted(true, "eval(script) inside crypto.generateCRMFRequest: no CSP at all",
|
||||
"eval executed during crypto.generateCRMFRequest where no CSP is set at all");
|
||||
} catch (e) {
|
||||
onevalblocked(true, "eval(script) inside crypto.generateCRMFRequest",
|
||||
"eval was blocked during crypto.generateCRMFRequest");
|
||||
}
|
||||
}, false);
|
|
@ -20,19 +20,10 @@ support-files =
|
|||
file_CSP_bug888172.sjs
|
||||
file_CSP_evalscript_main.js
|
||||
file_CSP_evalscript_main_allowed.js
|
||||
file_CSP_evalscript_main_allowed_getCRMFRequest.js
|
||||
file_CSP_evalscript_main_getCRMFRequest.js
|
||||
file_CSP_evalscript_main.html
|
||||
file_CSP_evalscript_main.html^headers^
|
||||
file_CSP_evalscript_main_allowed.html
|
||||
file_CSP_evalscript_main_allowed.html^headers^
|
||||
file_CSP_evalscript_main_allowed_getCRMFRequest.html
|
||||
file_CSP_evalscript_main_allowed_getCRMFRequest.html^headers^
|
||||
file_CSP_evalscript_main_getCRMFRequest.html
|
||||
file_CSP_evalscript_main_getCRMFRequest.html^headers^
|
||||
file_CSP_evalscript_no_CSP_at_all.html
|
||||
file_CSP_evalscript_no_CSP_at_all.html^headers^
|
||||
file_CSP_evalscript_no_CSP_at_all.js
|
||||
file_CSP_frameancestors_main.html
|
||||
file_CSP_frameancestors_main.js
|
||||
file_CSP_frameancestors.sjs
|
||||
|
@ -112,8 +103,6 @@ support-files =
|
|||
[test_CSP_bug885433.html]
|
||||
[test_CSP_bug888172.html]
|
||||
[test_CSP_evalscript.html]
|
||||
[test_CSP_evalscript_getCRMFRequest.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # no (deprecated) window.crypto support in multiprocess (bug 824652)
|
||||
[test_CSP_frameancestors.html]
|
||||
skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || toolkit == 'android' # Times out, not sure why (bug 1008445)
|
||||
[test_CSP_inlinescript.html]
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Content Security Policy "no eval" in crypto.getCRMFRequest()</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<iframe style="width:100%;height:300px;" id='cspframe'></iframe>
|
||||
<iframe style="width:100%;height:300px;" id='cspframe2'></iframe>
|
||||
<iframe style="width:100%;height:300px;" id='cspframe3'></iframe>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var path = "/tests/content/base/test/csp/";
|
||||
|
||||
var evalScriptsThatRan = 0;
|
||||
var evalScriptsBlocked = 0;
|
||||
var evalScriptsTotal = 3;
|
||||
|
||||
// called by scripts that run
|
||||
var scriptRan = function(shouldrun, testname, data) {
|
||||
evalScriptsThatRan++;
|
||||
ok(shouldrun, 'EVAL SCRIPT RAN: ' + testname + '(' + data + ')');
|
||||
checkTestResults();
|
||||
}
|
||||
|
||||
// called when a script is blocked
|
||||
var scriptBlocked = function(shouldrun, testname, data) {
|
||||
evalScriptsBlocked++;
|
||||
ok(!shouldrun, 'EVAL SCRIPT BLOCKED: ' + testname + '(' + data + ')');
|
||||
checkTestResults();
|
||||
}
|
||||
|
||||
// Check to see if all the tests have run
|
||||
var checkTestResults = function() {
|
||||
// if any test is incomplete, keep waiting
|
||||
if (evalScriptsTotal - evalScriptsBlocked - evalScriptsThatRan > 0)
|
||||
return;
|
||||
|
||||
// ... otherwise, finish
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function loadElements() {
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById('cspframe').src = 'file_CSP_evalscript_main_getCRMFRequest.html';
|
||||
document.getElementById('cspframe2').src = 'file_CSP_evalscript_main_allowed_getCRMFRequest.html';
|
||||
document.getElementById('cspframe3').src = 'file_CSP_evalscript_no_CSP_at_all.html';
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// set up and go
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.unsafe_legacy_crypto.enabled", true]]},
|
||||
loadElements);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -17,6 +17,7 @@
|
|||
#include "mozilla/Telemetry.h"
|
||||
#include "soundtouch/SoundTouch.h"
|
||||
#include "Latency.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#ifdef XP_MACOSX
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
@ -254,6 +255,7 @@ AudioStream::AudioStream()
|
|||
, mState(INITIALIZED)
|
||||
, mNeedsStart(false)
|
||||
, mShouldDropFrames(false)
|
||||
, mPendingAudioInitTask(false)
|
||||
{
|
||||
// keep a ref in case we shut down later than nsLayoutStatics
|
||||
mLatencyLog = AsyncLatencyLogger::Get(true);
|
||||
|
@ -535,19 +537,24 @@ AudioStream::Init(int32_t aNumChannels, int32_t aRate,
|
|||
// cause us to move from INITIALIZED to RUNNING. Until then, we
|
||||
// can't access any cubeb functions.
|
||||
// Use a RefPtr to avoid leaks if Dispatch fails
|
||||
mPendingAudioInitTask = true;
|
||||
RefPtr<AudioInitTask> init = new AudioInitTask(this, aLatencyRequest, params);
|
||||
init->Dispatch();
|
||||
return NS_OK;
|
||||
nsresult rv = init->Dispatch();
|
||||
if (NS_FAILED(rv)) {
|
||||
mPendingAudioInitTask = false;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
// High latency - open synchronously
|
||||
nsresult rv = OpenCubeb(params, aLatencyRequest);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// See if we need to start() the stream, since we must do that from this
|
||||
// thread for now (cubeb API issue)
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
CheckForStart();
|
||||
}
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// On certain MacBookPro, the microphone is located near the left speaker.
|
||||
|
@ -627,15 +634,9 @@ nsresult
|
|||
AudioStream::OpenCubeb(cubeb_stream_params &aParams,
|
||||
LatencyRequest aLatencyRequest)
|
||||
{
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
if (mState == AudioStream::SHUTDOWN) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
cubeb* cubebContext = GetCubebContext();
|
||||
if (!cubebContext) {
|
||||
NS_WARNING("Can't get cubeb context!");
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
mState = AudioStream::ERRORED;
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -658,21 +659,15 @@ AudioStream::OpenCubeb(cubeb_stream_params &aParams,
|
|||
if (cubeb_stream_init(cubebContext, &stream, "AudioStream", aParams,
|
||||
latency, DataCallback_S, StateCallback_S, this) == CUBEB_OK) {
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
MOZ_ASSERT(mState != SHUTDOWN);
|
||||
mCubebStream.own(stream);
|
||||
// Make sure we weren't shut down while in flight!
|
||||
if (mState == SHUTDOWN) {
|
||||
mCubebStream.reset();
|
||||
LOG(("AudioStream::OpenCubeb() %p Shutdown while opening cubeb", this));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// We can't cubeb_stream_start() the thread from a transient thread due to
|
||||
// cubeb API requirements (init can be called from another thread, but
|
||||
// not start/stop/destroy/etc)
|
||||
} else {
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
mState = ERRORED;
|
||||
LOG(("AudioStream::OpenCubeb() %p failed to init cubeb", this));
|
||||
NS_WARNING(nsPrintfCString("AudioStream::OpenCubeb() %p failed to init cubeb", this).get());
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
@ -693,6 +688,14 @@ AudioStream::OpenCubeb(cubeb_stream_params &aParams,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
AudioStream::AudioInitTaskFinished()
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
mPendingAudioInitTask = false;
|
||||
mon.NotifyAll();
|
||||
}
|
||||
|
||||
void
|
||||
AudioStream::CheckForStart()
|
||||
{
|
||||
|
@ -731,6 +734,7 @@ AudioInitTask::Run()
|
|||
}
|
||||
|
||||
nsresult rv = mAudioStream->OpenCubeb(mParams, mLatencyRequest);
|
||||
mAudioStream->AudioInitTaskFinished();
|
||||
|
||||
// and now kill this thread
|
||||
NS_DispatchToMainThread(this);
|
||||
|
@ -951,6 +955,10 @@ AudioStream::Shutdown()
|
|||
MonitorAutoLock mon(mMonitor);
|
||||
LOG(("AudioStream: Shutdown %p, state %d", this, mState));
|
||||
|
||||
while (mPendingAudioInitTask) {
|
||||
mon.Wait();
|
||||
}
|
||||
|
||||
if (mCubebStream) {
|
||||
MonitorAutoUnlock mon(mMonitor);
|
||||
// Force stop to put the cubeb stream in a stable state before deletion.
|
||||
|
|
|
@ -299,6 +299,7 @@ private:
|
|||
// So we can call it asynchronously from AudioInitTask
|
||||
nsresult OpenCubeb(cubeb_stream_params &aParams,
|
||||
LatencyRequest aLatencyRequest);
|
||||
void AudioInitTaskFinished();
|
||||
|
||||
void CheckForStart();
|
||||
|
||||
|
@ -425,6 +426,9 @@ private:
|
|||
// is not going to be called for a little while, simply drop incoming frames.
|
||||
// This is only on OSX for now, because other systems handle this gracefully.
|
||||
bool mShouldDropFrames;
|
||||
// True if there is a pending AudioInitTask. Shutdown() will wait until the
|
||||
// pending AudioInitTask is finished.
|
||||
bool mPendingAudioInitTask;
|
||||
|
||||
// This mutex protects the static members below.
|
||||
static StaticMutex sMutex;
|
||||
|
|
|
@ -127,82 +127,6 @@ Crypto::Subtle()
|
|||
return mSubtle;
|
||||
}
|
||||
|
||||
#ifndef MOZ_DISABLE_CRYPTOLEGACY
|
||||
// Stub out the legacy nsIDOMCrypto methods. The actual
|
||||
// implementations are in security/manager/ssl/src/nsCrypto.{cpp,h}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Crypto::GetEnableSmartCardEvents(bool *aEnableSmartCardEvents)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Crypto::SetEnableSmartCardEvents(bool aEnableSmartCardEvents)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
bool
|
||||
Crypto::EnableSmartCardEvents()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
Crypto::SetEnableSmartCardEvents(bool aEnable, ErrorResult& aRv)
|
||||
{
|
||||
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
void
|
||||
Crypto::GetVersion(nsString& aVersion)
|
||||
{
|
||||
}
|
||||
|
||||
mozilla::dom::CRMFObject*
|
||||
Crypto::GenerateCRMFRequest(JSContext* aContext,
|
||||
const nsCString& aReqDN,
|
||||
const nsCString& aRegToken,
|
||||
const nsCString& aAuthenticator,
|
||||
const nsCString& aEaCert,
|
||||
const nsCString& aJsCallback,
|
||||
const Sequence<JS::Value>& aArgs,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
Crypto::ImportUserCertificates(const nsAString& aNickname,
|
||||
const nsAString& aCmmfResponse,
|
||||
bool aDoForcedBackup,
|
||||
nsAString& aReturn,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
void
|
||||
Crypto::SignText(JSContext* aContext,
|
||||
const nsAString& aStringToSign,
|
||||
const nsAString& aCaOption,
|
||||
const Sequence<nsCString>& aArgs,
|
||||
nsAString& aReturn)
|
||||
|
||||
{
|
||||
aReturn.AssignLiteral("error:internalError");
|
||||
}
|
||||
|
||||
void
|
||||
Crypto::Logout(ErrorResult& aRv)
|
||||
{
|
||||
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* static */ uint8_t*
|
||||
Crypto::GetRandomValues(uint32_t aLength)
|
||||
{
|
||||
|
|
|
@ -4,17 +4,7 @@
|
|||
#ifndef mozilla_dom_Crypto_h
|
||||
#define mozilla_dom_Crypto_h
|
||||
|
||||
#ifdef MOZ_DISABLE_CRYPTOLEGACY
|
||||
#include "nsIDOMCrypto.h"
|
||||
#else
|
||||
#include "nsIDOMCryptoLegacy.h"
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class CRMFObject;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "mozilla/dom/SubtleCrypto.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
|
@ -51,38 +41,6 @@ public:
|
|||
SubtleCrypto*
|
||||
Subtle();
|
||||
|
||||
#ifndef MOZ_DISABLE_CRYPTOLEGACY
|
||||
virtual bool EnableSmartCardEvents();
|
||||
virtual void SetEnableSmartCardEvents(bool aEnable, ErrorResult& aRv);
|
||||
|
||||
virtual void GetVersion(nsString& aVersion);
|
||||
|
||||
virtual mozilla::dom::CRMFObject*
|
||||
GenerateCRMFRequest(JSContext* aContext,
|
||||
const nsCString& aReqDN,
|
||||
const nsCString& aRegToken,
|
||||
const nsCString& aAuthenticator,
|
||||
const nsCString& aEaCert,
|
||||
const nsCString& aJsCallback,
|
||||
const Sequence<JS::Value>& aArgs,
|
||||
ErrorResult& aRv);
|
||||
|
||||
virtual void ImportUserCertificates(const nsAString& aNickname,
|
||||
const nsAString& aCmmfResponse,
|
||||
bool aDoForcedBackup,
|
||||
nsAString& aReturn,
|
||||
ErrorResult& aRv);
|
||||
|
||||
virtual void SignText(JSContext* aContext,
|
||||
const nsAString& aStringToSign,
|
||||
const nsAString& aCaOption,
|
||||
const Sequence<nsCString>& aArgs,
|
||||
nsAString& aReturn);
|
||||
|
||||
virtual void Logout(ErrorResult& aRv);
|
||||
|
||||
#endif
|
||||
|
||||
// WebIDL
|
||||
|
||||
nsPIDOMWindow*
|
||||
|
|
|
@ -83,9 +83,6 @@
|
|||
#include "nsIDocCharset.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "Crypto.h"
|
||||
#ifndef MOZ_DISABLE_CRYPTOLEGACY
|
||||
#include "nsIDOMCryptoLegacy.h"
|
||||
#endif
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
|
@ -2364,14 +2361,6 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
|
|||
|
||||
nsCOMPtr<nsIDocument> oldDoc = mDoc;
|
||||
|
||||
#ifndef MOZ_DISABLE_CRYPTOLEGACY
|
||||
// clear smartcard events, our document has gone away.
|
||||
if (mCrypto && XRE_GetProcessType() != GeckoProcessType_Content) {
|
||||
nsresult rv = mCrypto->SetEnableSmartCardEvents(false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
#endif
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init();
|
||||
JSContext *cx = jsapi.cx();
|
||||
|
@ -4459,20 +4448,7 @@ nsGlobalWindow::GetCrypto(ErrorResult& aError)
|
|||
FORWARD_TO_INNER_OR_THROW(GetCrypto, (aError), aError, nullptr);
|
||||
|
||||
if (!mCrypto) {
|
||||
#ifndef MOZ_DISABLE_CRYPTOLEGACY
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Content) {
|
||||
nsresult rv;
|
||||
mCrypto = do_CreateInstance(NS_CRYPTO_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
aError.Throw(rv);
|
||||
return nullptr;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
mCrypto = new Crypto();
|
||||
}
|
||||
|
||||
mCrypto = new Crypto();
|
||||
mCrypto->Init(this);
|
||||
}
|
||||
return mCrypto;
|
||||
|
|
|
@ -251,14 +251,7 @@ DOMInterfaces = {
|
|||
'headerFile': 'nsGeoPosition.h'
|
||||
},
|
||||
|
||||
'CRMFObject': {
|
||||
'headerFile': 'nsCrypto.h',
|
||||
'nativeOwnership': 'owned',
|
||||
'wrapperCache': False,
|
||||
},
|
||||
|
||||
'Crypto' : {
|
||||
'implicitJSContext': [ 'generateCRMFRequest', 'signText' ],
|
||||
'headerFile': 'Crypto.h'
|
||||
},
|
||||
|
||||
|
|
|
@ -146,6 +146,94 @@ enum BluetoothStatus {
|
|||
STATUS_RMT_DEV_DOWN
|
||||
};
|
||||
|
||||
enum BluetoothBondState {
|
||||
BOND_STATE_NONE,
|
||||
BOND_STATE_BONDING,
|
||||
BOND_STATE_BONDED
|
||||
};
|
||||
|
||||
enum BluetoothDeviceType {
|
||||
DEVICE_TYPE_BREDR,
|
||||
DEVICE_TYPE_BLE,
|
||||
DEVICE_TYPE_DUAL
|
||||
};
|
||||
|
||||
enum BluetoothPropertyType {
|
||||
PROPERTY_BDNAME,
|
||||
PROPERTY_BDADDR,
|
||||
PROPERTY_UUIDS,
|
||||
PROPERTY_CLASS_OF_DEVICE,
|
||||
PROPERTY_TYPE_OF_DEVICE,
|
||||
PROPERTY_SERVICE_RECORD,
|
||||
PROPERTY_ADAPTER_SCAN_MODE,
|
||||
PROPERTY_ADAPTER_BONDED_DEVICES,
|
||||
PROPERTY_ADAPTER_DISCOVERY_TIMEOUT,
|
||||
PROPERTY_REMOTE_FRIENDLY_NAME,
|
||||
PROPERTY_REMOTE_RSSI,
|
||||
PROPERTY_REMOTE_VERSION_INFO,
|
||||
PROPERTY_REMOTE_DEVICE_TIMESTAMP
|
||||
};
|
||||
|
||||
enum BluetoothScanMode {
|
||||
SCAN_MODE_NONE,
|
||||
SCAN_MODE_CONNECTABLE,
|
||||
SCAN_MODE_CONNECTABLE_DISCOVERABLE
|
||||
};
|
||||
|
||||
struct BluetoothUuid {
|
||||
uint8_t mUuid[16];
|
||||
};
|
||||
|
||||
struct BluetoothServiceRecord {
|
||||
BluetoothUuid mUuid;
|
||||
uint16_t mChannel;
|
||||
char mName[256];
|
||||
};
|
||||
|
||||
struct BluetoothRemoteInfo {
|
||||
int mVerMajor;
|
||||
int mVerMinor;
|
||||
int mManufacturer;
|
||||
};
|
||||
|
||||
struct BluetoothProperty {
|
||||
/* Type */
|
||||
BluetoothPropertyType mType;
|
||||
|
||||
/* Value
|
||||
*/
|
||||
|
||||
/* PROPERTY_BDNAME
|
||||
PROPERTY_BDADDR
|
||||
PROPERTY_REMOTE_FRIENDLY_NAME */
|
||||
nsString mString;
|
||||
|
||||
/* PROPERTY_UUIDS */
|
||||
nsTArray<BluetoothUuid> mUuidArray;
|
||||
|
||||
/* PROPERTY_ADAPTER_BONDED_DEVICES */
|
||||
nsTArray<nsString> mStringArray;
|
||||
|
||||
/* PROPERTY_CLASS_OF_DEVICE
|
||||
PROPERTY_ADAPTER_DISCOVERY_TIMEOUT */
|
||||
uint32_t mUint32;
|
||||
|
||||
/* PROPERTY_RSSI_VALUE */
|
||||
int32_t mInt32;
|
||||
|
||||
/* PROPERTY_DEVICE_TYPE */
|
||||
BluetoothDeviceType mDeviceType;
|
||||
|
||||
/* PROPERTY_SERVICE_RECORD */
|
||||
BluetoothServiceRecord mServiceRecord;
|
||||
|
||||
/* PROPERTY_SCAN_MODE */
|
||||
BluetoothScanMode mScanMode;
|
||||
|
||||
/* PROPERTY_REMOTE_VERSION_INFO */
|
||||
BluetoothRemoteInfo mRemoteInfo;
|
||||
};
|
||||
|
||||
enum BluetoothSocketType {
|
||||
RFCOMM = 1,
|
||||
SCO = 2,
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -326,6 +326,50 @@ private:
|
|||
// Bluetooth Core Interface
|
||||
//
|
||||
|
||||
class BluetoothNotificationHandler
|
||||
{
|
||||
public:
|
||||
virtual ~BluetoothNotificationHandler();
|
||||
|
||||
virtual void AdapterStateChangedNotification(bool aState) { }
|
||||
virtual void AdapterPropertiesNotification(
|
||||
BluetoothStatus aStatus, int aNumProperties,
|
||||
const BluetoothProperty* aProperties) { }
|
||||
|
||||
virtual void RemoteDevicePropertiesNotification(
|
||||
BluetoothStatus aStatus, const nsAString& aBdAddr,
|
||||
int aNumProperties, const BluetoothProperty* aProperties) { }
|
||||
|
||||
virtual void DeviceFoundNotification(
|
||||
int aNumProperties, const BluetoothProperty* aProperties) { }
|
||||
|
||||
virtual void DiscoveryStateChangedNotification(bool aState) { }
|
||||
|
||||
virtual void PinRequestNotification(const nsAString& aRemoteBdAddr,
|
||||
const nsAString& aBdName, uint32_t aCod) { }
|
||||
virtual void SspRequestNotification(const nsAString& aRemoteBdAddr,
|
||||
const nsAString& aBdName,
|
||||
uint32_t aCod,
|
||||
const nsAString& aPairingVariant,
|
||||
uint32_t aPassKey) { }
|
||||
|
||||
virtual void BondStateChangedNotification(BluetoothStatus aStatus,
|
||||
const nsAString& aRemoteBdAddr,
|
||||
BluetoothBondState aState) { }
|
||||
virtual void AclStateChangedNotification(BluetoothStatus aStatus,
|
||||
const nsAString& aRemoteBdAddr,
|
||||
bool aState) { }
|
||||
|
||||
virtual void DutModeRecvNotification(uint16_t aOpcode,
|
||||
const uint8_t* aBuf, uint8_t aLen) { }
|
||||
virtual void LeTestModeNotification(BluetoothStatus aStatus,
|
||||
uint16_t aNumPackets) { }
|
||||
|
||||
protected:
|
||||
BluetoothNotificationHandler()
|
||||
{ }
|
||||
};
|
||||
|
||||
class BluetoothResultHandler
|
||||
{
|
||||
public:
|
||||
|
@ -375,7 +419,8 @@ class BluetoothInterface
|
|||
public:
|
||||
static BluetoothInterface* GetInstance();
|
||||
|
||||
void Init(bt_callbacks_t* aCallbacks, BluetoothResultHandler* aRes);
|
||||
void Init(BluetoothNotificationHandler* aNotificationHandler,
|
||||
BluetoothResultHandler* aRes);
|
||||
void Cleanup(BluetoothResultHandler* aRes);
|
||||
|
||||
void Enable(BluetoothResultHandler* aRes);
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "BluetoothA2dpManager.h"
|
||||
#include "BluetoothHfpManager.h"
|
||||
#include "BluetoothOppManager.h"
|
||||
#include "BluetoothInterface.h"
|
||||
#include "BluetoothProfileController.h"
|
||||
#include "BluetoothReplyRunnable.h"
|
||||
#include "BluetoothUtils.h"
|
||||
|
@ -41,7 +40,6 @@
|
|||
} \
|
||||
} while(0)
|
||||
|
||||
#define MAX_UUID_SIZE 16
|
||||
// Audio: Major service class = 0x100 (Bit 21 is set)
|
||||
#define SET_AUDIO_BIT(cod) (cod |= 0x200000)
|
||||
// Rendering: Major service class = 0x20 (Bit 18 is set)
|
||||
|
@ -51,12 +49,9 @@ using namespace mozilla;
|
|||
using namespace mozilla::ipc;
|
||||
USING_BLUETOOTH_NAMESPACE
|
||||
|
||||
// TODO: Non thread-safe static variables
|
||||
static nsString sAdapterBdAddress;
|
||||
static nsString sAdapterBdName;
|
||||
static InfallibleTArray<nsString> sAdapterBondedAddressArray;
|
||||
|
||||
// Static variables below should only be used on *main thread*
|
||||
static BluetoothInterface* sBtInterface;
|
||||
static nsTArray<nsRefPtr<BluetoothProfileController> > sControllerArray;
|
||||
static InfallibleTArray<BluetoothNamedValue> sRemoteDevicesPack;
|
||||
|
@ -65,41 +60,12 @@ static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sSetPropertyRunnableArray;
|
|||
static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sGetDeviceRunnableArray;
|
||||
static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sBondingRunnableArray;
|
||||
static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sUnbondingRunnableArray;
|
||||
|
||||
// Static variables below should only be used on *callback thread*
|
||||
|
||||
|
||||
// Atomic static variables
|
||||
static Atomic<bool> sAdapterDiscoverable(false);
|
||||
static Atomic<uint32_t> sAdapterDiscoverableTimeout(0);
|
||||
static bool sAdapterDiscoverable(false);
|
||||
static uint32_t sAdapterDiscoverableTimeout(0);
|
||||
|
||||
/**
|
||||
* Classes only used in this file
|
||||
*/
|
||||
class DistributeBluetoothSignalTask MOZ_FINAL : public nsRunnable
|
||||
{
|
||||
public:
|
||||
DistributeBluetoothSignalTask(const BluetoothSignal& aSignal) :
|
||||
mSignal(aSignal)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
|
||||
|
||||
bs->DistributeSignal(mSignal);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
BluetoothSignal mSignal;
|
||||
};
|
||||
|
||||
class SetupAfterEnabledTask MOZ_FINAL : public nsRunnable
|
||||
{
|
||||
|
@ -327,509 +293,6 @@ PlayStatusStringToControlPlayStatus(const nsAString& aPlayStatus)
|
|||
return playStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bluedroid HAL callback functions
|
||||
*
|
||||
* Several callbacks are dispatched to main thread to avoid racing issues.
|
||||
*/
|
||||
static void
|
||||
AdapterStateChangeCallback(bt_state_t aStatus)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
BT_LOGR("BT_STATE: %d", aStatus);
|
||||
|
||||
bool isBtEnabled = (aStatus == BT_STATE_ON);
|
||||
|
||||
if (!isBtEnabled &&
|
||||
NS_FAILED(NS_DispatchToMainThread(new CleanupTask()))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<nsRunnable> runnable =
|
||||
new BluetoothService::ToggleBtAck(isBtEnabled);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (isBtEnabled &&
|
||||
NS_FAILED(NS_DispatchToMainThread(new SetupAfterEnabledTask()))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
class AdapterPropertiesCallbackTask MOZ_FINAL : public nsRunnable
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD
|
||||
Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!sSetPropertyRunnableArray.IsEmpty()) {
|
||||
DispatchBluetoothReply(sSetPropertyRunnableArray[0],
|
||||
BluetoothValue(true), EmptyString());
|
||||
sSetPropertyRunnableArray.RemoveElementAt(0);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* AdapterPropertiesCallback will be called after enable() but before
|
||||
* AdapterStateChangeCallback is called. At that moment, both
|
||||
* BluetoothManager/BluetoothAdapter does not register observer yet.
|
||||
*/
|
||||
static void
|
||||
AdapterPropertiesCallback(bt_status_t aStatus, int aNumProperties,
|
||||
bt_property_t *aProperties)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
BluetoothValue propertyValue;
|
||||
InfallibleTArray<BluetoothNamedValue> props;
|
||||
|
||||
for (int i = 0; i < aNumProperties; i++) {
|
||||
bt_property_t p;
|
||||
// See Bug 989976, consider aProperties address is not aligned
|
||||
memcpy(&p, &aProperties[i], sizeof(p));
|
||||
|
||||
if (p.type == BT_PROPERTY_BDADDR) {
|
||||
BdAddressTypeToString((bt_bdaddr_t*)p.val, sAdapterBdAddress);
|
||||
propertyValue = sAdapterBdAddress;
|
||||
BT_APPEND_NAMED_VALUE(props, "Address", propertyValue);
|
||||
} else if (p.type == BT_PROPERTY_BDNAME) {
|
||||
// Construct nsCString here because Bd name returned from bluedroid
|
||||
// is missing a null terminated character after SetProperty.
|
||||
propertyValue = sAdapterBdName = NS_ConvertUTF8toUTF16(
|
||||
nsCString((char*)p.val, p.len));
|
||||
BT_APPEND_NAMED_VALUE(props, "Name", propertyValue);
|
||||
} else if (p.type == BT_PROPERTY_ADAPTER_SCAN_MODE) {
|
||||
bt_scan_mode_t newMode = *(bt_scan_mode_t*)p.val;
|
||||
|
||||
if (newMode == BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
|
||||
propertyValue = sAdapterDiscoverable = true;
|
||||
} else {
|
||||
propertyValue = sAdapterDiscoverable = false;
|
||||
}
|
||||
|
||||
BT_APPEND_NAMED_VALUE(props, "Discoverable", propertyValue);
|
||||
} else if (p.type == BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT) {
|
||||
propertyValue = sAdapterDiscoverableTimeout = *(uint32_t*)p.val;
|
||||
BT_APPEND_NAMED_VALUE(props, "DiscoverableTimeout", propertyValue);
|
||||
} else if (p.type == BT_PROPERTY_ADAPTER_BONDED_DEVICES) {
|
||||
// We have to cache addresses of bonded devices. Unlike BlueZ,
|
||||
// bluedroid would not send an another BT_PROPERTY_ADAPTER_BONDED_DEVICES
|
||||
// event after bond completed
|
||||
bt_bdaddr_t* deviceBdAddressTypes = (bt_bdaddr_t*)p.val;
|
||||
int numOfAddresses = p.len / BLUETOOTH_ADDRESS_BYTES;
|
||||
BT_LOGD("Adapter property: BONDED_DEVICES. Count: %d", numOfAddresses);
|
||||
|
||||
// Whenever reloading paired devices, force refresh
|
||||
sAdapterBondedAddressArray.Clear();
|
||||
|
||||
for (int index = 0; index < numOfAddresses; index++) {
|
||||
nsAutoString deviceBdAddress;
|
||||
BdAddressTypeToString(deviceBdAddressTypes + index, deviceBdAddress);
|
||||
sAdapterBondedAddressArray.AppendElement(deviceBdAddress);
|
||||
}
|
||||
|
||||
propertyValue = sAdapterBondedAddressArray;
|
||||
BT_APPEND_NAMED_VALUE(props, "Devices", propertyValue);
|
||||
} else if (p.type == BT_PROPERTY_UUIDS) {
|
||||
//FIXME: This will be implemented in the later patchset
|
||||
continue;
|
||||
} else {
|
||||
BT_LOGD("Unhandled adapter property type: %d", p.type);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE_VOID(props.Length() > 0);
|
||||
|
||||
BluetoothValue value(props);
|
||||
BluetoothSignal signal(NS_LITERAL_STRING("PropertyChanged"),
|
||||
NS_LITERAL_STRING(KEY_ADAPTER), value);
|
||||
nsRefPtr<DistributeBluetoothSignalTask>
|
||||
t = new DistributeBluetoothSignalTask(signal);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(t))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
}
|
||||
|
||||
// Redirect to main thread to avoid racing problem
|
||||
NS_DispatchToMainThread(new AdapterPropertiesCallbackTask());
|
||||
}
|
||||
|
||||
class RemoteDevicePropertiesCallbackTask : public nsRunnable
|
||||
{
|
||||
const InfallibleTArray<BluetoothNamedValue> mProps;
|
||||
nsString mRemoteDeviceBdAddress;
|
||||
public:
|
||||
RemoteDevicePropertiesCallbackTask(
|
||||
const InfallibleTArray<BluetoothNamedValue>& aProps,
|
||||
const nsAString& aRemoteDeviceBdAddress)
|
||||
: mProps(aProps)
|
||||
, mRemoteDeviceBdAddress(aRemoteDeviceBdAddress)
|
||||
{ }
|
||||
|
||||
NS_IMETHOD
|
||||
Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (sRequestedDeviceCountArray.IsEmpty()) {
|
||||
// This is possible because the callback would be called after turning
|
||||
// Bluetooth on.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Update to registered BluetoothDevice objects
|
||||
BluetoothSignal signal(NS_LITERAL_STRING("PropertyChanged"),
|
||||
mRemoteDeviceBdAddress, mProps);
|
||||
nsRefPtr<DistributeBluetoothSignalTask>
|
||||
t = new DistributeBluetoothSignalTask(signal);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(t))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Use address as the index
|
||||
sRemoteDevicesPack.AppendElement(
|
||||
BluetoothNamedValue(mRemoteDeviceBdAddress, mProps));
|
||||
|
||||
if (--sRequestedDeviceCountArray[0] == 0) {
|
||||
if (!sGetDeviceRunnableArray.IsEmpty()) {
|
||||
DispatchBluetoothReply(sGetDeviceRunnableArray[0],
|
||||
sRemoteDevicesPack, EmptyString());
|
||||
sGetDeviceRunnableArray.RemoveElementAt(0);
|
||||
}
|
||||
|
||||
sRequestedDeviceCountArray.RemoveElementAt(0);
|
||||
sRemoteDevicesPack.Clear();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* RemoteDevicePropertiesCallback will be called, as the following conditions:
|
||||
* 1. When BT is turning on, bluedroid automatically execute this callback
|
||||
* 2. When get_remote_device_properties()
|
||||
*/
|
||||
static void
|
||||
RemoteDevicePropertiesCallback(bt_status_t aStatus, bt_bdaddr_t *aBdAddress,
|
||||
int aNumProperties, bt_property_t *aProperties)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
InfallibleTArray<BluetoothNamedValue> props;
|
||||
|
||||
nsString remoteDeviceBdAddress;
|
||||
BdAddressTypeToString(aBdAddress, remoteDeviceBdAddress);
|
||||
BT_APPEND_NAMED_VALUE(props, "Address", remoteDeviceBdAddress);
|
||||
|
||||
bool isCodInvalid = false;
|
||||
for (int i = 0; i < aNumProperties; ++i) {
|
||||
bt_property_t p = aProperties[i];
|
||||
|
||||
if (p.type == BT_PROPERTY_BDNAME) {
|
||||
BluetoothValue propertyValue = NS_ConvertUTF8toUTF16((char*)p.val);
|
||||
BT_APPEND_NAMED_VALUE(props, "Name", propertyValue);
|
||||
} else if (p.type == BT_PROPERTY_CLASS_OF_DEVICE) {
|
||||
uint32_t cod = *(uint32_t*)p.val;
|
||||
nsString icon;
|
||||
ClassToIcon(cod, icon);
|
||||
if (!icon.IsEmpty()) {
|
||||
// Valid CoD
|
||||
BT_APPEND_NAMED_VALUE(props, "Class", cod);
|
||||
BT_APPEND_NAMED_VALUE(props, "Icon", icon);
|
||||
} else {
|
||||
// If Cod is invalid, fallback to check UUIDs. It usually happens due to
|
||||
// NFC directly trigger pairing. bluedroid sends wrong CoD due to missing
|
||||
// EIR query records.
|
||||
isCodInvalid = true;
|
||||
}
|
||||
} else if (p.type == BT_PROPERTY_UUIDS) {
|
||||
InfallibleTArray<nsString> uuidsArray;
|
||||
int uuidListLength = p.len / MAX_UUID_SIZE;
|
||||
uint32_t cod = 0;
|
||||
|
||||
for (int i = 0; i < uuidListLength; i++) {
|
||||
uint16_t uuidServiceClass = UuidToServiceClassInt((bt_uuid_t*)(p.val +
|
||||
(i * MAX_UUID_SIZE)));
|
||||
BluetoothServiceClass serviceClass = BluetoothUuidHelper::
|
||||
GetBluetoothServiceClass(uuidServiceClass);
|
||||
|
||||
// Get Uuid string from BluetoothServiceClass
|
||||
nsString uuid;
|
||||
BluetoothUuidHelper::GetString(serviceClass, uuid);
|
||||
uuidsArray.AppendElement(uuid);
|
||||
|
||||
// Restore CoD value
|
||||
if (isCodInvalid) {
|
||||
if (serviceClass == BluetoothServiceClass::HANDSFREE ||
|
||||
serviceClass == BluetoothServiceClass::HEADSET) {
|
||||
BT_LOGD("Restore Class Of Device to Audio bit");
|
||||
SET_AUDIO_BIT(cod);
|
||||
} else if (serviceClass == BluetoothServiceClass::A2DP_SINK) {
|
||||
BT_LOGD("Restore Class of Device to Rendering bit");
|
||||
SET_RENDERING_BIT(cod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isCodInvalid) {
|
||||
BT_APPEND_NAMED_VALUE(props, "Class", cod);
|
||||
// 'audio-card' refers to 'Audio' device
|
||||
BT_APPEND_NAMED_VALUE(props, "Icon", NS_LITERAL_STRING("audio-card"));
|
||||
}
|
||||
BT_APPEND_NAMED_VALUE(props, "UUIDS", uuidsArray);
|
||||
} else {
|
||||
BT_LOGD("Other non-handled device properties. Type: %d", p.type);
|
||||
}
|
||||
}
|
||||
|
||||
// Redirect to main thread to avoid racing problem
|
||||
NS_DispatchToMainThread(
|
||||
new RemoteDevicePropertiesCallbackTask(props, remoteDeviceBdAddress));
|
||||
}
|
||||
|
||||
static void
|
||||
DeviceFoundCallback(int aNumProperties, bt_property_t *aProperties)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
BluetoothValue propertyValue;
|
||||
InfallibleTArray<BluetoothNamedValue> propertiesArray;
|
||||
|
||||
for (int i = 0; i < aNumProperties; i++) {
|
||||
bt_property_t p = aProperties[i];
|
||||
|
||||
if (p.type == BT_PROPERTY_BDADDR) {
|
||||
nsString remoteDeviceBdAddress;
|
||||
BdAddressTypeToString((bt_bdaddr_t*)p.val, remoteDeviceBdAddress);
|
||||
propertyValue = remoteDeviceBdAddress;
|
||||
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "Address", propertyValue);
|
||||
} else if (p.type == BT_PROPERTY_BDNAME) {
|
||||
propertyValue = NS_ConvertUTF8toUTF16((char*)p.val);
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "Name", propertyValue);
|
||||
} else if (p.type == BT_PROPERTY_CLASS_OF_DEVICE) {
|
||||
uint32_t cod = *(uint32_t*)p.val;
|
||||
propertyValue = cod;
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "Class", propertyValue);
|
||||
|
||||
nsString icon;
|
||||
ClassToIcon(cod, icon);
|
||||
propertyValue = icon;
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "Icon", propertyValue);
|
||||
} else {
|
||||
BT_LOGD("Not handled remote device property: %d", p.type);
|
||||
}
|
||||
}
|
||||
|
||||
BluetoothValue value = propertiesArray;
|
||||
BluetoothSignal signal(NS_LITERAL_STRING("DeviceFound"),
|
||||
NS_LITERAL_STRING(KEY_ADAPTER), value);
|
||||
nsRefPtr<DistributeBluetoothSignalTask>
|
||||
t = new DistributeBluetoothSignalTask(signal);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(t))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
DiscoveryStateChangedCallback(bt_discovery_state_t aState)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
bool isDiscovering = (aState == BT_DISCOVERY_STARTED);
|
||||
BluetoothSignal signal(NS_LITERAL_STRING(DISCOVERY_STATE_CHANGED_ID),
|
||||
NS_LITERAL_STRING(KEY_ADAPTER), isDiscovering);
|
||||
|
||||
nsRefPtr<DistributeBluetoothSignalTask> t =
|
||||
new DistributeBluetoothSignalTask(signal);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(t))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
PinRequestCallback(bt_bdaddr_t* aRemoteBdAddress,
|
||||
bt_bdname_t* aRemoteBdName, uint32_t aRemoteClass)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
InfallibleTArray<BluetoothNamedValue> propertiesArray;
|
||||
nsAutoString remoteAddress;
|
||||
BdAddressTypeToString(aRemoteBdAddress, remoteAddress);
|
||||
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "address", remoteAddress);
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "method",
|
||||
NS_LITERAL_STRING("pincode"));
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "name",
|
||||
NS_ConvertUTF8toUTF16(
|
||||
(const char*)aRemoteBdName->name));
|
||||
|
||||
BluetoothValue value = propertiesArray;
|
||||
BluetoothSignal signal(NS_LITERAL_STRING("RequestPinCode"),
|
||||
NS_LITERAL_STRING(KEY_LOCAL_AGENT), value);
|
||||
nsRefPtr<DistributeBluetoothSignalTask>
|
||||
t = new DistributeBluetoothSignalTask(signal);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(t))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SspRequestCallback(bt_bdaddr_t* aRemoteBdAddress, bt_bdname_t* aRemoteBdName,
|
||||
uint32_t aRemoteClass, bt_ssp_variant_t aPairingVariant,
|
||||
uint32_t aPasskey)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
InfallibleTArray<BluetoothNamedValue> propertiesArray;
|
||||
nsAutoString remoteAddress;
|
||||
BdAddressTypeToString(aRemoteBdAddress, remoteAddress);
|
||||
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "address", remoteAddress);
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "method",
|
||||
NS_LITERAL_STRING("confirmation"));
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "name",
|
||||
NS_ConvertUTF8toUTF16(
|
||||
(const char*)aRemoteBdName->name));
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "passkey", aPasskey);
|
||||
|
||||
BluetoothValue value = propertiesArray;
|
||||
BluetoothSignal signal(NS_LITERAL_STRING("RequestConfirmation"),
|
||||
NS_LITERAL_STRING(KEY_LOCAL_AGENT), value);
|
||||
nsRefPtr<DistributeBluetoothSignalTask>
|
||||
t = new DistributeBluetoothSignalTask(signal);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(t))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
}
|
||||
}
|
||||
|
||||
class BondStateChangedCallbackTask : public nsRunnable
|
||||
{
|
||||
nsString mRemoteDeviceBdAddress;
|
||||
bool mBonded;
|
||||
public:
|
||||
BondStateChangedCallbackTask(const nsAString& aRemoteDeviceBdAddress,
|
||||
bool aBonded)
|
||||
: mRemoteDeviceBdAddress(aRemoteDeviceBdAddress)
|
||||
, mBonded(aBonded)
|
||||
{ }
|
||||
|
||||
NS_IMETHOD
|
||||
Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mBonded && !sBondingRunnableArray.IsEmpty()) {
|
||||
DispatchBluetoothReply(sBondingRunnableArray[0],
|
||||
BluetoothValue(true), EmptyString());
|
||||
|
||||
sBondingRunnableArray.RemoveElementAt(0);
|
||||
} else if (!mBonded && !sUnbondingRunnableArray.IsEmpty()) {
|
||||
DispatchBluetoothReply(sUnbondingRunnableArray[0],
|
||||
BluetoothValue(true), EmptyString());
|
||||
|
||||
sUnbondingRunnableArray.RemoveElementAt(0);
|
||||
}
|
||||
|
||||
// Update bonding status to gaia
|
||||
InfallibleTArray<BluetoothNamedValue> propertiesArray;
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "address", mRemoteDeviceBdAddress);
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "status", mBonded);
|
||||
|
||||
BluetoothSignal signal(NS_LITERAL_STRING(PAIRED_STATUS_CHANGED_ID),
|
||||
NS_LITERAL_STRING(KEY_ADAPTER),
|
||||
BluetoothValue(propertiesArray));
|
||||
NS_DispatchToMainThread(new DistributeBluetoothSignalTask(signal));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
static void
|
||||
BondStateChangedCallback(bt_status_t aStatus, bt_bdaddr_t* aRemoteBdAddress,
|
||||
bt_bond_state_t aState)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
if (aState == BT_BOND_STATE_BONDING) {
|
||||
// No need to handle bonding state
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoString remoteBdAddress;
|
||||
BdAddressTypeToString(aRemoteBdAddress, remoteBdAddress);
|
||||
|
||||
if (aState == BT_BOND_STATE_BONDED &&
|
||||
sAdapterBondedAddressArray.Contains(remoteBdAddress)) {
|
||||
// See bug 940271 for more details about this case.
|
||||
return;
|
||||
}
|
||||
|
||||
bool bonded;
|
||||
if (aState == BT_BOND_STATE_NONE) {
|
||||
bonded = false;
|
||||
sAdapterBondedAddressArray.RemoveElement(remoteBdAddress);
|
||||
} else if (aState == BT_BOND_STATE_BONDED) {
|
||||
bonded = true;
|
||||
sAdapterBondedAddressArray.AppendElement(remoteBdAddress);
|
||||
}
|
||||
|
||||
// Update bonded address list to BluetoothAdapter
|
||||
InfallibleTArray<BluetoothNamedValue> propertiesChangeArray;
|
||||
BT_APPEND_NAMED_VALUE(propertiesChangeArray, "Devices",
|
||||
sAdapterBondedAddressArray);
|
||||
|
||||
BluetoothValue value(propertiesChangeArray);
|
||||
BluetoothSignal signal(NS_LITERAL_STRING("PropertyChanged"),
|
||||
NS_LITERAL_STRING(KEY_ADAPTER),
|
||||
BluetoothValue(propertiesChangeArray));
|
||||
NS_DispatchToMainThread(new DistributeBluetoothSignalTask(signal));
|
||||
|
||||
// Redirect to main thread to avoid racing problem
|
||||
NS_DispatchToMainThread(
|
||||
new BondStateChangedCallbackTask(remoteBdAddress, bonded));
|
||||
}
|
||||
|
||||
static void
|
||||
AclStateChangedCallback(bt_status_t aStatus, bt_bdaddr_t* aRemoteBdAddress,
|
||||
bt_acl_state_t aState)
|
||||
{
|
||||
//FIXME: This will be implemented in the later patchset
|
||||
}
|
||||
|
||||
static void
|
||||
CallbackThreadEvent(bt_cb_thread_evt evt)
|
||||
{
|
||||
//FIXME: This will be implemented in the later patchset
|
||||
}
|
||||
|
||||
bt_callbacks_t sBluetoothCallbacks =
|
||||
{
|
||||
sizeof(sBluetoothCallbacks),
|
||||
AdapterStateChangeCallback,
|
||||
AdapterPropertiesCallback,
|
||||
RemoteDevicePropertiesCallback,
|
||||
DeviceFoundCallback,
|
||||
DiscoveryStateChangedCallback,
|
||||
PinRequestCallback,
|
||||
SspRequestCallback,
|
||||
BondStateChangedCallback,
|
||||
AclStateChangedCallback,
|
||||
CallbackThreadEvent
|
||||
};
|
||||
|
||||
/**
|
||||
* Static functions
|
||||
*/
|
||||
|
@ -952,7 +415,8 @@ StartGonkBluetooth()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
sBtInterface->Init(&sBluetoothCallbacks, new InitResultHandler());
|
||||
sBtInterface->Init(reinterpret_cast<BluetoothServiceBluedroid*>(bs),
|
||||
new InitResultHandler());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1750,3 +1214,402 @@ BluetoothServiceBluedroid::ToggleCalls(BluetoothReplyRunnable* aRunnable)
|
|||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Bluetooth notifications
|
||||
//
|
||||
|
||||
void
|
||||
BluetoothServiceBluedroid::AdapterStateChangedNotification(bool aState)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
BT_LOGR("BT_STATE: %d", aState);
|
||||
|
||||
bool isBtEnabled = (aState == true);
|
||||
|
||||
if (!isBtEnabled &&
|
||||
NS_FAILED(NS_DispatchToMainThread(new CleanupTask()))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<nsRunnable> runnable =
|
||||
new BluetoothService::ToggleBtAck(isBtEnabled);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (isBtEnabled &&
|
||||
NS_FAILED(NS_DispatchToMainThread(new SetupAfterEnabledTask()))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AdapterPropertiesNotification will be called after enable() but
|
||||
* before AdapterStateChangeCallback is called. At that moment, both
|
||||
* BluetoothManager and BluetoothAdapter, do not register observer
|
||||
* yet.
|
||||
*/
|
||||
void
|
||||
BluetoothServiceBluedroid::AdapterPropertiesNotification(
|
||||
BluetoothStatus aStatus, int aNumProperties,
|
||||
const BluetoothProperty* aProperties)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
BluetoothValue propertyValue;
|
||||
InfallibleTArray<BluetoothNamedValue> props;
|
||||
|
||||
for (int i = 0; i < aNumProperties; i++) {
|
||||
|
||||
const BluetoothProperty& p = aProperties[i];
|
||||
|
||||
if (p.mType == PROPERTY_BDADDR) {
|
||||
sAdapterBdAddress = p.mString;
|
||||
propertyValue = sAdapterBdAddress;
|
||||
BT_APPEND_NAMED_VALUE(props, "Address", propertyValue);
|
||||
|
||||
} else if (p.mType == PROPERTY_BDNAME) {
|
||||
sAdapterBdName = p.mString;
|
||||
propertyValue = sAdapterBdName;
|
||||
BT_APPEND_NAMED_VALUE(props, "Name", propertyValue);
|
||||
|
||||
} else if (p.mType == PROPERTY_ADAPTER_SCAN_MODE) {
|
||||
BluetoothScanMode newMode = p.mScanMode;
|
||||
|
||||
if (newMode == SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
|
||||
propertyValue = sAdapterDiscoverable = true;
|
||||
} else {
|
||||
propertyValue = sAdapterDiscoverable = false;
|
||||
}
|
||||
|
||||
BT_APPEND_NAMED_VALUE(props, "Discoverable", propertyValue);
|
||||
|
||||
} else if (p.mType == PROPERTY_ADAPTER_DISCOVERY_TIMEOUT) {
|
||||
propertyValue = sAdapterDiscoverableTimeout = p.mUint32;
|
||||
BT_APPEND_NAMED_VALUE(props, "DiscoverableTimeout", propertyValue);
|
||||
|
||||
} else if (p.mType == PROPERTY_ADAPTER_BONDED_DEVICES) {
|
||||
// We have to cache addresses of bonded devices. Unlike BlueZ,
|
||||
// Bluedroid would not send another PROPERTY_ADAPTER_BONDED_DEVICES
|
||||
// event after bond completed.
|
||||
BT_LOGD("Adapter property: BONDED_DEVICES. Count: %d",
|
||||
p.mStringArray.Length());
|
||||
|
||||
// Whenever reloading paired devices, force refresh
|
||||
sAdapterBondedAddressArray.Clear();
|
||||
|
||||
for (size_t index = 0; index < p.mStringArray.Length(); index++) {
|
||||
sAdapterBondedAddressArray.AppendElement(p.mStringArray[index]);
|
||||
}
|
||||
|
||||
propertyValue = sAdapterBondedAddressArray;
|
||||
BT_APPEND_NAMED_VALUE(props, "Devices", propertyValue);
|
||||
|
||||
} else if (p.mType == PROPERTY_UUIDS) {
|
||||
//FIXME: This will be implemented in the later patchset
|
||||
continue;
|
||||
} else {
|
||||
BT_LOGD("Unhandled adapter property type: %d", p.mType);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE_VOID(props.Length() > 0);
|
||||
|
||||
DistributeSignal(BluetoothSignal(NS_LITERAL_STRING("PropertyChanged"),
|
||||
NS_LITERAL_STRING(KEY_ADAPTER),
|
||||
BluetoothValue(props)));
|
||||
|
||||
// Send reply for SetProperty
|
||||
|
||||
if (!sSetPropertyRunnableArray.IsEmpty()) {
|
||||
DispatchBluetoothReply(sSetPropertyRunnableArray[0],
|
||||
BluetoothValue(true), EmptyString());
|
||||
sSetPropertyRunnableArray.RemoveElementAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* RemoteDevicePropertiesNotification will be called
|
||||
*
|
||||
* (1) automatically by Bluedroid when BT is turning on, or
|
||||
* (2) as result of GetRemoteDeviceProperties.
|
||||
*/
|
||||
void
|
||||
BluetoothServiceBluedroid::RemoteDevicePropertiesNotification(
|
||||
BluetoothStatus aStatus, const nsAString& aBdAddr,
|
||||
int aNumProperties, const BluetoothProperty* aProperties)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
InfallibleTArray<BluetoothNamedValue> props;
|
||||
|
||||
BT_APPEND_NAMED_VALUE(props, "Address", BluetoothValue(nsString(aBdAddr)));
|
||||
|
||||
bool isCodInvalid = false;
|
||||
for (int i = 0; i < aNumProperties; ++i) {
|
||||
|
||||
const BluetoothProperty& p = aProperties[i];
|
||||
|
||||
if (p.mType == PROPERTY_BDNAME) {
|
||||
BT_APPEND_NAMED_VALUE(props, "Name", p.mString);
|
||||
} else if (p.mType == PROPERTY_CLASS_OF_DEVICE) {
|
||||
uint32_t cod = p.mUint32;
|
||||
nsString icon;
|
||||
ClassToIcon(cod, icon);
|
||||
if (!icon.IsEmpty()) {
|
||||
// Valid CoD
|
||||
BT_APPEND_NAMED_VALUE(props, "Class", cod);
|
||||
BT_APPEND_NAMED_VALUE(props, "Icon", icon);
|
||||
} else {
|
||||
// If Cod is invalid, fallback to check UUIDs. It usually happens due to
|
||||
// NFC directly trigger pairing. bluedroid sends wrong CoD due to missing
|
||||
// EIR query records.
|
||||
isCodInvalid = true;
|
||||
}
|
||||
} else if (p.mType == PROPERTY_UUIDS) {
|
||||
InfallibleTArray<nsString> uuidsArray;
|
||||
uint32_t cod = 0;
|
||||
|
||||
for (size_t i = 0; i < p.mUuidArray.Length(); i++) {
|
||||
uint16_t uuidServiceClass = UuidToServiceClassInt(p.mUuidArray[i]);
|
||||
BluetoothServiceClass serviceClass =
|
||||
BluetoothUuidHelper::GetBluetoothServiceClass(uuidServiceClass);
|
||||
|
||||
// Get Uuid string from BluetoothServiceClass
|
||||
nsString uuid;
|
||||
BluetoothUuidHelper::GetString(serviceClass, uuid);
|
||||
uuidsArray.AppendElement(uuid);
|
||||
|
||||
// Restore CoD value
|
||||
if (isCodInvalid) {
|
||||
if (serviceClass == BluetoothServiceClass::HANDSFREE ||
|
||||
serviceClass == BluetoothServiceClass::HEADSET) {
|
||||
BT_LOGD("Restore Class Of Device to Audio bit");
|
||||
SET_AUDIO_BIT(cod);
|
||||
} else if (serviceClass == BluetoothServiceClass::A2DP_SINK) {
|
||||
BT_LOGD("Restore Class of Device to Rendering bit");
|
||||
SET_RENDERING_BIT(cod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isCodInvalid) {
|
||||
BT_APPEND_NAMED_VALUE(props, "Class", cod);
|
||||
// 'audio-card' refers to 'Audio' device
|
||||
BT_APPEND_NAMED_VALUE(props, "Icon", NS_LITERAL_STRING("audio-card"));
|
||||
}
|
||||
BT_APPEND_NAMED_VALUE(props, "UUIDS", uuidsArray);
|
||||
} else {
|
||||
BT_LOGD("Other non-handled device properties. Type: %d", p.mType);
|
||||
}
|
||||
}
|
||||
|
||||
if (sRequestedDeviceCountArray.IsEmpty()) {
|
||||
// This is possible because the callback would be called after turning
|
||||
// Bluetooth on.
|
||||
return;
|
||||
}
|
||||
|
||||
// Use address as the index
|
||||
sRemoteDevicesPack.AppendElement(
|
||||
BluetoothNamedValue(nsString(aBdAddr), props));
|
||||
|
||||
if (--sRequestedDeviceCountArray[0] == 0) {
|
||||
if (!sGetDeviceRunnableArray.IsEmpty()) {
|
||||
DispatchBluetoothReply(sGetDeviceRunnableArray[0],
|
||||
sRemoteDevicesPack, EmptyString());
|
||||
sGetDeviceRunnableArray.RemoveElementAt(0);
|
||||
}
|
||||
|
||||
sRequestedDeviceCountArray.RemoveElementAt(0);
|
||||
sRemoteDevicesPack.Clear();
|
||||
}
|
||||
|
||||
// Update to registered BluetoothDevice objects
|
||||
DistributeSignal(BluetoothSignal(NS_LITERAL_STRING("PropertyChanged"),
|
||||
nsString(aBdAddr),
|
||||
BluetoothValue(props)));
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothServiceBluedroid::DeviceFoundNotification(
|
||||
int aNumProperties, const BluetoothProperty* aProperties)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
BluetoothValue propertyValue;
|
||||
InfallibleTArray<BluetoothNamedValue> propertiesArray;
|
||||
|
||||
for (int i = 0; i < aNumProperties; i++) {
|
||||
|
||||
const BluetoothProperty& p = aProperties[i];
|
||||
|
||||
if (p.mType == PROPERTY_BDADDR) {
|
||||
propertyValue = p.mString;
|
||||
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "Address", propertyValue);
|
||||
} else if (p.mType == PROPERTY_BDNAME) {
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "Name", p.mString);
|
||||
} else if (p.mType == PROPERTY_CLASS_OF_DEVICE) {
|
||||
uint32_t cod = p.mUint32;
|
||||
propertyValue = cod;
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "Class", propertyValue);
|
||||
|
||||
nsString icon;
|
||||
ClassToIcon(cod, icon);
|
||||
propertyValue = icon;
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "Icon", propertyValue);
|
||||
} else {
|
||||
BT_LOGD("Not handled remote device property: %d", p.mType);
|
||||
}
|
||||
}
|
||||
|
||||
DistributeSignal(BluetoothSignal(NS_LITERAL_STRING("DeviceFound"),
|
||||
NS_LITERAL_STRING(KEY_ADAPTER),
|
||||
BluetoothValue(propertiesArray)));
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothServiceBluedroid::DiscoveryStateChangedNotification(bool aState)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
bool isDiscovering = (aState == true);
|
||||
|
||||
DistributeSignal(
|
||||
BluetoothSignal(NS_LITERAL_STRING(DISCOVERY_STATE_CHANGED_ID),
|
||||
NS_LITERAL_STRING(KEY_ADAPTER), isDiscovering));
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothServiceBluedroid::PinRequestNotification(const nsAString& aRemoteBdAddr,
|
||||
const nsAString& aBdName,
|
||||
uint32_t aCod)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
InfallibleTArray<BluetoothNamedValue> propertiesArray;
|
||||
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "address", nsString(aRemoteBdAddr));
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "method",
|
||||
NS_LITERAL_STRING("pincode"));
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "name", nsString(aBdName));
|
||||
|
||||
DistributeSignal(BluetoothSignal(NS_LITERAL_STRING("RequestPinCode"),
|
||||
NS_LITERAL_STRING(KEY_LOCAL_AGENT),
|
||||
BluetoothValue(propertiesArray)));
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothServiceBluedroid::SspRequestNotification(
|
||||
const nsAString& aRemoteBdAddr, const nsAString& aBdName, uint32_t aCod,
|
||||
const nsAString& aPairingaVariant, uint32_t aPassKey)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
InfallibleTArray<BluetoothNamedValue> propertiesArray;
|
||||
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "address", nsString(aRemoteBdAddr));
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "method",
|
||||
NS_LITERAL_STRING("confirmation"));
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "name", nsString(aBdName));
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "passkey", aPassKey);
|
||||
|
||||
DistributeSignal(BluetoothSignal(NS_LITERAL_STRING("RequestConfirmation"),
|
||||
NS_LITERAL_STRING(KEY_LOCAL_AGENT),
|
||||
BluetoothValue(propertiesArray)));
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothServiceBluedroid::BondStateChangedNotification(
|
||||
BluetoothStatus aStatus, const nsAString& aRemoteBdAddr,
|
||||
BluetoothBondState aState)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (aState == BOND_STATE_BONDING) {
|
||||
// No need to handle bonding state
|
||||
return;
|
||||
}
|
||||
|
||||
if (aState == BOND_STATE_BONDED &&
|
||||
sAdapterBondedAddressArray.Contains(aRemoteBdAddr)) {
|
||||
// See bug 940271 for more details about this case.
|
||||
return;
|
||||
}
|
||||
|
||||
bool bonded;
|
||||
if (aState == BOND_STATE_NONE) {
|
||||
bonded = false;
|
||||
sAdapterBondedAddressArray.RemoveElement(aRemoteBdAddr);
|
||||
} else if (aState == BOND_STATE_BONDED) {
|
||||
bonded = true;
|
||||
sAdapterBondedAddressArray.AppendElement(aRemoteBdAddr);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update bonded address list to BluetoothAdapter
|
||||
InfallibleTArray<BluetoothNamedValue> propertiesChangeArray;
|
||||
BT_APPEND_NAMED_VALUE(propertiesChangeArray, "Devices",
|
||||
sAdapterBondedAddressArray);
|
||||
|
||||
DistributeSignal(BluetoothSignal(NS_LITERAL_STRING("PropertyChanged"),
|
||||
NS_LITERAL_STRING(KEY_ADAPTER),
|
||||
BluetoothValue(propertiesChangeArray)));
|
||||
|
||||
if (bonded && !sBondingRunnableArray.IsEmpty()) {
|
||||
DispatchBluetoothReply(sBondingRunnableArray[0],
|
||||
BluetoothValue(true), EmptyString());
|
||||
|
||||
sBondingRunnableArray.RemoveElementAt(0);
|
||||
} else if (!bonded && !sUnbondingRunnableArray.IsEmpty()) {
|
||||
DispatchBluetoothReply(sUnbondingRunnableArray[0],
|
||||
BluetoothValue(true), EmptyString());
|
||||
|
||||
sUnbondingRunnableArray.RemoveElementAt(0);
|
||||
}
|
||||
|
||||
// Update bonding status to gaia
|
||||
InfallibleTArray<BluetoothNamedValue> propertiesArray;
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "address", nsString(aRemoteBdAddr));
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "status", bonded);
|
||||
|
||||
DistributeSignal(
|
||||
BluetoothSignal(NS_LITERAL_STRING(PAIRED_STATUS_CHANGED_ID),
|
||||
NS_LITERAL_STRING(KEY_ADAPTER),
|
||||
BluetoothValue(propertiesArray)));
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothServiceBluedroid::AclStateChangedNotification(
|
||||
BluetoothStatus aStatus, const nsAString& aRemoteBdAddr, bool aState)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// FIXME: This will be implemented in the later patchset
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothServiceBluedroid::DutModeRecvNotification(uint16_t aOpcode,
|
||||
const uint8_t* aBuf,
|
||||
uint8_t aLen)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// FIXME: This will be implemented in the later patchset
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothServiceBluedroid::LeTestModeNotification(BluetoothStatus aStatus,
|
||||
uint16_t aNumPackets)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// FIXME: This will be implemented in the later patchset
|
||||
}
|
||||
|
|
|
@ -8,11 +8,13 @@
|
|||
#define mozilla_dom_bluetooth_bluetoothservicebluedroid_h__
|
||||
|
||||
#include "BluetoothCommon.h"
|
||||
#include "BluetoothInterface.h"
|
||||
#include "BluetoothService.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
class BluetoothServiceBluedroid : public BluetoothService
|
||||
, public BluetoothNotificationHandler
|
||||
{
|
||||
public:
|
||||
BluetoothServiceBluedroid();
|
||||
|
@ -153,6 +155,46 @@ public:
|
|||
virtual nsresult
|
||||
SendInputMessage(const nsAString& aDeviceAddresses,
|
||||
const nsAString& aMessage) MOZ_OVERRIDE;
|
||||
|
||||
//
|
||||
// Bluetooth notifications
|
||||
//
|
||||
|
||||
virtual void AdapterStateChangedNotification(bool aState) MOZ_OVERRIDE;
|
||||
virtual void AdapterPropertiesNotification(
|
||||
BluetoothStatus aStatus, int aNumProperties,
|
||||
const BluetoothProperty* aProperties) MOZ_OVERRIDE;
|
||||
|
||||
virtual void RemoteDevicePropertiesNotification(
|
||||
BluetoothStatus aStatus, const nsAString& aBdAddr,
|
||||
int aNumProperties, const BluetoothProperty* aProperties) MOZ_OVERRIDE;
|
||||
|
||||
virtual void DeviceFoundNotification(
|
||||
int aNumProperties, const BluetoothProperty* aProperties) MOZ_OVERRIDE;
|
||||
|
||||
virtual void DiscoveryStateChangedNotification(bool aState) MOZ_OVERRIDE;
|
||||
|
||||
virtual void PinRequestNotification(const nsAString& aRemoteBdAddr,
|
||||
const nsAString& aBdName,
|
||||
uint32_t aCod) MOZ_OVERRIDE;
|
||||
virtual void SspRequestNotification(const nsAString& aRemoteBdAddr,
|
||||
const nsAString& aBdName,
|
||||
uint32_t aCod,
|
||||
const nsAString& aPairingaVariant,
|
||||
uint32_t aPassKey) MOZ_OVERRIDE;
|
||||
|
||||
virtual void BondStateChangedNotification(
|
||||
BluetoothStatus aStatus, const nsAString& aRemoteBdAddr,
|
||||
BluetoothBondState aState) MOZ_OVERRIDE;
|
||||
virtual void AclStateChangedNotification(BluetoothStatus aStatus,
|
||||
const nsAString& aRemoteBdAddr,
|
||||
bool aState) MOZ_OVERRIDE;
|
||||
|
||||
virtual void DutModeRecvNotification(uint16_t aOpcode,
|
||||
const uint8_t* aBuf,
|
||||
uint8_t aLen) MOZ_OVERRIDE;
|
||||
virtual void LeTestModeNotification(BluetoothStatus aStatus,
|
||||
uint16_t aNumPackets) MOZ_OVERRIDE;
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
|
|
@ -23,19 +23,6 @@
|
|||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
void
|
||||
StringToBdAddressType(const nsAString& aBdAddress,
|
||||
bt_bdaddr_t *aRetBdAddressType)
|
||||
{
|
||||
NS_ConvertUTF16toUTF8 bdAddressUTF8(aBdAddress);
|
||||
const char* str = bdAddressUTF8.get();
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
aRetBdAddressType->address[i] = (uint8_t) strtoul(str, (char **)&str, 16);
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BdAddressTypeToString(bt_bdaddr_t* aBdAddressType, nsAString& aRetBdAddress)
|
||||
{
|
||||
|
@ -50,11 +37,11 @@ BdAddressTypeToString(bt_bdaddr_t* aBdAddressType, nsAString& aRetBdAddress)
|
|||
}
|
||||
|
||||
uint16_t
|
||||
UuidToServiceClassInt(bt_uuid_t* p_uuid)
|
||||
UuidToServiceClassInt(const BluetoothUuid& mUuid)
|
||||
{
|
||||
// extract short UUID 0000xxxx-0000-1000-8000-00805f9b34fb
|
||||
uint16_t shortUuid;
|
||||
memcpy(&shortUuid, &(p_uuid->uu[2]), sizeof(uint16_t));
|
||||
memcpy(&shortUuid, mUuid.mUuid + 2, sizeof(uint16_t));
|
||||
return ntohs(shortUuid);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,16 +18,12 @@ class BluetoothNamedValue;
|
|||
class BluetoothValue;
|
||||
class BluetoothReplyRunnable;
|
||||
|
||||
void
|
||||
StringToBdAddressType(const nsAString& aBdAddress,
|
||||
bt_bdaddr_t *aRetBdAddressType);
|
||||
|
||||
void
|
||||
BdAddressTypeToString(bt_bdaddr_t* aBdAddressType,
|
||||
nsAString& aRetBdAddress);
|
||||
|
||||
uint16_t
|
||||
UuidToServiceClassInt(bt_uuid_t* p_uuid);
|
||||
UuidToServiceClassInt(const BluetoothUuid& mUuid);
|
||||
|
||||
bool
|
||||
SetJsObject(JSContext* aContext,
|
||||
|
|
|
@ -644,15 +644,15 @@ BrowserElementChild.prototype = {
|
|||
isCollapsed: (e.selectedText.length == 0),
|
||||
};
|
||||
|
||||
// Get correct geometry information if we have nested <iframe mozbrowser>
|
||||
// Get correct geometry information if we have nested iframe.
|
||||
let currentWindow = e.target.defaultView;
|
||||
while (currentWindow.realFrameElement) {
|
||||
let currentRect = currentWindow.realFrameElement.getBoundingClientRect();
|
||||
while (currentWindow.top != currentWindow) {
|
||||
let currentRect = currentWindow.frameElement.getBoundingClientRect();
|
||||
detail.rect.top += currentRect.top;
|
||||
detail.rect.bottom += currentRect.top;
|
||||
detail.rect.left += currentRect.left;
|
||||
detail.rect.right += currentRect.left;
|
||||
currentWindow = currentWindow.realFrameElement.ownerDocument.defaultView;
|
||||
currentWindow = currentWindow.parent;
|
||||
}
|
||||
|
||||
sendAsyncMsg("selectionchange", detail);
|
||||
|
|
|
@ -371,10 +371,6 @@ const kEventConstructors = {
|
|||
return e;
|
||||
},
|
||||
},
|
||||
SmartCardEvent: { create: function (aName, aProps) {
|
||||
return new SmartCardEvent(aName, aProps);
|
||||
},
|
||||
},
|
||||
SpeechRecognitionEvent: { create: function (aName, aProps) {
|
||||
return new SpeechRecognitionEvent(aName, aProps);
|
||||
},
|
||||
|
|
|
@ -748,29 +748,6 @@ is(e.requestingWindow, window);
|
|||
is(e.popupWindowFeatures, "features");
|
||||
is(e.popupWindowName, "name");
|
||||
|
||||
|
||||
// SmartCardEvent
|
||||
|
||||
try {
|
||||
e = new SmartCardEvent();
|
||||
} catch(exp) {
|
||||
ex = true;
|
||||
}
|
||||
ok(ex, "SmartCardEvent: First parameter is required!");
|
||||
ex = false;
|
||||
|
||||
e = new SmartCardEvent("hello");
|
||||
is(e.type, "hello", "SmartCardEvent: Wrong event type!");
|
||||
ok(!e.isTrusted, "SmartCardEvent: Event shouldn't be trusted!");
|
||||
ok(!e.bubbles, "SmartCardEvent: Event shouldn't bubble!");
|
||||
ok(!e.cancelable, "SmartCardEvent: Event shouldn't be cancelable!");
|
||||
is(e.tokenName, "");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "SmartCardEvent: Wrong event!");
|
||||
|
||||
e = new SmartCardEvent("hello", { tokenName: "foo" });
|
||||
is(e.tokenName, "foo");
|
||||
|
||||
// WheelEvent
|
||||
|
||||
try {
|
||||
|
|
|
@ -1707,7 +1707,9 @@ public:
|
|||
|
||||
NS_ASSERTION(database->IsClosed(),
|
||||
"AbortCloseStoragesForWindow should have closed database");
|
||||
ownerDoc->DisallowBFCaching();
|
||||
if (ownerDoc) {
|
||||
ownerDoc->DisallowBFCaching();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ XPIDL_SOURCES += [
|
|||
'nsIDOMClientRect.idl',
|
||||
'nsIDOMClientRectList.idl',
|
||||
'nsIDOMConstructor.idl',
|
||||
'nsIDOMCrypto.idl',
|
||||
'nsIDOMGlobalObjectConstructor.idl',
|
||||
'nsIDOMGlobalPropertyInitializer.idl',
|
||||
'nsIDOMHistory.idl',
|
||||
|
@ -37,15 +38,6 @@ XPIDL_SOURCES += [
|
|||
'nsITabParent.idl',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_DISABLE_CRYPTOLEGACY']:
|
||||
XPIDL_SOURCES += [
|
||||
'nsIDOMCrypto.idl',
|
||||
]
|
||||
else:
|
||||
XPIDL_SOURCES += [
|
||||
'nsIDOMCryptoLegacy.idl',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_B2G']:
|
||||
XPIDL_SOURCES += [
|
||||
'nsIDOMWindowB2G.idl',
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 "domstubs.idl"
|
||||
|
||||
interface nsIDOMWindow;
|
||||
|
||||
[uuid(c25ecf08-3f46-4420-bee4-8505792fd63a)]
|
||||
interface nsIDOMCrypto : nsISupports
|
||||
{
|
||||
[notxpcom] void init(in nsIDOMWindow window);
|
||||
attribute boolean enableSmartCardEvents;
|
||||
};
|
|
@ -575,7 +575,7 @@ ContentParent::RunNuwaProcess()
|
|||
|
||||
// PreallocateAppProcess is called by the PreallocatedProcessManager.
|
||||
// ContentParent then takes this process back within
|
||||
// MaybeTakePreallocatedAppProcess.
|
||||
// GetNewOrPreallocatedAppProcess.
|
||||
/*static*/ already_AddRefed<ContentParent>
|
||||
ContentParent::PreallocateAppProcess()
|
||||
{
|
||||
|
@ -590,21 +590,47 @@ ContentParent::PreallocateAppProcess()
|
|||
}
|
||||
|
||||
/*static*/ already_AddRefed<ContentParent>
|
||||
ContentParent::MaybeTakePreallocatedAppProcess(const nsAString& aAppManifestURL,
|
||||
ProcessPriority aInitialPriority)
|
||||
ContentParent::GetNewOrPreallocatedAppProcess(mozIApplication* aApp,
|
||||
ProcessPriority aInitialPriority,
|
||||
ContentParent* aOpener,
|
||||
/*out*/ bool* aTookPreAllocated)
|
||||
{
|
||||
MOZ_ASSERT(aApp);
|
||||
nsRefPtr<ContentParent> process = PreallocatedProcessManager::Take();
|
||||
if (!process) {
|
||||
return nullptr;
|
||||
|
||||
if (process) {
|
||||
if (!process->SetPriorityAndCheckIsAlive(aInitialPriority)) {
|
||||
// Kill the process just in case it's not actually dead; we don't want
|
||||
// to "leak" this process!
|
||||
process->KillHard();
|
||||
}
|
||||
else {
|
||||
nsAutoString manifestURL;
|
||||
if (NS_FAILED(aApp->GetManifestURL(manifestURL))) {
|
||||
NS_ERROR("Failed to get manifest URL");
|
||||
return nullptr;
|
||||
}
|
||||
process->TransformPreallocatedIntoApp(manifestURL);
|
||||
if (aTookPreAllocated) {
|
||||
*aTookPreAllocated = true;
|
||||
}
|
||||
return process.forget();
|
||||
}
|
||||
}
|
||||
|
||||
if (!process->SetPriorityAndCheckIsAlive(aInitialPriority)) {
|
||||
// Kill the process just in case it's not actually dead; we don't want
|
||||
// to "leak" this process!
|
||||
process->KillHard();
|
||||
return nullptr;
|
||||
// XXXkhuey Nuwa wants the frame loader to try again later, but the
|
||||
// frame loader is really not set up to do that ...
|
||||
NS_WARNING("Unable to use pre-allocated app process");
|
||||
process = new ContentParent(aApp,
|
||||
/* aOpener = */ aOpener,
|
||||
/* isForBrowserElement = */ false,
|
||||
/* isForPreallocated = */ false,
|
||||
aInitialPriority);
|
||||
process->Init();
|
||||
|
||||
if (aTookPreAllocated) {
|
||||
*aTookPreAllocated = false;
|
||||
}
|
||||
process->TransformPreallocatedIntoApp(aAppManifestURL);
|
||||
|
||||
return process.forget();
|
||||
}
|
||||
|
@ -693,9 +719,9 @@ ContentParent::JoinAllSubprocesses()
|
|||
}
|
||||
|
||||
/*static*/ already_AddRefed<ContentParent>
|
||||
ContentParent::GetNewOrUsed(bool aForBrowserElement,
|
||||
ProcessPriority aPriority,
|
||||
ContentParent* aOpener)
|
||||
ContentParent::GetNewOrUsedBrowserProcess(bool aForBrowserElement,
|
||||
ProcessPriority aPriority,
|
||||
ContentParent* aOpener)
|
||||
{
|
||||
if (!sNonAppContentParents)
|
||||
sNonAppContentParents = new nsTArray<ContentParent*>();
|
||||
|
@ -805,10 +831,31 @@ ContentParent::RecvCreateChildProcess(const IPCTabContext& aContext,
|
|||
return false;
|
||||
}
|
||||
#endif
|
||||
nsRefPtr<ContentParent> cp;
|
||||
MaybeInvalidTabContext tc(aContext);
|
||||
if (!tc.IsValid()) {
|
||||
NS_ERROR(nsPrintfCString("Received an invalid TabContext from "
|
||||
"the child process. (%s)",
|
||||
tc.GetInvalidReason()).get());
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<mozIApplication> ownApp = tc.GetTabContext().GetOwnApp();
|
||||
if (ownApp) {
|
||||
cp = GetNewOrPreallocatedAppProcess(ownApp,
|
||||
aPriority,
|
||||
this);
|
||||
}
|
||||
else {
|
||||
cp = GetNewOrUsedBrowserProcess(/* isBrowserElement = */ true,
|
||||
aPriority,
|
||||
this);
|
||||
}
|
||||
|
||||
if (!cp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<ContentParent> cp = GetNewOrUsed(/* isBrowserElement = */ true,
|
||||
aPriority,
|
||||
this);
|
||||
*aId = cp->ChildID();
|
||||
*aIsForApp = cp->IsForApp();
|
||||
*aIsForBrowser = cp->IsForBrowser();
|
||||
|
@ -849,36 +896,20 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
|
|||
}
|
||||
|
||||
ProcessPriority initialPriority = GetInitialProcessPriority(aFrameElement);
|
||||
bool isInContentProcess = (XRE_GetProcessType() != GeckoProcessType_Default);
|
||||
|
||||
if (aContext.IsBrowserElement() || !aContext.HasOwnApp()) {
|
||||
nsRefPtr<TabParent> tp;
|
||||
nsRefPtr<nsIContentParent> constructorSender;
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||
if (isInContentProcess) {
|
||||
MOZ_ASSERT(aContext.IsBrowserElement());
|
||||
ContentChild* child = ContentChild::GetSingleton();
|
||||
uint64_t id;
|
||||
bool isForApp;
|
||||
bool isForBrowser;
|
||||
if (!child->SendCreateChildProcess(aContext.AsIPCTabContext(),
|
||||
initialPriority,
|
||||
&id,
|
||||
&isForApp,
|
||||
&isForBrowser)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!child->CallBridgeToChildProcess(id)) {
|
||||
return nullptr;
|
||||
}
|
||||
ContentBridgeParent* parent = child->GetLastBridge();
|
||||
parent->SetChildID(id);
|
||||
parent->SetIsForApp(isForApp);
|
||||
parent->SetIsForBrowser(isForBrowser);
|
||||
constructorSender = parent;
|
||||
constructorSender = CreateContentBridgeParent(aContext, initialPriority);
|
||||
} else {
|
||||
if (aOpenerContentParent) {
|
||||
constructorSender = aOpenerContentParent;
|
||||
} else {
|
||||
constructorSender = GetNewOrUsed(aContext.IsBrowserElement(), initialPriority);
|
||||
constructorSender = GetNewOrUsedBrowserProcess(aContext.IsBrowserElement(),
|
||||
initialPriority);
|
||||
}
|
||||
}
|
||||
if (constructorSender) {
|
||||
|
@ -928,105 +959,115 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
|
|||
// If we got here, we have an app and we're not a browser element. ownApp
|
||||
// shouldn't be null, because we otherwise would have gone into the
|
||||
// !HasOwnApp() branch above.
|
||||
nsCOMPtr<mozIApplication> ownApp = aContext.GetOwnApp();
|
||||
|
||||
if (!sAppContentParents) {
|
||||
sAppContentParents =
|
||||
new nsDataHashtable<nsStringHashKey, ContentParent*>();
|
||||
}
|
||||
|
||||
// Each app gets its own ContentParent instance unless it shares it with
|
||||
// a parent app.
|
||||
nsRefPtr<nsIContentParent> parent;
|
||||
bool reused = false;
|
||||
bool tookPreallocated = false;
|
||||
nsAutoString manifestURL;
|
||||
if (NS_FAILED(ownApp->GetManifestURL(manifestURL))) {
|
||||
NS_ERROR("Failed to get manifest URL");
|
||||
return nullptr;
|
||||
|
||||
if (isInContentProcess) {
|
||||
parent = CreateContentBridgeParent(aContext, initialPriority);
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<mozIApplication> ownApp = aContext.GetOwnApp();
|
||||
|
||||
nsRefPtr<ContentParent> p = sAppContentParents->Get(manifestURL);
|
||||
if (!sAppContentParents) {
|
||||
sAppContentParents =
|
||||
new nsDataHashtable<nsStringHashKey, ContentParent*>();
|
||||
}
|
||||
|
||||
if (!p && Preferences::GetBool("dom.ipc.reuse_parent_app")) {
|
||||
nsAutoString parentAppManifestURL;
|
||||
aFrameElement->GetAttr(kNameSpaceID_None,
|
||||
nsGkAtoms::parentapp, parentAppManifestURL);
|
||||
nsAdoptingString systemAppManifestURL =
|
||||
Preferences::GetString("b2g.system_manifest_url");
|
||||
nsCOMPtr<nsIAppsService> appsService =
|
||||
do_GetService(APPS_SERVICE_CONTRACTID);
|
||||
if (!parentAppManifestURL.IsEmpty() &&
|
||||
!parentAppManifestURL.Equals(systemAppManifestURL) &&
|
||||
appsService) {
|
||||
nsCOMPtr<mozIApplication> parentApp;
|
||||
nsCOMPtr<mozIApplication> app;
|
||||
appsService->GetAppByManifestURL(parentAppManifestURL,
|
||||
getter_AddRefs(parentApp));
|
||||
appsService->GetAppByManifestURL(manifestURL,
|
||||
getter_AddRefs(app));
|
||||
// Each app gets its own ContentParent instance unless it shares it with
|
||||
// a parent app.
|
||||
if (NS_FAILED(ownApp->GetManifestURL(manifestURL))) {
|
||||
NS_ERROR("Failed to get manifest URL");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Only let certified apps re-use the same process.
|
||||
unsigned short parentAppStatus = 0;
|
||||
unsigned short appStatus = 0;
|
||||
if (app &&
|
||||
NS_SUCCEEDED(app->GetAppStatus(&appStatus)) &&
|
||||
appStatus == nsIPrincipal::APP_STATUS_CERTIFIED &&
|
||||
parentApp &&
|
||||
NS_SUCCEEDED(parentApp->GetAppStatus(&parentAppStatus)) &&
|
||||
parentAppStatus == nsIPrincipal::APP_STATUS_CERTIFIED) {
|
||||
// Check if we can re-use the process of the parent app.
|
||||
p = sAppContentParents->Get(parentAppManifestURL);
|
||||
nsRefPtr<ContentParent> p = sAppContentParents->Get(manifestURL);
|
||||
|
||||
if (!p && Preferences::GetBool("dom.ipc.reuse_parent_app")) {
|
||||
nsAutoString parentAppManifestURL;
|
||||
aFrameElement->GetAttr(kNameSpaceID_None,
|
||||
nsGkAtoms::parentapp, parentAppManifestURL);
|
||||
nsAdoptingString systemAppManifestURL =
|
||||
Preferences::GetString("b2g.system_manifest_url");
|
||||
nsCOMPtr<nsIAppsService> appsService =
|
||||
do_GetService(APPS_SERVICE_CONTRACTID);
|
||||
if (!parentAppManifestURL.IsEmpty() &&
|
||||
!parentAppManifestURL.Equals(systemAppManifestURL) &&
|
||||
appsService) {
|
||||
nsCOMPtr<mozIApplication> parentApp;
|
||||
nsCOMPtr<mozIApplication> app;
|
||||
appsService->GetAppByManifestURL(parentAppManifestURL,
|
||||
getter_AddRefs(parentApp));
|
||||
appsService->GetAppByManifestURL(manifestURL,
|
||||
getter_AddRefs(app));
|
||||
|
||||
// Only let certified apps re-use the same process.
|
||||
unsigned short parentAppStatus = 0;
|
||||
unsigned short appStatus = 0;
|
||||
if (app &&
|
||||
NS_SUCCEEDED(app->GetAppStatus(&appStatus)) &&
|
||||
appStatus == nsIPrincipal::APP_STATUS_CERTIFIED &&
|
||||
parentApp &&
|
||||
NS_SUCCEEDED(parentApp->GetAppStatus(&parentAppStatus)) &&
|
||||
parentAppStatus == nsIPrincipal::APP_STATUS_CERTIFIED) {
|
||||
// Check if we can re-use the process of the parent app.
|
||||
p = sAppContentParents->Get(parentAppManifestURL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p) {
|
||||
// Check that the process is still alive and set its priority.
|
||||
// Hopefully the process won't die after this point, if this call
|
||||
// succeeds.
|
||||
if (!p->SetPriorityAndCheckIsAlive(initialPriority)) {
|
||||
p = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
reused = !!p;
|
||||
if (!p) {
|
||||
p = GetNewOrPreallocatedAppProcess(ownApp,
|
||||
initialPriority,
|
||||
nullptr,
|
||||
&tookPreallocated);
|
||||
MOZ_ASSERT(p);
|
||||
sAppContentParents->Put(manifestURL, p);
|
||||
}
|
||||
parent = static_cast<nsIContentParent*>(p);
|
||||
}
|
||||
|
||||
if (p) {
|
||||
// Check that the process is still alive and set its priority.
|
||||
// Hopefully the process won't die after this point, if this call
|
||||
// succeeds.
|
||||
if (!p->SetPriorityAndCheckIsAlive(initialPriority)) {
|
||||
p = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool reused = !!p;
|
||||
bool tookPreallocated = false;
|
||||
if (!p) {
|
||||
p = MaybeTakePreallocatedAppProcess(manifestURL,
|
||||
initialPriority);
|
||||
tookPreallocated = !!p;
|
||||
if (!tookPreallocated) {
|
||||
// XXXkhuey Nuwa wants the frame loader to try again later, but the
|
||||
// frame loader is really not set up to do that ...
|
||||
NS_WARNING("Unable to use pre-allocated app process");
|
||||
p = new ContentParent(ownApp,
|
||||
/* aOpener = */ nullptr,
|
||||
/* isForBrowserElement = */ false,
|
||||
/* isForPreallocated = */ false,
|
||||
initialPriority);
|
||||
p->Init();
|
||||
}
|
||||
sAppContentParents->Put(manifestURL, p);
|
||||
if (!parent) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t chromeFlags = 0;
|
||||
|
||||
nsRefPtr<TabParent> tp = new TabParent(p, aContext, chromeFlags);
|
||||
nsRefPtr<TabParent> tp = new TabParent(parent, aContext, chromeFlags);
|
||||
tp->SetOwnerElement(aFrameElement);
|
||||
PBrowserParent* browser = p->SendPBrowserConstructor(
|
||||
PBrowserParent* browser = parent->SendPBrowserConstructor(
|
||||
// DeallocPBrowserParent() releases this ref.
|
||||
nsRefPtr<TabParent>(tp).forget().take(),
|
||||
aContext.AsIPCTabContext(),
|
||||
chromeFlags,
|
||||
p->ChildID(),
|
||||
p->IsForApp(),
|
||||
p->IsForBrowser());
|
||||
parent->ChildID(),
|
||||
parent->IsForApp(),
|
||||
parent->IsForBrowser());
|
||||
|
||||
if (isInContentProcess) {
|
||||
// Just return directly without the following check in content process.
|
||||
return static_cast<TabParent*>(browser);
|
||||
}
|
||||
|
||||
if (!browser) {
|
||||
// We failed to actually start the PBrowser. This can happen if the
|
||||
// other process has already died.
|
||||
if (!reused) {
|
||||
// Don't leave a broken ContentParent in the hashtable.
|
||||
p->KillHard();
|
||||
parent->AsContentParent()->KillHard();
|
||||
sAppContentParents->Remove(manifestURL);
|
||||
p = nullptr;
|
||||
parent = nullptr;
|
||||
}
|
||||
|
||||
// If we took the preallocated process and it was already dead, try
|
||||
|
@ -1043,11 +1084,36 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
p->MaybeTakeCPUWakeLock(aFrameElement);
|
||||
parent->AsContentParent()->MaybeTakeCPUWakeLock(aFrameElement);
|
||||
|
||||
return static_cast<TabParent*>(browser);
|
||||
}
|
||||
|
||||
/*static*/ ContentBridgeParent*
|
||||
ContentParent::CreateContentBridgeParent(const TabContext& aContext,
|
||||
const hal::ProcessPriority& aPriority)
|
||||
{
|
||||
ContentChild* child = ContentChild::GetSingleton();
|
||||
uint64_t id;
|
||||
bool isForApp;
|
||||
bool isForBrowser;
|
||||
if (!child->SendCreateChildProcess(aContext.AsIPCTabContext(),
|
||||
aPriority,
|
||||
&id,
|
||||
&isForApp,
|
||||
&isForBrowser)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!child->CallBridgeToChildProcess(id)) {
|
||||
return nullptr;
|
||||
}
|
||||
ContentBridgeParent* parent = child->GetLastBridge();
|
||||
parent->SetChildID(id);
|
||||
parent->SetIsForApp(isForApp);
|
||||
parent->SetIsForBrowser(isForBrowser);
|
||||
return parent;
|
||||
}
|
||||
|
||||
void
|
||||
ContentParent::GetAll(nsTArray<ContentParent*>& aArray)
|
||||
{
|
||||
|
|
|
@ -63,6 +63,7 @@ class ClonedMessageData;
|
|||
class MemoryReport;
|
||||
class TabContext;
|
||||
class PFileDescriptorSetParent;
|
||||
class ContentBridgeParent;
|
||||
|
||||
class ContentParent : public PContentParent
|
||||
, public nsIContentParent
|
||||
|
@ -96,11 +97,17 @@ public:
|
|||
static bool PreallocatedProcessReady();
|
||||
static void RunAfterPreallocatedProcessReady(nsIRunnable* aRequest);
|
||||
|
||||
/**
|
||||
* Get or create a content process for:
|
||||
* 1. browser iframe
|
||||
* 2. remote xul <browser>
|
||||
* 3. normal iframe
|
||||
*/
|
||||
static already_AddRefed<ContentParent>
|
||||
GetNewOrUsed(bool aForBrowserElement = false,
|
||||
hal::ProcessPriority aPriority =
|
||||
hal::ProcessPriority::PROCESS_PRIORITY_FOREGROUND,
|
||||
ContentParent* aOpener = nullptr);
|
||||
GetNewOrUsedBrowserProcess(bool aForBrowserElement = false,
|
||||
hal::ProcessPriority aPriority =
|
||||
hal::ProcessPriority::PROCESS_PRIORITY_FOREGROUND,
|
||||
ContentParent* aOpener = nullptr);
|
||||
|
||||
/**
|
||||
* Create a subprocess suitable for use as a preallocated app process.
|
||||
|
@ -286,13 +293,18 @@ private:
|
|||
|
||||
// Take the preallocated process and transform it into a "real" app process,
|
||||
// for the specified manifest URL. If there is no preallocated process (or
|
||||
// if it's dead), this returns false.
|
||||
// if it's dead), create a new one and set aTookPreAllocated to false.
|
||||
static already_AddRefed<ContentParent>
|
||||
MaybeTakePreallocatedAppProcess(const nsAString& aAppManifestURL,
|
||||
hal::ProcessPriority aInitialPriority);
|
||||
GetNewOrPreallocatedAppProcess(mozIApplication* aApp,
|
||||
hal::ProcessPriority aInitialPriority,
|
||||
ContentParent* aOpener,
|
||||
/*out*/ bool* aTookPreAllocated = nullptr);
|
||||
|
||||
static hal::ProcessPriority GetInitialProcessPriority(Element* aFrameElement);
|
||||
|
||||
static ContentBridgeParent* CreateContentBridgeParent(const TabContext& aContext,
|
||||
const hal::ProcessPriority& aPriority);
|
||||
|
||||
// Hide the raw constructor methods since we don't want client code
|
||||
// using them.
|
||||
virtual PBrowserParent* SendPBrowserConstructor(
|
||||
|
|
|
@ -23,8 +23,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=983504
|
|||
* Run a test to verify that we can complete a start and stop media playback
|
||||
* cycle for an screenshare LocalMediaStream on a video HTMLMediaElement.
|
||||
*/
|
||||
SimpleTest.expectAssertions(0, 3); // Bug 1047842
|
||||
|
||||
runTest(function () {
|
||||
const isWinXP = navigator.userAgent.indexOf("Windows NT 5.1") != -1;
|
||||
if (IsMacOSX10_6orOlder() || isWinXP) {
|
||||
|
|
|
@ -23,8 +23,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=983504
|
|||
* Run a test to verify that we can complete a start and stop media playback
|
||||
* cycle for an screenshare LocalMediaStream on a video HTMLMediaElement.
|
||||
*/
|
||||
SimpleTest.expectAssertions(0, 3); // Bug 1047842
|
||||
|
||||
runTest(function () {
|
||||
const isWinXP = navigator.userAgent.indexOf("Windows NT 5.1") != -1;
|
||||
if (IsMacOSX10_6orOlder() || isWinXP) {
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
title: "Basic screenshare-only peer connection"
|
||||
});
|
||||
|
||||
SimpleTest.expectAssertions(0, 1); // Bug 1047842
|
||||
|
||||
var test;
|
||||
runNetworkTest(function (options) {
|
||||
const isWinXP = navigator.userAgent.indexOf("Windows NT 5.1") != -1;
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
title: "Basic windowshare-only peer connection"
|
||||
});
|
||||
|
||||
SimpleTest.expectAssertions(0, 1); // Bug 1047842
|
||||
|
||||
var test;
|
||||
runNetworkTest(function (options) {
|
||||
const isWinXP = navigator.userAgent.indexOf("Windows NT 5.1") != -1;
|
||||
|
|
|
@ -60,33 +60,19 @@ let sysMsgHelper = (function() {
|
|||
}
|
||||
}
|
||||
|
||||
function sendFile(msg) {
|
||||
log("system message nfc-manager-send-file");
|
||||
let send = mSendFile.shift();
|
||||
if (send) {
|
||||
send(msg);
|
||||
}
|
||||
}
|
||||
|
||||
let mDiscovered = [], mLost = [], mSendFile = [];
|
||||
let mDiscovered = [], mLost = [];
|
||||
window.navigator.mozSetMessageHandler("nfc-manager-tech-discovered",
|
||||
techDiscovered);
|
||||
window.navigator.mozSetMessageHandler("nfc-manager-tech-lost", techLost);
|
||||
window.navigator.mozSetMessageHandler("nfc-manager-send-file", sendFile);
|
||||
|
||||
return {
|
||||
waitForTechDiscovered: function(discovered) {
|
||||
waitForTechDiscovered: function (discovered) {
|
||||
mDiscovered.push(discovered);
|
||||
},
|
||||
|
||||
waitForTechLost: function(lost) {
|
||||
waitForTechLost: function (lost) {
|
||||
mLost.push(lost);
|
||||
},
|
||||
|
||||
waitForSendFile: function(sendFile) {
|
||||
mSendFile.push(sendFile);
|
||||
},
|
||||
|
||||
};
|
||||
}());
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ qemu=true
|
|||
[test_nfc_manager_tech_lost.js]
|
||||
[test_nfc_peer.js]
|
||||
[test_nfc_peer_sendndef.js]
|
||||
[test_nfc_peer_sendFile.js]
|
||||
[test_nfc_read_tag.js]
|
||||
[test_nfc_checkP2PRegistration.js]
|
||||
[test_nfc_error_messages.js]
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 30000;
|
||||
MARIONETTE_HEAD_JS = "head.js";
|
||||
|
||||
let MANIFEST_URL = "app://system.gaiamobile.org/manifest.webapp";
|
||||
|
||||
function sendFile(msg) {
|
||||
log("sendFile msg="+JSON.stringify(msg));
|
||||
let peer = nfc.getNFCPeer(msg.sessionToken);
|
||||
ok(peer instanceof MozNFCPeer, "should get a MozNFCPeer");
|
||||
ok(msg.blob instanceof Blob, "should get a Blob");
|
||||
|
||||
nfc.peerready = null;
|
||||
NCI.deactivate().then(() => toggleNFC(false)).then(runNextTest);
|
||||
}
|
||||
|
||||
function testSendFile() {
|
||||
nfc.onpeerready = function(evt) {
|
||||
let peer = evt.peer;
|
||||
peer.sendFile(new Blob());
|
||||
sysMsgHelper.waitForSendFile(sendFile);
|
||||
};
|
||||
|
||||
sysMsgHelper.waitForTechDiscovered(function(msg) {
|
||||
let request = nfc.checkP2PRegistration(MANIFEST_URL);
|
||||
request.onsuccess = function(evt) {
|
||||
is(request.result, true, "check for P2P registration result");
|
||||
nfc.notifyUserAcceptedP2P(MANIFEST_URL);
|
||||
}
|
||||
|
||||
request.onerror = function() {
|
||||
ok(false, "checkP2PRegistration failed.");
|
||||
toggleNFC(false).then(runNextTest);
|
||||
}
|
||||
});
|
||||
|
||||
toggleNFC(true).then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0));
|
||||
}
|
||||
|
||||
let tests = [
|
||||
testSendFile
|
||||
];
|
||||
|
||||
SpecialPowers.pushPermissions(
|
||||
[{"type": "nfc", "allow": true,
|
||||
"read": true, 'write': true, context: document},
|
||||
{"type": "nfc-manager", 'allow': true, context: document}], runTests);
|
|
@ -1116,6 +1116,48 @@ RilObject.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if operator name needs to be overriden by current voiceRegistrationState
|
||||
* , EFOPL and EFPNN. See 3GPP TS 31.102 clause 4.2.58 EFPNN and 4.2.59 EFOPL
|
||||
* for detail.
|
||||
*
|
||||
* @return true if operator name is overridden, false otherwise.
|
||||
*/
|
||||
overrideICCNetworkName: function() {
|
||||
if (!this.operator) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We won't get network name using PNN and OPL if voice registration isn't
|
||||
// ready.
|
||||
if (!this.voiceRegistrationState.cell ||
|
||||
this.voiceRegistrationState.cell.gsmLocationAreaCode == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let ICCUtilsHelper = this.context.ICCUtilsHelper;
|
||||
let networkName = ICCUtilsHelper.getNetworkNameFromICC(
|
||||
this.operator.mcc,
|
||||
this.operator.mnc,
|
||||
this.voiceRegistrationState.cell.gsmLocationAreaCode);
|
||||
|
||||
if (!networkName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
this.context.debug("Operator names will be overriden: " +
|
||||
"longName = " + networkName.fullName + ", " +
|
||||
"shortName = " + networkName.shortName);
|
||||
}
|
||||
|
||||
this.operator.longName = networkName.fullName;
|
||||
this.operator.shortName = networkName.shortName;
|
||||
|
||||
this._sendNetworkInfoMessage(NETWORK_INFO_OPERATOR, this.operator);
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Request the phone's radio to be enabled or disabled.
|
||||
*
|
||||
|
@ -1566,6 +1608,61 @@ RilObject.prototype = {
|
|||
*/
|
||||
cachedDialRequest : null,
|
||||
|
||||
/**
|
||||
* Dial a non-emergency number.
|
||||
*
|
||||
* @param isDialEmergency
|
||||
* Whether it is called by dialEmergency.
|
||||
* @param isEmergency
|
||||
* Whether the number is an emergency number.
|
||||
* @param number
|
||||
* String containing the number to dial.
|
||||
* @param clirMode
|
||||
* Integer for showing/hidding the caller Id to the called party.
|
||||
* @param uusInfo
|
||||
* Integer doing something XXX TODO
|
||||
*/
|
||||
dial: function(options) {
|
||||
let onerror = (function onerror(options, errorMsg) {
|
||||
options.success = false;
|
||||
options.errorMsg = errorMsg;
|
||||
this.sendChromeMessage(options);
|
||||
}).bind(this, options);
|
||||
|
||||
let isRadioOff = (this.radioState === GECKO_RADIOSTATE_OFF);
|
||||
|
||||
if (options.isEmergency) {
|
||||
if (isRadioOff) {
|
||||
if (DEBUG) {
|
||||
this.context.debug("Automatically enable radio for an emergency call.");
|
||||
}
|
||||
|
||||
this.cachedDialRequest = {
|
||||
callback: this.dialEmergencyNumber.bind(this, options),
|
||||
onerror: onerror
|
||||
};
|
||||
this.setRadioEnabled({enabled: true});
|
||||
return;
|
||||
}
|
||||
|
||||
this.dialEmergencyNumber(options);
|
||||
} else {
|
||||
// Notify error in establishing the call without radio.
|
||||
if (isRadioOff) {
|
||||
onerror(GECKO_ERROR_RADIO_NOT_AVAILABLE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Shouldn't dial a non-emergency number by dialEmergency.
|
||||
if (options.isDialEmergency || this.voiceRegistrationState.emergencyCallsOnly) {
|
||||
onerror(GECKO_CALL_ERROR_BAD_NUMBER);
|
||||
return;
|
||||
}
|
||||
|
||||
this.dialNonEmergencyNumber(options);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Dial a non-emergency number.
|
||||
*
|
||||
|
@ -1577,23 +1674,6 @@ RilObject.prototype = {
|
|||
* Integer doing something XXX TODO
|
||||
*/
|
||||
dialNonEmergencyNumber: function(options) {
|
||||
let onerror = (function onerror(options, errorMsg) {
|
||||
options.success = false;
|
||||
options.errorMsg = errorMsg;
|
||||
this.sendChromeMessage(options);
|
||||
}).bind(this, options);
|
||||
|
||||
if (this.radioState == GECKO_RADIOSTATE_OFF) {
|
||||
// Notify error in establishing the call without radio.
|
||||
onerror(GECKO_ERROR_RADIO_NOT_AVAILABLE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.voiceRegistrationState.emergencyCallsOnly) {
|
||||
onerror(RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_UNOBTAINABLE_NUMBER]);
|
||||
return;
|
||||
}
|
||||
|
||||
// Exit emergency callback mode when user dial a non-emergency call.
|
||||
if (this._isInEmergencyCbMode) {
|
||||
this.exitEmergencyCbMode();
|
||||
|
@ -1614,7 +1694,6 @@ RilObject.prototype = {
|
|||
}
|
||||
|
||||
options.request = REQUEST_DIAL;
|
||||
options.isEmergency = false;
|
||||
this.sendDialRequest(options);
|
||||
},
|
||||
|
||||
|
@ -1629,30 +1708,8 @@ RilObject.prototype = {
|
|||
* Integer doing something XXX TODO
|
||||
*/
|
||||
dialEmergencyNumber: function(options) {
|
||||
let onerror = (function onerror(options, errorMsg) {
|
||||
options.success = false;
|
||||
options.errorMsg = errorMsg;
|
||||
this.sendChromeMessage(options);
|
||||
}).bind(this, options);
|
||||
|
||||
options.request = RILQUIRKS_REQUEST_USE_DIAL_EMERGENCY_CALL ?
|
||||
REQUEST_DIAL_EMERGENCY_CALL : REQUEST_DIAL;
|
||||
options.isEmergency = true;
|
||||
|
||||
if (this.radioState == GECKO_RADIOSTATE_OFF) {
|
||||
if (DEBUG) {
|
||||
this.context.debug("Automatically enable radio for an emergency call.");
|
||||
}
|
||||
|
||||
if (!this.cachedDialRequest) {
|
||||
this.cachedDialRequest = {};
|
||||
}
|
||||
this.cachedDialRequest.onerror = onerror;
|
||||
this.cachedDialRequest.callback = this.sendDialRequest.bind(this, options);
|
||||
this.setRadioEnabled({enabled: true});
|
||||
return;
|
||||
}
|
||||
|
||||
this.sendDialRequest(options);
|
||||
},
|
||||
|
||||
|
@ -3903,35 +3960,20 @@ RilObject.prototype = {
|
|||
}
|
||||
}
|
||||
|
||||
this.operator.longName = longName;
|
||||
this.operator.shortName = shortName;
|
||||
|
||||
let ICCUtilsHelper = this.context.ICCUtilsHelper;
|
||||
let networkName;
|
||||
// We won't get network name using PNN and OPL if voice registration isn't ready
|
||||
if (this.voiceRegistrationState.cell &&
|
||||
this.voiceRegistrationState.cell.gsmLocationAreaCode != -1) {
|
||||
networkName = ICCUtilsHelper.getNetworkNameFromICC(
|
||||
this.operator.mcc,
|
||||
this.operator.mnc,
|
||||
this.voiceRegistrationState.cell.gsmLocationAreaCode);
|
||||
}
|
||||
|
||||
if (networkName) {
|
||||
if (DEBUG) {
|
||||
this.context.debug("Operator names will be overriden: " +
|
||||
"longName = " + networkName.fullName + ", " +
|
||||
"shortName = " + networkName.shortName);
|
||||
}
|
||||
|
||||
this.operator.longName = networkName.fullName;
|
||||
this.operator.shortName = networkName.shortName;
|
||||
} else {
|
||||
this.operator.longName = longName;
|
||||
this.operator.shortName = shortName;
|
||||
}
|
||||
|
||||
if (ICCUtilsHelper.updateDisplayCondition()) {
|
||||
ICCUtilsHelper.handleICCInfoChange();
|
||||
}
|
||||
this._sendNetworkInfoMessage(NETWORK_INFO_OPERATOR, this.operator);
|
||||
|
||||
// NETWORK_INFO_OPERATOR message will be sent out by overrideICCNetworkName
|
||||
// itself if operator name is overridden after checking, or we have to
|
||||
// do it by ourself.
|
||||
if (!this.overrideICCNetworkName()) {
|
||||
this._sendNetworkInfoMessage(NETWORK_INFO_OPERATOR, this.operator);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -8676,7 +8718,7 @@ GsmPDUHelperObject.prototype = {
|
|||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
};
|
||||
|
||||
let totalLength = 0, length, pageLengths = [];
|
||||
for (let i = 0; i < numOfPages; i++) {
|
||||
|
@ -13695,11 +13737,14 @@ SimRecordHelperObject.prototype = {
|
|||
}
|
||||
Buf.readStringDelimiter(strLen);
|
||||
|
||||
let RIL = this.context.RIL;
|
||||
if (options.p1 < options.totalRecords) {
|
||||
ICCIOHelper.loadNextRecord(options);
|
||||
} else {
|
||||
this.context.RIL.iccInfoPrivate.OPL = opl;
|
||||
RIL.iccInfoPrivate.OPL = opl;
|
||||
}
|
||||
|
||||
RIL.overrideICCNetworkName();
|
||||
}
|
||||
|
||||
ICCIOHelper.loadLinearFixedEF({fileId: ICC_EF_OPL,
|
||||
|
@ -13757,6 +13802,7 @@ SimRecordHelperObject.prototype = {
|
|||
pnn.push(pnnElement);
|
||||
}
|
||||
|
||||
let RIL = this.context.RIL;
|
||||
// Will ignore remaining records when got the contents of a record are all 0xff.
|
||||
if (pnnElement && options.p1 < options.totalRecords) {
|
||||
ICCIOHelper.loadNextRecord(options);
|
||||
|
@ -13766,8 +13812,10 @@ SimRecordHelperObject.prototype = {
|
|||
this.context.debug("PNN: [" + i + "]: " + JSON.stringify(pnn[i]));
|
||||
}
|
||||
}
|
||||
this.context.RIL.iccInfoPrivate.PNN = pnn;
|
||||
RIL.iccInfoPrivate.PNN = pnn;
|
||||
}
|
||||
|
||||
RIL.overrideICCNetworkName();
|
||||
}
|
||||
|
||||
let pnn = [];
|
||||
|
@ -14204,17 +14252,55 @@ ICCUtilsHelperObject.prototype = {
|
|||
pnnEntry = iccInfoPriv.PNN[0];
|
||||
}
|
||||
} else {
|
||||
let GsmPDUHelper = this.context.GsmPDUHelper;
|
||||
let wildChar = GsmPDUHelper.bcdChars.charAt(0x0d);
|
||||
// According to 3GPP TS 31.102 Sec. 4.2.59 and 3GPP TS 51.011 Sec. 10.3.42,
|
||||
// the ME shall use this EF_OPL in association with the EF_PNN in place
|
||||
// of any network name stored within the ME's internal list and any network
|
||||
// name received when registered to the PLMN.
|
||||
let length = iccInfoPriv.OPL ? iccInfoPriv.OPL.length : 0;
|
||||
for (let i = 0; i < length; i++) {
|
||||
let unmatch = false;
|
||||
let opl = iccInfoPriv.OPL[i];
|
||||
// Try to match the MCC/MNC.
|
||||
if (mcc != opl.mcc || mnc != opl.mnc) {
|
||||
// Try to match the MCC/MNC. Besides, A BCD value of 'D' in any of the
|
||||
// MCC and/or MNC digits shall be used to indicate a "wild" value for
|
||||
// that corresponding MCC/MNC digit.
|
||||
if (opl.mcc.indexOf(wildChar) !== -1) {
|
||||
for (let j = 0; j < opl.mcc.length; j++) {
|
||||
if (opl.mcc[j] !== wildChar && opl.mcc[j] !== mcc[j]) {
|
||||
unmatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (unmatch) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (mcc !== opl.mcc) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (mnc.length !== opl.mnc.length) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (opl.mnc.indexOf(wildChar) !== -1) {
|
||||
for (let j = 0; j < opl.mnc.length; j++) {
|
||||
if (opl.mnc[j] !== wildChar && opl.mnc[j] !== mnc[j]) {
|
||||
unmatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (unmatch) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (mnc !== opl.mnc) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to match the location area code. If current local area code is
|
||||
// covered by lac range that specified in the OPL entry, use the PNN
|
||||
// that specified in the OPL entry.
|
||||
|
|
|
@ -161,12 +161,12 @@ add_test(function test_get_network_name_from_icc() {
|
|||
}
|
||||
|
||||
// Before EF_OPL and EF_PNN have been loaded.
|
||||
testGetNetworkNameFromICC({mcc: 123, mnc: 456, lac: 0x1000}, null);
|
||||
testGetNetworkNameFromICC({mcc: 321, mnc: 654, lac: 0x2000}, null);
|
||||
testGetNetworkNameFromICC({mcc: "123", mnc: "456", lac: 0x1000}, null);
|
||||
testGetNetworkNameFromICC({mcc: "321", mnc: "654", lac: 0x2000}, null);
|
||||
|
||||
// Set HPLMN
|
||||
RIL.iccInfo.mcc = 123;
|
||||
RIL.iccInfo.mnc = 456;
|
||||
RIL.iccInfo.mcc = "123";
|
||||
RIL.iccInfo.mnc = "456";
|
||||
|
||||
RIL.voiceRegistrationState = {
|
||||
cell: {
|
||||
|
@ -181,56 +181,108 @@ add_test(function test_get_network_name_from_icc() {
|
|||
{"fullName": "PNN1Long", "shortName": "PNN1Short"},
|
||||
{"fullName": "PNN2Long", "shortName": "PNN2Short"},
|
||||
{"fullName": "PNN3Long", "shortName": "PNN3Short"},
|
||||
{"fullName": "PNN4Long", "shortName": "PNN4Short"}
|
||||
{"fullName": "PNN4Long", "shortName": "PNN4Short"},
|
||||
{"fullName": "PNN5Long", "shortName": "PNN5Short"},
|
||||
{"fullName": "PNN6Long", "shortName": "PNN6Short"},
|
||||
{"fullName": "PNN7Long", "shortName": "PNN7Short"},
|
||||
{"fullName": "PNN8Long", "shortName": "PNN8Short"}
|
||||
]
|
||||
};
|
||||
|
||||
// EF_OPL isn't available and current isn't in HPLMN,
|
||||
testGetNetworkNameFromICC({mcc: 321, mnc: 654, lac: 0x1000}, null);
|
||||
testGetNetworkNameFromICC({mcc: "321", mnc: "654", lac: 0x1000}, null);
|
||||
|
||||
// EF_OPL isn't available and current is in HPLMN,
|
||||
// the first record of PNN should be returned.
|
||||
testGetNetworkNameFromICC({mcc: 123, mnc: 456, lac: 0x1000},
|
||||
testGetNetworkNameFromICC({mcc: "123", mnc: "456", lac: 0x1000},
|
||||
{longName: "PNN1Long", shortName: "PNN1Short"});
|
||||
|
||||
// Set EF_OPL
|
||||
RIL.iccInfoPrivate.OPL = [
|
||||
{
|
||||
"mcc": 123,
|
||||
"mnc": 456,
|
||||
"mcc": "123",
|
||||
"mnc": "456",
|
||||
"lacTacStart": 0,
|
||||
"lacTacEnd": 0xFFFE,
|
||||
"pnnRecordId": 4
|
||||
},
|
||||
{
|
||||
"mcc": 321,
|
||||
"mnc": 654,
|
||||
"mcc": "321",
|
||||
"mnc": "654",
|
||||
"lacTacStart": 0,
|
||||
"lacTacEnd": 0x0010,
|
||||
"pnnRecordId": 3
|
||||
},
|
||||
{
|
||||
"mcc": 321,
|
||||
"mnc": 654,
|
||||
"mcc": "321",
|
||||
"mnc": "654",
|
||||
"lacTacStart": 0x0100,
|
||||
"lacTacEnd": 0x1010,
|
||||
"pnnRecordId": 2
|
||||
},
|
||||
{
|
||||
"mcc": ";;;",
|
||||
"mnc": "01",
|
||||
"lacTacStart": 0,
|
||||
"lacTacEnd": 0xFFFE,
|
||||
"pnnRecordId": 5
|
||||
},
|
||||
{
|
||||
"mcc": "00;",
|
||||
"mnc": "02",
|
||||
"lacTacStart": 0,
|
||||
"lacTacEnd": 0xFFFE,
|
||||
"pnnRecordId": 6
|
||||
},
|
||||
{
|
||||
"mcc": "001",
|
||||
"mnc": ";;",
|
||||
"lacTacStart": 0,
|
||||
"lacTacEnd": 0xFFFE,
|
||||
"pnnRecordId": 7
|
||||
},
|
||||
{
|
||||
"mcc": "002",
|
||||
"mnc": "0;",
|
||||
"lacTacStart": 0,
|
||||
"lacTacEnd": 0xFFFE,
|
||||
"pnnRecordId": 8
|
||||
}
|
||||
];
|
||||
|
||||
// Both EF_PNN and EF_OPL are presented, and current PLMN is HPLMN,
|
||||
testGetNetworkNameFromICC({mcc: 123, mnc: 456, lac: 0x1000},
|
||||
testGetNetworkNameFromICC({mcc: "123", mnc: "456", lac: 0x1000},
|
||||
{longName: "PNN4Long", shortName: "PNN4Short"});
|
||||
|
||||
// Current PLMN is not HPLMN, and according to LAC, we should get
|
||||
// the second PNN record.
|
||||
testGetNetworkNameFromICC({mcc: 321, mnc: 654, lac: 0x1000},
|
||||
testGetNetworkNameFromICC({mcc: "321", mnc: "654", lac: 0x1000},
|
||||
{longName: "PNN2Long", shortName: "PNN2Short"});
|
||||
|
||||
// Current PLMN is not HPLMN, and according to LAC, we should get
|
||||
// the thrid PNN record.
|
||||
testGetNetworkNameFromICC({mcc: 321, mnc: 654, lac: 0x0001},
|
||||
testGetNetworkNameFromICC({mcc: "321", mnc: "654", lac: 0x0001},
|
||||
{longName: "PNN3Long", shortName: "PNN3Short"});
|
||||
|
||||
// Current PLMN is not HPLMN, and according to LAC, we should get
|
||||
// the 5th PNN record after wild char (ie: ';') handling.
|
||||
testGetNetworkNameFromICC({mcc: "001", mnc: "01", lac: 0x0001},
|
||||
{longName: "PNN5Long", shortName: "PNN5Short"});
|
||||
|
||||
// Current PLMN is not HPLMN, and according to LAC, we should get
|
||||
// the 6th PNN record after wild char (ie: ';') handling.
|
||||
testGetNetworkNameFromICC({mcc: "001", mnc: "02", lac: 0x0001},
|
||||
{longName: "PNN6Long", shortName: "PNN6Short"});
|
||||
|
||||
// Current PLMN is not HPLMN, and according to LAC, we should get
|
||||
// the 7th PNN record after wild char (ie: ';') handling.
|
||||
testGetNetworkNameFromICC({mcc: "001", mnc: "03", lac: 0x0001},
|
||||
{longName: "PNN7Long", shortName: "PNN7Short"});
|
||||
|
||||
// Current PLMN is not HPLMN, and according to LAC, we should get
|
||||
// the 8th PNN record after wild char (ie: ';') handling.
|
||||
testGetNetworkNameFromICC({mcc: "002", mnc: "03", lac: 0x0001},
|
||||
{longName: "PNN8Long", shortName: "PNN8Short"});
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
|
|
@ -466,6 +466,13 @@ TelephonyService.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
// We can only have at most two calls on the same line (client).
|
||||
if (this._numCallsOnLine(aClientId) >= 2) {
|
||||
if (DEBUG) debug("Error: Already has more than 2 calls on line.");
|
||||
aCallback.notifyDialError(DIAL_ERROR_INVALID_STATE_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
// For DSDS, if there is aleady a call on SIM 'aClientId', we cannot place
|
||||
// any new call on other SIM.
|
||||
if (this._hasCallsOnOtherClient(aClientId)) {
|
||||
|
@ -474,13 +481,6 @@ TelephonyService.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
// We can only have at most two calls on the same line (client).
|
||||
if (this._numCallsOnLine(aClientId) >= 2) {
|
||||
if (DEBUG) debug("Error: Has more than 2 calls on line.");
|
||||
aCallback.notifyDialError(DIAL_ERROR_INVALID_STATE_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
// We don't try to be too clever here, as the phone is probably in the
|
||||
// locked state. Let's just check if it's a number without normalizing
|
||||
if (!aIsDialEmergency) {
|
||||
|
@ -495,33 +495,27 @@ TelephonyService.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
if (this._isEmergencyNumber(aNumber)) {
|
||||
// Select a proper clientId for dialEmergency.
|
||||
aClientId = gRadioInterfaceLayer.getClientIdForEmergencyCall() ;
|
||||
let isEmergencyNumber = this._isEmergencyNumber(aNumber);
|
||||
|
||||
if (isEmergencyNumber) {
|
||||
// Automatically select a proper clientId for emergency call.
|
||||
aClientId = gRadioInterfaceLayer.getClientIdForEmergencyCall() ;
|
||||
if (aClientId === -1) {
|
||||
if (DEBUG) debug("Error: No client is avaialble for emergency call.");
|
||||
aCallback.notifyDialError(DIAL_ERROR_INVALID_STATE_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
this._dialInternal(aClientId, "dialEmergencyNumber", aNumber, aCallback);
|
||||
} else {
|
||||
// Shouldn't dial a non-emergency number by dialEmergency.
|
||||
if (aIsDialEmergency) {
|
||||
if (DEBUG) debug("Error: dialEmergency with a non-emergency number");
|
||||
aCallback.notifyDialError(DIAL_ERROR_BAD_NUMBER);
|
||||
return;
|
||||
}
|
||||
|
||||
this._dialInternal(aClientId, "dialNonEmergencyNumber", aNumber, aCallback);
|
||||
}
|
||||
},
|
||||
|
||||
_dialInternal: function(aClientId, aMsg, aNumber, aCallback) {
|
||||
this.isDialing = true;
|
||||
this._getClient(aClientId).sendWorkerMessage(aMsg,
|
||||
{number: aNumber},
|
||||
|
||||
let options = {
|
||||
isDialEmergency: aIsDialEmergency,
|
||||
isEmergency: isEmergencyNumber,
|
||||
number: aNumber
|
||||
};
|
||||
|
||||
this._getClient(aClientId).sendWorkerMessage("dial", options,
|
||||
(function(response) {
|
||||
this.isDialing = false;
|
||||
if (!response.success) {
|
||||
|
|
|
@ -494,6 +494,36 @@ let emulator = (function() {
|
|||
return deferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an outgoing emergency call.
|
||||
*
|
||||
* @param number
|
||||
* A string.
|
||||
* @return A deferred promise.
|
||||
*/
|
||||
function dialEmergency(number) {
|
||||
log("Make an outgoing emergency call: " + number);
|
||||
|
||||
let deferred = Promise.defer();
|
||||
|
||||
telephony.dialEmergency(number).then(call => {
|
||||
ok(call);
|
||||
is(call.id.number, number);
|
||||
is(call.state, "dialing");
|
||||
|
||||
call.onalerting = function onalerting(event) {
|
||||
call.onalerting = null;
|
||||
log("Received 'onalerting' call event.");
|
||||
checkEventCallState(event, call, "alerting");
|
||||
deferred.resolve(call);
|
||||
};
|
||||
}, cause => {
|
||||
deferred.reject(cause);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Answer an incoming call.
|
||||
*
|
||||
|
@ -1160,6 +1190,7 @@ let emulator = (function() {
|
|||
this.gCheckState = checkState;
|
||||
this.gCheckAll = checkAll;
|
||||
this.gDial = dial;
|
||||
this.gDialEmergency = dialEmergency;
|
||||
this.gAnswer = answer;
|
||||
this.gHangUp = hangUp;
|
||||
this.gHold = hold;
|
||||
|
|
|
@ -62,3 +62,4 @@ disabled = Bug 821958
|
|||
[test_call_presentation.js]
|
||||
[test_incomingcall_phonestate_speaker.js]
|
||||
[test_temporary_clir.js]
|
||||
[test_outgoing_error_state.js]
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 60000;
|
||||
MARIONETTE_HEAD_JS = 'head.js';
|
||||
|
||||
const number = "0912345678";
|
||||
|
||||
function setRadioEnabled(enabled) {
|
||||
log("Set radio enabled: " + enabled + ".");
|
||||
|
||||
let desiredRadioState = enabled ? 'enabled' : 'disabled';
|
||||
let deferred = Promise.defer();
|
||||
let connection = navigator.mozMobileConnections[0];
|
||||
ok(connection instanceof MozMobileConnection,
|
||||
"connection is instanceof " + connection.constructor);
|
||||
|
||||
connection.onradiostatechange = function() {
|
||||
let state = connection.radioState;
|
||||
log("Received 'radiostatechange' event, radioState: " + state);
|
||||
|
||||
// We are waiting for 'desiredRadioState.' Ignore any transient state.
|
||||
if (state === desiredRadioState) {
|
||||
connection.onradiostatechange = null;
|
||||
deferred.resolve();
|
||||
}
|
||||
};
|
||||
connection.setRadioEnabled(enabled);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
startTestWithPermissions(['mobileconnection'], function() {
|
||||
let outCall;
|
||||
setRadioEnabled(false)
|
||||
.then(() => gDial(number))
|
||||
.then(null, cause => { is(cause, "RadioNotAvailable"); })
|
||||
.then(() => gDialEmergency(number))
|
||||
.then(null, cause => { is(cause, "RadioNotAvailable"); })
|
||||
.then(() => setRadioEnabled(true))
|
||||
.then(() => gDialEmergency(number))
|
||||
.then(null, cause => { is(cause, "BadNumberError"); })
|
||||
.then(finish);
|
||||
});
|
|
@ -1,2 +0,0 @@
|
|||
[test_legacy.html]
|
||||
skip-if = e10s
|
|
@ -2,4 +2,3 @@
|
|||
skip-if = e10s
|
||||
|
||||
[test_getRandomValues.html]
|
||||
[test_no_legacy.html]
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test presence of legacy window.crypto features when
|
||||
MOZ_DISABLE_CRYPTOLEGACY is NOT set and dom.unsafe_legacy_crypto.enabled is true</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
function test_unsafe_legacy_crypto_enabled() {
|
||||
ok("crypto" in window, "crypto in window");
|
||||
ok("version" in window.crypto, "version in window.crypto");
|
||||
ok("enableSmartCardEvents" in window.crypto,
|
||||
"enableSmartCardEvents in window.crypto");
|
||||
ok("generateCRMFRequest" in window.crypto,
|
||||
"generateCRMFRequest in window.crypto");
|
||||
ok("importUserCertificates" in window.crypto,
|
||||
"importUserCertificates in window.crypto");
|
||||
ok("signText" in window.crypto, "signText in window.crypto");
|
||||
|
||||
function jsCallback () {
|
||||
}
|
||||
|
||||
try {
|
||||
window.crypto.generateCRMFRequest(null, null, null, null, jsCallback.toString());
|
||||
ok(false, "window.crypto.generateCRMFRequest failed, should throw error");
|
||||
} catch (e) {
|
||||
ok(e.toString().search(/Failure/) > -1,
|
||||
"Expected error: ReqDN cannot be null");
|
||||
}
|
||||
|
||||
try {
|
||||
window.crypto.generateCRMFRequest(document.documentElement, null, null, null,
|
||||
null);
|
||||
ok(false, "window.crypto.generateCRMFRequest failed, should throw error");
|
||||
} catch (e) {
|
||||
ok(e.toString().search(/Failure/) > -1,
|
||||
"Expected error: jsCallback cannot be null");
|
||||
}
|
||||
|
||||
try {
|
||||
window.crypto.generateCRMFRequest(document.documentElement, null, null, null,
|
||||
jsCallback.toString(), 1024);
|
||||
ok(false, "window.crypto.generateCRMFRequest failed, should throw error");
|
||||
} catch (e) {
|
||||
ok(e.toString().search(/TypeError/) > -1,
|
||||
"Expected error: Not enough arguments");
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.unsafe_legacy_crypto.enabled", true]]},
|
||||
test_unsafe_legacy_crypto_enabled);
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
</body></html>
|
|
@ -1,23 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test lack of legacy window.crypto features when
|
||||
MOZ_DISABLE_CRYPTOLEGACY is set or dom.unsafe_legacy_crypto.enabled is false</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
ok("crypto" in window, "crypto in window");
|
||||
ok(!("version" in window.crypto), "version not in window.crypto");
|
||||
ok(!("enableSmartCardEvents" in window.crypto),
|
||||
"enableSmartCardEvents not in window.crypto");
|
||||
ok(!("generateCRMFRequest" in window.crypto),
|
||||
"generateCRMFRequest not in window.crypto");
|
||||
ok(!("importUserCertificates" in window.crypto),
|
||||
"importUserCertificates not in window.crypto");
|
||||
ok(!("signText" in window.crypto), "signText not in window.crypto");
|
||||
|
||||
</script>
|
||||
</body></html>
|
|
@ -857,8 +857,6 @@ var interfaceNamesInGlobalScope =
|
|||
"SimpleGestureEvent",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "SimpleTest", xbl: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"SmartCardEvent",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "SpeechSynthesisEvent", b2g: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
|
|
@ -48,11 +48,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gtk2':
|
|||
'mochitest/pointerlock/mochitest.ini',
|
||||
]
|
||||
|
||||
if not CONFIG['MOZ_DISABLE_CRYPTOLEGACY']:
|
||||
MOCHITEST_MANIFESTS += [
|
||||
'mochitest/crypto/mochitest-legacy.ini',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_GAMEPAD']:
|
||||
MOCHITEST_MANIFESTS += [
|
||||
'mochitest/gamepad/mochitest.ini',
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/.
|
||||
*/
|
||||
|
||||
[NoInterfaceObject]
|
||||
interface CRMFObject {
|
||||
readonly attribute DOMString request;
|
||||
};
|
|
@ -19,38 +19,3 @@ interface Crypto {
|
|||
[Pref="dom.webcrypto.enabled"]
|
||||
readonly attribute SubtleCrypto subtle;
|
||||
};
|
||||
|
||||
#ifndef MOZ_DISABLE_CRYPTOLEGACY
|
||||
[NoInterfaceObject]
|
||||
interface CryptoLegacy {
|
||||
[Pref="dom.unsafe_legacy_crypto.enabled"]
|
||||
readonly attribute DOMString version;
|
||||
|
||||
[SetterThrows,Pref="dom.unsafe_legacy_crypto.enabled"]
|
||||
attribute boolean enableSmartCardEvents;
|
||||
|
||||
[Throws,NewObject,Pref="dom.unsafe_legacy_crypto.enabled"]
|
||||
CRMFObject? generateCRMFRequest(ByteString? reqDN,
|
||||
ByteString? regToken,
|
||||
ByteString? authenticator,
|
||||
ByteString? eaCert,
|
||||
ByteString? jsCallback,
|
||||
any... args);
|
||||
|
||||
[Throws,Pref="dom.unsafe_legacy_crypto.enabled"]
|
||||
DOMString importUserCertificates(DOMString nickname,
|
||||
DOMString cmmfResponse,
|
||||
boolean doForcedBackup);
|
||||
|
||||
[Pref="dom.unsafe_legacy_crypto.enabled"]
|
||||
DOMString signText(DOMString stringToSign,
|
||||
DOMString caOption,
|
||||
ByteString... args);
|
||||
|
||||
[Throws,Pref="dom.unsafe_legacy_crypto.enabled"]
|
||||
void logout();
|
||||
};
|
||||
|
||||
Crypto implements CryptoLegacy;
|
||||
#endif // !MOZ_DISABLE_CRYPTOLEGACY
|
||||
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/.
|
||||
*/
|
||||
|
||||
[Constructor(DOMString type, optional SmartCardEventInit eventInitDict)]
|
||||
interface SmartCardEvent : Event
|
||||
{
|
||||
readonly attribute DOMString? tokenName;
|
||||
};
|
||||
|
||||
dictionary SmartCardEventInit : EventInit
|
||||
{
|
||||
DOMString tokenName = "";
|
||||
};
|
|
@ -552,7 +552,6 @@ WEBIDL_FILES += [
|
|||
'PopupBlockedEvent.webidl',
|
||||
'ProgressEvent.webidl',
|
||||
'RecordErrorEvent.webidl',
|
||||
'SmartCardEvent.webidl',
|
||||
'StyleRuleChangeEvent.webidl',
|
||||
'StyleSheetApplicableStateChangeEvent.webidl',
|
||||
'StyleSheetChangeEvent.webidl',
|
||||
|
@ -627,11 +626,6 @@ if CONFIG['MOZ_B2G_FM']:
|
|||
'FMRadio.webidl',
|
||||
]
|
||||
|
||||
if not CONFIG['MOZ_DISABLE_CRYPTOLEGACY']:
|
||||
WEBIDL_FILES += [
|
||||
'CRMFObject.webidl',
|
||||
]
|
||||
|
||||
GENERATED_EVENTS_WEBIDL_FILES = [
|
||||
'AutocompleteErrorEvent.webidl',
|
||||
'BlobEvent.webidl',
|
||||
|
@ -672,7 +666,6 @@ GENERATED_EVENTS_WEBIDL_FILES = [
|
|||
'RTCPeerConnectionIdentityErrorEvent.webidl',
|
||||
'RTCPeerConnectionIdentityEvent.webidl',
|
||||
'SelectionChangeEvent.webidl',
|
||||
'SmartCardEvent.webidl',
|
||||
'StyleRuleChangeEvent.webidl',
|
||||
'StyleSheetApplicableStateChangeEvent.webidl',
|
||||
'StyleSheetChangeEvent.webidl',
|
||||
|
|
|
@ -17,6 +17,7 @@ USING_WORKERS_NAMESPACE
|
|||
ServiceWorker::ServiceWorker(nsPIDOMWindow* aWindow,
|
||||
SharedWorker* aSharedWorker)
|
||||
: DOMEventTargetHelper(aWindow),
|
||||
mState(ServiceWorkerState::Installing),
|
||||
mSharedWorker(aSharedWorker)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "nsString.h"
|
||||
#include "nsIDialogParamBlock.h"
|
||||
#include "nsIMutableArray.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
|
||||
/****************************************************************
|
||||
************************ nsCookiePromptService *****************
|
||||
|
@ -71,6 +72,11 @@ nsCookiePromptService::CookieDialog(nsIDOMWindow *aParent,
|
|||
parent = do_QueryInterface(privateParent);
|
||||
}
|
||||
|
||||
// We're opening a chrome window and passing in a nsIDialogParamBlock. Setting
|
||||
// the nsIDialogParamBlock as the .arguments property on the chrome window
|
||||
// requires system principals on the stack, so we use an AutoNoJSAPI for that.
|
||||
mozilla::dom::AutoNoJSAPI nojsapi;
|
||||
|
||||
// The cookie dialog will be modal for the root chrome window rather than the
|
||||
// tab containing the permission-requesting page. This removes confusion
|
||||
// about which monitor is displaying the dialog (see bug 470356), but also
|
||||
|
|
|
@ -38,3 +38,4 @@ support-files =
|
|||
[test_same_base_domain_5.html]
|
||||
[test_same_base_domain_6.html]
|
||||
[test_samedomain.html]
|
||||
[test_bug1041808.html]
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1041808
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 1041808</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 1041808 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var dialogsOpened = 0;
|
||||
var dialogsClosed = 0;
|
||||
function dismissDialog(aSubject, aTopic, aData)
|
||||
{
|
||||
if (aTopic == "domwindowopened") {
|
||||
var win = SpecialPowers.wrap(aSubject);
|
||||
win.addEventListener("pageshow", function() {
|
||||
win.removeEventListener("pageshow", arguments.callee, false);
|
||||
sendKey("RETURN", aSubject);
|
||||
}, false);
|
||||
++dialogsOpened;
|
||||
} else if (aTopic == "domwindowclosed") {
|
||||
++dialogsClosed;
|
||||
}
|
||||
}
|
||||
|
||||
function runTest()
|
||||
{
|
||||
SpecialPowers.Services.ww.registerNotification(dismissDialog);
|
||||
document.cookie = "test1=testValue";
|
||||
document.cookie = "test2=testValue";
|
||||
document.cookie = "test3=testValue";
|
||||
SpecialPowers.Services.ww.unregisterNotification(dismissDialog);
|
||||
is(dialogsOpened, 3, "Setting a cookie should have asked for permission");
|
||||
is(dialogsOpened - dialogsClosed, 0,
|
||||
"Setting a cookie shouldn't have left any additional windows open");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv({"set": [["network.cookie.lifetimePolicy", 1]]},
|
||||
runTest);
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1041808">Mozilla Bug 1041808</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -123,6 +123,9 @@ ValidateGlobalVariable(JSContext *cx, const AsmJSModule &module, AsmJSModule::Gl
|
|||
if (!GetDataProperty(cx, importVal, field, &v))
|
||||
return false;
|
||||
|
||||
if (!v.isPrimitive())
|
||||
return LinkFail(cx, "Imported values must be primitives");
|
||||
|
||||
switch (global.varInitCoercion()) {
|
||||
case AsmJS_ToInt32:
|
||||
if (!ToInt32(cx, v, (int32_t *)datum))
|
||||
|
@ -181,6 +184,7 @@ ValidateMathBuiltinFunction(JSContext *cx, AsmJSModule::Global &global, HandleVa
|
|||
RootedValue v(cx);
|
||||
if (!GetDataProperty(cx, globalVal, cx->names().Math, &v))
|
||||
return false;
|
||||
|
||||
RootedPropertyName field(cx, global.mathName());
|
||||
if (!GetDataProperty(cx, v, field, &v))
|
||||
return false;
|
||||
|
@ -226,6 +230,7 @@ ValidateConstant(JSContext *cx, AsmJSModule::Global &global, HandleValue globalV
|
|||
|
||||
if (!GetDataProperty(cx, v, field, &v))
|
||||
return false;
|
||||
|
||||
if (!v.isNumber())
|
||||
return LinkFail(cx, "math / global constant value needs to be a number");
|
||||
|
||||
|
|
|
@ -38,29 +38,47 @@ extern const JSFunctionSpec Int32x4Methods[];
|
|||
|
||||
static const char *laneNames[] = {"lane 0", "lane 1", "lane 2", "lane3"};
|
||||
|
||||
template<typename V>
|
||||
static bool
|
||||
IsVectorObject(HandleValue v)
|
||||
{
|
||||
if (!v.isObject())
|
||||
return false;
|
||||
|
||||
JSObject &obj = v.toObject();
|
||||
if (!obj.is<TypedObject>())
|
||||
return false;
|
||||
|
||||
TypeDescr &typeRepr = obj.as<TypedObject>().typeDescr();
|
||||
if (typeRepr.kind() != type::X4)
|
||||
return false;
|
||||
|
||||
return typeRepr.as<X4TypeDescr>().type() == V::type;
|
||||
}
|
||||
|
||||
template<typename Elem>
|
||||
static Elem
|
||||
TypedObjectMemory(HandleValue v)
|
||||
{
|
||||
TypedObject &obj = v.toObject().as<TypedObject>();
|
||||
MOZ_ASSERT(!obj.owner().isNeutered());
|
||||
return reinterpret_cast<Elem>(obj.typedMem());
|
||||
}
|
||||
|
||||
template<typename Type32x4, int lane>
|
||||
static bool GetX4Lane(JSContext *cx, unsigned argc, Value *vp) {
|
||||
static bool GetX4Lane(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
typedef typename Type32x4::Elem Elem;
|
||||
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
if (!args.thisv().isObject() || !args.thisv().toObject().is<TypedObject>()) {
|
||||
if (!IsVectorObject<Type32x4>(args.thisv())) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
|
||||
X4TypeDescr::class_.name, laneNames[lane],
|
||||
InformalValueTypeName(args.thisv()));
|
||||
return false;
|
||||
}
|
||||
|
||||
TypedObject &typedObj = args.thisv().toObject().as<TypedObject>();
|
||||
TypeDescr &descr = typedObj.typeDescr();
|
||||
if (descr.kind() != type::X4 || descr.as<X4TypeDescr>().type() != Type32x4::type) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
|
||||
X4TypeDescr::class_.name, laneNames[lane],
|
||||
InformalValueTypeName(args.thisv()));
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!typedObj.owner().isNeutered());
|
||||
Elem *data = reinterpret_cast<Elem *>(typedObj.typedMem());
|
||||
Elem *data = TypedObjectMemory<Elem *>(args.thisv());
|
||||
Type32x4::setReturn(args, data[lane]);
|
||||
return true;
|
||||
}
|
||||
|
@ -82,7 +100,8 @@ static bool type##Lane##lane(JSContext *cx, unsigned argc, Value *vp) { \
|
|||
#undef LANE_ACCESSOR
|
||||
|
||||
template<typename Type32x4>
|
||||
static bool SignMask(JSContext *cx, unsigned argc, Value *vp) {
|
||||
static bool SignMask(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
typedef typename Type32x4::Elem Elem;
|
||||
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
@ -388,33 +407,6 @@ js_InitSIMDClass(JSContext *cx, HandleObject obj)
|
|||
return SIMDObject::initClass(cx, global);
|
||||
}
|
||||
|
||||
template<typename V>
|
||||
static bool
|
||||
IsVectorObject(HandleValue v)
|
||||
{
|
||||
if (!v.isObject())
|
||||
return false;
|
||||
|
||||
JSObject &obj = v.toObject();
|
||||
if (!obj.is<TypedObject>())
|
||||
return false;
|
||||
|
||||
TypeDescr &typeRepr = obj.as<TypedObject>().typeDescr();
|
||||
if (typeRepr.kind() != type::X4)
|
||||
return false;
|
||||
|
||||
return typeRepr.as<X4TypeDescr>().type() == V::type;
|
||||
}
|
||||
|
||||
template<typename Elem>
|
||||
static Elem
|
||||
TypedObjectMemory(HandleValue v)
|
||||
{
|
||||
TypedObject &obj = v.toObject().as<TypedObject>();
|
||||
MOZ_ASSERT(!obj.owner().isNeutered());
|
||||
return reinterpret_cast<Elem>(obj.typedMem());
|
||||
}
|
||||
|
||||
template<typename V>
|
||||
JSObject *
|
||||
js::CreateSimd(JSContext *cx, typename V::Elem *data)
|
||||
|
@ -437,30 +429,33 @@ template JSObject *js::CreateSimd<Float32x4>(JSContext *cx, Float32x4::Elem *dat
|
|||
template JSObject *js::CreateSimd<Int32x4>(JSContext *cx, Int32x4::Elem *data);
|
||||
|
||||
namespace js {
|
||||
// Unary SIMD operators
|
||||
template<typename T>
|
||||
struct Abs {
|
||||
static inline T apply(T x, T zero) { return x < 0 ? -1 * x : x; }
|
||||
static inline T apply(T x) { return x < 0 ? -1 * x : x; }
|
||||
};
|
||||
template<typename T>
|
||||
struct Neg {
|
||||
static inline T apply(T x, T zero) { return -1 * x; }
|
||||
static inline T apply(T x) { return -1 * x; }
|
||||
};
|
||||
template<typename T>
|
||||
struct Not {
|
||||
static inline T apply(T x, T zero) { return ~x; }
|
||||
static inline T apply(T x) { return ~x; }
|
||||
};
|
||||
template<typename T>
|
||||
struct Rec {
|
||||
static inline T apply(T x, T zero) { return 1 / x; }
|
||||
static inline T apply(T x) { return 1 / x; }
|
||||
};
|
||||
template<typename T>
|
||||
struct RecSqrt {
|
||||
static inline T apply(T x, T zero) { return 1 / sqrt(x); }
|
||||
static inline T apply(T x) { return 1 / sqrt(x); }
|
||||
};
|
||||
template<typename T>
|
||||
struct Sqrt {
|
||||
static inline T apply(T x, T zero) { return sqrt(x); }
|
||||
static inline T apply(T x) { return sqrt(x); }
|
||||
};
|
||||
|
||||
// Binary SIMD operators
|
||||
template<typename T>
|
||||
struct Add {
|
||||
static inline T apply(T l, T r) { return l + r; }
|
||||
|
@ -575,53 +570,71 @@ ErrorBadArgs(JSContext *cx)
|
|||
return false;
|
||||
}
|
||||
|
||||
template<typename Out>
|
||||
static bool
|
||||
StoreResult(JSContext *cx, CallArgs &args, typename Out::Elem *result)
|
||||
{
|
||||
RootedObject obj(cx, CreateSimd<Out>(cx, result));
|
||||
if (!obj)
|
||||
return false;
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Coerces the inputs of type In to the type Coercion, apply the operator Op
|
||||
// and converts the result to the type Out.
|
||||
template<typename In, typename Coercion, template<typename C> class Op, typename Out>
|
||||
static bool
|
||||
CoercedFunc(JSContext *cx, unsigned argc, Value *vp)
|
||||
CoercedUnaryFunc(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
typedef typename Coercion::Elem CoercionElem;
|
||||
typedef typename Out::Elem RetElem;
|
||||
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
if (args.length() != 1 && args.length() != 2)
|
||||
if (args.length() != 1 || !IsVectorObject<In>(args[0]))
|
||||
return ErrorBadArgs(cx);
|
||||
|
||||
CoercionElem result[Coercion::lanes];
|
||||
if (args.length() == 1) {
|
||||
if (!IsVectorObject<In>(args[0]))
|
||||
return ErrorBadArgs(cx);
|
||||
|
||||
CoercionElem *val = TypedObjectMemory<CoercionElem *>(args[0]);
|
||||
for (unsigned i = 0; i < Coercion::lanes; i++)
|
||||
result[i] = Op<CoercionElem>::apply(val[i], 0);
|
||||
} else {
|
||||
JS_ASSERT(args.length() == 2);
|
||||
if (!IsVectorObject<In>(args[0]) || !IsVectorObject<In>(args[1]))
|
||||
return ErrorBadArgs(cx);
|
||||
|
||||
CoercionElem *left = TypedObjectMemory<CoercionElem *>(args[0]);
|
||||
CoercionElem *right = TypedObjectMemory<CoercionElem *>(args[1]);
|
||||
for (unsigned i = 0; i < Coercion::lanes; i++)
|
||||
result[i] = Op<CoercionElem>::apply(left[i], right[i]);
|
||||
}
|
||||
|
||||
RetElem *coercedResult = reinterpret_cast<RetElem *>(result);
|
||||
RootedObject obj(cx, CreateSimd<Out>(cx, coercedResult));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
CoercionElem *val = TypedObjectMemory<CoercionElem *>(args[0]);
|
||||
for (unsigned i = 0; i < Coercion::lanes; i++)
|
||||
result[i] = Op<CoercionElem>::apply(val[i]);
|
||||
return StoreResult<Out>(cx, args, (RetElem*) result);
|
||||
}
|
||||
|
||||
// Same as above, with Coercion == Out
|
||||
// Coerces the inputs of type In to the type Coercion, apply the operator Op
|
||||
// and converts the result to the type Out.
|
||||
template<typename In, typename Coercion, template<typename C> class Op, typename Out>
|
||||
static bool
|
||||
CoercedBinaryFunc(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
typedef typename Coercion::Elem CoercionElem;
|
||||
typedef typename Out::Elem RetElem;
|
||||
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
if (args.length() != 2 || !IsVectorObject<In>(args[0]) || !IsVectorObject<In>(args[1]))
|
||||
return ErrorBadArgs(cx);
|
||||
|
||||
CoercionElem result[Coercion::lanes];
|
||||
CoercionElem *left = TypedObjectMemory<CoercionElem *>(args[0]);
|
||||
CoercionElem *right = TypedObjectMemory<CoercionElem *>(args[1]);
|
||||
for (unsigned i = 0; i < Coercion::lanes; i++)
|
||||
result[i] = Op<CoercionElem>::apply(left[i], right[i]);
|
||||
return StoreResult<Out>(cx, args, (RetElem *) result);
|
||||
}
|
||||
|
||||
// Same as above, with no coercion, i.e. Coercion == In.
|
||||
template<typename In, template<typename C> class Op, typename Out>
|
||||
static bool
|
||||
Func(JSContext *cx, unsigned argc, Value *vp)
|
||||
UnaryFunc(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
return CoercedFunc<In, Out, Op, Out>(cx, argc, vp);
|
||||
return CoercedUnaryFunc<In, Out, Op, Out>(cx, argc, vp);
|
||||
}
|
||||
|
||||
template<typename In, template<typename C> class Op, typename Out>
|
||||
static bool
|
||||
BinaryFunc(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
return CoercedBinaryFunc<In, Out, Op, Out>(cx, argc, vp);
|
||||
}
|
||||
|
||||
template<typename V, template<typename T> class OpWith>
|
||||
|
@ -652,13 +665,7 @@ FuncWith(JSContext *cx, unsigned argc, Value *vp)
|
|||
for (unsigned i = 0; i < V::lanes; i++)
|
||||
result[i] = OpWith<Elem>::apply(i, withAsBool, val[i]);
|
||||
}
|
||||
|
||||
RootedObject obj(cx, CreateSimd<V>(cx, result));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
return StoreResult<V>(cx, args, result);
|
||||
}
|
||||
|
||||
template<typename V>
|
||||
|
@ -712,12 +719,7 @@ FuncShuffle(JSContext *cx, unsigned argc, Value *vp)
|
|||
result[i] = val2[(maskArg >> (i * SELECT_SHIFT)) & SELECT_MASK];
|
||||
}
|
||||
|
||||
RootedObject obj(cx, CreateSimd<V>(cx, result));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
return StoreResult<V>(cx, args, result);
|
||||
}
|
||||
|
||||
template<typename Op>
|
||||
|
@ -739,13 +741,7 @@ Int32x4BinaryScalar(JSContext *cx, unsigned argc, Value *vp)
|
|||
|
||||
for (unsigned i = 0; i < 4; i++)
|
||||
result[i] = Op::apply(val[i], bits);
|
||||
|
||||
RootedObject obj(cx, CreateSimd<Int32x4>(cx, result));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
return StoreResult<Int32x4>(cx, args, result);
|
||||
}
|
||||
|
||||
template<typename V, typename Vret>
|
||||
|
@ -763,13 +759,7 @@ FuncConvert(JSContext *cx, unsigned argc, Value *vp)
|
|||
RetElem result[Vret::lanes];
|
||||
for (unsigned i = 0; i < Vret::lanes; i++)
|
||||
result[i] = RetElem(val[i]);
|
||||
|
||||
RootedObject obj(cx, CreateSimd<Vret>(cx, result));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
return StoreResult<Vret>(cx, args, result);
|
||||
}
|
||||
|
||||
template<typename V, typename Vret>
|
||||
|
@ -782,13 +772,8 @@ FuncConvertBits(JSContext *cx, unsigned argc, Value *vp)
|
|||
if (args.length() != 1 || !IsVectorObject<V>(args[0]))
|
||||
return ErrorBadArgs(cx);
|
||||
|
||||
RetElem *val = TypedObjectMemory<RetElem *>(args[0]);
|
||||
RootedObject obj(cx, CreateSimd<Vret>(cx, val));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
RetElem *result = TypedObjectMemory<RetElem *>(args[0]);
|
||||
return StoreResult<Vret>(cx, args, result);
|
||||
}
|
||||
|
||||
template<typename Vret>
|
||||
|
@ -804,13 +789,7 @@ FuncZero(JSContext *cx, unsigned argc, Value *vp)
|
|||
RetElem result[Vret::lanes];
|
||||
for (unsigned i = 0; i < Vret::lanes; i++)
|
||||
result[i] = RetElem(0);
|
||||
|
||||
RootedObject obj(cx, CreateSimd<Vret>(cx, result));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
return StoreResult<Vret>(cx, args, result);
|
||||
}
|
||||
|
||||
template<typename Vret>
|
||||
|
@ -830,13 +809,7 @@ FuncSplat(JSContext *cx, unsigned argc, Value *vp)
|
|||
RetElem result[Vret::lanes];
|
||||
for (unsigned i = 0; i < Vret::lanes; i++)
|
||||
result[i] = arg;
|
||||
|
||||
RootedObject obj(cx, CreateSimd<Vret>(cx, result));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
return StoreResult<Vret>(cx, args, result);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -853,13 +826,7 @@ Int32x4Bool(JSContext *cx, unsigned argc, Value *vp)
|
|||
int32_t result[Int32x4::lanes];
|
||||
for (unsigned i = 0; i < Int32x4::lanes; i++)
|
||||
result[i] = args[i].toBoolean() ? 0xFFFFFFFF : 0x0;
|
||||
|
||||
RootedObject obj(cx, CreateSimd<Int32x4>(cx, result));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
return StoreResult<Int32x4>(cx, args, result);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -882,12 +849,7 @@ Float32x4Clamp(JSContext *cx, unsigned argc, Value *vp)
|
|||
result[i] = result[i] > upperLimit[i] ? upperLimit[i] : result[i];
|
||||
}
|
||||
|
||||
RootedObject obj(cx, CreateSimd<Float32x4>(cx, result));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
return StoreResult<Float32x4>(cx, args, result);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -910,41 +872,36 @@ Int32x4Select(JSContext *cx, unsigned argc, Value *vp)
|
|||
|
||||
int32_t fr[Int32x4::lanes];
|
||||
for (unsigned i = 0; i < Int32x4::lanes; i++)
|
||||
fr[i] = And<int32_t>::apply(Not<int32_t>::apply(val[i], 0), fv[i]);
|
||||
fr[i] = And<int32_t>::apply(Not<int32_t>::apply(val[i]), fv[i]);
|
||||
|
||||
int32_t orInt[Int32x4::lanes];
|
||||
for (unsigned i = 0; i < Int32x4::lanes; i++)
|
||||
orInt[i] = Or<int32_t>::apply(tr[i], fr[i]);
|
||||
|
||||
float *result = reinterpret_cast<float *>(orInt);
|
||||
RootedObject obj(cx, CreateSimd<Float32x4>(cx, result));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
return StoreResult<Float32x4>(cx, args, result);
|
||||
}
|
||||
|
||||
#define DEFINE_SIMD_FLOAT32X4_FUNCTION(Name, Func, Operands, Flags, MIRId) \
|
||||
bool \
|
||||
js::simd_float32x4_##Name(JSContext *cx, unsigned argc, Value *vp) \
|
||||
{ \
|
||||
return Func(cx, argc, vp); \
|
||||
#define DEFINE_SIMD_FLOAT32X4_FUNCTION(Name, Func, Operands, Flags) \
|
||||
bool \
|
||||
js::simd_float32x4_##Name(JSContext *cx, unsigned argc, Value *vp) \
|
||||
{ \
|
||||
return Func(cx, argc, vp); \
|
||||
}
|
||||
FLOAT32X4_FUNCTION_LIST(DEFINE_SIMD_FLOAT32X4_FUNCTION)
|
||||
#undef DEFINE_SIMD_FLOAT32x4_FUNCTION
|
||||
|
||||
#define DEFINE_SIMD_INT32X4_FUNCTION(Name, Func, Operands, Flags, MIRId) \
|
||||
bool \
|
||||
js::simd_int32x4_##Name(JSContext *cx, unsigned argc, Value *vp) \
|
||||
{ \
|
||||
return Func(cx, argc, vp); \
|
||||
#define DEFINE_SIMD_INT32X4_FUNCTION(Name, Func, Operands, Flags) \
|
||||
bool \
|
||||
js::simd_int32x4_##Name(JSContext *cx, unsigned argc, Value *vp) \
|
||||
{ \
|
||||
return Func(cx, argc, vp); \
|
||||
}
|
||||
INT32X4_FUNCTION_LIST(DEFINE_SIMD_INT32X4_FUNCTION)
|
||||
#undef DEFINE_SIMD_INT32X4_FUNCTION
|
||||
|
||||
const JSFunctionSpec js::Float32x4Methods[] = {
|
||||
#define SIMD_FLOAT32X4_FUNCTION_ITEM(Name, Func, Operands, Flags, MIRId) \
|
||||
#define SIMD_FLOAT32X4_FUNCTION_ITEM(Name, Func, Operands, Flags) \
|
||||
JS_FN(#Name, js::simd_float32x4_##Name, Operands, Flags),
|
||||
FLOAT32X4_FUNCTION_LIST(SIMD_FLOAT32X4_FUNCTION_ITEM)
|
||||
#undef SIMD_FLOAT32x4_FUNCTION_ITEM
|
||||
|
@ -952,7 +909,7 @@ const JSFunctionSpec js::Float32x4Methods[] = {
|
|||
};
|
||||
|
||||
const JSFunctionSpec js::Int32x4Methods[] = {
|
||||
#define SIMD_INT32X4_FUNCTION_ITEM(Name, Func, Operands, Flags, MIRId) \
|
||||
#define SIMD_INT32X4_FUNCTION_ITEM(Name, Func, Operands, Flags) \
|
||||
JS_FN(#Name, js::simd_int32x4_##Name, Operands, Flags),
|
||||
INT32X4_FUNCTION_LIST(SIMD_INT32X4_FUNCTION_ITEM)
|
||||
#undef SIMD_INT32X4_FUNCTION_ITEM
|
||||
|
|
|
@ -18,98 +18,98 @@
|
|||
* https://github.com/johnmccutchan/ecmascript_simd/blob/master/src/ecmascript_simd.js
|
||||
*/
|
||||
|
||||
#define FLOAT32X4_NULLARY_FUNCTION_LIST(V) \
|
||||
V(zero, (FuncZero<Float32x4>), 0, 0, Zero)
|
||||
#define FLOAT32X4_NULLARY_FUNCTION_LIST(V) \
|
||||
V(zero, (FuncZero<Float32x4>), 0, 0)
|
||||
|
||||
#define FLOAT32X4_UNARY_FUNCTION_LIST(V) \
|
||||
V(abs, (Func<Float32x4, Abs, Float32x4>), 1, 0, Abs) \
|
||||
V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Float32x4>), 1, 0, FromInt32x4Bits) \
|
||||
V(neg, (Func<Float32x4, Neg, Float32x4>), 1, 0, Neg) \
|
||||
V(not, (CoercedFunc<Float32x4, Int32x4, Not, Float32x4>), 1, 0, Not) \
|
||||
V(reciprocal, (Func<Float32x4, Rec, Float32x4>), 1, 0, Reciprocal) \
|
||||
V(reciprocalSqrt, (Func<Float32x4, RecSqrt, Float32x4>), 1, 0, ReciprocalSqrt) \
|
||||
V(splat, (FuncSplat<Float32x4>), 1, 0, Splat) \
|
||||
V(sqrt, (Func<Float32x4, Sqrt, Float32x4>), 1, 0, Sqrt) \
|
||||
V(fromInt32x4, (FuncConvert<Int32x4, Float32x4> ), 1, 0, FromInt32x4)
|
||||
#define FLOAT32X4_UNARY_FUNCTION_LIST(V) \
|
||||
V(abs, (UnaryFunc<Float32x4, Abs, Float32x4>), 1, 0) \
|
||||
V(fromInt32x4Bits, (FuncConvertBits<Int32x4, Float32x4>), 1, 0) \
|
||||
V(neg, (UnaryFunc<Float32x4, Neg, Float32x4>), 1, 0) \
|
||||
V(not, (CoercedUnaryFunc<Float32x4, Int32x4, Not, Float32x4>), 1, 0) \
|
||||
V(reciprocal, (UnaryFunc<Float32x4, Rec, Float32x4>), 1, 0) \
|
||||
V(reciprocalSqrt, (UnaryFunc<Float32x4, RecSqrt, Float32x4>), 1, 0) \
|
||||
V(splat, (FuncSplat<Float32x4>), 1, 0) \
|
||||
V(sqrt, (UnaryFunc<Float32x4, Sqrt, Float32x4>), 1, 0) \
|
||||
V(fromInt32x4, (FuncConvert<Int32x4, Float32x4> ), 1, 0)
|
||||
|
||||
#define FLOAT32X4_BINARY_FUNCTION_LIST(V) \
|
||||
V(add, (Func<Float32x4, Add, Float32x4>), 2, 0, Add) \
|
||||
V(and, (CoercedFunc<Float32x4, Int32x4, And, Float32x4>), 2, 0, And) \
|
||||
V(div, (Func<Float32x4, Div, Float32x4>), 2, 0, Div) \
|
||||
V(equal, (Func<Float32x4, Equal, Int32x4>), 2, 0, Equal) \
|
||||
V(greaterThan, (Func<Float32x4, GreaterThan, Int32x4>), 2, 0, GreaterThan) \
|
||||
V(greaterThanOrEqual, (Func<Float32x4, GreaterThanOrEqual, Int32x4>), 2, 0, GreaterThanOrEqual) \
|
||||
V(lessThan, (Func<Float32x4, LessThan, Int32x4>), 2, 0, LessThan) \
|
||||
V(lessThanOrEqual, (Func<Float32x4, LessThanOrEqual, Int32x4>), 2, 0, LessThanOrEqual) \
|
||||
V(max, (Func<Float32x4, Maximum, Float32x4>), 2, 0, Max) \
|
||||
V(min, (Func<Float32x4, Minimum, Float32x4>), 2, 0, Min) \
|
||||
V(mul, (Func<Float32x4, Mul, Float32x4>), 2, 0, Mul) \
|
||||
V(notEqual, (Func<Float32x4, NotEqual, Int32x4>), 2, 0, NotEqual) \
|
||||
V(shuffle, FuncShuffle<Float32x4>, 2, 0, Shuffle) \
|
||||
V(or, (CoercedFunc<Float32x4, Int32x4, Or, Float32x4>), 2, 0, Or) \
|
||||
V(scale, (FuncWith<Float32x4, Scale>), 2, 0, Scale) \
|
||||
V(sub, (Func<Float32x4, Sub, Float32x4>), 2, 0, Sub) \
|
||||
V(withX, (FuncWith<Float32x4, WithX>), 2, 0, WithX) \
|
||||
V(withY, (FuncWith<Float32x4, WithY>), 2, 0, WithY) \
|
||||
V(withZ, (FuncWith<Float32x4, WithZ>), 2, 0, WithZ) \
|
||||
V(withW, (FuncWith<Float32x4, WithW>), 2, 0, WithW) \
|
||||
V(xor, (CoercedFunc<Float32x4, Int32x4, Xor, Float32x4>), 2, 0, Xor)
|
||||
#define FLOAT32X4_BINARY_FUNCTION_LIST(V) \
|
||||
V(add, (BinaryFunc<Float32x4, Add, Float32x4>), 2, 0) \
|
||||
V(and, (CoercedBinaryFunc<Float32x4, Int32x4, And, Float32x4>), 2, 0) \
|
||||
V(div, (BinaryFunc<Float32x4, Div, Float32x4>), 2, 0) \
|
||||
V(equal, (BinaryFunc<Float32x4, Equal, Int32x4>), 2, 0) \
|
||||
V(greaterThan, (BinaryFunc<Float32x4, GreaterThan, Int32x4>), 2, 0) \
|
||||
V(greaterThanOrEqual, (BinaryFunc<Float32x4, GreaterThanOrEqual, Int32x4>), 2, 0) \
|
||||
V(lessThan, (BinaryFunc<Float32x4, LessThan, Int32x4>), 2, 0) \
|
||||
V(lessThanOrEqual, (BinaryFunc<Float32x4, LessThanOrEqual, Int32x4>), 2, 0) \
|
||||
V(max, (BinaryFunc<Float32x4, Maximum, Float32x4>), 2, 0) \
|
||||
V(min, (BinaryFunc<Float32x4, Minimum, Float32x4>), 2, 0) \
|
||||
V(mul, (BinaryFunc<Float32x4, Mul, Float32x4>), 2, 0) \
|
||||
V(notEqual, (BinaryFunc<Float32x4, NotEqual, Int32x4>), 2, 0) \
|
||||
V(shuffle, FuncShuffle<Float32x4>, 2, 0) \
|
||||
V(or, (CoercedBinaryFunc<Float32x4, Int32x4, Or, Float32x4>), 2, 0) \
|
||||
V(scale, (FuncWith<Float32x4, Scale>), 2, 0) \
|
||||
V(sub, (BinaryFunc<Float32x4, Sub, Float32x4>), 2, 0) \
|
||||
V(withX, (FuncWith<Float32x4, WithX>), 2, 0) \
|
||||
V(withY, (FuncWith<Float32x4, WithY>), 2, 0) \
|
||||
V(withZ, (FuncWith<Float32x4, WithZ>), 2, 0) \
|
||||
V(withW, (FuncWith<Float32x4, WithW>), 2, 0) \
|
||||
V(xor, (CoercedBinaryFunc<Float32x4, Int32x4, Xor, Float32x4>), 2, 0)
|
||||
|
||||
#define FLOAT32X4_TERNARY_FUNCTION_LIST(V) \
|
||||
V(clamp, Float32x4Clamp, 3, 0, Clamp) \
|
||||
V(shuffleMix, FuncShuffle<Float32x4>, 3, 0, ShuffleMix)
|
||||
#define FLOAT32X4_TERNARY_FUNCTION_LIST(V) \
|
||||
V(clamp, Float32x4Clamp, 3, 0) \
|
||||
V(shuffleMix, FuncShuffle<Float32x4>, 3, 0)
|
||||
|
||||
#define FLOAT32X4_FUNCTION_LIST(V) \
|
||||
FLOAT32X4_NULLARY_FUNCTION_LIST(V) \
|
||||
FLOAT32X4_UNARY_FUNCTION_LIST(V) \
|
||||
FLOAT32X4_BINARY_FUNCTION_LIST(V) \
|
||||
#define FLOAT32X4_FUNCTION_LIST(V) \
|
||||
FLOAT32X4_NULLARY_FUNCTION_LIST(V) \
|
||||
FLOAT32X4_UNARY_FUNCTION_LIST(V) \
|
||||
FLOAT32X4_BINARY_FUNCTION_LIST(V) \
|
||||
FLOAT32X4_TERNARY_FUNCTION_LIST(V)
|
||||
|
||||
#define INT32X4_NULLARY_FUNCTION_LIST(V) \
|
||||
V(zero, (FuncZero<Int32x4>), 0, 0, Zero)
|
||||
#define INT32X4_NULLARY_FUNCTION_LIST(V) \
|
||||
V(zero, (FuncZero<Int32x4>), 0, 0)
|
||||
|
||||
#define INT32X4_UNARY_FUNCTION_LIST(V) \
|
||||
V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Int32x4>), 1, 0, FromFloat32x4Bits) \
|
||||
V(neg, (Func<Int32x4, Neg, Int32x4>), 1, 0, Neg) \
|
||||
V(not, (Func<Int32x4, Not, Int32x4>), 1, 0, Not) \
|
||||
V(splat, (FuncSplat<Int32x4>), 0, 0, Splat) \
|
||||
V(fromFloat32x4, (FuncConvert<Float32x4, Int32x4>), 1, 0, FromFloat32x4)
|
||||
#define INT32X4_UNARY_FUNCTION_LIST(V) \
|
||||
V(fromFloat32x4Bits, (FuncConvertBits<Float32x4, Int32x4>), 1, 0) \
|
||||
V(neg, (UnaryFunc<Int32x4, Neg, Int32x4>), 1, 0) \
|
||||
V(not, (UnaryFunc<Int32x4, Not, Int32x4>), 1, 0) \
|
||||
V(splat, (FuncSplat<Int32x4>), 0, 0) \
|
||||
V(fromFloat32x4, (FuncConvert<Float32x4, Int32x4>), 1, 0)
|
||||
|
||||
#define INT32X4_BINARY_FUNCTION_LIST(V) \
|
||||
V(add, (Func<Int32x4, Add, Int32x4>), 2, 0, Add) \
|
||||
V(and, (Func<Int32x4, And, Int32x4>), 2, 0, And) \
|
||||
V(equal, (Func<Int32x4, Equal, Int32x4>), 2, 0, Equal) \
|
||||
V(greaterThan, (Func<Int32x4, GreaterThan, Int32x4>), 2, 0, GreaterThan) \
|
||||
V(lessThan, (Func<Int32x4, LessThan, Int32x4>), 2, 0, LessThan) \
|
||||
V(mul, (Func<Int32x4, Mul, Int32x4>), 2, 0, Mul) \
|
||||
V(or, (Func<Int32x4, Or, Int32x4>), 2, 0, Or) \
|
||||
V(sub, (Func<Int32x4, Sub, Int32x4>), 2, 0, Sub) \
|
||||
V(shiftLeft, (Int32x4BinaryScalar<ShiftLeft>), 2, 0, ShiftLeft) \
|
||||
V(shiftRight, (Int32x4BinaryScalar<ShiftRight>), 2, 0, ShiftRight) \
|
||||
V(shiftRightLogical, (Int32x4BinaryScalar<ShiftRightLogical>), 2, 0, ShiftRightLogical) \
|
||||
V(shuffle, FuncShuffle<Int32x4>, 2, 0, Shuffle) \
|
||||
V(withFlagX, (FuncWith<Int32x4, WithFlagX>), 2, 0, WithFlagX) \
|
||||
V(withFlagY, (FuncWith<Int32x4, WithFlagY>), 2, 0, WithFlagY) \
|
||||
V(withFlagZ, (FuncWith<Int32x4, WithFlagZ>), 2, 0, WithFlagZ) \
|
||||
V(withFlagW, (FuncWith<Int32x4, WithFlagW>), 2, 0, WithFlagW) \
|
||||
V(withX, (FuncWith<Int32x4, WithX>), 2, 0, WithX) \
|
||||
V(withY, (FuncWith<Int32x4, WithY>), 2, 0, WithY) \
|
||||
V(withZ, (FuncWith<Int32x4, WithZ>), 2, 0, WithZ) \
|
||||
V(withW, (FuncWith<Int32x4, WithW>), 2, 0, WithW) \
|
||||
V(xor, (Func<Int32x4, Xor, Int32x4>), 2, 0, Xor)
|
||||
#define INT32X4_BINARY_FUNCTION_LIST(V) \
|
||||
V(add, (BinaryFunc<Int32x4, Add, Int32x4>), 2, 0) \
|
||||
V(and, (BinaryFunc<Int32x4, And, Int32x4>), 2, 0) \
|
||||
V(equal, (BinaryFunc<Int32x4, Equal, Int32x4>), 2, 0) \
|
||||
V(greaterThan, (BinaryFunc<Int32x4, GreaterThan, Int32x4>), 2, 0) \
|
||||
V(lessThan, (BinaryFunc<Int32x4, LessThan, Int32x4>), 2, 0) \
|
||||
V(mul, (BinaryFunc<Int32x4, Mul, Int32x4>), 2, 0) \
|
||||
V(or, (BinaryFunc<Int32x4, Or, Int32x4>), 2, 0) \
|
||||
V(sub, (BinaryFunc<Int32x4, Sub, Int32x4>), 2, 0) \
|
||||
V(shiftLeft, (Int32x4BinaryScalar<ShiftLeft>), 2, 0) \
|
||||
V(shiftRight, (Int32x4BinaryScalar<ShiftRight>), 2, 0) \
|
||||
V(shiftRightLogical, (Int32x4BinaryScalar<ShiftRightLogical>), 2, 0) \
|
||||
V(shuffle, FuncShuffle<Int32x4>, 2, 0) \
|
||||
V(withFlagX, (FuncWith<Int32x4, WithFlagX>), 2, 0) \
|
||||
V(withFlagY, (FuncWith<Int32x4, WithFlagY>), 2, 0) \
|
||||
V(withFlagZ, (FuncWith<Int32x4, WithFlagZ>), 2, 0) \
|
||||
V(withFlagW, (FuncWith<Int32x4, WithFlagW>), 2, 0) \
|
||||
V(withX, (FuncWith<Int32x4, WithX>), 2, 0) \
|
||||
V(withY, (FuncWith<Int32x4, WithY>), 2, 0) \
|
||||
V(withZ, (FuncWith<Int32x4, WithZ>), 2, 0) \
|
||||
V(withW, (FuncWith<Int32x4, WithW>), 2, 0) \
|
||||
V(xor, (BinaryFunc<Int32x4, Xor, Int32x4>), 2, 0)
|
||||
|
||||
#define INT32X4_TERNARY_FUNCTION_LIST(V) \
|
||||
V(select, Int32x4Select, 3, 0, Select) \
|
||||
V(shuffleMix, FuncShuffle<Int32x4>, 3, 0, ShuffleMix)
|
||||
#define INT32X4_TERNARY_FUNCTION_LIST(V) \
|
||||
V(select, Int32x4Select, 3, 0) \
|
||||
V(shuffleMix, FuncShuffle<Int32x4>, 3, 0)
|
||||
|
||||
#define INT32X4_QUARTERNARY_FUNCTION_LIST(V) \
|
||||
V(bool, Int32x4Bool, 4, 0, Bool)
|
||||
#define INT32X4_QUARTERNARY_FUNCTION_LIST(V) \
|
||||
V(bool, Int32x4Bool, 4, 0)
|
||||
|
||||
#define INT32X4_FUNCTION_LIST(V) \
|
||||
INT32X4_NULLARY_FUNCTION_LIST(V) \
|
||||
INT32X4_UNARY_FUNCTION_LIST(V) \
|
||||
INT32X4_BINARY_FUNCTION_LIST(V) \
|
||||
INT32X4_TERNARY_FUNCTION_LIST(V) \
|
||||
#define INT32X4_FUNCTION_LIST(V) \
|
||||
INT32X4_NULLARY_FUNCTION_LIST(V) \
|
||||
INT32X4_UNARY_FUNCTION_LIST(V) \
|
||||
INT32X4_BINARY_FUNCTION_LIST(V) \
|
||||
INT32X4_TERNARY_FUNCTION_LIST(V) \
|
||||
INT32X4_QUARTERNARY_FUNCTION_LIST(V)
|
||||
|
||||
namespace js {
|
||||
|
@ -166,14 +166,14 @@ struct Int32x4 {
|
|||
template<typename V>
|
||||
JSObject *CreateSimd(JSContext *cx, typename V::Elem *data);
|
||||
|
||||
#define DECLARE_SIMD_FLOAT32X4_FUNCTION(Name, Func, Operands, Flags, MIRId) \
|
||||
extern bool \
|
||||
#define DECLARE_SIMD_FLOAT32X4_FUNCTION(Name, Func, Operands, Flags) \
|
||||
extern bool \
|
||||
simd_float32x4_##Name(JSContext *cx, unsigned argc, Value *vp);
|
||||
FLOAT32X4_FUNCTION_LIST(DECLARE_SIMD_FLOAT32X4_FUNCTION)
|
||||
#undef DECLARE_SIMD_FLOAT32X4_FUNCTION
|
||||
|
||||
#define DECLARE_SIMD_INT32x4_FUNCTION(Name, Func, Operands, Flags, MIRId) \
|
||||
extern bool \
|
||||
#define DECLARE_SIMD_INT32x4_FUNCTION(Name, Func, Operands, Flags) \
|
||||
extern bool \
|
||||
simd_int32x4_##Name(JSContext *cx, unsigned argc, Value *vp);
|
||||
INT32X4_FUNCTION_LIST(DECLARE_SIMD_INT32x4_FUNCTION)
|
||||
#undef DECLARE_SIMD_INT32x4_FUNCTION
|
||||
|
|
|
@ -1550,7 +1550,10 @@ ia64*-hpux*)
|
|||
TARGET_NSPR_MDCPUCFG='\"md/_linux.cfg\"'
|
||||
|
||||
MOZ_GFX_OPTIMIZE_MOBILE=1
|
||||
MOZ_OPTIMIZE_FLAGS="-O3 -freorder-blocks -fno-reorder-functions"
|
||||
MOZ_OPTIMIZE_FLAGS="-O3 -fno-reorder-functions"
|
||||
if test -z "$CLANG_CC"; then
|
||||
MOZ_OPTIMIZE_FLAGS="-freorder-blocks $MOZ_OPTIMIZE_FLAGS"
|
||||
fi
|
||||
# The Maemo builders don't know about this flag
|
||||
MOZ_ARM_VFP_FLAGS="-mfpu=vfp"
|
||||
;;
|
||||
|
@ -1569,7 +1572,10 @@ ia64*-hpux*)
|
|||
MOZ_OPTIMIZE_SIZE_TWEAK="-finline-limit=50"
|
||||
esac
|
||||
MOZ_PGO_OPTIMIZE_FLAGS="-O3"
|
||||
MOZ_OPTIMIZE_FLAGS="-O3 -freorder-blocks $MOZ_OPTIMIZE_SIZE_TWEAK"
|
||||
MOZ_OPTIMIZE_FLAGS="-O3 $MOZ_OPTIMIZE_SIZE_TWEAK"
|
||||
if test -z "$CLANG_CC"; then
|
||||
MOZ_OPTIMIZE_FLAGS="-freorder-blocks $MOZ_OPTIMIZE_FLAGS"
|
||||
fi
|
||||
fi
|
||||
|
||||
TARGET_NSPR_MDCPUCFG='\"md/_linux.cfg\"'
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
load(libdir + "asm.js");
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
assertAsmTypeFail(USE_ASM + "var i; function f(){} return f");
|
||||
assertAsmTypeFail(USE_ASM + "const i; function f(){} return f");
|
||||
|
@ -117,6 +118,14 @@ assertEq(asmLink(asmCompile('global', 'imp', USE_ASM + "const i=+imp.i; function
|
|||
assertEq(asmLink(asmCompile('global', 'imp', USE_ASM + "var i=+imp.i; function f() { return +i } return f")(this, {i:1.4})), 1.4);
|
||||
assertEq(asmLink(asmCompile('global', 'imp', USE_ASM + "const i=+imp.i; function f() { return +i } return f")(this, {i:1.4})), 1.4);
|
||||
assertEq(asmLink(asmCompile(USE_ASM + "var g=0; function f() { var i=42; while (1) { break; } g = i; return g|0 } return f"))(), 42);
|
||||
assertAsmLinkFail(asmCompile('glob','foreign', USE_ASM + 'var i = +foreign.x; function f() {} return f'), null, {x:{valueOf:function() { return 42 }}});
|
||||
assertAsmLinkFail(asmCompile('glob','foreign', USE_ASM + 'var i = foreign.x|0; function f() {} return f'), null, {x:{valueOf:function() { return 42 }}});
|
||||
assertEq(asmLink(asmCompile('glob','foreign', USE_ASM + 'var i = foreign.x|0; function f() { return i|0} return f'), null, {x:"blah"})(), 0);
|
||||
assertEq(asmLink(asmCompile('glob','foreign', USE_ASM + 'var i = +foreign.x; function f() { return +i} return f'), null, {x:"blah"})(), NaN);
|
||||
assertEq(asmLink(asmCompile('glob','foreign', USE_ASM + 'var tof = glob.Math.fround; var i = tof(foreign.x); function f() { return +i} return f'), this, {x:"blah"})(), NaN);
|
||||
assertThrowsInstanceOf(() => asmCompile('glob','foreign',USE_ASM + 'var i = foreign.x|0; function f() { return i|0} return f')(null, {x:Symbol("blah")}), TypeError);
|
||||
assertThrowsInstanceOf(() => asmCompile('glob','foreign',USE_ASM + 'var i = +foreign.x; function f() { return +i} return f')(null, {x:Symbol("blah")}), TypeError);
|
||||
assertThrowsInstanceOf(() => asmCompile('glob','foreign',USE_ASM + 'var tof = glob.Math.fround; var i = tof(foreign.x); function f() { return +i} return f')(this, {x:Symbol("blah")}), TypeError);
|
||||
|
||||
var f1 = asmCompile('global', 'foreign', 'heap', USE_ASM + 'var i32 = new global.Int32Array(heap); function g() { return i32[4]|0 } return g');
|
||||
var global = this;
|
||||
|
|
|
@ -199,7 +199,7 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue,
|
|||
const nsCSSValue* tokenStream = nullptr;
|
||||
uint32_t totalCount = 0, importantCount = 0,
|
||||
initialCount = 0, inheritCount = 0, unsetCount = 0,
|
||||
matchingTokenStreamCount = 0;
|
||||
matchingTokenStreamCount = 0, nonMatchingTokenStreamCount = 0;
|
||||
CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p, aProperty) {
|
||||
if (*p == eCSSProperty__x_system_font ||
|
||||
nsCSSProps::PropHasFlags(*p, CSS_PROPERTY_DIRECTIONAL_SOURCE)) {
|
||||
|
@ -224,10 +224,13 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue,
|
|||
++initialCount;
|
||||
} else if (val->GetUnit() == eCSSUnit_Unset) {
|
||||
++unsetCount;
|
||||
} else if (val->GetUnit() == eCSSUnit_TokenStream &&
|
||||
val->GetTokenStreamValue()->mShorthandPropertyID == aProperty) {
|
||||
tokenStream = val;
|
||||
++matchingTokenStreamCount;
|
||||
} else if (val->GetUnit() == eCSSUnit_TokenStream) {
|
||||
if (val->GetTokenStreamValue()->mShorthandPropertyID == aProperty) {
|
||||
tokenStream = val;
|
||||
++matchingTokenStreamCount;
|
||||
} else {
|
||||
++nonMatchingTokenStreamCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (importantCount != 0 && importantCount != totalCount) {
|
||||
|
@ -252,8 +255,9 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue,
|
|||
nsCSSValue::eNormalized);
|
||||
return;
|
||||
}
|
||||
if (initialCount != 0 || inheritCount != 0 || unsetCount != 0) {
|
||||
// Case (2): partially initial, inherit or unset.
|
||||
if (initialCount != 0 || inheritCount != 0 ||
|
||||
unsetCount != 0 || nonMatchingTokenStreamCount != 0) {
|
||||
// Case (2): partially initial, inherit, unset or token stream.
|
||||
return;
|
||||
}
|
||||
if (tokenStream) {
|
||||
|
|
|
@ -81,6 +81,9 @@ function xfail_compute(property, value)
|
|||
return false;
|
||||
}
|
||||
|
||||
// constructed to map longhands ==> list of containing shorthands
|
||||
var gPropertyShorthands = {};
|
||||
|
||||
var gElement = document.getElementById("testnode");
|
||||
var gDeclaration = gElement.style;
|
||||
var gComputedStyle = window.getComputedStyle(gElement, "");
|
||||
|
@ -105,6 +108,17 @@ function test_property(property)
|
|||
is(gDeclaration.cssText, "", "non-empty serialization after removing all properties " + errstr);
|
||||
}
|
||||
|
||||
function test_other_shorthands_empty(value, subprop) {
|
||||
if (!(subprop in gPropertyShorthands)) return;
|
||||
var shorthands = gPropertyShorthands[subprop];
|
||||
for (idx in shorthands) {
|
||||
var sh = shorthands[idx];
|
||||
if (sh.replace("-moz-","") == property.replace("-moz-","")) continue;
|
||||
is(gDeclaration.getPropertyValue(sh), "",
|
||||
"setting '" + value + "' on '" + property + "' (for shorthand '" + sh + "')");
|
||||
}
|
||||
}
|
||||
|
||||
function test_value(value, resolved_value) {
|
||||
var value_has_variable_reference = resolved_value != null;
|
||||
|
||||
|
@ -134,6 +148,7 @@ function test_property(property)
|
|||
(!info.alias_for || info.type == CSS_TYPE_TRUE_SHORTHAND)) {
|
||||
is(gDeclaration.getPropertyValue(subprop), "",
|
||||
"setting '" + value + "' on '" + property + "' (for '" + subprop + "')");
|
||||
test_other_shorthands_empty(value, subprop);
|
||||
} else {
|
||||
isnot(gDeclaration.getPropertyValue(subprop), "",
|
||||
"setting '" + value + "' on '" + property + "' (for '" + subprop + "')");
|
||||
|
@ -273,8 +288,19 @@ function runTest() {
|
|||
// property at a time.
|
||||
ok(SpecialPowers.getBoolPref("layout.css.variables.enabled"), "pref not set #1");
|
||||
var props = [];
|
||||
for (var prop in gCSSProperties)
|
||||
for (var prop in gCSSProperties) {
|
||||
var info = gCSSProperties[prop];
|
||||
if ("subproperties" in info) {
|
||||
for (var idx in info.subproperties) {
|
||||
var subprop = info.subproperties[idx];
|
||||
if (!(subprop in gPropertyShorthands)) {
|
||||
gPropertyShorthands[subprop] = [];
|
||||
}
|
||||
gPropertyShorthands[subprop].push(prop);
|
||||
}
|
||||
}
|
||||
props.push(prop);
|
||||
}
|
||||
props = props.reverse();
|
||||
function do_one() {
|
||||
if (props.length == 0) {
|
||||
|
|
|
@ -438,12 +438,15 @@ nsSliderFrame::HandleEvent(nsPresContext* aPresContext,
|
|||
break;
|
||||
}
|
||||
if (mChange) {
|
||||
// We're in the process of moving the thumb to the mouse,
|
||||
// but the mouse just moved. Make sure to update our
|
||||
// destination point.
|
||||
// On Linux the destination point is determined by the initial click
|
||||
// on the scrollbar track and doesn't change until the mouse button
|
||||
// is released.
|
||||
#ifndef MOZ_WIDGET_GTK
|
||||
// On the other platforms we need to update the destination point now.
|
||||
mDestinationPoint = eventPoint;
|
||||
StopRepeat();
|
||||
StartRepeat();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -523,6 +526,12 @@ nsSliderFrame::HandleEvent(nsPresContext* aPresContext,
|
|||
NS_ENSURE_TRUE(weakFrame.IsAlive(), NS_OK);
|
||||
|
||||
DragThumb(true);
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
nsCOMPtr<nsIContent> thumb = thumbFrame->GetContent();
|
||||
thumb->SetAttr(kNameSpaceID_None, nsGkAtoms::active, NS_LITERAL_STRING("true"), true);
|
||||
#endif
|
||||
|
||||
if (aEvent->mClass == eTouchEventClass) {
|
||||
*aEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
|
@ -534,6 +543,21 @@ nsSliderFrame::HandleEvent(nsPresContext* aPresContext,
|
|||
|
||||
mDragStart = pos - mThumbStart;
|
||||
}
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
else if (ShouldScrollForEvent(aEvent) &&
|
||||
aEvent->mClass == eMouseEventClass &&
|
||||
aEvent->AsMouseEvent()->button == WidgetMouseEvent::eRightButton) {
|
||||
// HandlePress and HandleRelease are usually called via
|
||||
// nsFrame::HandleEvent, but only for the left mouse button.
|
||||
if (aEvent->message == NS_MOUSE_BUTTON_DOWN) {
|
||||
HandlePress(aPresContext, aEvent, aEventStatus);
|
||||
} else if (aEvent->message == NS_MOUSE_BUTTON_UP) {
|
||||
HandleRelease(aPresContext, aEvent, aEventStatus);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
// XXX hack until handle release is actually called in nsframe.
|
||||
// if (aEvent->message == NS_MOUSE_EXIT_SYNTH || aEvent->message == NS_MOUSE_RIGHT_BUTTON_UP || aEvent->message == NS_MOUSE_LEFT_BUTTON_UP)
|
||||
|
@ -862,6 +886,11 @@ nsSliderFrame::StartDrag(nsIDOMEvent* aEvent)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
nsCOMPtr<nsIContent> thumb = thumbFrame->GetContent();
|
||||
thumb->SetAttr(kNameSpaceID_None, nsGkAtoms::active, NS_LITERAL_STRING("true"), true);
|
||||
#endif
|
||||
|
||||
if (isHorizontal)
|
||||
mThumbStart = thumbFrame->GetPosition().x;
|
||||
else
|
||||
|
@ -881,6 +910,15 @@ nsSliderFrame::StopDrag()
|
|||
{
|
||||
AddListener();
|
||||
DragThumb(false);
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
nsIFrame* thumbFrame = mFrames.FirstChild();
|
||||
if (thumbFrame) {
|
||||
nsCOMPtr<nsIContent> thumb = thumbFrame->GetContent();
|
||||
thumb->UnsetAttr(kNameSpaceID_None, nsGkAtoms::active, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mChange) {
|
||||
StopRepeat();
|
||||
mChange = 0;
|
||||
|
@ -955,8 +993,14 @@ nsSliderFrame::ShouldScrollForEvent(WidgetGUIEvent* aEvent)
|
|||
case NS_MOUSE_BUTTON_DOWN:
|
||||
case NS_MOUSE_BUTTON_UP: {
|
||||
uint16_t button = aEvent->AsMouseEvent()->button;
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
return (button == WidgetMouseEvent::eLeftButton) ||
|
||||
(button == WidgetMouseEvent::eRightButton && GetScrollToClick()) ||
|
||||
(button == WidgetMouseEvent::eMiddleButton && gMiddlePref && !GetScrollToClick());
|
||||
#else
|
||||
return (button == WidgetMouseEvent::eLeftButton) ||
|
||||
(button == WidgetMouseEvent::eMiddleButton && gMiddlePref);
|
||||
#endif
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
|
@ -978,8 +1022,8 @@ nsSliderFrame::ShouldScrollToClickForEvent(WidgetGUIEvent* aEvent)
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// On Mac, clicking the scrollbar thumb should never scroll to click.
|
||||
#if defined(XP_MACOSX) || defined(MOZ_WIDGET_GTK)
|
||||
// On Mac and Linux, clicking the scrollbar thumb should never scroll to click.
|
||||
if (IsEventOverThumb(aEvent)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -995,6 +1039,12 @@ nsSliderFrame::ShouldScrollToClickForEvent(WidgetGUIEvent* aEvent)
|
|||
return GetScrollToClick() != invertPref;
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
if (mouseEvent->button == WidgetMouseEvent::eRightButton) {
|
||||
return !GetScrollToClick();
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1054,7 +1104,25 @@ nsSliderFrame::HandlePress(nsPresContext* aPresContext,
|
|||
|
||||
mChange = change;
|
||||
DragThumb(true);
|
||||
// On Linux we want to keep scrolling in the direction indicated by |change|
|
||||
// until the mouse is released. On the other platforms we want to stop
|
||||
// scrolling as soon as the scrollbar thumb has reached the current mouse
|
||||
// position.
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
nsRect clientRect;
|
||||
GetClientRect(clientRect);
|
||||
|
||||
// Set the destination point to the very end of the scrollbar so that
|
||||
// scrolling doesn't stop halfway through.
|
||||
if (change > 0) {
|
||||
mDestinationPoint = nsPoint(clientRect.width, clientRect.height);
|
||||
}
|
||||
else {
|
||||
mDestinationPoint = nsPoint(0, 0);
|
||||
}
|
||||
#else
|
||||
mDestinationPoint = eventPoint;
|
||||
#endif
|
||||
StartRepeat();
|
||||
PageUpDown(change);
|
||||
return NS_OK;
|
||||
|
|
|
@ -208,7 +208,6 @@ public class UpdateService extends IntentService {
|
|||
|
||||
Log.i(LOGTAG, "update available, buildID = " + info.buildID);
|
||||
|
||||
int connectionType = netInfo.getType();
|
||||
int autoDownloadPolicy = getAutoDownloadPolicy();
|
||||
|
||||
|
||||
|
@ -217,12 +216,11 @@ public class UpdateService extends IntentService {
|
|||
*
|
||||
* - We have a FORCE_DOWNLOAD flag passed in
|
||||
* - The preference is set to 'always'
|
||||
* - The preference is set to 'wifi' and we are actually using wifi (or regular ethernet)
|
||||
* - The preference is set to 'wifi' and we are using a non-metered network (i.e. the user is OK with large data transfers occuring)
|
||||
*/
|
||||
boolean shouldStartDownload = hasFlag(flags, UpdateServiceHelper.FLAG_FORCE_DOWNLOAD) ||
|
||||
autoDownloadPolicy == UpdateServiceHelper.AUTODOWNLOAD_ENABLED ||
|
||||
(autoDownloadPolicy == UpdateServiceHelper.AUTODOWNLOAD_WIFI &&
|
||||
(connectionType == ConnectivityManager.TYPE_WIFI || connectionType == ConnectivityManager.TYPE_ETHERNET));
|
||||
(autoDownloadPolicy == UpdateServiceHelper.AUTODOWNLOAD_WIFI && !mConnectivityManager.isActiveNetworkMetered());
|
||||
|
||||
if (!shouldStartDownload) {
|
||||
Log.i(LOGTAG, "not initiating automatic update download due to policy " + autoDownloadPolicy);
|
||||
|
|
|
@ -18,7 +18,7 @@ MOZ_ANDROID_MIN_SDK_VERSION=9
|
|||
|
||||
MOZ_SAFE_BROWSING=1
|
||||
|
||||
MOZ_DISABLE_CRYPTOLEGACY=1
|
||||
MOZ_NO_SMART_CARDS=1
|
||||
|
||||
# Enable getUserMedia
|
||||
MOZ_MEDIA_NAVIGATOR=1
|
||||
|
|
|
@ -574,16 +574,18 @@ pref("accessibility.browsewithcaret_shortcut.enabled", true);
|
|||
// unless accessibility.tabfocus is set by the user.
|
||||
pref("accessibility.tabfocus", 7);
|
||||
pref("accessibility.tabfocus_applies_to_xul", false);
|
||||
|
||||
// On OS X, we follow the "Click in the scrollbar to:" system preference
|
||||
// unless this preference was set manually
|
||||
pref("ui.scrollToClick", 0);
|
||||
|
||||
#else
|
||||
// Only on mac tabfocus is expected to handle UI widgets as well as web content
|
||||
pref("accessibility.tabfocus_applies_to_xul", true);
|
||||
#endif
|
||||
|
||||
// We follow the "Click in the scrollbar to:" system preference on OS X and
|
||||
// "gtk-primary-button-warps-slider" property with GTK (since 2.24 / 3.6),
|
||||
// unless this preference is explicitly set.
|
||||
#if !defined(XP_MACOSX) && !defined(MOZ_WIDGET_GTK)
|
||||
pref("ui.scrollToClick", 0);
|
||||
#endif
|
||||
|
||||
// provide ability to turn on support for canvas focus rings
|
||||
pref("canvas.focusring.enabled", true);
|
||||
pref("canvas.customfocusring.enabled", false);
|
||||
|
|
|
@ -611,6 +611,12 @@ class CCacheStats(object):
|
|||
|
||||
return '\n'.join(lines)
|
||||
|
||||
def __nonzero__(self):
|
||||
relative_values = [v for k, v in self._values.items()
|
||||
if k not in self.ABSOLUTE_KEYS]
|
||||
return (all(v >= 0 for v in relative_values) and
|
||||
any(v > 0 for v in relative_values))
|
||||
|
||||
@staticmethod
|
||||
def _format_value(v):
|
||||
if v > CCacheStats.GiB:
|
||||
|
|
|
@ -397,8 +397,9 @@ class Build(MachCommandBase):
|
|||
|
||||
if ccache_start and ccache_end:
|
||||
ccache_diff = ccache_end - ccache_start
|
||||
self.log(logging.INFO, 'ccache',
|
||||
{'msg': ccache_diff.hit_rate_message()}, "{msg}")
|
||||
if ccache_diff:
|
||||
self.log(logging.INFO, 'ccache',
|
||||
{'msg': ccache_diff.hit_rate_message()}, "{msg}")
|
||||
|
||||
if monitor.elapsed > 300:
|
||||
# Display a notification when the build completes.
|
||||
|
|
|
@ -73,6 +73,21 @@ class TestCcacheStats(unittest.TestCase):
|
|||
stats_diff = stats2 - stats1
|
||||
self.assertEqual(stats_diff.hit_rates(), (0.9, 0.05, 0.05))
|
||||
|
||||
def test_stats_contains_data(self):
|
||||
stats0 = CCacheStats(self.STAT0)
|
||||
stats1 = CCacheStats(self.STAT1)
|
||||
stats2 = CCacheStats(self.STAT2)
|
||||
stats_diff_zero = stats1 - stats1
|
||||
stats_diff_negative1 = stats0 - stats1
|
||||
stats_diff_negative2 = stats1 - stats2
|
||||
|
||||
self.assertFalse(stats0)
|
||||
self.assertTrue(stats1)
|
||||
self.assertTrue(stats2)
|
||||
self.assertFalse(stats_diff_zero)
|
||||
self.assertFalse(stats_diff_negative1)
|
||||
self.assertFalse(stats_diff_negative2)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -370,6 +370,13 @@ class TestStrictOrderingOnAppendListWithFlagsFactory(unittest.TestCase):
|
|||
with self.assertRaises(AttributeError):
|
||||
l['b'].baz = False
|
||||
|
||||
l['b'].update(foo=False, bar=12)
|
||||
self.assertEqual(l['b'].foo, False)
|
||||
self.assertEqual(l['b'].bar, 12)
|
||||
|
||||
with self.assertRaises(AttributeError):
|
||||
l['b'].update(xyz=1)
|
||||
|
||||
|
||||
class TestHierarchicalStringListWithFlagsFactory(unittest.TestCase):
|
||||
def test_hierarchical_string_list_with_flags_factory(self):
|
||||
|
|
|
@ -375,6 +375,10 @@ def FlagsFactory(flags):
|
|||
__slots__ = flags.keys()
|
||||
_flags = flags
|
||||
|
||||
def update(self, **kwargs):
|
||||
for k, v in kwargs.iteritems():
|
||||
setattr(self, k, v)
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name not in self.__slots__:
|
||||
raise AttributeError("'%s' object has no attribute '%s'" %
|
||||
|
|
|
@ -372,8 +372,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
|||
case certificateUsageVerifyCA:
|
||||
case certificateUsageStatusResponder: {
|
||||
// XXX This is a pretty useless way to verify a certificate. It is used
|
||||
// by the implementation of window.crypto.importCertificates and in the
|
||||
// certificate viewer UI. Because we don't know what trust bit is
|
||||
// by the certificate viewer UI. Because we don't know what trust bit is
|
||||
// interesting, we just try them all.
|
||||
mozilla::pkix::EndEntityOrCA endEntityOrCA;
|
||||
mozilla::pkix::KeyUsage keyUsage;
|
||||
|
|
|
@ -81,11 +81,6 @@
|
|||
<!ENTITY createCertInfo.msg1 "Key Generation in progress… This may take a few minutes….">
|
||||
<!ENTITY createCertInfo.msg2 "Please wait…">
|
||||
|
||||
<!-- Form Signing confirmation prompt -->
|
||||
<!ENTITY formSigning.title "Text Signing Request">
|
||||
<!ENTITY formSigning.cert "Signing Certificate">
|
||||
<!ENTITY formSigning.confirmPassword "To confirm you agree to sign this text message using your selected certificate, please confirm by entering the master password:">
|
||||
|
||||
<!-- Strings for protectedAuth dialog -->
|
||||
<!ENTITY protectedAuth.title "Protected Token Authentication">
|
||||
<!ENTITY protectedAuth.msg "Please authenticate to the token. Authentication method depends on the type of your token.">
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче