Selaa lähdekoodia

Implements screen sharing for firefox, using a jidesha extension.

Renames some fields in config.js.
master
Boris Grozev 9 vuotta sitten
vanhempi
commit
995b3be6e7

+ 25
- 4
config.js Näytä tiedosto

17
     clientNode: 'http://jitsi.org/jitsimeet', // The name of client node advertised in XEP-0115 'c' stanza
17
     clientNode: 'http://jitsi.org/jitsimeet', // The name of client node advertised in XEP-0115 'c' stanza
18
     //focusUserJid: 'focus@auth.jitsi-meet.example.com', // The real JID of focus participant - can be overridden here
18
     //focusUserJid: 'focus@auth.jitsi-meet.example.com', // The real JID of focus participant - can be overridden here
19
     //defaultSipNumber: '', // Default SIP number
19
     //defaultSipNumber: '', // Default SIP number
20
-    desktopSharing: 'ext', // Desktop sharing method. Can be set to 'ext', 'webrtc' or false to disable.
21
-    chromeExtensionId: 'diibjkoicjeejcmhdnailmkgecihlobk', // Id of desktop streamer Chrome extension
22
-    desktopSharingSources: ['screen', 'window'],
23
-    minChromeExtVersion: '0.1', // Required version of Chrome extension
20
+
21
+    // Desktop sharing method. Can be set to 'ext', 'webrtc' or false to disable.
22
+    desktopSharingChromeMethod: 'ext',
23
+    // The ID of the jidesha extension for Chrome.
24
+    desktopSharingChromeExtId: 'diibjkoicjeejcmhdnailmkgecihlobk',
25
+    // The media sources to use when using screen sharing with the Chrome
26
+    // extension.
27
+    desktopSharingChromeSources: ['screen', 'window'],
28
+    // Required version of Chrome extension
29
+    desktopSharingChromeMinExtVersion: '0.1',
30
+
31
+    // The ID of the jidesha extension for Firefox. If null, we assume that no
32
+    // extension is required.
33
+    desktopSharingFirefoxExtId: null,
34
+    // Whether desktop sharing should be disabled on Firefox.
35
+    desktopSharingFirefoxDisabled: true,
36
+    // The maximum version of Firefox which requires a jidesha extension.
37
+    // Example: if set to 41, we will require the extension for Firefox versions
38
+    // up to and including 41. On Firefox 42 and higher, we will run without the
39
+    // extension.
40
+    // If set to -1, an extension will be required for all versions of Firefox.
41
+    desktopSharingFirefoxMaxVersionExtRequired: -1,
42
+    // The URL to the Firefox extension for desktop sharing.
43
+    desktopSharingFirefoxExtensionURL: null,
44
+
24
     openSctp: true, // Toggle to enable/disable SCTP channels
45
     openSctp: true, // Toggle to enable/disable SCTP channels
25
     disableStats: false,
46
     disableStats: false,
26
     disableAudioLevels: false,
47
     disableAudioLevels: false,

+ 3
- 3
index.html Näytä tiedosto

11
     <meta itemprop="image" content="/images/jitsilogo.png"/>
11
     <meta itemprop="image" content="/images/jitsilogo.png"/>
12
     <script src="https://api.callstats.io/static/callstats.min.js"></script>
12
     <script src="https://api.callstats.io/static/callstats.min.js"></script>
13
     <script src="libs/jquery-2.1.1.min.js"></script>
13
     <script src="libs/jquery-2.1.1.min.js"></script>
14
-    <script src="config.js?v=12"></script><!-- adapt to your needs, i.e. set hosts and bosh path -->
14
+    <script src="config.js?v=13"></script><!-- adapt to your needs, i.e. set hosts and bosh path -->
15
     <script src="libs/strophe/strophe.min.js?v=2"></script>
15
     <script src="libs/strophe/strophe.min.js?v=2"></script>
16
     <script src="libs/strophe/strophe.disco.min.js?v=1"></script>
16
     <script src="libs/strophe/strophe.disco.min.js?v=1"></script>
17
     <script src="libs/strophe/strophe.caps.jsonly.min.js?v=1"></script>
17
     <script src="libs/strophe/strophe.caps.jsonly.min.js?v=1"></script>
20
     <script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
20
     <script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
