瀏覽代碼

feat(remotecontrol): multi monitor support

master
hristoterezov 8 年之前
父節點
當前提交
814d56c25c

+ 11
- 0
conference.js 查看文件

@@ -2118,5 +2118,16 @@ export default {
2118 2118
             room.setDisplayName(formattedNickname);
2119 2119
             APP.UI.changeDisplayName(this.getMyUserId(), formattedNickname);
2120 2120
         }
2121
+    },
2122
+
2123
+    /**
2124
+     * Returns the desktop sharing source id or undefined if the desktop sharing
2125
+     * is not active at the moment.
2126
+     *
2127
+     * @returns {string|undefined} - The source id. If the track is not desktop
2128
+     * track or the source id is not available, undefined will be returned.
2129
+     */
2130
+    getDesktopSharingSourceId() {
2131
+        return localVideo.sourceId;
2121 2132
     }
2122 2133
 };

+ 23
- 23
modules/remotecontrol/Controller.js 查看文件

@@ -4,9 +4,9 @@ import { getLogger } from 'jitsi-meet-logger';
4 4
 
5 5
 import * as KeyCodes from '../keycode/keycode';
6 6
 import {
7
-    EVENT_TYPES,
7
+    EVENTS,
8 8
     PERMISSIONS_ACTIONS,
9
-    REMOTE_CONTROL_EVENT_NAME
9
+    REMOTE_CONTROL_MESSAGE_NAME
10 10
 } from '../../service/remotecontrol/Constants';
11 11
 import UIEvents from '../../service/UI/UIEvents';
12 12
 
