Browse Source

fix(gum) update permissions prompt detection

Fire PERMISSION_PROMPT_IS_SHOWN when none of the devices have a label
Fire a new SLOW_GET_USER_MEDIA event if the timeout for getUserMedia is exceeded

Update JitsiMeetJS.createLocalTracks to include the options for firing the above events
in the provided options argument. Deprecate the firePermissionPromptIsShownEvent flag in
method's signature
dev1
Tudor-Ovidiu Avram 4 years ago
parent
commit
41a5ee63c9
4 changed files with 44 additions and 18 deletions
  1. 2
    0
      JitsiMediaDevicesEvents.js
  2. 23
    17
      JitsiMeetJS.js
  3. 8
    0
      modules/RTC/RTC.js
  4. 11
    1
      modules/RTC/RTCUtils.js

+ 2
- 0
JitsiMediaDevicesEvents.js View File

30
  */
30
  */
31
 export const PERMISSION_PROMPT_IS_SHOWN
31
 export const PERMISSION_PROMPT_IS_SHOWN
32
     = 'mediaDevices.permissionPromptIsShown';
32
     = 'mediaDevices.permissionPromptIsShown';
33
+
34
+export const SLOW_GET_USER_MEDIA = 'mediaDevices.slowGetUserMedia';

+ 23
- 17
JitsiMeetJS.js View File

46
  * The amount of time to wait until firing
46
  * The amount of time to wait until firing
47
  * {@link JitsiMediaDevicesEvents.PERMISSION_PROMPT_IS_SHOWN} event.
47
  * {@link JitsiMediaDevicesEvents.PERMISSION_PROMPT_IS_SHOWN} event.
48
  */
48
  */
49
-const USER_MEDIA_PERMISSION_PROMPT_TIMEOUT = 1000;
49
+const USER_MEDIA_SLOW_PROMISE_TIMEOUT = 1000;
50
 
50
 
51
 /**
51
 /**
52
  * Gets the next lowest desirable resolution to try for a camera. If the given
52
  * Gets the next lowest desirable resolution to try for a camera. If the given
300
      * which should be created. should be created or some additional
300
      * which should be created. should be created or some additional
301
      * configurations about resolution for example.
301
      * configurations about resolution for example.
302
      * @param {Array} options.effects optional effects array for the track
302
      * @param {Array} options.effects optional effects array for the track
303
+     * @param {boolean} options.firePermissionPromptIsShownEvent - if event
304
+     * JitsiMediaDevicesEvents.PERMISSION_PROMPT_IS_SHOWN should be fired
305
+     * @param {boolean} options.fireSlowPromiseEvent - if event
306
+     * JitsiMediaDevicesEvents.USER_MEDIA_SLOW_PROMISE_TIMEOUT should be fired
303
      * @param {Array} options.devices the devices that will be requested
307
      * @param {Array} options.devices the devices that will be requested
304
      * @param {string} options.resolution resolution constraints
308
      * @param {string} options.resolution resolution constraints
305
      * @param {string} options.cameraDeviceId
309
      * @param {string} options.cameraDeviceId
322
      * will finish the execution. If checkAgain returns false, createLocalTracks
326
      * will finish the execution. If checkAgain returns false, createLocalTracks
323
      * will finish the execution with rejected Promise.
327
      * will finish the execution with rejected Promise.
324
      *
328
      *
325
-     * @param {boolean} (firePermissionPromptIsShownEvent) - if event
326
-     * JitsiMediaDevicesEvents.PERMISSION_PROMPT_IS_SHOWN should be fired
329
+     * @deprecated old firePermissionPromptIsShownEvent
327
      * @param originalOptions - internal use only, to be able to store the
330
      * @param originalOptions - internal use only, to be able to store the
328
      * originally requested options.
331
      * originally requested options.
329
      * @returns {Promise.<{Array.<JitsiTrack>}, JitsiConferenceError>} A promise
332
      * @returns {Promise.<{Array.<JitsiTrack>}, JitsiConferenceError>} A promise
330
      * that returns an array of created JitsiTracks if resolved, or a
333
      * that returns an array of created JitsiTracks if resolved, or a
331
      * JitsiConferenceError if rejected.
334
      * JitsiConferenceError if rejected.
332
      */
335
      */
