[PATCH] Bug 959870 - Error reporting improvements to WebRTC IdP r=jib

From e1fce543ab34ddd69bb8f8efde56c45bddaa1152 Mon Sep 17 00:00:00 2001
---
 dom/events/test/test_all_synthetic_events.html     |   6 +-
 dom/media/IdpProxy.jsm                             |  10 +-
 dom/media/PeerConnection.js                        |  31 ++----
 dom/media/PeerConnectionIdp.jsm                    | 124 +++++++++++++--------
 dom/media/tests/identity/identityevent.js          |  15 +++
 dom/media/tests/identity/idp-proxy.js              |  10 +-
 dom/media/tests/identity/mochitest.ini             |   1 +
 .../tests/identity/test_getIdentityAssertion.html  |  30 +++--
 dom/media/tests/identity/test_idpproxy.html        |   7 --
 .../tests/identity/test_setIdentityProvider.html   |  25 ++++-
 .../test_setIdentityProviderWithErrors.html        |  72 +++++++++---
 dom/media/tests/mochitest/pc.js                    |  22 +++-
 dom/webidl/RTCPeerConnection.webidl                |   7 +-
 .../RTCPeerConnectionIdentityErrorEvent.webidl     |  23 ++++
 dom/webidl/moz.build                               |   1 +
 modules/libpref/src/init/all.js                    | 108 +++++++++---------
 16 files changed, 316 insertions(+), 176 deletions(-)
 create mode 100644 dom/media/tests/identity/identityevent.js
 create mode 100644 dom/webidl/RTCPeerConnectionIdentityErrorEvent.webidl
This commit is contained in:
Martin Thomson 2014-03-14 11:26:19 -07:00
parent ebcffdc9e3
commit c035bce6b9
16 changed files with 317 additions and 177 deletions

View File

