Explorar el Código

feat(remotecontrol): announce remotecontrol support

j8
hristoterezov hace 8 años
padre
commit
0f33e59e4d

+ 3
- 3
app.js Ver fichero

@@ -22,8 +22,7 @@ import conference from './conference';
22 22
 import API from './modules/API/API';
23 23
 
24 24
 import translation from "./modules/translation/translation";
25
-// For remote control testing:
26
-// import remoteControlController from "./modules/remotecontrol/Controller";
25
+import remoteControl from "./modules/remotecontrol/remotecontrol";
27 26
 
28 27
 const APP = {
29 28
     // Used by do_external_connect.js if we receive the attach data after
@@ -61,7 +60,8 @@ const APP = {
61 60
      */
62 61
     ConferenceUrl : null,
63 62
     connection: null,
64
-    API
63
+    API,
64
+    remoteControl
65 65
 };
66 66
 
67 67
 // TODO The execution of the mobile app starts from react/index.native.js.

+ 1
- 0
conference.js Ver fichero

@@ -488,6 +488,7 @@ export default {
488 488
             }).then(([tracks, con]) => {
489 489
                 logger.log('initialized with %s local tracks', tracks.length);
490 490
                 APP.connection = connection = con;
491
+                APP.remoteControl.init();
491 492
                 this._bindConnectionFailedHandler(con);
492 493
                 this._createRoom(tracks);
493 494
                 this.isDesktopSharingEnabled =

+ 31
- 14
modules/API/API.js Ver fichero

@@ -55,7 +55,9 @@ function initCommands() {
55 55
             APP.conference.toggleScreenSharing.bind(APP.conference),
56 56
         "video-hangup": () => APP.conference.hangup(),
57 57
         "email": APP.conference.changeLocalEmail,
58
-        "avatar-url": APP.conference.changeLocalAvatarUrl
58
+        "avatar-url": APP.conference.changeLocalAvatarUrl,
59
+        "remote-control-supported": isSupported =>
60
+            APP.remoteControl.onRemoteControlSupported(isSupported)
59 61
     };
60 62
     Object.keys(commands).forEach(function (key) {
61 63
         postis.listen(key, args => commands[key](...args));
@@ -94,7 +96,13 @@ function triggerEvent (name, object) {
94 96
     }
95 97
 }
96 98
 
97
-export default {
99
+class API {
100
+    /**
101
+     * Constructs new instance
102
+     * @constructor
103
+     */
104
+    constructor() { }
105
+
98 106
     /**
99 107
      * Initializes the APIConnector. Setups message event listeners that will
100 108
      * receive information from external applications that embed Jitsi Meet.
@@ -108,6 +116,13 @@ export default {
108 116
             return;
109 117
 
110 118
         enabled = true;
119
+    }
120
+
121
+    /**
122
+     * initializes postis library.
123
+     * @private
124
+     */
125
+    _initPostis() {
111 126
         let postisOptions = {
112 127
             window: target
113 128
         };
@@ -116,7 +131,7 @@ export default {
116 131
                 = "jitsi_meet_external_api_" + jitsi_meet_external_api_id;
117 132
         postis = postisInit(postisOptions);
118 133
         initCommands();
119
-    },
134
+    }
120 135
 
121 136
     /**
122 137
      * Notify external application (if API is enabled) that message was sent.
@@ -124,7 +139,7 @@ export default {
124 139
      */
125 140
     notifySendingChatMessage (body) {
126 141
         triggerEvent("outgoing-message", {"message": body});
127
-    },
142
+    }
128 143
 
129 144
     /**
130 145
      * Notify external application (if API is enabled) that
@@ -143,7 +158,7 @@ export default {
143 158
             "incoming-message",
144 159
             {"from": id, "nick": nick, "message": body, "stamp": ts}
145 160
         );
146
-    },
161
+    }
147 162
 
148 163
     /**
149 164
      * Notify external application (if API is enabled) that
@@ -152,7 +167,7 @@ export default {
152 167
      */
153 168
     notifyUserJoined (id) {
154 169
         triggerEvent("participant-joined", {id});
155
-    },
170
+    }
156 171
 
157 172
     /**
158 173
      * Notify external application (if API is enabled) that
@@ -161,7 +176,7 @@ export default {
161 176
      */
162 177
     notifyUserLeft (id) {
163 178
         triggerEvent("participant-left", {id});
164
-    },
179
+    }
165 180
 
166 181
     /**
167 182
      * Notify external application (if API is enabled) that
@@ -171,7 +186,7 @@ export default {
171 186
      */
172 187
     notifyDisplayNameChanged (id, displayName) {
173 188
         triggerEvent("display-name-change", {id, displayname: displayName});
174
-    },
189
+    }
175 190
 
176 191
     /**
177 192
      * Notify external application (if API is enabled) that
@@ -181,7 +196,7 @@ export default {
181 196
      */
182 197
     notifyConferenceJoined (room) {
183 198
         triggerEvent("video-conference-joined", {roomName: room});
184
-    },
199
+    }
185 200
 
