|
|
@@ -140,7 +140,8 @@ class ExternalAPIModule extends ReactContextBaseJavaModule {
|
|
140
|
140
|
}
|
|
141
|
141
|
|
|
142
|
142
|
/**
|
|
143
|
|
- * Dispatches an event that occurred on JavaScript to the view's listener.
|
|
|
143
|
+ * Dispatches an event that occurred on the JavaScript side of the SDK to
|
|
|
144
|
+ * the specified {@link JitsiMeetView}'s listener.
|
|
144
|
145
|
*
|
|
145
|
146
|
* @param name The name of the event.
|
|
146
|
147
|
* @param data The details/specifics of the event to send determined
|
|
|
@@ -151,50 +152,81 @@ class ExternalAPIModule extends ReactContextBaseJavaModule {
|
|
151
|
152
|
public void sendEvent(final String name,
|
|
152
|
153
|
final ReadableMap data,
|
|
153
|
154
|
final String scope) {
|
|
154
|
|
- UiThreadUtil.runOnUiThread(new Runnable() {
|
|
155
|
|
- @Override
|
|
156
|
|
- public void run() {
|
|
157
|
|
- // The JavaScript App needs to provide uniquely identifying
|
|
158
|
|
- // information to the native ExternalAPI module so that the
|
|
159
|
|
- // latter may match the former to the native JitsiMeetView which
|
|
160
|
|
- // hosts it.
|
|
161
|
|
- JitsiMeetView view
|
|
162
|
|
- = JitsiMeetView.findViewByExternalAPIScope(scope);
|
|
163
|
|
-
|
|
164
|
|
- if (view == null) {
|
|
165
|
|
- return;
|
|
|
155
|
+ // The JavaScript App needs to provide uniquely identifying information
|
|
|
156
|
+ // to the native ExternalAPI module so that the latter may match the
|
|
|
157
|
+ // former to the native JitsiMeetView which hosts it.
|
|
|
158
|
+ JitsiMeetView view = JitsiMeetView.findViewByExternalAPIScope(scope);
|
|
|
159
|
+
|
|
|
160
|
+ if (view == null) {
|
|
|
161
|
+ return;
|
|
|
162
|
+ }
|
|
|
163
|
+
|
|
|
164
|
+ // XXX The JitsiMeetView property URL was introduced in order to address
|
|
|
165
|
+ // an exception in the Picture-in-Picture functionality which arose
|
|
|
166
|
+ // because of delays related to bridging between JavaScript and Java. To
|
|
|
167
|
+ // reduce these delays do not wait for the call to be transfered to the
|
|
|
168
|
+ // UI thread.
|
|
|
169
|
+ maybeSetViewURL(name, data, view);
|
|
|
170
|
+
|
|
|
171
|
+ // Make sure JitsiMeetView's listener is invoked on the UI thread. It
|
|
|
172
|
+ // was requested by SDK consumers.
|
|
|
173
|
+ if (UiThreadUtil.isOnUiThread()) {
|
|
|
174
|
+ sendEventOnUiThread(name, data, scope);
|
|
|
175
|
+ } else {
|
|
|
176
|
+ UiThreadUtil.runOnUiThread(new Runnable() {
|
|
|
177
|
+ @Override
|
|
|
178
|
+ public void run() {
|
|
|
179
|
+ sendEventOnUiThread(name, data, scope);
|
|
166
|
180
|
}
|
|
|
181
|
+ });
|
|
|
182
|
+ }
|
|
|
183
|
+ }
|
|
|
184
|
+
|
|
|
185
|
+ /**
|
|
|
186
|
+ * Dispatches an event that occurred on the JavaScript side of the SDK to
|
|
|
187
|
+ * the specified {@link JitsiMeetView}'s listener on the UI thread.
|
|
|
188
|
+ *
|
|
|
189
|
+ * @param name The name of the event.
|
|
|
190
|
+ * @param data The details/specifics of the event to send determined
|
|
|
191
|
+ * by/associated with the specified {@code name}.
|
|
|
192
|
+ * @param scope
|
|
|
193
|
+ */
|
|
|
194
|
+ private void sendEventOnUiThread(final String name,
|
|
|
195
|
+ final ReadableMap data,
|
|
|
196
|
+ final String scope) {
|
|
|
197
|
+ // The JavaScript App needs to provide uniquely identifying information
|
|
|
198
|
+ // to the native ExternalAPI module so that the latter may match the
|
|
|
199
|
+ // former to the native JitsiMeetView which hosts it.
|
|
|
200
|
+ JitsiMeetView view = JitsiMeetView.findViewByExternalAPIScope(scope);
|
|
167
|
201
|
|
|
168
|
|
- maybeSetViewURL(name, data, view);
|
|
|
202
|
+ if (view == null) {
|
|
|
203
|
+ return;
|
|
|
204
|
+ }
|
|
169
|
205
|
|
|
170
|
|
- JitsiMeetViewListener listener = view.getListener();
|
|
|
206
|
+ JitsiMeetViewListener listener = view.getListener();
|
|
171
|
207
|
|
|
172
|
|
- if (listener == null) {
|
|
173
|
|
- return;
|
|
174
|
|
- }
|
|
|
208
|
+ if (listener == null) {
|
|
|
209
|
+ return;
|
|
|
210
|
+ }
|
|
175
|
211
|
|
|
176
|
|
- Method method = JITSI_MEET_VIEW_LISTENER_METHODS.get(name);
|
|
177
|
|
-
|
|
178
|
|
- if (method != null) {
|
|
179
|
|
- try {
|
|
180
|
|
- method.invoke(listener, toHashMap(data));
|
|
181
|
|
- } catch (IllegalAccessException e) {
|
|
182
|
|
- // FIXME There was a multicatch for
|
|
183
|
|
- // IllegalAccessException and InvocationTargetException,
|
|
184
|
|
- // but Android Studio complained with: "Multi-catch with
|
|
185
|
|
- // these reflection exceptions requires API level 19
|
|
186
|
|
- // (current min is 16) because they get compiled to the
|
|
187
|
|
- // common but new super type
|
|
188
|
|
- // ReflectiveOperationException. As a workaround either
|
|
189
|
|
- // create individual catch statements, or
|
|
190
|
|
- // catch Exception."
|
|
191
|
|
- throw new RuntimeException(e);
|
|
192
|
|
- } catch (InvocationTargetException e) {
|
|
193
|
|
- throw new RuntimeException(e);
|
|
194
|
|
- }
|
|
195
|
|
- }
|
|
|
212
|
+ Method method = JITSI_MEET_VIEW_LISTENER_METHODS.get(name);
|
|
|
213
|
+
|
|
|
214
|
+ if (method != null) {
|
|
|
215
|
+ try {
|
|
|
216
|
+ method.invoke(listener, toHashMap(data));
|
|
|
217
|
+ } catch (IllegalAccessException e) {
|
|
|
218
|
+ // FIXME There was a multicatch for IllegalAccessException and
|
|
|
219
|
+ // InvocationTargetException, but Android Studio complained
|
|
|
220
|
+ // with: "Multi-catch with these reflection exceptions requires
|
|
|
221
|
+ // API level 19 (current min is 16) because they get compiled to
|
|
|
222
|
+ // the common but new super type ReflectiveOperationException.
|
|
|
223
|
+ // As a workaround either create individual catch statements, or
|
|
|
224
|
+ // catch Exception."
|
|
|
225
|
+ throw new RuntimeException(e);
|
|
|
226
|
+ } catch (InvocationTargetException e) {
|
|
|
227
|
+ throw new RuntimeException(e);
|
|
196
|
228
|
}
|
|
197
|
|
- });
|
|
|
229
|
+ }
|
|
198
|
230
|
}
|
|
199
|
231
|
|
|
200
|
232
|
/**
|