@ -227,7 +227,7 @@ const kEventConstructors = {
},
},
MozApplicationEvent: { create: function (aName, aProps) {
return new MozApplicationEvent(aName, aProps);
return new MozApplicationEvent(aName, aProps);
},
},
MozCellBroadcastEvent: { create: function (aName, aProps) {
@ -326,6 +326,10 @@ const kEventConstructors = {
return new RTCPeerConnectionIdentityEvent(aName, aProps);
},
},
RTCPeerConnectionIdentityErrorEvent: { create: function (aName, aProps) {
return new RTCPeerConnectionIdentityErrorEvent(aName, aProps);
},
},
ScrollAreaEvent: { create: function (aName, aProps) {
var e = document.createEvent("scrollareaevent");
e.initScrollAreaEvent(aName, aProps.bubbles, aProps.cancelable,

View File

@ -53,8 +53,8 @@ IdpChannel.prototype = {
_sandboxReady: function(aCallback, aSandbox) {
// Inject a message channel into the subframe.
this.messagechannel = new aSandbox._frame.contentWindow.MessageChannel();
try {
this.messagechannel = new aSandbox._frame.contentWindow.MessageChannel();
Object.defineProperty(
aSandbox._frame.contentWindow.wrappedJSObject,
"rtcwebIdentityPort",
@ -254,13 +254,13 @@ IdpProxy.prototype = {
// dump a message of type "ERROR" in response to all outstanding
// messages to the IdP
let error = { type: "ERROR", message: "IdP closed" };
let error = { type: "ERROR", error: "IdP closed" };
Object.keys(trackingCopy).forEach(function(k) {
this.trackingCopy[k](error);
}, this);
trackingCopy[k](error);
});
pendingCopy.forEach(function(p) {
p.callback(error);
}, this);
});
},
toString: function() {

View File

@ -313,6 +313,8 @@ RTCPeerConnection.prototype = {
this.makeGetterSetterEH("oniceconnectionstatechange");
this.makeGetterSetterEH("onidentityresult");
this.makeGetterSetterEH("onpeeridentity");
this.makeGetterSetterEH("onidpassertionerror");
this.makeGetterSetterEH("onidpvalidationerror");
this._pc = new this._win.PeerConnectionImpl();
@ -350,8 +352,10 @@ RTCPeerConnection.prototype = {
let prefName = "media.peerconnection.identity.timeout";
let idpTimeout = Services.prefs.getIntPref(prefName);
let warningFunc = this.reportWarning.bind(this);
this._localIdp = new PeerConnectionIdp(this._win, idpTimeout, warningFunc);
this._remoteIdp = new PeerConnectionIdp(this._win, idpTimeout, warningFunc);
this._localIdp = new PeerConnectionIdp(this._win, idpTimeout, warningFunc,
this.dispatchEvent.bind(this));
this._remoteIdp = new PeerConnectionIdp(this._win, idpTimeout, warningFunc,
this.dispatchEvent.bind(this));
},
/**
@ -700,34 +704,17 @@ RTCPeerConnection.prototype = {
this.dispatchEvent(ev);
},
// we're going off spec with the error callback here.
getIdentityAssertion: function(errorCallback) {
getIdentityAssertion: function() {
this._checkClosed();
if (typeof errorCallback !== "function") {
if (errorCallback) {
let message ="getIdentityAssertion argument must be a function";
throw new this._win.DOMError("", message);
}
errorCallback = function() {
this.reportWarning("getIdentityAssertion: no error callback set");
}.bind(this);
}
function gotAssertion(assertion) {
if (assertion) {
this._gotIdentityAssertion(assertion);
} else {
errorCallback("IdP did not produce an assertion");
}
}
try {
this._localIdp.getIdentityAssertion(this._impl.fingerprint,
gotAssertion.bind(this));
}
catch (e) {
errorCallback("Could not get identity assertion: " + e.message);
}
this._localIdp.getIdentityAssertion(this._impl.fingerprint,
gotAssertion.bind(this));
},
updateIce: function(config, constraints) {

View File

@ -18,11 +18,13 @@ XPCOMUtils.defineLazyModuleGetter(this, "IdpProxy",
* @param window (object) the window object to use for miscellaneous goodies
* @param timeout (int) the timeout in milliseconds
* @param warningFunc (function) somewhere to dump warning messages
* @param dispatchEventFunc (function) somewhere to dump error events
*/
function PeerConnectionIdp(window, timeout, warningFunc) {
function PeerConnectionIdp(window, timeout, warningFunc, dispatchEventFunc) {
this._win = window;
this._timeout = timeout || 5000;
this._warning = warningFunc;
this._dispatchEvent = dispatchEventFunc;
this.assertion = null;
this.provider = null;
@ -40,6 +42,7 @@ function PeerConnectionIdp(window, timeout, warningFunc) {
PeerConnectionIdp.prototype = {
setIdentityProvider: function(provider, protocol, username) {
this.provider = provider;
this.protocol = protocol;
this.username = username;
if (this._idpchannel) {
if (this._idpchannel.isSame(provider, protocol)) {
@ -59,6 +62,25 @@ PeerConnectionIdp.prototype = {
}
},
/**
* Generate an error event of the identified type;
* and put a little more precise information in the console.
*/
reportError: function(type, message, extra) {
let args = {
idp: this.provider,
protocol: this.protocol
};
if (extra) {
Object.keys(extra).forEach(function(k) {
args[k] = extra[k];
});
}
this._warning("RTC identity: " + message, null, 0);
let ev = new this._win.RTCPeerConnectionIdentityErrorEvent('idp' + type + 'error', args);
this._dispatchEvent(ev);
},
_getFingerprintFromSdp: function(sdp) {
let sections = sdp.split(PeerConnectionIdp._mLinePattern);
let attributes = sections.map(function(sect) {
@ -68,8 +90,8 @@ PeerConnectionIdp.prototype = {
if (!remainder.match(PeerConnectionIdp._fingerprintPattern)) {
return { algorithm: m[1], digest: m[2] };
}
this._warning("RTC identity: two fingerprint values in same media " +
"section are not supported", null, 0);
this.reportError("validation", "two fingerprint values" +
" in same media section are not supported");
// we have to return non-falsy here so that a media section doesn't
// accidentally fall back to the session-level stuff (which is bad)
return "error";
@ -96,8 +118,7 @@ PeerConnectionIdp.prototype = {
},
_getIdentityFromSdp: function(sdp) {
// we only pull from the session level right now
// TODO allow for per-m=-section identity
// a=identity is session level
let mLineMatch = sdp.match(PeerConnectionIdp._mLinePattern);
let sessionLevel = sdp.substring(0, mLineMatch.index);
let idMatch = sessionLevel.match(PeerConnectionIdp._identityPattern);
@ -106,15 +127,17 @@ PeerConnectionIdp.prototype = {
try {
assertion = JSON.parse(atob(idMatch[1]));
} catch (e) {
this._warning("RTC identity: invalid identity assertion: " + e, null, 0);
this.reportError("validation",
"invalid identity assertion: " + e);
} // for JSON.parse
if (typeof assertion.idp === "object" &&
typeof assertion.idp.domain === "string" &&
typeof assertion.assertion === "string") {
return assertion;
}
this._warning("RTC identity: assertion missing idp/idp.domain/assertion",
null, 0);
this.reportError("validation", "assertion missing" +
" idp/idp.domain/assertion");
}
// undefined!
},
@ -128,14 +151,14 @@ PeerConnectionIdp.prototype = {
verifyIdentityFromSDP: function(sdp, callback) {
let identity = this._getIdentityFromSdp(sdp);
let fingerprint = this._getFingerprintFromSdp(sdp);
// it's safe to use the fingerprint from the SDP here,
// it's safe to use the fingerprint we got from the SDP here,
// only because we ensure that there is only one
if (!fingerprint || !identity) {
callback(null);
return;
}
this.setIdentityProvider(identity.idp.domain, identity.idp.protocol);
this.setIdentityProvider(identity.idp.domain, identity.idp.protocol);
this._verifyIdentity(identity.assertion, fingerprint, callback);
},
@ -160,7 +183,7 @@ PeerConnectionIdp.prototype = {
if (providerPortIdx > 0) {
provider = provider.substring(0, providerPortIdx);
}
var idnService = Components.classes["@mozilla.org/network/idn-service;1"].
let idnService = Components.classes["@mozilla.org/network/idn-service;1"].
getService(Components.interfaces.nsIIDNService);
if (idnService.convertUTF8toACE(tail) !==
idnService.convertUTF8toACE(provider)) {
@ -174,10 +197,10 @@ PeerConnectionIdp.prototype = {
// we are very defensive here when handling the message from the IdP
// proxy so that broken IdPs can only do as little harm as possible.
_checkVerifyResponse: function(
message, fingerprint) {
let warn = function(message) {
this._warning("RTC identity: VERIFY error: " + message, null, 0);
_checkVerifyResponse: function(message, fingerprint) {
let warn = function(msg) {
this.reportError("validation",
"assertion validation failure: " + msg);
}.bind(this);
try {
@ -207,14 +230,10 @@ PeerConnectionIdp.prototype = {
_verifyIdentity: function(
assertion, fingerprint, callback) {
function onVerification(message) {
if (!message) {
this._warning("RTC identity: verification failure", null, 0);
callback(null);
return;
}
if (this._checkVerifyResponse(message, fingerprint)) {
if (message && this._checkVerifyResponse(message, fingerprint)) {
callback(message);
} else {
this._warning("RTC identity: assertion validation failure", null, 0);
callback(null);
}
}
@ -223,7 +242,7 @@ PeerConnectionIdp.prototype = {
type: "VERIFY",
message: assertion
};
this._sendToIdp(request, onVerification.bind(this));
this._sendToIdp(request, "validation", onVerification.bind(this));
},
/**
@ -233,21 +252,16 @@ PeerConnectionIdp.prototype = {
* line) is passed to the callback.
*/
appendIdentityToSDP: function(sdp, fingerprint, callback) {
if (!this._idpchannel) {
callback(sdp);
let onAssertion = function() {
callback(this.wrapSdp(sdp), this.assertion);
}.bind(this);
if (!this._idpchannel || this.assertion) {
onAssertion();
return;
}
if (this.assertion) {
callback(this.wrapSdp(sdp));
return;
}
function onAssertion(assertion) {
callback(this.wrapSdp(sdp), assertion);
}
this._getIdentityAssertion(fingerprint, onAssertion.bind(this));
this._getIdentityAssertion(fingerprint, onAssertion);
},
/**
@ -267,7 +281,9 @@ PeerConnectionIdp.prototype = {
getIdentityAssertion: function(fingerprint, callback) {
if (!this._idpchannel) {
throw new Error("IdP not set");
this.reportError("assertion", "IdP not set");
callback(null);
return;
}
this._getIdentityAssertion(fingerprint, callback);
@ -298,19 +314,33 @@ PeerConnectionIdp.prototype = {
callback(this.assertion);
}
this._sendToIdp(request, trapAssertion.bind(this));
this._sendToIdp(request, "assertion", trapAssertion.bind(this));
},
/**
* Packages a message and sends it to the IdP.
* @param request (dictionary) the message to send
* @param type (DOMString) the type of message (assertion/validation)
* @param callback (function) the function to call with the results
*/
_sendToIdp: function(request, callback) {
// this is not secure
// but there are no good alternatives until bug 968335 lands
// when that happens, change this to use the new mechanism
request.origin = this._win.document.nodePrincipal.origin;
_sendToIdp: function(request, type, callback) {
request.origin = Cu.getWebIDLCallerPrincipal().origin;
this._idpchannel.send(request, this._wrapCallback(type, callback));
},
this._idpchannel.send(request, this._wrapCallback(callback));
_reportIdpError: function(type, message) {
let args = {};
let msg = "";
if (message.type === "ERROR") {
msg = message.error;
} else {
msg = JSON.stringify(message.message);
if (message.type === "LOGINNEEDED") {
args.loginUrl = message.loginUrl;
}
}
this.reportError(type, "received response of type '" +
message.type + "' from IdP: " + msg, args);
},
/**
@ -318,10 +348,10 @@ PeerConnectionIdp.prototype = {
* receive any message other than one where the IdP generated a "SUCCESS"
* response.
*/
_wrapCallback: function(callback) {
_wrapCallback: function(type, callback) {
let timeout = this._win.setTimeout(function() {
this._warning("RTC identity: IdP timeout for " + this._idpchannel + " " +
(this._idpchannel.ready ? "[ready]" : "[not ready]"), null, 0);
this.reportError(type, "IdP timeout for " + this._idpchannel + " " +
(this._idpchannel.ready ? "[ready]" : "[not ready]"));
timeout = null;
callback(null);
}.bind(this), this._timeout);
@ -332,12 +362,12 @@ PeerConnectionIdp.prototype = {
}
this._win.clearTimeout(timeout);
timeout = null;
var content = null;
let content = null;
if (message.type === "SUCCESS") {
content = message.message;
} else {
this._warning("RTC Identity: received response of type '" +
message.type + "' from IdP: " + message.message, null, 0);
this._reportIdpError(type, message);
}
callback(content);
}.bind(this);

View File

@ -0,0 +1,15 @@
(function(g) {
'use strict';
g.trapIdentityEvents = function(target) {
var state = {};
var identityEvents = ['idpassertionerror', 'idpvalidationerror',
'identityresult', 'peeridentity'];
identityEvents.forEach(function(name) {
target.addEventListener(name, function(e) {
state[name] = e;
}, false);
});
return state;
};
}(this));

View File

@ -3,6 +3,8 @@
function IDPJS() {
this.domain = window.location.host;
var p = window.location.pathname;
this.protocol = p.substring(p.lastIndexOf('/') + 1) + window.location.hash;
this.username = "someone@" + this.domain;
// so rather than create a million different IdP configurations and litter
// the world with files all containing near-identical code, let's use the
@ -70,7 +72,7 @@
message : {
idp : {
domain : this.domain,
protocol : "idp.html"
protocol : this.protocol
},
assertion : JSON.stringify({
username : this.username,
@ -82,12 +84,16 @@
case "VERIFY":
var payload = JSON.parse(message.message);
var contents = payload.contents;
if (this.instructions.some(is("bad"))) {
contents = {};
}
this.sendResponse({
type : "SUCCESS",
id : message.id,
message : {
identity : payload.username,
contents : payload.contents
contents : contents
}
});
break;

View File

@ -3,6 +3,7 @@ skip-if = e10s
support-files =
/.well-known/idp-proxy/idp.html
/.well-known/idp-proxy/idp-proxy.js
identityevent.js
# All tests are disabled on android due to lack of https support in mochitest
# (Bug 975149)

View File

@ -30,10 +30,11 @@ function theTest() {
[
"GET_IDENTITY_ASSERTION_FAILS_WITHOUT_PROVIDER",
function(test) {
test.pcLocal._pc.getIdentityAssertion(function(err) {
ok(err, "getIdentityAssertion must fail without provider");
test.pcLocal._pc.onidpassertionerror = function(e) {
ok(e, "getIdentityAssertion must fail without provider");
test.next();
});
};
test.pcLocal._pc.getIdentityAssertion();
},
],
[
@ -52,6 +53,10 @@ function theTest() {
test.next();
}
};
test.pcLocal._pc.onidpassertionerror = function(e) {
ok(false, "error event fired");
test.next();
};
test.pcLocal._pc.getIdentityAssertion();
test.pcLocal._pc.getIdentityAssertion();
}
@ -64,10 +69,11 @@ function theTest() {
ok(false, "Should not get an identity result");
test.next();
};
test.pcLocal._pc.getIdentityAssertion(function(err) {
ok(err, "Got error callback from getIdentityAssertion");
test.pcLocal._pc.onidpassertionerror = function(err) {
ok(err, "Got error event from getIdentityAssertion");
test.next();
});
};
test.pcLocal._pc.getIdentityAssertion();
}
],
[
@ -78,10 +84,11 @@ function theTest() {
ok(false, "Should not get an identity result");
test.next();
};
test.pcLocal._pc.getIdentityAssertion(function(err) {
ok(err, "Got error callback from getIdentityAssertion");
test.pcLocal._pc.onidpassertionerror = function(e) {
ok(e, "Got error callback from getIdentityAssertion");
test.next();
});
};
test.pcLocal._pc.getIdentityAssertion();
}
],
[
@ -92,10 +99,11 @@ function theTest() {
checkIdentity(e.assertion, 'user@example.com');
test.next();
};
test.pcLocal._pc.getIdentityAssertion(function(err) {
test.pcLocal._pc.onidpassertionerror = function(e) {
ok(false, "Got error callback from getIdentityAssertion");
test.next();
});
};
test.pcLocal._pc.getIdentityAssertion();
}
]
]);

View File

@ -55,19 +55,16 @@ function handleFailure(done) {
ok(false, "IdP error" + error);
done();
}
setTimeout(failure, 5000);
return failure;
}
function test_success_response(done) {
var idp;
var failure = handleFailure(done);
var timeout = setTimeout(failure, 5000);;
function handleResponse(response) {
is(SpecialPowers.wrap(response).type, "SUCCESS", "IdP responds with SUCCESS");
idp.close();
clearTimeout(timeout);
done();
}
@ -79,12 +76,10 @@ function test_success_response(done) {
function test_error_response(done) {
var idp;
var failure = handleFailure(done);
var timeout = setTimeout(failure, 5000);;
function handleResponse(response) {
is(SpecialPowers.wrap(response).type, "ERROR", "IdP should produce ERROR");
idp.close();
clearTimeout(timeout);
done();
}
@ -96,13 +91,11 @@ function test_error_response(done) {
function test_delayed_response(done) {
var idp;
var failure = handleFailure(done);
var timeout = setTimeout(failure, 5000);;
function handleResponse(response) {
is(SpecialPowers.wrap(response).type, "SUCCESS",
"IdP should handle delayed response");
idp.close();
clearTimeout(timeout);
done();
}

View File

@ -7,6 +7,7 @@
<script type="application/javascript" src="../mochitest/head.js"></script>
<script type="application/javascript" src="../mochitest/pc.js"></script>
<script type="application/javascript" src="../mochitest/templates.js"></script>
<script type="application/javascript" src="identityevent.js"></script>
</head>
<body>
<pre id="test">
@ -21,6 +22,10 @@ function theTest() {
test.setMediaConstraints([{audio: true}], [{audio: true}]);
test.setIdentityProvider(test.pcLocal, "test1.example.com", "idp.html", "someone");
test.setIdentityProvider(test.pcRemote, "test2.example.com", "idp.html", "someone");
var localEvents = trapIdentityEvents(test.pcLocal._pc);
var remoteEvents = trapIdentityEvents(test.pcRemote._pc);
test.chain.append([
[
"PEER_IDENTITY_IS_SET_CORRECTLY",
@ -33,6 +38,7 @@ function theTest() {
function checkOrSetupCheck(pc, pfx, idp, name) {
function checkIdentity() {
ok(pc.peerIdentity, pfx + "peerIdentity is set");
is(pc.peerIdentity.idp, idp, pfx + "IdP is correct");
is(pc.peerIdentity.name, name + "@" + idp, pfx + "identity is correct");
}
@ -53,11 +59,6 @@ function theTest() {
}
}
setTimeout(function() {
ok(false, "Timed out waiting for peerIdentity.");
test.next();
}, 5000); // probably should be something in the base harness for this
checkOrSetupCheck(test.pcLocal._pc, "local: ", "test2.example.com", "someone");
checkOrSetupCheck(test.pcRemote._pc, "remote: ", "test1.example.com", "someone");
if (outstanding <= 0) {
@ -65,6 +66,20 @@ function theTest() {
}
}
],
[
"CHECK_IDENTITY_EVENTS",
function(test) {
ok(!localEvents.idpassertionerror , "No assertion generation errors on local");
ok(!remoteEvents.idpassertionerror, "No assertion generation errors on remote");
ok(!localEvents.idpvalidationerror, "No assertion validation errors on local");
ok( !remoteEvents.idpvalidationerror, "No assertion validation errors on remote");
ok(localEvents.identityresult, "local acquired identity assertions");
ok(remoteEvents.identityresult, "remote acquired identity assertions");
ok(localEvents.peeridentity, "local got peer identity");
ok(remoteEvents.peeridentity, "remote got peer identity");
test.next();
}
],
[
"OFFERS_AND_ANSWERS_INCLUDE_IDENTITY",
function(test) {

View File

@ -6,6 +6,7 @@
<script type="application/javascript" src="../mochitest/head.js"></script>
<script type="application/javascript" src="../mochitest/pc.js"></script>
<script type="application/javascript" src="../mochitest/templates.js"></script>
<script type="application/javascript" src="identityevent.js"></script>
</head>
<body>
<pre id="test">
@ -20,25 +21,60 @@ runTest(function () {
test.setMediaConstraints([{audio: true}], [{audio: true}]);
// first example generates an error
test.setIdentityProvider(test.pcLocal, 'example.com', 'idp.html#error', 'nobody');
// first doesn't even get a ready message from the IdP - results in a timeout
test.setIdentityProvider(test.pcRemote, 'example.com', 'idp.html#error:ready', 'nobody');
// second generates a bad assertion; which fails to validate
test.setIdentityProvider(test.pcRemote, 'example.com', 'idp.html#bad', 'nobody');
var localEvents = trapIdentityEvents(test.pcLocal._pc);
var remoteEvents = trapIdentityEvents(test.pcRemote._pc);
test.chain.append([
[
"PEER_IDENTITY_IS_EMPTY",
function(test) {
ok(!test.pcLocal._pc.peerIdentity, "local peerIdentity is not set");
ok(!test.pcRemote._pc.peerIdentity, "remote peerIdentity is not set");
test.next();
}
],
[
"OFFERS_AND_ANSWERS_DONT_INCLUDE_IDENTITY",
function(test) {
ok(!test.pcLocal._last_offer.sdp.contains("a=identity"), "a=identity not contained in the offer SDP");
ok(!test.pcRemote._last_answer.sdp.contains("a=identity"), "a=identity not contained in the answer SDP");
test.next();
}
],
[
'CHECK_IDENTITY_EVENTS',
function(test) {
function checkEvents() {
ok(localEvents.idpassertionerror, 'local assertion generation should fail (idpassertionerror)');
is(localEvents.idpassertionerror.idp, 'example.com', 'event IdP is correct');
is(localEvents.idpassertionerror.protocol, 'idp.html#error', 'event IdP protocol is #error');
ok(!remoteEvents.idpassertionerror, 'remote assertion generation should succeed (idpassertionerror)');
ok(!localEvents.identityresult, 'local assertion generation should fail (identityresult)');
ok(remoteEvents.identityresult, 'remote assertion generation should succeed (identityresult)');
ok(!localEvents.peeridentity, 'no peer identity event for local peer');
ok(!remoteEvents.peeridentity, 'no peer identity event for remote peer');
ok(localEvents.idpvalidationerror, 'local fails to validate');
is(localEvents.idpvalidationerror.idp, 'example.com', 'event IdP is correct');
is(localEvents.idpvalidationerror.protocol, 'idp.html#bad', 'event IdP protocol is #bad');
ok(!remoteEvents.idpvalidationerror, 'remote doesn\'t even see an assertion');
test.next();
}
// we actually have to wait on this because IdP validation happens asynchronously
if (localEvents.idpvalidationerror) {
checkEvents();
} else {
// have to let the other event handler have a chance to record success
// before we run the checks that rely on that recording
test.pcLocal._pc.onidpvalidationerror = setTimeout.bind(window, checkEvents, 1);
}
}
],
[
'PEER_IDENTITY_IS_EMPTY',
function(test) {
ok(!test.pcLocal._pc.peerIdentity, 'local peerIdentity is not set');
ok(!test.pcRemote._pc.peerIdentity, 'remote peerIdentity is not set');
test.next();
}
],
[
'ONLY_REMOTE_SDP_INCLUDES_IDENTITY_ASSERTION',
function(test) {
ok(!test.pcLocal._last_offer.sdp.contains('a=identity'), 'a=identity not contained in the offer SDP');
ok(test.pcRemote._last_answer.sdp.contains('a=identity'), 'a=identity is contained in the answer SDP');
test.next();
}
]
]);
test.run();
});

View File

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/**
* This class mimics a state machine and handles a list of commands by
@ -73,7 +75,8 @@ CommandChain.prototype = {
var step = self._commands[self._current];
self._current++;
info("Run step: " + step[0]); // Label
self.currentStepLabel = step[0];
info("Run step: " + self.currentStepLabel);
step[1](self._framework); // Execute step
}
else if (typeof(self.onFinished) === 'function') {
@ -505,9 +508,24 @@ PeerConnectionTest.prototype.close = function PCT_close(onSuccess) {
* Executes the next command.
*/
PeerConnectionTest.prototype.next = function PCT_next() {
if (this._stepTimeout) {
clearTimeout(this._stepTimeout);
this._stepTimeout = null;
}
this.chain.executeNext();
};
/**
* Set a timeout for the current step.
* @param {long] ms the number of milliseconds to allow for this step
*/
PeerConnectionTest.prototype.setStepTimeout = function(ms) {
this._stepTimeout = setTimeout(function() {
ok(false, "Step timed out: " + this.chain.currentStepLabel);
this.next();
}.bind(this), ms);
};
/**
* Creates an answer for the specified peer connection instance
* and automatically handles the failure case.
@ -1489,7 +1507,7 @@ PeerConnectionWrapper.prototype = {
* Checks if the ICE connection state still waits for a connection to get
* established.
*
* @returns {boolean} True if the connection state is "checking" or "new",
* @returns {boolean} True if the connection state is "checking" or "new",
* otherwise false.
*/
isIceConnectionPending : function PCW_isIceConnectionPending() {

View File

@ -92,7 +92,7 @@ interface mozRTCPeerConnection : EventTarget {
optional DOMString protocol,
optional DOMString username);
[Pref="media.peerconnection.identity.enabled"]
void getIdentityAssertion(optional RTCPeerConnectionErrorCallback failureCallback);
void getIdentityAssertion();
void createOffer (RTCSessionDescriptionCallback successCallback,
RTCPeerConnectionErrorCallback failureCallback,
optional MediaConstraints constraints);
@ -145,5 +145,8 @@ interface mozRTCPeerConnection : EventTarget {
attribute EventHandler onidentityresult;
[Pref="media.peerconnection.identity.enabled"]
attribute EventHandler onpeeridentity;
[Pref="media.peerconnection.identity.enabled"]
attribute EventHandler onidpassertionerror;
[Pref="media.peerconnection.identity.enabled"]
attribute EventHandler onidpvalidationerror;
};

View File

@ -0,0 +1,23 @@
/* -*- 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/.
*
* Proposed only, not in spec yet:
* http://lists.w3.org/Archives/Public/public-webrtc/2013Dec/0104.html
*/
dictionary RTCPeerConnectionIdentityErrorEventInit : EventInit {
DOMString idp = "";
DOMString protocol = "";
DOMString? loginUrl = null;
};
[ChromeOnly,
Constructor(DOMString type,
optional RTCPeerConnectionIdentityErrorEventInit eventInitDict)]
interface RTCPeerConnectionIdentityErrorEvent : Event {
readonly attribute DOMString idp;
readonly attribute DOMString protocol;
readonly attribute DOMString? loginUrl;
};

View File

@ -597,6 +597,7 @@ GENERATED_EVENTS_WEBIDL_FILES = [
'MozStkCommandEvent.webidl',
'RTCDataChannelEvent.webidl',
'RTCPeerConnectionIceEvent.webidl',
'RTCPeerConnectionIdentityErrorEvent.webidl',
'RTCPeerConnectionIdentityEvent.webidl',
'TrackEvent.webidl',
'UserProximityEvent.webidl',

View File

@ -56,7 +56,7 @@ pref("browser.cache.disk.max_entry_size", 51200); // 50 MB
pref("browser.cache.memory.enable", true);
// -1 = determine dynamically, 0 = none, n = memory capacity in kilobytes
//pref("browser.cache.memory.capacity", -1);
// Max-size (in KB) for entries in memory cache. Set to -1 for no limit.
// Max-size (in KB) for entries in memory cache. Set to -1 for no limit.
// (Note: entries bigger than than 90% of the mem-cache are never cached)
pref("browser.cache.memory.max_entry_size", 5120);
pref("browser.cache.disk_cache_ssl", true);
@ -128,8 +128,8 @@ pref("browser.display.use_system_colors", false);
pref("browser.display.foreground_color", "#000000");
pref("browser.display.background_color", "#FFFFFF");
pref("browser.display.force_inline_alttext", false); // true = force ALT text for missing images to be layed out inline
// 0 = no external leading,
// 1 = use external leading only when font provides,
// 0 = no external leading,
// 1 = use external leading only when font provides,
// 2 = add extra leading both internal leading and external leading are zero
pref("browser.display.normal_lineheight_calc_control", 2);
pref("browser.display.show_image_placeholders", true); // true = show image placeholders while image is loaded and when image is broken
@ -259,9 +259,9 @@ pref("media.peerconnection.use_document_iceservers", true);
// Do not enable identity before fixing domain comparison: see Bug 958741
// Do not enable identity before fixing origin spoofing: see Bug 968335
pref("media.peerconnection.identity.enabled", false);
pref("media.peerconnection.identity.timeout", 5000);
pref("media.peerconnection.identity.timeout", 10000);
// These values (aec, agc, and noice) are from media/webrtc/trunk/webrtc/common_types.h
// kXxxUnchanged = 0, kXxxDefault = 1, and higher values are specific to each
// kXxxUnchanged = 0, kXxxDefault = 1, and higher values are specific to each
// setting (for Xxx = Ec, Agc, or Ns). Defaults are all set to kXxxDefault here.
pref("media.peerconnection.turn.disable", false);
pref("media.peerconnection.aec_enabled", true);
@ -350,7 +350,7 @@ pref("gfx.hidpi.enabled", 2);
pref("gfx.layerscope.enabled", false);
pref("gfx.layerscope.port", 23456);
// 0 = Off, 1 = Full, 2 = Tagged Images Only.
// 0 = Off, 1 = Full, 2 = Tagged Images Only.
// See eCMSMode in gfx/thebes/gfxPlatform.h
pref("gfx.color_management.mode", 2);
pref("gfx.color_management.display_profile", "");
@ -594,7 +594,7 @@ pref("nglayout.enable_drag_images", true);
pref("nglayout.debug.paint_flashing", false);
pref("nglayout.debug.paint_flashing_chrome", false);
// enable/disable widget update area flashing --- only supported with
// enable/disable widget update area flashing --- only supported with
// BasicLayers (other layer managers always update the entire widget area)
pref("nglayout.debug.widget_update_flashing", false);
@ -666,7 +666,7 @@ pref("print.print_unwriteable_margin_left", -1);
pref("print.print_unwriteable_margin_right", -1);
pref("print.print_unwriteable_margin_bottom", -1);
// Enables you to specify the gap from the edge of the paper's
// Enables you to specify the gap from the edge of the paper's
// unwriteable area to the margin.
// This is used by both Printing and Print Preview
// Units are in 1/100ths of an inch.
@ -675,7 +675,7 @@ pref("print.print_edge_left", 0);
pref("print.print_edge_right", 0);
pref("print.print_edge_bottom", 0);
// Pref used by the spellchecker extension to control the
// Pref used by the spellchecker extension to control the
// maximum number of misspelled words that will be underlined
// in a document.
pref("extensions.spellcheck.inline.max-misspellings", 500);
@ -809,7 +809,7 @@ pref("image.animation_mode", "normal");
pref("security.fileuri.strict_origin_policy", true);
// If there is ever a security firedrill that requires
// us to block certian ports global, this is the pref
// us to block certian ports global, this is the pref
// to use. Is is a comma delimited list of port numbers
// for example:
// pref("network.security.ports.banned", "1,2,3,4,5");
@ -876,7 +876,7 @@ pref("network.warnOnAboutNetworking", true);
// pref("network.protocol-handler.expose.imap", true);
// <http>
pref("network.http.version", "1.1"); // default
pref("network.http.version", "1.1"); // default
// pref("network.http.version", "1.0"); // uncomment this out in case of problems
// pref("network.http.version", "0.9"); // it'll work too if you're crazy
// keep-alive option is effectively obsolete. Nevertheless it'll work with
@ -906,7 +906,7 @@ pref("network.http.response.timeout", 300);
// Limit the absolute number of http connections.
// Note: the socket transport service will clamp the number below 256 if the OS
// cannot allocate that many FDs, and it also always tries to reserve up to 250
// file descriptors for things other than sockets.
// file descriptors for things other than sockets.
pref("network.http.max-connections", 256);
// If NOT connecting via a proxy, then
@ -930,13 +930,13 @@ pref("network.http.accept.default", "text/html,application/xhtml+xml,application
// Prefs allowing granular control of referers
// 0=don't send any, 1=send only on clicks, 2=send on image requests as well
pref("network.http.sendRefererHeader", 2);
// false=real referer, true=spoof referer (use target URI as referer)
pref("network.http.referer.spoofSource", false);
pref("network.http.sendRefererHeader", 2);
// false=real referer, true=spoof referer (use target URI as referer)
pref("network.http.referer.spoofSource", false);
// 0=full URI, 1=scheme+host+port+path, 2=scheme+host+port
pref("network.http.referer.trimmingPolicy", 0);
pref("network.http.referer.trimmingPolicy", 0);
// 0=always send, 1=send iff base domains match, 2=send iff hosts match
pref("network.http.referer.XOriginPolicy", 0);
pref("network.http.referer.XOriginPolicy", 0);
// Controls whether we send HTTPS referres to other HTTPS sites.
// By default this is enabled for compatibility (see bug 141641)
@ -1062,7 +1062,7 @@ pref("network.ftp.control.qos", 0);
// <ws>: WebSocket
pref("network.websocket.enabled", true);
// 2147483647 == PR_INT32_MAX == ~2 GB
// 2147483647 == PR_INT32_MAX == ~2 GB
pref("network.websocket.max-message-size", 2147483647);
// Should we automatically follow http 3xx redirects during handshake
@ -1100,7 +1100,7 @@ pref("network.websocket.max-connections", 200);
pref("network.websocket.allowInsecureFromHTTPS", false);
// by default we delay websocket reconnects to same host/port if previous
// connection failed, per RFC 6455 section 7.2.3
// connection failed, per RFC 6455 section 7.2.3
pref("network.websocket.delay-failed-reconnects", true);
// </ws>
@ -1187,7 +1187,7 @@ pref("network.IDN.whitelist.yt", true);
// IDN ccTLDs
// ae, UAE, .<Emarat>
pref("network.IDN.whitelist.xn--mgbaam7a8h", true);
pref("network.IDN.whitelist.xn--mgbaam7a8h", true);
// cn, China, .<China> with variants
pref("network.IDN.whitelist.xn--fiqz9s", true); // Traditional
pref("network.IDN.whitelist.xn--fiqs8s", true); // Simplified
@ -1210,7 +1210,7 @@ pref("network.IDN.whitelist.xn--90a3ac", true);
// ru, Russian Federation, .<RF>
pref("network.IDN.whitelist.xn--p1ai", true);
// sa, Saudi Arabia, .<al-Saudiah> with variants
pref("network.IDN.whitelist.xn--mgberp4a5d4ar", true);
pref("network.IDN.whitelist.xn--mgberp4a5d4ar", true);
pref("network.IDN.whitelist.xn--mgberp4a5d4a87g", true);
pref("network.IDN.whitelist.xn--mgbqly7c0a67fbc", true);
pref("network.IDN.whitelist.xn--mgbqly7cvafr", true);
@ -1248,9 +1248,9 @@ pref("network.IDN.whitelist.xn--jxalpdlp", true);
pref("network.IDN.whitelist.xn--kgbechtv", true);
pref("network.IDN.whitelist.xn--zckzah", true);
// If a domain includes any of the following characters, it may be a spoof
// attempt and so we always display the domain name as punycode. This would
// override the settings "network.IDN_show_punycode" and
// If a domain includes any of the following characters, it may be a spoof
// attempt and so we always display the domain name as punycode. This would
// override the settings "network.IDN_show_punycode" and
// "network.IDN.whitelist.*".
pref("network.IDN.blacklist_chars", "\u0020\u00A0\u00BC\u00BD\u00BE\u01C3\u02D0\u0337\u0338\u0589\u05C3\u05F4\u0609\u060A\u066A\u06D4\u0701\u0702\u0703\u0704\u115F\u1160\u1735\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u200B\u2024\u2027\u2028\u2029\u202F\u2039\u203A\u2041\u2044\u2052\u205F\u2153\u2154\u2155\u2156\u2157\u2158\u2159\u215A\u215B\u215C\u215D\u215E\u215F\u2215\u2236\u23AE\u2571\u29F6\u29F8\u2AFB\u2AFD\u2FF0\u2FF1\u2FF2\u2FF3\u2FF4\u2FF5\u2FF6\u2FF7\u2FF8\u2FF9\u2FFA\u2FFB\u3000\u3002\u3014\u3015\u3033\u3164\u321D\u321E\u33AE\u33AF\u33C6\u33DF\uA789\uFE14\uFE15\uFE3F\uFE5D\uFE5E\uFEFF\uFF0E\uFF0F\uFF61\uFFA0\uFFF9\uFFFA\uFFFB\uFFFC\uFFFD");
@ -1343,7 +1343,7 @@ pref("network.negotiate-auth.using-native-gsslib", true);
#ifdef XP_WIN
// Default to using the SSPI intead of GSSAPI on windows
// Default to using the SSPI intead of GSSAPI on windows
pref("network.auth.use-sspi", true);
#endif
@ -1354,7 +1354,7 @@ pref("network.auth.use-sspi", true);
// with native NTLM. (See bug 520607 for details.) Using generic NTLM authentication
// can expose the user to reflection attack vulnerabilities. Do not change this
// unless you know what you're doing!
// This pref should be removed 6 months after the release of firefox 3.6.
// This pref should be removed 6 months after the release of firefox 3.6.
pref("network.auth.force-generic-ntlm", false);
// The following prefs are used to enable automatic use of the operating
@ -1703,7 +1703,7 @@ pref("profile.manage_only_at_launch", false);
pref("prefs.converted-to-utf8",false);
// --------------------------------------------------
// IBMBIDI
// IBMBIDI
// --------------------------------------------------
//
// ------------------
@ -1761,7 +1761,7 @@ pref("layout.word_select.stop_at_punctuation", true);
// 0 = use platform default
// 1 = caret moves and blinks as when there is no selection; word
// delete deselects the selection and then deletes word
// 2 = caret moves to selection edge and is not visible during selection;
// 2 = caret moves to selection edge and is not visible during selection;
// word delete deletes the selection (Mac and Linux default)
// 3 = caret moves and blinks as when there is no selection; word delete
// deletes the selection
@ -1796,7 +1796,7 @@ pref("layout.css.masking.enabled", false);
pref("layout.css.masking.enabled", true);
#endif
// Is support for mix-blend-mode enabled?
// Is support for mix-blend-mode enabled?
pref("layout.css.mix-blend-mode.enabled", false);
// Is support for the the @supports rule enabled?
@ -1997,7 +1997,7 @@ pref("dom.ipc.plugins.parentTimeoutSecs", 0);
// we consider it failed.
pref("dom.ipc.plugins.processLaunchTimeoutSecs", 45);
#ifdef XP_WIN
// How long a plugin is allowed to process a synchronous IPC message
// How long a plugin is allowed to process a synchronous IPC message
// before we display the plugin hang UI
pref("dom.ipc.plugins.hangUITimeoutSecs", 11);
// Minimum time that the plugin hang UI will be displayed
@ -2287,7 +2287,7 @@ pref("font.name-list.monospace.zh-CN", "MS Song, SimSun, SimSun-ExtB");
// Per Taiwanese users' demand. They don't want to use TC fonts for
// rendering Latin letters. (bug 88579)
pref("font.name.serif.zh-TW", "Times New Roman");
pref("font.name.serif.zh-TW", "Times New Roman");
pref("font.name.sans-serif.zh-TW", "Arial");
pref("font.name.monospace.zh-TW", "MingLiU");
pref("font.name-list.serif.zh-TW", "PMingLiu, MingLiU, MingLiU-ExtB");
@ -2326,8 +2326,8 @@ pref("font.name-list.monospace.x-armn", "Arial AMU, Arial Unicode MS, Code2000")
pref("font.name.serif.x-beng", "Vrinda");
pref("font.name.sans-serif.x-beng", "Vrinda");
pref("font.name.monospace.x-beng", "Mitra Mono");
pref("font.name-list.serif.x-beng", "Vrinda, Akaash, Likhan, Ekushey Punarbhaba, Code2000, Arial Unicode MS");
pref("font.name-list.sans-serif.x-beng", "Vrinda, Akaash, Likhan, Ekushey Punarbhaba, Code2000, Arial Unicode MS");
pref("font.name-list.serif.x-beng", "Vrinda, Akaash, Likhan, Ekushey Punarbhaba, Code2000, Arial Unicode MS");
pref("font.name-list.sans-serif.x-beng", "Vrinda, Akaash, Likhan, Ekushey Punarbhaba, Code2000, Arial Unicode MS");
pref("font.name-list.monospace.x-beng", "Likhan, Mukti Narrow, Code2000, Arial Unicode MS");
pref("font.name.serif.x-cans", "Aboriginal Serif");
@ -2537,7 +2537,7 @@ pref("font.size.fixed.zh-HK", 16);
// We have special support for Monotype Symbol on Windows.
pref("font.mathfont-family", "MathJax_Main, STIXNonUnicode, STIXSizeOneSym, STIXSize1, STIXGeneral, Asana Math, Symbol, DejaVu Sans, Cambria Math");
// cleartype settings - false implies default system settings
// cleartype settings - false implies default system settings
// use cleartype rendering for downloadable fonts (win xp only)
pref("gfx.font_rendering.cleartype.use_for_downloadable_fonts", true);
@ -2552,7 +2552,7 @@ pref("gfx.font_rendering.cleartype.always_use_for_content", false);
// HKLM/Software/Microsoft/Avalon.Graphics/<display> (gamma, pixel structure)
// and selection of the ClearType/antialiasing mode.
//
// A value of -1 implies use the default value, otherwise value ranges
// A value of -1 implies use the default value, otherwise value ranges
// follow registry settings:
// gamma [1000, 2200] default: based on screen, typically 2200 (== 2.2)
// enhanced contrast [0, 1000] default: 50
@ -2569,7 +2569,7 @@ pref("gfx.font_rendering.cleartype.always_use_for_content", false);
// See:
// http://msdn.microsoft.com/en-us/library/aa970267.aspx
// http://msdn.microsoft.com/en-us/library/dd368190%28v=VS.85%29.aspx
// Note: DirectWrite uses the "Enhanced Contrast Level" value rather than the
// Note: DirectWrite uses the "Enhanced Contrast Level" value rather than the
// "Text Contrast Level" value
pref("gfx.font_rendering.cleartype_params.gamma", -1);
@ -2675,7 +2675,7 @@ pref("browser.drag_out_of_frame_style", 1);
pref("ui.key.saveLink.shift", false); // true = shift, false = meta
// default fonts (in UTF8 and using canonical names)
// to determine canonical font names, use a debug build and
// to determine canonical font names, use a debug build and
// enable NSPR logging for module fontInfoLog:5
// canonical names immediately follow '(fontinit) family:' in the log
@ -2714,10 +2714,10 @@ pref("font.name-list.fantasy.he", "Times New Roman");
pref("font.name.serif.ja", "Hiragino Mincho ProN");
pref("font.name.sans-serif.ja", "Hiragino Kaku Gothic ProN");
pref("font.name.monospace.ja", "Osaka-Mono");
pref("font.name.monospace.ja", "Osaka-Mono");
pref("font.name-list.serif.ja", "Hiragino Mincho ProN,Hiragino Mincho Pro");
pref("font.name-list.sans-serif.ja", "Hiragino Kaku Gothic ProN,Hiragino Kaku Gothic Pro");
pref("font.name-list.monospace.ja", "Osaka-Mono");
pref("font.name-list.monospace.ja", "Osaka-Mono");
pref("font.name.serif.ko", "AppleMyungjo");
pref("font.name.sans-serif.ko", "Apple SD Gothic Neo");
@ -2750,7 +2750,7 @@ pref("font.name.monospace.x-armn", "Mshtakan");
pref("font.name-list.serif.x-armn", "Mshtakan");
pref("font.name-list.sans-serif.x-armn", "Mshtakan");
pref("font.name-list.monospace.x-armn", "Mshtakan");
pref("font.name.serif.x-baltic", "Times");
pref("font.name.sans-serif.x-baltic", "Helvetica");
pref("font.name.monospace.x-baltic", "Courier");
@ -2821,42 +2821,42 @@ pref("font.name-list.monospace.x-ethi", "Kefa,Abyssinica SIL");
pref("font.name.serif.x-geor", "TITUS Cyberbit Basic");
pref("font.name.sans-serif.x-geor", "Zuzumbo");
pref("font.name.monospace.x-geor", "Zuzumbo");
pref("font.name-list.serif.x-geor", "TITUS Cyberbit Basic");
pref("font.name-list.serif.x-geor", "TITUS Cyberbit Basic");
pref("font.name-list.sans-serif.x-geor", "Zuzumbo");
pref("font.name-list.monospace.x-geor", "Zuzumbo");
pref("font.name.serif.x-gujr", "Gujarati MT");
pref("font.name.sans-serif.x-gujr", "Gujarati Sangam MN");
pref("font.name.monospace.x-gujr", "Gujarati Sangam MN");
pref("font.name-list.serif.x-gujr", "Gujarati MT");
pref("font.name-list.serif.x-gujr", "Gujarati MT");
pref("font.name-list.sans-serif.x-gujr", "Gujarati Sangam MN,Gujarati MT");
pref("font.name-list.monospace.x-gujr", "Gujarati Sangam MN,Gujarati MT");
pref("font.name.serif.x-guru", "Gurmukhi MT");
pref("font.name.sans-serif.x-guru", "Gurmukhi MT");
pref("font.name.monospace.x-guru", "Gurmukhi MT");
pref("font.name-list.serif.x-guru", "Gurmukhi MT");
pref("font.name-list.serif.x-guru", "Gurmukhi MT");
pref("font.name-list.sans-serif.x-guru", "Gurmukhi MT");
pref("font.name-list.monospace.x-guru", "Gurmukhi MT");
pref("font.name.serif.x-khmr", "Khmer MN");
pref("font.name.sans-serif.x-khmr", "Khmer Sangam MN");
pref("font.name.monospace.x-khmr", "Khmer Sangam MN");
pref("font.name-list.serif.x-khmr", "Khmer MN");
pref("font.name-list.serif.x-khmr", "Khmer MN");
pref("font.name-list.sans-serif.x-khmr", "Khmer Sangam MN");
pref("font.name-list.monospace.x-khmr", "Khmer Sangam MN");
pref("font.name.serif.x-mlym", "Malayalam MN");
pref("font.name.sans-serif.x-mlym", "Malayalam Sangam MN");
pref("font.name.monospace.x-mlym", "Malayalam Sangam MN");
pref("font.name-list.serif.x-mlym", "Malayalam MN");
pref("font.name-list.serif.x-mlym", "Malayalam MN");
pref("font.name-list.sans-serif.x-mlym", "Malayalam Sangam MN");
pref("font.name-list.monospace.x-mlym", "Malayalam Sangam MN");
pref("font.name.serif.x-orya", "Oriya MN");
pref("font.name.sans-serif.x-orya", "Oriya Sangam MN");
pref("font.name.monospace.x-orya", "Oriya Sangam MN");
pref("font.name-list.serif.x-orya", "Oriya MN");
pref("font.name-list.serif.x-orya", "Oriya MN");
pref("font.name-list.sans-serif.x-orya", "Oriya Sangam MN");
pref("font.name-list.monospace.x-orya", "Oriya Sangam MN");
@ -2927,9 +2927,9 @@ pref("font.name-list.serif.zh-CN", "Times,STSong,Heiti SC");
pref("font.name-list.sans-serif.zh-CN", "Helvetica,STHeiti,Heiti SC");
pref("font.name-list.monospace.zh-CN", "Courier,STHeiti,Heiti SC");
pref("font.name.serif.zh-TW", "Times");
pref("font.name.sans-serif.zh-TW", "Helvetica");
pref("font.name.monospace.zh-TW", "Courier");
pref("font.name.serif.zh-TW", "Times");
pref("font.name.sans-serif.zh-TW", "Helvetica");
pref("font.name.monospace.zh-TW", "Courier");
pref("font.name-list.serif.zh-TW", "Times,LiSong Pro,Heiti TC");
pref("font.name-list.sans-serif.zh-TW", "Helvetica,Heiti TC,LiHei Pro");
pref("font.name-list.monospace.zh-TW", "Courier,Heiti TC,LiHei Pro");
@ -3105,7 +3105,7 @@ pref("ui.key.menuAccessKey", 0);
pref("ui.key.accelKey", 224);
// (pinkerton, joki, saari) IE5 for mac uses Control for access keys. The HTML4 spec
// suggests to use command on mac, but this really sucks (imagine someone having a "q"
// as an access key and not letting you quit the app!). As a result, we've made a
// as an access key and not letting you quit the app!). As a result, we've made a
// command decision 1 day before tree lockdown to change it to the control key.
pref("ui.key.generalAccessKey", -1);
@ -3597,7 +3597,7 @@ pref("font.name.serif.zh-CN", "serif");
pref("font.name.sans-serif.zh-CN", "sans-serif");
pref("font.name.monospace.zh-CN", "monospace");
// ming_uni.ttf (HKSCS-2001)
// ming_uni.ttf (HKSCS-2001)
// http://www.info.gov.hk/digital21/eng/hkscs/download/uime.exe
pref("font.name.serif.zh-HK", "serif");
pref("font.name.sans-serif.zh-HK", "sans-serif");
@ -4095,11 +4095,11 @@ pref("device.storage.enabled", false);
// Toggle which thread the HTML5 parser uses for stream parsing
pref("html5.offmainthread", true);
// Time in milliseconds between the time a network buffer is seen and the
// timer firing when the timer hasn't fired previously in this parse in the
// Time in milliseconds between the time a network buffer is seen and the
// timer firing when the timer hasn't fired previously in this parse in the
// off-the-main-thread HTML5 parser.
pref("html5.flushtimer.initialdelay", 120);
// Time in milliseconds between the time a network buffer is seen and the
// Time in milliseconds between the time a network buffer is seen and the
// timer firing when the timer has already fired previously in this parse.
pref("html5.flushtimer.subsequentdelay", 120);