21
     <script src="libs/toastr.js?v=1"></script><!-- notifications lib -->
21
     <script src="libs/toastr.js?v=1"></script><!-- notifications lib -->
22
     <script src="interface_config.js?v=5"></script>
22
     <script src="interface_config.js?v=5"></script>
23
-    <script src="libs/app.bundle.js?v=134"></script>
23
+    <script src="libs/app.bundle.js?v=131"></script>
24
     <script src="analytics.js?v=1"></script><!-- google analytics plugin -->
24
     <script src="analytics.js?v=1"></script><!-- google analytics plugin -->
25
     <link rel="stylesheet" href="css/font.css?v=7"/>
25
     <link rel="stylesheet" href="css/font.css?v=7"/>
26
     <link rel="stylesheet" href="css/toastr.css?v=1">
26
     <link rel="stylesheet" href="css/toastr.css?v=1">
27
     <link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=31"/>
27
     <link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=31"/>
28
-    <link rel="stylesheet" type="text/css" media="screen" href="css/videolayout_default.css?v=21" id="videolayout_default"/>
28
+    <link rel="stylesheet" type="text/css" media="screen" href="css/videolayout_default.css?v=20" id="videolayout_default"/>
29
     <link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
29
     <link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
30
     <link rel="stylesheet" href="css/jquery-impromptu.css?v=4">
30
     <link rel="stylesheet" href="css/jquery-impromptu.css?v=4">
31
     <link rel="stylesheet" href="css/modaldialog.css?v=3">
31
     <link rel="stylesheet" href="css/modaldialog.css?v=3">

+ 3
- 1
lang/main.json Näytä tiedosto

194
         "password": "password",
194
         "password": "password",
195
         "userPassword": "user password",
195
         "userPassword": "user password",
196
         "token": "token",
196
         "token": "token",
197
-        "displayNameRequired": "Please enter your display name:"
197
+        "displayNameRequired": "Please enter your display name:",
198
+        "extensionRequired": "Extension required:",
199
+        "firefoxExtensionPrompt": "You need to install a Firefox extension in order to use screen sharing. Please try again after you <a href='__url__'>get it from here</a>!"
198
     },
200
     },
199
     "email":
201
     "email":
