diff options
Diffstat (limited to 'mobile/android/modules/geckoview/GeckoViewMedia.jsm')
-rw-r--r-- | mobile/android/modules/geckoview/GeckoViewMedia.jsm | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/mobile/android/modules/geckoview/GeckoViewMedia.jsm b/mobile/android/modules/geckoview/GeckoViewMedia.jsm new file mode 100644 index 0000000000..26a95a9d50 --- /dev/null +++ b/mobile/android/modules/geckoview/GeckoViewMedia.jsm @@ -0,0 +1,131 @@ +/* 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"; + +var EXPORTED_SYMBOLS = ["GeckoViewMedia", "GeckoViewRecordingMedia"]; + +const { GeckoViewModule } = ChromeUtils.import( + "resource://gre/modules/GeckoViewModule.jsm" +); +const { GeckoViewUtils } = ChromeUtils.import( + "resource://gre/modules/GeckoViewUtils.jsm" +); +const { XPCOMUtils } = ChromeUtils.import( + "resource://gre/modules/XPCOMUtils.jsm" +); + +XPCOMUtils.defineLazyModuleGetters(this, { + GeckoViewUtils: "resource://gre/modules/GeckoViewUtils.jsm", +}); + +XPCOMUtils.defineLazyServiceGetter( + this, + "MediaManagerService", + "@mozilla.org/mediaManagerService;1", + "nsIMediaManagerService" +); + +const STATUS_RECORDING = "recording"; +const STATUS_INACTIVE = "inactive"; +const TYPE_CAMERA = "camera"; +const TYPE_MICROPHONE = "microphone"; + +class GeckoViewMedia extends GeckoViewModule { + onEnable() { + this.registerListener([ + "GeckoView:MediaObserve", + "GeckoView:MediaUnobserve", + "GeckoView:MediaPlay", + "GeckoView:MediaPause", + "GeckoView:MediaSeek", + "GeckoView:MediaSetVolume", + "GeckoView:MediaSetMuted", + "GeckoView:MediaSetPlaybackRate", + ]); + } + + onDisable() { + this.unregisterListener(); + } + + onEvent(aEvent, aData, aCallback) { + debug`onEvent: event=${aEvent}, data=${aData}`; + this.messageManager.sendAsyncMessage(aEvent, aData); + } +} + +const GeckoViewRecordingMedia = { + // The event listener for this is hooked up in GeckoViewStartup.jsm + observe(aSubject, aTopic, aData) { + debug`observe: aTopic=${aTopic}`; + switch (aTopic) { + case "recording-device-events": { + this.handleRecordingDeviceEvents(); + break; + } + } + }, + + handleRecordingDeviceEvents() { + const [dispatcher] = GeckoViewUtils.getActiveDispatcherAndWindow(); + if (dispatcher) { + const windows = MediaManagerService.activeMediaCaptureWindows; + const devices = []; + + const getStatusString = function(activityStatus) { + switch (activityStatus) { + case MediaManagerService.STATE_CAPTURE_ENABLED: + case MediaManagerService.STATE_CAPTURE_DISABLED: + return STATUS_RECORDING; + case MediaManagerService.STATE_NOCAPTURE: + return STATUS_INACTIVE; + default: + throw new Error("Unexpected activityStatus value"); + } + }; + + for (let i = 0; i < windows.length; i++) { + const win = windows.queryElementAt(i, Ci.nsIDOMWindow); + const hasCamera = {}; + const hasMicrophone = {}; + const screen = {}; + const window = {}; + const browser = {}; + const mediaDevices = {}; + MediaManagerService.mediaCaptureWindowState( + win, + hasCamera, + hasMicrophone, + screen, + window, + browser, + mediaDevices + ); + var cameraStatus = getStatusString(hasCamera.value); + var microphoneStatus = getStatusString(hasMicrophone.value); + if (hasCamera.value != MediaManagerService.STATE_NOCAPTURE) { + devices.push({ + type: TYPE_CAMERA, + status: cameraStatus, + }); + } + if (hasMicrophone.value != MediaManagerService.STATE_NOCAPTURE) { + devices.push({ + type: TYPE_MICROPHONE, + status: microphoneStatus, + }); + } + } + dispatcher.sendRequestForResult({ + type: "GeckoView:MediaRecordingStatusChanged", + devices, + }); + } else { + console.log("no dispatcher present"); + } + }, +}; + +const { debug, warn } = GeckoViewMedia.initLogging("GeckoViewMedia"); |