WebAPI/WebMMS

From MozillaWiki
Jump to: navigation, search

Overview

On the surface, MMS messages are very similar to multipart HTML emails. One part is responsible for the layout of the message, though MMS uses SMIL rather than HTML. The other parts are attachments, such as text, picture, video, and sound files. Much like in multipart emails, the attachments have "file names" and are referred to by those from the presentation part.

The API proposal below tries to reuse as many existing Web technologies as applicable. The SMIL document is exposed as a DOM document and the attachments as Blob objects. On a User Agent capable of rendering SMIL, the web application may simply render the DOM right away. On other User Agents, it may use XSLT or some other method to convert SMIL to HTML.

To read the attachments, the web application may use the FileReader API. However, it's not that useful or efficient to have image/audio/video data in memory (e.g. as a typed array). For display purposes the web application just needs a URI that resolves to the data, so that it can point to it in a <video>, <audio>, <img> element. This is possible with the window.URL API.

API

MmsManager

 /**
  * TODO should we merge with this with SmsManager? There are good reasons for and against it.
  * Pro: One API to rule them all, less API clutter, easier to write integrated SMS/MMS app
  *      (which is what everybody wants anyway) 
  * Con: MMS is vastly more complex than SMS, both in terms of API as in terms of implementation
  *      and storing; implementations need to be acutely aware of MMS and how to deal with them.
  */
 interface MmsManager
 {
   DOMRequest   send(MmsMessage message);
   DOMRequest[] send(MmsMessage message[]);
   DOMRequest   delete(long id);
   DOMRequest   delete(MmsMessage message);
   DOMRequest   getMessage(long id);
   DOMRequest   getMessages(SMSFilter filter, bool reverse);
   
   /**
    * Fetch a message's data. Only applicable if message.delivery == "unfetched"
    */
   DOMRequest   fetchMessage(MmsMessage message);
   
   /**
    * Forward a message to a different number.
    */
   DOMRequest   forwardMessage(MmsMessage message, recipient);
   
   /**
    * Cancel a message's delivery with the MMSC.
    */
   DOMRequest   cancelMessage(MmsMessage message);
 }

MmsMessage

 /**
  * MmsMessage constructor.
  */
 MmsMessage MmsMessage(
   DOMString receiver,
   Document document
 );
 
 [Constructor]
 interface MmsMessage
 {
   /**
    * Cf. SmsMessage
    */
   readonly attribute long                 id;
   
   /**
    * Like SmsMessage::delivery, but with an additional possible value: "unfetched"
    */
   readonly attribute DOMString            delivery;
   
   /**
    * Cf. SmsMessage
    */
   readonly attribute DOMString            sender;
   
   /**
    * TODO Should this be plural? (AFAIK MMS supports group messaging.)
    */
   readonly attribute DOMString            receiver;
   
   /**
    * Cf. SmsMessage
    */
   readonly attribute Date                 timestamp;
   
   /**
    * DOM document object representing the SMIL document.
    */
   readonly attribute Document             contentDocument;
   
   /**
    * Object containing all other parts.
    */
   readonly attribute MmsAttachmentStorage attachments;     
 }

MmsAttachmentStorage

 /**
  * This object implements a mapping to look up attachments (blobs) by their name.
  *
  *   var text = message.attachments["text.txt"];
  *   message.attachments["movie.mov"] = new Blob([data], {type: "application/video"});
  *   delete message.attachments["picture.png"];
  */
 interface MmsAttachmentStorage
 {
   getter Blob getAttachment(DOMString name);
   setter creator void setAttachment(DOMString name, Blob attachment);
   deleter void deleteAttachment(DOMString name);
 }

Examples

Receiving an MMS

 // Listen for incoming MMS. If the message contents hasn't been fetched yet, do so.
 navigator.mms.onreceived = function (event) {
   var message = event.message;
   if (message.delivery == "unfetched") {
     message.fetch().onsuccess(function (event) {
       handleNewMessage(event.target.result);
     });
   } else {
     handleNewMessage(message);
   }
 }
 
 // Deconstruct and display an MMS. For simplicity's sake, this only supports one
 // slide and one multimedia element per slide.
 function handleNewMessage(message) {
   var firstPar = message.contentDocument.querySelectorAll("par")[0];
   var mediaEl = firstPar.querySelectorAll("img|audio|video")[0];
   var importedEl = document.importNode(mediaEl);
   var mediaUrl = window.URL.createObjectURL(message.attachments[importedEl.src]);
   importedEl.src = mediaUrl;
   messageDisplayContainer.appendChild(importedEl);
   window.URL.revokeObjectURL(mediaUrl);
 }

Sending an MMS

 <html>
 <body>
   <input type="file" id="picture" accept="image/*">
   <div>
     <input type="text" id="number">
     <button onclick="sendMMS();">Send</button>
   </div>
   <script>
     function sendMMS() {
       var smil = "<smil><body><par><video src="lolcat.mov"/></par></body></smil>";
       var doc = (new DOMParser()).parseFromString(smil, "application/smil");
       var number = document.getElementById("number").value;
       var message = new MmsMessage(number, doc);
       
       var pictureEl = document.getElementById("picture");
       var pictureBlob = pictureEl.files[0];
       message.attachments["picture.jpg"] = pictureBlob;
       
       navigator.mms.send(message);
     }
   </script>
 </body>
 </html>