Bug 1213056 - change getStats to be maplike.
MozReview-Commit-ID: 3nkMtbFfGR2
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -272,54 +272,44 @@ function RTCStatsReport(win, dict) {
this._report = convertToRTCStatsReport(dict);
}
RTCStatsReport.prototype = {
classDescription: "RTCStatsReport",
classID: PC_STATS_CID,
contractID: PC_STATS_CONTRACT,
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
- // TODO: Change to use webidl getters once available (Bug 952122)
+ setInternal: function(aKey, aObj) {
+ return this.__DOM_IMPL__.__set(aKey, aObj);
+ },
+
+ // TODO: Remove legacy API eventually
//
- // Since webidl getters are not available, we make the stats available as
+ // Since maplike is recent, we still also make the stats available as legacy
// enumerable read-only properties directly on our content-facing object.
// Must be called after our webidl sandwich is made.
- makeStatsPublic: function() {
- let props = {};
- this.forEach(function(stat) {
- props[stat.id] = { enumerable: true, configurable: false,
- writable: false, value: stat };
- });
- Object.defineProperties(this.__DOM_IMPL__.wrappedJSObject, props);
- },
-
- forEach: function(cb, thisArg) {
- for (var key in this._report) {
- cb.call(thisArg || this._report, this.get(key), key, this._report);
- }
- },
+ makeStatsPublic: function(warnNullable) {
+ let legacyProps = {};
+ for (let key in this._report) {
+ let value = Cu.cloneInto(this._report[key], this._win);
+ this.setInternal(key, value);
- get: function(key) {
- function publifyReadonly(win, obj) {
- let props = {};
- for (let k in obj) {
- props[k] = {enumerable:true, configurable:false, writable:false, value:obj[k]};
- }
- let pubobj = Cu.createObjectIn(win);
- Object.defineProperties(pubobj, props);
- return pubobj;
+ legacyProps[key] = {
+ enumerable: true, configurable: false,
+ get: Cu.exportFunction(function() {
+ if (warnNullable.warn) {
+ warnNullable.warn();
+ warnNullable.warn = null;
+ }
+ return value;
+ }, this.__DOM_IMPL__.wrappedJSObject)
+ };
}
-
- // Return a content object rather than a wrapped chrome one.
- return publifyReadonly(this._win, this._report[key]);
- },
-
- has: function(key) {
- return this._report[key] !== undefined;
+ Object.defineProperties(this.__DOM_IMPL__.wrappedJSObject, legacyProps);
},
get mozPcid() { return this._pcid; }
};
function RTCPeerConnection() {
this._senders = [];
this._receivers = [];
@@ -429,16 +419,21 @@ RTCPeerConnection.prototype = {
this.__DOM_IMPL__._innerObject = this;
this._observer = new this._win.PeerConnectionObserver(this.__DOM_IMPL__);
var location = "" + this._win.location;
this._isLoop = location.startsWith("about:loop") ||
location.startsWith("https://hello.firefox.com/");
+ // Warn just once per PeerConnection about deprecated getStats usage.
+ this._warnDeprecatedStatsAccessNullable = { warn: () =>
+ this.logWarning("non-maplike pc.getStats access is deprecated! " +
+ "See http://w3c.github.io/webrtc-pc/#example for usage.") };
+
// Add a reference to the PeerConnection to global list (before init).
_globalPCList.addPC(this);
this._impl.initialize(this._observer, this._win, rtcConfig,
Services.tm.currentThread);
this._initCertificate(rtcConfig.certificates);
this._initIdp();
_globalPCList.notifyLifecycleObservers(this, "initialized");
@@ -1504,17 +1499,17 @@ PeerConnectionObserver.prototype = {
break;
}
},
onGetStatsSuccess: function(dict) {
let pc = this._dompc;
let chromeobj = new RTCStatsReport(pc._win, dict);
let webidlobj = pc._win.RTCStatsReport._create(pc._win, chromeobj);
- chromeobj.makeStatsPublic();
+ chromeobj.makeStatsPublic(pc._warnDeprecatedStatsAccessNullable);
pc._onGetStatsSuccess(webidlobj);
},
onGetStatsError: function(code, message) {
this._dompc._onGetStatsFailure(this.newError(message, code));
},
onAddStream: function(stream) {
--- a/dom/webidl/RTCStatsReport.webidl
+++ b/dom/webidl/RTCStatsReport.webidl
@@ -141,18 +141,16 @@ dictionary RTCIceCandidateStats : RTCSta
dictionary RTCCodecStats : RTCStats {
unsigned long payloadType; // As used in RTP encoding.
DOMString codec; // video/vp8 or equivalent
unsigned long clockRate;
unsigned long channels; // 2=stereo, missing for most other cases.
DOMString parameters; // From SDP description line
};
-callback RTCStatsReportCallback = void (RTCStatsReport obj);
-
// This is the internal representation of the report in this implementation
// to be received from c++
dictionary RTCStatsReportInternal {
DOMString pcid = "";
sequence<RTCInboundRTPStreamStats> inboundRTPStreamStats;
sequence<RTCOutboundRTPStreamStats> outboundRTPStreamStats;
sequence<RTCMediaStreamTrackStats> mediaStreamTrackStats;
@@ -168,14 +166,12 @@ dictionary RTCStatsReportInternal {
boolean closed; // Is the PC now closed
};
[Pref="media.peerconnection.enabled",
// TODO: Use MapClass here once it's available (Bug 928114)
// MapClass(DOMString, object)
JSImplementation="@mozilla.org/dom/rtcstatsreport;1"]
interface RTCStatsReport {
+ readonly maplike<DOMString, object>;
[ChromeOnly]
readonly attribute DOMString mozPcid;
- void forEach(RTCStatsReportCallback callbackFn, optional any thisArg);
- object get(DOMString key);
- boolean has(DOMString key);
};