Browse Source

feat(mobile) adds ToggleScreenShare event and action.

j8
Titus-Andrei Moldovan 4 years ago
parent
commit
45f4643469

+ 2
- 1
android/sdk/src/main/java/org/jitsi/meet/sdk/BroadcastAction.java View File

61
     enum Type {
61
     enum Type {
62
         SET_AUDIO_MUTED("org.jitsi.meet.SET_AUDIO_MUTED"),
62
         SET_AUDIO_MUTED("org.jitsi.meet.SET_AUDIO_MUTED"),
63
         HANG_UP("org.jitsi.meet.HANG_UP"),
63
         HANG_UP("org.jitsi.meet.HANG_UP"),
64
-        SEND_ENDPOINT_TEXT_MESSAGE("org.jitsi.meet.SEND_ENDPOINT_TEXT_MESSAGE");
64
+        SEND_ENDPOINT_TEXT_MESSAGE("org.jitsi.meet.SEND_ENDPOINT_TEXT_MESSAGE"),
65
+        TOGGLE_SCREEN_SHARE("org.jitsi.meet.TOGGLE_SCREEN_SHARE");
65
 
66
 
66
         private final String action;
67
         private final String action;
67
 
68
 

+ 5
- 1
android/sdk/src/main/java/org/jitsi/meet/sdk/BroadcastEvent.java View File

81
         AUDIO_MUTED_CHANGED("org.jitsi.meet.AUDIO_MUTED_CHANGED"),
81
         AUDIO_MUTED_CHANGED("org.jitsi.meet.AUDIO_MUTED_CHANGED"),
82
         PARTICIPANT_JOINED("org.jitsi.meet.PARTICIPANT_JOINED"),
82
         PARTICIPANT_JOINED("org.jitsi.meet.PARTICIPANT_JOINED"),
83
         PARTICIPANT_LEFT("org.jitsi.meet.PARTICIPANT_LEFT"),
83
         PARTICIPANT_LEFT("org.jitsi.meet.PARTICIPANT_LEFT"),
84
-        ENDPOINT_TEXT_MESSAGE_RECEIVED("org.jitsi.meet.ENDPOINT_TEXT_MESSAGE_RECEIVED");
84
+        ENDPOINT_TEXT_MESSAGE_RECEIVED("org.jitsi.meet.ENDPOINT_TEXT_MESSAGE_RECEIVED"),
85
+        SCREEN_SHARE_TOGGLED("org.jitsi.meet.SCREEN_SHARE_TOGGLED");
85
 
86
 
86
         private static final String CONFERENCE_WILL_JOIN_NAME = "CONFERENCE_WILL_JOIN";
87
         private static final String CONFERENCE_WILL_JOIN_NAME = "CONFERENCE_WILL_JOIN";
87
         private static final String CONFERENCE_JOINED_NAME = "CONFERENCE_JOINED";
88
         private static final String CONFERENCE_JOINED_NAME = "CONFERENCE_JOINED";
90
         private static final String PARTICIPANT_JOINED_NAME = "PARTICIPANT_JOINED";
91
         private static final String PARTICIPANT_JOINED_NAME = "PARTICIPANT_JOINED";
91
         private static final String PARTICIPANT_LEFT_NAME = "PARTICIPANT_LEFT";
92
         private static final String PARTICIPANT_LEFT_NAME = "PARTICIPANT_LEFT";
92
         private static final String ENDPOINT_TEXT_MESSAGE_RECEIVED_NAME = "ENDPOINT_TEXT_MESSAGE_RECEIVED";
93
         private static final String ENDPOINT_TEXT_MESSAGE_RECEIVED_NAME = "ENDPOINT_TEXT_MESSAGE_RECEIVED";
94
+        private static final String SCREEN_SHARE_TOGGLED_NAME= "SCREEN_SHARE_TOGGLED";
93
 
95
 
94
         private final String action;
96
         private final String action;
95
 
97
 
126
                     return PARTICIPANT_LEFT;
128
                     return PARTICIPANT_LEFT;
127
                 case ENDPOINT_TEXT_MESSAGE_RECEIVED_NAME:
129
                 case ENDPOINT_TEXT_MESSAGE_RECEIVED_NAME:
128
                     return ENDPOINT_TEXT_MESSAGE_RECEIVED;
130
                     return ENDPOINT_TEXT_MESSAGE_RECEIVED;
131
+                case SCREEN_SHARE_TOGGLED_NAME:
132
+                    return SCREEN_SHARE_TOGGLED;
129
             }
133
             }