186 201
     /**
187 202
      * Notify external application (if API is enabled) that
@@ -191,7 +206,7 @@ export default {
191 206
      */
192 207
     notifyConferenceLeft (room) {
193 208
         triggerEvent("video-conference-left", {roomName: room});
194
-    },
209
+    }
195 210
 
196 211
     /**
197 212
      * Notify external application (if API is enabled) that
@@ -199,7 +214,7 @@ export default {
199 214
      */
200 215
     notifyReadyToClose () {
201 216
         triggerEvent("video-ready-to-close", {});
202
-    },
217
+    }
203 218
 
204 219
     /**
205 220
      * Sends remote control event.
@@ -207,13 +222,15 @@ export default {
207 222
      */
208 223
     sendRemoteControlEvent(event) {
209 224
         sendMessage({method: "remote-control-event", params: event});
210
-    },
225
+    }
211 226
 
212 227
     /**
213 228
      * Removes the listeners.
214 229
      */
215
-    dispose: function () {
230
+    dispose () {
216 231
         if(enabled)
217 232
             postis.destroy();
218 233
     }
219
-};
234
+}
235
+
236
+export default new API();

+ 33
- 17
modules/remotecontrol/Controller.js Ver fichero

@@ -1,5 +1,7 @@
1 1
 /* global $, APP */
2 2
 import * as KeyCodes from "../keycode/keycode";
3
+import {EVENT_TYPES, API_EVENT_TYPE}
4
+    from "../../service/remotecontrol/Constants";
3 5
 
4 6
 /**
5 7
  * Extract the keyboard key from the keyboard event.
@@ -42,11 +44,21 @@ function getModifiers(event) {
42 44
  * It listens for mouse and keyboard events and sends them to the receiver
43 45
  * party of the remote control session.
44 46
  */
