react-native-webrtc / react-native-callkeep

iOS CallKit framework and Android ConnectionService for React Native
ISC License
923 stars 445 forks source link

hasPhoneAccount() returns true in self managed mode, without checking if the device supports it #761

Open wilmxre opened 9 months ago

wilmxre commented 9 months ago

Description

I encountered a problem in self managed mode, on some Lenovo devices if you call setup like you should and you receive or start a call, you will be encountered with this error:

Remote stack trace:
    at com.android.server.telecom.TelecomServiceImpl.enforceTelecomFeature(TelecomServiceImpl.java:2449)
    at com.android.server.telecom.TelecomServiceImpl.enforcePhoneAccountModificationForPackage(TelecomServiceImpl.java:2409)
    at com.android.server.telecom.TelecomServiceImpl.-$$Nest$menforcePhoneAccountModificationForPackage(Unknown Source:0)
    at com.android.server.telecom.TelecomServiceImpl$1.registerPhoneAccount(TelecomServiceImpl.java:564)
    at com.android.internal.telecom.ITelecomService$Stub.onTransact(ITelecomService.java:857)

This usually means that a phone account couldn't register successfully or the device doesn't support this functionality. From what i've read, calling RNCallKeep.setup() should be enough to set up your app for calls, but i tried to explicitly register a phone account, without success. I come to the conclusion that there are some devices that are simply not supporting phone account.

Now i made a workaround for devices that are encountering this specific issue and i wanted to check it programatically, but i noticed something unusual. When calling RNCallKeep.checkPhoneAccountEnabled, this method is called:

private boolean hasPhoneAccount() {
        if (telecomManager == null) {
            this.initializeTelecomManager();
        }

        if (isSelfManaged()) {
            return true;
        }

        return isConnectionServiceAvailable() && telecomManager != null &&
            hasPermissions() && telecomManager.getPhoneAccount(handle) != null &&
            telecomManager.getPhoneAccount(handle).isEnabled();
    }

If the app is in self managed mode, this method automatically returns true, without checking if the app has a phone account. Why is this the case? Shouldn't be better to remove that if statement and let the last return statement handle this logic? For my use case i had to remove it, i am curious what was the need for that early return.

Do self managed apps always have the possibility to register a phone account? From my experiences there are some devices, especially Lenovo tablets, where it is simply impossible to do (registerPhoneAccount not allowed on non-voice capable device). If the config_voice_capable is simply set to false in some device, that device won't support phone accounts.