| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 | 
							- /* @flow */
 - 
 - import { getLogger } from 'jitsi-meet-logger';
 - 
 - import * as JitsiMeetConferenceEvents from '../../ConferenceEvents';
 - import {
 -     openRemoteControlAuthorizationDialog
 - } from '../../react/features/remote-control';
 - import {
 -     DISCO_REMOTE_CONTROL_FEATURE,
 -     EVENTS,
 -     PERMISSIONS_ACTIONS,
 -     REMOTE_CONTROL_MESSAGE_NAME,
 -     REQUESTS
 - } from '../../service/remotecontrol/Constants';
 - import { getJitsiMeetTransport } from '../transport';
 - 
 - import RemoteControlParticipant from './RemoteControlParticipant';
 - 
 - declare var APP: Object;
 - declare var config: Object;
 - declare var interfaceConfig: Object;
 - declare var JitsiMeetJS: Object;
 - 
 - const ConferenceEvents = JitsiMeetJS.events.conference;
 - const logger = getLogger(__filename);
 - 
 - /**
 -  * The transport instance used for communication with external apps.
 -  *
 -  * @type {Transport}
 -  */
 - const transport = getJitsiMeetTransport();
 - 
 - /**
 -  * This class represents the receiver party for a remote controller session.
 -  * It handles "remote-control-event" events and sends them to the
 -  * API module. From there the events can be received from wrapper application
 -  * and executed.
 -  */
 - export default class Receiver extends RemoteControlParticipant {
 -     _controller: ?string;
 -     _enabled: boolean;
 -     _hangupListener: Function;
 -     _remoteControlEventsListener: Function;
 -     _userLeftListener: Function;
 - 
 -     /**
 -      * Creates new instance.
 -      */
 -     constructor() {
 -         super();
 -         this._controller = null;
 -         this._remoteControlEventsListener
 -             = this._onRemoteControlMessage.bind(this);
 -         this._userLeftListener = this._onUserLeft.bind(this);
 -         this._hangupListener = this._onHangup.bind(this);
 - 
 -         // We expect here that even if we receive the supported event earlier
 -         // it will be cached and we'll receive it.
 -         transport.on('event', event => {
 -             if (event.name === REMOTE_CONTROL_MESSAGE_NAME) {
 -                 this._onRemoteControlAPIEvent(event);
 - 
 -                 return true;
 -             }
 - 
 -             return false;
 -         });
 -     }
 - 
 -     /**
 -      * Enables / Disables the remote control.
 -      *
 -      * @param {boolean} enabled - The new state.
 -      * @returns {void}
 -      */
 -     _enable(enabled: boolean) {
 -         if (this._enabled === enabled) {
 -             return;
 -         }
 -         this._enabled = enabled;
 -         if (enabled === true) {
 -             logger.log('Remote control receiver enabled.');
 - 
 -             // Announce remote control support.
 -             APP.connection.addFeature(DISCO_REMOTE_CONTROL_FEATURE, true);
 -             APP.conference.addConferenceListener(
 -                 ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
 -                 this._remoteControlEventsListener);
 -             APP.conference.addListener(JitsiMeetConferenceEvents.BEFORE_HANGUP,
 -                 this._hangupListener);
 -         } else {
 -             logger.log('Remote control receiver disabled.');
 -             this._stop(true);
 -             APP.connection.removeFeature(DISCO_REMOTE_CONTROL_FEATURE);
 -             APP.conference.removeConferenceListener(
 -                 ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
 -                 this._remoteControlEventsListener);
 -             APP.conference.removeListener(
 -                 JitsiMeetConferenceEvents.BEFORE_HANGUP,
 -                 this._hangupListener);
 -         }
 -     }
 - 
 -     /**
 -      * Removes the listener for ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED
 -      * events. Sends stop message to the wrapper application. Optionally
 -      * displays dialog for informing the user that remote control session
 -      * ended.
 -      *
 -      * @param {boolean} [dontNotify] - If true - a notification about stopping
 -      * the remote control won't be displayed.
 -      * @returns {void}
 -      */
 -     _stop(dontNotify: boolean = false) {
 -         if (!this._controller) {
 -             return;
 -         }
 -         logger.log('Remote control receiver stop.');
 -         this._controller = null;
 -         APP.conference.removeConferenceListener(ConferenceEvents.USER_LEFT,
 -             this._userLeftListener);
 -         transport.sendEvent({
 -             name: REMOTE_CONTROL_MESSAGE_NAME,
 -             type: EVENTS.stop
 -         });
 -         if (!dontNotify) {
 -             APP.UI.messageHandler.notify(
 -                 'dialog.remoteControlTitle',
 -                 'dialog.remoteControlStopMessage'
 -             );
 -         }
 -     }
 - 
 -     /**
 -      * Calls this._stop() and sends stop message to the controller participant.
 -      *
 -      * @returns {void}
 -      */
 -     stop() {
 -         if (!this._controller) {
 -             return;
 -         }
 -         this.sendRemoteControlEndpointMessage(this._controller, {
 -             type: EVENTS.stop
 -         });
 -         this._stop();
 -     }
 - 
 -     /**
 -      * Listens for data channel EndpointMessage. Handles only remote control
 -      * messages. Sends the remote control messages to the external app that
 -      * will execute them.
 -      *
 -      * @param {JitsiParticipant} participant - The controller participant.
 -      * @param {Object} message - EndpointMessage from the data channels.
 -      * @param {string} message.name - The function processes only messages with
 -      * name REMOTE_CONTROL_MESSAGE_NAME.
 -      * @returns {void}
 -      */
 -     _onRemoteControlMessage(participant: Object, message: Object) {
 -         if (message.name !== REMOTE_CONTROL_MESSAGE_NAME) {
 -             return;
 -         }
 - 
 -         if (this._enabled) {
 -             if (this._controller === null
 -                     && message.type === EVENTS.permissions
 -                     && message.action === PERMISSIONS_ACTIONS.request) {
 -                 const userId = participant.getId();
 - 
 -                 APP.store.dispatch(
 -                     openRemoteControlAuthorizationDialog(userId));
 -             } else if (this._controller === participant.getId()) {
 -                 if (message.type === EVENTS.stop) {
 -                     this._stop();
 -                 } else { // forward the message
 -                     transport.sendEvent(message);
 -                 }
 -             } // else ignore
 -         } else {
 -             logger.log('Remote control message is ignored because remote '
 -                 + 'control is disabled', message);
 -         }
 -     }
 - 
 -     /**
 -      * Denies remote control access for user associated with the passed user id.
 -      *
 -      * @param {string} userId - The id associated with the user who sent the
 -      * request for remote control authorization.
 -      * @returns {void}
 -      */
 -     deny(userId: string) {
 -         this.sendRemoteControlEndpointMessage(userId, {
 -             type: EVENTS.permissions,
 -             action: PERMISSIONS_ACTIONS.deny
 -         });
 -     }
 - 
 -     /**
 -      * Grants remote control access to user associated with the passed user id.
 -      *
 -      * @param {string} userId - The id associated with the user who sent the
 -      * request for remote control authorization.
 -      * @returns {void}
 -      */
 -     grant(userId: string) {
 -         APP.conference.addConferenceListener(ConferenceEvents.USER_LEFT,
 -             this._userLeftListener);
 -         this._controller = userId;
 -         logger.log(`Remote control permissions granted to: ${userId}`);
 - 
 -         let promise;
 - 
 -         if (APP.conference.isSharingScreen
 -                 && APP.conference.getDesktopSharingSourceType() === 'screen') {
 -             promise = this._sendStartRequest();
 -         } else {
 -             promise = APP.conference.toggleScreenSharing(
 -                 true,
 -                 {
 -                     desktopSharingSources: [ 'screen' ]
 -                 })
 -                 .then(() => this._sendStartRequest());
 -         }
 - 
 -         promise
 -             .then(() =>
 -                 this.sendRemoteControlEndpointMessage(userId, {
 -                     type: EVENTS.permissions,
 -                     action: PERMISSIONS_ACTIONS.grant
 -                 })
 -             )
 -             .catch(error => {
 -                 logger.error(error);
 - 
 -                 this.sendRemoteControlEndpointMessage(userId, {
 -                     type: EVENTS.permissions,
 -                     action: PERMISSIONS_ACTIONS.error
 -                 });
 - 
 -                 APP.UI.messageHandler.notify(
 -                     'dialog.remoteControlTitle',
 -                     'dialog.startRemoteControlErrorMessage'
 -                 );
 - 
 -                 this._stop(true);
 -             });
 -     }
 - 
 -     /**
 -      * Sends remote control start request.
 -      *
 -      * @returns {Promise}
 -      */
 -     _sendStartRequest() {
 -         return transport.sendRequest({
 -             name: REMOTE_CONTROL_MESSAGE_NAME,
 -             type: REQUESTS.start,
 -             sourceId: APP.conference.getDesktopSharingSourceId()
 -         });
 -     }
 - 
 -     /**
 -      * Handles remote control events from the external app. Currently only
 -      * events with type EVENTS.supported and EVENTS.stop are
 -      * supported.
 -      *
 -      * @param {RemoteControlEvent} event - The remote control event.
 -      * @returns {void}
 -      */
 -     _onRemoteControlAPIEvent(event: Object) {
 -         switch (event.type) {
 -         case EVENTS.supported:
 -             this._onRemoteControlSupported();
 -             break;
 -         case EVENTS.stop:
 -             this.stop();
 -             break;
 -         }
 -     }
 - 
 -     /**
 -      * Handles events for support for executing remote control events into
 -      * the wrapper application.
 -      *
 -      * @returns {void}
 -      */
 -     _onRemoteControlSupported() {
 -         logger.log('Remote Control supported.');
 -         if (config.disableRemoteControl) {
 -             logger.log('Remote Control disabled.');
 -         } else {
 -             this._enable(true);
 -         }
 -     }
 - 
 -     /**
 -      * Calls the stop method if the other side have left.
 -      *
 -      * @param {string} id - The user id for the participant that have left.
 -      * @returns {void}
 -      */
 -     _onUserLeft(id: string) {
 -         if (this._controller === id) {
 -             this._stop();
 -         }
 -     }
 - 
 -     /**
 -      * Handles hangup events. Disables the receiver.
 -      *
 -      * @returns {void}
 -      */
 -     _onHangup() {
 -         this._enable(false);
 -     }
 - }
 
 
  |