45
-class Controller {
47
+export default class Controller {
46 48
     /**
47 49
      * Creates new instance.
48 50
      */
49
-    constructor() {}
51
+    constructor() {
52
+        this.enabled = false;
53
+    }
54
+
55
+    /**
56
+     * Enables / Disables the remote control
57
+     * @param {boolean} enabled the new state.
58
+     */
59
+    enable(enabled) {
60
+        this.enabled = enabled;
61
+    }
50 62
 
51 63
     /**
52 64
      * Starts processing the mouse and keyboard events.
@@ -54,29 +66,34 @@ class Controller {
54 66
      * attaching the listeners on.
55 67
      */
56 68
     start(area) {
69
+        if(!this.enabled)
70
+            return;
57 71
         this.area = area;
58 72
         this.area.mousemove(event => {
59 73
             const position = this.area.position();
60
-            this._sendEvent({
61
-                type: "mousemove",
74
+            this._sendRemoteControlEvent({
75
+                type: EVENT_TYPES.mousemove,
62 76
                 x: (event.pageX - position.left)/this.area.width(),
63 77
                 y: (event.pageY - position.top)/this.area.height()
64 78
             });
65 79
         });
66
-        this.area.mousedown(this._onMouseClickHandler.bind(this, "mousedown"));
67
-        this.area.mouseup(this._onMouseClickHandler.bind(this, "mouseup"));
80
+        this.area.mousedown(this._onMouseClickHandler.bind(this,
81
+            EVENT_TYPES.mousedown));
82
+        this.area.mouseup(this._onMouseClickHandler.bind(this,
83
+            EVENT_TYPES.mouseup));
68 84
         this.area.dblclick(
69
-            this._onMouseClickHandler.bind(this, "mousedblclick"));
85
+            this._onMouseClickHandler.bind(this, EVENT_TYPES.mousedblclick));
70 86
         this.area.contextmenu(() => false);
71 87
         this.area[0].onmousewheel = event => {
72
-            this._sendEvent({
73
-                type: "mousescroll",
88
+            this._sendRemoteControlEvent({
89
+                type: EVENT_TYPES.mousescroll,
74 90
                 x: event.deltaX,
75 91
                 y: event.deltaY
76 92
             });
77 93
         };
78
-        $(window).keydown(this._onKeyPessHandler.bind(this, "keydown"));
79
-        $(window).keyup(this._onKeyPessHandler.bind(this, "keyup"));
94
+        $(window).keydown(this._onKeyPessHandler.bind(this,
95
+            EVENT_TYPES.keydown));
96
+        $(window).keyup(this._onKeyPessHandler.bind(this, EVENT_TYPES.keyup));
80 97
     }
81 98
 
82 99
     /**
@@ -99,7 +116,7 @@ class Controller {
99 116
      * @param {Event} event the mouse event.
100 117
      */
101 118
     _onMouseClickHandler(type, event) {
102
-        this._sendEvent({
119
+        this._sendRemoteControlEvent({
103 120
             type: type,
104 121
             button: event.which
105 122
         });
@@ -111,7 +128,7 @@ class Controller {
111 128
      * @param {Event} event the key event.
112 129
      */
113 130
     _onKeyPessHandler(type, event) {
114
-        this._sendEvent({
131
+        this._sendRemoteControlEvent({
115 132
             type: type,
116 133
             key: getKey(event),
117 134
             modifiers: getModifiers(event),
@@ -123,14 +140,13 @@ class Controller {
123 140
      * @param {Object} event the remote control event.
124 141
      */
125 142
     _sendRemoteControlEvent(event) {
143
+        if(!this.enabled)
144
+            return;
126 145
         try{
127 146
             APP.conference.sendEndpointMessage("",
128
-                {type: "remote-control-event", event});
147
+                {type: API_EVENT_TYPE, event});
129 148
         } catch (e) {
130 149
             // failed to send the event.
131 150
         }
132 151
     }
133 152
 }
134
-
135
-
136
-export default new Controller();

+ 25
- 8
modules/remotecontrol/Receiver.js Ver fichero

@@ -1,4 +1,7 @@
1 1
 /* global APP, JitsiMeetJS */
2
+import {DISCO_REMOTE_CONTROL_FEATURE, API_EVENT_TYPE}
3
+    from "../../service/remotecontrol/Constants";
4
+
2 5
 const ConferenceEvents = JitsiMeetJS.events.conference;
3 6
 
4 7
 /**
@@ -7,20 +10,36 @@ const ConferenceEvents = JitsiMeetJS.events.conference;
7 10
  * API module. From there the events can be received from wrapper application
8 11
  * and executed.
9 12
  */
10
-class Receiver {
13
+export default class Receiver {
11 14
     /**
12 15
      * Creates new instance.
13 16
      * @constructor
14 17
      */
15
-    constructor() {}
18
+    constructor() {
19
+        this.enabled = false;
20
+    }
21
+
22
+    /**
23
+     * Enables / Disables the remote control
24
+     * @param {boolean} enabled the new state.
25
+     */
26
+    enable(enabled) {
27
+        if(this.enabled !== enabled && enabled === true) {
28
+            this.enabled = enabled;
29
+            // Announce remote control support.
30
+            APP.connection.addFeature(DISCO_REMOTE_CONTROL_FEATURE, true);
31
+        }
32
+    }
16 33
 
17 34
     /**
18 35
      * Attaches listener for ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED events.
19 36
      */
20 37
     start() {
21
-        APP.conference.addConferenceListener(
22
-            ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
23
-            this._onRemoteControlEvent);
38
+        if(this.enabled) {
39
+            APP.conference.addConferenceListener(
40
+                ConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
41
+                this._onRemoteControlEvent);
42
+        }
24 43
     }
25 44
 
26 45
     /**
@@ -39,9 +58,7 @@ class Receiver {
39 58
      * @param {Object} event the remote control event.
40 59
      */
41 60
     _onRemoteControlEvent(participant, event) {
42
-        if(event.type === "remote-control-event")
61
+        if(event.type === API_EVENT_TYPE && this.enabled)
43 62
             APP.API.sendRemoteControlEvent(event.event);
44 63
     }
45 64
 }
46
-
47
-export default new Receiver();

+ 51
- 0
modules/remotecontrol/RemoteControl.js Ver fichero

@@ -0,0 +1,51 @@
1
+/* global APP, config */
2
+import Controller from "./Controller";
3
+import Receiver from "./Receiver";
4
+
5
+/**
6
+ * Implements the remote control functionality.
7
+ */
8
+class RemoteControl {
9
+    /**
10
+     * Constructs new instance. Creates controller and receiver properties.
11
+     * @constructor
12
+     */
13
+    constructor() {
14
+        this.controller = new Controller();
15
+        this.receiver = new Receiver();
16
+        this.enabled = false;
17
+        this.initialized = false;
18
+    }
19
+
20
+    /**
21
+     * Initializes the remote control - checks if the remote control should be
22
+     * enabled or not, initializes the API module.
23
+     */
24
+    init() {
25
+        if(config.disableRemoteControl || this.initialized) {
26
+            return;
27
+        }
28
+        this.initialized = true;
29
+        APP.API.init({
30
+            forceEnable: true,
31
+        });
32
+        this.controller.enable(true);
33
+    }
34
+
35
+    /**
36
+     * Handles API event for support for executing remote control events into
37
+     * the wrapper application.
38
+     * @param {boolean} isSupported true if the receiver side is supported by
39
+     * the wrapper application.
40
+     */
41
+    onRemoteControlSupported(isSupported) {
42
+        if(isSupported && !config.disableRemoteControl) {
43
+            this.enabled = true;
44
+            if(this.initialized) {
45
+                this.receiver.enable(true);
46
+            }
47
+        }
48
+    }
49
+}
50
+
51
+export default new RemoteControl();

+ 0
- 4
modules/tokendata/TokenData.js Ver fichero

@@ -73,10 +73,6 @@ class TokenData{
73 73
 
74 74
         this.jwt = jwt;
75 75
 
76
-        //External API settings
77
-        this.externalAPISettings = {
78
-            forceEnable: true
79
-        };
80 76
         this._decode();
81 77
         // Use JWT param as token if there is not other token set and if the
82 78
         // iss field is not anonymous. If you want to pass data with JWT token

+ 1
- 1
react/features/app/functions.web.js Ver fichero

@@ -23,7 +23,7 @@ export function init() {
23 23
 
24 24
     APP.keyboardshortcut = KeyboardShortcut;
25 25
     APP.tokenData = getTokenData();
26
-    APP.API.init(APP.tokenData.externalAPISettings);
26
+    APP.API.init(APP.tokenData.jwt ? {forceEnable: true} : undefined);
27 27
 
28 28
     APP.translation.init(settings.getLanguage());
29 29
 }

+ 23
- 0
service/remotecontrol/Constants.js Ver fichero

@@ -0,0 +1,23 @@
1
+/**
2
+ * The value for the "var" attribute of feature tag in disco-info packets.
3
+ */
4
+export const DISCO_REMOTE_CONTROL_FEATURE
5
+    = "http://jitsi.org/meet/remotecontrol";
6
+
7
+/**
8
+ * Types of remote-control-event events.
9
+ */
10
+export const EVENT_TYPES = {
11
+    mousemove: "mousemove",
12
+    mousedown: "mousedown",
13
+    mouseup: "mouseup",
14
+    mousedblclick: "mousedblclick",
15
+    mousescroll: "mousescroll",
16
+    keydown: "keydown",
17
+    keyup: "keyup"
18
+};
19
+
20
+/**
21
+ * The type of remote control events sent trough the API module.
22
+ */
23
+export const API_EVENT_TYPE = "remote-control-event";

Loading…
Cancelar
Guardar