Commit Graph

238 Commits

Author SHA1 Message Date
Daniel Calviño Sánchez
4457e92504 Generalize PUBLISHER_FAILED event
Rather than emitting PUBLISHER_FAILED when the publisher connection
fails now PEER_FAILED is emitted when any connection fails, and the
handler checks if the connection was the publisher one to apply the
specific behaviour.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-12-28 15:48:45 +01:00
Daniel Calviño Sánchez
64c4f8c7ee Remove unneeded condition
The publisher peer connection when the HPB is used is a sender only
connection, so it never adds or removes a remote stream.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-12-28 15:48:45 +01:00
Daniel Calviño Sánchez
30aafed0e8 Post MediaStreamEvent when the stream is actually added
The MediaStreamEvent was posted when the connection with the remote peer
was established. However, the MediaStream is added earlier (as soon as
the remote description is received), so the event is moved to better
reflect that.

Note that checking if the connection is an MCU publisher is no longer
needed, as publisher connections are sender only and therefore no remote
stream is added for publisher connections.

In any case, note that the stream will not start until the connection is
established, and a progress bar will be anyway shown on the
ParticipantDisplayItem until it is connected.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-12-28 15:48:45 +01:00
Daniel Calviño Sánchez
29117e8b1b Get user ID from signaling message when creating ParticipantDisplayItem
The user ID set when creating the ParticipantDisplayItem was got from
the join event when the external signaling server was used, and from an
API call when the internal signaling server was used. However, the user
ID is already known from the signaling message that updates the
participant list, and is the one set on the ParticipantDisplayItems
when a participant joins the call. Therefore the other sources are not
needed, so now it is unified to always use the value from the signaling
message.

Note that in the rare cases in which a ParticipantDisplayItem is created
before the participant is seen as in the call the user ID will be
temporary unknown, although it will be automatically fixed once the
participant list update is received. Moreover, even if the other sources
were used it was not guaranteed that the user ID was known, so this
should not be a problem.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-12-28 15:48:45 +01:00
Daniel Calviño Sánchez
3762526318 Rewrite if/else chain as if/return blocks
Just a matter of preference :-)

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-12-28 11:47:56 +01:00
Daniel Calviño Sánchez
dceb4a6d79 Add listener for data channel messages
For now only the same data channel messages that were already handled
are taken into account, but at a later point the missing messages
("speaking" and "stoppedSpeaking") could be added too.

Note that the thread used to handle the data channel messages has
changed; the EventBus subscriber mode was "MAIN", but as the messages
were posted from a DataChannel observer, which run in a worker thread
rather than in the main thread, the subscriber was executed in the main
thread rather than in the same thread as the poster. Due to this the
actions performed by the handler now must be explicitly run in the main
thread.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-12-28 11:47:55 +01:00
Daniel Calviño Sánchez
ac4be52b84 Do not guard code that can not throw the caught exception
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-12-28 11:47:55 +01:00
Daniel Calviño Sánchez
af514b142a Reorder code that handles nick changed events
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-12-28 11:47:55 +01:00
Daniel Calviño Sánchez
81f353f7f0 Return empty display name rather than default nick from web socket
If the display name is not known whether "Guest" or something else needs
to be shown is not a responsibility of the web socket, so now an empty
string is returned instead.

In practice this should not make any difference, though, as the display
name of users is always known as soon as the user joined, and if the
nick of a guest is not known the UI will set it to "Guest".

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-12-28 11:47:55 +01:00
Daniel Calviño Sánchez
0dcdd6161f Move nick handling out of PeerConnectionWrapper
PeerConnectionWrappers should not be concerned with the nick of
participants. Moreover, the nick is included in offers and answers due
to legacy reasons and only when the internal signaling server is used.
Due to that the nick was moved out of PeerConnectionWrapper; although
the handling is now different the end result should be the same (there
might be some differences in very specific sequences of events, but in
any case all this is just a temporary step and any leftover issue should
be addressed once call participants and peer connections are split).

As the PeerConnectionWrapper does not keep track of the nick now the
nick changed event is always emitted when a nick changed data channel
message is received, even if the nick did not actually change.
Nevertheless, before it was anyway always emitted if it was for a user
and only when it was for a guest it was emitted only on real changes. In
any case this is not expected to cause any issue (other than some
unneeded view updates, but that will be addressed at a later point by
updating the views only when the model actually changed).

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-12-28 11:47:55 +01:00
Daniel Calviño Sánchez
2eac8c2cba Move default nick out of PeerConnectionWrapper
If the nick is not known whether "Guest" or something else needs to be
shown is a responsability of the UI, so now the PeerConnectionWrapper
just returns an empty string and the UI shows the default guest nick if
needed.

