diff --git a/app/src/main/java/com/nextcloud/talk/controllers/CallController.java b/app/src/main/java/com/nextcloud/talk/controllers/CallController.java index 17477e987..5994caa8b 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/CallController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/CallController.java @@ -445,12 +445,12 @@ public class CallController extends BaseController { .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer() { @Override - public void onSubscribe(Disposable d) { - + public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) { + // unused atm } @Override - public void onNext(RoomsOverall roomsOverall) { + public void onNext(@io.reactivex.annotations.NonNull RoomsOverall roomsOverall) { for (Conversation conversation : roomsOverall.getOcs().getData()) { if (roomId.equals(conversation.getRoomId())) { roomToken = conversation.getToken(); @@ -462,13 +462,13 @@ public class CallController extends BaseController { } @Override - public void onError(Throwable e) { - + public void onError(@io.reactivex.annotations.NonNull Throwable e) { + // unused atm } @Override public void onComplete() { - + // unused atm } }); } @@ -500,7 +500,6 @@ public class CallController extends BaseController { pipVideoView.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT); pipVideoView.setOnTouchListener(new SelfVideoTouchListener()); - } gridView.setOnTouchListener(new View.OnTouchListener() { @@ -942,17 +941,16 @@ public class CallController extends BaseController { } } - if (isConnectionEstablished()) { + if (isConnectionEstablished() && magicPeerConnectionWrapperList != null) { if (!hasMCU) { - for (int i = 0; i < magicPeerConnectionWrapperList.size(); i++) { - magicPeerConnectionWrapperList.get(i).sendChannelData(new DataChannelMessage(message)); + for (MagicPeerConnectionWrapper magicPeerConnectionWrapper : magicPeerConnectionWrapperList) { + magicPeerConnectionWrapper.sendChannelData(new DataChannelMessage(message)); } } else { - for (int i = 0; i < magicPeerConnectionWrapperList.size(); i++) { - if (magicPeerConnectionWrapperList.get(i).getSessionId().equals(webSocketClient.getSessionId())) { - magicPeerConnectionWrapperList.get(i).sendChannelData(new DataChannelMessage(message)); + for (MagicPeerConnectionWrapper magicPeerConnectionWrapper : magicPeerConnectionWrapperList) { + if (magicPeerConnectionWrapper.getSessionId().equals(webSocketClient.getSessionId())) { + magicPeerConnectionWrapper.sendChannelData(new DataChannelMessage(message)); break; - } } } @@ -1095,7 +1093,7 @@ public class CallController extends BaseController { } private void fetchSignalingSettings() { - int apiVersion = ApiUtils.getSignalingApiVersion(conversationUser, new int[] {2, 1}); + int apiVersion = ApiUtils.getSignalingApiVersion(conversationUser, new int[] {ApiUtils.APIv3, 2, 1}); ncApi.getSignalingSettings(credentials, ApiUtils.getUrlForSignalingSettings(apiVersion, baseUrl)) .subscribeOn(Schedulers.io()) @@ -1103,13 +1101,12 @@ public class CallController extends BaseController { .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer() { @Override - public void onSubscribe(Disposable d) { - + public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) { + // unused atm } @Override - public void onNext(SignalingSettingsOverall signalingSettingsOverall) { - IceServer iceServer; + public void onNext(@io.reactivex.annotations.NonNull SignalingSettingsOverall signalingSettingsOverall) { if (signalingSettingsOverall != null && signalingSettingsOverall.getOcs() != null && signalingSettingsOverall.getOcs().getSettings() != null) { @@ -1143,30 +1140,34 @@ public class CallController extends BaseController { } if (signalingSettingsOverall.getOcs().getSettings().getStunServers() != null) { - for (int i = 0; i < signalingSettingsOverall.getOcs().getSettings().getStunServers().size(); - i++) { - iceServer = signalingSettingsOverall.getOcs().getSettings().getStunServers().get(i); - if (TextUtils.isEmpty(iceServer.getUsername()) || TextUtils.isEmpty(iceServer - .getCredential())) { - iceServers.add(new PeerConnection.IceServer(iceServer.getUrl())); - } else { - iceServers.add(new PeerConnection.IceServer(iceServer.getUrl(), - iceServer.getUsername(), iceServer.getCredential())); + List stunServers = + signalingSettingsOverall.getOcs().getSettings().getStunServers(); + if (apiVersion == ApiUtils.APIv3) { + for (IceServer stunServer : stunServers) { + if (stunServer.getUrls() != null) { + for (String url : stunServer.getUrls()) { + iceServers.add(new PeerConnection.IceServer(url)); + } + } + } + } else { + if (signalingSettingsOverall.getOcs().getSettings().getStunServers() != null) { + for (IceServer stunServer : stunServers) { + iceServers.add(new PeerConnection.IceServer(stunServer.getUrl())); + } } } } if (signalingSettingsOverall.getOcs().getSettings().getTurnServers() != null) { - for (int i = 0; i < signalingSettingsOverall.getOcs().getSettings().getTurnServers().size(); - i++) { - iceServer = signalingSettingsOverall.getOcs().getSettings().getTurnServers().get(i); - for (int j = 0; j < iceServer.getUrls().size(); j++) { - if (TextUtils.isEmpty(iceServer.getUsername()) || TextUtils.isEmpty(iceServer - .getCredential())) { - iceServers.add(new PeerConnection.IceServer(iceServer.getUrls().get(j))); - } else { - iceServers.add(new PeerConnection.IceServer(iceServer.getUrls().get(j), - iceServer.getUsername(), iceServer.getCredential())); + List turnServers = + signalingSettingsOverall.getOcs().getSettings().getTurnServers(); + for (IceServer turnServer : turnServers) { + if (turnServer.getUrls() != null) { + for (String url : turnServer.getUrls()) { + iceServers.add(new PeerConnection.IceServer( + url, turnServer.getUsername(), turnServer.getCredential() + )); } } } @@ -1177,13 +1178,13 @@ public class CallController extends BaseController { } @Override - public void onError(Throwable e) { + public void onError(@io.reactivex.annotations.NonNull Throwable e) { Log.e(TAG, e.getMessage(), e); } @Override public void onComplete() { - + // unused atm } }); } @@ -1195,12 +1196,12 @@ public class CallController extends BaseController { .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer() { @Override - public void onSubscribe(Disposable d) { - + public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) { + // unused atm } @Override - public void onNext(CapabilitiesOverall capabilitiesOverall) { + public void onNext(@io.reactivex.annotations.NonNull CapabilitiesOverall capabilitiesOverall) { // FIXME check for compatible Call API version if (hasExternalSignalingServer) { setupAndInitiateWebSocketsConnection(); @@ -1210,13 +1211,13 @@ public class CallController extends BaseController { } @Override - public void onError(Throwable e) { - + public void onError(@io.reactivex.annotations.NonNull Throwable e) { + // unused atm } @Override public void onComplete() { - + // unused atm } }); } @@ -1234,12 +1235,12 @@ public class CallController extends BaseController { .retry(3) .subscribe(new Observer() { @Override - public void onSubscribe(Disposable d) { - + public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) { + // unused atm } @Override - public void onNext(RoomOverall roomOverall) { + public void onNext(@io.reactivex.annotations.NonNull RoomOverall roomOverall) { callSession = roomOverall.getOcs().getData().getSessionId(); ApplicationWideCurrentRoomHolder.getInstance().setSession(callSession); ApplicationWideCurrentRoomHolder.getInstance().setCurrentRoomId(roomId); @@ -1249,13 +1250,13 @@ public class CallController extends BaseController { } @Override - public void onError(Throwable e) { - + public void onError(@io.reactivex.annotations.NonNull Throwable e) { + // unused atm } @Override public void onComplete() { - + // unused atm } }); } else { @@ -1288,26 +1289,31 @@ public class CallController extends BaseController { .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer() { @Override - public void onSubscribe(Disposable d) { - + public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) { + // unused atm } @Override - public void onNext(GenericOverall genericOverall) { + public void onNext(@io.reactivex.annotations.NonNull GenericOverall genericOverall) { if (!currentCallStatus.equals(CallStatus.LEAVING)) { setCallState(CallStatus.JOINED); ApplicationWideCurrentRoomHolder.getInstance().setInCall(true); if (!TextUtils.isEmpty(roomToken)) { - NotificationUtils.INSTANCE.cancelExistingNotificationsForRoom(getApplicationContext(), conversationUser, roomToken); + NotificationUtils.INSTANCE.cancelExistingNotificationsForRoom(getApplicationContext(), + conversationUser, + roomToken); } if (!hasExternalSignalingServer) { - int apiVersion = ApiUtils.getSignalingApiVersion(conversationUser, new int[] {2, 1}); + int apiVersion = ApiUtils.getSignalingApiVersion(conversationUser, + new int[] {ApiUtils.APIv3, 2, 1}); - ncApi.pullSignalingMessages(credentials, ApiUtils.getUrlForSignaling(apiVersion, - baseUrl, roomToken)) + ncApi.pullSignalingMessages(credentials, + ApiUtils.getUrlForSignaling(apiVersion, + baseUrl, + roomToken)) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .repeatWhen(observable -> observable) @@ -1315,26 +1321,19 @@ public class CallController extends BaseController { .retry(3, observable -> isConnectionEstablished()) .subscribe(new Observer() { @Override - public void onSubscribe(Disposable d) { + public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) { signalingDisposable = d; } @Override - public void onNext(SignalingOverall signalingOverall) { - if (signalingOverall.getOcs().getSignalings() != null) { - for (int i = 0; i < signalingOverall.getOcs().getSignalings().size(); i++) { - try { - receivedSignalingMessage(signalingOverall.getOcs().getSignalings().get(i)); - } catch (IOException e) { - Log.e(TAG, "Failed to process received signaling" + - " message"); - } - } - } + public void onNext( + @io.reactivex.annotations.NonNull + SignalingOverall signalingOverall) { + receivedSignalingMessages(signalingOverall.getOcs().getSignalings()); } @Override - public void onError(Throwable e) { + public void onError(@io.reactivex.annotations.NonNull Throwable e) { dispose(signalingDisposable); } @@ -1343,19 +1342,18 @@ public class CallController extends BaseController { dispose(signalingDisposable); } }); - - } } } @Override - public void onError(Throwable e) { + public void onError(@io.reactivex.annotations.NonNull Throwable e) { + // unused atm } @Override public void onComplete() { - + // unused atm } }); } @@ -1397,7 +1395,6 @@ public class CallController extends BaseController { } else { initiateCall(); } - } else { } break; case "roomJoined": @@ -1409,14 +1406,19 @@ public class CallController extends BaseController { break; case "participantsUpdate": if (webSocketCommunicationEvent.getHashMap().get("roomToken").equals(roomToken)) { - processUsersInRoom((List>) webSocketClient.getJobWithId(Integer.valueOf(webSocketCommunicationEvent.getHashMap().get("jobId")))); + processUsersInRoom( + (List>) webSocketClient + .getJobWithId( + Integer.valueOf(webSocketCommunicationEvent.getHashMap().get("jobId")))); } break; case "signalingMessage": - processMessage((NCSignalingMessage) webSocketClient.getJobWithId(Integer.valueOf(webSocketCommunicationEvent.getHashMap().get("jobId")))); + processMessage((NCSignalingMessage) webSocketClient.getJobWithId( + Integer.valueOf(webSocketCommunicationEvent.getHashMap().get("jobId")))); break; case "peerReadyForRequestingOffer": - webSocketClient.requestOfferForSessionIdWithType(webSocketCommunicationEvent.getHashMap().get("sessionId"), "video"); + webSocketClient.requestOfferForSessionIdWithType( + webSocketCommunicationEvent.getHashMap().get("sessionId"), "video"); break; } } @@ -1437,6 +1439,18 @@ public class CallController extends BaseController { } } + private void receivedSignalingMessages(@Nullable List signalingList) { + if (signalingList != null) { + for (Signaling signaling : signalingList) { + try { + receivedSignalingMessage(signaling); + } catch (IOException e) { + Log.e(TAG, "Failed to process received signaling message", e); + } + } + } + } + private void receivedSignalingMessage(Signaling signaling) throws IOException { String messageType = signaling.getType(); @@ -2000,7 +2014,7 @@ public class CallController extends BaseController { String stringToSend = stringBuilder.toString(); strings.add(stringToSend); - int apiVersion = ApiUtils.getSignalingApiVersion(conversationUser, new int[] {2, 1}); + int apiVersion = ApiUtils.getSignalingApiVersion(conversationUser, new int[] {ApiUtils.APIv3, 2, 1}); ncApi.sendSignalingMessages(credentials, ApiUtils.getUrlForSignaling(apiVersion, baseUrl, roomToken), strings.toString()) @@ -2008,31 +2022,23 @@ public class CallController extends BaseController { .subscribeOn(Schedulers.io()) .subscribe(new Observer() { @Override - public void onSubscribe(Disposable d) { - + public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) { + // unused atm } @Override - public void onNext(SignalingOverall signalingOverall) { - if (signalingOverall.getOcs().getSignalings() != null) { - for (int i = 0; i < signalingOverall.getOcs().getSignalings().size(); i++) { - try { - receivedSignalingMessage(signalingOverall.getOcs().getSignalings().get(i)); - } catch (IOException e) { - Log.e(TAG, "", e); - } - } - } + public void onNext(@io.reactivex.annotations.NonNull SignalingOverall signalingOverall) { + receivedSignalingMessages(signalingOverall.getOcs().getSignalings()); } @Override - public void onError(Throwable e) { + public void onError(@io.reactivex.annotations.NonNull Throwable e) { Log.e(TAG, "", e); } @Override public void onComplete() { - + // unused atm } }); } else { diff --git a/app/src/main/java/com/nextcloud/talk/controllers/CallNotificationController.java b/app/src/main/java/com/nextcloud/talk/controllers/CallNotificationController.java index 35ff72f70..e6e64f84e 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/CallNotificationController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/CallNotificationController.java @@ -385,8 +385,11 @@ public class CallNotificationController extends BaseController { avatarImageView.setVisibility(View.VISIBLE); ImageRequest imageRequest = - DisplayUtils.getImageRequestForUrl(ApiUtils.getUrlForAvatarWithName(userBeingCalled.getBaseUrl(), - currentConversation.getName(), R.dimen.avatar_size_very_big), null); + DisplayUtils.getImageRequestForUrl( + ApiUtils.getUrlForAvatarWithName(userBeingCalled.getBaseUrl(), + currentConversation.getName(), + R.dimen.avatar_size_very_big), + null); ImagePipeline imagePipeline = Fresco.getImagePipeline(); DataSource> dataSource = imagePipeline.fetchDecodedImage(imageRequest, null); @@ -399,11 +402,12 @@ public class CallNotificationController extends BaseController { true); if (getResources() != null) { - incomingTextRelativeLayout.setBackground(getResources().getDrawable(R.drawable - .incoming_gradient)); + incomingTextRelativeLayout.setBackground( + getResources().getDrawable(R.drawable.incoming_gradient)); } - if (AvatarStatusCodeHolder.getInstance().getStatusCode() == 200 || AvatarStatusCodeHolder.getInstance().getStatusCode() == 0) { + if (AvatarStatusCodeHolder.getInstance().getStatusCode() == 200 || + AvatarStatusCodeHolder.getInstance().getStatusCode() == 0) { if (getActivity() != null) { Bitmap backgroundBitmap = bitmap.copy(bitmap.getConfig(), true); new BlurPostProcessor(5, getActivity()).process(backgroundBitmap); @@ -425,6 +429,7 @@ public class CallNotificationController extends BaseController { @Override protected void onFailureImpl(DataSource> dataSource) { + // unused atm } }, UiThreadImmediateExecutorService.getInstance()); @@ -467,10 +472,11 @@ public class CallNotificationController extends BaseController { } private void dispose() { - Disposable disposable; - for (int i = 0; i < disposablesList.size(); i++) { - if (!(disposable = disposablesList.get(i)).isDisposed()) { - disposable.dispose(); + if (disposablesList != null) { + for (Disposable disposable : disposablesList) { + if (!disposable.isDisposed()) { + disposable.dispose(); + } } } } @@ -486,7 +492,8 @@ public class CallNotificationController extends BaseController { "/raw/librem_by_feandesign_call"); } else { try { - RingtoneSettings ringtoneSettings = LoganSquare.parse(callRingtonePreferenceString, RingtoneSettings.class); + RingtoneSettings ringtoneSettings = LoganSquare.parse( + callRingtonePreferenceString, RingtoneSettings.class); ringtoneUri = ringtoneSettings.getRingtoneUri(); } catch (IOException e) { Log.e(TAG, "Failed to parse ringtone settings"); @@ -501,8 +508,11 @@ public class CallNotificationController extends BaseController { mediaPlayer.setDataSource(getActivity(), ringtoneUri); mediaPlayer.setLooping(true); - AudioAttributes audioAttributes = new AudioAttributes.Builder().setContentType(AudioAttributes - .CONTENT_TYPE_SONIFICATION).setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE).build(); + AudioAttributes audioAttributes = new AudioAttributes + .Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE) + .build(); mediaPlayer.setAudioAttributes(audioAttributes); mediaPlayer.setOnPreparedListener(mp -> mediaPlayer.start()); diff --git a/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/OperationsMenuController.java b/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/OperationsMenuController.java index 650f468be..2f2230c4e 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/OperationsMenuController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/bottomsheet/OperationsMenuController.java @@ -565,7 +565,7 @@ public class OperationsMenuController extends BaseController { ApiUtils.getConversationApiVersion(currentUser, new int[] {ApiUtils.APIv4, 1}); ApiUtils.getCallApiVersion(currentUser, new int[] {ApiUtils.APIv4, 1}); ApiUtils.getChatApiVersion(currentUser, new int[] {1}); - ApiUtils.getSignalingApiVersion(currentUser, new int[] {2, 1}); + ApiUtils.getSignalingApiVersion(currentUser, new int[] {ApiUtils.APIv3, 2, 1}); } private void inviteUsersToAConversation() { diff --git a/app/src/main/java/com/nextcloud/talk/jobs/SignalingSettingsWorker.java b/app/src/main/java/com/nextcloud/talk/jobs/SignalingSettingsWorker.java index fad4021bf..fcc6b802e 100644 --- a/app/src/main/java/com/nextcloud/talk/jobs/SignalingSettingsWorker.java +++ b/app/src/main/java/com/nextcloud/talk/jobs/SignalingSettingsWorker.java @@ -90,7 +90,7 @@ public class SignalingSettingsWorker extends Worker { userEntity = userEntityList.get(i); UserEntity finalUserEntity = userEntity; - int apiVersion = ApiUtils.getSignalingApiVersion(finalUserEntity, new int[] {2, 1}); + int apiVersion = ApiUtils.getSignalingApiVersion(finalUserEntity, new int[] {ApiUtils.APIv3, 2, 1}); ncApi.getSignalingSettings(ApiUtils.getCredentials(userEntity.getUsername(), userEntity.getToken()), ApiUtils.getUrlForSignalingSettings(apiVersion, userEntity.getBaseUrl())) diff --git a/app/src/main/java/com/nextcloud/talk/models/json/signaling/settings/IceServer.java b/app/src/main/java/com/nextcloud/talk/models/json/signaling/settings/IceServer.java index 428660e9b..1df8eaa40 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/signaling/settings/IceServer.java +++ b/app/src/main/java/com/nextcloud/talk/models/json/signaling/settings/IceServer.java @@ -27,6 +27,7 @@ import java.util.List; @JsonObject public class IceServer { + @Deprecated @JsonField(name = "url") String url; @@ -39,6 +40,7 @@ public class IceServer { @JsonField(name = "credential") String credential; + @Deprecated public String getUrl() { return this.url; } diff --git a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java index 5870a1114..a95717788 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java +++ b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java @@ -146,12 +146,19 @@ public class ApiUtils { public static int getSignalingApiVersion(UserEntity capabilities, int[] versions) throws NoSupportedApiException { for (int version : versions) { - if (version == 2 && capabilities.hasSpreedFeatureCapability("sip-support")) { + if (capabilities.hasSpreedFeatureCapability("signaling-v" + version)) { return version; } - if (version == 1) { - // Has no capability, we just assume it is always there for now. + if (version == 2 && + capabilities.hasSpreedFeatureCapability("sip-support") && + !capabilities.hasSpreedFeatureCapability("signaling-v3")) { + return version; + } + + if (version == 1 && + !capabilities.hasSpreedFeatureCapability("signaling-v3")) { + // Has no capability, we just assume it is always there when there is no v3 or later return version; } } diff --git a/app/src/main/java/com/nextcloud/talk/webrtc/WebSocketConnectionHelper.java b/app/src/main/java/com/nextcloud/talk/webrtc/WebSocketConnectionHelper.java index 004027087..3ae978c30 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/WebSocketConnectionHelper.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/WebSocketConnectionHelper.java @@ -101,7 +101,7 @@ public class WebSocketConnectionHelper { } HelloOverallWebSocketMessage getAssembledHelloModel(UserEntity userEntity, String ticket) { - int apiVersion = ApiUtils.getSignalingApiVersion(userEntity, new int[] {2, 1}); + int apiVersion = ApiUtils.getSignalingApiVersion(userEntity, new int[] {ApiUtils.APIv3, 2, 1}); HelloOverallWebSocketMessage helloOverallWebSocketMessage = new HelloOverallWebSocketMessage(); helloOverallWebSocketMessage.setType("hello"); diff --git a/scripts/analysis/findbugs-results.txt b/scripts/analysis/findbugs-results.txt index 88101bccd..7d4983b98 100644 --- a/scripts/analysis/findbugs-results.txt +++ b/scripts/analysis/findbugs-results.txt @@ -1 +1 @@ -465 \ No newline at end of file +458 \ No newline at end of file