Skip to content

Commit

Permalink
fix(ScreenObtainer) fix using gDM with old Electron clients
Browse files Browse the repository at this point in the history
Detect if gDM support has been enabled and fallback to the previous gUM
flow otherwise.
  • Loading branch information
saghul committed Feb 12, 2025
1 parent 5c84d56 commit 522577a
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 10 deletions.
2 changes: 2 additions & 0 deletions JitsiTrackError.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ TRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.SCREENSHARING_USER_CANCELED]
= 'User canceled screen sharing prompt';
TRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.SCREENSHARING_GENERIC_ERROR]
= 'Unknown error from screensharing';
TRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.SCREENSHARING_NOT_SUPPORTED_ERROR]
= 'Not supported';
TRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.ELECTRON_DESKTOP_PICKER_ERROR]
= 'Unkown error from desktop picker';
TRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.ELECTRON_DESKTOP_PICKER_NOT_FOUND]
Expand Down
3 changes: 3 additions & 0 deletions JitsiTrackErrors.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ describe( "/JitsiTrackErrors members", () => {
NOT_FOUND,
PERMISSION_DENIED,
SCREENSHARING_GENERIC_ERROR,
SCREENSHARING_NOT_SUPPORTED_ERROR,
SCREENSHARING_USER_CANCELED,
TIMEOUT,
TRACK_IS_DISPOSED,
Expand All @@ -30,6 +31,7 @@ describe( "/JitsiTrackErrors members", () => {
expect( NOT_FOUND ).toBe( 'gum.not_found' );
expect( PERMISSION_DENIED ).toBe( 'gum.permission_denied' );
expect( SCREENSHARING_GENERIC_ERROR ).toBe( 'gum.screensharing_generic_error' );
expect( SCREENSHARING_NOT_SUPPORTED_ERROR ).toBe( 'gdm.screen_sharing_not_supported' );
expect( SCREENSHARING_USER_CANCELED ).toBe( 'gum.screensharing_user_canceled' );
expect( TIMEOUT ).toBe( 'gum.timeout' );
expect( TRACK_IS_DISPOSED ).toBe( 'track.track_is_disposed' );
Expand All @@ -47,6 +49,7 @@ describe( "/JitsiTrackErrors members", () => {
expect( JitsiTrackErrors.NOT_FOUND ).toBe( 'gum.not_found' );
expect( JitsiTrackErrors.PERMISSION_DENIED ).toBe( 'gum.permission_denied' );
expect( JitsiTrackErrors.SCREENSHARING_GENERIC_ERROR ).toBe( 'gum.screensharing_generic_error' );
expect( JitsiTrackErrors.SCREENSHARING_NOT_SUPPORTED_ERROR ).toBe( 'gdm.screen_sharing_not_supported' );
expect( JitsiTrackErrors.SCREENSHARING_USER_CANCELED ).toBe( 'gum.screensharing_user_canceled' );
expect( JitsiTrackErrors.TIMEOUT ).toBe( 'gum.timeout' );
expect( JitsiTrackErrors.TRACK_IS_DISPOSED ).toBe( 'track.track_is_disposed' );
Expand Down
7 changes: 7 additions & 0 deletions JitsiTrackErrors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ export enum JitsiTrackErrors {
*/
SCREENSHARING_GENERIC_ERROR = 'gum.screensharing_generic_error',

/**
* Error in getDisplayMedia when not supported. Can happen in Electron if no
* permission handler was set.
*/
SCREENSHARING_NOT_SUPPORTED_ERROR = 'gdm.screen_sharing_not_supported',

/**
* An error which indicates that user canceled screen sharing window
* selection dialog.
Expand Down Expand Up @@ -89,6 +95,7 @@ export const GENERAL = JitsiTrackErrors.GENERAL;
export const NOT_FOUND = JitsiTrackErrors.NOT_FOUND;
export const PERMISSION_DENIED = JitsiTrackErrors.PERMISSION_DENIED;
export const SCREENSHARING_GENERIC_ERROR = JitsiTrackErrors.SCREENSHARING_GENERIC_ERROR;
export const SCREENSHARING_NOT_SUPPORTED_ERROR = JitsiTrackErrors.SCREENSHARING_NOT_SUPPORTED_ERROR;
export const SCREENSHARING_USER_CANCELED = JitsiTrackErrors.SCREENSHARING_USER_CANCELED;
export const TIMEOUT = JitsiTrackErrors.TIMEOUT;
export const TRACK_IS_DISPOSED = JitsiTrackErrors.TRACK_IS_DISPOSED;
Expand Down
38 changes: 28 additions & 10 deletions modules/RTC/ScreenObtainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ const ScreenObtainer = {
if (!this.obtainStream) {
logger.info('Desktop sharing disabled');
}

this._electronSkipDisplayMedia = false;
},

/**
Expand All @@ -48,7 +50,7 @@ const ScreenObtainer = {
_createObtainStreamMethod() {
const supportsGetDisplayMedia = browser.supportsGetDisplayMedia();

if (browser.isElectron() && !this.options.testing?.electronUseGetDisplayMedia) {
if (browser.isElectron()) {
return this.obtainScreenOnElectron;
} else if (browser.isReactNative() && supportsGetDisplayMedia) {
return this.obtainScreenFromGetDisplayMediaRN;
Expand Down Expand Up @@ -94,12 +96,24 @@ const ScreenObtainer = {
* @param {Object} options - Optional parameters.
*/
obtainScreenOnElectron(onSuccess, onFailure, options = {}) {
if (typeof window.JitsiMeetScreenObtainer?.openDesktopPicker === 'function') {
// Detect if we have the fallback option.
if (window.JitsiMeetScreenObtainer?.gDMSupported) {
return this.obtainScreenFromGetDisplayMedia(onSuccess, onFailure);
}
if (!this._electronSkipDisplayMedia) {
// Fall-back to the old API in case of not supported error. This can happen if
// an old Electron SDK is used with a new Jitsi Meet + lib-jitsi-meet version.
this.obtainScreenFromGetDisplayMedia(onSuccess, err => {
if (err.name === JitsiTrackErrors.SCREENSHARING_NOT_SUPPORTED_ERROR) {
// Make sure we don't recurse infinitely.
this._electronSkipDisplayMedia = true;
this.obtainScreenOnElectron(onSuccess, onFailure);
} else {
onFailure(err);
}
});

return;
}

// TODO: legacy flow, remove after the Electron SDK supporting gDM has been out for a while.
if (typeof window.JitsiMeetScreenObtainer?.openDesktopPicker === 'function') {
const { desktopSharingFrameRate, desktopSharingResolution, desktopSharingSources } = this.options;

window.JitsiMeetScreenObtainer.openDesktopPicker(
Expand Down Expand Up @@ -293,14 +307,18 @@ const ScreenObtainer = {
})
.catch(error => {
const errorDetails = {
errorName: error?.name,
errorMsg: error?.message,
errorStack: error?.stack
errorCode: error.code,
errorName: error.name,
errorMsg: error.message,
errorStack: error.stack
};

logger.warn('getDisplayMedia error', JSON.stringify(constraints), JSON.stringify(errorDetails));

if (errorDetails.errorMsg?.indexOf('denied by system') !== -1) {
if (errorDetails.code === DOMException.NOT_SUPPORTED_ERR) {
// This error is thrown when an Electron client has not set a permissions handler.
errorCallback(new JitsiTrackError(JitsiTrackErrors.SCREENSHARING_NOT_SUPPORTED_ERROR));
} else if (errorDetails.errorMsg?.indexOf('denied by system') !== -1) {
// On Chrome this is the only thing different between error returned when user cancels
// and when no permission was given on the OS level.
errorCallback(new JitsiTrackError(JitsiTrackErrors.PERMISSION_DENIED));
Expand Down

0 comments on commit 522577a

Please sign in to comment.