130
 
134
 
131
             return null;
135
             return null;

+ 4
- 0
android/sdk/src/main/java/org/jitsi/meet/sdk/BroadcastIntentHelper.java View File

19
         intent.putExtra("message", message);
19
         intent.putExtra("message", message);
20
         return intent;
20
         return intent;
21
     }
21
     }
22
+
23
+    public static Intent buildToggleScreenShareIntent() {
24
+        return new Intent(BroadcastAction.Type.TOGGLE_SCREEN_SHARE.getAction());
25
+    }
22
 }
26
 }

+ 4
- 3
android/sdk/src/main/java/org/jitsi/meet/sdk/BroadcastReceiver.java View File

16
         LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
16
         LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
17
 
17
 
18
         IntentFilter intentFilter = new IntentFilter();
18
         IntentFilter intentFilter = new IntentFilter();
19
-        intentFilter.addAction(BroadcastAction.Type.SET_AUDIO_MUTED.getAction());
20
-        intentFilter.addAction(BroadcastAction.Type.HANG_UP.getAction());
21
-        intentFilter.addAction(BroadcastAction.Type.SEND_ENDPOINT_TEXT_MESSAGE.getAction());
19
+
20
+        for (BroadcastAction.Type type : BroadcastAction.Type.values()) {
21
+            intentFilter.addAction(type.getAction());
22
+        }
22
 
23
 
23
         localBroadcastManager.registerReceiver(this, intentFilter);
24
         localBroadcastManager.registerReceiver(this, intentFilter);
24
     }
25
     }

+ 1
- 0
android/sdk/src/main/java/org/jitsi/meet/sdk/ExternalAPIModule.java View File

78
         constants.put("SET_AUDIO_MUTED", BroadcastAction.Type.SET_AUDIO_MUTED.getAction());
78
         constants.put("SET_AUDIO_MUTED", BroadcastAction.Type.SET_AUDIO_MUTED.getAction());
79
         constants.put("HANG_UP", BroadcastAction.Type.HANG_UP.getAction());
79
         constants.put("HANG_UP", BroadcastAction.Type.HANG_UP.getAction());
80
         constants.put("SEND_ENDPOINT_TEXT_MESSAGE", BroadcastAction.Type.SEND_ENDPOINT_TEXT_MESSAGE.getAction());
80
         constants.put("SEND_ENDPOINT_TEXT_MESSAGE", BroadcastAction.Type.SEND_ENDPOINT_TEXT_MESSAGE.getAction());
81
+        constants.put("TOGGLE_SCREEN_SHARE", BroadcastAction.Type.TOGGLE_SCREEN_SHARE.getAction());
81
 
82
 
82
         return constants;
83
         return constants;
83
     }
84
     }

+ 4
- 6
android/sdk/src/main/java/org/jitsi/meet/sdk/JitsiMeetActivity.java View File

266
 
266
 
267
     private void registerForBroadcastMessages() {
267
     private void registerForBroadcastMessages() {
268
         IntentFilter intentFilter = new IntentFilter();
268
         IntentFilter intentFilter = new IntentFilter();
269
-        intentFilter.addAction(BroadcastEvent.Type.CONFERENCE_JOINED.getAction());
270
-        intentFilter.addAction(BroadcastEvent.Type.CONFERENCE_WILL_JOIN.getAction());
271
-        intentFilter.addAction(BroadcastEvent.Type.CONFERENCE_TERMINATED.getAction());
272
-        intentFilter.addAction(BroadcastEvent.Type.PARTICIPANT_JOINED.getAction());
273
-        intentFilter.addAction(BroadcastEvent.Type.PARTICIPANT_LEFT.getAction());
274
-        intentFilter.addAction(BroadcastEvent.Type.ENDPOINT_TEXT_MESSAGE_RECEIVED.getAction());
269
+
270
+        for (BroadcastEvent.Type type : BroadcastEvent.Type.values()) {
271
+            intentFilter.addAction(type.getAction());
272
+        }
275
 
273
 
276
         LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, intentFilter);
274
         LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, intentFilter);
277
     }
275
     }

+ 5
- 1
ios/app/src/ViewController.m View File

115
   NSLog(@"%@%@", @"Audio muted changed: ", data[@"muted"]);
115
   NSLog(@"%@%@", @"Audio muted changed: ", data[@"muted"]);
116
 }
116
 }