Moreover, the nick stored in the PeerConnectionWrapper was not always
correct, as if no nick was received it was returned as "Guest" even
if the connection belonged to a user. Now "Guest" is used only for
actual guests.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-12-28 11:47:55 +01:00
Daniel Calviño Sánchez
68cf4ee028 Use generic data channel message instead of nick specific one
The generic data channel message works fine for receiving, but it could
not be used for sending, because the serialization of the payload failed
(the generated JsonMapper did not call 'writeFieldName("payload")',
apparently because the payload was defined as "Any", so there was no
field name set when serializing the payload contents).

It is very likely that the nick data channel message, which has an
explicit payload type and was used only for sending but not for
receiving, was added back in the day just to work around that
limitation. However, due to how the JsonMappers are generated if several
properties with the same name are defined only the first one will be
parsed, and only those with a value will be serialized. This makes
possible to define first a generic payload property and then a payload
property with an explicit type to have a single data channel message
class that can be used both for sending and receiving.

As the nick data channel message is now no longer needed it was removed.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-12-28 11:47:55 +01:00
Daniel Calviño Sánchez
faf25f8071 Replace concrete implementation with interface
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-12-28 11:47:55 +01:00
Daniel Calviño Sánchez
65ff4efcb9
Send signaling messages directly from PeerConnectionWrapper
Note that the thread used to send the message does not change; the
EventBus subscriber mode was "BACKGROUND", but as the messages were
posted from a WebSocket handler (when requesting offers to the HPB) and
peer connection observers (when sending offers/answers and candidates,
both with and without HPB), which run in worker threads rather than in
the main thread, the subscriber was executed in the same thread as
the poster.

