Note that the thread used to handle the participant list messages from
the external signaling server does not change; the EventBus subscriber
mode was "BACKGROUND", but as the message was posted from a WebSocket
handler, which runs in a worker thread rather than in the main thread,
the subscriber was executed in the same thread as the poster.
Also note that the removed "userId" remark was not fully accurate;
although some external signaling messages do actually use "userid" those
currently handled to process the users do not, they always use "userId"
(as documented in the SignalingMessageReceiver).
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Note that the thread used to handle and notify messages from the
external signaling server does not change; the EventBus subscriber mode
was "BACKGROUND", but as the message was posted from a WebSocket
handler, which runs in a worker thread rather than in the main thread,
the subscriber was executed in the same thread as the poster.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Eventually all signaling related code should be moved to a Signaling
class that abstracts the differences between the internal and external
signaling servers, including how messages are sent and listened to. In
the meantime a temporary SignalingMessageReceiver implementation is
added to CallActivity to be able to start using it.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Although the rest of the methods are no longer needed since the handling
of WebRTC messages was moved to PeerConnectionWrapper "setSessionId()"
was not needed even before that.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
During the migration from Java to Kotlin this was not done and resulted
in
BundleKeys.INSTANCE.getKEY_CALL_VOICE_ONLY()
instead of
BundleKeys.KEY_CALL_VOICE_ONLY
Signed-off-by: Tim Krüger <t@timkrueger.me>
RTCPeerConnections have several states but, for simplicity, for now the
events posted reflect only if the connection is fully established or
not (which includes both a broken connection or an established
connection that is unstable or being updated), which is enough for a
basic information about the connection state in the UI.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
This change is needed to make the 'MagicBluetoothManager' startable
after the from Android SDK 31 introduced BLUETOOTH_CONNECT is granted by
the user.
Before this change the 'MagicBluetoothManager' was only started in
'MagicAudioManager#start'. Now the new method
'MagicAudioManager#startBluetoothManager' can be used to start the
'MagicBluetoothManager'.
This change is also a preperation to fix#1309 and #2114.
See: #2132, #1309, #2124
Signed-off-by: Tim Krüger <t@timkrueger.me>
Refactored method 'hasPermission' to 'hasNoBluetoothPermission'. The new method
respect the in SKD 31 introduced permission BLUETOOTH_CONNECT. For older SDK
versions the permission BLUETOOTH will be used.
Additionaly make methods private which need bluetooth permissions and only
called locally. For public methods which need bluetooth permissions the method
'hasNoBluetoothPermission' is called to check them.
Also add suppress lint annotation for 'MissingPermission'.
From SDK 30 to SDK 31 the bluetooth related permissions changed and it
is suggested to add the attribute 'android:maxSdkVersion="30"' to the
legacy BLUETOOTH permission in the 'AndroidManifest.xml' [1]:
> For your legacy Bluetooth-related permission declarations, set
> android:maxSdkVersion to 30. This app compatibility step helps the system
> grant your app only the Bluetooth permissions that it needs when installed
> on devices that run Android 12 or higher.
This is explicitly not done here!
During runtime (on Android 12) while starting the 'MagicBluetoothManger' the
following part in 'android.bluetooth.BluetootHeadset' constructor will be
executed and results in the previous exception:
// Preserve legacy compatibility where apps were depending on
// registerStateChangeCallback() performing a permissions check which
// has been relaxed in modern platform versions
if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.R
&& context.checkSelfPermission(android.Manifest.permission.BLUETOOTH)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Need BLUETOOTH permission");
}
In the 'build.gradle' the 'targetSdkVersion 30' and 'compileSdkVersion 31' is
configured. Because the 'MagicBluetoothManager' checks for the 'targetSdkVersion'
instead of 'Build.VERSION.SDK_INT' also on a Android 12 (SDK 31) the 'BLUETOOTH'
permission is needed.
So the solution is to don't set `android:maxSdkVersion="30"' for the BLUETOOTH
permission and request the BLUETOOTH_CONNECT permission.
Resolves: #2132
See:
[1] https://web.archive.org/web/20220416121005/https://developer.android.com/guide/topics/connectivity/bluetooth/permissions#declare-android12-or-higher
Signed-off-by: Tim Krüger <t@timkrueger.me>
In case a moderator of a restricted room ends the call for all
participants a update participants event with the field 'all=true' will
be thrown by the HPB.
{
"type": "event"
"event": {
"target": "participants",
"type": "update",
"update": [
"roomid": "the-room-id",
"incall": new-incall-state,
"all": true
]
}
}
In that case the call can be ended directly without handling every
single participant.
Resolves: #1881
Signed-off-by: Tim Krüger <t@timkrueger.me>
After the migration from WebRTC from plan b to unified plan in commit 86f20dc
the media constraints are ignored for creating an answer on a peer
connection:
> Offer to Receive Options/Constraints
>
> These constraints are passed to PeerConnection’s methods for creating SDP to
> add placeholder media sections in case a sending track would not have already
> created one.
>
> With Unified Plan semantics, these are still supported for creating offers
> using a backwards compatibility shim (basically creating an RtpTransceiver if
> one doesn’t exist). It is recommended to switch to the RtpTransceiver API
> (example below). _They are no longer supported when creating answers._
>
> [1]
Because of that now all transceivers of type VIDEO will be stopped if it
is only an audio call. After stopping the transceivers the status for the
video tracks will be automatically set to ENDED.
In the 'ParticipantsAdapter' it will be checked if the video tracks are
ENDED. In that case the user avatar will be shown like before.
Resolves: #1852
See: #1773, commit 86f20dc, [1]
[1] https://docs.google.com/document/d/1PPHWV6108znP1tk_rkCnyagH9FK205hHeE9k5mhUzOg/edit#heading=h.9dcmkavg608r
Signed-off-by: Tim Krüger <t@timkrueger.me>
The in 'MagicPeerConnectionWrapper#removePeerConnection' used method
'PeerConnection#removeStream' was not longer available in the unified
plan. So to make sure that the local stream is disposed, it will now be
done in 'CallActivity#hangup'.
Resolves: #1773
See: [1]
[1] https://webrtc.org/getting-started/unified-plan-transition-guide
Signed-off-by: Tim Krüger <t@timkrueger.me>