- From: Jan-Ivar Bruaroey <jib@mozilla.com>
- Date: Mon, 13 May 2013 21:40:04 -0400
- To: public-webrtc@w3.org
I took some notes while moving our http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCPeerConnection implementation to our latest webidl compiler. Here are nine points I wanted to share. My apologies if any of these are repeats. --- #1 - Proposal: I propose we make iceServers a sequence rather than a webidl array, because sequence is passed by value (represented in JS by an actual JS array), and [] is passed by reference (represented in JS by some weird array-like object, according to our webidl guy): - RTCIceServer[] iceServers; + sequence<RTCIceServer> iceServers; #2 - Proposal: Wherever EventInit is mentioned (like in MediaStreamEvent) it would be nice if the draft linked to http://dom.spec.whatwg.org/#eventinit instead of trying to re-describe what essentially is already the default inherited behavior for bubbles and cancelable. Unless I misunderstand, we want the implementer to add and subtract nothing to how bubbles and cancelable are dealt with by default here. I propose the best way to get this across is not to mention it at all. dictionary EventInit { boolean bubbles = false; boolean cancelable = false; }; #3 - Observation: In the draft, addStream talks about a failure callback it doesn't have. It says: "... If the constraints could not be successfully applied, provide an RTCError object of type INCOMPATIBLE_CONSTRAINTS to the failure callback.”. It seems to me that we either must do constraint parsing synchronously (and throw on errors) or addStream needs success/failure callbacks here. #4 - Proposal: Similarly, addIceCandidate needs a failure callback to handle bad passed-in SDP, which can happen in the field, and callers need a success callback to learn that the SDP did not fail. I'm assuming we've decided we can't parse SDP synchronously, so I propose we add: void addIceCandidate (mozRTCIceCandidate candidate, + optional VoidFunction successCallback, + optional RTCPeerConnectionErrorCallback failureCallback); #5 - Not a spec bug, but apprtc currently passes in null failureCallbacks to createOffer/Answer. Can someone with commit access bring it in line with spec, so we can remove workarounds? void createOffer (RTCSessionDescriptionCallback successCallback, RTCPeerConnectionErrorCallback? failureCallback, // for apprtc optional object? constraints); void createAnswer (RTCSessionDescriptionCallback successCallback, RTCPeerConnectionErrorCallback? failureCallback, // for apprtc optional object? constraints); #6 - Proposal: I notice local/remoteDescription are not marked as nullable ('?') even though "A null object will be returned if the local/remote description has not yet been set." I think the wording makes sense and the webidl is wrong, so I propose this "null means unset" change: - readonly attribute RTCSessionDescription localDescription; - readonly attribute RTCSessionDescription remoteDescription; + readonly attribute RTCSessionDescription? localDescription; + readonly attribute RTCSessionDescription? remoteDescription; #7 - In light of #6 ("null means unset"), allowing independently nullable type and sdp seems superfluous, so I was about to propose we make type and sdp non-nullable, as I assumed having people pass in null is undesirable. However, I then noticed that the constructor-init-dictionary itself is optional, and wonder what purpose does that serve? Seems like an undesirable variant. I wanted to propose: -[Constructor (optional RTCSessionDescriptionInit descriptionInitDict)] +[Constructor (RTCSessionDescriptionInit descriptionInitDict)] interface RTCSessionDescription { - attribute RTCSdpType? type; - attribute DOMString? sdp; + attribute RTCSdpType type; + attribute DOMString sdp; and have it throw if type is not specified (see next point). #8 - It is hard to describe invariants with *Init dictionaries as constructor args, since dictionary keys are inherently optional. In other words, it is not clear from the webidl alone which constructor-init-dictionary-keys are required to avoid throwing and which are not. For example: dictionary RTCPeerConnectionIceEventInit : EventInit { RTCIceCandidate candidate; }; [Constructor(DOMString type, RTCPeerConnectionIceEventInit eventInitDict)] interface RTCPeerConnectionIceEvent : Event { readonly attribute RTCIceCandidate candidate; }; Should new RTCPeerConnectionIceEventInit("icecandidate", { }); throw? - If it should, there is nothing that states so (meaning: webidl wrappers wont throw for us), and we should document the need to throw. - If it shouldn't, then what should the value of the candidate attribute be after creation? Null is not valid here, so maybe undefined or maybe an empty RTCIceCandidate object (which can be created from zero arguments)? There is no way to know. #9 Proposal: For the latter case in #8 (optional constructor-init-dictionary-keys), once answers are found, I propose a convention where we specify default values in the dictionary whenever possible. This is descriptive, as readers learn both that the argument is optional and what value they'll get when omitting the key; The implementation benefits as well by gaining an invariant (see below); and we benefit by being forced to consider what the default value should be. For example: webidl: dictionary RTCIceCandidateInit { - DOMString candidate; - DOMString sdpMid; + DOMString? candidate = null; + DOMString? sdpMid = null; unsigned short sdpMLineIndex; }; [Constructor (optional RTCIceCandidateInit candidateInitDict)] interface RTCIceCandidate { attribute DOMString? candidate; attribute DOMString? sdpMid; attribute unsigned short? sdpMLineIndex; Implementation effect: RTCIceCandidate: function(dict) { - this.candidate = ("candidate" in dict)? dict.candidate : null; - this.sdpMid = ("sdpMid" in dict)? dict.sdpMid : null; + this.candidate = dict.candidate; + this.sdpMid = dict.sdpMid; this.sdpMLineIndex = ("sdpMLineIndex" in dict)? dict.sdpMLineIndex+1 : null; } In general, such default values should be addable without making keys nullable where they weren't before (defaults can be any constant value). However, in this particular case, with the attributes themselves being defined as nullable already (why?), my best guess (since it is not specified) is that the intent here is that they also default to null, in which case a caller can already null them implicitly by omitting the corresponding keys, so this doesn't really expand the complexity even though it may appear to. That's what I have. Thoughts? .: Jan-Ivar :.
Received on Tuesday, 14 May 2013 01:40:33 UTC