Просмотр исходного кода

android: handle ConnectionService failures more resiliently

Some Samsung devices will fail to fully engage ConnectionService if no SIM card
was ever installed on the device. We could check for it, but it would require
the CALL_PHONE permission, which is not something we want to do, so fallback to
not using ConnectionService.
master
Saúl Ibarra Corretgé 5 лет назад
Родитель
Сommit
a622a4c713

+ 5
- 2
android/sdk/src/main/java/org/jitsi/meet/sdk/ConnectionService.java Просмотреть файл

123
      * {@link android.telecom.Connection#STATE_ACTIVE}.
123
      * {@link android.telecom.Connection#STATE_ACTIVE}.
124
      *
124
      *
125
      * @param callUUID the call UUID which identifies the connection.
125
      * @param callUUID the call UUID which identifies the connection.
126
+     * @return Whether the connection was set as active or not.
126
      */
127
      */
127
-    static void setConnectionActive(String callUUID) {
128
+    static boolean setConnectionActive(String callUUID) {
128
         ConnectionImpl connection = connections.get(callUUID);
129
         ConnectionImpl connection = connections.get(callUUID);
129
 
130
 
130
         if (connection != null) {
131
         if (connection != null) {
131
             connection.setActive();
132
             connection.setActive();
133
+            return true;
132
         } else {
134
         } else {
133
-            JitsiMeetLogger.e("%s setConnectionActive - no connection for UUID: %s", TAG, callUUID);
135
+            JitsiMeetLogger.w("%s setConnectionActive - no connection for UUID: %s", TAG, callUUID);
136
+            return false;
134
         }
137
         }
135
     }
138
     }
136
 
139
 

+ 5
- 2
android/sdk/src/main/java/org/jitsi/meet/sdk/RNConnectionService.java Просмотреть файл

158
     @ReactMethod
158
     @ReactMethod
159
     public void reportConnectedOutgoingCall(String callUUID, Promise promise) {
159
     public void reportConnectedOutgoingCall(String callUUID, Promise promise) {
160
         JitsiMeetLogger.d(TAG + " reportConnectedOutgoingCall " + callUUID);
160
         JitsiMeetLogger.d(TAG + " reportConnectedOutgoingCall " + callUUID);
161
-        ConnectionService.setConnectionActive(callUUID);
162
-        promise.resolve(null);
161
+        if (ConnectionService.setConnectionActive(callUUID)) {
162
+            promise.resolve(null);
163
+        } else {
164
+            promise.reject("CONNECTION_NOT_FOUND_ERROR", "Connection wasn't found.");
165
+        }
163
     }
166
     }
164
 
167
 
165
     @Override
168
     @Override

+ 50
- 17
react/features/mobile/call-integration/middleware.js Просмотреть файл

186
     const { callUUID } = action.conference;
186
     const { callUUID } = action.conference;
187
 
187
 
188
     if (callUUID) {
188
     if (callUUID) {
189
-        CallIntegration.reportConnectedOutgoingCall(callUUID).then(() => {
190
-            // iOS 13 doesn't like the mute state to be false before the call is started
191
-            // so we update it here in case the user selected startWithAudioMuted.
192
-            if (Platform.OS === 'ios') {
193
-                _updateCallIntegrationMuted(action.conference, getState());
194
-            }
195
-        });
189
+        CallIntegration.reportConnectedOutgoingCall(callUUID)
190
+            .then(() => {
191
+                // iOS 13 doesn't like the mute state to be false before the call is started
192
+                // so we update it here in case the user selected startWithAudioMuted.
193
+                if (Platform.OS === 'ios') {
194
+                    _updateCallIntegrationMuted(action.conference, getState());
195
+                }
196
+            })
197
+            .catch(error => {
198
+                // Currently this error code is emitted only by Android.
199
+                //
200
+                if (error.code === 'CONNECTION_NOT_FOUND_ERROR') {
201
+                    // Some Samsung devices will fail to fully engage ConnectionService if no SIM card
202
+                    // was ever installed on the device. We could check for it, but it would require
203
+                    // the CALL_PHONE permission, which is not something we want to do, so fallback to
204
+                    // not using ConnectionService.
205
+                    _handleConnectionServiceFailure(getState());
206
+                }
207
+            });
196
     }
208
     }
197
 
209
 
198
     return result;
210
     return result;
294
                     { cancelable: false });
306
                     { cancelable: false });
295
             } else if (error.code === 'SECURITY_ERROR') {
307
             } else if (error.code === 'SECURITY_ERROR') {
296
                 // Some devices fail because the CALL_PHONE permission is not granted, which is
308
                 // Some devices fail because the CALL_PHONE permission is not granted, which is
297
-                // nonsense, because it's not needed for self-managed connections. Alas, this also
298
-                // means audio device management would be broken, so fallback to not using ConnectionService.
299
-                // NOTE: We are not storing this in Settings, in case it's a transient issue, as far fetched as
300
-                // that may be.
301
-                if (AudioMode.setUseConnectionService) {
302
-                    AudioMode.setUseConnectionService(false);
303
-
304
-                    // Set the desired audio mode, since we just reset the whole thing.
305
-                    AudioMode.setMode(hasVideo ? AudioMode.VIDEO_CALL : AudioMode.AUDIO_CALL);
306
-                }
309
+                // nonsense, because it's not needed for self-managed connections.
310
+
311
+                _handleConnectionServiceFailure(state);
307
             }
312
             }
308
         });
313
         });
309
 
314
 
310
     return result;
315
     return result;
311
 }
316
 }
312
 
317
 
318
+/**
319
+ * Handles a ConnectionService fatal error by falling back to non-ConnectionService device management.
320
+ *
321
+ * @param {Object} state - Redux store.
322
+ * @returns {void}
323
+ */
324
+function _handleConnectionServiceFailure(state: Object) {
325
+    const conference = getCurrentConference(state);
326
+
327
+    if (conference) {
328
+        // We're not tracking the call anymore.
329
+        delete conference.callUUID;
330
+
331
+        // ConnectionService has fatally failed. Alas, this also means audio device management would be broken, so
332
+        // fallback to not using ConnectionService.
333
+        // NOTE: We are not storing this in Settings, in case it's a transient issue, as far fetched as
334
+        // that may be.
335
+        if (AudioMode.setUseConnectionService) {
336
+            AudioMode.setUseConnectionService(false);
337
+
338
+            const hasVideo = !isVideoMutedByAudioOnly(state);
339
+
340
+            // Set the desired audio mode, since we just reset the whole thing.
341
+            AudioMode.setMode(hasVideo ? AudioMode.VIDEO_CALL : AudioMode.AUDIO_CALL);
342
+        }
343
+    }
344
+}
345
+
313
 /**
346
 /**
314
  * Handles CallKit's event {@code performEndCallAction}.
347
  * Handles CallKit's event {@code performEndCallAction}.
315
  *
348
  *

Загрузка…
Отмена
Сохранить