For legacy reasons, when the internal signaling server is used the
offers and answers are expected to also provide the nick of the local
participant. When the external signaling server is used the field can be
included, but it is just ignored and not sent to the other clients. As
the local participant nick is a value unrelated to the peer connection
and is only needed with one type of signaling server the messages are
adjusted as needed before being sent rather than handling this inside
the PeerConnectionWrapper.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-12-27 14:28:57 +01:00
Daniel Calviño Sánchez
58e371c98c
Do not apply "toLowerCase()" on already lower case canonical form
The canonical form is already in lower case (see
https://webrtc.googlesource.com/src/+/79d8df02/sdk/android/api/org/webrtc/SessionDescription.java#29),
so there is no need to apply "toLowerCase()".

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-12-27 14:28:57 +01:00
Daniel Calviño Sánchez
473b8b238d
Extract interface to send signaling messages
Like done with SignalingMessageReceiver, an implementation specific to
each signaling server type (internal or external) is added.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-12-27 14:28:57 +01:00
Daniel Calviño Sánchez
4086499a32
Remove special method to request offers
As the "requestoffer" message is just a signaling message the generic
method can be used instead.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-12-27 14:28:57 +01:00
Daniel Calviño Sánchez
37db855170
Use generic message rather than specific one for requesting offers
"requestoffer" messages are compatible with the generic messages, so for
simplicity the generic message is used now instead of having specific
classes just for it.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-12-27 14:28:56 +01:00
Daniel Calviño Sánchez
e1eca7764f
Replace wrapper with actual message in external signaling server
NCMessageWrapper is used only for messages sent and received by the
internal signaling server. However, it is unused by the external
signaling server, except for getting the NCSignalingMessage, which is
the common message for both signaling servers.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-12-27 14:28:55 +01:00
Daniel Calviño Sánchez
c4c64df5a6 Remove no longer needed code after removing EventBus message
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-12-23 20:44:41 +01:00
Daniel Calviño Sánchez
5e224c5a24 Use listener for participant list messages
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>
2022-12-23 20:44:41 +01:00
Daniel Calviño Sánchez
c8e77c3d3b Split message receiver for internal and external signaling servers
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>
2022-12-23 20:44:41 +01:00
Daniel Calviño Sánchez
476fb59a08 Use temporary SignalingMessageReceiver implementation in CallActivity
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>
2022-12-23 20:40:01 +01:00
Daniel Calviño Sánchez
0e36002036 Hide and delete no longer needed public methods
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>
2022-12-23 20:40:01 +01:00
Daniel Calviño Sánchez
4dffd29ceb Move handling of WebRTC messages to PeerConnectionWrapper
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-12-23 20:40:01 +01:00
Tim Krüger
4b46270362
Set minSdkVersion to 23 (Android 6)
Signed-off-by: Tim Krüger <t@timkrueger.me>
2022-12-07 13:45:57 +01:00
Daniel Calviño Sánchez
ed54b9f03a
Fix video stream type not included in PeerConnectionEvent
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-11-16 15:45:34 +01:00
Daniel Calviño Sánchez
969c08ea79
Use comparison operator rather than equals for enums in WebRTC code
Fixes SPP_EQUALS_ON_ENUM issue from SpotBugs.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-11-14 11:29:52 +01:00
Tim Krüger
dda5a9e3da
Define 'BundleKeys' as 'const'
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>
2022-09-26 11:41:10 +02:00
Daniel Calviño Sánchez
9f445efc1c Post event when a participant is connected and disconnected
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>
2022-09-18 23:25:57 +02:00
Andy Scherzinger
d999815ffa
remove unused java imports
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
2022-07-26 22:24:18 +02:00
Andy Scherzinger
9ab4c58b41
remove all legacy code except basic requery implementation still needed for the cypher upgrade
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
2022-07-24 14:19:20 +02:00
Andy Scherzinger
fde2667fe7
Migrate Call Activity and used classes/methods from requery to room
Resolves #2216

Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
2022-07-14 18:19:43 +02:00
Tim Krüger
834d310eb8
Use simple class name for logging
Signed-off-by: Tim Krüger <t@timkrueger.me>
2022-06-23 15:35:42 +02:00
Tim Krüger
10a4521af9
Rename 'WebRtcAudioManger' to 'WebRtcAudioManager'
Signed-off-by: Tim Krüger <t@timkrueger.me>
2022-06-23 15:20:32 +02:00
drone
4b67a71ff4 Merge commit '1f936cb677ed17f93fba461ae59ac84bda5e99db' 2022-06-22 09:00:28 +00:00
Tim Krüger
6e4841ae3a
Rename 'MagicAudioManager' and 'MagicBluetoothManager'
It's not magic but WebRtc related.

Signed-off-by: Tim Krüger <t@timkrueger.me>
2022-06-21 15:13:47 +02:00
Andy Scherzinger
49792ecf1e
rename blacklist/whitelist variables to include/exclude sets to reflect their collection type
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
2022-06-18 16:29:57 +02:00
Andy Scherzinger
993e50dbdb
rename variable to reflect its collection type
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
2022-06-18 15:37:42 +02:00
Tim Krüger
dedbe40cc0
Launch 'MagicBluetoothManager' independently
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>
2022-06-17 15:51:44 +02:00
Tim Krüger
4821b02729
Add Android build switch for checking bluetooth permissions
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>
2022-06-17 15:51:44 +02:00
Andy Scherzinger
6386bb05d7
remove permission LOCAL_MAC_ADDRESS need
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
2022-05-19 18:21:38 +02:00
Andy Scherzinger
0bbf14a2f0
remove obsolete sdk version check
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
2022-05-18 17:29:14 +02:00
Andy Scherzinger
a617f10473
Migrate participant to kotlin data class
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
2022-05-16 23:06:29 +02:00
drone
be1b075234 Merge commit 'e52b2d8b7ffbad4e4343bb6b97d40663ddc58149' 2022-05-05 11:06:39 +00:00
Tim Krüger
e52b2d8b7f
Add null checks and extract constants
Signed-off-by: Tim Krüger <t@timkrueger.me>
2022-05-05 13:06:15 +02:00
Tim Krüger
4f5a344a20
Add handling for "event.participants.update.all"
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>
2022-05-04 13:49:04 +02:00
Daniel Calviño Sánchez
3274c1e1fa
Fix typo in name of method to check if video should not be received
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2022-05-02 13:36:13 +02:00
Andy Scherzinger
deac2059ff
improve lint/detekt
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
2022-04-08 09:21:11 +02:00
Marcel Hibbe
49fd2640bf
rename method
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
2022-03-30 12:08:54 +02:00