333
-    createLocalTracks(
334
-            options = {}, firePermissionPromptIsShownEvent, originalOptions) {
336
+    createLocalTracks(options = {}, oldfirePermissionPromptIsShownEvent, originalOptions) {
335
         let promiseFulfilled = false;
337
         let promiseFulfilled = false;
336
 
338
 
337
-        if (firePermissionPromptIsShownEvent === true) {
339
+        const { firePermissionPromptIsShownEvent, fireSlowPromiseEvent, ...restOptions } = options;
340
+        const firePermissionPrompt = firePermissionPromptIsShownEvent || oldfirePermissionPromptIsShownEvent;
341
+
342
+        if (firePermissionPrompt && !RTC.arePermissionsGrantedForAvailableDevices()) {
343
+            JitsiMediaDevices.emitEvent(
344
+                JitsiMediaDevicesEvents.PERMISSION_PROMPT_IS_SHOWN,
345
+                browser.getName());
346
+        } else if (fireSlowPromiseEvent) {
338
             window.setTimeout(() => {
347
             window.setTimeout(() => {
339
                 if (!promiseFulfilled) {
348
                 if (!promiseFulfilled) {
340
-                    JitsiMediaDevices.emitEvent(
341
-                        JitsiMediaDevicesEvents.PERMISSION_PROMPT_IS_SHOWN,
342
-                        browser.getName());
349
+                    JitsiMediaDevices.emitEvent(JitsiMediaDevicesEvents.SLOW_GET_USER_MEDIA);
343
                 }
350
                 }
344
-            }, USER_MEDIA_PERMISSION_PROMPT_TIMEOUT);
351
+            }, USER_MEDIA_SLOW_PROMISE_TIMEOUT);
345
         }
352
         }
346
 
353
 
347
         if (!window.connectionTimes) {
354
         if (!window.connectionTimes) {
350
         window.connectionTimes['obtainPermissions.start']
357
         window.connectionTimes['obtainPermissions.start']
351
             = window.performance.now();
358
             = window.performance.now();
352
 
359
 
353
-        return RTC.obtainAudioAndVideoPermissions(options)
360
+        return RTC.obtainAudioAndVideoPermissions(restOptions)
354
             .then(tracks => {
361
             .then(tracks => {
355
                 promiseFulfilled = true;
362
                 promiseFulfilled = true;
356
 
363
 
360
                 Statistics.sendAnalytics(
367
                 Statistics.sendAnalytics(
361
                     createGetUserMediaEvent(
368
                     createGetUserMediaEvent(
362
                         'success',
369
                         'success',
363
-                        getAnalyticsAttributesFromOptions(options)));
370
+                        getAnalyticsAttributesFromOptions(restOptions)));
364
 
371
 
365
                 if (!RTC.options.disableAudioLevels) {
372
                 if (!RTC.options.disableAudioLevels) {
366
                     for (let i = 0; i < tracks.length; i++) {
373
                     for (let i = 0; i < tracks.length; i++) {
408
 
415
 
409
                 if (error.name === JitsiTrackErrors.UNSUPPORTED_RESOLUTION
416
                 if (error.name === JitsiTrackErrors.UNSUPPORTED_RESOLUTION
410
                     && !browser.usesNewGumFlow()) {
417
                     && !browser.usesNewGumFlow()) {
411
-                    const oldResolution = options.resolution || '720';
418
+                    const oldResolution = restOptions.resolution || '720';
412
                     const newResolution = getLowerResolution(oldResolution);
419
                     const newResolution = getLowerResolution(oldResolution);
413
 
420
 
414
                     if (newResolution !== null) {
421
                     if (newResolution !== null) {
415
-                        options.resolution = newResolution;
422
+                        restOptions.resolution = newResolution;
416
 
423
 
417
                         logger.debug(
424
                         logger.debug(
418
                             'Retry createLocalTracks with resolution',
425
                             'Retry createLocalTracks with resolution',
427
                             }));
434
                             }));
428
 
435
 
429
                         return this.createLocalTracks(
436
                         return this.createLocalTracks(
430
-                            options,
431
-                            undefined,
432
-                            originalOptions || Object.assign({}, options));
437
+                            restOptions,
438
+                            originalOptions || Object.assign({}, restOptions));
433
                     }
439
                     }
434
 
440
 
435
                     // We tried everything. If there is a mandatory device id,
441
                     // We tried everything. If there is a mandatory device id,

+ 8
- 0
modules/RTC/RTC.js View File

742
         return RTCUtils.getCurrentlyAvailableMediaDevices();
742
         return RTCUtils.getCurrentlyAvailableMediaDevices();
743
     }
743
     }
744
 
744
 
745
+    /**
746
+     * Returns whether available devices have permissions granted
747
+     * @returns {Boolean}
748
+     */
749
+    static arePermissionsGrantedForAvailableDevices() {
750
+        return RTCUtils.arePermissionsGrantedForAvailableDevices();
751
+    }
752
+
745
     /**
753
     /**
746
      * Returns event data for device to be reported to stats.
754
      * Returns event data for device to be reported to stats.
747
      * @returns {MediaDeviceInfo} device.
755
      * @returns {MediaDeviceInfo} device.

+ 11
- 1
modules/RTC/RTCUtils.js View File

120
                 .then(devices => {
120
                 .then(devices => {
121
                     updateKnownDevices(devices);
121
                     updateKnownDevices(devices);
122
                     callback(devices);
122
                     callback(devices);
123
-                }, () => {
123
+                })
124
+                .catch(error => {
125
+                    logger.warn(`Failed to  enumerate devices. ${error}`);
124
                     updateKnownDevices([]);
126
                     updateKnownDevices([]);
125
                     callback([]);
127
                     callback([]);
126
                 });
128
                 });
1500
         return availableDevices;
1502
         return availableDevices;
1501
     }
1503
     }
1502
 
1504
 
1505
+    /**
1506
+     * Returns whether available devices have permissions granted
1507
+     * @returns {Boolean}
1508
+     */
1509
+    arePermissionsGrantedForAvailableDevices() {
1510
+        return availableDevices.some(device => Boolean(device.label));
1511
+    }
1512
+
1503
     /**
1513
     /**
1504
      * Returns event data for device to be reported to stats.
1514
      * Returns event data for device to be reported to stats.
1505
      * @returns {MediaDeviceInfo} device.
1515
      * @returns {MediaDeviceInfo} device.

Loading…
Cancel
Save