117
 
117
 
118
-- (void)endpointTextMessageReceived:(NSDictionary *)data; {
118
+- (void)endpointTextMessageReceived:(NSDictionary *)data {
119
   NSLog(@"%@%@", @"Endpoint text message received: ", data);
119
   NSLog(@"%@%@", @"Endpoint text message received: ", data);
120
 }
120
 }
121
 
121
 
122
+- (void)screenShareToggled:(NSDictionary *)data {
123
+  NSLog(@"%@%@", @"Screen share toggled: ", data);
124
+}
125
+
122
 #pragma mark - Helpers
126
 #pragma mark - Helpers
123
 
127
 
124
 - (void)terminate {
128
 - (void)terminate {

+ 1
- 0
ios/sdk/src/ExternalAPI.h View File

21
 - (void)sendHangUp;
21
 - (void)sendHangUp;
22
 - (void)sendSetAudioMuted: (BOOL)muted;
22
 - (void)sendSetAudioMuted: (BOOL)muted;
23
 - (void)sendEndpointTextMessage:(NSString*)to :(NSString*)message;
23
 - (void)sendEndpointTextMessage:(NSString*)to :(NSString*)message;
24
+- (void)toggleScreenShare;
24
 
25
 
25
 @end
26
 @end

+ 8
- 2
ios/sdk/src/ExternalAPI.m View File

21
 static NSString * const hangUpAction = @"org.jitsi.meet.HANG_UP";
21
 static NSString * const hangUpAction = @"org.jitsi.meet.HANG_UP";
22
 static NSString * const setAudioMutedAction = @"org.jitsi.meet.SET_AUDIO_MUTED";
22
 static NSString * const setAudioMutedAction = @"org.jitsi.meet.SET_AUDIO_MUTED";
23
 static NSString * const sendEndpointTextMessageAction = @"org.jitsi.meet.SEND_ENDPOINT_TEXT_MESSAGE";
23
 static NSString * const sendEndpointTextMessageAction = @"org.jitsi.meet.SEND_ENDPOINT_TEXT_MESSAGE";
24
+static NSString * const toggleScreenShareAction = @"org.jitsi.meet.TOGGLE_SCREEN_SHARE";
24
 
25
 
25
 @implementation ExternalAPI
26
 @implementation ExternalAPI
26
 
27
 
30
     return @{
31
     return @{
31
         @"HANG_UP": hangUpAction,
32
         @"HANG_UP": hangUpAction,
32
         @"SET_AUDIO_MUTED" : setAudioMutedAction,
33
         @"SET_AUDIO_MUTED" : setAudioMutedAction,
33
-        @"SEND_ENDPOINT_TEXT_MESSAGE": sendEndpointTextMessageAction
34
+        @"SEND_ENDPOINT_TEXT_MESSAGE": sendEndpointTextMessageAction,
35
+        @"TOGGLE_SCREEN_SHARE": toggleScreenShareAction
34
     };
36
     };
35
 };
37
 };
36
 
38
 
46
 }
48
 }
47
 
49
 
48
 - (NSArray<NSString *> *)supportedEvents {
50
 - (NSArray<NSString *> *)supportedEvents {
49
-    return @[ hangUpAction, setAudioMutedAction, sendEndpointTextMessageAction ];
51
+    return @[ hangUpAction, setAudioMutedAction, sendEndpointTextMessageAction, toggleScreenShareAction ];
50
 }
52
 }
51
 
53
 
52
 /**
54
 /**
123
     [self sendEventWithName:sendEndpointTextMessageAction body:data];
125
     [self sendEventWithName:sendEndpointTextMessageAction body:data];
124
 }
126
 }
125
 
127
 
128
+- (void)toggleScreenShare {
129
+    [self sendEventWithName:toggleScreenShareAction body:nil];
130
+}
131
+
126
 @end
132
 @end

+ 2
- 0
ios/sdk/src/JitsiMeetView.h View File

43
 
43
 
44
 - (void)sendEndpointTextMessage:(NSString*)to :(NSString*)message;
44
 - (void)sendEndpointTextMessage:(NSString*)to :(NSString*)message;
45
 
45
 
46
+- (void)toggleScreenShare;
47
+
46
 @end
48
 @end

+ 5
- 0
ios/sdk/src/JitsiMeetView.m View File

130
     [externalAPI sendEndpointTextMessage:to :message];
130
     [externalAPI sendEndpointTextMessage:to :message];
131
 }
131
 }
132
 
132
 
133
+- (void)toggleScreenShare {
134
+    ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
135
+    [externalAPI toggleScreenShare];
136
+}
137
+
133
 #pragma mark Private methods
138
 #pragma mark Private methods
134
 
139
 
135
 /**
140
 /**

+ 7
- 0
ios/sdk/src/JitsiMeetViewDelegate.h View File

83
  */
