diff --git a/app/src/gplay/java/com/nextcloud/talk/services/firebase/MagicFirebaseMessagingService.kt b/app/src/gplay/java/com/nextcloud/talk/services/firebase/MagicFirebaseMessagingService.kt index f966235f5..319565de7 100644 --- a/app/src/gplay/java/com/nextcloud/talk/services/firebase/MagicFirebaseMessagingService.kt +++ b/app/src/gplay/java/com/nextcloud/talk/services/firebase/MagicFirebaseMessagingService.kt @@ -302,9 +302,12 @@ class MagicFirebaseMessagingService : FirebaseMessagingService() { var hasParticipantsInCall = false var inCallOnDifferentDevice = false + val apiVersion = ApiUtils.getConversationApiVersion(signatureVerification.userEntity, intArrayOf(1)) + ncApi.getPeersForCall( ApiUtils.getCredentials(signatureVerification.userEntity.username, signatureVerification.userEntity.token), ApiUtils.getUrlForCall( + apiVersion, signatureVerification.userEntity.baseUrl, decryptedPushMessage.id ) diff --git a/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt b/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt index 897ebbb15..486253ec9 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt @@ -229,9 +229,10 @@ class MainActivity : BaseActivity(), ActionBarProvider { val roomType = "1" val currentUser = userUtils.currentUser ?: return + val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(1)) val credentials = ApiUtils.getCredentials(currentUser.username, currentUser.token) val retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom( - currentUser.baseUrl, roomType, + apiVersion, currentUser.baseUrl, roomType, userId, null ) ncApi.createRoom( @@ -251,7 +252,8 @@ class MainActivity : BaseActivity(), ActionBarProvider { if (currentUser.hasSpreedFeatureCapability("chat-v2")) { ncApi.getRoom( credentials, - ApiUtils.getRoom( + ApiUtils.getUrlForRoom( + apiVersion, currentUser.baseUrl, roomOverall.ocs.data.token ) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/AccountVerificationController.java b/app/src/main/java/com/nextcloud/talk/controllers/AccountVerificationController.java index 9ad6f13a6..30f1f532b 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/AccountVerificationController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/AccountVerificationController.java @@ -46,6 +46,7 @@ import com.nextcloud.talk.jobs.CapabilitiesWorker; import com.nextcloud.talk.jobs.PushRegistrationWorker; import com.nextcloud.talk.jobs.SignalingSettingsWorker; import com.nextcloud.talk.models.database.UserEntity; +import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall; import com.nextcloud.talk.models.json.generic.Status; import com.nextcloud.talk.models.json.conversations.RoomsOverall; import com.nextcloud.talk.models.json.userprofile.UserProfileOverall; @@ -221,17 +222,35 @@ public class AccountVerificationController extends BaseController { } private void findServerTalkApp(String credentials) { - ncApi.getRooms(credentials, ApiUtils.getUrlForGetRooms(baseUrl)) + ncApi.getCapabilities(credentials, ApiUtils.getUrlForCapabilities(baseUrl)) .subscribeOn(Schedulers.io()) - .subscribe(new Observer() { + .subscribe(new Observer() { @Override public void onSubscribe(Disposable d) { disposables.add(d); } @Override - public void onNext(RoomsOverall roomsOverall) { - fetchProfile(credentials); + public void onNext(CapabilitiesOverall capabilitiesOverall) { + boolean hasTalk = + capabilitiesOverall.getOcs().getData().getCapabilities() != null + && capabilitiesOverall.getOcs().getData().getCapabilities().getSpreedCapability() != null + && capabilitiesOverall.getOcs().getData().getCapabilities().getSpreedCapability().getFeatures() != null + && !capabilitiesOverall.getOcs().getData().getCapabilities().getSpreedCapability().getFeatures().isEmpty(); + + if (hasTalk) { + fetchProfile(credentials); + } else { + if (getActivity() != null && getResources() != null) { + getActivity().runOnUiThread(() -> progressText.setText(String.format(getResources().getString( + R.string.nc_nextcloud_talk_app_not_installed), getResources().getString(R.string.nc_app_name)))); + } + + ApplicationWideMessageHolder.getInstance().setMessageType( + ApplicationWideMessageHolder.MessageType.SERVER_WITHOUT_TALK); + + abortVerification(); + } } @Override 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 21416baca..7dc788631 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/CallController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/CallController.java @@ -441,7 +441,9 @@ public class CallController extends BaseController { } private void handleFromNotification() { - ncApi.getRooms(credentials, ApiUtils.getUrlForGetRooms(baseUrl)) + int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[] {1}); + + ncApi.getRooms(credentials, ApiUtils.getUrlForRooms(apiVersion, baseUrl)) .retry(3) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) @@ -1097,7 +1099,9 @@ public class CallController extends BaseController { } private void fetchSignalingSettings() { - ncApi.getSignalingSettings(credentials, ApiUtils.getUrlForSignalingSettings(baseUrl)) + int apiVersion = ApiUtils.getSignalingApiVersion(conversationUser, new int[] {2, 1}); + + ncApi.getSignalingSettings(credentials, ApiUtils.getUrlForSignalingSettings(apiVersion, baseUrl)) .subscribeOn(Schedulers.io()) .retry(3) .observeOn(AndroidSchedulers.mainThread()) @@ -1234,9 +1238,11 @@ public class CallController extends BaseController { private void joinRoomAndCall() { callSession = ApplicationWideCurrentRoomHolder.getInstance().getSession(); + int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[] {1}); + if (TextUtils.isEmpty(callSession)) { - ncApi.joinRoom(credentials, ApiUtils.getUrlForSettingMyselfAsActiveParticipant(baseUrl, - roomToken), conversationPassword) + ncApi.joinRoom(credentials, ApiUtils.getUrlForParticipantsActive(apiVersion, baseUrl, roomToken), + conversationPassword) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .retry(3) @@ -1288,8 +1294,9 @@ public class CallController extends BaseController { inCallFlag = (int) Participant.ParticipantFlags.IN_CALL_WITH_AUDIO_AND_VIDEO.getValue(); } - ncApi.joinCall(credentials, - ApiUtils.getUrlForCall(baseUrl, roomToken), inCallFlag) + int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[] {1}); + + ncApi.joinCall(credentials, ApiUtils.getUrlForCall(apiVersion, baseUrl, roomToken), inCallFlag) .subscribeOn(Schedulers.io()) .retry(3) .observeOn(AndroidSchedulers.mainThread()) @@ -1349,7 +1356,10 @@ public class CallController extends BaseController { } if (!hasExternalSignalingServer) { - ncApi.pullSignalingMessages(credentials, ApiUtils.getUrlForSignaling(baseUrl, urlToken)) + int apiVersion = ApiUtils.getSignalingApiVersion(conversationUser, new int[] {2, 1}); + + ncApi.pullSignalingMessages(credentials, ApiUtils.getUrlForSignaling(apiVersion, + baseUrl, urlToken)) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .repeatWhen(observable -> observable) @@ -1613,7 +1623,9 @@ public class CallController extends BaseController { } private void hangupNetworkCalls(boolean shutDownView) { - ncApi.leaveCall(credentials, ApiUtils.getUrlForCall(baseUrl, roomToken)) + int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[] {1}); + + ncApi.leaveCall(credentials, ApiUtils.getUrlForCall(apiVersion, baseUrl, roomToken)) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer() { @@ -1648,7 +1660,9 @@ public class CallController extends BaseController { } private void leaveRoom(boolean shutDownView) { - ncApi.leaveRoom(credentials, ApiUtils.getUrlForSettingMyselfAsActiveParticipant(baseUrl, roomToken)) + int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[] {1}); + + ncApi.leaveRoom(credentials, ApiUtils.getUrlForParticipantsActive(apiVersion, baseUrl, roomToken)) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer() { @@ -1741,7 +1755,9 @@ public class CallController extends BaseController { private void getPeersForCall() { Log.d(TAG, "getPeersForCall"); - ncApi.getPeersForCall(credentials, ApiUtils.getUrlForCall(baseUrl, roomToken)) + int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[] {1}); + + ncApi.getPeersForCall(credentials, ApiUtils.getUrlForCall(apiVersion, baseUrl, roomToken)) .subscribeOn(Schedulers.io()) .subscribe(new Observer() { @Override @@ -2045,7 +2061,9 @@ public class CallController extends BaseController { urlToken = roomToken; } - ncApi.sendSignalingMessages(credentials, ApiUtils.getUrlForSignaling(baseUrl, urlToken), + int apiVersion = ApiUtils.getSignalingApiVersion(conversationUser, new int[] {2, 1}); + + ncApi.sendSignalingMessages(credentials, ApiUtils.getUrlForSignaling(apiVersion, baseUrl, urlToken), strings.toString()) .retry(3) .subscribeOn(Schedulers.io()) 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 2ccd5a57b..b225c12d8 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/CallNotificationController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/CallNotificationController.java @@ -209,7 +209,9 @@ public class CallNotificationController extends BaseController { } private void checkIfAnyParticipantsRemainInRoom() { - ncApi.getPeersForCall(credentials, ApiUtils.getUrlForCall(userBeingCalled.getBaseUrl(), + int apiVersion = ApiUtils.getConversationApiVersion(userBeingCalled, new int[] {1}); + + ncApi.getPeersForCall(credentials, ApiUtils.getUrlForCall(apiVersion, userBeingCalled.getBaseUrl(), currentConversation.getToken())) .subscribeOn(Schedulers.io()) .takeWhile(observable -> !leavingScreen) @@ -258,23 +260,24 @@ public class CallNotificationController extends BaseController { } private void handleFromNotification() { - boolean isConversationApiV3 = userBeingCalled.hasSpreedFeatureCapability("conversation-v3"); - if (isConversationApiV3) { - ncApi.getRoom(credentials, ApiUtils.getRoomV3(userBeingCalled.getBaseUrl(), roomId)) - .subscribeOn(Schedulers.io()) - .retry(3) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Observer() { - @Override - public void onSubscribe(Disposable d) { - disposablesList.add(d); - } + int apiVersion = ApiUtils.getConversationApiVersion(userBeingCalled, new int[] {4, 3, 1}); - @Override - public void onNext(@NotNull RoomOverall roomOverall) { - currentConversation = roomOverall.getOcs().data; - runAllThings(); + ncApi.getRoom(credentials, ApiUtils.getUrlForRoom(apiVersion, userBeingCalled.getBaseUrl(), roomId)) + .subscribeOn(Schedulers.io()) + .retry(3) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + disposablesList.add(d); + } + @Override + public void onNext(@NotNull RoomOverall roomOverall) { + currentConversation = roomOverall.getOcs().data; + runAllThings(); + + if (apiVersion >= 3) { boolean hasCallFlags = userBeingCalled.hasSpreedFeatureCapability("conversation-call-flags"); if (hasCallFlags) { if (isInCallWithVideo(currentConversation.callFlag)) { @@ -286,46 +289,19 @@ public class CallNotificationController extends BaseController { } } } + } - @Override - public void onError(Throwable e) { + @SuppressLint("LongLogTag") + @Override + public void onError(Throwable e) { + Log.e(TAG, e.getMessage(), e); + } - } + @Override + public void onComplete() { - @Override - public void onComplete() { - - } - }); - } else { - ncApi.getRoom(credentials, ApiUtils.getRoom(userBeingCalled.getBaseUrl(), roomId)) - .subscribeOn(Schedulers.io()) - .retry(3) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Observer() { - @Override - public void onSubscribe(Disposable d) { - disposablesList.add(d); - } - - @SuppressLint("LongLogTag") - @Override - public void onNext(@NotNull RoomOverall roomOverall) { - currentConversation = roomOverall.getOcs().data; - runAllThings(); - } - - @Override - public void onError(Throwable e) { - - } - - @Override - public void onComplete() { - - } - }); - } + } + }); } private boolean isInCallWithVideo(int callFlag) { diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt index e4e7b63c2..7ae8d7f01 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt @@ -293,7 +293,9 @@ class ChatController(args: Bundle) : } if (conversationUser != null) { - ncApi?.getRoom(credentials, ApiUtils.getRoom(conversationUser.baseUrl, roomToken)) + val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(1)) + + ncApi?.getRoom(credentials, ApiUtils.getUrlForRoom(apiVersion, conversationUser.baseUrl, roomToken)) ?.subscribeOn(Schedulers.io()) ?.observeOn(AndroidSchedulers.mainThread()) ?.subscribe(object : Observer { @@ -332,7 +334,13 @@ class ChatController(args: Bundle) : } private fun handleFromNotification() { - ncApi?.getRooms(credentials, ApiUtils.getUrlForGetRooms(conversationUser?.baseUrl)) + var apiVersion = 1 + // FIXME Can this be called for guests? + if (conversationUser != null) { + apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(1)) + } + + ncApi?.getRooms(credentials, ApiUtils.getUrlForRooms(apiVersion, conversationUser?.baseUrl)) ?.subscribeOn(Schedulers.io())?.observeOn(AndroidSchedulers.mainThread()) ?.subscribe(object : Observer { override fun onSubscribe(d: Disposable) { @@ -958,9 +966,16 @@ class ChatController(args: Bundle) : if (currentConversation == null || TextUtils.isEmpty(currentConversation?.sessionId) || currentConversation?.sessionId == "0" ) { + var apiVersion = 1 + // FIXME Fix API checking with guests? + if (conversationUser != null) { + apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(1)) + } + ncApi?.joinRoom( credentials, - ApiUtils.getUrlForSettingMyselfAsActiveParticipant(conversationUser?.baseUrl, roomToken), roomPassword + ApiUtils.getUrlForParticipantsActive(apiVersion, conversationUser?.baseUrl, roomToken), + roomPassword ) ?.subscribeOn(Schedulers.io()) ?.observeOn(AndroidSchedulers.mainThread()) @@ -1024,9 +1039,16 @@ class ChatController(args: Bundle) : } private fun leaveRoom() { + var apiVersion = 1 + // FIXME Fix API checking with guests? + if (conversationUser != null) { + apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(1)) + } + ncApi?.leaveRoom( credentials, - ApiUtils.getUrlForSettingMyselfAsActiveParticipant( + ApiUtils.getUrlForParticipantsActive( + apiVersion, conversationUser?.baseUrl, roomToken ) @@ -1107,9 +1129,11 @@ class ChatController(args: Bundle) : private fun sendMessage(message: CharSequence, replyTo: Int?) { if (conversationUser != null) { + val apiVersion = ApiUtils.getChatApiVersion(conversationUser, intArrayOf(1)) + ncApi!!.sendChatMessage( credentials, - ApiUtils.getUrlForChat(conversationUser.baseUrl, roomToken), + ApiUtils.getUrlForChat(apiVersion, conversationUser.baseUrl, roomToken), message, conversationUser.displayName, replyTo @@ -1209,11 +1233,17 @@ class ChatController(args: Bundle) : } if (!wasDetached) { + var apiVersion = 1 + // FIXME this is a best guess, guests would need to get the capabilities themselves + if (conversationUser != null) { + apiVersion = ApiUtils.getChatApiVersion(conversationUser, intArrayOf(1)) + } + if (lookIntoFuture > 0) { val finalTimeout = timeout ncApi?.pullChatMessages( credentials, - ApiUtils.getUrlForChat(conversationUser?.baseUrl, roomToken), fieldMap + ApiUtils.getUrlForChat(apiVersion, conversationUser?.baseUrl, roomToken), fieldMap ) ?.subscribeOn(Schedulers.io()) ?.observeOn(AndroidSchedulers.mainThread()) @@ -1242,7 +1272,7 @@ class ChatController(args: Bundle) : } else { ncApi?.pullChatMessages( credentials, - ApiUtils.getUrlForChat(conversationUser?.baseUrl, roomToken), fieldMap + ApiUtils.getUrlForChat(apiVersion, conversationUser?.baseUrl, roomToken), fieldMap ) ?.subscribeOn(Schedulers.io()) ?.observeOn(AndroidSchedulers.mainThread()) @@ -1632,9 +1662,20 @@ class ChatController(args: Bundle) : true } R.id.action_delete_message -> { + var apiVersion = 1 + // FIXME Fix API checking with guests? + if (conversationUser != null) { + apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(1)) + } + ncApi?.deleteChatMessage( credentials, - ApiUtils.getUrlForMessageDeletion(conversationUser?.baseUrl, roomToken, message?.id) + ApiUtils.getUrlForChatMessage( + apiVersion, + conversationUser?.baseUrl, + roomToken, + message?.id + ) )?.subscribeOn(Schedulers.io()) ?.observeOn(AndroidSchedulers.mainThread()) ?.subscribe(object : Observer { @@ -1743,8 +1784,15 @@ class ChatController(args: Bundle) : if (currentConversation?.type != Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL || currentConversation?.name != userMentionClickEvent.userId ) { + + var apiVersion = 1 + // FIXME Fix API checking with guests? + if (conversationUser != null) { + apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(1)) + } + val retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom( - conversationUser?.baseUrl, "1", + apiVersion, conversationUser?.baseUrl, "1", userMentionClickEvent.userId, null ) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.java b/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.java index 4567d7f02..a0f4ff797 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/ContactsController.java @@ -288,8 +288,12 @@ public class ContactsController extends BaseController implements SearchView.OnQ userId = selectedUserIds.iterator().next(); } - RetrofitBucket retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(currentUser.getBaseUrl(), roomType, - userId, null); + int apiVersion = ApiUtils.getConversationApiVersion(currentUser, new int[] {1}); + RetrofitBucket retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(apiVersion, + currentUser.getBaseUrl(), + roomType, + userId, + null); ncApi.createRoom(credentials, retrofitBucket.getUrl(), retrofitBucket.getQueryMap()) .subscribeOn(Schedulers.io()) @@ -310,7 +314,7 @@ public class ContactsController extends BaseController implements SearchView.OnQ if (currentUser.hasSpreedFeatureCapability("chat-v2")) { ncApi.getRoom(credentials, - ApiUtils.getRoom(currentUser.getBaseUrl(), + ApiUtils.getUrlForRoom(apiVersion, currentUser.getBaseUrl(), roomOverall.getOcs().getData().getToken())) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) @@ -848,7 +852,13 @@ public class ContactsController extends BaseController implements SearchView.OnQ roomType = "2"; } - RetrofitBucket retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(currentUser.getBaseUrl(), roomType, userItem.getModel().getUserId(), null); + int apiVersion = ApiUtils.getConversationApiVersion(currentUser, new int[] {1}); + + RetrofitBucket retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(apiVersion, + currentUser.getBaseUrl(), + roomType, + userItem.getModel().getUserId(), + null); ncApi.createRoom(credentials, retrofitBucket.getUrl(), retrofitBucket.getQueryMap()) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt index dda408a6c..bb774eab3 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt @@ -306,9 +306,12 @@ class ConversationInfoController(args: Bundle) : BaseController(args), FlexibleA ) as SwitchCompat ).isChecked ) 1 else 0 + + val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(1)) + ncApi.setLobbyForConversation( ApiUtils.getCredentials(conversationUser!!.username, conversationUser.token), - ApiUtils.getUrlForLobbyForConversation(conversationUser.baseUrl, conversation!!.token), + ApiUtils.getUrlForRoomWebinaryLobby(apiVersion, conversationUser.baseUrl, conversation!!.token), state, conversation!!.lobbyTimer ) @@ -438,9 +441,15 @@ class ConversationInfoController(args: Bundle) : BaseController(args), FlexibleA } private fun getListOfParticipants() { + var apiVersion = 1 + // FIXME Fix API checking with guests? + if (conversationUser != null) { + apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(1)) + } + ncApi.getPeersForCall( credentials, - ApiUtils.getUrlForParticipants(conversationUser!!.baseUrl, conversationToken) + ApiUtils.getUrlForParticipants(apiVersion, conversationUser!!.baseUrl, conversationToken) ) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) @@ -527,7 +536,13 @@ class ConversationInfoController(args: Bundle) : BaseController(args), FlexibleA } private fun fetchRoomInfo() { - ncApi.getRoom(credentials, ApiUtils.getRoom(conversationUser!!.baseUrl, conversationToken)) + var apiVersion = 1 + // FIXME Fix API checking with guests? + if (conversationUser != null) { + apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(1)) + } + + ncApi.getRoom(credentials, ApiUtils.getUrlForRoom(apiVersion, conversationUser!!.baseUrl, conversationToken)) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(object : Observer { @@ -701,11 +716,17 @@ class ConversationInfoController(args: Bundle) : BaseController(args), FlexibleA title(text = participant.displayName) listItemsWithImage(items = items) { dialog, index, _ -> + val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(1)) + if (index == 0) { if (participant.type == Participant.ParticipantType.MODERATOR) { ncApi.demoteModeratorToUser( credentials, - ApiUtils.getUrlForModerators(conversationUser.baseUrl, conversation!!.token), + ApiUtils.getUrlForRoomModerators( + apiVersion, + conversationUser.baseUrl, + conversation!!.token + ), participant.userId ) .subscribeOn(Schedulers.io()) @@ -716,7 +737,11 @@ class ConversationInfoController(args: Bundle) : BaseController(args), FlexibleA } else if (participant.type == Participant.ParticipantType.USER) { ncApi.promoteUserToModerator( credentials, - ApiUtils.getUrlForModerators(conversationUser.baseUrl, conversation!!.token), + ApiUtils.getUrlForRoomModerators( + apiVersion, + conversationUser.baseUrl, + conversation!!.token + ), participant.userId ) .subscribeOn(Schedulers.io()) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java b/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java index 2fb61a98e..0fff10672 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java @@ -418,7 +418,10 @@ public class ConversationsListController extends BaseController implements Searc callItems = new ArrayList<>(); - roomsQueryDisposable = ncApi.getRooms(credentials, ApiUtils.getUrlForGetRooms(currentUser.getBaseUrl())) + int apiVersion = ApiUtils.getConversationApiVersion(currentUser, new int[] {4, 1}); + + roomsQueryDisposable = ncApi.getRooms(credentials, ApiUtils.getUrlForRooms(apiVersion, + currentUser.getBaseUrl())) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(roomsOverall -> { 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 fd2eeb9d4..d3bea42d3 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 @@ -185,13 +185,20 @@ public class OperationsMenuController extends BaseController { if (currentUser != null) { credentials = ApiUtils.getCredentials(currentUser.getUsername(), currentUser.getToken()); + int apiVersion; if (!TextUtils.isEmpty(baseUrl) && !baseUrl.equals(currentUser.getBaseUrl())) { credentials = null; + // FIXME joining a public link we need to check other capabilities + apiVersion = 1; + } else { + apiVersion = ApiUtils.getConversationApiVersion(currentUser, new int[] {1}); } + switch (operationCode) { case 2: - ncApi.renameRoom(credentials, ApiUtils.getRoom(currentUser.getBaseUrl(), conversation.getToken()), + ncApi.renameRoom(credentials, ApiUtils.getUrlForRoom(apiVersion, currentUser.getBaseUrl(), + conversation.getToken()), conversation.getName()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) @@ -199,8 +206,8 @@ public class OperationsMenuController extends BaseController { .subscribe(operationsObserver); break; case 3: - ncApi.makeRoomPublic(credentials, ApiUtils.getUrlForRoomVisibility(currentUser.getBaseUrl(), conversation - .getToken())) + ncApi.makeRoomPublic(credentials, ApiUtils.getUrlForRoomPublic(apiVersion, currentUser.getBaseUrl(), + conversation.getToken())) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .retry(1) @@ -213,8 +220,8 @@ public class OperationsMenuController extends BaseController { if (conversation.getPassword() != null) { pass = conversation.getPassword(); } - ncApi.setPassword(credentials, ApiUtils.getUrlForPassword(currentUser.getBaseUrl(), - conversation.getToken()), pass) + ncApi.setPassword(credentials, ApiUtils.getUrlForRoomPassword(apiVersion, currentUser.getBaseUrl(), + conversation.getToken()), pass) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .retry(1) @@ -224,15 +231,16 @@ public class OperationsMenuController extends BaseController { // Operation 7 is sharing, so we handle this differently break; case 8: - ncApi.makeRoomPrivate(credentials, ApiUtils.getUrlForRoomVisibility(currentUser.getBaseUrl(), conversation - .getToken())) + ncApi.makeRoomPrivate(credentials, ApiUtils.getUrlForRoomPublic(apiVersion, + currentUser.getBaseUrl(), + conversation.getToken())) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .retry(1) .subscribe(operationsObserver); break; case 10: - ncApi.getRoom(credentials, ApiUtils.getRoom(baseUrl, conversationToken)) + ncApi.getRoom(credentials, ApiUtils.getUrlForRoom(apiVersion, baseUrl, conversationToken)) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .retry(1) @@ -271,7 +279,7 @@ public class OperationsMenuController extends BaseController { if (conversationType.equals(Conversation.ConversationType.ROOM_PUBLIC_CALL) || !currentUser.hasSpreedFeatureCapability("empty-group-room")) { - retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(currentUser.getBaseUrl(), + retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(apiVersion, currentUser.getBaseUrl(), "3", invite, conversationName); } else { String roomType = "2"; @@ -280,7 +288,7 @@ public class OperationsMenuController extends BaseController { roomType = "3"; } - retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(currentUser.getBaseUrl(), + retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom(apiVersion, currentUser.getBaseUrl(), roomType, invite, conversationName); } @@ -300,7 +308,8 @@ public class OperationsMenuController extends BaseController { conversation = roomOverall.getOcs().getData(); ncApi.getRoom(credentials, - ApiUtils.getRoom(currentUser.getBaseUrl(), conversation.getToken())) + ApiUtils.getUrlForRoom(apiVersion, currentUser.getBaseUrl(), + conversation.getToken())) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer() { @@ -349,15 +358,19 @@ public class OperationsMenuController extends BaseController { case 97: case 98: if (operationCode == 97) { - ncApi.removeConversationFromFavorites(credentials, ApiUtils.getUrlForConversationFavorites(currentUser.getBaseUrl(), - conversation.getToken())) + ncApi.removeConversationFromFavorites(credentials, + ApiUtils.getUrlForRoomFavorite(apiVersion, + currentUser.getBaseUrl(), + conversation.getToken())) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .retry(1) .subscribe(operationsObserver); } else { - ncApi.addConversationToFavorites(credentials, ApiUtils.getUrlForConversationFavorites(currentUser.getBaseUrl(), - conversation.getToken())) + ncApi.addConversationToFavorites(credentials, + ApiUtils.getUrlForRoomFavorite(apiVersion, + currentUser.getBaseUrl(), + conversation.getToken())) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .retry(1) @@ -365,7 +378,9 @@ public class OperationsMenuController extends BaseController { } break; case 99: - ncApi.joinRoom(credentials, ApiUtils.getUrlForSettingMyselfAsActiveParticipant(baseUrl, conversationToken), + ncApi.joinRoom(credentials, ApiUtils.getUrlForParticipantsActive(apiVersion, + baseUrl, + conversationToken), callPassword) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) @@ -379,7 +394,10 @@ public class OperationsMenuController extends BaseController { } private void performGroupCallWorkaround(String credentials) { - ncApi.makeRoomPrivate(credentials, ApiUtils.getUrlForRoomVisibility(currentUser.getBaseUrl(), conversation.getToken())) + int apiVersion = ApiUtils.getConversationApiVersion(currentUser, new int[] {1}); + + ncApi.makeRoomPrivate(credentials, ApiUtils.getUrlForRoomPublic(apiVersion, currentUser.getBaseUrl(), + conversation.getToken())) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .retry(1) @@ -534,11 +552,15 @@ public class OperationsMenuController extends BaseController { localInvitedGroups.remove(0); } + int apiVersion = ApiUtils.getConversationApiVersion(currentUser, new int[] {1}); + if (localInvitedUsers.size() > 0 || (localInvitedGroups.size() > 0 && currentUser.hasSpreedFeatureCapability("invite-groups-and-mails"))) { if ((localInvitedGroups.size() > 0 && currentUser.hasSpreedFeatureCapability("invite-groups-and-mails"))) { for (int i = 0; i < localInvitedGroups.size(); i++) { final String groupId = localInvitedGroups.get(i); - retrofitBucket = ApiUtils.getRetrofitBucketForAddGroupParticipant(currentUser.getBaseUrl(), conversation.getToken(), + retrofitBucket = ApiUtils.getRetrofitBucketForAddGroupParticipant(apiVersion, + currentUser.getBaseUrl(), + conversation.getToken(), groupId); ncApi.addParticipant(credentials, retrofitBucket.getUrl(), retrofitBucket.getQueryMap()) @@ -578,8 +600,10 @@ public class OperationsMenuController extends BaseController { for (int i = 0; i < localInvitedUsers.size(); i++) { final String userId = invitedUsers.get(i); - retrofitBucket = ApiUtils.getRetrofitBucketForAddParticipant(currentUser.getBaseUrl(), conversation.getToken(), - userId); + retrofitBucket = ApiUtils.getRetrofitBucketForAddParticipant(apiVersion, + currentUser.getBaseUrl(), + conversation.getToken(), + userId); ncApi.addParticipant(credentials, retrofitBucket.getUrl(), retrofitBucket.getQueryMap()) .subscribeOn(Schedulers.io()) diff --git a/app/src/main/java/com/nextcloud/talk/jobs/AddParticipantsToConversation.java b/app/src/main/java/com/nextcloud/talk/jobs/AddParticipantsToConversation.java index cb2d8cb4d..cf0b6846e 100644 --- a/app/src/main/java/com/nextcloud/talk/jobs/AddParticipantsToConversation.java +++ b/app/src/main/java/com/nextcloud/talk/jobs/AddParticipantsToConversation.java @@ -33,8 +33,6 @@ import com.nextcloud.talk.utils.database.user.UserUtils; import org.greenrobot.eventbus.EventBus; -import java.util.ArrayList; - import javax.inject.Inject; import androidx.annotation.NonNull; @@ -67,12 +65,16 @@ public class AddParticipantsToConversation extends Worker { String[] selectedUserIds = data.getStringArray(BundleKeys.INSTANCE.getKEY_SELECTED_USERS()); String[] selectedGroupIds = data.getStringArray(BundleKeys.INSTANCE.getKEY_SELECTED_GROUPS()); UserEntity user = userUtils.getUserWithInternalId(data.getLong(BundleKeys.INSTANCE.getKEY_INTERNAL_USER_ID(), -1)); + + int apiVersion = ApiUtils.getConversationApiVersion(user, new int[] {1}); + String conversationToken = data.getString(BundleKeys.INSTANCE.getKEY_TOKEN()); String credentials = ApiUtils.getCredentials(user.getUsername(), user.getToken()); RetrofitBucket retrofitBucket; for (String userId : selectedUserIds) { - retrofitBucket = ApiUtils.getRetrofitBucketForAddParticipant(user.getBaseUrl(), conversationToken, + retrofitBucket = ApiUtils.getRetrofitBucketForAddParticipant(apiVersion, user.getBaseUrl(), + conversationToken, userId); ncApi.addParticipant(credentials, retrofitBucket.getUrl(), retrofitBucket.getQueryMap()) @@ -81,7 +83,7 @@ public class AddParticipantsToConversation extends Worker { } for (String groupId : selectedGroupIds) { - retrofitBucket = ApiUtils.getRetrofitBucketForAddGroupParticipant(user.getBaseUrl(), conversationToken, + retrofitBucket = ApiUtils.getRetrofitBucketForAddGroupParticipant(apiVersion, user.getBaseUrl(), conversationToken, groupId); ncApi.addParticipant(credentials, retrofitBucket.getUrl(), retrofitBucket.getQueryMap()) diff --git a/app/src/main/java/com/nextcloud/talk/jobs/DeleteConversationWorker.java b/app/src/main/java/com/nextcloud/talk/jobs/DeleteConversationWorker.java index 0bde3e7ac..b22e1adfd 100644 --- a/app/src/main/java/com/nextcloud/talk/jobs/DeleteConversationWorker.java +++ b/app/src/main/java/com/nextcloud/talk/jobs/DeleteConversationWorker.java @@ -75,6 +75,8 @@ public class DeleteConversationWorker extends Worker { UserEntity operationUser = userUtils.getUserWithId(operationUserId); if (operationUser != null) { + int apiVersion = ApiUtils.getConversationApiVersion(operationUser, new int[] {1}); + String credentials = ApiUtils.getCredentials(operationUser.getUsername(), operationUser.getToken()); ncApi = retrofit.newBuilder().client(okHttpClient.newBuilder().cookieJar(new JavaNetCookieJar(new CookieManager())).build()).build().create(NcApi.class); @@ -82,7 +84,8 @@ public class DeleteConversationWorker extends Worker { EventStatus eventStatus = new EventStatus(operationUser.getId(), EventStatus.EventType.CONVERSATION_UPDATE, true); - ncApi.deleteRoom(credentials, ApiUtils.getRoom(operationUser.getBaseUrl(), conversationToken)) + ncApi.deleteRoom(credentials, ApiUtils.getUrlForRoom(apiVersion, operationUser.getBaseUrl(), + conversationToken)) .subscribeOn(Schedulers.io()) .blockingSubscribe(new Observer() { Disposable disposable; diff --git a/app/src/main/java/com/nextcloud/talk/jobs/LeaveConversationWorker.java b/app/src/main/java/com/nextcloud/talk/jobs/LeaveConversationWorker.java index c1a59096f..3704b5d2f 100644 --- a/app/src/main/java/com/nextcloud/talk/jobs/LeaveConversationWorker.java +++ b/app/src/main/java/com/nextcloud/talk/jobs/LeaveConversationWorker.java @@ -47,6 +47,7 @@ import java.net.CookieManager; @AutoInjector(NextcloudTalkApplication.class) public class LeaveConversationWorker extends Worker { + @Inject Retrofit retrofit; @@ -82,7 +83,11 @@ public class LeaveConversationWorker extends Worker { EventStatus eventStatus = new EventStatus(operationUser.getId(), EventStatus.EventType.CONVERSATION_UPDATE, true); - ncApi.removeSelfFromRoom(credentials, ApiUtils.getUrlForRemoveSelfFromRoom(operationUser.getBaseUrl(), conversationToken)) + int apiVersion = ApiUtils.getConversationApiVersion(operationUser, new int[] {1}); + + ncApi.removeSelfFromRoom(credentials, ApiUtils.getUrlForParticipantsSelf(apiVersion, + operationUser.getBaseUrl(), + conversationToken)) .subscribeOn(Schedulers.io()) .blockingSubscribe(new Observer() { Disposable disposable; diff --git a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java index 60ef8115f..ad5f09d2e 100644 --- a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java +++ b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java @@ -152,8 +152,9 @@ public class NotificationWorker extends Worker { importantConversation = Boolean.parseBoolean(arbitraryStorageEntity.getValue()); } + int apiVersion = ApiUtils.getConversationApiVersion(userEntity, new int[] {1}); - ncApi.getRoom(credentials, ApiUtils.getRoom(userEntity.getBaseUrl(), + ncApi.getRoom(credentials, ApiUtils.getUrlForRoom(apiVersion, userEntity.getBaseUrl(), intent.getExtras().getString(BundleKeys.INSTANCE.getKEY_ROOM_TOKEN()))) .blockingSubscribe(new Observer() { @Override 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 7bf50c724..7d640dbc1 100644 --- a/app/src/main/java/com/nextcloud/talk/jobs/SignalingSettingsWorker.java +++ b/app/src/main/java/com/nextcloud/talk/jobs/SignalingSettingsWorker.java @@ -81,8 +81,11 @@ public class SignalingSettingsWorker extends Worker { for (int i = 0; i < userEntityList.size(); i++) { userEntity = userEntityList.get(i); UserEntity finalUserEntity = userEntity; + + int apiVersion = ApiUtils.getSignalingApiVersion(finalUserEntity, new int[] {2, 1}); + ncApi.getSignalingSettings(ApiUtils.getCredentials(userEntity.getUsername(), userEntity.getToken()), - ApiUtils.getUrlForSignalingSettings(userEntity.getBaseUrl())) + ApiUtils.getUrlForSignalingSettings(apiVersion, userEntity.getBaseUrl())) .blockingSubscribe(new Observer() { @Override public void onSubscribe(Disposable d) { diff --git a/app/src/main/java/com/nextcloud/talk/presenters/MentionAutocompletePresenter.java b/app/src/main/java/com/nextcloud/talk/presenters/MentionAutocompletePresenter.java index 22d18e705..c998feaf3 100644 --- a/app/src/main/java/com/nextcloud/talk/presenters/MentionAutocompletePresenter.java +++ b/app/src/main/java/com/nextcloud/talk/presenters/MentionAutocompletePresenter.java @@ -91,9 +91,12 @@ public class MentionAutocompletePresenter extends RecyclerViewPresenter queryString = ""; } + int apiVersion = ApiUtils.getChatApiVersion(currentUser, new int[] {1}); + adapter.setFilter(queryString); - ncApi.getMentionAutocompleteSuggestions(ApiUtils.getCredentials(currentUser.getUsername(), currentUser - .getToken()), ApiUtils.getUrlForMentionSuggestions(currentUser.getBaseUrl(), roomToken), + ncApi.getMentionAutocompleteSuggestions( + ApiUtils.getCredentials(currentUser.getUsername(), currentUser.getToken()), + ApiUtils.getUrlForMentionSuggestions(apiVersion, currentUser.getBaseUrl(), roomToken), queryString, 5) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) 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 14eecdf4a..40a50f07e 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java +++ b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java @@ -21,11 +21,13 @@ package com.nextcloud.talk.utils; import android.net.Uri; import android.text.TextUtils; +import android.util.Log; import com.nextcloud.talk.BuildConfig; import com.nextcloud.talk.R; import com.nextcloud.talk.application.NextcloudTalkApplication; import com.nextcloud.talk.models.RetrofitBucket; +import com.nextcloud.talk.models.database.UserEntity; import java.util.HashMap; import java.util.Map; @@ -35,21 +37,24 @@ import androidx.annotation.Nullable; import okhttp3.Credentials; public class ApiUtils { - private static String ocsApiVersion = "/ocs/v2.php"; - private static String spreedApiVersion = "/apps/spreed/api/v1"; + private static final String TAG = "ApiUtils"; + private static final String ocsApiVersion = "/ocs/v2.php"; + private static final String spreedApiVersion = "/apps/spreed/api/v1"; + private static final String spreedApiBase = ocsApiVersion + "/apps/spreed/api/v"; - private static String userAgent = "Mozilla/5.0 (Android) Nextcloud-Talk v"; + private static final String userAgent = "Mozilla/5.0 (Android) Nextcloud-Talk v"; public static String getUserAgent() { return userAgent + BuildConfig.VERSION_NAME; } - public static String getUrlForLobbyForConversation(String baseUrl, String token) { - return getRoom(baseUrl, token) + "/webinary/lobby"; - } - + /** + * @deprecated This is only supported on API v1-3, in API v4+ please use + * {@link ApiUtils#getUrlForAttendees(int, String, String)} instead. + */ + @Deprecated public static String getUrlForRemovingParticipantFromConversation(String baseUrl, String roomToken, boolean isGuest) { - String url = getUrlForParticipants(baseUrl, roomToken); + String url = getUrlForParticipants(1, baseUrl, roomToken); if (isGuest) { url += "/guests"; @@ -100,41 +105,154 @@ public class ApiUtils { return retrofitBucket; } - - public static String getUrlForSettingNotificationlevel(String baseUrl, String token) { - return getRoom(baseUrl, token) + "/notify"; - } - - public static String getUrlForSettingMyselfAsActiveParticipant(String baseUrl, String token) { - return getRoom(baseUrl, token) + "/participants/active"; - } - - - public static String getUrlForParticipants(String baseUrl, String token) { - return getRoom(baseUrl, token) + "/participants"; - } - public static String getUrlForCapabilities(String baseUrl) { return baseUrl + ocsApiVersion + "/cloud/capabilities"; } - public static String getUrlForGetRooms(String baseUrl) { - return baseUrl + ocsApiVersion + spreedApiVersion + "/room"; + public static int getConversationApiVersion(UserEntity capabilities, int[] versions) throws NoSupportedApiException { + boolean hasApiV4 = false; + for (int version : versions) { + hasApiV4 |= version == 4; + } + + if (!hasApiV4) { + Exception e = new Exception("Api call did not try conversation-v4 api"); + Log.d(TAG, e.getMessage(), e); + } + + for (int version : versions) { + if (capabilities.hasSpreedFeatureCapability("conversation-v" + version)) { + return version; + } + + // Fallback for old API versions + if ((version == 1 || version == 2)) { + if (capabilities.hasSpreedFeatureCapability("conversation-v2")) { + return version; + } + if (version == 1 && capabilities.hasSpreedFeatureCapability("conversation")) { + return version; + } + } + } + throw new NoSupportedApiException(); } - public static String getRoom(String baseUrl, String token) { - return baseUrl + ocsApiVersion + spreedApiVersion + "/room/" + token; + public static int getSignalingApiVersion(UserEntity capabilities, int[] versions) throws NoSupportedApiException { + for (int version : versions) { + if (version == 2 && capabilities.hasSpreedFeatureCapability("sip-support")) { + return version; + } + + if (version == 1) { + // Has no capability, we just assume it is always there for now. + return version; + } + } + throw new NoSupportedApiException(); } - public static String getRoomV3(String baseUrl, String token) { - return baseUrl + ocsApiVersion + "/apps/spreed/api/v3" + "/room/" + token; + public static int getChatApiVersion(UserEntity capabilities, int[] versions) throws NoSupportedApiException { + for (int version : versions) { + if (version == 1 && capabilities.hasSpreedFeatureCapability("chat-v2")) { + // Do not question that chat-v2 capability shows the availability of api/v1/ endpoint *see no evil* + return version; + } + } + throw new NoSupportedApiException(); } - public static RetrofitBucket getRetrofitBucketForCreateRoom(String baseUrl, String roomType, + protected static String getUrlForApi(int version, String baseUrl) { + return baseUrl + spreedApiBase + version; + } + + public static String getUrlForRooms(int version, String baseUrl) { + return getUrlForApi(version, baseUrl) + "/room"; + } + + public static String getUrlForRoom(int version, String baseUrl, String token) { + return getUrlForRooms(version, baseUrl) + "/" + token; + } + + public static String getUrlForAttendees(int version, String baseUrl, String token) { + return getUrlForRoom(version, baseUrl, token) + "/attendees"; + } + + public static String getUrlForParticipants(int version, String baseUrl, String token) { + return getUrlForRoom(version, baseUrl, token) + "/participants"; + } + + public static String getUrlForParticipantsActive(int version, String baseUrl, String token) { + return getUrlForParticipants(version, baseUrl, token) + "/active"; + } + + public static String getUrlForParticipantsSelf(int version, String baseUrl, String token) { + return getUrlForParticipants(version, baseUrl, token) + "/self"; + } + + public static String getUrlForRoomFavorite(int version, String baseUrl, String token) { + return getUrlForRoom(version, baseUrl, token) + "/favorite"; + } + + public static String getUrlForRoomModerators(int version, String baseUrl, String token) { + return getUrlForRoom(version, baseUrl, token) + "/moderators"; + } + + public static String getUrlForRoomNotificationLevel(int version, String baseUrl, String token) { + return getUrlForRoom(version, baseUrl, token) + "/notify"; + } + + public static String getUrlForRoomPublic(int version, String baseUrl, String token) { + return getUrlForRoom(version, baseUrl, token) + "/public"; + } + + public static String getUrlForRoomPassword(int version, String baseUrl, String token) { + return getUrlForRoom(version, baseUrl, token) + "/password"; + } + + public static String getUrlForRoomReadOnlyState(int version, String baseUrl, String token) { + return getUrlForRoom(version, baseUrl, token) + "/read-only"; + } + + public static String getUrlForRoomWebinaryLobby(int version, String baseUrl, String token) { + return getUrlForRoom(version, baseUrl, token) + "/webinary/lobby"; + } + + public static String getUrlForCall(int version, String baseUrl, String token) { + return getUrlForApi(version, baseUrl) + "/call/" + token; + } + public static String getUrlForChat(int version, String baseUrl, String token) { + return getUrlForApi(version, baseUrl) + "/chat/" + token; + } + + public static String getUrlForMentionSuggestions(int version, String baseUrl, String token) { + return getUrlForChat(version, baseUrl, token) + "/mentions"; + } + public static String getUrlForChatMessage(int version, String baseUrl, String token, String messageId) { + return getUrlForChat(version, baseUrl, token) + "/" + messageId; + } + + public static String getUrlForSignaling(int version, String baseUrl) { + return getUrlForApi(version, baseUrl) + "/signaling"; + } + + public static String getUrlForSignalingBackend(int version, String baseUrl) { + return getUrlForSignaling(version, baseUrl) + "/backend"; + } + + public static String getUrlForSignalingSettings(int version, String baseUrl) { + return getUrlForSignaling(version, baseUrl) + "/settings"; + } + + public static String getUrlForSignaling(int version, String baseUrl, String token) { + return getUrlForSignaling(version, baseUrl) + "/" + token; + } + + public static RetrofitBucket getRetrofitBucketForCreateRoom(int version, String baseUrl, String roomType, @Nullable String invite, @Nullable String conversationName) { RetrofitBucket retrofitBucket = new RetrofitBucket(); - retrofitBucket.setUrl(baseUrl + ocsApiVersion + spreedApiVersion + "/room"); + retrofitBucket.setUrl(getUrlForRooms(version, baseUrl)); Map queryMap = new HashMap<>(); queryMap.put("roomType", roomType); @@ -151,9 +269,9 @@ public class ApiUtils { return retrofitBucket; } - public static RetrofitBucket getRetrofitBucketForAddParticipant(String baseUrl, String token, String user) { + public static RetrofitBucket getRetrofitBucketForAddParticipant(int version, String baseUrl, String token, String user) { RetrofitBucket retrofitBucket = new RetrofitBucket(); - retrofitBucket.setUrl(baseUrl + ocsApiVersion + spreedApiVersion + "/room/" + token + "/participants"); + retrofitBucket.setUrl(getUrlForParticipants(version, baseUrl, token)); Map queryMap = new HashMap<>(); @@ -165,65 +283,26 @@ public class ApiUtils { } - public static RetrofitBucket getRetrofitBucketForAddGroupParticipant(String baseUrl, String token, String group) { - RetrofitBucket retrofitBucket = getRetrofitBucketForAddParticipant(baseUrl, token, group); + public static RetrofitBucket getRetrofitBucketForAddGroupParticipant(int version, String baseUrl, String token, String group) { + RetrofitBucket retrofitBucket = getRetrofitBucketForAddParticipant(version, baseUrl, token, group); retrofitBucket.getQueryMap().put("source", "groups"); return retrofitBucket; } - public static RetrofitBucket getRetrofitBucketForAddMailParticipant(String baseUrl, String token, String mail) { - RetrofitBucket retrofitBucket = getRetrofitBucketForAddParticipant(baseUrl, token, mail); + public static RetrofitBucket getRetrofitBucketForAddMailParticipant(int version, String baseUrl, String token, String mail) { + RetrofitBucket retrofitBucket = getRetrofitBucketForAddParticipant(version, baseUrl, token, mail); retrofitBucket.getQueryMap().put("source", "emails"); return retrofitBucket; } - public static String getUrlForRemoveSelfFromRoom(String baseUrl, String token) { - return baseUrl + ocsApiVersion + spreedApiVersion + "/room/" + token + "/participants/self"; - } - - public static String getUrlForRoomVisibility(String baseUrl, String token) { - return baseUrl + ocsApiVersion + spreedApiVersion + "/room/" + token + "/public"; - } - - public static String getUrlForCall(String baseUrl, String token) { - return baseUrl + ocsApiVersion + spreedApiVersion + "/call/" + token; - - } - + /** + * @deprecated Method is only needed before Talk 4 which is from 2018 => todrop + */ + @Deprecated public static String getUrlForCallPing(String baseUrl, String token) { - return getUrlForCall(baseUrl, token) + "/ping"; + return getUrlForCall(1, baseUrl, token) + "/ping"; } - public static String getUrlForChat(String baseUrl, String token) { - return baseUrl + ocsApiVersion + spreedApiVersion + "/chat/" + token; - } - - public static String getUrlForExternalServerAuthBackend(String baseUrl) { - return baseUrl + ocsApiVersion + spreedApiVersion + "/signaling/backend"; - } - - public static String getUrlForMentionSuggestions(String baseUrl, String token) { - return getUrlForChat(baseUrl, token) + "/mentions"; - } - - public static String getUrlForSignaling(String baseUrl, @Nullable String token) { - String signalingUrl = baseUrl + ocsApiVersion + spreedApiVersion + "/signaling"; - if (token == null) { - return signalingUrl; - } else { - return signalingUrl + "/" + token; - } - } - - public static String getUrlForModerators(String baseUrl, String roomToken) { - return getRoom(baseUrl, roomToken) + "/moderators"; - } - - public static String getUrlForSignalingSettings(String baseUrl) { - return getUrlForSignaling(baseUrl, null) + "/settings"; - } - - public static String getUrlForUserProfile(String baseUrl) { return baseUrl + ocsApiVersion + "/cloud/user"; } @@ -233,6 +312,7 @@ public class ApiUtils { } public static String getUrlForUserSettings(String baseUrl) { + // FIXME Introduce API version return baseUrl + ocsApiVersion + spreedApiVersion + "/settings/user"; } @@ -259,10 +339,6 @@ public class ApiUtils { return baseUrl + "/index.php/avatar/guest/" + Uri.encode(name) + "/" + avatarSize; } - public static String getUrlForPassword(String baseUrl, String token) { - return baseUrl + ocsApiVersion + spreedApiVersion + "/room/" + token + "/password"; - } - public static String getCredentials(String username, String token) { if (TextUtils.isEmpty(username) && TextUtils.isEmpty(token)) { return null; @@ -279,18 +355,10 @@ public class ApiUtils { getApplicationContext().getResources().getString(R.string.nc_push_server_url) + "/devices"; } - public static String getUrlForConversationFavorites(String baseUrl, String roomToken) { - return baseUrl + ocsApiVersion + spreedApiVersion + "/room/" + roomToken + "/favorite"; - } - public static String getUrlForNotificationWithId(String baseUrl, String notificationId) { return baseUrl + ocsApiVersion + "/apps/notifications/api/v2/notifications/" + notificationId; } - public static String getUrlForReadOnlyState(String baseUrl, String roomToken) { - return baseUrl + ocsApiVersion + spreedApiVersion + "/room/" + roomToken + "/read-only"; - } - public static String getUrlForSearchByNumber(String baseUrl) { return baseUrl + ocsApiVersion + "/cloud/users/search/by-phone"; } @@ -303,10 +371,6 @@ public class ApiUtils { return baseUrl + "/remote.php/dav/files/" + user + "/" + remotePath; } - public static String getUrlForMessageDeletion(String baseUrl, String token, String messageId) { - return baseUrl + ocsApiVersion + spreedApiVersion + "/chat/" + token + "/" + messageId; - } - public static String getUrlForTempAvatar(String baseUrl) { return baseUrl + ocsApiVersion + "/apps/spreed/temp-user-avatar"; } diff --git a/app/src/main/java/com/nextcloud/talk/utils/NoSupportedApiException.kt b/app/src/main/java/com/nextcloud/talk/utils/NoSupportedApiException.kt new file mode 100644 index 000000000..450963486 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/utils/NoSupportedApiException.kt @@ -0,0 +1,23 @@ +/* + * Nextcloud Talk application + * + * @author Joas Schilling + * Copyright (C) 2021 Joas Schilling + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.nextcloud.talk.utils + +class NoSupportedApiException : RuntimeException("No supported API version found") diff --git a/app/src/main/java/com/nextcloud/talk/utils/preferences/preferencestorage/DatabaseStorageModule.java b/app/src/main/java/com/nextcloud/talk/utils/preferences/preferencestorage/DatabaseStorageModule.java index 61f127a95..b0b5b3cc2 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/preferences/preferencestorage/DatabaseStorageModule.java +++ b/app/src/main/java/com/nextcloud/talk/utils/preferences/preferencestorage/DatabaseStorageModule.java @@ -53,6 +53,7 @@ public class DatabaseStorageModule implements StorageModule { private boolean lobbyValue; private String messageNotificationLevel; + public DatabaseStorageModule(UserEntity conversationUser, String conversationToken) { NextcloudTalkApplication.Companion.getSharedApplication().getComponentApplication().inject(this); @@ -92,8 +93,11 @@ public class DatabaseStorageModule implements StorageModule { intValue = 0; } + int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[] {4, 1}); + ncApi.setNotificationLevel(ApiUtils.getCredentials(conversationUser.getUsername(), conversationUser.getToken()), - ApiUtils.getUrlForSettingNotificationlevel(conversationUser.getBaseUrl(), conversationToken), + ApiUtils.getUrlForRoomNotificationLevel(apiVersion, conversationUser.getBaseUrl(), + conversationToken), intValue) .subscribeOn(Schedulers.io()) .subscribe(new Observer() { 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 40f8d0ee7..8882e3b77 100644 --- a/app/src/main/java/com/nextcloud/talk/webrtc/WebSocketConnectionHelper.java +++ b/app/src/main/java/com/nextcloud/talk/webrtc/WebSocketConnectionHelper.java @@ -88,12 +88,14 @@ public class WebSocketConnectionHelper { } HelloOverallWebSocketMessage getAssembledHelloModel(UserEntity userEntity, String ticket) { + int apiVersion = ApiUtils.getSignalingApiVersion(userEntity, new int[] {2, 1}); + HelloOverallWebSocketMessage helloOverallWebSocketMessage = new HelloOverallWebSocketMessage(); helloOverallWebSocketMessage.setType("hello"); HelloWebSocketMessage helloWebSocketMessage = new HelloWebSocketMessage(); helloWebSocketMessage.setVersion("1.0"); AuthWebSocketMessage authWebSocketMessage = new AuthWebSocketMessage(); - authWebSocketMessage.setUrl(ApiUtils.getUrlForExternalServerAuthBackend(userEntity.getBaseUrl())); + authWebSocketMessage.setUrl(ApiUtils.getUrlForSignalingBackend(apiVersion, userEntity.getBaseUrl())); AuthParametersWebSocketMessage authParametersWebSocketMessage = new AuthParametersWebSocketMessage(); authParametersWebSocketMessage.setTicket(ticket); authParametersWebSocketMessage.setUserid(userEntity.getUserId());