200
     {
202
     {

+ 10
- 0
modules/UI/UI.js Näytä tiedosto

199
     APP.desktopsharing.addListener(
199
     APP.desktopsharing.addListener(
200
         DesktopSharingEventTypes.SWITCHING_DONE,
200
         DesktopSharingEventTypes.SWITCHING_DONE,
201
         Toolbar.changeDesktopSharingButtonState);
201
         Toolbar.changeDesktopSharingButtonState);
202
+    APP.desktopsharing.addListener(
203
+        DesktopSharingEventTypes.FIREFOX_EXTENSION_NEEDED,
204
+        function (url) {
205
+            APP.UI.messageHandler.openMessageDialog(
206
+                "dialog.extensionRequired",
207
+                null,
208
+                null,
209
+                APP.translation.generateTranslationHTML(
210
+                    "dialog.firefoxExtensionPrompt", {url: url}));
211
+        });
202
     APP.connectionquality.addListener(CQEvents.LOCALSTATS_UPDATED,
212
     APP.connectionquality.addListener(CQEvents.LOCALSTATS_UPDATED,
203
         VideoLayout.updateLocalConnectionStats);
213
         VideoLayout.updateLocalConnectionStats);
204
     APP.connectionquality.addListener(CQEvents.REMOTESTATS_UPDATED,
214
     APP.connectionquality.addListener(CQEvents.REMOTESTATS_UPDATED,

+ 14
- 6
modules/UI/util/MessageHandler.js Näytä tiedosto

11
     /**
11
     /**
12
      * Shows a message to the user.
12
      * Shows a message to the user.
13
      *
13
      *
14
-     * @param titleKey the title of the message
15
-     * @param messageKey the text of the message
14
+     * @param titleKey the key used to find the translation of the title of the
15
+     * message, if a message title is not provided.
16
+     * @param messageKey the key used to find the translation of the message,
17
+     * if a message is not provided.
18
+     * @param title the title of the message. If a falsy value is provided,
19
+     * titleKey will be used to get a title via the translation API.
20
+     * @param message the message to show. If a falsy value is provided,
21
+     * messageKey will be used to get a message via the translation API.
16
      */
22
      */
17
-    my.openMessageDialog = function(titleKey, messageKey) {
18
-        var title = null;
19
-        if(titleKey) {
23
+    my.openMessageDialog = function(titleKey, messageKey, title, message) {
24
+        if (!title) {
20
             title = APP.translation.generateTranslationHTML(titleKey);
25
             title = APP.translation.generateTranslationHTML(titleKey);
21
         }
26
         }
22
-        var message = APP.translation.generateTranslationHTML(messageKey);
27
+        if (!message) {
28
+            message = APP.translation.generateTranslationHTML(messageKey);
29
+        }
30
+
23
         $.prompt(message,
31
         $.prompt(message,
24
             {title: title, persistent: false}
32
             {title: title, persistent: false}
25
         );
33
         );

+ 156
- 15
modules/desktopsharing/ScreenObtainer.js Näytä tiedosto

2
 /* jshint -W003 */
2
 /* jshint -W003 */
3
 var RTCBrowserType = require("../RTC/RTCBrowserType");
3
 var RTCBrowserType = require("../RTC/RTCBrowserType");
4
 var AdapterJS = require("../RTC/adapter.screenshare");
4
 var AdapterJS = require("../RTC/adapter.screenshare");
5
+var DesktopSharingEventTypes
6
+    = require("../../service/desktopsharing/DesktopSharingEventTypes");
5
 
7
 
6
 /**
8
 /**
7
  * Indicates whether the Chrome desktop sharing extension is installed.
9
  * Indicates whether the Chrome desktop sharing extension is installed.
8
  * @type {boolean}
10
  * @type {boolean}
9
  */
11
  */
10
 var chromeExtInstalled = false;
12
 var chromeExtInstalled = false;
13
+
11
 /**
14
 /**
12
  * Indicates whether an update of the Chrome desktop sharing extension is
15
  * Indicates whether an update of the Chrome desktop sharing extension is
13
  * required.
16
  * required.
15
  */
18
  */
16
 var chromeExtUpdateRequired = false;
19
 var chromeExtUpdateRequired = false;
17
 
20
 
21
+/**
22
+ * Whether the jidesha extension for firefox is installed for the domain on
23
+ * which we are running. Null designates an unknown value.
24
+ * @type {null}
25
+ */
26
+var firefoxExtInstalled = null;
27
+
28
+/**
29
+ * If set to true, detection of an installed firefox extension will be started
30
+ * again the next time obtainScreenOnFirefox is called (e.g. next time the
31
+ * user tries to enable screen sharing).
32
+ */
33
+var reDetectFirefoxExtension = false;
34
+
18
 /**
35
 /**
19
  * Handles obtaining a stream from a screen capture on different browsers.
36
  * Handles obtaining a stream from a screen capture on different browsers.
20
  */
37
  */
21
 function ScreenObtainer(){
38
 function ScreenObtainer(){
22
 }
39
 }
23
 
40
 
41
+/**
42
+ * The EventEmitter to use to emit events.
43
+ * @type {null}
44
+ */
45
+ScreenObtainer.prototype.eventEmitter = null;
46
+
24
 /**
47
 /**
25
  * Initializes the function used to obtain a screen capture (this.obtainStream).
48
  * Initializes the function used to obtain a screen capture (this.obtainStream).
26
  *
49
  *
27
- * If the browser is Chrome, it uses the value of 'config.desktopSharing' to
28
- * decide whether to use the a Chrome extension (if the value is 'ext'), use
29
- * the "screen" media source (if the value is 'webrtc'), or disable screen
30
- * capture (if the value is other).
50
+ * If the browser is Chrome, it uses the value of
51
+ * 'config.desktopSharingChromeMethod' (or 'config.desktopSharing') to * decide
52
+ * whether to use the a Chrome extension (if the value is 'ext'), use the
53
+ * "screen" media source (if the value is 'webrtc'), or disable screen capture
54
+ * (if the value is other).
31
  * Note that for the "screen" media source to work the
55
  * Note that for the "screen" media source to work the
32
  * 'chrome://flags/#enable-usermedia-screen-capture' flag must be set.
56
  * 'chrome://flags/#enable-usermedia-screen-capture' flag must be set.
33
  */
57
  */
34
-ScreenObtainer.prototype.init = function() {
58
+ScreenObtainer.prototype.init = function(eventEmitter) {
59
+    this.eventEmitter = eventEmitter;
35
     var obtainDesktopStream = null;
60
     var obtainDesktopStream = null;
36
 
61
 
37
-    // When TemasysWebRTC plugin is used we always use getUserMedia, so we don't
38
-    // care about the value of config.desktopSharing.
62
+    if (RTCBrowserType.isFirefox())
63
+        initFirefoxExtensionDetection();
64
+
65
+    // TODO remove this, config.desktopSharing is deprecated.
66
+    var chromeMethod =
67
+        (config.desktopSharingChromeMethod || config.desktopSharing);
68
+
39
     if (RTCBrowserType.isTemasysPluginUsed()) {
69
     if (RTCBrowserType.isTemasysPluginUsed()) {
40
         if (!AdapterJS.WebRTCPlugin.plugin.HasScreensharingFeature) {
70
         if (!AdapterJS.WebRTCPlugin.plugin.HasScreensharingFeature) {
41
             console.info("Screensharing not supported by this plugin version");
71
             console.info("Screensharing not supported by this plugin version");
47
             console.info("Using Temasys plugin for desktop sharing");
77
             console.info("Using Temasys plugin for desktop sharing");
48
         }
78
         }
49
     } else if (RTCBrowserType.isChrome()) {
79
     } else if (RTCBrowserType.isChrome()) {
50
-        if (config.desktopSharing == "ext") {
80
+        if (chromeMethod == "ext") {
51
             if (RTCBrowserType.getChromeVersion() >= 34) {
81
             if (RTCBrowserType.getChromeVersion() >= 34) {
52
                 obtainDesktopStream = obtainScreenFromExtension;
82
                 obtainDesktopStream = obtainScreenFromExtension;
53
                 console.info("Using Chrome extension for desktop sharing");
83
                 console.info("Using Chrome extension for desktop sharing");
55
             } else {
85
             } else {
56
                 console.info("Chrome extension not supported until ver 34");
86
                 console.info("Chrome extension not supported until ver 34");
57
             }
87
             }
58
-        } else if (config.desktopSharing == "webrtc") {
88
+        } else if (chromeMethod == "webrtc") {
59
             obtainDesktopStream = obtainWebRTCScreen;
89
             obtainDesktopStream = obtainWebRTCScreen;
60
             console.info("Using Chrome WebRTC for desktop sharing");
90
             console.info("Using Chrome WebRTC for desktop sharing");
61
         }
91
         }
62
     } else if (RTCBrowserType.isFirefox()) {
92
     } else if (RTCBrowserType.isFirefox()) {
63
-        obtainDesktopStream = obtainWebRTCScreen;
93
+        if (config.desktopSharingFirefoxDisabled) {
94
+            obtainDesktopStream = null;
95
+        } else if (window.location.protocol === "http:"){
96
+            console.log("Screen sharing is not supported over HTTP. Use of " +
97
+                "HTTPS is required.");
98
+            obtainDesktopStream = null;
99
+        } else {
100
+            obtainDesktopStream = this.obtainScreenOnFirefox;
101
+        }
102
+
64
     }
103
     }
65
 
104
 
66
     if (!obtainDesktopStream) {
105
     if (!obtainDesktopStream) {
67
         console.info("Desktop sharing disabled");
106
         console.info("Desktop sharing disabled");
68
     }
107
     }
69
 
108
 
70
-    ScreenObtainer.prototype.obtainStream = obtainDesktopStream.bind(this);
109
+    ScreenObtainer.prototype.obtainStream = obtainDesktopStream;
71
 };
110
 };
72
 
111
 
73
 ScreenObtainer.prototype.obtainStream = null;
112
 ScreenObtainer.prototype.obtainStream = null;
105
  */
144
  */
106
 function getWebStoreInstallUrl()
145
 function getWebStoreInstallUrl()
107
 {
146
 {
147
+    //TODO remove chromeExtensionId (deprecated)
108
     return "https://chrome.google.com/webstore/detail/" +
148
     return "https://chrome.google.com/webstore/detail/" +
109
-        config.chromeExtensionId;
149
+        (config.desktopSharingChromeExtId || config.chromeExtensionId);
110
 }
150
 }
111
 
151
 
112
 /**
152
 /**
156
         return;
196
         return;
157
     }
197
     }
158
     chrome.runtime.sendMessage(
198
     chrome.runtime.sendMessage(
159
-        config.chromeExtensionId,
199
+        //TODO: remove chromeExtensionId (deprecated)
200
+        (config.desktopSharingChromeExtId || config.chromeExtensionId),
160
         { getVersion: true },
201
         { getVersion: true },
161
         function (response) {
202
         function (response) {
162
             if (!response || !response.version) {
203
             if (!response || !response.version) {
169
             // Check installed extension version
210
             // Check installed extension version
170
             var extVersion = response.version;
211
             var extVersion = response.version;
171
             console.log('Extension version is: ' + extVersion);
212
             console.log('Extension version is: ' + extVersion);
213
+            //TODO: remove minChromeExtVersion (deprecated)
172
             var updateRequired
214
             var updateRequired
173
-                = isUpdateRequired(config.minChromeExtVersion, extVersion);
215
+                = isUpdateRequired(
216
+                    (config.desktopSharingChromeMinExtVersion ||
217
+                        config.minChromeExtVersion),
218
+                    extVersion);
174
             callback(!updateRequired, updateRequired);
219
             callback(!updateRequired, updateRequired);
175
         }
220
         }
176
     );
221
     );
181
     // Extension id must be defined in the config.
226
     // Extension id must be defined in the config.
182
     chrome.runtime.sendMessage(
227
     chrome.runtime.sendMessage(
183
         config.chromeExtensionId,
228
         config.chromeExtensionId,
184
-        { getStream: true, sources: config.desktopSharingSources },
229
+        {
230
+            getStream: true,
231
+            //TODO: remove desktopSharingSources (deprecated).
232
+            sources: (config.desktopSharingChromeSources ||
233
+                config.desktopSharingSources)
234
+        },
185
         function (response) {
235
         function (response) {
186
             if (!response) {
236
             if (!response) {
187
                 failCallback(chrome.runtime.lastError);
237
                 failCallback(chrome.runtime.lastError);
261
     });
311
     });
262
 }
312
 }
263
 
313
 
314
+/**
315
+ * Obtains a screen capture stream on Firefox.
316
+ * @param callback
317
+ * @param errorCallback
318
+ */
319
+ScreenObtainer.prototype.obtainScreenOnFirefox =
320
+       function (callback, errorCallback) {
321
+    var self = this;
322
+    var extensionRequired = false;
323
+    if (config.desktopSharingFirefoxMaxVersionExtRequired === -1 ||
324
+        (config.desktopSharingFirefoxMaxVersionExtRequired >= 0 &&
325
+            RTCBrowserType.getFirefoxVersion() <=
326
+                config.desktopSharingFirefoxMaxVersionExtRequired)) {
327
+        extensionRequired = true;
328
+        console.log("Jidesha extension required on firefox version " +
329
+            RTCBrowserType.getFirefoxVersion());
330
+    }
331
+
332
+    if (!extensionRequired || firefoxExtInstalled === true) {
333
+        obtainWebRTCScreen(callback, errorCallback);
334
+        return;
335
+    }
336
+
337
+    if (reDetectFirefoxExtension) {
338
+        reDetectFirefoxExtension = false;
339
+        initFirefoxExtensionDetection();
340
+    }
341
+
342
+    // Give it some (more) time to initialize, and assume lack of extension if
343
+    // it hasn't.
344
+    if (firefoxExtInstalled === null) {
345
+        window.setTimeout(
346
+            function() {
347
+                if (firefoxExtInstalled === null)
348
+                    firefoxExtInstalled = false;
349
+                self.obtainScreenOnFirefox(callback, errorCallback);
350
+            },
351
+            300
352
+        );
353
+        console.log("Waiting for detection of jidesha on firefox to finish.");
354
+        return;
355
+    }
356
+
357
+    // We need an extension and it isn't installed.
358
+
359
+    // Make sure we check for the extension when the user clicks again.
360
+    firefoxExtInstalled = null;
361
+    reDetectFirefoxExtension = true;
362
+
363
+    // Prompt the user to install the extension
364
+    this.eventEmitter.emit(DesktopSharingEventTypes.FIREFOX_EXTENSION_NEEDED,
365
+                           config.desktopSharingFirefoxExtensionURL);
366
+
367
+    // Make sure desktopsharing knows that we failed, so that it doesn't get
368
+    // stuck in 'switching' mode.
369
+    errorCallback('Firefox extension required.');
370
+};
371
+
372
+/**
373
+ * Starts the detection of an installed jidesha extension for firefox.
374
+ */
375
+function initFirefoxExtensionDetection() {
376
+    if (config.desktopSharingFirefoxDisabled) {
377
+        return;
378
+    }
379
+    if (firefoxExtInstalled === false || firefoxExtInstalled === true)
380
+        return;
381
+    if (!config.desktopSharingFirefoxExtId) {
382
+        firefoxExtInstalled = false;
383
+        return;
384
+    }
385
+
386
+    var img = document.createElement('img');
387
+    img.onload = function(){
388
+        console.log("Detected firefox screen sharing extension.");
389
+        firefoxExtInstalled = true;
390
+    };
391
+    img.onerror = function(){
392
+        console.log("Detected lack of firefox screen sharing extension.");
393
+        firefoxExtInstalled = false;
394
+    };
395
+
396
+    // The jidesha extension exposes an empty image file under the url:
397
+    // "chrome://EXT_ID/content/DOMAIN.png"
398
+    // Where EXT_ID is the ID of the extension with "@" replaced by ".", and
399
+    // DOMAIN is a domain whitelisted by the extension.
400
+    var src = "chrome://" +
401
+        (config.desktopSharingFirefoxExtId.replace('@', '.')) +
402
+        "/content/" + document.location.hostname + ".png";
403
+    img.setAttribute('src', src);
404
+}
264
 
405
 
265
 module.exports = ScreenObtainer;
406
 module.exports = ScreenObtainer;

+ 12
- 8
modules/desktopsharing/desktopsharing.js Näytä tiedosto

62
     }
62
     }
63
 }
63
 }
64
 
64
 
65
-// Called when RTC finishes initialization
66
-function onWebRtcReady() {
67
-    screenObtainer.init();
68
-    eventEmitter.emit(DesktopSharingEventTypes.INIT);
69
-}
70
-
71
 module.exports = {
65
 module.exports = {
72
     isUsingScreenStream: function () {
66
     isUsingScreenStream: function () {
73
         return isUsingScreenStream;
67
         return isUsingScreenStream;
82
     },
76
     },
83
     
77
     
84
     init: function () {
78
     init: function () {
85
-        APP.RTC.addListener(RTCEvents.RTC_READY, onWebRtcReady);
79
+        // Called when RTC finishes initialization
80
+        APP.RTC.addListener(RTCEvents.RTC_READY,
81
+            function() {
82
+                screenObtainer.init(eventEmitter);
83
+                eventEmitter.emit(DesktopSharingEventTypes.INIT);
84
+            });
86
     },
85
     },
87
 
86
 
88
     addListener: function (type, listener) {
87
     addListener: function (type, listener) {
139
                 getVideoStreamFailed, config.resolution || '360'
138
                 getVideoStreamFailed, config.resolution || '360'
140
             );
139
             );
141
         }
140
         }
142
-    }
141
+    },
142
+    /*
143
+     * Exports the event emitter to allow use by ScreenObtainer. Not for outside
144
+     * use.
145
+     */
146
+    eventEmitter: eventEmitter
143
 };
147
 };
144
 
148
 

+ 7
- 1
service/desktopsharing/DesktopSharingEventTypes.js Näytä tiedosto

3
 
3
 
4
     SWITCHING_DONE: "ds.switching_done",
4
     SWITCHING_DONE: "ds.switching_done",
5
 
5
 
6
-    NEW_STREAM_CREATED: "ds.new_stream_created"
6
+    NEW_STREAM_CREATED: "ds.new_stream_created",
7
+
8
+    /**
9
+     * An event which indicates that the jidesha extension for Firefox is
10
+     * needed to proceed with screen sharing, and that it is not installed.
11
+     */
12
+    FIREFOX_EXTENSION_NEEDED: "ds.firefox_extension_needed"
7
 };
13
 };
8
 
14
 
9
 module.exports = DesktopSharingEventTypes;
15
 module.exports = DesktopSharingEventTypes;

Loading…
Peruuta
Tallenna