|
|
@@ -50,16 +50,41 @@ const CHROME_EXTENSION_POPUP_ERROR
|
|
50
|
50
|
const CHROME_EXTENSION_IFRAME_ERROR
|
|
51
|
51
|
= 'Chrome Web Store installations can only be started by the top frame.';
|
|
52
|
52
|
|
|
|
53
|
+/**
|
|
|
54
|
+ * The error returned by chrome when trying to start inline installation
|
|
|
55
|
+ * not from the "main" whitelisted site.
|
|
|
56
|
+ * @type {string}
|
|
|
57
|
+ */
|
|
|
58
|
+const CHROME_EXTENSION_INLINE_ERROR
|
|
|
59
|
+ = 'Installs can only be initiated by one of'
|
|
|
60
|
+ + ' the Chrome Web Store item\'s verified sites.';
|
|
|
61
|
+
|
|
53
|
62
|
/**
|
|
54
|
63
|
* The error message returned by chrome when the extension is installed.
|
|
55
|
64
|
*/
|
|
56
|
65
|
const CHROME_NO_EXTENSION_ERROR_MSG // eslint-disable-line no-unused-vars
|
|
57
|
66
|
= 'Could not establish connection. Receiving end does not exist.';
|
|
58
|
67
|
|
|
|
68
|
+/**
|
|
|
69
|
+ * The error message returned by chrome when the extension install action needs
|
|
|
70
|
+ * to be initiated by a user gesture.
|
|
|
71
|
+ * @type {string}
|
|
|
72
|
+ */
|
|
|
73
|
+const CHROME_USER_GESTURE_REQ_ERROR
|
|
|
74
|
+ = 'Chrome Web Store installations can only be initated by a user gesture.';
|
|
|
75
|
+
|
|
59
|
76
|
/**
|
|
60
|
77
|
* Handles obtaining a stream from a screen capture on different browsers.
|
|
61
|
78
|
*/
|
|
62
|
79
|
const ScreenObtainer = {
|
|
|
80
|
+ /**
|
|
|
81
|
+ * If not <tt>null</tt> it means that the initialization process is still in
|
|
|
82
|
+ * progress. It is used to make desktop stream request wait and continue
|
|
|
83
|
+ * after it's done.
|
|
|
84
|
+ * {@type Promise|null}
|
|
|
85
|
+ */
|
|
|
86
|
+ intChromeExtPromise: null,
|
|
|
87
|
+
|
|
63
|
88
|
obtainStream: null,
|
|
64
|
89
|
|
|
65
|
90
|
/**
|
|
|
@@ -177,7 +202,10 @@ const ScreenObtainer = {
|
|
177
|
202
|
}
|
|
178
|
203
|
|
|
179
|
204
|
logger.info('Using Chrome extension for desktop sharing');
|
|
180
|
|
- initChromeExtension(options);
|
|
|
205
|
+ this.intChromeExtPromise
|
|
|
206
|
+ = initChromeExtension(options).then(() => {
|
|
|
207
|
+ this.intChromeExtPromise = null;
|
|
|
208
|
+ });
|
|
181
|
209
|
|
|
182
|
210
|
return this.obtainScreenFromExtension;
|
|
183
|
211
|
} else if (RTCBrowserType.isFirefox()) {
|
|
|
@@ -315,6 +343,15 @@ const ScreenObtainer = {
|
|
315
|
343
|
* 'desktop' stream for returned stream token.
|
|
316
|
344
|
*/
|
|
317
|
345
|
obtainScreenFromExtension(options, streamCallback, failCallback) {
|
|
|
346
|
+ if (this.intChromeExtPromise !== null) {
|
|
|
347
|
+ this.intChromeExtPromise.then(() => {
|
|
|
348
|
+ this.obtainScreenFromExtension(
|
|
|
349
|
+ options, streamCallback, failCallback);
|
|
|
350
|
+ });
|
|
|
351
|
+
|
|
|
352
|
+ return;
|
|
|
353
|
+ }
|
|
|
354
|
+
|
|
318
|
355
|
const {
|
|
319
|
356
|
desktopSharingChromeExtId,
|
|
320
|
357
|
desktopSharingChromeSources
|
|
|
@@ -379,7 +416,8 @@ const ScreenObtainer = {
|
|
379
|
416
|
const webStoreInstallUrl = getWebStoreInstallUrl(this.options);
|
|
380
|
417
|
|
|
381
|
418
|
if ((CHROME_EXTENSION_POPUP_ERROR === e
|
|
382
|
|
- || CHROME_EXTENSION_IFRAME_ERROR === e)
|
|
|
419
|
+ || CHROME_EXTENSION_IFRAME_ERROR === e
|
|
|
420
|
+ || CHROME_EXTENSION_INLINE_ERROR === e)
|
|
383
|
421
|
&& options.interval > 0
|
|
384
|
422
|
&& typeof options.checkAgain === 'function'
|
|
385
|
423
|
&& typeof options.listener === 'function') {
|
|
|
@@ -394,9 +432,13 @@ const ScreenObtainer = {
|
|
394
|
432
|
= `Failed to install the extension from ${webStoreInstallUrl}`;
|
|
395
|
433
|
|
|
396
|
434
|
logger.log(msg, e);
|
|
397
|
|
- failCallback(new JitsiTrackError(
|
|
398
|
|
- JitsiTrackErrors.CHROME_EXTENSION_INSTALLATION_ERROR,
|
|
399
|
|
- msg));
|
|
|
435
|
+
|
|
|
436
|
+ const error
|
|
|
437
|
+ = e === CHROME_USER_GESTURE_REQ_ERROR
|
|
|
438
|
+ ? JitsiTrackErrors.CHROME_EXTENSION_USER_GESTURE_REQUIRED
|
|
|
439
|
+ : JitsiTrackErrors.CHROME_EXTENSION_INSTALLATION_ERROR;
|
|
|
440
|
+
|
|
|
441
|
+ failCallback(new JitsiTrackError(error, msg));
|
|
400
|
442
|
},
|
|
401
|
443
|
|
|
402
|
444
|
/* eslint-enable max-params */
|
|
|
@@ -583,19 +625,25 @@ function initInlineInstalls(options) {
|
|
583
|
625
|
/**
|
|
584
|
626
|
*
|
|
585
|
627
|
* @param options
|
|
|
628
|
+ *
|
|
|
629
|
+ * @return {Promise} - a Promise resolved once the initialization process is
|
|
|
630
|
+ * finished.
|
|
586
|
631
|
*/
|
|
587
|
632
|
function initChromeExtension(options) {
|
|
588
|
633
|
// Initialize Chrome extension inline installs
|
|
589
|
634
|
initInlineInstalls(options);
|
|
590
|
635
|
|
|
591
|
|
- // Check if extension is installed
|
|
592
|
|
- checkChromeExtInstalled((installed, updateRequired) => {
|
|
593
|
|
- chromeExtInstalled = installed;
|
|
594
|
|
- chromeExtUpdateRequired = updateRequired;
|
|
595
|
|
- logger.info(
|
|
596
|
|
- `Chrome extension installed: ${chromeExtInstalled
|
|
597
|
|
- } updateRequired: ${chromeExtUpdateRequired}`);
|
|
598
|
|
- }, options);
|
|
|
636
|
+ return new Promise(resolve => {
|
|
|
637
|
+ // Check if extension is installed
|
|
|
638
|
+ checkChromeExtInstalled((installed, updateRequired) => {
|
|
|
639
|
+ chromeExtInstalled = installed;
|
|
|
640
|
+ chromeExtUpdateRequired = updateRequired;
|
|
|
641
|
+ logger.info(
|
|
|
642
|
+ `Chrome extension installed: ${chromeExtInstalled
|
|
|
643
|
+ } updateRequired: ${chromeExtUpdateRequired}`);
|
|
|
644
|
+ resolve();
|
|
|
645
|
+ }, options);
|
|
|
646
|
+ });
|
|
599
|
647
|
}
|
|
600
|
648
|
|
|
601
|
649
|
/**
|