@@ -145,8 +145,8 @@ export default class Controller extends RemoteControlParticipant {
145 145
             APP.conference.addConferenceListener(ConferenceEvents.USER_LEFT,
146 146
                 onUserLeft);
147 147
             this._requestedParticipant = userId;
148
-            this.sendRemoteControlEvent(userId, {
149
-                type: EVENT_TYPES.permissions,
148
+            this.sendRemoteControlEndpointMessage(userId, {
149
+                type: EVENTS.permissions,
150 150
                 action: PERMISSIONS_ACTIONS.request
151 151
             }, e => {
152 152
                 clearRequest();
@@ -167,8 +167,8 @@ export default class Controller extends RemoteControlParticipant {
167 167
         const userId = participant.getId();
168 168
 
169 169
         if (this._enabled
170
-                && event.name === REMOTE_CONTROL_EVENT_NAME
171
-                && event.type === EVENT_TYPES.permissions
170
+                && event.name === REMOTE_CONTROL_MESSAGE_NAME
171
+                && event.type === EVENTS.permissions
172 172
                 && userId === this._requestedParticipant) {
173 173
             if (event.action !== PERMISSIONS_ACTIONS.grant) {
174 174
                 this._area = undefined;
@@ -201,13 +201,13 @@ export default class Controller extends RemoteControlParticipant {
201 201
      * event.
202 202
      * @param {Object} event - EndpointMessage event from the data channels.
203 203
      * @property {string} type - The function process only events with
204
-     * name REMOTE_CONTROL_EVENT_NAME.
204
+     * name REMOTE_CONTROL_MESSAGE_NAME.
205 205
      * @returns {void}
206 206
      */
207 207
     _handleRemoteControlStoppedEvent(participant: Object, event: Object) {
208 208
         if (this._enabled
209
-                && event.name === REMOTE_CONTROL_EVENT_NAME
210
-                && event.type === EVENT_TYPES.stop
209
+                && event.name === REMOTE_CONTROL_MESSAGE_NAME
210
+                && event.type === EVENTS.stop
211 211
                 && participant.getId() === this._controlledParticipant) {
212 212
             this._stop();
213 213
         }
@@ -251,8 +251,8 @@ export default class Controller extends RemoteControlParticipant {
251 251
             // $FlowDisableNextLine: we are sure that this._area is not null.
252 252
             const position = this._area.position();
253 253
 
254
-            this.sendRemoteControlEvent(this._controlledParticipant, {
255
-                type: EVENT_TYPES.mousemove,
254
+            this.sendRemoteControlEndpointMessage(this._controlledParticipant, {
255
+                type: EVENTS.mousemove,
256 256
 
257 257
                 // $FlowDisableNextLine: we are sure that this._area is not null
258 258
                 x: (event.pageX - position.left) / this._area.width(),
@@ -264,30 +264,30 @@ export default class Controller extends RemoteControlParticipant {
264 264
 
265 265
         // $FlowDisableNextLine: we are sure that this._area is not null.
266 266
         this._area.mousedown(this._onMouseClickHandler.bind(this,
267
-            EVENT_TYPES.mousedown));
267
+            EVENTS.mousedown));
268 268
 
269 269
         // $FlowDisableNextLine: we are sure that this._area is not null.
270 270
         this._area.mouseup(this._onMouseClickHandler.bind(this,
271
-            EVENT_TYPES.mouseup));
271
+            EVENTS.mouseup));
272 272
 
273 273
         // $FlowDisableNextLine: we are sure that this._area is not null.
274 274
         this._area.dblclick(
275
-            this._onMouseClickHandler.bind(this, EVENT_TYPES.mousedblclick));
275
+            this._onMouseClickHandler.bind(this, EVENTS.mousedblclick));
276 276
 
277 277
         // $FlowDisableNextLine: we are sure that this._area is not null.
278 278
         this._area.contextmenu(() => false);
279 279
 
280 280
         // $FlowDisableNextLine: we are sure that this._area is not null.
281 281
         this._area[0].onmousewheel = event => {
282
-            this.sendRemoteControlEvent(this._controlledParticipant, {
283
-                type: EVENT_TYPES.mousescroll,
282
+            this.sendRemoteControlEndpointMessage(this._controlledParticipant, {
283
+                type: EVENTS.mousescroll,
284 284
                 x: event.deltaX,
285 285
                 y: event.deltaY
286 286
             });
287 287
         };
288 288
         $(window).keydown(this._onKeyPessHandler.bind(this,
289
-            EVENT_TYPES.keydown));
290
-        $(window).keyup(this._onKeyPessHandler.bind(this, EVENT_TYPES.keyup));
289
+            EVENTS.keydown));
290
+        $(window).keyup(this._onKeyPessHandler.bind(this, EVENTS.keyup));
291 291
     }
292 292
 
293 293
     /**
@@ -309,8 +309,8 @@ export default class Controller extends RemoteControlParticipant {
309 309
             this._stopListener);
310 310
         APP.conference.removeConferenceListener(ConferenceEvents.USER_LEFT,
311 311
             this._userLeftListener);
312
-        this._controlledParticipant = null;
313 312
         this.pause();
313
+        this._controlledParticipant = null;
314 314
         this._area = undefined;
315 315
         APP.UI.messageHandler.openMessageDialog(
316 316
             'dialog.remoteControlTitle',
@@ -330,8 +330,8 @@ export default class Controller extends RemoteControlParticipant {
330 330
         if (!this._controlledParticipant) {
331 331
             return;
332 332
         }
333
-        this.sendRemoteControlEvent(this._controlledParticipant, {
334
-            type: EVENT_TYPES.stop
333
+        this.sendRemoteControlEndpointMessage(this._controlledParticipant, {
334
+            type: EVENTS.stop
335 335
         });
336 336
         this._stop();
337 337
     }
@@ -383,7 +383,7 @@ export default class Controller extends RemoteControlParticipant {
383 383
      * @returns {void}
384 384
      */
385 385
     _onMouseClickHandler(type: string, event: Object) {
386
-        this.sendRemoteControlEvent(this._controlledParticipant, {
386
+        this.sendRemoteControlEndpointMessage(this._controlledParticipant, {
387 387
             type,
388 388
             button: event.which
389 389
         });
@@ -416,7 +416,7 @@ export default class Controller extends RemoteControlParticipant {
416 416
      * @returns {void}
417 417
      */
418 418
     _onKeyPessHandler(type: string, event: Object) {
419
-        this.sendRemoteControlEvent(this._controlledParticipant, {
419
+        this.sendRemoteControlEndpointMessage(this._controlledParticipant, {
420 420
             type,
421 421
             key: getKey(event),
422 422
             modifiers: getModifiers(event)

+ 74
- 105
modules/remotecontrol/Receiver.js 查看文件

@@ -8,9 +8,10 @@ import {
8 8
 } from '../../react/features/remote-control';
9 9
 import {
10 10
     DISCO_REMOTE_CONTROL_FEATURE,
11
-    EVENT_TYPES,
11
+    EVENTS,
12 12
     PERMISSIONS_ACTIONS,
13
-    REMOTE_CONTROL_EVENT_NAME
13
+    REMOTE_CONTROL_MESSAGE_NAME,
14
+    REQUESTS
14 15
 } from '../../service/remotecontrol/Constants';
15 16
 import { getJitsiMeetTransport } from '../transport';
16 17
 
@@ -51,14 +52,14 @@ export default class Receiver extends RemoteControlParticipant {
51 52
         super();
52 53
         this._controller = null;
53 54
         this._remoteControlEventsListener
54
-            = this._onRemoteControlEvent.bind(this);
55
+            = this._onRemoteControlMessage.bind(this);
55 56
         this._userLeftListener = this._onUserLeft.bind(this);
56 57
         this._hangupListener = this._onHangup.bind(this);
57 58
 
58 59
         // We expect here that even if we receive the supported event earlier
59 60
         // it will be cached and we'll receive it.
60 61
         transport.on('event', event => {
61
-            if (event.name === REMOTE_CONTROL_EVENT_NAME) {
62
+            if (event.name === REMOTE_CONTROL_MESSAGE_NAME) {
62 63
                 this._onRemoteControlAPIEvent(event);
63 64
 
64 65
                 return true;
@@ -120,12 +121,10 @@ export default class Receiver extends RemoteControlParticipant {
120 121
         this._controller = null;
121 122
         APP.conference.removeConferenceListener(ConferenceEvents.USER_LEFT,
122 123
             this._userLeftListener);
123
-        if (this.remoteControlExternalAuth) {
124
-            transport.sendEvent({
125
-                name: REMOTE_CONTROL_EVENT_NAME,
126
-                type: EVENT_TYPES.stop
127
-            });
128
-        }
124
+        transport.sendEvent({
125
+            name: REMOTE_CONTROL_MESSAGE_NAME,
126
+            type: EVENTS.stop
127
+        });
129 128
         if (!dontShowDialog) {
130 129
             APP.UI.messageHandler.openMessageDialog(
131 130
                 'dialog.remoteControlTitle',
@@ -143,89 +142,46 @@ export default class Receiver extends RemoteControlParticipant {
143 142
         if (!this._controller) {
144 143
             return;
145 144
         }
146
-        this.sendRemoteControlEvent(this._controller, {
147
-            type: EVENT_TYPES.stop
145
+        this.sendRemoteControlEndpointMessage(this._controller, {
146
+            type: EVENTS.stop
148 147
         });
149 148
         this._stop();
150 149
     }
151 150
 
152 151
     /**
153
-     * Listens for data channel EndpointMessage events. Handles only events of
154
-     * type remote control. Sends "remote-control-event" events to the API
155
-     * module.
152
+     * Listens for data channel EndpointMessage. Handles only remote control
153
+     * messages. Sends the remote control messages to the external app that
154
+     * will execute them.
156 155
      *
157 156
      * @param {JitsiParticipant} participant - The controller participant.
158
-     * @param {Object} event - EndpointMessage event from the data channels.
159
-     * @param {string} event.name - The function process only events with
160
-     * name REMOTE_CONTROL_EVENT_NAME.
157
+     * @param {Object} message - EndpointMessage from the data channels.
158
+     * @param {string} message.name - The function processes only messages with
159
+     * name REMOTE_CONTROL_MESSAGE_NAME.
161 160
      * @returns {void}
162 161
      */
163
-    _onRemoteControlEvent(participant: Object, event: Object) {
164
-        if (event.name !== REMOTE_CONTROL_EVENT_NAME) {
162
+    _onRemoteControlMessage(participant: Object, message: Object) {
163
+        if (message.name !== REMOTE_CONTROL_MESSAGE_NAME) {
165 164
             return;
166 165
         }
167 166
 
168
-        const remoteControlEvent = Object.assign({}, event);
169
-
170 167
         if (this._enabled) {
171 168
             if (this._controller === null
172
-                    && event.type === EVENT_TYPES.permissions
173
-                    && event.action === PERMISSIONS_ACTIONS.request) {
169
+                    && message.type === EVENTS.permissions
170
+                    && message.action === PERMISSIONS_ACTIONS.request) {
174 171
                 const userId = participant.getId();
175 172
 
176
-                if (!config.remoteControlExternalAuth) {
177
-                    APP.store.dispatch(
178
-                        openRemoteControlAuthorizationDialog(userId));
179
-
180
-                    return;
173
+                APP.store.dispatch(
174
+                    openRemoteControlAuthorizationDialog(userId));
175
+            } else if (this._controller === participant.getId()) {
176
+                if (message.type === EVENTS.stop) {
177
+                    this._stop();
178
+                } else { // forward the message
179
+                    transport.sendEvent(message);
181 180
                 }
182
-
183
-                // FIXME: Maybe use transport.sendRequest in this case???
184
-                remoteControlEvent.userId = userId;
185
-                remoteControlEvent.userJID = participant.getJid();
186
-                remoteControlEvent.displayName = participant.getDisplayName()
187
-                    || interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME;
188
-                remoteControlEvent.screenSharing
189
-                    = APP.conference.isSharingScreen;
190
-            } else if (this._controller !== participant.getId()) {
191
-                return;
192
-            } else if (event.type === EVENT_TYPES.stop) {
193
-                this._stop();
194
-
195
-                return;
196
-            }
197
-            transport.sendEvent(remoteControlEvent);
181
+            } // else ignore
198 182
         } else {
199
-            logger.log('Remote control event is ignored because remote '
200
-                + 'control is disabled', event);
201
-        }
202
-    }
203
-
204
-    /**
205
-     * Handles remote control permission events.
206
-     *
207
-     * @param {string} userId - The user id of the participant related to the
208
-     * event.
209
-     * @param {PERMISSIONS_ACTIONS} action - The action related to the event.
210
-     * @returns {void}
211
-     */
212
-    _onRemoteControlPermissionsEvent(userId: string, action: string) {
213
-        switch (action) {
214
-        case PERMISSIONS_ACTIONS.grant:
215
-            this.grant(userId);
216
-            break;
217
-        case PERMISSIONS_ACTIONS.deny:
218
-            this.deny(userId);
219
-            break;
220
-        case PERMISSIONS_ACTIONS.error:
221
-            this.sendRemoteControlEvent(userId, {
222
-                type: EVENT_TYPES.permissions,
223
-                action
224
-            });
225
-            break;
226
-        default:
227
-
228
-                // Unknown action. Ignore.
183
+            logger.log('Remote control message is ignored because remote '
184
+                + 'control is disabled', message);
229 185
         }
230 186
     }
231 187
 
@@ -237,8 +193,8 @@ export default class Receiver extends RemoteControlParticipant {
237 193
      * @returns {void}
238 194
      */
239 195
     deny(userId: string) {
240
-        this.sendRemoteControlEvent(userId, {
241
-            type: EVENT_TYPES.permissions,
196
+        this.sendRemoteControlEndpointMessage(userId, {
197
+            type: EVENTS.permissions,
242 198
             action: PERMISSIONS_ACTIONS.deny
243 199
         });
244 200
     }
@@ -255,50 +211,63 @@ export default class Receiver extends RemoteControlParticipant {
255 211
             this._userLeftListener);
256 212
         this._controller = userId;
257 213
         logger.log(`Remote control permissions granted to: ${userId}`);
214
+
215
+        let promise;
216
+
258 217
         if (APP.conference.isSharingScreen) {
259
-            this.sendRemoteControlEvent(userId, {
260
-                type: EVENT_TYPES.permissions,
261
-                action: PERMISSIONS_ACTIONS.grant
262
-            });
218
+            promise = this._sendStartRequest();
263 219
         } else {
264
-            APP.conference.toggleScreenSharing()
265
-                .then(() => {
266
-                    if (APP.conference.isSharingScreen) {
267
-                        this.sendRemoteControlEvent(userId, {
268
-                            type: EVENT_TYPES.permissions,
269
-                            action: PERMISSIONS_ACTIONS.grant
270
-                        });
271
-                    } else {
272
-                        this.sendRemoteControlEvent(userId, {
273
-                            type: EVENT_TYPES.permissions,
274
-                            action: PERMISSIONS_ACTIONS.error
275
-                        });
276
-                    }
220
+            promise = APP.conference.toggleScreenSharing()
221
+                .then(() => this._sendStartRequest());
222
+        }
223
+
224
+        promise
225
+            .then(() =>
226
+                this.sendRemoteControlEndpointMessage(userId, {
227
+                    type: EVENTS.permissions,
228
+                    action: PERMISSIONS_ACTIONS.grant
277 229
                 })
278
-                .catch(() => {
279
-                    this.sendRemoteControlEvent(userId, {
280
-                        type: EVENT_TYPES.permissions,
281
-                        action: PERMISSIONS_ACTIONS.error
282
-                    });
230
+            )
231
+            .catch(() => {
232
+                this.sendRemoteControlEndpointMessage(userId, {
233
+                    type: EVENTS.permissions,
234
+                    action: PERMISSIONS_ACTIONS.error
283 235
                 });
284
-        }
236
+
237
+                // FIXME: show err msg
238
+                this._stop();
239
+            });
240
+    }
241
+
242
+    /**
243
+     * Sends remote control start request.
244
+     *
245
+     * @returns {Promise}
246
+     */
247
+    _sendStartRequest() {
248
+        return transport.sendRequest({
249
+            name: REMOTE_CONTROL_MESSAGE_NAME,
250
+            type: REQUESTS.start,
251
+            sourceId: APP.conference.getDesktopSharingSourceId()
252
+        });
285 253
     }
286 254
 
287 255
     /**
288 256
      * Handles remote control events from the external app. Currently only
289
-     * events with type = EVENT_TYPES.supported or EVENT_TYPES.permissions.
257
+     * events with type EVENTS.supported and EVENTS.stop are
258
+     * supported.
290 259
      *
291 260
      * @param {RemoteControlEvent} event - The remote control event.
292 261
      * @returns {void}
293 262
      */
294 263
     _onRemoteControlAPIEvent(event: Object) {
295 264
         switch (event.type) {
296
-        case EVENT_TYPES.permissions:
297
-            this._onRemoteControlPermissionsEvent(event.userId, event.action);
298
-            break;
299
-        case EVENT_TYPES.supported:
265
+        case EVENTS.supported:
300 266
             this._onRemoteControlSupported();
301 267
             break;
268
+        case EVENTS.stop:
269
+            this.stop();
270
+            break;
302 271
         }
303 272
     }
304 273
 

+ 4
- 4
modules/remotecontrol/RemoteControlParticipant.js 查看文件

@@ -3,7 +3,7 @@
3 3
 import { getLogger } from 'jitsi-meet-logger';
4 4
 
5 5
 import {
6
-    REMOTE_CONTROL_EVENT_NAME
6
+    REMOTE_CONTROL_MESSAGE_NAME
7 7
 } from '../../service/remotecontrol/Constants';
8 8
 
9 9
 const logger = getLogger(__filename);
@@ -34,14 +34,14 @@ export default class RemoteControlParticipant {
34 34
     }
35 35
 
36 36
     /**
37
-     * Sends remote control event to other participant trough data channel.
37
+     * Sends remote control message to other participant trough data channel.
38 38
      *
39 39
      * @param {string} to - The participant who will receive the event.
40 40
      * @param {RemoteControlEvent} event - The remote control event.
41 41
      * @param {Function} onDataChannelFail - Handler for data channel failure.
42 42
      * @returns {void}
43 43
      */
44
-    sendRemoteControlEvent(
44
+    sendRemoteControlEndpointMessage(
45 45
             to: ?string,
46 46
             event: Object,
47 47
             onDataChannelFail: ?Function) {
@@ -55,7 +55,7 @@ export default class RemoteControlParticipant {
55 55
         }
56 56
         try {
57 57
             APP.conference.sendEndpointMessage(to, {
58
-                name: REMOTE_CONTROL_EVENT_NAME,
58
+                name: REMOTE_CONTROL_MESSAGE_NAME,
59 59
                 ...event
60 60
             });
61 61
         } catch (e) {

+ 18
- 8
service/remotecontrol/Constants.js 查看文件

@@ -5,11 +5,11 @@ export const DISCO_REMOTE_CONTROL_FEATURE
5 5
     = "http://jitsi.org/meet/remotecontrol";
6 6
 
7 7
 /**
8
- * Types of remote-control-event events.
8
+ * Types of remote-control events.
9 9
   * @readonly
10 10
   * @enum {string}
11 11
  */
12
-export const EVENT_TYPES = {
12
+export const EVENTS = {
13 13
     mousemove: "mousemove",
14 14
     mousedown: "mousedown",
15 15
     mouseup: "mouseup",
@@ -18,10 +18,20 @@ export const EVENT_TYPES = {
18 18
     keydown: "keydown",
19 19
     keyup: "keyup",
20 20
     permissions: "permissions",
21
+    start: "start",
21 22
     stop: "stop",
22 23
     supported: "supported"
23 24
 };
24 25
 
26
+/**
27
+ * Types of remote-control requests.
28
+  * @readonly
29
+  * @enum {string}
30
+ */
31
+export const REQUESTS = {
32
+    start: "start"
33
+};
34
+
25 35
 /**
26 36
  * Actions for the remote control permission events.
27 37
  * @readonly
@@ -35,20 +45,20 @@ export const PERMISSIONS_ACTIONS = {
35 45
 };
36 46
 
37 47
 /**
38
- * The type of remote control events sent trough the API module.
48
+ * The type of remote control messages.
39 49
  */
40
-export const REMOTE_CONTROL_EVENT_NAME = "remote-control-event";
50
+export const REMOTE_CONTROL_MESSAGE_NAME = "remote-control";
41 51
 
42 52
 /**
43 53
  * The remote control event.
44 54
  * @typedef {object} RemoteControlEvent
45
- * @property {EVENT_TYPES} type - the type of the event
46
- * @property {int} x - avaibale for type === mousemove only. The new x
55
+ * @property {EVENTS | REQUESTS} type - the type of the message
56
+ * @property {number} x - avaibale for type === mousemove only. The new x
47 57
  * coordinate of the mouse
48
- * @property {int} y - For mousemove type - the new y
58
+ * @property {number} y - For mousemove type - the new y
49 59
  * coordinate of the mouse and for mousescroll - represents the vertical
50 60
  * scrolling diff value
51
- * @property {int} button - 1(left), 2(middle) or 3 (right). Supported by
61
+ * @property {number} button - 1(left), 2(middle) or 3 (right). Supported by
52 62
  * mousedown, mouseup and mousedblclick types.
53 63
  * @property {KEYS} key - Represents the key related to the event. Supported by
54 64
  * keydown and keyup types.

Loading…
取消
儲存