83
  */
84
 - (void)endpointTextMessageReceived:(NSDictionary *)data;
84
 - (void)endpointTextMessageReceived:(NSDictionary *)data;
85
 
85
 
86
+/**
87
+ * Called when a participant toggled shared screen.
88
+ *
89
+ * The `data` dictionary contains a `participantId` key with the id of the participant  and a 'sharing' key with boolean value.
90
+ */
91
+- (void)screenShareToggled:(NSDictionary *)data;
92
+
86
 @end
93
 @end

+ 1
- 0
react/features/app/reducers.native.js View File

4
 import '../mobile/audio-mode/reducer';
4
 import '../mobile/audio-mode/reducer';
5
 import '../mobile/background/reducer';
5
 import '../mobile/background/reducer';
6
 import '../mobile/call-integration/reducer';
6
 import '../mobile/call-integration/reducer';
7
+import '../mobile/external-api/reducer';
7
 import '../mobile/full-screen/reducer';
8
 import '../mobile/full-screen/reducer';
8
 import '../mobile/incoming-call/reducer';
9
 import '../mobile/incoming-call/reducer';
9
 import '../mobile/watchos/reducer';
10
 import '../mobile/watchos/reducer';

+ 11
- 0
react/features/mobile/external-api/actionTypes.js View File

1
+/**
2
+ * The type of the action which sets the list of known participant IDs which
3
+ * have an active screen share.
4
+ *
5
+ * @returns {{
6
+    *     type: SCREEN_SHARE_PARTICIPANTS_UPDATED,
7
+    *     participantIds: Array<string>
8
+    * }}
9
+    */
10
+export const SCREEN_SHARE_PARTICIPANTS_UPDATED
11
+    = 'SCREEN_SHARE_PARTICIPANTS_UPDATED';

+ 21
- 0
react/features/mobile/external-api/actions.js View File

1
+// @flow
2
+
3
+import { SCREEN_SHARE_PARTICIPANTS_UPDATED } from './actionTypes';
4
+
5
+/**
6
+ * Creates a (redux) action which signals that the list of known participants
7
+ * with screen shares has changed.
8
+ *
9
+ * @param {string} participantIds - The participants which currently have active
10
+ * screen share streams.
11
+ * @returns {{
12
+    *     type: SCREEN_SHARE_PARTICIPANTS_UPDATED,
13
+    *     participantId: string
14
+    * }}
15
+    */
16
+export function setParticipantsWithScreenShare(participantIds: Array<string>) {
17
+    return {
18
+        type: SCREEN_SHARE_PARTICIPANTS_UPDATED,
19
+        participantIds
20
+    };
21
+}

+ 56
- 1
react/features/mobile/external-api/middleware.js View File

1
 // @flow
1
 // @flow
2
 
2
 
3
+import debounce from 'lodash/debounce';
3
 import { NativeEventEmitter, NativeModules } from 'react-native';
4
 import { NativeEventEmitter, NativeModules } from 'react-native';
4
 
5
 
5
 import { ENDPOINT_TEXT_MESSAGE_NAME } from '../../../../modules/API/constants';
6
 import { ENDPOINT_TEXT_MESSAGE_NAME } from '../../../../modules/API/constants';
27
 import { JitsiConferenceEvents } from '../../base/lib-jitsi-meet';
28
 import { JitsiConferenceEvents } from '../../base/lib-jitsi-meet';
28
 import { SET_AUDIO_MUTED } from '../../base/media/actionTypes';
29
 import { SET_AUDIO_MUTED } from '../../base/media/actionTypes';
29
 import { PARTICIPANT_JOINED, PARTICIPANT_LEFT } from '../../base/participants';
30
 import { PARTICIPANT_JOINED, PARTICIPANT_LEFT } from '../../base/participants';
30
-import { MiddlewareRegistry } from '../../base/redux';
31
+import { MiddlewareRegistry, StateListenerRegistry } from '../../base/redux';
32
+import { toggleScreensharing } from '../../base/tracks';
31
 import { muteLocal } from '../../remote-video-menu/actions';
