From 58bd48c1ae2c4407dea0d55279056391634965de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= <saghul@jitsi.org> Date: Wed, 27 Nov 2019 12:08:54 +0100 Subject: [PATCH] android: disable ConnectionService if permissions are not granted Some devices seem to have a bug in their Android versions and startCall fails with SecurityError because the CALL_PHONE permissions is not granted. This is not a requirement for self-managed connection services as per the official documentation though: https://developer.android.com/guide/topics/connectivity/telecom/selfManaged Alas, connection services takes over audio device management too, so let's handle the error and disable CS if we get SecurityError. --- .../jitsi/meet/sdk/RNConnectionService.java | 6 +++++- .../mobile/call-integration/middleware.js | 18 ++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/android/sdk/src/main/java/org/jitsi/meet/sdk/RNConnectionService.java b/android/sdk/src/main/java/org/jitsi/meet/sdk/RNConnectionService.java index 464a543ff..9b0e248c2 100644 --- a/android/sdk/src/main/java/org/jitsi/meet/sdk/RNConnectionService.java +++ b/android/sdk/src/main/java/org/jitsi/meet/sdk/RNConnectionService.java @@ -116,7 +116,11 @@ class RNConnectionService extends ReactContextBaseJavaModule { tm.unregisterPhoneAccount(accountHandle); } ConnectionService.unregisterStartCallPromise(callUUID); - promise.reject(e); + if (e instanceof SecurityException) { + promise.reject("SECURITY_ERROR", "Required permissions not granted."); + } else { + promise.reject(e); + } } } diff --git a/react/features/mobile/call-integration/middleware.js b/react/features/mobile/call-integration/middleware.js index 101fde9fb..19dca9115 100644 --- a/react/features/mobile/call-integration/middleware.js +++ b/react/features/mobile/call-integration/middleware.js @@ -1,6 +1,6 @@ // @flow -import { Alert, Platform } from 'react-native'; +import { Alert, NativeModules, Platform } from 'react-native'; import uuid from 'uuid'; import { createTrackMutedEvent, sendAnalytics } from '../../analytics'; @@ -36,6 +36,7 @@ import CallKit from './CallKit'; import ConnectionService from './ConnectionService'; import { isCallIntegrationEnabled } from './functions'; +const { AudioMode } = NativeModules; const CallIntegration = CallKit || ConnectionService; /** @@ -276,7 +277,8 @@ function _conferenceWillJoin({ dispatch, getState }, next, action) { } }) .catch(error => { - // Currently this error code is emitted only by Android. + // Currently this error codes are emitted only by Android. + // if (error.code === 'CREATE_OUTGOING_CALL_FAILED') { // We're not tracking the call anymore - it doesn't exist on // the native side. @@ -290,6 +292,18 @@ function _conferenceWillJoin({ dispatch, getState }, next, action) { { text: 'OK' } ], { cancelable: false }); + } else if (error.code === 'SECURITY_ERROR') { + // Some devices fail because the CALL_PHONE permission is not granted, which is + // nonsense, because it's not needed for self-managed connections. Alas, this also + // means audio device management would be broken, so fallback to not using ConnectionService. + // NOTE: We are not storing this in Settings, in case it's a transient issue, as far fetched as + // that may be. + if (AudioMode.setUseConnectionService) { + AudioMode.setUseConnectionService(false); + + // Set the desired audio mode, since we just reset the whole thing. + AudioMode.setMode(hasVideo ? AudioMode.VIDEO_CALL : AudioMode.AUDIO_CALL); + } } });