browser/modules/webrtcUI.jsm
author Joel Maher <jmaher@mozilla.com>
Mon, 12 Nov 2012 07:56:34 -0500
changeset 112987 e960dece2a232b9a7d0c1f58486b69d93d85b726
parent 111947 5ce71981e005a52d4cb0b831ad3db9284f2fb356
child 116828 06cdd349042e501dee55995944bd28f55f75dfcf
permissions -rw-r--r--
Bug 737961 - add reftest manifest conditions for height width. r=dbaron

/* 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/. */

"use strict";

this.EXPORTED_SYMBOLS = ["webrtcUI"];

const Cu = Components.utils;
const Ci = Components.interfaces;

Cu.import("resource://gre/modules/Services.jsm");

this.webrtcUI = {
  init: function () {
    Services.obs.addObserver(handleRequest, "getUserMedia:request", false);
  },
  uninit: function () {
    Services.obs.removeObserver(handleRequest, "getUserMedia:request");
  }
}

function handleRequest(aSubject, aTopic, aData) {
  let {windowID: windowID, callID: callID} = JSON.parse(aData);

  let someWindow = Services.wm.getMostRecentWindow(null);
  let contentWindow = someWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                                .getInterface(Ci.nsIDOMWindowUtils)
                                .getOuterWindowWithId(windowID);
  let browser = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                             .getInterface(Ci.nsIWebNavigation)
                             .QueryInterface(Ci.nsIDocShell)
                             .chromeEventHandler;

  let params = aSubject.QueryInterface(Ci.nsIMediaStreamOptions);

  browser.ownerDocument.defaultView.navigator.mozGetUserMediaDevices(
    function (devices) {
      prompt(browser, callID, params.audio, params.video, devices);
    },
    function (error) {
      Cu.reportError(error);
    }
  );
}

function prompt(aBrowser, aCallID, aAudioRequested, aVideoRequested, aDevices) {
  let audioDevices = [];
  let videoDevices = [];
  for (let device of aDevices) {
    device = device.QueryInterface(Ci.nsIMediaDevice);
    switch (device.type) {
      case "audio":
        if (aAudioRequested)
          audioDevices.push(device);
        break;
      case "video":
        if (aVideoRequested)
          videoDevices.push(device);
        break;
    }
  }

  let requestType;
  if (audioDevices.length && videoDevices.length)
    requestType = "shareCameraAndMicrophone";
  else if (audioDevices.length)
    requestType = "shareMicrophone";
  else if (videoDevices.length)
    requestType = "shareCamera";
  else
    return;

  let host = aBrowser.contentDocument.documentURIObject.asciiHost;
  let chromeWin = aBrowser.ownerDocument.defaultView;
  let stringBundle = chromeWin.gNavigatorBundle;
  let message = stringBundle.getFormattedString("getUserMedia." + requestType + ".message",
                                                [ host ]);

  let mainAction = {
    label: stringBundle.getString("getUserMedia." + requestType + ".label"),
    accessKey: stringBundle.getString("getUserMedia." + requestType + ".accesskey"),
    callback: function () {
      Services.obs.notifyObservers(null, "getUserMedia:response:allow", aCallID);
    }
  };

  let secondaryActions = [];
  let selectableDevices = videoDevices.length ? videoDevices : audioDevices;
  if (selectableDevices.length > 1) {
    let selectableDeviceNumber = 0;
    for (let device of selectableDevices) {
      // See bug 449811 for why we do this
      let actual_device = device;
      selectableDeviceNumber++;
      secondaryActions.push({
        label: stringBundle.getFormattedString(
                 device.type == "audio" ?
                   "getUserMedia.shareSpecificMicrophone.label" :
                   "getUserMedia.shareSpecificCamera.label",
                 [ device.name ]),
        accessKey: selectableDeviceNumber,
        callback: function () {
          Services.obs.notifyObservers(actual_device, "getUserMedia:response:allow", aCallID);
        }
      });
    }
  }
  secondaryActions.push({
    label: stringBundle.getString("getUserMedia.denyRequest.label"),
    accessKey: stringBundle.getString("getUserMedia.denyRequest.accesskey"),
    callback: function () {
      Services.obs.notifyObservers(null, "getUserMedia:response:deny", aCallID);
    }
  });

  let options = {
  };

  chromeWin.PopupNotifications.show(aBrowser, "webRTC-shareDevices", message,
                                    "webRTC-notification-icon", mainAction,
                                    secondaryActions, options);
}