33
 import { muteLocal } from '../../remote-video-menu/actions';
32
 import { ENTER_PICTURE_IN_PICTURE } from '../picture-in-picture';
34
 import { ENTER_PICTURE_IN_PICTURE } from '../picture-in-picture';
33
 
35
 
36
+import { setParticipantsWithScreenShare } from './actions';
34
 import { sendEvent } from './functions';
37
 import { sendEvent } from './functions';
35
 import logger from './logger';
38
 import logger from './logger';
36
 
39
 
46
  */
49
  */
47
 const ENDPOINT_TEXT_MESSAGE_RECEIVED = 'ENDPOINT_TEXT_MESSAGE_RECEIVED';
50
 const ENDPOINT_TEXT_MESSAGE_RECEIVED = 'ENDPOINT_TEXT_MESSAGE_RECEIVED';
48
 
51
 
52
+/**
53
+ * Event which will be emitted on the native side to indicate a participant togggles
54
+ * the screen share.
55
+ */
56
+const SCREEN_SHARE_TOGGLED = 'SCREEN_SHARE_TOGGLED';
57
+
49
 const { ExternalAPI } = NativeModules;
58
 const { ExternalAPI } = NativeModules;
50
 const eventEmitter = new NativeEventEmitter(ExternalAPI);
59
 const eventEmitter = new NativeEventEmitter(ExternalAPI);
51
 
60
 
171
     return result;
180
     return result;
172
 });
181
 });
173
 
182
 
183
+/**
184
+ * Listen for changes to the known media tracks and look
185
+ * for updates to screen shares for emitting native events.
186
+ * The listener is debounced to avoid state thrashing that might occur,
187
+ * especially when switching in or out of p2p.
188
+ */
189
+StateListenerRegistry.register(
190
+    /* selector */ state => state['features/base/tracks'],
191
+    /* listener */ debounce((tracks, store) => {
192
+        const oldScreenShares = store.getState()['features/mobile/external-api'].screenShares || [];
193
+        const newScreenShares = tracks
194
+            .filter(track => track.mediaType === 'video' && track.videoType === 'desktop')
195
+            .map(track => track.participantId);
196
+
197
+        oldScreenShares.forEach(participantId => {
198
+            if (!newScreenShares.includes(participantId)) {
199
+                sendEvent(
200
+                    store,
201
+                    SCREEN_SHARE_TOGGLED,
202
+                    /* data */ {
203
+                        participantId,
204
+                        sharing: false
205
+                    });
206
+            }
207
+        });
208
+
209
+        newScreenShares.forEach(participantId => {
210
+            if (!oldScreenShares.includes(participantId)) {
211
+                sendEvent(
212
+                    store,
213
+                    SCREEN_SHARE_TOGGLED,
214
+                    /* data */ {
215
+                        participantId,
216
+                        sharing: true
217
+                    });
218
+            }
219
+        });
220
+
221
+        store.dispatch(setParticipantsWithScreenShare(newScreenShares));
222
+
223
+    }, 100));
224
+
174
 /**
225
 /**
175
  * Registers for events sent from the native side via NativeEventEmitter.
226
  * Registers for events sent from the native side via NativeEventEmitter.
176
  *
227
  *
199
             logger.warn('Cannot send endpointMessage', error);
250
             logger.warn('Cannot send endpointMessage', error);
200
         }
251
         }
201
     });
252
     });
253
+
254
+    eventEmitter.addListener(ExternalAPI.TOGGLE_SCREEN_SHARE, () => {
255
+        dispatch(toggleScreensharing());
256
+    });
202
 }
257
 }
203
 
258
 
204
 /**
259
 /**

+ 22
- 0
react/features/mobile/external-api/reducer.js View File

1
+// @flow
2
+
3
+import { ReducerRegistry } from '../../base/redux';
4
+
5
+import { SCREEN_SHARE_PARTICIPANTS_UPDATED } from './actionTypes';
6
+
7
+const DEFAULT_STATE = {
8
+    screenShares: []
9
+};
10
+
11
+ReducerRegistry.register('features/mobile/external-api', (state = DEFAULT_STATE, action) => {
12
+    switch (action.type) {
13
+    case SCREEN_SHARE_PARTICIPANTS_UPDATED: {
14
+        return {
15
+            ...state,
16
+            screenShares: action.participantIds
17
+        };
18
+    }
19
+    }
20
+
21
+    return state;
22
+});

Loading…
Cancel
Save