mobile/android/chrome/content/WebrtcUI.js

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     4 "use strict";
     6 XPCOMUtils.defineLazyModuleGetter(this, "Notifications", "resource://gre/modules/Notifications.jsm");
     8 var WebrtcUI = {
     9   _notificationId: null,
    11   observe: function(aSubject, aTopic, aData) {
    12     if (aTopic === "getUserMedia:request") {
    13       this.handleRequest(aSubject, aTopic, aData);
    14     } else if (aTopic === "recording-device-events") {
    15       switch (aData) {
    16         case "shutdown":
    17         case "starting":
    18           this.notify();
    19           break;
    20       }
    21     }
    22   },
    24   notify: function() {
    25     let windows = MediaManagerService.activeMediaCaptureWindows;
    26     let count = windows.Count();
    27     let msg = {};
    28     if (count == 0) {
    29       if (this._notificationId) {
    30         Notifications.cancel(this._notificationId);
    31         this._notificationId = null;
    32       }
    33     } else {
    34       let notificationOptions = {
    35         title: Strings.brand.GetStringFromName("brandShortName"),
    36         when: null, // hide the date row
    37         light: [0xFF9500FF, 1000, 1000],
    38         ongoing: true
    39       };
    41       let cameraActive = false;
    42       let audioActive = false;
    43       for (let i = 0; i < count; i++) {
    44         let win = windows.GetElementAt(i);
    45         let hasAudio = {};
    46         let hasVideo = {};
    47         MediaManagerService.mediaCaptureWindowState(win, hasVideo, hasAudio);
    48         if (hasVideo.value) cameraActive = true;
    49         if (hasAudio.value) audioActive = true;
    50       }
    52       if (cameraActive && audioActive) {
    53         notificationOptions.message = Strings.browser.GetStringFromName("getUserMedia.sharingCameraAndMicrophone.message2");
    54         notificationOptions.icon = "drawable:alert_mic_camera";
    55       } else if (cameraActive) {
    56         notificationOptions.message = Strings.browser.GetStringFromName("getUserMedia.sharingCamera.message2");
    57         notificationOptions.icon = "drawable:alert_camera";
    58       } else if (audioActive) {
    59         notificationOptions.message = Strings.browser.GetStringFromName("getUserMedia.sharingMicrophone.message2");
    60         notificationOptions.icon = "drawable:alert_mic";
    61       } else {
    62         // somethings wrong. lets throw
    63         throw "Couldn't find any cameras or microphones being used"
    64       }
    66       if (this._notificationId)
    67           Notifications.update(this._notificationId, notificationOptions);
    68       else
    69         this._notificationId = Notifications.create(notificationOptions);
    70       if (count > 1)
    71         msg.count = count;
    72     }
    73   },
    75   handleRequest: function handleRequest(aSubject, aTopic, aData) {
    76     let constraints = aSubject.getConstraints();
    77     let contentWindow = Services.wm.getOuterWindowWithId(aSubject.windowID);
    79     contentWindow.navigator.mozGetUserMediaDevices(
    80       constraints,
    81       function (devices) {
    82         WebrtcUI.prompt(contentWindow, aSubject.callID, constraints.audio,
    83                         constraints.video, devices);
    84       },
    85       function (error) {
    86         Cu.reportError(error);
    87       },
    88       aSubject.innerWindowID);
    89   },
    91   getDeviceButtons: function(audioDevices, videoDevices, aCallID) {
    92     return [{
    93       label: Strings.browser.GetStringFromName("getUserMedia.denyRequest.label"),
    94       callback: function() {
    95         Services.obs.notifyObservers(null, "getUserMedia:response:deny", aCallID);
    96       }
    97     },
    98     {
    99       label: Strings.browser.GetStringFromName("getUserMedia.shareRequest.label"),
   100       callback: function(checked /* ignored */, inputs) {
   101         let allowedDevices = Cc["@mozilla.org/supports-array;1"].createInstance(Ci.nsISupportsArray);
   103         let audioId = 0;
   104         if (inputs && inputs.audioDevice != undefined)
   105           audioId = inputs.audioDevice;
   106         if (audioDevices[audioId])
   107           allowedDevices.AppendElement(audioDevices[audioId]);
   109         let videoId = 0;
   110         if (inputs && inputs.videoDevice != undefined)
   111           videoId = inputs.videoDevice;
   112         if (videoDevices[videoId])
   113           allowedDevices.AppendElement(videoDevices[videoId]);
   115         Services.obs.notifyObservers(allowedDevices, "getUserMedia:response:allow", aCallID);
   116       }
   117     }];
   118   },
   120   // Get a list of string names for devices. Ensures that none of the strings are blank
   121   _getList: function(aDevices, aType) {
   122     let defaultCount = 0;
   123     return aDevices.map(function(device) {
   124         // if this is a Camera input, convert the name to something readable
   125         let res = /Camera\ \d+,\ Facing (front|back)/.exec(device.name);
   126         if (res)
   127           return Strings.browser.GetStringFromName("getUserMedia." + aType + "." + res[1] + "Camera");
   129         if (device.name.startsWith("&") && device.name.endsWith(";"))
   130           return Strings.browser.GetStringFromName(device.name.substring(1, device.name.length -1));
   132         if (device.name.trim() == "") {
   133           defaultCount++;
   134           return Strings.browser.formatStringFromName("getUserMedia." + aType + ".default", [defaultCount], 1);
   135         }
   136         return device.name
   137       }, this);
   138   },
   140   _addDevicesToOptions: function(aDevices, aType, aOptions, extraOptions) {
   141     if (aDevices.length) {
   143       // Filter out empty items from the list
   144       let list = this._getList(aDevices, aType);
   145       if (extraOptions)
   146         list = list.concat(extraOptions);
   148       if (list.length > 0) {
   149         aOptions.inputs.push({
   150           id: aType,
   151           type: "menulist",
   152           label: Strings.browser.GetStringFromName("getUserMedia." + aType + ".prompt"),
   153           values: list
   154         });
   156       }
   157     }
   158   },
   160   prompt: function prompt(aContentWindow, aCallID, aAudioRequested,
   161                           aVideoRequested, aDevices) {
   162     let audioDevices = [];
   163     let videoDevices = [];
   164     for (let device of aDevices) {
   165       device = device.QueryInterface(Ci.nsIMediaDevice);
   166       switch (device.type) {
   167       case "audio":
   168         if (aAudioRequested)
   169           audioDevices.push(device);
   170         break;
   171       case "video":
   172         if (aVideoRequested)
   173           videoDevices.push(device);
   174         break;
   175       }
   176     }
   178     let requestType;
   179     if (audioDevices.length && videoDevices.length)
   180       requestType = "CameraAndMicrophone";
   181     else if (audioDevices.length)
   182       requestType = "Microphone";
   183     else if (videoDevices.length)
   184       requestType = "Camera";
   185     else
   186       return;
   188     let host = aContentWindow.document.documentURIObject.host;
   189     let requestor = BrowserApp.manifest ? "'" + BrowserApp.manifest.name  + "'" : host;
   190     let message = Strings.browser.formatStringFromName("getUserMedia.share" + requestType + ".message", [ requestor ], 1);
   192     let options = { inputs: [] };
   193     // if the users only option would be to select "No Audio" or "No Video"
   194     // i.e. we're only showing audio or only video and there is only one device for that type
   195     // don't bother showing a menulist to select from
   196     var extraItems = null;
   197     if (videoDevices.length > 1 || audioDevices.length > 0) {
   198       // Only show the No Video option if there are also Audio devices to choose from
   199       if (audioDevices.length > 0)
   200         extraItems = [ Strings.browser.GetStringFromName("getUserMedia.videoDevice.none") ];
   201       this._addDevicesToOptions(videoDevices, "videoDevice", options, extraItems);
   202     }
   204     if (audioDevices.length > 1 || videoDevices.length > 0) {
   205       // Only show the No Audio option if there are also Video devices to choose from
   206       if (videoDevices.length > 0)
   207         extraItems = [ Strings.browser.GetStringFromName("getUserMedia.audioDevice.none") ];
   208       this._addDevicesToOptions(audioDevices, "audioDevice", options, extraItems);
   209     }
   211     let buttons = this.getDeviceButtons(audioDevices, videoDevices, aCallID);
   213     NativeWindow.doorhanger.show(message, "webrtc-request", buttons, BrowserApp.selectedTab.id, options);
   214   }
   215 }

mercurial