From 45afc044212ffb3a71818f8266c769d3e0d7496e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olive=CC=81r=20Falvai?= Date: Wed, 27 Apr 2022 20:24:57 +0200 Subject: [PATCH 001/125] Use fixed text size in read receipt counter --- vector/src/main/res/layout/view_read_receipts.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vector/src/main/res/layout/view_read_receipts.xml b/vector/src/main/res/layout/view_read_receipts.xml index 907f1ec0e3..e8101ec28d 100644 --- a/vector/src/main/res/layout/view_read_receipts.xml +++ b/vector/src/main/res/layout/view_read_receipts.xml @@ -16,6 +16,8 @@ android:paddingStart="4dp" android:paddingEnd="4dp" android:textColor="?vctr_content_primary" + android:textSize="12dp" + tools:ignore="SpUsage" tools:text="999+" /> Date: Wed, 27 Apr 2022 20:34:03 +0200 Subject: [PATCH 002/125] Add changelog --- changelog.d/5856.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5856.bugfix diff --git a/changelog.d/5856.bugfix b/changelog.d/5856.bugfix new file mode 100644 index 0000000000..87f10ac9b2 --- /dev/null +++ b/changelog.d/5856.bugfix @@ -0,0 +1 @@ +Use fixed text size in read receipt counter From 042ec3628fc7caed9c15a936036f36a2ef64f79a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olive=CC=81r=20Falvai?= Date: Thu, 28 Apr 2022 19:02:48 +0200 Subject: [PATCH 003/125] Extract text size to style --- library/ui-styles/src/main/res/values/styles_timeline.xml | 7 +++++-- vector/src/main/res/layout/view_read_receipts.xml | 4 +--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/library/ui-styles/src/main/res/values/styles_timeline.xml b/library/ui-styles/src/main/res/values/styles_timeline.xml index c86eeb8efb..20c375c2d6 100644 --- a/library/ui-styles/src/main/res/values/styles_timeline.xml +++ b/library/ui-styles/src/main/res/values/styles_timeline.xml @@ -1,5 +1,5 @@ - + + - \ No newline at end of file + diff --git a/vector/src/main/res/layout/view_read_receipts.xml b/vector/src/main/res/layout/view_read_receipts.xml index e8101ec28d..11fdeb74d5 100644 --- a/vector/src/main/res/layout/view_read_receipts.xml +++ b/vector/src/main/res/layout/view_read_receipts.xml @@ -7,7 +7,7 @@ Date: Thu, 12 May 2022 12:22:27 +0300 Subject: [PATCH 004/125] Refactor editing polls. --- .../sdk/internal/session/SessionModule.kt | 5 ++ .../EventRelationsAggregationProcessor.kt | 22 ++---- .../poll/DefaultPollAggregationProcessor.kt | 69 +++++++++++++++++++ .../poll/PollAggregationProcessor.kt | 50 ++++++++++++++ 4 files changed, 130 insertions(+), 16 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessor.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt index 0aae9f3105..d48aa4f8cd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt @@ -90,6 +90,8 @@ import org.matrix.android.sdk.internal.session.permalinks.DefaultPermalinkServic import org.matrix.android.sdk.internal.session.room.EventRelationsAggregationProcessor import org.matrix.android.sdk.internal.session.room.aggregation.livelocation.DefaultLiveLocationAggregationProcessor import org.matrix.android.sdk.internal.session.room.aggregation.livelocation.LiveLocationAggregationProcessor +import org.matrix.android.sdk.internal.session.room.aggregation.poll.DefaultPollAggregationProcessor +import org.matrix.android.sdk.internal.session.room.aggregation.poll.PollAggregationProcessor import org.matrix.android.sdk.internal.session.room.create.RoomCreateEventProcessor import org.matrix.android.sdk.internal.session.room.prune.RedactionEventProcessor import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessor @@ -395,4 +397,7 @@ internal abstract class SessionModule { @Binds abstract fun bindLiveLocationAggregationProcessor(processor: DefaultLiveLocationAggregationProcessor): LiveLocationAggregationProcessor + + @Binds + abstract fun bindPollAggregationProcessor(processor: DefaultPollAggregationProcessor): PollAggregationProcessor } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt index 7e0b44a314..0bc89eaa02 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt @@ -68,6 +68,7 @@ import org.matrix.android.sdk.internal.di.SessionId import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.session.EventInsertLiveProcessor import org.matrix.android.sdk.internal.session.room.aggregation.livelocation.LiveLocationAggregationProcessor +import org.matrix.android.sdk.internal.session.room.aggregation.poll.PollAggregationProcessor import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource import org.matrix.android.sdk.internal.util.time.Clock import timber.log.Timber @@ -79,6 +80,7 @@ internal class EventRelationsAggregationProcessor @Inject constructor( @SessionId private val sessionId: String, private val sessionManager: SessionManager, private val liveLocationAggregationProcessor: LiveLocationAggregationProcessor, + private val pollAggregationProcessor: PollAggregationProcessor, private val clock: Clock, ) : EventInsertLiveProcessor { @@ -317,22 +319,6 @@ internal class EventRelationsAggregationProcessor @Inject constructor( return } - ContentMapper - .map(eventAnnotationsSummaryEntity.pollResponseSummary?.aggregatedContent) - ?.toModel() - ?.let { existingPollSummaryContent -> - eventAnnotationsSummaryEntity.pollResponseSummary?.aggregatedContent = ContentMapper.map( - PollSummaryContent( - myVote = existingPollSummaryContent.myVote, - votes = emptyList(), - votesSummary = emptyMap(), - totalVotes = 0, - winnerVoteCount = 0, - ) - .toContent() - ) - } - val txId = event.unsignedData?.transactionId // is it a remote echo? if (!isLocalEcho && existingSummary.editions.any { it.eventId == txId }) { @@ -362,6 +348,10 @@ internal class EventRelationsAggregationProcessor @Inject constructor( } } + if (event.getClearType() in EventType.POLL_START) { + pollAggregationProcessor.handlePollStartEvent(realm, event) + } + if (!isLocalEcho) { val replaceEvent = TimelineEventEntity .where(realm, roomId, eventId) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt new file mode 100644 index 0000000000..5d168b5ec8 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt @@ -0,0 +1,69 @@ +/* + * Copyright 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.session.room.aggregation.poll + +import io.realm.Realm +import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.events.model.RelationType +import org.matrix.android.sdk.api.session.events.model.toContent +import org.matrix.android.sdk.api.session.events.model.toModel +import org.matrix.android.sdk.api.session.room.model.PollSummaryContent +import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent +import org.matrix.android.sdk.internal.database.mapper.ContentMapper +import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity +import org.matrix.android.sdk.internal.database.query.getOrCreate +import javax.inject.Inject + +class DefaultPollAggregationProcessor @Inject constructor() : PollAggregationProcessor { + + override fun handlePollStartEvent(realm: Realm, event: Event): Boolean { + val content = event.getClearContent()?.toModel() + if (content?.relatesTo?.type != RelationType.REPLACE) { + return false + } + + val roomId = event.roomId ?: return false + val targetEventId = content.relatesTo.eventId ?: return false + + EventAnnotationsSummaryEntity.getOrCreate(realm, roomId, targetEventId).let { eventAnnotationsSummaryEntity -> + ContentMapper + .map(eventAnnotationsSummaryEntity.pollResponseSummary?.aggregatedContent) + ?.toModel() + ?.let { existingPollSummaryContent -> + eventAnnotationsSummaryEntity.pollResponseSummary?.aggregatedContent = ContentMapper.map( + PollSummaryContent( + myVote = existingPollSummaryContent.myVote, + votes = emptyList(), + votesSummary = emptyMap(), + totalVotes = 0, + winnerVoteCount = 0, + ) + .toContent() + ) + } + } + return true + } + + override fun handlePollResponseEvent(realm: Realm, event: Event): Boolean { + TODO("Not yet implemented") + } + + override fun handlePollEndEvent(realm: Realm, event: Event): Boolean { + TODO("Not yet implemented") + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessor.kt new file mode 100644 index 0000000000..e97a85c6b3 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessor.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.session.room.aggregation.poll + +import io.realm.Realm +import org.matrix.android.sdk.api.session.events.model.Event + +interface PollAggregationProcessor { + /** + * Poll start events don't need to be processed by the aggregator. + * This function will only handle if the poll is edited and will update the poll summary entity. + * Returns true if the event is aggregated. + */ + fun handlePollStartEvent( + realm: Realm, + event: Event + ): Boolean + + /** + * Aggregates poll response event after many conditional checks like if the poll is ended, if the user is changing his/her vote etc. + * Returns true if the event is aggregated. + */ + fun handlePollResponseEvent( + realm: Realm, + event: Event + ): Boolean + + /** + * Updates poll summary entity and mark it is ended after many conditional checks like if the poll is already ended etc. + * Returns true if the event is aggregated. + */ + fun handlePollEndEvent( + realm: Realm, + event: Event + ): Boolean +} From 817428e2959963234379a863a33717d3fdf214aa Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Thu, 12 May 2022 17:53:08 +0300 Subject: [PATCH 005/125] Refactor ending polls. --- .../EventRelationsAggregationProcessor.kt | 202 ++---------------- .../poll/DefaultPollAggregationProcessor.kt | 147 ++++++++++++- .../poll/PollAggregationProcessor.kt | 5 + 3 files changed, 166 insertions(+), 188 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt index 0bc89eaa02..4945c69c20 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt @@ -16,7 +16,6 @@ package org.matrix.android.sdk.internal.session.room import io.realm.Realm -import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.crypto.verification.VerificationState import org.matrix.android.sdk.api.session.events.model.AggregatedAnnotation @@ -25,26 +24,18 @@ import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.LocalEcho import org.matrix.android.sdk.api.session.events.model.RelationType import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent -import org.matrix.android.sdk.api.session.events.model.getRelationContent import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.events.model.toModel -import org.matrix.android.sdk.api.session.room.getTimelineEvent -import org.matrix.android.sdk.api.session.room.model.PollSummaryContent import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent import org.matrix.android.sdk.api.session.room.model.ReferencesAggregatedContent -import org.matrix.android.sdk.api.session.room.model.VoteInfo -import org.matrix.android.sdk.api.session.room.model.VoteSummary import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconInfoContent import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconLocationDataContent import org.matrix.android.sdk.api.session.room.model.message.MessageContent -import org.matrix.android.sdk.api.session.room.model.message.MessageEndPollContent import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent import org.matrix.android.sdk.api.session.room.model.message.MessagePollResponseContent import org.matrix.android.sdk.api.session.room.model.message.MessageRelationContent import org.matrix.android.sdk.api.session.room.model.relation.ReactionContent import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper -import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent -import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent import org.matrix.android.sdk.internal.SessionManager import org.matrix.android.sdk.internal.crypto.verification.toState import org.matrix.android.sdk.internal.database.helper.findRootThreadEvent @@ -55,7 +46,6 @@ import org.matrix.android.sdk.internal.database.model.EditionOfEvent import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity import org.matrix.android.sdk.internal.database.model.EventEntity import org.matrix.android.sdk.internal.database.model.EventInsertType -import org.matrix.android.sdk.internal.database.model.PollResponseAggregatedSummaryEntity import org.matrix.android.sdk.internal.database.model.ReactionAggregatedSummaryEntity import org.matrix.android.sdk.internal.database.model.ReactionAggregatedSummaryEntityFields import org.matrix.android.sdk.internal.database.model.ReferencesAggregatedSummaryEntity @@ -164,9 +154,8 @@ internal class EventRelationsAggregationProcessor @Inject constructor( // A replace! handleReplace(realm, event, it, roomId, isLocalEcho, encryptedEventContent.relatesTo.eventId) } else if (event.getClearType() in EventType.POLL_RESPONSE) { - event.getClearContent().toModel(catchError = true)?.let { pollResponseContent -> - Timber.v("###RESPONSE in room $roomId for event ${event.eventId}") - handleResponse(realm, event, pollResponseContent, roomId, isLocalEcho, encryptedEventContent.relatesTo.eventId) + sessionManager.getSessionComponent(sessionId)?.session()?.let { session -> + pollAggregationProcessor.handlePollResponseEvent(session, realm, event) } } } @@ -186,12 +175,16 @@ internal class EventRelationsAggregationProcessor @Inject constructor( } in EventType.POLL_RESPONSE -> { event.getClearContent().toModel(catchError = true)?.let { - handleResponse(realm, event, it, roomId, isLocalEcho, event.getRelationContent()?.eventId) + sessionManager.getSessionComponent(sessionId)?.session()?.let { session -> + pollAggregationProcessor.handlePollResponseEvent(session, realm, event) + } } } in EventType.POLL_END -> { - event.content.toModel(catchError = true)?.let { - handleEndPoll(realm, event, it, roomId, isLocalEcho) + sessionManager.getSessionComponent(sessionId)?.session()?.let { session -> + getPowerLevelsHelper(event.roomId)?.let { + pollAggregationProcessor.handlePollEndEvent(session, it, realm, event) + } } } in EventType.BEACON_LOCATION_DATA -> { @@ -249,12 +242,16 @@ internal class EventRelationsAggregationProcessor @Inject constructor( } in EventType.POLL_RESPONSE -> { event.content.toModel(catchError = true)?.let { - handleResponse(realm, event, it, roomId, isLocalEcho) + sessionManager.getSessionComponent(sessionId)?.session()?.let { session -> + pollAggregationProcessor.handlePollResponseEvent(session, realm, event) + } } } in EventType.POLL_END -> { - event.content.toModel(catchError = true)?.let { - handleEndPoll(realm, event, it, roomId, isLocalEcho) + sessionManager.getSessionComponent(sessionId)?.session()?.let { session -> + getPowerLevelsHelper(event.roomId)?.let { + pollAggregationProcessor.handlePollEndEvent(session, it, realm, event) + } } } in EventType.STATE_ROOM_BEACON_INFO -> { @@ -381,173 +378,10 @@ internal class EventRelationsAggregationProcessor @Inject constructor( } } - private fun handleResponse(realm: Realm, - event: Event, - content: MessagePollResponseContent, - roomId: String, - isLocalEcho: Boolean, - relatedEventId: String? = null) { - val eventId = event.eventId ?: return - val senderId = event.senderId ?: return - val targetEventId = relatedEventId ?: content.relatesTo?.eventId ?: return - val eventTimestamp = event.originServerTs ?: return - - val targetPollContent = getPollContent(roomId, targetEventId) ?: return - - // ok, this is a poll response - var existing = EventAnnotationsSummaryEntity.where(realm, roomId, targetEventId).findFirst() - if (existing == null) { - Timber.v("## POLL creating new relation summary for $targetEventId") - existing = EventAnnotationsSummaryEntity.create(realm, roomId, targetEventId) - } - - // we have it - val existingPollSummary = existing.pollResponseSummary - ?: realm.createObject(PollResponseAggregatedSummaryEntity::class.java).also { - existing.pollResponseSummary = it - } - - val closedTime = existingPollSummary.closedTime - if (closedTime != null && eventTimestamp > closedTime) { - Timber.v("## POLL is closed ignore event poll:$targetEventId, event :${event.eventId}") - return - } - - val currentModel = ContentMapper.map(existingPollSummary.aggregatedContent).toModel() - - if (existingPollSummary.sourceEvents.contains(eventId)) { - // ignore this event, we already know it (??) - Timber.v("## POLL ignoring event for summary, it's known eventId:$eventId") - return - } - val txId = event.unsignedData?.transactionId - // is it a remote echo? - if (!isLocalEcho && existingPollSummary.sourceLocalEchoEvents.contains(txId)) { - // ok it has already been managed - Timber.v("## POLL Receiving remote echo of response eventId:$eventId") - existingPollSummary.sourceLocalEchoEvents.remove(txId) - existingPollSummary.sourceEvents.add(event.eventId) - return - } - - val option = content.getBestResponse()?.answers?.first() ?: return Unit.also { - Timber.d("## POLL Ignoring malformed response no option eventId:$eventId content: ${event.content}") - } - - // Check if this option is in available options - if (!targetPollContent.getBestPollCreationInfo()?.answers?.map { it.id }?.contains(option).orFalse()) { - Timber.v("## POLL $targetEventId doesn't contain option $option") - return - } - - val votes = currentModel?.votes.orEmpty().toMutableList() - - var myVote: String? = null - val existingVoteIndex = votes.indexOfFirst { it.userId == senderId } - if (existingVoteIndex != -1) { - // Is the vote newer? - val existingVote = votes[existingVoteIndex] - if (existingVote.voteTimestamp < eventTimestamp) { - // Take the new one - votes[existingVoteIndex] = VoteInfo(senderId, option, eventTimestamp) - if (userId == senderId) { - myVote = option - } - Timber.v("## POLL adding vote $option for user $senderId in poll :$targetEventId ") - } else { - Timber.v("## POLL Ignoring vote (older than known one) eventId:$eventId ") - } - } else { - votes.add(VoteInfo(senderId, option, eventTimestamp)) - if (userId == senderId) { - myVote = option - } - Timber.v("## POLL adding vote $option for user $senderId in poll :$targetEventId ") - } - - // Precompute the percentage of votes for all options - val totalVotes = votes.size - val newVotesSummary = votes - .groupBy({ it.option }, { it.userId }) - .mapValues { - VoteSummary( - total = it.value.size, - percentage = if (totalVotes == 0 && it.value.isEmpty()) 0.0 else it.value.size.toDouble() / totalVotes - ) - } - val newWinnerVoteCount = newVotesSummary.maxOf { it.value.total } - - if (isLocalEcho) { - existingPollSummary.sourceLocalEchoEvents.add(eventId) - } else { - existingPollSummary.sourceEvents.add(eventId) - } - - val newSumModel = PollSummaryContent( - myVote = myVote, - votes = votes, - votesSummary = newVotesSummary, - totalVotes = totalVotes, - winnerVoteCount = newWinnerVoteCount - ) - - existingPollSummary.aggregatedContent = ContentMapper.map(newSumModel.toContent()) - } - - private fun handleEndPoll(realm: Realm, - event: Event, - content: MessageEndPollContent, - roomId: String, - isLocalEcho: Boolean) { - val pollEventId = content.relatesTo?.eventId ?: return - val pollOwnerId = getPollEvent(roomId, pollEventId)?.root?.senderId - val isPollOwner = pollOwnerId == event.senderId - val powerLevelsHelper = stateEventDataSource.getStateEvent(roomId, EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.NoCondition) + private fun getPowerLevelsHelper(roomId: String): PowerLevelsHelper? { + return stateEventDataSource.getStateEvent(roomId, EventType.STATE_ROOM_POWER_LEVELS, QueryStringValue.NoCondition) ?.content?.toModel() ?.let { PowerLevelsHelper(it) } - - if (!isPollOwner && !powerLevelsHelper?.isUserAbleToRedact(event.senderId ?: "").orFalse()) { - Timber.v("## Received poll.end event $pollEventId but user ${event.senderId} doesn't have enough power level in room $roomId") - return - } - - var existingPoll = EventAnnotationsSummaryEntity.where(realm, roomId, pollEventId).findFirst() - if (existingPoll == null) { - Timber.v("## POLL creating new relation summary for $pollEventId") - existingPoll = EventAnnotationsSummaryEntity.create(realm, roomId, pollEventId) - } - - // we have it - val existingPollSummary = existingPoll.pollResponseSummary - ?: realm.createObject(PollResponseAggregatedSummaryEntity::class.java).also { - existingPoll.pollResponseSummary = it - } - - val txId = event.unsignedData?.transactionId - existingPollSummary.closedTime = event.originServerTs - - // is it a remote echo? - if (!isLocalEcho && existingPollSummary.sourceLocalEchoEvents.contains(txId)) { - // ok it has already been managed - Timber.v("## POLL Receiving remote echo of response eventId:$pollEventId") - existingPollSummary.sourceLocalEchoEvents.remove(txId) - existingPollSummary.sourceEvents.add(event.eventId) - } - } - - private fun getPollEvent(roomId: String, eventId: String): TimelineEvent? { - val session = sessionManager.getSessionComponent(sessionId)?.session() - return session?.roomService()?.getRoom(roomId)?.getTimelineEvent(eventId) ?: return null.also { - Timber.v("## POLL target poll event $eventId not found in room $roomId") - } - } - - private fun getPollContent(roomId: String, eventId: String): MessagePollContent? { - val pollEvent = getPollEvent(roomId, eventId) ?: return null - - return pollEvent.getLastMessageContent() as? MessagePollContent ?: return null.also { - Timber.v("## POLL target poll event $eventId content is malformed") - } } private fun handleInitialAggregatedRelations(realm: Realm, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt index 5d168b5ec8..0eabf7d387 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt @@ -17,15 +17,31 @@ package org.matrix.android.sdk.internal.session.room.aggregation.poll import io.realm.Realm +import org.matrix.android.sdk.api.extensions.orFalse +import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.events.model.LocalEcho import org.matrix.android.sdk.api.session.events.model.RelationType +import org.matrix.android.sdk.api.session.events.model.getRelationContent import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.events.model.toModel +import org.matrix.android.sdk.api.session.room.getTimelineEvent import org.matrix.android.sdk.api.session.room.model.PollSummaryContent +import org.matrix.android.sdk.api.session.room.model.VoteInfo +import org.matrix.android.sdk.api.session.room.model.VoteSummary +import org.matrix.android.sdk.api.session.room.model.message.MessageEndPollContent import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent +import org.matrix.android.sdk.api.session.room.model.message.MessagePollResponseContent +import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper +import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent +import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent import org.matrix.android.sdk.internal.database.mapper.ContentMapper import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity +import org.matrix.android.sdk.internal.database.model.PollResponseAggregatedSummaryEntity +import org.matrix.android.sdk.internal.database.query.create import org.matrix.android.sdk.internal.database.query.getOrCreate +import org.matrix.android.sdk.internal.database.query.where +import timber.log.Timber import javax.inject.Inject class DefaultPollAggregationProcessor @Inject constructor() : PollAggregationProcessor { @@ -59,11 +75,134 @@ class DefaultPollAggregationProcessor @Inject constructor() : PollAggregationPro return true } - override fun handlePollResponseEvent(realm: Realm, event: Event): Boolean { - TODO("Not yet implemented") + override fun handlePollResponseEvent(session: Session, realm: Realm, event: Event): Boolean { + val content = event.getClearContent()?.toModel() ?: return false + val roomId = event.roomId ?: return false + val senderId = event.senderId ?: return false + val targetEventId = event.getRelationContent()?.eventId ?: return false + val targetPollContent = getPollContent(session, roomId, targetEventId) ?: return false + + val annotationsSummaryEntity = getAnnotationsSummaryEntity(realm, roomId, targetEventId) + val aggregatedPollSummaryEntity = getAggregatedPollSummaryEntity(realm, annotationsSummaryEntity) + + val closedTime = aggregatedPollSummaryEntity.closedTime + val responseTime = event.originServerTs ?: return false + if (closedTime != null && responseTime > closedTime) { + return false + } + + if (aggregatedPollSummaryEntity.sourceEvents.contains(event.eventId)) { + return false + } + + val txId = event.unsignedData?.transactionId + val isLocalEcho = LocalEcho.isLocalEchoId(event.eventId ?: "") + if (!isLocalEcho && aggregatedPollSummaryEntity.sourceLocalEchoEvents.contains(txId)) { + aggregatedPollSummaryEntity.sourceLocalEchoEvents.remove(txId) + aggregatedPollSummaryEntity.sourceEvents.add(event.eventId) + return false + } + + val vote = content.getBestResponse()?.answers?.first() ?: return false + if (!targetPollContent.getBestPollCreationInfo()?.answers?.map { it.id }?.contains(vote).orFalse()) { + return false + } + + val pollSummaryModel = ContentMapper.map(aggregatedPollSummaryEntity.aggregatedContent).toModel() + val existingVotes = pollSummaryModel?.votes.orEmpty().toMutableList() + val existingVoteIndex = existingVotes.indexOfFirst { it.userId == senderId } + + if (existingVoteIndex != -1) { + val existingVote = existingVotes[existingVoteIndex] + if (existingVote.voteTimestamp > responseTime) { + return false + } + existingVotes[existingVoteIndex] = VoteInfo(senderId, vote, responseTime) + } else { + existingVotes.add(VoteInfo(senderId, vote, responseTime)) + } + + // Precompute the percentage of votes for all options + val totalVotes = existingVotes.size + val newVotesSummary = existingVotes + .groupBy({ it.option }, { it.userId }) + .mapValues { + VoteSummary( + total = it.value.size, + percentage = if (totalVotes == 0 && it.value.isEmpty()) 0.0 else it.value.size.toDouble() / totalVotes + ) + } + val newWinnerVoteCount = newVotesSummary.maxOf { it.value.total } + + if (isLocalEcho) { + aggregatedPollSummaryEntity.sourceLocalEchoEvents.add(event.eventId) + } else { + aggregatedPollSummaryEntity.sourceEvents.add(event.eventId) + } + + val newSumModel = PollSummaryContent( + myVote = vote, + votes = existingVotes, + votesSummary = newVotesSummary, + totalVotes = totalVotes, + winnerVoteCount = newWinnerVoteCount + ) + aggregatedPollSummaryEntity.aggregatedContent = ContentMapper.map(newSumModel.toContent()) + + return true } - override fun handlePollEndEvent(realm: Realm, event: Event): Boolean { - TODO("Not yet implemented") + override fun handlePollEndEvent(session: Session, powerLevelsHelper: PowerLevelsHelper, realm: Realm, event: Event): Boolean { + val content = event.getClearContent()?.toModel() ?: return false + val roomId = event.roomId ?: return false + val pollEventId = content.relatesTo?.eventId ?: return false + val pollOwnerId = getPollEvent(session, roomId, pollEventId)?.root?.senderId + val isPollOwner = pollOwnerId == event.senderId + + if (!isPollOwner && !powerLevelsHelper.isUserAbleToRedact(event.senderId ?: "")) { + Timber.v("## Received poll.end event $pollEventId but user ${event.senderId} doesn't have enough power level in room $roomId") + return false + } + + val annotationsSummaryEntity = getAnnotationsSummaryEntity(realm, roomId, pollEventId) + val aggregatedPollSummaryEntity = getAggregatedPollSummaryEntity(realm, annotationsSummaryEntity) + + val txId = event.unsignedData?.transactionId + aggregatedPollSummaryEntity.closedTime = event.originServerTs + + val isLocalEcho = LocalEcho.isLocalEchoId(event.eventId ?: "") + if (!isLocalEcho && aggregatedPollSummaryEntity.sourceLocalEchoEvents.contains(txId)) { + aggregatedPollSummaryEntity.sourceLocalEchoEvents.remove(txId) + aggregatedPollSummaryEntity.sourceEvents.add(event.eventId) + } + + return true + } + + private fun getPollEvent(session: Session, roomId: String, eventId: String): TimelineEvent? { + return session.roomService().getRoom(roomId)?.getTimelineEvent(eventId) ?: return null.also { + Timber.v("## POLL target poll event $eventId not found in room $roomId") + } + } + + private fun getPollContent(session: Session, roomId: String, eventId: String): MessagePollContent? { + val pollEvent = getPollEvent(session, roomId, eventId) ?: return null + + return pollEvent.getLastMessageContent() as? MessagePollContent ?: return null.also { + Timber.v("## POLL target poll event $eventId content is malformed") + } + } + + private fun getAnnotationsSummaryEntity(realm: Realm, roomId: String, eventId: String): EventAnnotationsSummaryEntity { + return EventAnnotationsSummaryEntity.where(realm, roomId, eventId).findFirst() + ?: EventAnnotationsSummaryEntity.create(realm, roomId, eventId) + } + + private fun getAggregatedPollSummaryEntity(realm: Realm, + eventAnnotationsSummaryEntity: EventAnnotationsSummaryEntity): PollResponseAggregatedSummaryEntity { + return eventAnnotationsSummaryEntity.pollResponseSummary + ?: realm.createObject(PollResponseAggregatedSummaryEntity::class.java).also { + eventAnnotationsSummaryEntity.pollResponseSummary = it + } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessor.kt index e97a85c6b3..848643b435 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessor.kt @@ -17,7 +17,9 @@ package org.matrix.android.sdk.internal.session.room.aggregation.poll import io.realm.Realm +import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper interface PollAggregationProcessor { /** @@ -35,6 +37,7 @@ interface PollAggregationProcessor { * Returns true if the event is aggregated. */ fun handlePollResponseEvent( + session: Session, realm: Realm, event: Event ): Boolean @@ -44,6 +47,8 @@ interface PollAggregationProcessor { * Returns true if the event is aggregated. */ fun handlePollEndEvent( + session: Session, + powerLevelsHelper: PowerLevelsHelper, realm: Realm, event: Event ): Boolean From 85708b7c60ca8f3b6c8e18d4ea685808e3cac9ff Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Fri, 13 May 2022 12:59:41 +0300 Subject: [PATCH 006/125] Fix related event id. --- .../room/aggregation/poll/DefaultPollAggregationProcessor.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt index 0eabf7d387..6ea8f698e3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt @@ -79,7 +79,7 @@ class DefaultPollAggregationProcessor @Inject constructor() : PollAggregationPro val content = event.getClearContent()?.toModel() ?: return false val roomId = event.roomId ?: return false val senderId = event.senderId ?: return false - val targetEventId = event.getRelationContent()?.eventId ?: return false + val targetEventId = (event.getRelationContent() ?: content.relatesTo)?.eventId ?: return false val targetPollContent = getPollContent(session, roomId, targetEventId) ?: return false val annotationsSummaryEntity = getAnnotationsSummaryEntity(realm, roomId, targetEventId) From 47f43a88f4caff48fe53ffbd03912c2804bc759f Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Fri, 13 May 2022 14:04:33 +0300 Subject: [PATCH 007/125] Create dummy poll event for tests. --- .../poll/PollAggregationProcessorTest.kt | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt new file mode 100644 index 0000000000..e31e62c58a --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt @@ -0,0 +1,81 @@ +/* + * Copyright 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.session.room.aggregation.poll + +import org.junit.Test +import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.toContent +import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent +import org.matrix.android.sdk.api.session.room.model.message.PollAnswer +import org.matrix.android.sdk.api.session.room.model.message.PollCreationInfo +import org.matrix.android.sdk.api.session.room.model.message.PollQuestion +import org.matrix.android.sdk.test.fakes.FakeMonarchy + +private const val A_USER_ID_1 = "@user_1:matrix.org" +private const val A_USER_ID_2 = "@user_2:matrix.org" +private const val A_ROOM_ID = "!sUeOGZKsBValPTUMax:matrix.org" + +private val A_POLL_CONTENT = MessagePollContent( + unstablePollCreationInfo = PollCreationInfo( + question = PollQuestion( + unstableQuestion = "What is your favourite coffee?" + ), + maxSelections = 1, + answers = listOf( + PollAnswer( + id = "5ef5f7b0-c9a1-49cf-a0b3-374729a43e76", + unstableAnswer = "Double Espresso" + ), + PollAnswer( + id = "ec1a4db0-46d8-4d7a-9bb6-d80724715938", + unstableAnswer = "Macchiato" + ), + PollAnswer( + id = "3677ca8e-061b-40ab-bffe-b22e4e88fcad", + unstableAnswer = "Iced Coffee" + ) + ) + ) +) + +private val A_POLL_START_EVENT = Event( + type = EventType.POLL_START.first(), + eventId = "\$vApgexcL8Vfh-WxYKsFKCDooo67ttbjm3TiVKXaWijU", + originServerTs = 1652435922563, + senderId = A_USER_ID_1, + roomId = A_ROOM_ID, + content = A_POLL_CONTENT.toContent() +) + +class PollAggregationProcessorTest { + + private val pollAggregationProcessor: PollAggregationProcessor = DefaultPollAggregationProcessor() + private val monarchy = FakeMonarchy() + + @Test + fun handlePollStartEvent() { + } + + @Test + fun handlePollResponseEvent() { + } + + @Test + fun handlePollEndEvent() { + } +} From 2e08c07dad693c1ff78c4ab1da46e1ed9cf45bb8 Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Mon, 16 May 2022 13:05:38 +0300 Subject: [PATCH 008/125] Enhance decryption to prevent DUPLICATED_MESSAGE_INDEX when decrypting the same eventId Improve code format --- .../crypto/replay_attack/ReplayAttackTest.kt | 160 ++++++++++++++++++ .../sdk/internal/crypto/MXOlmDevice.kt | 100 ++++++----- .../algorithms/megolm/MXMegolmDecryption.kt | 1 + 3 files changed, 218 insertions(+), 43 deletions(-) create mode 100644 matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replay_attack/ReplayAttackTest.kt diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replay_attack/ReplayAttackTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replay_attack/ReplayAttackTest.kt new file mode 100644 index 0000000000..5c9892e264 --- /dev/null +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replay_attack/ReplayAttackTest.kt @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.crypto.replay_attack + +import android.util.Log +import androidx.test.filters.LargeTest +import org.junit.Assert +import org.junit.Assert.assertEquals +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import org.junit.runners.MethodSorters +import org.matrix.android.sdk.InstrumentedTest +import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.toModel +import org.matrix.android.sdk.api.session.room.Room +import org.matrix.android.sdk.api.session.room.model.message.MessageContent +import org.matrix.android.sdk.api.session.room.send.SendState +import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings +import org.matrix.android.sdk.common.CommonTestHelper +import org.matrix.android.sdk.common.CryptoTestHelper +import org.matrix.android.sdk.common.TestConstants + +@RunWith(JUnit4::class) +@FixMethodOrder(MethodSorters.JVM) +@LargeTest +class ReplayAttackTest : InstrumentedTest { + + @Test + fun replayAttackTest() { + val testHelper = CommonTestHelper(context()) + val cryptoTestHelper = CryptoTestHelper(testHelper) + val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom(true) + + val e2eRoomID = cryptoTestData.roomId + + // Alice + val aliceSession = cryptoTestData.firstSession + val aliceRoomPOV = aliceSession.roomService().getRoom(e2eRoomID)!! + + // Bob + val bobSession = cryptoTestData.secondSession + val bobRoomPOV = bobSession!!.roomService().getRoom(e2eRoomID)!! + + assertEquals(bobRoomPOV.roomSummary()?.joinedMembersCount, 2) + Log.v("##REPLAY ATTACK", "Alice and Bob are in roomId: $e2eRoomID") + + + val sentEvents = testHelper.sendTextMessage(aliceRoomPOV, "Hello", 20) + +// val aliceMessageId: String? = sendMessageInRoom(aliceRoomPOV, "Hello Bob, I am Alice!", testHelper) + Assert.assertTrue("Message should be sent", sentEvents.size == 20) + Log.v("##REPLAY ATTACK", "Alice sent message to roomId: $e2eRoomID") + + // Bob should be able to decrypt the message +// testHelper.waitWithLatch { latch -> +// testHelper.retryPeriodicallyWithLatch(latch) { +// val timelineEvent = bobSession.roomService().getRoom(e2eRoomID)?.timelineService()?.getTimelineEvent(aliceMessageId!!) +// (timelineEvent != null && +// timelineEvent.isEncrypted() && +// timelineEvent.root.getClearType() == EventType.MESSAGE).also { +// if (it) { +// Log.v("#E2E TEST", "Bob can decrypt the message: ${timelineEvent?.root?.getDecryptedTextSummary()}") +// } +// } +// } +// } +// +// // Create a new user +// val arisSession = testHelper.createAccount("aris", SessionTestParams(true)) +// Log.v("#E2E TEST", "Aris user created") +// +// // Alice invites new user to the room +// testHelper.runBlockingTest { +// Log.v("#E2E TEST", "Alice invites ${arisSession.myUserId}") +// aliceRoomPOV.membershipService().invite(arisSession.myUserId) +// } +// +// waitForAndAcceptInviteInRoom(arisSession, e2eRoomID, testHelper) +// +// ensureMembersHaveJoined(aliceSession, arrayListOf(arisSession), e2eRoomID, testHelper) +// Log.v("#E2E TEST", "Aris has joined roomId: $e2eRoomID") +// +// when (roomHistoryVisibility) { +// RoomHistoryVisibility.WORLD_READABLE, +// RoomHistoryVisibility.SHARED, +// null +// -> { +// // Aris should be able to decrypt the message +// testHelper.waitWithLatch { latch -> +// testHelper.retryPeriodicallyWithLatch(latch) { +// val timelineEvent = arisSession.roomService().getRoom(e2eRoomID)?.timelineService()?.getTimelineEvent(aliceMessageId!!) +// (timelineEvent != null && +// timelineEvent.isEncrypted() && +// timelineEvent.root.getClearType() == EventType.MESSAGE +// ).also { +// if (it) { +// Log.v("#E2E TEST", "Aris can decrypt the message: ${timelineEvent?.root?.getDecryptedTextSummary()}") +// } +// } +// } +// } +// } +// RoomHistoryVisibility.INVITED, +// RoomHistoryVisibility.JOINED -> { +// // Aris should not even be able to get the message +// testHelper.waitWithLatch { latch -> +// testHelper.retryPeriodicallyWithLatch(latch) { +// val timelineEvent = arisSession.roomService().getRoom(e2eRoomID) +// ?.timelineService() +// ?.getTimelineEvent(aliceMessageId!!) +// timelineEvent == null +// } +// } +// } +// } + +// testHelper.signOutAndClose(arisSession) + cryptoTestData.cleanUp(testHelper) + } + + private fun sendMessageInRoom(aliceRoomPOV: Room, text: String, testHelper: CommonTestHelper): String? { + aliceRoomPOV.sendService().sendTextMessage(text) + var sentEventId: String? = null + testHelper.waitWithLatch(4 * TestConstants.timeOutMillis) { latch -> + val timeline = aliceRoomPOV.timelineService().createTimeline(null, TimelineSettings(60)) + timeline.start() + testHelper.retryPeriodicallyWithLatch(latch) { + val decryptedMsg = timeline.getSnapshot() + .filter { it.root.getClearType() == EventType.MESSAGE } + .also { list -> + val message = list.joinToString(",", "[", "]") { "${it.root.type}|${it.root.sendState}" } + Log.v("#E2E TEST", "Timeline snapshot is $message") + } + .filter { it.root.sendState == SendState.SYNCED } + .firstOrNull { it.root.getClearContent().toModel()?.body?.startsWith(text) == true } + sentEventId = decryptedMsg?.eventId + decryptedMsg != null + } + + timeline.dispose() + } + return sentEventId + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt index 68a1519670..16e6bb173d 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt @@ -99,6 +99,8 @@ internal class MXOlmDevice @Inject constructor( // The second level keys are strings of form "||" private val inboundGroupSessionMessageIndexes: MutableMap> = HashMap() + private val replayAttackMap: MutableMap = HashMap() + init { // Retrieve the account from the store try { @@ -763,59 +765,71 @@ internal class MXOlmDevice @Inject constructor( suspend fun decryptGroupMessage(body: String, roomId: String, timeline: String?, + eventId: String, sessionId: String, senderKey: String): OlmDecryptionResult { val sessionHolder = getInboundGroupSession(sessionId, senderKey, roomId) val wrapper = sessionHolder.wrapper val inboundGroupSession = wrapper.olmInboundGroupSession ?: throw MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_DECRYPT, "Session is null") - // Check that the room id matches the original one for the session. This stops - // the HS pretending a message was targeting a different room. - if (roomId == wrapper.roomId) { - val decryptResult = try { - sessionHolder.mutex.withLock { - inboundGroupSession.decryptMessage(body) - } - } catch (e: OlmException) { - Timber.tag(loggerTag.value).e(e, "## decryptGroupMessage () : decryptMessage failed") - throw MXCryptoError.OlmError(e) - } - - if (timeline?.isNotBlank() == true) { - val timelineSet = inboundGroupSessionMessageIndexes.getOrPut(timeline) { mutableSetOf() } - - val messageIndexKey = senderKey + "|" + sessionId + "|" + decryptResult.mIndex - - if (timelineSet.contains(messageIndexKey)) { - val reason = String.format(MXCryptoError.DUPLICATE_MESSAGE_INDEX_REASON, decryptResult.mIndex) - Timber.tag(loggerTag.value).e("## decryptGroupMessage() timelineId=$timeline: $reason") - throw MXCryptoError.Base(MXCryptoError.ErrorType.DUPLICATED_MESSAGE_INDEX, reason) - } - - timelineSet.add(messageIndexKey) - } - - inboundGroupSessionStore.storeInBoundGroupSession(sessionHolder, sessionId, senderKey) - val payload = try { - val adapter = MoshiProvider.providesMoshi().adapter(JSON_DICT_PARAMETERIZED_TYPE) - val payloadString = convertFromUTF8(decryptResult.mDecryptedMessage) - adapter.fromJson(payloadString) - } catch (e: Exception) { - Timber.tag(loggerTag.value).e("## decryptGroupMessage() : fails to parse the payload") - throw MXCryptoError.Base(MXCryptoError.ErrorType.BAD_DECRYPTED_FORMAT, MXCryptoError.BAD_DECRYPTED_FORMAT_TEXT_REASON) - } - - return OlmDecryptionResult( - payload, - wrapper.keysClaimed, - senderKey, - wrapper.forwardingCurve25519KeyChain - ) - } else { + if (roomId != wrapper.roomId) { + // Check that the room id matches the original one for the session. This stops + // the HS pretending a message was targeting a different room. val reason = String.format(MXCryptoError.INBOUND_SESSION_MISMATCH_ROOM_ID_REASON, roomId, wrapper.roomId) Timber.tag(loggerTag.value).e("## decryptGroupMessage() : $reason") throw MXCryptoError.Base(MXCryptoError.ErrorType.INBOUND_SESSION_MISMATCH_ROOM_ID, reason) } + val decryptResult = try { + sessionHolder.mutex.withLock { + inboundGroupSession.decryptMessage(body) + } + } catch (e: OlmException) { + Timber.tag(loggerTag.value).e(e, "## decryptGroupMessage () : decryptMessage failed") + throw MXCryptoError.OlmError(e) + } + + val messageIndexKey = senderKey + "|" + sessionId + "|" + roomId + "|" + decryptResult.mIndex + Timber.tag(loggerTag.value).d("##########################################################") + Timber.tag(loggerTag.value).d("## decryptGroupMessage() timeline: $timeline") + Timber.tag(loggerTag.value).d("## decryptGroupMessage() senderKey: $senderKey") + Timber.tag(loggerTag.value).d("## decryptGroupMessage() sessionId: $sessionId") + Timber.tag(loggerTag.value).d("## decryptGroupMessage() roomId: $roomId") + Timber.tag(loggerTag.value).d("## decryptGroupMessage() eventId: $eventId") + Timber.tag(loggerTag.value).d("## decryptGroupMessage() mIndex: ${decryptResult.mIndex}") + + if (timeline?.isNotBlank() == true) { + val timelineSet = inboundGroupSessionMessageIndexes.getOrPut(timeline) { mutableSetOf() } + if (timelineSet.contains(messageIndexKey) && messageIndexKey.alreadyUsed(eventId)) { + val reason = String.format(MXCryptoError.DUPLICATE_MESSAGE_INDEX_REASON, decryptResult.mIndex) + Timber.tag(loggerTag.value).e("## decryptGroupMessage() timelineId=$timeline: $reason") + throw MXCryptoError.Base(MXCryptoError.ErrorType.DUPLICATED_MESSAGE_INDEX, reason) + } + timelineSet.add(messageIndexKey) + } + replayAttackMap[messageIndexKey] = eventId + inboundGroupSessionStore.storeInBoundGroupSession(sessionHolder, sessionId, senderKey) + val payload = try { + val adapter = MoshiProvider.providesMoshi().adapter(JSON_DICT_PARAMETERIZED_TYPE) + val payloadString = convertFromUTF8(decryptResult.mDecryptedMessage) + adapter.fromJson(payloadString) + } catch (e: Exception) { + Timber.tag(loggerTag.value).e("## decryptGroupMessage() : fails to parse the payload") + throw MXCryptoError.Base(MXCryptoError.ErrorType.BAD_DECRYPTED_FORMAT, MXCryptoError.BAD_DECRYPTED_FORMAT_TEXT_REASON) + } + + return OlmDecryptionResult( + payload, + wrapper.keysClaimed, + senderKey, + wrapper.forwardingCurve25519KeyChain + ) + } + + /** + * Determines whether or not the messageKey has already been used to decrypt another eventId + */ + private fun String.alreadyUsed(eventId: String): Boolean { + return replayAttackMap[this] != null && replayAttackMap[this] != eventId } /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt index d65b05f655..aff8013784 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt @@ -78,6 +78,7 @@ internal class MXMegolmDecryption( encryptedEventContent.ciphertext, event.roomId, timeline, + eventId = event.eventId.orEmpty(), encryptedEventContent.sessionId, encryptedEventContent.senderKey ) From a893f5acdb74c2553ffc7cbbd8991f27f4aa3fed Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 16 May 2022 12:00:53 +0100 Subject: [PATCH 009/125] applying the manual reordering of the sign up stages only when matrix.org is selected - lifts the logic up to the view model --- changelog.d/5783.wip | 1 + .../app/features/onboarding/OnboardingViewModel.kt | 13 ++++++++++++- .../features/onboarding/ftueauth/FtueAuthVariant.kt | 8 +------- 3 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 changelog.d/5783.wip diff --git a/changelog.d/5783.wip b/changelog.d/5783.wip new file mode 100644 index 0000000000..6f44813d81 --- /dev/null +++ b/changelog.d/5783.wip @@ -0,0 +1 @@ +FTUE - Overrides sign up flow ordering for matrix.org only diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index 25ae0327a8..a7468cf95b 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -42,6 +42,7 @@ import im.vector.app.features.login.ReAuthHelper import im.vector.app.features.login.ServerType import im.vector.app.features.login.SignMode import im.vector.app.features.onboarding.StartAuthenticationFlowUseCase.StartAuthenticationResult +import im.vector.app.features.onboarding.ftueauth.FtueMissingRegistrationStagesComparator import kotlinx.coroutines.Job import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.launch @@ -289,9 +290,19 @@ class OnboardingViewModel @AssistedInject constructor( } private fun emitFlowResultViewEvent(flowResult: FlowResult) { - _viewEvents.post(OnboardingViewEvents.RegistrationFlowResult(flowResult, isRegistrationStarted)) + withState { state -> + val orderedResult = when { + state.hasSelectedMatrixOrg() && vectorFeatures.isOnboardingCombinedRegisterEnabled() -> flowResult.overrideOrder() + else -> flowResult + } + _viewEvents.post(OnboardingViewEvents.RegistrationFlowResult(orderedResult, isRegistrationStarted)) + } } + private fun OnboardingViewState.hasSelectedMatrixOrg() = selectedHomeserver.userFacingUrl == matrixOrgUrl + + private fun FlowResult.overrideOrder() = copy(missingStages = missingStages.sortedWith(FtueMissingRegistrationStagesComparator())) + private fun handleRegisterWith(action: OnboardingAction.Register) { reAuthHelper.data = action.password handleRegisterAction( diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt index 63b3bc0f71..8513845b8e 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt @@ -54,7 +54,6 @@ import im.vector.app.features.onboarding.OnboardingViewState import im.vector.app.features.onboarding.ftueauth.terms.FtueAuthLegacyStyleTermsFragment import im.vector.app.features.onboarding.ftueauth.terms.FtueAuthTermsFragment import im.vector.app.features.onboarding.ftueauth.terms.FtueAuthTermsLegacyStyleFragmentArgument -import org.matrix.android.sdk.api.auth.registration.FlowResult import org.matrix.android.sdk.api.auth.registration.Stage import org.matrix.android.sdk.api.auth.toLocalizedLoginTerms import org.matrix.android.sdk.api.extensions.tryOrNull @@ -240,17 +239,12 @@ class FtueAuthVariant( private fun onRegistrationFlow(viewEvents: OnboardingViewEvents.RegistrationFlowResult) { when { registrationShouldFallback(viewEvents) -> displayFallbackWebDialog() - viewEvents.isRegistrationStarted -> handleRegistrationNavigation(viewEvents.flowResult.orderedStages()) + viewEvents.isRegistrationStarted -> handleRegistrationNavigation(viewEvents.flowResult.missingStages) vectorFeatures.isOnboardingCombinedRegisterEnabled() -> openStartCombinedRegister() else -> openAuthLoginFragmentWithTag(FRAGMENT_REGISTRATION_STAGE_TAG) } } - private fun FlowResult.orderedStages() = when { - vectorFeatures.isOnboardingCombinedRegisterEnabled() -> missingStages.sortedWith(FtueMissingRegistrationStagesComparator()) - else -> missingStages - } - private fun openStartCombinedRegister() { addRegistrationStageFragmentToBackstack(FtueAuthCombinedRegisterFragment::class.java) } From 4065bce47a2f98c237c863432cdd123e20d2af28 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Mon, 16 May 2022 15:05:17 +0300 Subject: [PATCH 010/125] Write unit tests for poll start event aggregation. --- .../poll/PollAggregationProcessorTest.kt | 82 ++++++++++++++++++- .../android/sdk/test/fakes/FakeRealm.kt | 36 ++++++++ 2 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRealm.kt diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt index e31e62c58a..a14ce5b697 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt @@ -16,19 +16,30 @@ package org.matrix.android.sdk.internal.session.room.aggregation.poll +import io.mockk.every +import io.realm.RealmModel +import io.realm.RealmQuery +import org.amshove.kluent.shouldBeFalse +import org.amshove.kluent.shouldBeTrue import org.junit.Test import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.RelationType import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent import org.matrix.android.sdk.api.session.room.model.message.PollAnswer import org.matrix.android.sdk.api.session.room.model.message.PollCreationInfo import org.matrix.android.sdk.api.session.room.model.message.PollQuestion -import org.matrix.android.sdk.test.fakes.FakeMonarchy +import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent +import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity +import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntityFields +import org.matrix.android.sdk.internal.database.model.PollResponseAggregatedSummaryEntity +import org.matrix.android.sdk.test.fakes.FakeRealm private const val A_USER_ID_1 = "@user_1:matrix.org" private const val A_USER_ID_2 = "@user_2:matrix.org" private const val A_ROOM_ID = "!sUeOGZKsBValPTUMax:matrix.org" +private const val AN_EVENT_ID = "\$vApgexcL8Vfh-WxYKsFKCDooo67ttbjm3TiVKXaWijU" private val A_POLL_CONTENT = MessagePollContent( unstablePollCreationInfo = PollCreationInfo( @@ -55,20 +66,79 @@ private val A_POLL_CONTENT = MessagePollContent( private val A_POLL_START_EVENT = Event( type = EventType.POLL_START.first(), - eventId = "\$vApgexcL8Vfh-WxYKsFKCDooo67ttbjm3TiVKXaWijU", + eventId = AN_EVENT_ID, originServerTs = 1652435922563, senderId = A_USER_ID_1, roomId = A_ROOM_ID, content = A_POLL_CONTENT.toContent() ) +private val A_POLL_REPLACE_EVENT = A_POLL_START_EVENT.copy( + content = A_POLL_CONTENT + .copy( + relatesTo = RelationDefaultContent( + type = RelationType.REPLACE, + eventId = AN_EVENT_ID + ) + ) + .toContent() +) + +private val A_BROKEN_POLL_REPLACE_EVENT = A_POLL_START_EVENT.copy( + content = A_POLL_CONTENT + .copy( + relatesTo = RelationDefaultContent( + type = RelationType.REPLACE, + eventId = null + ) + ) + .toContent() +) + +private val A_POLL_REFERENCE_EVENT = A_POLL_START_EVENT.copy( + content = A_POLL_CONTENT + .copy( + relatesTo = RelationDefaultContent( + type = RelationType.REFERENCE, + eventId = AN_EVENT_ID + ) + ) + .toContent() +) + +private val AN_EVENT_ANNOTATIONS_SUMMARY_ENTITY = EventAnnotationsSummaryEntity( + roomId = A_ROOM_ID, + eventId = AN_EVENT_ID, + pollResponseSummary = PollResponseAggregatedSummaryEntity() +) + class PollAggregationProcessorTest { private val pollAggregationProcessor: PollAggregationProcessor = DefaultPollAggregationProcessor() - private val monarchy = FakeMonarchy() + private val realm = FakeRealm() @Test - fun handlePollStartEvent() { + fun `given a poll start event which is not a replace is not processed by poll aggregator`() { + pollAggregationProcessor.handlePollStartEvent(realm.instance, A_POLL_START_EVENT).shouldBeFalse() + } + + @Test + fun `given a poll start event with a reference is not processed by poll aggregator`() { + pollAggregationProcessor.handlePollStartEvent(realm.instance, A_POLL_REFERENCE_EVENT).shouldBeFalse() + } + + @Test + fun `given a poll start event with a replace but without target event id is not processed by poll aggregator`() { + pollAggregationProcessor.handlePollStartEvent(realm.instance, A_BROKEN_POLL_REPLACE_EVENT).shouldBeFalse() + } + + @Test + fun `given a poll start event with a replace is processed by poll aggregator`() { + val queryResult = realm.givenWhereReturns(result = EventAnnotationsSummaryEntity()) + queryResult.givenEqualTo(EventAnnotationsSummaryEntityFields.ROOM_ID, A_POLL_REPLACE_EVENT.roomId!!, queryResult) + queryResult.givenEqualTo(EventAnnotationsSummaryEntityFields.EVENT_ID, A_POLL_REPLACE_EVENT.eventId!!, queryResult) + + pollAggregationProcessor.handlePollStartEvent(realm.instance, A_POLL_REPLACE_EVENT).shouldBeTrue() } @Test @@ -78,4 +148,8 @@ class PollAggregationProcessorTest { @Test fun handlePollEndEvent() { } + + private inline fun RealmQuery.givenEqualTo(fieldName: String, value: String, result: RealmQuery) { + every { equalTo(fieldName, value) } returns result + } } diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRealm.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRealm.kt new file mode 100644 index 0000000000..a3462c4acc --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRealm.kt @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.test.fakes + +import io.mockk.every +import io.mockk.mockk +import io.realm.Realm +import io.realm.RealmModel +import io.realm.RealmQuery +import io.realm.kotlin.where + +internal class FakeRealm { + + val instance = mockk(relaxed = true) + + inline fun givenWhereReturns(result: T?): RealmQuery { + val queryResult = mockk>(relaxed = true) + every { queryResult.findFirst() } returns result + every { instance.where() } returns queryResult + return queryResult + } +} From 6c3150edb7e671e522369ed63f16ff20a13dd5eb Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 16 May 2022 17:16:37 +0100 Subject: [PATCH 011/125] using compareTo instead of direct subtraction --- .../ftueauth/FtueMissingRegistrationStagesComparator.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueMissingRegistrationStagesComparator.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueMissingRegistrationStagesComparator.kt index 6a6326625e..4d9fe10852 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueMissingRegistrationStagesComparator.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueMissingRegistrationStagesComparator.kt @@ -21,7 +21,7 @@ import org.matrix.android.sdk.api.auth.registration.Stage class FtueMissingRegistrationStagesComparator : Comparator { override fun compare(a: Stage?, b: Stage?): Int { - return (a?.toPriority() ?: 0) - (b?.toPriority() ?: 0) + return (a?.toPriority() ?: 0).compareTo(b?.toPriority() ?: 0) } private fun Stage.toPriority() = when (this) { From 51ffe26a919a8b0e999496d7eb5cb16f8095d413 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 16 May 2022 17:17:15 +0100 Subject: [PATCH 012/125] renaming comparator to give more context to its usage --- .../im/vector/app/features/onboarding/OnboardingViewModel.kt | 4 ++-- ...tor.kt => MatrixOrgMissingRegistrationStagesComparator.kt} | 2 +- ...kt => MatrixOrgMissingRegistrationStagesComparatorTest.kt} | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename vector/src/main/java/im/vector/app/features/onboarding/ftueauth/{FtueMissingRegistrationStagesComparator.kt => MatrixOrgMissingRegistrationStagesComparator.kt} (93%) rename vector/src/test/java/im/vector/app/features/onboarding/ftueauth/{FtueMissingRegistrationStagesComparatorTest.kt => MatrixOrgMissingRegistrationStagesComparatorTest.kt} (91%) diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index a7468cf95b..94bb36dbbc 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -42,7 +42,7 @@ import im.vector.app.features.login.ReAuthHelper import im.vector.app.features.login.ServerType import im.vector.app.features.login.SignMode import im.vector.app.features.onboarding.StartAuthenticationFlowUseCase.StartAuthenticationResult -import im.vector.app.features.onboarding.ftueauth.FtueMissingRegistrationStagesComparator +import im.vector.app.features.onboarding.ftueauth.MatrixOrgMissingRegistrationStagesComparator import kotlinx.coroutines.Job import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.launch @@ -301,7 +301,7 @@ class OnboardingViewModel @AssistedInject constructor( private fun OnboardingViewState.hasSelectedMatrixOrg() = selectedHomeserver.userFacingUrl == matrixOrgUrl - private fun FlowResult.overrideOrder() = copy(missingStages = missingStages.sortedWith(FtueMissingRegistrationStagesComparator())) + private fun FlowResult.overrideOrder() = copy(missingStages = missingStages.sortedWith(MatrixOrgMissingRegistrationStagesComparator())) private fun handleRegisterWith(action: OnboardingAction.Register) { reAuthHelper.data = action.password diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueMissingRegistrationStagesComparator.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparator.kt similarity index 93% rename from vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueMissingRegistrationStagesComparator.kt rename to vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparator.kt index 4d9fe10852..894a474a9e 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueMissingRegistrationStagesComparator.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparator.kt @@ -18,7 +18,7 @@ package im.vector.app.features.onboarding.ftueauth import org.matrix.android.sdk.api.auth.registration.Stage -class FtueMissingRegistrationStagesComparator : Comparator { +class MatrixOrgMissingRegistrationStagesComparator : Comparator { override fun compare(a: Stage?, b: Stage?): Int { return (a?.toPriority() ?: 0).compareTo(b?.toPriority() ?: 0) diff --git a/vector/src/test/java/im/vector/app/features/onboarding/ftueauth/FtueMissingRegistrationStagesComparatorTest.kt b/vector/src/test/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparatorTest.kt similarity index 91% rename from vector/src/test/java/im/vector/app/features/onboarding/ftueauth/FtueMissingRegistrationStagesComparatorTest.kt rename to vector/src/test/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparatorTest.kt index 010cf5de60..1fe8ad6000 100644 --- a/vector/src/test/java/im/vector/app/features/onboarding/ftueauth/FtueMissingRegistrationStagesComparatorTest.kt +++ b/vector/src/test/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparatorTest.kt @@ -25,7 +25,7 @@ import im.vector.app.test.fixtures.anOtherStage import org.amshove.kluent.shouldBeEqualTo import org.junit.Test -class FtueMissingRegistrationStagesComparatorTest { +class MatrixOrgMissingRegistrationStagesComparatorTest { @Test fun `when ordering stages, then prioritizes email`() { @@ -38,7 +38,7 @@ class FtueMissingRegistrationStagesComparatorTest { aTermsStage() ) - val result = input.sortedWith(FtueMissingRegistrationStagesComparator()) + val result = input.sortedWith(MatrixOrgMissingRegistrationStagesComparator()) result shouldBeEqualTo listOf( anEmailStage(), From 444980395eb33c84749d93aede4950f014dfe2ce Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Mon, 16 May 2022 17:26:12 +0100 Subject: [PATCH 013/125] inlining single use extension --- .../vector/app/features/onboarding/OnboardingViewModel.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index 94bb36dbbc..8424a5e915 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -292,7 +292,9 @@ class OnboardingViewModel @AssistedInject constructor( private fun emitFlowResultViewEvent(flowResult: FlowResult) { withState { state -> val orderedResult = when { - state.hasSelectedMatrixOrg() && vectorFeatures.isOnboardingCombinedRegisterEnabled() -> flowResult.overrideOrder() + state.hasSelectedMatrixOrg() && vectorFeatures.isOnboardingCombinedRegisterEnabled() -> flowResult.copy( + missingStages = flowResult.missingStages.sortedWith(MatrixOrgMissingRegistrationStagesComparator()) + ) else -> flowResult } _viewEvents.post(OnboardingViewEvents.RegistrationFlowResult(orderedResult, isRegistrationStarted)) @@ -301,8 +303,6 @@ class OnboardingViewModel @AssistedInject constructor( private fun OnboardingViewState.hasSelectedMatrixOrg() = selectedHomeserver.userFacingUrl == matrixOrgUrl - private fun FlowResult.overrideOrder() = copy(missingStages = missingStages.sortedWith(MatrixOrgMissingRegistrationStagesComparator())) - private fun handleRegisterWith(action: OnboardingAction.Register) { reAuthHelper.data = action.password handleRegisterAction( From 271bc91303f4f2cff85204b956581e6d30f4fae3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 May 2022 23:08:43 +0000 Subject: [PATCH 014/125] Bump vanniktechEmoji from 0.9.0 to 0.12.0 Bumps `vanniktechEmoji` from 0.9.0 to 0.12.0. Updates `emoji-material` from 0.9.0 to 0.12.0 - [Release notes](https://github.com/vanniktech/Emoji/releases) - [Changelog](https://github.com/vanniktech/Emoji/blob/master/CHANGELOG.md) - [Commits](https://github.com/vanniktech/Emoji/compare/0.9.0...0.12.0) Updates `emoji-google` from 0.9.0 to 0.12.0 - [Release notes](https://github.com/vanniktech/Emoji/releases) - [Changelog](https://github.com/vanniktech/Emoji/blob/master/CHANGELOG.md) - [Commits](https://github.com/vanniktech/Emoji/compare/0.9.0...0.12.0) --- updated-dependencies: - dependency-name: com.vanniktech:emoji-material dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: com.vanniktech:emoji-google dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- dependencies.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies.gradle b/dependencies.gradle index 10f9539e5a..b868f74cd1 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -23,7 +23,7 @@ def mavericks = "2.6.1" def glide = "4.13.2" def bigImageViewer = "1.8.1" def jjwt = "0.11.5" -def vanniktechEmoji = "0.9.0" +def vanniktechEmoji = "0.12.0" // Testing def mockk = "1.12.4" From 1ec99ee89e85ef16823991fd6e00669a84a6131c Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 17 May 2022 10:31:32 +0100 Subject: [PATCH 015/125] renaming comparator to only specify the matrix.org domain --- .../im/vector/app/features/onboarding/OnboardingViewModel.kt | 4 ++-- ...Comparator.kt => MatrixOrgRegistrationStagesComparator.kt} | 2 +- ...orTest.kt => MatrixOrgRegistrationStagesComparatorTest.kt} | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename vector/src/main/java/im/vector/app/features/onboarding/ftueauth/{MatrixOrgMissingRegistrationStagesComparator.kt => MatrixOrgRegistrationStagesComparator.kt} (93%) rename vector/src/test/java/im/vector/app/features/onboarding/ftueauth/{MatrixOrgMissingRegistrationStagesComparatorTest.kt => MatrixOrgRegistrationStagesComparatorTest.kt} (91%) diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index 8424a5e915..9fd013ee79 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -42,7 +42,7 @@ import im.vector.app.features.login.ReAuthHelper import im.vector.app.features.login.ServerType import im.vector.app.features.login.SignMode import im.vector.app.features.onboarding.StartAuthenticationFlowUseCase.StartAuthenticationResult -import im.vector.app.features.onboarding.ftueauth.MatrixOrgMissingRegistrationStagesComparator +import im.vector.app.features.onboarding.ftueauth.MatrixOrgRegistrationStagesComparator import kotlinx.coroutines.Job import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.launch @@ -293,7 +293,7 @@ class OnboardingViewModel @AssistedInject constructor( withState { state -> val orderedResult = when { state.hasSelectedMatrixOrg() && vectorFeatures.isOnboardingCombinedRegisterEnabled() -> flowResult.copy( - missingStages = flowResult.missingStages.sortedWith(MatrixOrgMissingRegistrationStagesComparator()) + missingStages = flowResult.missingStages.sortedWith(MatrixOrgRegistrationStagesComparator()) ) else -> flowResult } diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparator.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgRegistrationStagesComparator.kt similarity index 93% rename from vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparator.kt rename to vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgRegistrationStagesComparator.kt index 894a474a9e..fcc70803a0 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparator.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgRegistrationStagesComparator.kt @@ -18,7 +18,7 @@ package im.vector.app.features.onboarding.ftueauth import org.matrix.android.sdk.api.auth.registration.Stage -class MatrixOrgMissingRegistrationStagesComparator : Comparator { +class MatrixOrgRegistrationStagesComparator : Comparator { override fun compare(a: Stage?, b: Stage?): Int { return (a?.toPriority() ?: 0).compareTo(b?.toPriority() ?: 0) diff --git a/vector/src/test/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparatorTest.kt b/vector/src/test/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgRegistrationStagesComparatorTest.kt similarity index 91% rename from vector/src/test/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparatorTest.kt rename to vector/src/test/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgRegistrationStagesComparatorTest.kt index 1fe8ad6000..08be0ee058 100644 --- a/vector/src/test/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgMissingRegistrationStagesComparatorTest.kt +++ b/vector/src/test/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgRegistrationStagesComparatorTest.kt @@ -25,7 +25,7 @@ import im.vector.app.test.fixtures.anOtherStage import org.amshove.kluent.shouldBeEqualTo import org.junit.Test -class MatrixOrgMissingRegistrationStagesComparatorTest { +class MatrixOrgRegistrationStagesComparatorTest { @Test fun `when ordering stages, then prioritizes email`() { @@ -38,7 +38,7 @@ class MatrixOrgMissingRegistrationStagesComparatorTest { aTermsStage() ) - val result = input.sortedWith(MatrixOrgMissingRegistrationStagesComparator()) + val result = input.sortedWith(MatrixOrgRegistrationStagesComparator()) result shouldBeEqualTo listOf( anEmailStage(), From 5f2cb671e2d27361b0e1561035fe1265d4061e6b Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 17 May 2022 10:35:14 +0100 Subject: [PATCH 016/125] making comparator override non null as kotlin guards against this --- .../ftueauth/MatrixOrgRegistrationStagesComparator.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgRegistrationStagesComparator.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgRegistrationStagesComparator.kt index fcc70803a0..527c20987a 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgRegistrationStagesComparator.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/MatrixOrgRegistrationStagesComparator.kt @@ -20,8 +20,8 @@ import org.matrix.android.sdk.api.auth.registration.Stage class MatrixOrgRegistrationStagesComparator : Comparator { - override fun compare(a: Stage?, b: Stage?): Int { - return (a?.toPriority() ?: 0).compareTo(b?.toPriority() ?: 0) + override fun compare(a: Stage, b: Stage): Int { + return a.toPriority().compareTo(b.toPriority()) } private fun Stage.toPriority() = when (this) { From 00e800459d59ff1c68a4a07755812b4667d56aa1 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Tue, 17 May 2022 14:13:38 +0300 Subject: [PATCH 017/125] Write unit tests for poll response event aggregation. --- .../poll/PollAggregationProcessorTest.kt | 131 +++++++++++++++++- 1 file changed, 126 insertions(+), 5 deletions(-) diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt index a14ce5b697..321680c8a7 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt @@ -17,20 +17,31 @@ package org.matrix.android.sdk.internal.session.room.aggregation.poll import io.mockk.every +import io.mockk.mockk +import io.realm.RealmList import io.realm.RealmModel import io.realm.RealmQuery import org.amshove.kluent.shouldBeFalse import org.amshove.kluent.shouldBeTrue +import org.junit.Before import org.junit.Test +import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.RelationType import org.matrix.android.sdk.api.session.events.model.toContent +import org.matrix.android.sdk.api.session.getRoom +import org.matrix.android.sdk.api.session.room.Room +import org.matrix.android.sdk.api.session.room.getTimelineEvent import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent +import org.matrix.android.sdk.api.session.room.model.message.MessagePollResponseContent import org.matrix.android.sdk.api.session.room.model.message.PollAnswer import org.matrix.android.sdk.api.session.room.model.message.PollCreationInfo import org.matrix.android.sdk.api.session.room.model.message.PollQuestion +import org.matrix.android.sdk.api.session.room.model.message.PollResponse import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent +import org.matrix.android.sdk.api.session.room.sender.SenderInfo +import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntityFields import org.matrix.android.sdk.internal.database.model.PollResponseAggregatedSummaryEntity @@ -64,6 +75,26 @@ private val A_POLL_CONTENT = MessagePollContent( ) ) +private val A_POLL_RESPONSE_CONTENT = MessagePollResponseContent( + unstableResponse = PollResponse( + answers = listOf("5ef5f7b0-c9a1-49cf-a0b3-374729a43e76") + ), + relatesTo = RelationDefaultContent( + type = RelationType.REFERENCE, + eventId = AN_EVENT_ID + ) +) + +private val AN_INVALID_POLL_RESPONSE_CONTENT = MessagePollResponseContent( + unstableResponse = PollResponse( + answers = listOf("fake-option-id") + ), + relatesTo = RelationDefaultContent( + type = RelationType.REFERENCE, + eventId = AN_EVENT_ID + ) +) + private val A_POLL_START_EVENT = Event( type = EventType.POLL_START.first(), eventId = AN_EVENT_ID, @@ -73,6 +104,45 @@ private val A_POLL_START_EVENT = Event( content = A_POLL_CONTENT.toContent() ) +private val A_POLL_RESPONSE_EVENT = Event( + type = EventType.POLL_RESPONSE.first(), + eventId = AN_EVENT_ID, + originServerTs = 1652435922563, + senderId = A_USER_ID_1, + roomId = A_ROOM_ID, + content = A_POLL_RESPONSE_CONTENT.toContent() +) + +private val A_TIMELINE_EVENT = TimelineEvent( + root = A_POLL_START_EVENT, + localId = 1234, + eventId = AN_EVENT_ID, + displayIndex = 0, + senderInfo = SenderInfo(A_USER_ID_1, "A_USER_ID_1", true, null) +) + +private val A_POLL_RESPONSE_EVENT_WITHOUT_REFERENCE = A_POLL_RESPONSE_EVENT.copy( + content = A_POLL_RESPONSE_CONTENT + .copy( + relatesTo = RelationDefaultContent( + type = RelationType.REFERENCE, + eventId = null + ) + ) + .toContent() +) + +private val A_POLL_RESPONSE_EVENT_WITH_A_WRONG_REFERENCE = A_POLL_RESPONSE_EVENT.copy( + content = A_POLL_RESPONSE_CONTENT + .copy( + relatesTo = RelationDefaultContent( + type = RelationType.REPLACE, + eventId = null + ) + ) + .toContent() +) + private val A_POLL_REPLACE_EVENT = A_POLL_START_EVENT.copy( content = A_POLL_CONTENT .copy( @@ -106,6 +176,10 @@ private val A_POLL_REFERENCE_EVENT = A_POLL_START_EVENT.copy( .toContent() ) +private val AN_INVALID_POLL_RESPONSE_EVENT = A_POLL_RESPONSE_EVENT.copy( + content = AN_INVALID_POLL_RESPONSE_CONTENT.toContent() +) + private val AN_EVENT_ANNOTATIONS_SUMMARY_ENTITY = EventAnnotationsSummaryEntity( roomId = A_ROOM_ID, eventId = AN_EVENT_ID, @@ -116,6 +190,13 @@ class PollAggregationProcessorTest { private val pollAggregationProcessor: PollAggregationProcessor = DefaultPollAggregationProcessor() private val realm = FakeRealm() + private val session = mockk() + + @Before + fun setup() { + mockEventAnnotationsSummaryEntity() + mockRoom(A_ROOM_ID, AN_EVENT_ID) + } @Test fun `given a poll start event which is not a replace is not processed by poll aggregator`() { @@ -134,15 +215,40 @@ class PollAggregationProcessorTest { @Test fun `given a poll start event with a replace is processed by poll aggregator`() { - val queryResult = realm.givenWhereReturns(result = EventAnnotationsSummaryEntity()) - queryResult.givenEqualTo(EventAnnotationsSummaryEntityFields.ROOM_ID, A_POLL_REPLACE_EVENT.roomId!!, queryResult) - queryResult.givenEqualTo(EventAnnotationsSummaryEntityFields.EVENT_ID, A_POLL_REPLACE_EVENT.eventId!!, queryResult) - pollAggregationProcessor.handlePollStartEvent(realm.instance, A_POLL_REPLACE_EVENT).shouldBeTrue() } @Test - fun handlePollResponseEvent() { + fun `given a poll response event with a broken reference is not processed by poll aggregator`() { + pollAggregationProcessor.handlePollResponseEvent(session, realm.instance, A_POLL_RESPONSE_EVENT_WITH_A_WRONG_REFERENCE).shouldBeFalse() + } + + @Test + fun `given a poll response event with a reference is processed by poll aggregator`() { + every { realm.instance.createObject(PollResponseAggregatedSummaryEntity::class.java) } returns PollResponseAggregatedSummaryEntity() + pollAggregationProcessor.handlePollResponseEvent(session, realm.instance, A_POLL_RESPONSE_EVENT).shouldBeTrue() + } + + @Test + fun `given a poll response event after poll is closed is not processed by poll aggregator`() { + every { realm.instance.createObject(PollResponseAggregatedSummaryEntity::class.java) } returns PollResponseAggregatedSummaryEntity().apply { + closedTime = (A_POLL_RESPONSE_EVENT.originServerTs ?: 0) - 1 + } + pollAggregationProcessor.handlePollResponseEvent(session, realm.instance, A_POLL_RESPONSE_EVENT).shouldBeFalse() + } + + @Test + fun `given a poll response event which is already processed is not processed by poll aggregator`() { + every { realm.instance.createObject(PollResponseAggregatedSummaryEntity::class.java) } returns PollResponseAggregatedSummaryEntity().apply { + sourceEvents = RealmList(A_POLL_RESPONSE_EVENT.eventId) + } + pollAggregationProcessor.handlePollResponseEvent(session, realm.instance, A_POLL_RESPONSE_EVENT).shouldBeFalse() + } + + @Test + fun `given a poll response event which is not one of the options is not processed by poll aggregator`() { + every { realm.instance.createObject(PollResponseAggregatedSummaryEntity::class.java) } returns PollResponseAggregatedSummaryEntity() + pollAggregationProcessor.handlePollResponseEvent(session, realm.instance, AN_INVALID_POLL_RESPONSE_EVENT).shouldBeFalse() } @Test @@ -152,4 +258,19 @@ class PollAggregationProcessorTest { private inline fun RealmQuery.givenEqualTo(fieldName: String, value: String, result: RealmQuery) { every { equalTo(fieldName, value) } returns result } + + private fun mockEventAnnotationsSummaryEntity() { + val queryResult = realm.givenWhereReturns(result = EventAnnotationsSummaryEntity()) + queryResult.givenEqualTo(EventAnnotationsSummaryEntityFields.ROOM_ID, A_POLL_REPLACE_EVENT.roomId!!, queryResult) + queryResult.givenEqualTo(EventAnnotationsSummaryEntityFields.EVENT_ID, A_POLL_REPLACE_EVENT.eventId!!, queryResult) + } + + private fun mockRoom( + roomId: String, + eventId: String + ) { + val room = mockk() + every { session.getRoom(roomId) } returns room + every { room.getTimelineEvent(eventId) } returns A_TIMELINE_EVENT + } } From 4c079cc0ac3cce749fa0549f5d58b75e43502a7a Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Tue, 17 May 2022 14:59:14 +0300 Subject: [PATCH 018/125] Write unit tests for poll end event aggregation. --- .../poll/DefaultPollAggregationProcessor.kt | 2 +- .../poll/PollAggregationProcessorTest.kt | 54 ++++++++++++------- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt index 6ea8f698e3..bdaa956d0f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt @@ -159,7 +159,7 @@ class DefaultPollAggregationProcessor @Inject constructor() : PollAggregationPro val pollOwnerId = getPollEvent(session, roomId, pollEventId)?.root?.senderId val isPollOwner = pollOwnerId == event.senderId - if (!isPollOwner && !powerLevelsHelper.isUserAbleToRedact(event.senderId ?: "")) { + if (!isPollOwner || !powerLevelsHelper.isUserAbleToRedact(event.senderId ?: "")) { Timber.v("## Received poll.end event $pollEventId but user ${event.senderId} doesn't have enough power level in room $roomId") return false } diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt index 321680c8a7..838796a135 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt @@ -33,6 +33,7 @@ import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.getRoom import org.matrix.android.sdk.api.session.room.Room import org.matrix.android.sdk.api.session.room.getTimelineEvent +import org.matrix.android.sdk.api.session.room.model.message.MessageEndPollContent import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent import org.matrix.android.sdk.api.session.room.model.message.MessagePollResponseContent import org.matrix.android.sdk.api.session.room.model.message.PollAnswer @@ -40,6 +41,7 @@ import org.matrix.android.sdk.api.session.room.model.message.PollCreationInfo import org.matrix.android.sdk.api.session.room.model.message.PollQuestion import org.matrix.android.sdk.api.session.room.model.message.PollResponse import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent +import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper import org.matrix.android.sdk.api.session.room.sender.SenderInfo import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity @@ -48,7 +50,6 @@ import org.matrix.android.sdk.internal.database.model.PollResponseAggregatedSumm import org.matrix.android.sdk.test.fakes.FakeRealm private const val A_USER_ID_1 = "@user_1:matrix.org" -private const val A_USER_ID_2 = "@user_2:matrix.org" private const val A_ROOM_ID = "!sUeOGZKsBValPTUMax:matrix.org" private const val AN_EVENT_ID = "\$vApgexcL8Vfh-WxYKsFKCDooo67ttbjm3TiVKXaWijU" @@ -85,6 +86,13 @@ private val A_POLL_RESPONSE_CONTENT = MessagePollResponseContent( ) ) +private val A_POLL_END_CONTENT = MessageEndPollContent( + relatesTo = RelationDefaultContent( + type = RelationType.REFERENCE, + eventId = AN_EVENT_ID + ) +) + private val AN_INVALID_POLL_RESPONSE_CONTENT = MessagePollResponseContent( unstableResponse = PollResponse( answers = listOf("fake-option-id") @@ -113,6 +121,15 @@ private val A_POLL_RESPONSE_EVENT = Event( content = A_POLL_RESPONSE_CONTENT.toContent() ) +private val A_POLL_END_EVENT = Event( + type = EventType.POLL_END.first(), + eventId = AN_EVENT_ID, + originServerTs = 1652435922563, + senderId = A_USER_ID_1, + roomId = A_ROOM_ID, + content = A_POLL_END_CONTENT.toContent() +) + private val A_TIMELINE_EVENT = TimelineEvent( root = A_POLL_START_EVENT, localId = 1234, @@ -121,17 +138,6 @@ private val A_TIMELINE_EVENT = TimelineEvent( senderInfo = SenderInfo(A_USER_ID_1, "A_USER_ID_1", true, null) ) -private val A_POLL_RESPONSE_EVENT_WITHOUT_REFERENCE = A_POLL_RESPONSE_EVENT.copy( - content = A_POLL_RESPONSE_CONTENT - .copy( - relatesTo = RelationDefaultContent( - type = RelationType.REFERENCE, - eventId = null - ) - ) - .toContent() -) - private val A_POLL_RESPONSE_EVENT_WITH_A_WRONG_REFERENCE = A_POLL_RESPONSE_EVENT.copy( content = A_POLL_RESPONSE_CONTENT .copy( @@ -180,12 +186,6 @@ private val AN_INVALID_POLL_RESPONSE_EVENT = A_POLL_RESPONSE_EVENT.copy( content = AN_INVALID_POLL_RESPONSE_CONTENT.toContent() ) -private val AN_EVENT_ANNOTATIONS_SUMMARY_ENTITY = EventAnnotationsSummaryEntity( - roomId = A_ROOM_ID, - eventId = AN_EVENT_ID, - pollResponseSummary = PollResponseAggregatedSummaryEntity() -) - class PollAggregationProcessorTest { private val pollAggregationProcessor: PollAggregationProcessor = DefaultPollAggregationProcessor() @@ -252,7 +252,17 @@ class PollAggregationProcessorTest { } @Test - fun handlePollEndEvent() { + fun `given a poll end event is processed by poll aggregator`() { + every { realm.instance.createObject(PollResponseAggregatedSummaryEntity::class.java) } returns PollResponseAggregatedSummaryEntity() + val powerLevelsHelper = mockRedactionPowerLevels(A_USER_ID_1, true) + pollAggregationProcessor.handlePollEndEvent(session, powerLevelsHelper, realm.instance, A_POLL_END_EVENT).shouldBeTrue() + } + + @Test + fun `given a poll end event without redaction power level is not processed by poll aggregator`() { + every { realm.instance.createObject(PollResponseAggregatedSummaryEntity::class.java) } returns PollResponseAggregatedSummaryEntity() + val powerLevelsHelper = mockRedactionPowerLevels(A_USER_ID_1, false) + pollAggregationProcessor.handlePollEndEvent(session, powerLevelsHelper, realm.instance, A_POLL_END_EVENT).shouldBeFalse() } private inline fun RealmQuery.givenEqualTo(fieldName: String, value: String, result: RealmQuery) { @@ -273,4 +283,10 @@ class PollAggregationProcessorTest { every { session.getRoom(roomId) } returns room every { room.getTimelineEvent(eventId) } returns A_TIMELINE_EVENT } + + private fun mockRedactionPowerLevels(userId: String, isAbleToRedact: Boolean): PowerLevelsHelper { + val powerLevelsHelper = mockk() + every { powerLevelsHelper.isUserAbleToRedact(userId) } returns isAbleToRedact + return powerLevelsHelper + } } From edd35872f37b581c6256c7e33fb5499b24dbe22a Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Tue, 17 May 2022 15:44:39 +0300 Subject: [PATCH 019/125] Fix ending poll power level condition. --- changelog.d/6074.bugfix | 1 + .../poll/DefaultPollAggregationProcessor.kt | 6 ++++-- .../poll/PollAggregationProcessorTest.kt | 13 +++++++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 changelog.d/6074.bugfix diff --git a/changelog.d/6074.bugfix b/changelog.d/6074.bugfix new file mode 100644 index 0000000000..692dce28d7 --- /dev/null +++ b/changelog.d/6074.bugfix @@ -0,0 +1 @@ +Poll refactoring with unit tests diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt index bdaa956d0f..2f55eb940e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt @@ -140,8 +140,10 @@ class DefaultPollAggregationProcessor @Inject constructor() : PollAggregationPro aggregatedPollSummaryEntity.sourceEvents.add(event.eventId) } + val myVote = existingVotes.find { it.userId == session.myUserId }?.option + val newSumModel = PollSummaryContent( - myVote = vote, + myVote = myVote, votes = existingVotes, votesSummary = newVotesSummary, totalVotes = totalVotes, @@ -159,7 +161,7 @@ class DefaultPollAggregationProcessor @Inject constructor() : PollAggregationPro val pollOwnerId = getPollEvent(session, roomId, pollEventId)?.root?.senderId val isPollOwner = pollOwnerId == event.senderId - if (!isPollOwner || !powerLevelsHelper.isUserAbleToRedact(event.senderId ?: "")) { + if (!isPollOwner && !powerLevelsHelper.isUserAbleToRedact(event.senderId ?: "")) { Timber.v("## Received poll.end event $pollEventId but user ${event.senderId} doesn't have enough power level in room $roomId") return false } diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt index 838796a135..9783a40d6c 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt @@ -196,6 +196,7 @@ class PollAggregationProcessorTest { fun setup() { mockEventAnnotationsSummaryEntity() mockRoom(A_ROOM_ID, AN_EVENT_ID) + every { session.myUserId } returns A_USER_ID_1 } @Test @@ -259,10 +260,18 @@ class PollAggregationProcessorTest { } @Test - fun `given a poll end event without redaction power level is not processed by poll aggregator`() { + fun `given a poll end event without redaction power level of event owner is processed by poll aggregator`() { every { realm.instance.createObject(PollResponseAggregatedSummaryEntity::class.java) } returns PollResponseAggregatedSummaryEntity() val powerLevelsHelper = mockRedactionPowerLevels(A_USER_ID_1, false) - pollAggregationProcessor.handlePollEndEvent(session, powerLevelsHelper, realm.instance, A_POLL_END_EVENT).shouldBeFalse() + pollAggregationProcessor.handlePollEndEvent(session, powerLevelsHelper, realm.instance, A_POLL_END_EVENT).shouldBeTrue() + } + + @Test + fun `given a poll end event without redaction power level of non event owner is not processed by poll aggregator`() { + every { realm.instance.createObject(PollResponseAggregatedSummaryEntity::class.java) } returns PollResponseAggregatedSummaryEntity() + val powerLevelsHelper = mockRedactionPowerLevels("another-sender-id", false) + val event = A_POLL_END_EVENT.copy(senderId = "another-sender-id") + pollAggregationProcessor.handlePollEndEvent(session, powerLevelsHelper, realm.instance, event).shouldBeFalse() } private inline fun RealmQuery.givenEqualTo(fieldName: String, value: String, result: RealmQuery) { From a0a7d3e7f6963aa27ab6a91c580ce580b0721226 Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Tue, 17 May 2022 16:28:30 +0300 Subject: [PATCH 020/125] Enhance reply attack to prevent DUPLICATED_MESSAGE_INDEX while decrypting the same event --- .../crypto/replay_attack/ReplayAttackTest.kt | 160 ------------------ .../crypto/replayattack/ReplayAttackTest.kt | 109 ++++++++++++ .../sync/handler/room/RoomSyncHandler.kt | 9 +- 3 files changed, 117 insertions(+), 161 deletions(-) delete mode 100644 matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replay_attack/ReplayAttackTest.kt create mode 100644 matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replay_attack/ReplayAttackTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replay_attack/ReplayAttackTest.kt deleted file mode 100644 index 5c9892e264..0000000000 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replay_attack/ReplayAttackTest.kt +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2022 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.replay_attack - -import android.util.Log -import androidx.test.filters.LargeTest -import org.junit.Assert -import org.junit.Assert.assertEquals -import org.junit.FixMethodOrder -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 -import org.junit.runners.MethodSorters -import org.matrix.android.sdk.InstrumentedTest -import org.matrix.android.sdk.api.session.events.model.EventType -import org.matrix.android.sdk.api.session.events.model.toModel -import org.matrix.android.sdk.api.session.room.Room -import org.matrix.android.sdk.api.session.room.model.message.MessageContent -import org.matrix.android.sdk.api.session.room.send.SendState -import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings -import org.matrix.android.sdk.common.CommonTestHelper -import org.matrix.android.sdk.common.CryptoTestHelper -import org.matrix.android.sdk.common.TestConstants - -@RunWith(JUnit4::class) -@FixMethodOrder(MethodSorters.JVM) -@LargeTest -class ReplayAttackTest : InstrumentedTest { - - @Test - fun replayAttackTest() { - val testHelper = CommonTestHelper(context()) - val cryptoTestHelper = CryptoTestHelper(testHelper) - val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom(true) - - val e2eRoomID = cryptoTestData.roomId - - // Alice - val aliceSession = cryptoTestData.firstSession - val aliceRoomPOV = aliceSession.roomService().getRoom(e2eRoomID)!! - - // Bob - val bobSession = cryptoTestData.secondSession - val bobRoomPOV = bobSession!!.roomService().getRoom(e2eRoomID)!! - - assertEquals(bobRoomPOV.roomSummary()?.joinedMembersCount, 2) - Log.v("##REPLAY ATTACK", "Alice and Bob are in roomId: $e2eRoomID") - - - val sentEvents = testHelper.sendTextMessage(aliceRoomPOV, "Hello", 20) - -// val aliceMessageId: String? = sendMessageInRoom(aliceRoomPOV, "Hello Bob, I am Alice!", testHelper) - Assert.assertTrue("Message should be sent", sentEvents.size == 20) - Log.v("##REPLAY ATTACK", "Alice sent message to roomId: $e2eRoomID") - - // Bob should be able to decrypt the message -// testHelper.waitWithLatch { latch -> -// testHelper.retryPeriodicallyWithLatch(latch) { -// val timelineEvent = bobSession.roomService().getRoom(e2eRoomID)?.timelineService()?.getTimelineEvent(aliceMessageId!!) -// (timelineEvent != null && -// timelineEvent.isEncrypted() && -// timelineEvent.root.getClearType() == EventType.MESSAGE).also { -// if (it) { -// Log.v("#E2E TEST", "Bob can decrypt the message: ${timelineEvent?.root?.getDecryptedTextSummary()}") -// } -// } -// } -// } -// -// // Create a new user -// val arisSession = testHelper.createAccount("aris", SessionTestParams(true)) -// Log.v("#E2E TEST", "Aris user created") -// -// // Alice invites new user to the room -// testHelper.runBlockingTest { -// Log.v("#E2E TEST", "Alice invites ${arisSession.myUserId}") -// aliceRoomPOV.membershipService().invite(arisSession.myUserId) -// } -// -// waitForAndAcceptInviteInRoom(arisSession, e2eRoomID, testHelper) -// -// ensureMembersHaveJoined(aliceSession, arrayListOf(arisSession), e2eRoomID, testHelper) -// Log.v("#E2E TEST", "Aris has joined roomId: $e2eRoomID") -// -// when (roomHistoryVisibility) { -// RoomHistoryVisibility.WORLD_READABLE, -// RoomHistoryVisibility.SHARED, -// null -// -> { -// // Aris should be able to decrypt the message -// testHelper.waitWithLatch { latch -> -// testHelper.retryPeriodicallyWithLatch(latch) { -// val timelineEvent = arisSession.roomService().getRoom(e2eRoomID)?.timelineService()?.getTimelineEvent(aliceMessageId!!) -// (timelineEvent != null && -// timelineEvent.isEncrypted() && -// timelineEvent.root.getClearType() == EventType.MESSAGE -// ).also { -// if (it) { -// Log.v("#E2E TEST", "Aris can decrypt the message: ${timelineEvent?.root?.getDecryptedTextSummary()}") -// } -// } -// } -// } -// } -// RoomHistoryVisibility.INVITED, -// RoomHistoryVisibility.JOINED -> { -// // Aris should not even be able to get the message -// testHelper.waitWithLatch { latch -> -// testHelper.retryPeriodicallyWithLatch(latch) { -// val timelineEvent = arisSession.roomService().getRoom(e2eRoomID) -// ?.timelineService() -// ?.getTimelineEvent(aliceMessageId!!) -// timelineEvent == null -// } -// } -// } -// } - -// testHelper.signOutAndClose(arisSession) - cryptoTestData.cleanUp(testHelper) - } - - private fun sendMessageInRoom(aliceRoomPOV: Room, text: String, testHelper: CommonTestHelper): String? { - aliceRoomPOV.sendService().sendTextMessage(text) - var sentEventId: String? = null - testHelper.waitWithLatch(4 * TestConstants.timeOutMillis) { latch -> - val timeline = aliceRoomPOV.timelineService().createTimeline(null, TimelineSettings(60)) - timeline.start() - testHelper.retryPeriodicallyWithLatch(latch) { - val decryptedMsg = timeline.getSnapshot() - .filter { it.root.getClearType() == EventType.MESSAGE } - .also { list -> - val message = list.joinToString(",", "[", "]") { "${it.root.type}|${it.root.sendState}" } - Log.v("#E2E TEST", "Timeline snapshot is $message") - } - .filter { it.root.sendState == SendState.SYNCED } - .firstOrNull { it.root.getClearContent().toModel()?.body?.startsWith(text) == true } - sentEventId = decryptedMsg?.eventId - decryptedMsg != null - } - - timeline.dispose() - } - return sentEventId - } -} diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt new file mode 100644 index 0000000000..cb672f5e8d --- /dev/null +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.crypto.replayattack + +import androidx.test.filters.LargeTest +import org.amshove.kluent.internal.assertFailsWith +import org.junit.Assert +import org.junit.Assert.assertEquals +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import org.junit.runners.MethodSorters +import org.matrix.android.sdk.InstrumentedTest +import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.common.CommonTestHelper +import org.matrix.android.sdk.common.CryptoTestHelper + +@RunWith(JUnit4::class) +@FixMethodOrder(MethodSorters.JVM) +@LargeTest +class ReplayAttackTest : InstrumentedTest { + + @Test + fun replayAttackAlreadyDecryptedEventTest() { + val testHelper = CommonTestHelper(context()) + val cryptoTestHelper = CryptoTestHelper(testHelper) + val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom(true) + + val e2eRoomID = cryptoTestData.roomId + + // Alice + val aliceSession = cryptoTestData.firstSession + val aliceRoomPOV = aliceSession.roomService().getRoom(e2eRoomID)!! + + // Bob + val bobSession = cryptoTestData.secondSession + val bobRoomPOV = bobSession!!.roomService().getRoom(e2eRoomID)!! + assertEquals(bobRoomPOV.roomSummary()?.joinedMembersCount, 2) + + // Alice will send a message + val sentEvents = testHelper.sendTextMessage(aliceRoomPOV, "Hello I will be decrypted twice", 1) + Assert.assertTrue("Message should be sent", sentEvents.size == 1) + + val fakeEventId = sentEvents[0].eventId + "_fake" + val fakeEventWithTheSameIndex = + sentEvents[0].copy(eventId = fakeEventId, root = sentEvents[0].root.copy(eventId = fakeEventId)) + + testHelper.runBlockingTest { + // Lets assume we are from the main timelineId + val timelineId = "timelineId" + // Lets decrypt the original event + aliceSession.cryptoService().decryptEvent(sentEvents[0].root, timelineId) + // Lets decrypt the fake event that will have the same message index + val exception = assertFailsWith { + // An exception should be thrown while the same index would have been used for the previous decryption + aliceSession.cryptoService().decryptEvent(fakeEventWithTheSameIndex.root, timelineId) + } + assertEquals(MXCryptoError.ErrorType.DUPLICATED_MESSAGE_INDEX, exception.errorType) + } + cryptoTestData.cleanUp(testHelper) + } + + @Test + fun replayAttackSameEventTest() { + val testHelper = CommonTestHelper(context()) + val cryptoTestHelper = CryptoTestHelper(testHelper) + val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom(true) + + val e2eRoomID = cryptoTestData.roomId + + // Alice + val aliceSession = cryptoTestData.firstSession + val aliceRoomPOV = aliceSession.roomService().getRoom(e2eRoomID)!! + + // Bob + val bobSession = cryptoTestData.secondSession + val bobRoomPOV = bobSession!!.roomService().getRoom(e2eRoomID)!! + assertEquals(bobRoomPOV.roomSummary()?.joinedMembersCount, 2) + + // Alice will send a message + val sentEvents = testHelper.sendTextMessage(aliceRoomPOV, "Hello I will be decrypted twice", 1) + Assert.assertTrue("Message should be sent", sentEvents.size == 1) + + testHelper.runBlockingTest { + // Lets assume we are from the main timelineId + val timelineId = "timelineId" + // Lets decrypt the original event + aliceSession.cryptoService().decryptEvent(sentEvents[0].root, timelineId) + // Lets try to decrypt the same event + aliceSession.cryptoService().decryptEvent(sentEvents[0].root, timelineId) + } + cryptoTestData.cleanUp(testHelper) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt index a3be8b56a1..879bde1862 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt @@ -25,6 +25,7 @@ import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.isThread import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService import org.matrix.android.sdk.api.session.initsync.InitSyncStep @@ -520,9 +521,10 @@ internal class RoomSyncHandler @Inject constructor( private fun decryptIfNeeded(event: Event, roomId: String) { try { + val timelineId = generateTimelineId(roomId, event) // Event from sync does not have roomId, so add it to the event first // note: runBlocking should be used here while we are in realm single thread executor, to avoid thread switching - val result = runBlocking { cryptoService.decryptEvent(event.copy(roomId = roomId), "") } + val result = runBlocking { cryptoService.decryptEvent(event.copy(roomId = roomId), timelineId) } event.mxDecryptionResult = OlmDecryptionResult( payload = result.clearEvent, senderKey = result.senderCurve25519Key, @@ -537,6 +539,11 @@ internal class RoomSyncHandler @Inject constructor( } } + private fun generateTimelineId(roomId: String, event: Event): String { + val threadIndicator = if (event.isThread()) "_thread_" else "_" + return "${RoomSyncHandler::class.java.simpleName}$threadIndicator$roomId" + } + data class EphemeralResult( val typingUserIds: List = emptyList() ) From abbc57429a7a38d9ff5e3e091ddbe93f39e03196 Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Tue, 17 May 2022 17:16:27 +0300 Subject: [PATCH 021/125] Add changelog --- changelog.d/6077.sdk | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/6077.sdk diff --git a/changelog.d/6077.sdk b/changelog.d/6077.sdk new file mode 100644 index 0000000000..80310a28f5 --- /dev/null +++ b/changelog.d/6077.sdk @@ -0,0 +1 @@ +Improve replay attacks and reduce duplicate message index errors From 5c9281bc7e8f3704bef2c92d895838997050a80f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 18 May 2022 12:23:28 +0200 Subject: [PATCH 022/125] Ensure calling 'fail()' is not caught by the Exception handler --- .../java/org/matrix/android/sdk/Util.kt | 44 ++++++++++++++ .../sdk/internal/crypto/E2eeSanityTests.kt | 5 +- .../crypto/gossiping/KeyShareTests.kt | 14 ++--- .../crypto/gossiping/WithHeldTests.kt | 59 ++++++++++--------- 4 files changed, 83 insertions(+), 39 deletions(-) create mode 100644 matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/Util.kt diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/Util.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/Util.kt new file mode 100644 index 0000000000..2970dec29a --- /dev/null +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/Util.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk + +import junit.framework.TestCase.fail + +/** + * Will fail the test if invoking [block] is not throwing a Throwable. + * + * @param message the failure message, if the block does not throw any Throwable + * @param failureBlock a Lambda to be able to do extra check on the thrown Throwable + * @param block the block to test + */ +internal suspend fun mustFail( + message: String = "must fail", + failureBlock: ((Throwable) -> Unit)? = null, + block: suspend () -> Unit, +) { + val isSuccess = try { + block.invoke() + true + } catch (throwable: Throwable) { + failureBlock?.invoke(throwable) + false + } + + if (isSuccess) { + fail(message) + } +} diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt index 38597269cb..552936971f 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt @@ -62,6 +62,7 @@ import org.matrix.android.sdk.common.RetryTestRule import org.matrix.android.sdk.common.SessionTestParams import org.matrix.android.sdk.common.TestConstants import org.matrix.android.sdk.common.TestMatrixCallback +import org.matrix.android.sdk.mustFail import java.util.concurrent.CountDownLatch @RunWith(JUnit4::class) @@ -525,10 +526,8 @@ class E2eeSanityTests : InstrumentedTest { // Confirm we can decrypt one but not the other testHelper.runBlockingTest { - try { + mustFail(message = "Should not be able to decrypt event") { newBobSession.cryptoService().decryptEvent(firstEventNewBobPov.root, "") - fail("Should not be able to decrypt event") - } catch (_: MXCryptoError) { } } diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt index 1bd2a46381..895f95aeac 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt @@ -21,7 +21,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest import junit.framework.TestCase.assertNotNull import junit.framework.TestCase.assertTrue -import junit.framework.TestCase.fail import org.amshove.kluent.internal.assertEquals import org.junit.Assert import org.junit.Assert.assertNull @@ -47,6 +46,7 @@ import org.matrix.android.sdk.common.CryptoTestHelper import org.matrix.android.sdk.common.RetryTestRule import org.matrix.android.sdk.common.SessionTestParams import org.matrix.android.sdk.common.TestConstants +import org.matrix.android.sdk.mustFail @RunWith(AndroidJUnit4::class) @FixMethodOrder(MethodSorters.JVM) @@ -95,12 +95,10 @@ class KeyShareTests : InstrumentedTest { assertNotNull(receivedEvent) assert(receivedEvent!!.isEncrypted()) - try { - commonTestHelper.runBlockingTest { + commonTestHelper.runBlockingTest { + mustFail { aliceSession2.cryptoService().decryptEvent(receivedEvent.root, "foo") } - fail("should fail") - } catch (failure: Throwable) { } val outgoingRequestsBefore = aliceSession2.cryptoService().getOutgoingRoomKeyRequests() @@ -168,12 +166,10 @@ class KeyShareTests : InstrumentedTest { } } - try { - commonTestHelper.runBlockingTest { + commonTestHelper.runBlockingTest { + mustFail { aliceSession2.cryptoService().decryptEvent(receivedEvent.root, "foo") } - fail("should fail") - } catch (failure: Throwable) { } // Mark the device as trusted diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt index 1c3c6c46e7..13133b726c 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt @@ -42,6 +42,7 @@ import org.matrix.android.sdk.common.MockOkHttpInterceptor import org.matrix.android.sdk.common.RetryTestRule import org.matrix.android.sdk.common.SessionTestParams import org.matrix.android.sdk.common.TestConstants +import org.matrix.android.sdk.mustFail @RunWith(AndroidJUnit4::class) @FixMethodOrder(MethodSorters.JVM) @@ -96,17 +97,19 @@ class WithHeldTests : InstrumentedTest { // ============================= // Bob should not be able to decrypt because the keys is withheld - try { - // .. might need to wait a bit for stability? - testHelper.runBlockingTest { + // .. might need to wait a bit for stability? + testHelper.runBlockingTest { + mustFail( + message = "This session should not be able to decrypt", + failureBlock = { failure -> + val type = (failure as MXCryptoError.Base).errorType + val technicalMessage = failure.technicalMessage + Assert.assertEquals("Error should be withheld", MXCryptoError.ErrorType.KEYS_WITHHELD, type) + Assert.assertEquals("Cause should be unverified", WithHeldCode.UNVERIFIED.value, technicalMessage) + } + ) { bobUnverifiedSession.cryptoService().decryptEvent(eventBobPOV.root, "") } - Assert.fail("This session should not be able to decrypt") - } catch (failure: Throwable) { - val type = (failure as MXCryptoError.Base).errorType - val technicalMessage = failure.technicalMessage - Assert.assertEquals("Error should be withheld", MXCryptoError.ErrorType.KEYS_WITHHELD, type) - Assert.assertEquals("Cause should be unverified", WithHeldCode.UNVERIFIED.value, technicalMessage) } // Let's see if the reply we got from bob first session is unverified @@ -137,17 +140,18 @@ class WithHeldTests : InstrumentedTest { } // Previous message should still be undecryptable (partially withheld session) - try { - // .. might need to wait a bit for stability? - testHelper.runBlockingTest { + // .. might need to wait a bit for stability? + testHelper.runBlockingTest { + mustFail( + message = "This session should not be able to decrypt", + failureBlock = { failure -> + val type = (failure as MXCryptoError.Base).errorType + val technicalMessage = failure.technicalMessage + Assert.assertEquals("Error should be withheld", MXCryptoError.ErrorType.KEYS_WITHHELD, type) + Assert.assertEquals("Cause should be unverified", WithHeldCode.UNVERIFIED.value, technicalMessage) + }) { bobUnverifiedSession.cryptoService().decryptEvent(eventBobPOV.root, "") } - Assert.fail("This session should not be able to decrypt") - } catch (failure: Throwable) { - val type = (failure as MXCryptoError.Base).errorType - val technicalMessage = failure.technicalMessage - Assert.assertEquals("Error should be withheld", MXCryptoError.ErrorType.KEYS_WITHHELD, type) - Assert.assertEquals("Cause should be unverified", WithHeldCode.UNVERIFIED.value, technicalMessage) } testHelper.signOutAndClose(aliceSession) @@ -190,17 +194,18 @@ class WithHeldTests : InstrumentedTest { // Previous message should still be undecryptable (partially withheld session) val eventBobPOV = bobSession.getRoom(testData.roomId)?.getTimelineEvent(eventId) - try { - // .. might need to wait a bit for stability? - testHelper.runBlockingTest { + // .. might need to wait a bit for stability? + testHelper.runBlockingTest { + mustFail( + message = "This session should not be able to decrypt", + failureBlock = { failure -> + val type = (failure as MXCryptoError.Base).errorType + val technicalMessage = failure.technicalMessage + Assert.assertEquals("Error should be withheld", MXCryptoError.ErrorType.KEYS_WITHHELD, type) + Assert.assertEquals("Cause should be unverified", WithHeldCode.NO_OLM.value, technicalMessage) + }) { bobSession.cryptoService().decryptEvent(eventBobPOV!!.root, "") } - Assert.fail("This session should not be able to decrypt") - } catch (failure: Throwable) { - val type = (failure as MXCryptoError.Base).errorType - val technicalMessage = failure.technicalMessage - Assert.assertEquals("Error should be withheld", MXCryptoError.ErrorType.KEYS_WITHHELD, type) - Assert.assertEquals("Cause should be unverified", WithHeldCode.NO_OLM.value, technicalMessage) } // Ensure that alice has marked the session to be shared with bob From 7ce093e239c706d13beb370f852e848a8826f68c Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Wed, 18 May 2022 13:39:12 +0300 Subject: [PATCH 023/125] Code review fixes. --- .../poll/DefaultPollAggregationProcessor.kt | 13 +- .../poll/PollAggregationProcessorTest.kt | 173 +++--------------- .../aggregation/poll/PollEventsTestData.kt | 171 +++++++++++++++++ .../android/sdk/test/fakes/FakeRealm.kt | 2 +- 4 files changed, 199 insertions(+), 160 deletions(-) create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollEventsTestData.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt index 2f55eb940e..d4b414aaea 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/DefaultPollAggregationProcessor.kt @@ -41,7 +41,6 @@ import org.matrix.android.sdk.internal.database.model.PollResponseAggregatedSumm import org.matrix.android.sdk.internal.database.query.create import org.matrix.android.sdk.internal.database.query.getOrCreate import org.matrix.android.sdk.internal.database.query.where -import timber.log.Timber import javax.inject.Inject class DefaultPollAggregationProcessor @Inject constructor() : PollAggregationProcessor { @@ -162,7 +161,6 @@ class DefaultPollAggregationProcessor @Inject constructor() : PollAggregationPro val isPollOwner = pollOwnerId == event.senderId if (!isPollOwner && !powerLevelsHelper.isUserAbleToRedact(event.senderId ?: "")) { - Timber.v("## Received poll.end event $pollEventId but user ${event.senderId} doesn't have enough power level in room $roomId") return false } @@ -182,17 +180,12 @@ class DefaultPollAggregationProcessor @Inject constructor() : PollAggregationPro } private fun getPollEvent(session: Session, roomId: String, eventId: String): TimelineEvent? { - return session.roomService().getRoom(roomId)?.getTimelineEvent(eventId) ?: return null.also { - Timber.v("## POLL target poll event $eventId not found in room $roomId") - } + return session.roomService().getRoom(roomId)?.getTimelineEvent(eventId) } private fun getPollContent(session: Session, roomId: String, eventId: String): MessagePollContent? { - val pollEvent = getPollEvent(session, roomId, eventId) ?: return null - - return pollEvent.getLastMessageContent() as? MessagePollContent ?: return null.also { - Timber.v("## POLL target poll event $eventId content is malformed") - } + val pollEvent = getPollEvent(session, roomId, eventId) + return pollEvent?.getLastMessageContent() as? MessagePollContent } private fun getAnnotationsSummaryEntity(realm: Realm, roomId: String, eventId: String): EventAnnotationsSummaryEntity { diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt index 9783a40d6c..dec325c8b2 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt @@ -47,145 +47,20 @@ import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntityFields import org.matrix.android.sdk.internal.database.model.PollResponseAggregatedSummaryEntity +import org.matrix.android.sdk.internal.session.room.aggregation.poll.PollEventsTestData.AN_EVENT_ID +import org.matrix.android.sdk.internal.session.room.aggregation.poll.PollEventsTestData.AN_INVALID_POLL_RESPONSE_EVENT +import org.matrix.android.sdk.internal.session.room.aggregation.poll.PollEventsTestData.A_BROKEN_POLL_REPLACE_EVENT +import org.matrix.android.sdk.internal.session.room.aggregation.poll.PollEventsTestData.A_POLL_END_EVENT +import org.matrix.android.sdk.internal.session.room.aggregation.poll.PollEventsTestData.A_POLL_REFERENCE_EVENT +import org.matrix.android.sdk.internal.session.room.aggregation.poll.PollEventsTestData.A_POLL_REPLACE_EVENT +import org.matrix.android.sdk.internal.session.room.aggregation.poll.PollEventsTestData.A_POLL_RESPONSE_EVENT +import org.matrix.android.sdk.internal.session.room.aggregation.poll.PollEventsTestData.A_POLL_RESPONSE_EVENT_WITH_A_WRONG_REFERENCE +import org.matrix.android.sdk.internal.session.room.aggregation.poll.PollEventsTestData.A_POLL_START_EVENT +import org.matrix.android.sdk.internal.session.room.aggregation.poll.PollEventsTestData.A_ROOM_ID +import org.matrix.android.sdk.internal.session.room.aggregation.poll.PollEventsTestData.A_TIMELINE_EVENT +import org.matrix.android.sdk.internal.session.room.aggregation.poll.PollEventsTestData.A_USER_ID_1 import org.matrix.android.sdk.test.fakes.FakeRealm -private const val A_USER_ID_1 = "@user_1:matrix.org" -private const val A_ROOM_ID = "!sUeOGZKsBValPTUMax:matrix.org" -private const val AN_EVENT_ID = "\$vApgexcL8Vfh-WxYKsFKCDooo67ttbjm3TiVKXaWijU" - -private val A_POLL_CONTENT = MessagePollContent( - unstablePollCreationInfo = PollCreationInfo( - question = PollQuestion( - unstableQuestion = "What is your favourite coffee?" - ), - maxSelections = 1, - answers = listOf( - PollAnswer( - id = "5ef5f7b0-c9a1-49cf-a0b3-374729a43e76", - unstableAnswer = "Double Espresso" - ), - PollAnswer( - id = "ec1a4db0-46d8-4d7a-9bb6-d80724715938", - unstableAnswer = "Macchiato" - ), - PollAnswer( - id = "3677ca8e-061b-40ab-bffe-b22e4e88fcad", - unstableAnswer = "Iced Coffee" - ) - ) - ) -) - -private val A_POLL_RESPONSE_CONTENT = MessagePollResponseContent( - unstableResponse = PollResponse( - answers = listOf("5ef5f7b0-c9a1-49cf-a0b3-374729a43e76") - ), - relatesTo = RelationDefaultContent( - type = RelationType.REFERENCE, - eventId = AN_EVENT_ID - ) -) - -private val A_POLL_END_CONTENT = MessageEndPollContent( - relatesTo = RelationDefaultContent( - type = RelationType.REFERENCE, - eventId = AN_EVENT_ID - ) -) - -private val AN_INVALID_POLL_RESPONSE_CONTENT = MessagePollResponseContent( - unstableResponse = PollResponse( - answers = listOf("fake-option-id") - ), - relatesTo = RelationDefaultContent( - type = RelationType.REFERENCE, - eventId = AN_EVENT_ID - ) -) - -private val A_POLL_START_EVENT = Event( - type = EventType.POLL_START.first(), - eventId = AN_EVENT_ID, - originServerTs = 1652435922563, - senderId = A_USER_ID_1, - roomId = A_ROOM_ID, - content = A_POLL_CONTENT.toContent() -) - -private val A_POLL_RESPONSE_EVENT = Event( - type = EventType.POLL_RESPONSE.first(), - eventId = AN_EVENT_ID, - originServerTs = 1652435922563, - senderId = A_USER_ID_1, - roomId = A_ROOM_ID, - content = A_POLL_RESPONSE_CONTENT.toContent() -) - -private val A_POLL_END_EVENT = Event( - type = EventType.POLL_END.first(), - eventId = AN_EVENT_ID, - originServerTs = 1652435922563, - senderId = A_USER_ID_1, - roomId = A_ROOM_ID, - content = A_POLL_END_CONTENT.toContent() -) - -private val A_TIMELINE_EVENT = TimelineEvent( - root = A_POLL_START_EVENT, - localId = 1234, - eventId = AN_EVENT_ID, - displayIndex = 0, - senderInfo = SenderInfo(A_USER_ID_1, "A_USER_ID_1", true, null) -) - -private val A_POLL_RESPONSE_EVENT_WITH_A_WRONG_REFERENCE = A_POLL_RESPONSE_EVENT.copy( - content = A_POLL_RESPONSE_CONTENT - .copy( - relatesTo = RelationDefaultContent( - type = RelationType.REPLACE, - eventId = null - ) - ) - .toContent() -) - -private val A_POLL_REPLACE_EVENT = A_POLL_START_EVENT.copy( - content = A_POLL_CONTENT - .copy( - relatesTo = RelationDefaultContent( - type = RelationType.REPLACE, - eventId = AN_EVENT_ID - ) - ) - .toContent() -) - -private val A_BROKEN_POLL_REPLACE_EVENT = A_POLL_START_EVENT.copy( - content = A_POLL_CONTENT - .copy( - relatesTo = RelationDefaultContent( - type = RelationType.REPLACE, - eventId = null - ) - ) - .toContent() -) - -private val A_POLL_REFERENCE_EVENT = A_POLL_START_EVENT.copy( - content = A_POLL_CONTENT - .copy( - relatesTo = RelationDefaultContent( - type = RelationType.REFERENCE, - eventId = AN_EVENT_ID - ) - ) - .toContent() -) - -private val AN_INVALID_POLL_RESPONSE_EVENT = A_POLL_RESPONSE_EVENT.copy( - content = AN_INVALID_POLL_RESPONSE_CONTENT.toContent() -) - class PollAggregationProcessorTest { private val pollAggregationProcessor: PollAggregationProcessor = DefaultPollAggregationProcessor() @@ -200,38 +75,38 @@ class PollAggregationProcessorTest { } @Test - fun `given a poll start event which is not a replace is not processed by poll aggregator`() { + fun `given a poll start event, when processing, then is ignored and returns false`() { pollAggregationProcessor.handlePollStartEvent(realm.instance, A_POLL_START_EVENT).shouldBeFalse() } @Test - fun `given a poll start event with a reference is not processed by poll aggregator`() { + fun `given a poll start event with a reference, when processing, then is ignored and returns false`() { pollAggregationProcessor.handlePollStartEvent(realm.instance, A_POLL_REFERENCE_EVENT).shouldBeFalse() } @Test - fun `given a poll start event with a replace but without target event id is not processed by poll aggregator`() { + fun `given a poll start event with a replace relation but without a target event id, when processing, then is ignored and returns false`() { pollAggregationProcessor.handlePollStartEvent(realm.instance, A_BROKEN_POLL_REPLACE_EVENT).shouldBeFalse() } @Test - fun `given a poll start event with a replace is processed by poll aggregator`() { + fun `given a poll start event with a replace, when processing, then is processed and returns true`() { pollAggregationProcessor.handlePollStartEvent(realm.instance, A_POLL_REPLACE_EVENT).shouldBeTrue() } @Test - fun `given a poll response event with a broken reference is not processed by poll aggregator`() { + fun `given a poll response event with a broken reference, when processing, then is ignored and returns false`() { pollAggregationProcessor.handlePollResponseEvent(session, realm.instance, A_POLL_RESPONSE_EVENT_WITH_A_WRONG_REFERENCE).shouldBeFalse() } @Test - fun `given a poll response event with a reference is processed by poll aggregator`() { + fun `given a poll response event with a reference, when processing, then is processed and returns true`() { every { realm.instance.createObject(PollResponseAggregatedSummaryEntity::class.java) } returns PollResponseAggregatedSummaryEntity() pollAggregationProcessor.handlePollResponseEvent(session, realm.instance, A_POLL_RESPONSE_EVENT).shouldBeTrue() } @Test - fun `given a poll response event after poll is closed is not processed by poll aggregator`() { + fun `given a poll response event after poll is closed, when processing, then is ignored and returns false`() { every { realm.instance.createObject(PollResponseAggregatedSummaryEntity::class.java) } returns PollResponseAggregatedSummaryEntity().apply { closedTime = (A_POLL_RESPONSE_EVENT.originServerTs ?: 0) - 1 } @@ -239,7 +114,7 @@ class PollAggregationProcessorTest { } @Test - fun `given a poll response event which is already processed is not processed by poll aggregator`() { + fun `given a poll response event which is already processed, when processing, then is ignored and returns false`() { every { realm.instance.createObject(PollResponseAggregatedSummaryEntity::class.java) } returns PollResponseAggregatedSummaryEntity().apply { sourceEvents = RealmList(A_POLL_RESPONSE_EVENT.eventId) } @@ -247,27 +122,27 @@ class PollAggregationProcessorTest { } @Test - fun `given a poll response event which is not one of the options is not processed by poll aggregator`() { + fun `given a poll response event which is not one of the options, when processing, then is ignored and returns false`() { every { realm.instance.createObject(PollResponseAggregatedSummaryEntity::class.java) } returns PollResponseAggregatedSummaryEntity() pollAggregationProcessor.handlePollResponseEvent(session, realm.instance, AN_INVALID_POLL_RESPONSE_EVENT).shouldBeFalse() } @Test - fun `given a poll end event is processed by poll aggregator`() { + fun `given a poll end event, when processing, then is processed and return true`() { every { realm.instance.createObject(PollResponseAggregatedSummaryEntity::class.java) } returns PollResponseAggregatedSummaryEntity() val powerLevelsHelper = mockRedactionPowerLevels(A_USER_ID_1, true) pollAggregationProcessor.handlePollEndEvent(session, powerLevelsHelper, realm.instance, A_POLL_END_EVENT).shouldBeTrue() } @Test - fun `given a poll end event without redaction power level of event owner is processed by poll aggregator`() { + fun `given a poll end event for my own poll without enough redaction power level, when processing, then is processed and returns true`() { every { realm.instance.createObject(PollResponseAggregatedSummaryEntity::class.java) } returns PollResponseAggregatedSummaryEntity() val powerLevelsHelper = mockRedactionPowerLevels(A_USER_ID_1, false) pollAggregationProcessor.handlePollEndEvent(session, powerLevelsHelper, realm.instance, A_POLL_END_EVENT).shouldBeTrue() } @Test - fun `given a poll end event without redaction power level of non event owner is not processed by poll aggregator`() { + fun `given a poll end event without enough redaction power level, when is processed, then is ignored and return false`() { every { realm.instance.createObject(PollResponseAggregatedSummaryEntity::class.java) } returns PollResponseAggregatedSummaryEntity() val powerLevelsHelper = mockRedactionPowerLevels("another-sender-id", false) val event = A_POLL_END_EVENT.copy(senderId = "another-sender-id") diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollEventsTestData.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollEventsTestData.kt new file mode 100644 index 0000000000..129d49633e --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollEventsTestData.kt @@ -0,0 +1,171 @@ +/* + * Copyright 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.session.room.aggregation.poll + +import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.RelationType +import org.matrix.android.sdk.api.session.events.model.toContent +import org.matrix.android.sdk.api.session.room.model.message.MessageEndPollContent +import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent +import org.matrix.android.sdk.api.session.room.model.message.MessagePollResponseContent +import org.matrix.android.sdk.api.session.room.model.message.PollAnswer +import org.matrix.android.sdk.api.session.room.model.message.PollCreationInfo +import org.matrix.android.sdk.api.session.room.model.message.PollQuestion +import org.matrix.android.sdk.api.session.room.model.message.PollResponse +import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent +import org.matrix.android.sdk.api.session.room.sender.SenderInfo +import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent + +object PollEventsTestData { + internal const val A_USER_ID_1 = "@user_1:matrix.org" + internal const val A_ROOM_ID = "!sUeOGZKsBValPTUMax:matrix.org" + internal const val AN_EVENT_ID = "\$vApgexcL8Vfh-WxYKsFKCDooo67ttbjm3TiVKXaWijU" + + internal val A_POLL_CONTENT = MessagePollContent( + unstablePollCreationInfo = PollCreationInfo( + question = PollQuestion( + unstableQuestion = "What is your favourite coffee?" + ), + maxSelections = 1, + answers = listOf( + PollAnswer( + id = "5ef5f7b0-c9a1-49cf-a0b3-374729a43e76", + unstableAnswer = "Double Espresso" + ), + PollAnswer( + id = "ec1a4db0-46d8-4d7a-9bb6-d80724715938", + unstableAnswer = "Macchiato" + ), + PollAnswer( + id = "3677ca8e-061b-40ab-bffe-b22e4e88fcad", + unstableAnswer = "Iced Coffee" + ) + ) + ) + ) + + internal val A_POLL_RESPONSE_CONTENT = MessagePollResponseContent( + unstableResponse = PollResponse( + answers = listOf("5ef5f7b0-c9a1-49cf-a0b3-374729a43e76") + ), + relatesTo = RelationDefaultContent( + type = RelationType.REFERENCE, + eventId = AN_EVENT_ID + ) + ) + + internal val A_POLL_END_CONTENT = MessageEndPollContent( + relatesTo = RelationDefaultContent( + type = RelationType.REFERENCE, + eventId = AN_EVENT_ID + ) + ) + + internal val AN_INVALID_POLL_RESPONSE_CONTENT = MessagePollResponseContent( + unstableResponse = PollResponse( + answers = listOf("fake-option-id") + ), + relatesTo = RelationDefaultContent( + type = RelationType.REFERENCE, + eventId = AN_EVENT_ID + ) + ) + + internal val A_POLL_START_EVENT = Event( + type = EventType.POLL_START.first(), + eventId = AN_EVENT_ID, + originServerTs = 1652435922563, + senderId = A_USER_ID_1, + roomId = A_ROOM_ID, + content = A_POLL_CONTENT.toContent() + ) + + internal val A_POLL_RESPONSE_EVENT = Event( + type = EventType.POLL_RESPONSE.first(), + eventId = AN_EVENT_ID, + originServerTs = 1652435922563, + senderId = A_USER_ID_1, + roomId = A_ROOM_ID, + content = A_POLL_RESPONSE_CONTENT.toContent() + ) + + internal val A_POLL_END_EVENT = Event( + type = EventType.POLL_END.first(), + eventId = AN_EVENT_ID, + originServerTs = 1652435922563, + senderId = A_USER_ID_1, + roomId = A_ROOM_ID, + content = A_POLL_END_CONTENT.toContent() + ) + + internal val A_TIMELINE_EVENT = TimelineEvent( + root = A_POLL_START_EVENT, + localId = 1234, + eventId = AN_EVENT_ID, + displayIndex = 0, + senderInfo = SenderInfo(A_USER_ID_1, "A_USER_ID_1", true, null) + ) + + internal val A_POLL_RESPONSE_EVENT_WITH_A_WRONG_REFERENCE = A_POLL_RESPONSE_EVENT.copy( + content = A_POLL_RESPONSE_CONTENT + .copy( + relatesTo = RelationDefaultContent( + type = RelationType.REPLACE, + eventId = null + ) + ) + .toContent() + ) + + internal val A_POLL_REPLACE_EVENT = A_POLL_START_EVENT.copy( + content = A_POLL_CONTENT + .copy( + relatesTo = RelationDefaultContent( + type = RelationType.REPLACE, + eventId = AN_EVENT_ID + ) + ) + .toContent() + ) + + internal val A_BROKEN_POLL_REPLACE_EVENT = A_POLL_START_EVENT.copy( + content = A_POLL_CONTENT + .copy( + relatesTo = RelationDefaultContent( + type = RelationType.REPLACE, + eventId = null + ) + ) + .toContent() + ) + + internal val A_POLL_REFERENCE_EVENT = A_POLL_START_EVENT.copy( + content = A_POLL_CONTENT + .copy( + relatesTo = RelationDefaultContent( + type = RelationType.REFERENCE, + eventId = AN_EVENT_ID + ) + ) + .toContent() + ) + + internal val AN_INVALID_POLL_RESPONSE_EVENT = A_POLL_RESPONSE_EVENT.copy( + content = AN_INVALID_POLL_RESPONSE_CONTENT.toContent() + ) +} diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRealm.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRealm.kt index a3462c4acc..c07f8e1873 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRealm.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRealm.kt @@ -28,7 +28,7 @@ internal class FakeRealm { val instance = mockk(relaxed = true) inline fun givenWhereReturns(result: T?): RealmQuery { - val queryResult = mockk>(relaxed = true) + val queryResult = mockk>() every { queryResult.findFirst() } returns result every { instance.where() } returns queryResult return queryResult From b9adbb7d60bee6a09163c24678610206edc85f48 Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Wed, 18 May 2022 14:05:58 +0300 Subject: [PATCH 024/125] PR remarks --- .../crypto/replayattack/ReplayAttackTest.kt | 9 ++++++-- .../sdk/internal/crypto/MXOlmDevice.kt | 21 ++++++------------- .../sync/handler/room/RoomSyncHandler.kt | 8 +++---- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt index cb672f5e8d..69be4a3678 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt @@ -20,6 +20,7 @@ import androidx.test.filters.LargeTest import org.amshove.kluent.internal.assertFailsWith import org.junit.Assert import org.junit.Assert.assertEquals +import org.junit.Assert.fail import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -101,8 +102,12 @@ class ReplayAttackTest : InstrumentedTest { val timelineId = "timelineId" // Lets decrypt the original event aliceSession.cryptoService().decryptEvent(sentEvents[0].root, timelineId) - // Lets try to decrypt the same event - aliceSession.cryptoService().decryptEvent(sentEvents[0].root, timelineId) + try { + // Lets try to decrypt the same event + aliceSession.cryptoService().decryptEvent(sentEvents[0].root, timelineId) + } catch (ex: Throwable) { + fail("Shouldn't throw a decryption error for same event") + } } cryptoTestData.cleanUp(testHelper) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt index 16e6bb173d..87384b3fe2 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt @@ -96,10 +96,9 @@ internal class MXOlmDevice @Inject constructor( // So, store these message indexes per timeline id. // // The first level keys are timeline ids. - // The second level keys are strings of form "||" - private val inboundGroupSessionMessageIndexes: MutableMap> = HashMap() - - private val replayAttackMap: MutableMap = HashMap() + // The second level values is a Map that represents: + // "|||" --> eventId + private val inboundGroupSessionMessageIndexes: MutableMap> = HashMap() init { // Retrieve the account from the store @@ -798,15 +797,14 @@ internal class MXOlmDevice @Inject constructor( Timber.tag(loggerTag.value).d("## decryptGroupMessage() mIndex: ${decryptResult.mIndex}") if (timeline?.isNotBlank() == true) { - val timelineSet = inboundGroupSessionMessageIndexes.getOrPut(timeline) { mutableSetOf() } - if (timelineSet.contains(messageIndexKey) && messageIndexKey.alreadyUsed(eventId)) { + val replayAttackMap = inboundGroupSessionMessageIndexes.getOrPut(timeline) { mutableMapOf() } + if (replayAttackMap.contains(messageIndexKey) && replayAttackMap[messageIndexKey] != eventId) { val reason = String.format(MXCryptoError.DUPLICATE_MESSAGE_INDEX_REASON, decryptResult.mIndex) Timber.tag(loggerTag.value).e("## decryptGroupMessage() timelineId=$timeline: $reason") throw MXCryptoError.Base(MXCryptoError.ErrorType.DUPLICATED_MESSAGE_INDEX, reason) } - timelineSet.add(messageIndexKey) + replayAttackMap[messageIndexKey] = eventId } - replayAttackMap[messageIndexKey] = eventId inboundGroupSessionStore.storeInBoundGroupSession(sessionHolder, sessionId, senderKey) val payload = try { val adapter = MoshiProvider.providesMoshi().adapter(JSON_DICT_PARAMETERIZED_TYPE) @@ -825,13 +823,6 @@ internal class MXOlmDevice @Inject constructor( ) } - /** - * Determines whether or not the messageKey has already been used to decrypt another eventId - */ - private fun String.alreadyUsed(eventId: String): Boolean { - return replayAttackMap[this] != null && replayAttackMap[this] != eventId - } - /** * Reset replay attack data for the given timeline. * diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt index 879bde1862..cf916dc907 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt @@ -25,7 +25,6 @@ import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType -import org.matrix.android.sdk.api.session.events.model.isThread import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService import org.matrix.android.sdk.api.session.initsync.InitSyncStep @@ -521,7 +520,7 @@ internal class RoomSyncHandler @Inject constructor( private fun decryptIfNeeded(event: Event, roomId: String) { try { - val timelineId = generateTimelineId(roomId, event) + val timelineId = generateTimelineId(roomId) // Event from sync does not have roomId, so add it to the event first // note: runBlocking should be used here while we are in realm single thread executor, to avoid thread switching val result = runBlocking { cryptoService.decryptEvent(event.copy(roomId = roomId), timelineId) } @@ -539,9 +538,8 @@ internal class RoomSyncHandler @Inject constructor( } } - private fun generateTimelineId(roomId: String, event: Event): String { - val threadIndicator = if (event.isThread()) "_thread_" else "_" - return "${RoomSyncHandler::class.java.simpleName}$threadIndicator$roomId" + private fun generateTimelineId(roomId: String): String { + return "${RoomSyncHandler::class.java.simpleName}$roomId" } data class EphemeralResult( From 328d8348519e13a9cf63763aada5eff696877742 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 18 May 2022 13:09:58 +0200 Subject: [PATCH 025/125] changelog --- changelog.d/6089.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/6089.misc diff --git a/changelog.d/6089.misc b/changelog.d/6089.misc new file mode 100644 index 0000000000..19b951c1a3 --- /dev/null +++ b/changelog.d/6089.misc @@ -0,0 +1 @@ +Test: Ensure calling 'fail()' is not caught by the catch block From 3bf9ea5b060e1e7d528c26514c262f6fb256cd97 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Wed, 18 May 2022 14:13:53 +0300 Subject: [PATCH 026/125] Lint fixes. --- .../poll/PollAggregationProcessorTest.kt | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt index dec325c8b2..837bbeea26 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt @@ -26,24 +26,10 @@ import org.amshove.kluent.shouldBeTrue import org.junit.Before import org.junit.Test import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.session.events.model.Event -import org.matrix.android.sdk.api.session.events.model.EventType -import org.matrix.android.sdk.api.session.events.model.RelationType -import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.getRoom import org.matrix.android.sdk.api.session.room.Room import org.matrix.android.sdk.api.session.room.getTimelineEvent -import org.matrix.android.sdk.api.session.room.model.message.MessageEndPollContent -import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent -import org.matrix.android.sdk.api.session.room.model.message.MessagePollResponseContent -import org.matrix.android.sdk.api.session.room.model.message.PollAnswer -import org.matrix.android.sdk.api.session.room.model.message.PollCreationInfo -import org.matrix.android.sdk.api.session.room.model.message.PollQuestion -import org.matrix.android.sdk.api.session.room.model.message.PollResponse -import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper -import org.matrix.android.sdk.api.session.room.sender.SenderInfo -import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntityFields import org.matrix.android.sdk.internal.database.model.PollResponseAggregatedSummaryEntity From dc1a4ae3a26f415408525fb039d56f6680caf960 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 May 2022 11:28:16 +0000 Subject: [PATCH 027/125] Bump stem-plugin from 2.0.0 to 2.1.1 Bumps [stem-plugin](https://github.com/LikeTheSalad/android-stem) from 2.0.0 to 2.1.1. - [Release notes](https://github.com/LikeTheSalad/android-stem/releases) - [Changelog](https://github.com/LikeTheSalad/android-stem/blob/master/CHANGELOG.md) - [Commits](https://github.com/LikeTheSalad/android-stem/compare/2.0.0...2.1.1) --- updated-dependencies: - dependency-name: com.likethesalad.android:stem-plugin dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 8553428b49..25ff8b91c0 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,7 @@ buildscript { classpath 'com.google.gms:google-services:4.3.10' classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.3' classpath 'com.google.android.gms:oss-licenses-plugin:0.10.5' - classpath "com.likethesalad.android:stem-plugin:2.0.0" + classpath "com.likethesalad.android:stem-plugin:2.1.1" classpath 'org.owasp:dependency-check-gradle:7.1.0.1' classpath "org.jetbrains.dokka:dokka-gradle-plugin:1.6.21" classpath "org.jetbrains.kotlinx:kotlinx-knit:0.4.0" From 5532e7dfa1c69969394cb7aa9f333b063c17218b Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Wed, 18 May 2022 14:57:50 +0300 Subject: [PATCH 028/125] Fix copyright --- .../sdk/internal/crypto/replayattack/ReplayAttackTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt index 69be4a3678..9932375ed2 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/replayattack/ReplayAttackTest.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 99d4bbe74bb75f0af8834d70cb24df488fcbc438 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 18 May 2022 14:12:44 +0200 Subject: [PATCH 029/125] Fix bad copyright --- .../src/androidTest/java/org/matrix/android/sdk/Util.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/Util.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/Util.kt index 2970dec29a..5e2c2ba25f 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/Util.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/Util.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From b2765e4b63613168a0c1c8a855e2ea2d02689566 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Tue, 10 May 2022 14:29:50 +0200 Subject: [PATCH 030/125] Adding changelog entry --- changelog.d/6012.wip | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/6012.wip diff --git a/changelog.d/6012.wip b/changelog.d/6012.wip new file mode 100644 index 0000000000..9c67d562fe --- /dev/null +++ b/changelog.d/6012.wip @@ -0,0 +1 @@ +Live location sharing: navigation from timeline to map screen From 52c0fa41c6ce56555dbc987703ddc6edd62d420c Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Tue, 10 May 2022 16:49:27 +0200 Subject: [PATCH 031/125] Creation of map view screen and basic navigation --- vector/src/main/AndroidManifest.xml | 1 + .../im/vector/app/core/di/FragmentModule.kt | 6 ++ .../home/room/detail/TimelineFragment.kt | 12 +++ .../live/map/LocationLiveMapViewActivity.kt | 68 +++++++++++++ .../live/map/LocationLiveMapViewFragment.kt | 99 +++++++++++++++++++ .../features/navigation/DefaultNavigator.kt | 10 ++ .../app/features/navigation/Navigator.kt | 2 + 7 files changed, 198 insertions(+) create mode 100644 vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt create mode 100644 vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index 20b7c4908a..fc78ce90a3 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -343,6 +343,7 @@ + diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index c68a35f4e5..6d42c83ac2 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -64,6 +64,7 @@ import im.vector.app.features.home.room.list.RoomListFragment import im.vector.app.features.home.room.threads.list.views.ThreadListFragment import im.vector.app.features.location.LocationPreviewFragment import im.vector.app.features.location.LocationSharingFragment +import im.vector.app.features.location.live.map.LocationLiveMapViewFragment import im.vector.app.features.login.LoginCaptchaFragment import im.vector.app.features.login.LoginFragment import im.vector.app.features.login.LoginGenericTextInputFormFragment @@ -993,4 +994,9 @@ interface FragmentModule { @IntoMap @FragmentKey(LocationPreviewFragment::class) fun bindLocationPreviewFragment(fragment: LocationPreviewFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LocationLiveMapViewFragment::class) + fun bindLocationLiveMapViewFragment(fragment: LocationLiveMapViewFragment): Fragment } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index 2bb620623c..bf7c506d79 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -221,6 +221,7 @@ import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.message.MessageAudioContent +import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconInfoContent import org.matrix.android.sdk.api.session.room.model.message.MessageContent import org.matrix.android.sdk.api.session.room.model.message.MessageFormat import org.matrix.android.sdk.api.session.room.model.message.MessageImageInfoContent @@ -647,6 +648,13 @@ class TimelineFragment @Inject constructor( ) } + private fun navigateToLocationLiveMap() { + navigator.openLocationLiveMap( + context = requireContext(), + roomId = timelineArgs.roomId + ) + } + private fun handleChangeLocationIndicator(event: RoomDetailViewEvents.ChangeLocationIndicator) { views.locationLiveStatusIndicator.isVisible = event.isVisible } @@ -2015,6 +2023,10 @@ class TimelineFragment @Inject constructor( is MessageLocationContent -> { handleShowLocationPreview(messageContent, informationData.senderId) } + is MessageBeaconInfoContent -> { + // TODO navigate only from running live location message: possible after merge of associated PR + navigateToLocationLiveMap() + } else -> { val handled = onThreadSummaryClicked(informationData.eventId, isRootThreadEvent) if (!handled) { diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt new file mode 100644 index 0000000000..cb54e93f97 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.location.live.map + +import android.content.Context +import android.content.Intent +import android.os.Parcelable +import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.core.extensions.addFragment +import im.vector.app.core.platform.VectorBaseActivity +import im.vector.app.databinding.ActivityLocationSharingBinding +import kotlinx.parcelize.Parcelize + +@Parcelize +data class LocationLiveMapViewArgs( + val roomId: String +) : Parcelable + +@AndroidEntryPoint +class LocationLiveMapViewActivity : VectorBaseActivity() { + + override fun getBinding() = ActivityLocationSharingBinding.inflate(layoutInflater) + + override fun initUiAndData() { + val mapViewArgs: LocationLiveMapViewArgs? = intent?.extras?.getParcelable(EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS) + if (mapViewArgs == null) { + finish() + return + } + setupToolbar(views.toolbar) + // TODO check what should be the title and create String resource + .setTitle("Live") + .allowBack() + + if (isFirstCreation()) { + addFragment( + views.fragmentContainer, + LocationLiveMapViewFragment::class.java, + mapViewArgs + ) + } + } + + companion object { + + private const val EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS = "EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS" + + fun getIntent(context: Context, locationLiveMapViewArgs: LocationLiveMapViewArgs): Intent { + return Intent(context, LocationLiveMapViewActivity::class.java).apply { + putExtra(EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS, locationLiveMapViewArgs) + } + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt new file mode 100644 index 0000000000..7e17712556 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.location.live.map + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.lifecycle.lifecycleScope +import com.airbnb.mvrx.args +import com.mapbox.mapboxsdk.maps.MapView +import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentLocationPreviewBinding +import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider +import im.vector.app.features.location.UrlMapProvider +import java.lang.ref.WeakReference +import javax.inject.Inject + +/** + * Screen showing a map with all the current users sharing their live location in room. + */ +class LocationLiveMapViewFragment @Inject constructor( + private val urlMapProvider: UrlMapProvider, + private val locationPinProvider: LocationPinProvider +) : VectorBaseFragment() { + + // TODO use a SupportMapFragment with FragmentManager + // TODO align design with Figma + + private val args: LocationLiveMapViewArgs by args() + + // Keep a ref to handle properly the onDestroy callback + private var mapView: WeakReference? = null + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLocationPreviewBinding { + return FragmentLocationPreviewBinding.inflate(layoutInflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + mapView = WeakReference(views.mapView) + views.mapView.onCreate(savedInstanceState) + + lifecycleScope.launchWhenCreated { + views.mapView.initialize(urlMapProvider.getMapUrl()) + } + } + + override fun onResume() { + super.onResume() + views.mapView.onResume() + } + + override fun onPause() { + views.mapView.onPause() + super.onPause() + } + + override fun onLowMemory() { + views.mapView.onLowMemory() + super.onLowMemory() + } + + override fun onStart() { + super.onStart() + views.mapView.onStart() + } + + override fun onStop() { + views.mapView.onStop() + super.onStop() + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + views.mapView.onSaveInstanceState(outState) + } + + override fun onDestroy() { + mapView?.get()?.onDestroy() + mapView?.clear() + super.onDestroy() + } +} diff --git a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt index 7cc42ec57f..1ec4011289 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt @@ -68,6 +68,8 @@ import im.vector.app.features.location.LocationData import im.vector.app.features.location.LocationSharingActivity import im.vector.app.features.location.LocationSharingArgs import im.vector.app.features.location.LocationSharingMode +import im.vector.app.features.location.live.map.LocationLiveMapViewActivity +import im.vector.app.features.location.live.map.LocationLiveMapViewArgs import im.vector.app.features.login.LoginActivity import im.vector.app.features.login.LoginConfig import im.vector.app.features.matrixto.MatrixToBottomSheet @@ -591,6 +593,14 @@ class DefaultNavigator @Inject constructor( context.startActivity(intent) } + override fun openLocationLiveMap(context: Context, roomId: String) { + val intent = LocationLiveMapViewActivity.getIntent( + context = context, + locationLiveMapViewArgs = LocationLiveMapViewArgs(roomId = roomId) + ) + context.startActivity(intent) + } + private fun startActivity(context: Context, intent: Intent, buildTask: Boolean) { if (buildTask) { val stackBuilder = TaskStackBuilder.create(context) diff --git a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt index 075b41daf3..d4ef2b8099 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt @@ -172,6 +172,8 @@ interface Navigator { initialLocationData: LocationData?, locationOwnerId: String?) + fun openLocationLiveMap(context: Context, roomId: String) + fun openThread(context: Context, threadTimelineArgs: ThreadTimelineArgs, eventIdToNavigate: String? = null) fun openThreadList(context: Context, threadTimelineArgs: ThreadTimelineArgs) From 54d7d47dfcda4fac17b3df81703a9229df2fcddd Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Tue, 10 May 2022 17:27:41 +0200 Subject: [PATCH 032/125] Updating the title of the map view screen --- .../features/location/live/map/LocationLiveMapViewActivity.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt index cb54e93f97..c0f07dba57 100644 --- a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt +++ b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt @@ -20,6 +20,7 @@ import android.content.Context import android.content.Intent import android.os.Parcelable import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.R import im.vector.app.core.extensions.addFragment import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityLocationSharingBinding @@ -42,8 +43,7 @@ class LocationLiveMapViewActivity : VectorBaseActivity Date: Wed, 11 May 2022 09:37:25 +0200 Subject: [PATCH 033/125] Use SupportMapFragment instead of custom fragment --- .../im/vector/app/core/di/FragmentModule.kt | 6 -- .../im/vector/app/core/extensions/Activity.kt | 6 +- .../live/map/LocationLiveMapViewActivity.kt | 34 +++++-- .../live/map/LocationLiveMapViewFragment.kt | 99 ------------------- 4 files changed, 32 insertions(+), 113 deletions(-) delete mode 100644 vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index 6d42c83ac2..c68a35f4e5 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -64,7 +64,6 @@ import im.vector.app.features.home.room.list.RoomListFragment import im.vector.app.features.home.room.threads.list.views.ThreadListFragment import im.vector.app.features.location.LocationPreviewFragment import im.vector.app.features.location.LocationSharingFragment -import im.vector.app.features.location.live.map.LocationLiveMapViewFragment import im.vector.app.features.login.LoginCaptchaFragment import im.vector.app.features.login.LoginFragment import im.vector.app.features.login.LoginGenericTextInputFormFragment @@ -994,9 +993,4 @@ interface FragmentModule { @IntoMap @FragmentKey(LocationPreviewFragment::class) fun bindLocationPreviewFragment(fragment: LocationPreviewFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(LocationLiveMapViewFragment::class) - fun bindLocationLiveMapViewFragment(fragment: LocationLiveMapViewFragment): Fragment } diff --git a/vector/src/main/java/im/vector/app/core/extensions/Activity.kt b/vector/src/main/java/im/vector/app/core/extensions/Activity.kt index 6f2ea9699a..cbdf5e3573 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/Activity.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/Activity.kt @@ -39,8 +39,10 @@ fun ComponentActivity.registerStartForActivityResult(onResult: (ActivityResult) fun AppCompatActivity.addFragment( container: ViewGroup, fragment: Fragment, - allowStateLoss: Boolean = false) { - supportFragmentManager.commitTransaction(allowStateLoss) { add(container.id, fragment) } + allowStateLoss: Boolean = false, + tag: String? = null +) { + supportFragmentManager.commitTransaction(allowStateLoss) { add(container.id, fragment, tag) } } fun AppCompatActivity.addFragment( diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt index c0f07dba57..41e08dc655 100644 --- a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt +++ b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt @@ -19,21 +19,31 @@ package im.vector.app.features.location.live.map import android.content.Context import android.content.Intent import android.os.Parcelable +import androidx.lifecycle.lifecycleScope +import com.mapbox.mapboxsdk.maps.MapboxMapOptions +import com.mapbox.mapboxsdk.maps.SupportMapFragment import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R import im.vector.app.core.extensions.addFragment import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityLocationSharingBinding +import im.vector.app.features.location.UrlMapProvider import kotlinx.parcelize.Parcelize +import javax.inject.Inject @Parcelize data class LocationLiveMapViewArgs( val roomId: String ) : Parcelable +/** + * Screen showing a map with all the current users sharing their live location in room. + */ @AndroidEntryPoint class LocationLiveMapViewActivity : VectorBaseActivity() { + @Inject lateinit var urlMapProvider: UrlMapProvider + override fun getBinding() = ActivityLocationSharingBinding.inflate(layoutInflater) override fun initUiAndData() { @@ -46,18 +56,30 @@ class LocationLiveMapViewActivity : VectorBaseActivity + lifecycleScope.launchWhenCreated { + mapBoxMap.setStyle(urlMapProvider.getMapUrl()) + } } } companion object { private const val EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS = "EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS" + private const val MAP_FRAGMENT_TAG = "im.vector.app.features.location.live.map" fun getIntent(context: Context, locationLiveMapViewArgs: LocationLiveMapViewArgs): Intent { return Intent(context, LocationLiveMapViewActivity::class.java).apply { diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt deleted file mode 100644 index 7e17712556..0000000000 --- a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2022 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package im.vector.app.features.location.live.map - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.lifecycle.lifecycleScope -import com.airbnb.mvrx.args -import com.mapbox.mapboxsdk.maps.MapView -import im.vector.app.core.platform.VectorBaseFragment -import im.vector.app.databinding.FragmentLocationPreviewBinding -import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider -import im.vector.app.features.location.UrlMapProvider -import java.lang.ref.WeakReference -import javax.inject.Inject - -/** - * Screen showing a map with all the current users sharing their live location in room. - */ -class LocationLiveMapViewFragment @Inject constructor( - private val urlMapProvider: UrlMapProvider, - private val locationPinProvider: LocationPinProvider -) : VectorBaseFragment() { - - // TODO use a SupportMapFragment with FragmentManager - // TODO align design with Figma - - private val args: LocationLiveMapViewArgs by args() - - // Keep a ref to handle properly the onDestroy callback - private var mapView: WeakReference? = null - - override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLocationPreviewBinding { - return FragmentLocationPreviewBinding.inflate(layoutInflater, container, false) - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - mapView = WeakReference(views.mapView) - views.mapView.onCreate(savedInstanceState) - - lifecycleScope.launchWhenCreated { - views.mapView.initialize(urlMapProvider.getMapUrl()) - } - } - - override fun onResume() { - super.onResume() - views.mapView.onResume() - } - - override fun onPause() { - views.mapView.onPause() - super.onPause() - } - - override fun onLowMemory() { - views.mapView.onLowMemory() - super.onLowMemory() - } - - override fun onStart() { - super.onStart() - views.mapView.onStart() - } - - override fun onStop() { - views.mapView.onStop() - super.onStop() - } - - override fun onSaveInstanceState(outState: Bundle) { - super.onSaveInstanceState(outState) - views.mapView.onSaveInstanceState(outState) - } - - override fun onDestroy() { - mapView?.get()?.onDestroy() - mapView?.clear() - super.onDestroy() - } -} From 23e8cad10f9f8435d847536f898f08cc06de5167 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Wed, 11 May 2022 16:53:13 +0200 Subject: [PATCH 034/125] Rollback to Fragment to be able to use Maverick capabilities --- .../im/vector/app/core/di/FragmentModule.kt | 6 ++ .../im/vector/app/core/extensions/Activity.kt | 6 +- .../im/vector/app/core/extensions/Fragment.kt | 3 +- .../live/map/LocationLiveMapViewActivity.kt | 34 ++------ .../live/map/LocationLiveMapViewFragment.kt | 77 +++++++++++++++++++ .../res/layout/fragment_live_location_map.xml | 5 ++ 6 files changed, 98 insertions(+), 33 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt create mode 100644 vector/src/main/res/layout/fragment_live_location_map.xml diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index c68a35f4e5..6d42c83ac2 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -64,6 +64,7 @@ import im.vector.app.features.home.room.list.RoomListFragment import im.vector.app.features.home.room.threads.list.views.ThreadListFragment import im.vector.app.features.location.LocationPreviewFragment import im.vector.app.features.location.LocationSharingFragment +import im.vector.app.features.location.live.map.LocationLiveMapViewFragment import im.vector.app.features.login.LoginCaptchaFragment import im.vector.app.features.login.LoginFragment import im.vector.app.features.login.LoginGenericTextInputFormFragment @@ -993,4 +994,9 @@ interface FragmentModule { @IntoMap @FragmentKey(LocationPreviewFragment::class) fun bindLocationPreviewFragment(fragment: LocationPreviewFragment): Fragment + + @Binds + @IntoMap + @FragmentKey(LocationLiveMapViewFragment::class) + fun bindLocationLiveMapViewFragment(fragment: LocationLiveMapViewFragment): Fragment } diff --git a/vector/src/main/java/im/vector/app/core/extensions/Activity.kt b/vector/src/main/java/im/vector/app/core/extensions/Activity.kt index cbdf5e3573..6f2ea9699a 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/Activity.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/Activity.kt @@ -39,10 +39,8 @@ fun ComponentActivity.registerStartForActivityResult(onResult: (ActivityResult) fun AppCompatActivity.addFragment( container: ViewGroup, fragment: Fragment, - allowStateLoss: Boolean = false, - tag: String? = null -) { - supportFragmentManager.commitTransaction(allowStateLoss) { add(container.id, fragment, tag) } + allowStateLoss: Boolean = false) { + supportFragmentManager.commitTransaction(allowStateLoss) { add(container.id, fragment) } } fun AppCompatActivity.addFragment( diff --git a/vector/src/main/java/im/vector/app/core/extensions/Fragment.kt b/vector/src/main/java/im/vector/app/core/extensions/Fragment.kt index dfbd2eba97..61c4fe2174 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/Fragment.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/Fragment.kt @@ -36,9 +36,10 @@ fun Fragment.registerStartForActivityResult(onResult: (ActivityResult) -> Unit): fun Fragment.addFragment( frameId: Int, fragment: Fragment, + tag: String? = null, allowStateLoss: Boolean = false ) { - parentFragmentManager.commitTransaction(allowStateLoss) { add(frameId, fragment) } + parentFragmentManager.commitTransaction(allowStateLoss) { add(frameId, fragment, tag) } } fun Fragment.addFragment( diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt index 41e08dc655..c0f07dba57 100644 --- a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt +++ b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewActivity.kt @@ -19,31 +19,21 @@ package im.vector.app.features.location.live.map import android.content.Context import android.content.Intent import android.os.Parcelable -import androidx.lifecycle.lifecycleScope -import com.mapbox.mapboxsdk.maps.MapboxMapOptions -import com.mapbox.mapboxsdk.maps.SupportMapFragment import dagger.hilt.android.AndroidEntryPoint import im.vector.app.R import im.vector.app.core.extensions.addFragment import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.databinding.ActivityLocationSharingBinding -import im.vector.app.features.location.UrlMapProvider import kotlinx.parcelize.Parcelize -import javax.inject.Inject @Parcelize data class LocationLiveMapViewArgs( val roomId: String ) : Parcelable -/** - * Screen showing a map with all the current users sharing their live location in room. - */ @AndroidEntryPoint class LocationLiveMapViewActivity : VectorBaseActivity() { - @Inject lateinit var urlMapProvider: UrlMapProvider - override fun getBinding() = ActivityLocationSharingBinding.inflate(layoutInflater) override fun initUiAndData() { @@ -56,30 +46,18 @@ class LocationLiveMapViewActivity : VectorBaseActivity - lifecycleScope.launchWhenCreated { - mapBoxMap.setStyle(urlMapProvider.getMapUrl()) - } + if (isFirstCreation()) { + addFragment( + views.fragmentContainer, + LocationLiveMapViewFragment::class.java, + mapViewArgs + ) } } companion object { private const val EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS = "EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS" - private const val MAP_FRAGMENT_TAG = "im.vector.app.features.location.live.map" fun getIntent(context: Context, locationLiveMapViewArgs: LocationLiveMapViewArgs): Intent { return Intent(context, LocationLiveMapViewActivity::class.java).apply { diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt new file mode 100644 index 0000000000..29c45f8945 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.location.live.map + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.lifecycle.lifecycleScope +import com.airbnb.mvrx.args +import com.mapbox.mapboxsdk.maps.MapView +import com.mapbox.mapboxsdk.maps.MapboxMapOptions +import com.mapbox.mapboxsdk.maps.SupportMapFragment +import im.vector.app.R +import im.vector.app.core.extensions.addFragment +import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentLiveLocationMapBinding +import im.vector.app.databinding.FragmentLocationPreviewBinding +import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider +import im.vector.app.features.location.UrlMapProvider +import java.lang.ref.WeakReference +import javax.inject.Inject + +/** + * Screen showing a map with all the current users sharing their live location in room. + */ +class LocationLiveMapViewFragment @Inject constructor( + private val urlMapProvider: UrlMapProvider, + private val locationPinProvider: LocationPinProvider +) : VectorBaseFragment() { + + private val args: LocationLiveMapViewArgs by args() + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLiveLocationMapBinding { + return FragmentLiveLocationMapBinding.inflate(layoutInflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setupMap() + } + + private fun setupMap() { + val mapFragment: SupportMapFragment = + parentFragmentManager.findFragmentByTag(MAP_FRAGMENT_TAG) as? SupportMapFragment + ?: run { + val options = MapboxMapOptions.createFromAttributes(requireContext(), null) + val fragment = SupportMapFragment.newInstance(options) + addFragment(R.id.liveLocationMapContainer, fragment, tag = MAP_FRAGMENT_TAG) + fragment + } + + mapFragment.getMapAsync { mapBoxMap -> + lifecycleScope.launchWhenCreated { + mapBoxMap.setStyle(urlMapProvider.getMapUrl()) + } + } + } + + companion object { + private const val MAP_FRAGMENT_TAG = "im.vector.app.features.location.live.map" + } +} diff --git a/vector/src/main/res/layout/fragment_live_location_map.xml b/vector/src/main/res/layout/fragment_live_location_map.xml new file mode 100644 index 0000000000..5238508d6f --- /dev/null +++ b/vector/src/main/res/layout/fragment_live_location_map.xml @@ -0,0 +1,5 @@ + + From 4864980a5afd194fb5ce619b6c49c56ecebf0d32 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Tue, 17 May 2022 11:07:21 +0200 Subject: [PATCH 035/125] Enable navigation only from running state item --- .../app/features/home/room/detail/TimelineFragment.kt | 1 - .../timeline/factory/LiveLocationShareMessageItemFactory.kt | 6 ++++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index bf7c506d79..7ab3ab2adc 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -2024,7 +2024,6 @@ class TimelineFragment @Inject constructor( handleShowLocationPreview(messageContent, informationData.senderId) } is MessageBeaconInfoContent -> { - // TODO navigate only from running live location message: possible after merge of associated PR navigateToLocationLiveMap() } else -> { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationShareMessageItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationShareMessageItemFactory.kt index 479a742369..912702aaed 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationShareMessageItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationShareMessageItemFactory.kt @@ -75,7 +75,8 @@ class LiveLocationShareMessageItemFactory @Inject constructor( val height = dimensionConverter.dpToPx(MessageItemFactory.MESSAGE_LOCATION_ITEM_HEIGHT_IN_DP) return MessageLiveLocationInactiveItem_() - .attributes(attributes) + // disable the click on this state item + .attributes(attributes.copy(itemClickListener = null)) .mapWidth(width) .mapHeight(height) .highlighted(highlight) @@ -90,7 +91,8 @@ class LiveLocationShareMessageItemFactory @Inject constructor( val height = dimensionConverter.dpToPx(MessageItemFactory.MESSAGE_LOCATION_ITEM_HEIGHT_IN_DP) return MessageLiveLocationStartItem_() - .attributes(attributes) + // disable the click on this state item + .attributes(attributes.copy(itemClickListener = null)) .mapWidth(width) .mapHeight(height) .highlighted(highlight) From 526585677234a063f4ebcbc9a88731fc1aeacb9b Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Tue, 17 May 2022 11:11:41 +0200 Subject: [PATCH 036/125] Remove unused imports --- .../location/live/map/LocationLiveMapViewFragment.kt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt index 29c45f8945..50526f2839 100644 --- a/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt +++ b/vector/src/main/java/im/vector/app/features/location/live/map/LocationLiveMapViewFragment.kt @@ -22,17 +22,13 @@ import android.view.View import android.view.ViewGroup import androidx.lifecycle.lifecycleScope import com.airbnb.mvrx.args -import com.mapbox.mapboxsdk.maps.MapView import com.mapbox.mapboxsdk.maps.MapboxMapOptions import com.mapbox.mapboxsdk.maps.SupportMapFragment import im.vector.app.R import im.vector.app.core.extensions.addFragment import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentLiveLocationMapBinding -import im.vector.app.databinding.FragmentLocationPreviewBinding -import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider import im.vector.app.features.location.UrlMapProvider -import java.lang.ref.WeakReference import javax.inject.Inject /** @@ -40,7 +36,6 @@ import javax.inject.Inject */ class LocationLiveMapViewFragment @Inject constructor( private val urlMapProvider: UrlMapProvider, - private val locationPinProvider: LocationPinProvider ) : VectorBaseFragment() { private val args: LocationLiveMapViewArgs by args() From 51ac6f22d7fbb1395439da468ca9e53209a65005 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Thu, 19 May 2022 12:01:42 +0300 Subject: [PATCH 037/125] Labs flag added for enabling live location sharing. --- .../features/debug/features/DebugFeaturesStateFactory.kt | 5 ----- .../app/features/debug/features/DebugVectorFeatures.kt | 3 --- .../src/main/java/im/vector/app/features/VectorFeatures.kt | 2 -- .../vector/app/features/location/LocationSharingFragment.kt | 6 +++--- .../im/vector/app/features/settings/VectorPreferences.kt | 5 +++++ vector/src/main/res/values/strings.xml | 2 ++ vector/src/main/res/xml/vector_settings_labs.xml | 6 ++++++ 7 files changed, 16 insertions(+), 13 deletions(-) diff --git a/vector/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt b/vector/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt index f2904e4b1a..00a073f832 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/features/DebugFeaturesStateFactory.kt @@ -60,11 +60,6 @@ class DebugFeaturesStateFactory @Inject constructor( key = DebugFeatureKeys.onboardingCombinedRegister, factory = VectorFeatures::isOnboardingCombinedRegisterEnabled ), - createBooleanFeature( - label = "Live location sharing", - key = DebugFeatureKeys.liveLocationSharing, - factory = VectorFeatures::isLiveLocationEnabled - ), ) ) } diff --git a/vector/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt b/vector/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt index 07fab8a58d..1bc37ff97e 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/features/DebugVectorFeatures.kt @@ -57,9 +57,6 @@ class DebugVectorFeatures( override fun isOnboardingCombinedRegisterEnabled(): Boolean = read(DebugFeatureKeys.onboardingCombinedRegister) ?: vectorFeatures.isOnboardingCombinedRegisterEnabled() - override fun isLiveLocationEnabled(): Boolean = read(DebugFeatureKeys.liveLocationSharing) - ?: vectorFeatures.isLiveLocationEnabled() - override fun isScreenSharingEnabled(): Boolean = read(DebugFeatureKeys.screenSharing) ?: vectorFeatures.isScreenSharingEnabled() diff --git a/vector/src/main/java/im/vector/app/features/VectorFeatures.kt b/vector/src/main/java/im/vector/app/features/VectorFeatures.kt index 42693a53f9..e3fded2824 100644 --- a/vector/src/main/java/im/vector/app/features/VectorFeatures.kt +++ b/vector/src/main/java/im/vector/app/features/VectorFeatures.kt @@ -26,7 +26,6 @@ interface VectorFeatures { fun isOnboardingUseCaseEnabled(): Boolean fun isOnboardingPersonalizeEnabled(): Boolean fun isOnboardingCombinedRegisterEnabled(): Boolean - fun isLiveLocationEnabled(): Boolean fun isScreenSharingEnabled(): Boolean enum class OnboardingVariant { @@ -43,6 +42,5 @@ class DefaultVectorFeatures : VectorFeatures { override fun isOnboardingUseCaseEnabled() = true override fun isOnboardingPersonalizeEnabled() = false override fun isOnboardingCombinedRegisterEnabled() = false - override fun isLiveLocationEnabled(): Boolean = false override fun isScreenSharingEnabled(): Boolean = true } diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt index e472c568b6..cc5586e7f5 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt @@ -37,11 +37,11 @@ import im.vector.app.core.utils.PERMISSIONS_FOR_FOREGROUND_LOCATION_SHARING import im.vector.app.core.utils.checkPermissions import im.vector.app.core.utils.registerForPermissionsResult import im.vector.app.databinding.FragmentLocationSharingBinding -import im.vector.app.features.VectorFeatures import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.detail.timeline.helper.MatrixItemColorProvider import im.vector.app.features.location.live.duration.ChooseLiveDurationBottomSheet import im.vector.app.features.location.option.LocationSharingOption +import im.vector.app.features.settings.VectorPreferences import org.matrix.android.sdk.api.util.MatrixItem import java.lang.ref.WeakReference import javax.inject.Inject @@ -53,7 +53,7 @@ class LocationSharingFragment @Inject constructor( private val urlMapProvider: UrlMapProvider, private val avatarRenderer: AvatarRenderer, private val matrixItemColorProvider: MatrixItemColorProvider, - private val vectorFeatures: VectorFeatures, + private val vectorPreferences: VectorPreferences, ) : VectorBaseFragment(), LocationTargetChangeListener, VectorBaseBottomSheetDialogFragment.ResultListener { @@ -255,7 +255,7 @@ class LocationSharingFragment @Inject constructor( // first, update the options view val options: Set = when (state.areTargetAndUserLocationEqual) { true -> { - if (vectorFeatures.isLiveLocationEnabled()) { + if (vectorPreferences.labsEnableLiveLocation()) { setOf(LocationSharingOption.USER_CURRENT, LocationSharingOption.USER_LIVE) } else { setOf(LocationSharingOption.USER_CURRENT) diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt index c841c6a0af..b368ce021c 100755 --- a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt @@ -203,6 +203,7 @@ class VectorPreferences @Inject constructor( private const val TAKE_PHOTO_VIDEO_MODE = "TAKE_PHOTO_VIDEO_MODE" private const val SETTINGS_LABS_RENDER_LOCATIONS_IN_TIMELINE = "SETTINGS_LABS_RENDER_LOCATIONS_IN_TIMELINE" + private const val SETTINGS_LABS_ENABLE_LIVE_LOCATION = "SETTINGS_LABS_ENABLE_LIVE_LOCATION" // This key will be used to identify clients with the old thread support enabled io.element.thread const val SETTINGS_LABS_ENABLE_THREAD_MESSAGES_OLD_CLIENTS = "SETTINGS_LABS_ENABLE_THREAD_MESSAGES" @@ -1041,6 +1042,10 @@ class VectorPreferences @Inject constructor( return defaultPrefs.getBoolean(SETTINGS_LABS_RENDER_LOCATIONS_IN_TIMELINE, true) } + fun labsEnableLiveLocation(): Boolean { + return defaultPrefs.getBoolean(SETTINGS_LABS_ENABLE_LIVE_LOCATION, false) + } + /** * Indicates whether or not thread messages are enabled. */ diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 20bedcaa1e..2f3e8d8134 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -3022,6 +3022,8 @@ %1$s left ${app_name} Live Location Location sharing is in progress + Enable Live Location Sharing + Temporary implementation: locations persist in room history Show Message bubbles diff --git a/vector/src/main/res/xml/vector_settings_labs.xml b/vector/src/main/res/xml/vector_settings_labs.xml index 8b25a8c287..19ee7e366f 100644 --- a/vector/src/main/res/xml/vector_settings_labs.xml +++ b/vector/src/main/res/xml/vector_settings_labs.xml @@ -69,4 +69,10 @@ android:key="SETTINGS_LABS_RENDER_LOCATIONS_IN_TIMELINE" android:title="@string/labs_render_locations_in_timeline" /> + + From 28c4abb505930d649b76a83930d847ca277ad424 Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Thu, 19 May 2022 10:34:38 +0100 Subject: [PATCH 038/125] Track number of retries of tests, and retry KeysBackupTest --- .../java/org/matrix/android/sdk/common/RetryTestRule.kt | 3 +++ .../android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt index b16ab98e6c..80ccf578e5 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt @@ -40,6 +40,9 @@ class RetryTestRule(val retryCount: Int = 3) : TestRule { for (i in 0 until retryCount) { try { base.evaluate() + if(i > 0) { + println("Retried test $i times") + } return } catch (t: Throwable) { caughtThrowable = t diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt index 9136272b1e..d5fd299f1f 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt @@ -24,6 +24,7 @@ import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.FixMethodOrder +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters @@ -45,6 +46,7 @@ import org.matrix.android.sdk.api.session.crypto.model.ImportRoomKeysResult import org.matrix.android.sdk.api.session.getRoom import org.matrix.android.sdk.common.CommonTestHelper import org.matrix.android.sdk.common.CryptoTestHelper +import org.matrix.android.sdk.common.RetryTestRule import org.matrix.android.sdk.common.TestConstants import org.matrix.android.sdk.common.TestMatrixCallback import java.util.Collections @@ -55,6 +57,8 @@ import java.util.concurrent.CountDownLatch @LargeTest class KeysBackupTest : InstrumentedTest { + @get:Rule val rule = RetryTestRule(3) + /** * - From doE2ETestWithAliceAndBobInARoomWithEncryptedMessages, we should have no backed up keys * - Check backup keys after having marked one as backed up From 5b43257f353cceefb8badf19ce0d587666ecd3c6 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Thu, 19 May 2022 12:44:51 +0300 Subject: [PATCH 039/125] Changelog added. --- changelog.d/6098.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/6098.feature diff --git a/changelog.d/6098.feature b/changelog.d/6098.feature new file mode 100644 index 0000000000..659da42094 --- /dev/null +++ b/changelog.d/6098.feature @@ -0,0 +1 @@ +Labs flag for enabling live location sharing From 9adbeb8dd2e5cd4aef59e85a2567733782e2a2c0 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Thu, 19 May 2022 14:04:37 +0300 Subject: [PATCH 040/125] Fix import. --- .../internal/session/room/EventRelationsAggregationProcessor.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt index 5d2a1477fc..c44f88b93d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt @@ -24,6 +24,7 @@ import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.LocalEcho import org.matrix.android.sdk.api.session.events.model.RelationType import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent +import org.matrix.android.sdk.api.session.events.model.getRelationContent import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent From fe793798fafa174323c4cd8b8461651abb056e1d Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Thu, 19 May 2022 12:06:54 +0100 Subject: [PATCH 041/125] Ignore E2eeSanityTests. They fail infrequently, but in a way that takes the entire test framework down, so ignore them for now and open an issue to fix. --- .../org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt index 38597269cb..5e740a79ee 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt @@ -23,6 +23,7 @@ import org.amshove.kluent.fail import org.amshove.kluent.internal.assertEquals import org.junit.Assert import org.junit.FixMethodOrder +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -67,6 +68,7 @@ import java.util.concurrent.CountDownLatch @RunWith(JUnit4::class) @FixMethodOrder(MethodSorters.JVM) @LargeTest +@Ignore("This test fails with an unhandled exception thrown from a coroutine which terminates the entire test run.") class E2eeSanityTests : InstrumentedTest { @get:Rule val rule = RetryTestRule(3) From a4fa65b4fdf79e7baf38ab8f515c7f17f7eeec3c Mon Sep 17 00:00:00 2001 From: Michael Kaye <1917473+michaelkaye@users.noreply.github.com> Date: Thu, 19 May 2022 12:37:41 +0100 Subject: [PATCH 042/125] Fix linting --- .../java/org/matrix/android/sdk/common/RetryTestRule.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt index 80ccf578e5..39f49a9ccc 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/RetryTestRule.kt @@ -40,7 +40,7 @@ class RetryTestRule(val retryCount: Int = 3) : TestRule { for (i in 0 until retryCount) { try { base.evaluate() - if(i > 0) { + if (i > 0) { println("Retried test $i times") } return From b379ef46ecc674320c8dc3e5b40d2ed0c05fe75e Mon Sep 17 00:00:00 2001 From: ClaireG Date: Thu, 19 May 2022 16:14:58 +0200 Subject: [PATCH 043/125] Revert: Use member name instead of room name in DM creation item (#6049) --- changelog.d/6032.bugfix | 1 + .../home/room/detail/timeline/item/MergedRoomCreationItem.kt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelog.d/6032.bugfix diff --git a/changelog.d/6032.bugfix b/changelog.d/6032.bugfix new file mode 100644 index 0000000000..c20d7ddd08 --- /dev/null +++ b/changelog.d/6032.bugfix @@ -0,0 +1 @@ +Revert: Use member name instead of room name in DM creation item diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MergedRoomCreationItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MergedRoomCreationItem.kt index f3ca525136..f41c17d9e7 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MergedRoomCreationItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MergedRoomCreationItem.kt @@ -135,7 +135,7 @@ abstract class MergedRoomCreationItem : BasedMergedItem Date: Wed, 18 May 2022 08:47:18 +0200 Subject: [PATCH 044/125] Detekt: Enable OutdatedDocumentation --- tools/detekt/detekt.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/detekt/detekt.yml b/tools/detekt/detekt.yml index 322f29e5b7..a836edc47a 100644 --- a/tools/detekt/detekt.yml +++ b/tools/detekt/detekt.yml @@ -87,8 +87,7 @@ comments: EndOfSentenceFormat: active: true OutdatedDocumentation: - # TODO Enable it - active: false + active: true UndocumentedPublicClass: active: false UndocumentedPublicFunction: From 2a66e037426fd5aa7c1a55ca035ef8563aa715de Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 18 May 2022 08:50:04 +0200 Subject: [PATCH 045/125] Kdoc: remove unnecessary `:` --- .../android/sdk/api/session/permalinks/PermalinkService.kt | 2 +- .../matrix/android/sdk/api/session/room/read/ReadService.kt | 2 +- .../matrix/android/sdk/api/session/space/SpaceService.kt | 2 +- .../matrix/android/sdk/api/session/widgets/WidgetService.kt | 4 ++-- .../android/sdk/internal/session/room/RoomAvatarResolver.kt | 2 +- .../session/room/membership/RoomDisplayNameResolver.kt | 4 ++-- .../matrix/android/sdk/internal/session/space/SpaceApi.kt | 6 +++--- .../android/sdk/internal/wellknown/GetWellknownTask.kt | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt index b49b80df09..476ded2e16 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt @@ -90,7 +90,7 @@ interface PermalinkService { * Creates a HTML or Markdown mention span template. Can be used to replace a mention with a permalink to mentioned user. * Ex: "%2\$s" or "[%2\$s](https://matrix.to/#/%1\$s)" * - * @param type: type of template to create + * @param type type of template to create * @param forceMatrixTo whether we should force using matrix.to base URL * * @return the created template diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/read/ReadService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/read/ReadService.kt index 036628c02f..dac1a1a773 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/read/ReadService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/read/ReadService.kt @@ -71,7 +71,7 @@ interface ReadService { /** * Returns a live list of read receipts for a given event. - * @param eventId: the event + * @param eventId the event */ fun getEventReadReceiptsLive(eventId: String): LiveData> } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt index 8f16b3b9c3..2ce00df856 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt @@ -61,7 +61,7 @@ interface SpaceService { * Get's information of a space by querying the server. * @param suggestedOnly If true, return only child events and rooms where the m.space.child event has suggested: true. * @param limit a client-defined limit to the maximum number of rooms to return per page. Must be a non-negative integer. - * @param from: Optional. Pagination token given to retrieve the next set of rooms. Note that if a pagination token is provided, + * @param from Optional. Pagination token given to retrieve the next set of rooms. Note that if a pagination token is provided, * then the parameters given for suggested_only and max_depth must be the same. */ suspend fun querySpaceChildren(spaceId: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/widgets/WidgetService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/widgets/WidgetService.kt index b06f8f7bc6..8ad6500d25 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/widgets/WidgetService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/widgets/WidgetService.kt @@ -111,8 +111,8 @@ interface WidgetService { /** * Deactivate a widget in a room. It makes sure you have the rights to handle this. * - * @param roomId: the room where you want to deactivate the widget. - * @param widgetId: the widget to deactivate. + * @param roomId the room where you want to deactivate the widget. + * @param widgetId the widget to deactivate. */ suspend fun destroyRoomWidget(roomId: String, widgetId: String) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAvatarResolver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAvatarResolver.kt index 29a303475b..c3d55b267a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAvatarResolver.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAvatarResolver.kt @@ -35,7 +35,7 @@ internal class RoomAvatarResolver @Inject constructor(@UserId private val userId /** * Compute the room avatar url. - * @param realm: the current instance of realm + * @param realm the current instance of realm * @param roomId the roomId of the room to resolve avatar * @return the room avatar url, can be a fallback to a room member avatar or null */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomDisplayNameResolver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomDisplayNameResolver.kt index 59e0f81ece..9e672dcc5c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomDisplayNameResolver.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomDisplayNameResolver.kt @@ -52,8 +52,8 @@ internal class RoomDisplayNameResolver @Inject constructor( /** * Compute the room display name. * - * @param realm: the current instance of realm - * @param roomId: the roomId to resolve the name of. + * @param realm the current instance of realm + * @param roomId the roomId to resolve the name of. * @return the room display name */ fun resolve(realm: Realm, roomId: String): RoomName { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/SpaceApi.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/SpaceApi.kt index d8daa55e15..db3c9c3f5f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/SpaceApi.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/SpaceApi.kt @@ -25,10 +25,10 @@ internal interface SpaceApi { /** * @param suggestedOnly Optional. If true, return only child events and rooms where the m.space.child event has suggested: true. - * @param limit: Optional: a client-defined limit to the maximum number of rooms to return per page. Must be a non-negative integer. - * @param maxDepth: Optional: The maximum depth in the tree (from the root room) to return. + * @param limit Optional: a client-defined limit to the maximum number of rooms to return per page. Must be a non-negative integer. + * @param maxDepth Optional: The maximum depth in the tree (from the root room) to return. * The deepest depth returned will not include children events. Defaults to no-limit. Must be a non-negative integer. - * @param from: Optional. Pagination token given to retrieve the next set of rooms. + * @param from Optional. Pagination token given to retrieve the next set of rooms. * Note that if a pagination token is provided, then the parameters given for suggested_only and max_depth must be the same. */ @GET(NetworkConstants.URI_API_PREFIX_PATH_V1 + "rooms/{roomId}/hierarchy") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/wellknown/GetWellknownTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/wellknown/GetWellknownTask.kt index 0d4a5ac28f..c2e9b4e731 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/wellknown/GetWellknownTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/wellknown/GetWellknownTask.kt @@ -75,7 +75,7 @@ internal class DefaultGetWellknownTask @Inject constructor( * - validate homeserver url and identity server url if provide in .well-known result * - return action and .well-known data * - * @param domain: homeserver domain, deduced from mx userId (ex: "matrix.org" from userId "@user:matrix.org") + * @param domain homeserver domain, deduced from mx userId (ex: "matrix.org" from userId "@user:matrix.org") */ private suspend fun findClientConfig(domain: String, client: OkHttpClient): WellknownResult { val wellKnownAPI = retrofitFactory.create(client, "https://dummy.org") From 51fe7b9a93df216e82dd76ba1d5bc6b4d0f9e758 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 18 May 2022 10:37:40 +0200 Subject: [PATCH 046/125] Detekt: Fix OutdatedDocumentation --- .../contentscanner/ContentScannerService.kt | 2 +- .../session/crypto/model/IncomingRoomKeyRequest.kt | 3 +-- .../api/session/crypto/model/MXUsersDevicesMap.kt | 4 ++-- .../android/sdk/api/session/file/FileService.kt | 2 +- .../sdk/api/session/identity/IdentityService.kt | 1 + .../IntegrationManagerService.kt | 1 + .../sdk/api/session/permalinks/MatrixLinkify.kt | 1 + .../api/session/permalinks/MatrixPermalinkSpan.kt | 4 ++-- .../sdk/api/session/permalinks/PermalinkService.kt | 1 + .../sdk/api/session/pushrules/PushRuleService.kt | 3 ++- .../api/session/room/crypto/RoomCryptoService.kt | 3 ++- .../session/room/model/relation/RelationService.kt | 6 ++++-- .../sdk/api/session/room/send/SendService.kt | 1 + .../sdk/api/session/room/state/StateService.kt | 6 ++++++ .../sdk/api/session/room/timeline/TimelineEvent.kt | 1 + .../securestorage/SharedSecretStorageService.kt | 2 +- .../android/sdk/api/session/space/SpaceService.kt | 12 +++++++++--- .../api/session/widgets/WidgetPostAPIMediator.kt | 3 ++- .../internal/crypto/CryptoSessionInfoProvider.kt | 1 + .../sdk/internal/crypto/DefaultCryptoService.kt | 2 ++ .../internal/crypto/MXMegolmExportEncryption.kt | 2 +- .../android/sdk/internal/crypto/MXOlmDevice.kt | 4 ++-- .../internal/crypto/algorithms/IMXDecrypting.kt | 1 + .../crypto/algorithms/IMXGroupEncryption.kt | 2 +- .../crypto/algorithms/megolm/MXMegolmDecryption.kt | 1 + .../crypto/algorithms/olm/MXOlmDecryption.kt | 2 +- .../android/sdk/internal/crypto/api/CryptoApi.kt | 2 +- .../crypto/attachments/MXEncryptedAttachments.kt | 2 ++ .../crypto/keysbackup/DefaultKeysBackupService.kt | 1 + .../crypto/keysbackup/KeysBackupPassword.kt | 1 + .../internal/crypto/keysbackup/api/RoomKeysApi.kt | 2 +- .../sdk/internal/crypto/store/IMXCryptoStore.kt | 10 +++++----- .../crypto/verification/VerificationTransport.kt | 5 +++++ .../internal/database/helper/ThreadEventsHelper.kt | 6 ++++++ .../database/helper/ThreadSummaryHelper.kt | 1 + .../matrix/android/sdk/internal/network/Request.kt | 1 + .../network/parsing/RuntimeJsonAdapterFactory.kt | 2 ++ .../android/sdk/internal/network/ssl/CertUtil.kt | 1 + .../sdk/internal/network/ssl/PinnedTrustManager.kt | 8 +++----- .../network/ssl/PinnedTrustManagerApi24.kt | 8 +++----- .../sdk/internal/session/directory/DirectoryAPI.kt | 1 + .../sdk/internal/session/openid/OpenIdAPI.kt | 1 + .../sdk/internal/session/pushers/PushRulesApi.kt | 2 +- .../room/EventRelationsAggregationProcessor.kt | 1 + .../android/sdk/internal/session/room/RoomAPI.kt | 12 ++++++++++++ .../internal/session/room/send/queue/QueuedTask.kt | 4 ++-- .../android/sdk/internal/session/space/SpaceApi.kt | 1 + .../sync/handler/room/ThreadsAwarenessHandler.kt | 12 ++++++++++-- .../widgets/DefaultWidgetPostAPIMediator.kt | 2 ++ .../sdk/internal/session/widgets/WidgetsAPI.kt | 1 + .../sdk/internal/task/CoroutineSequencer.kt | 1 + .../android/sdk/internal/util/JsonCanonicalizer.kt | 2 +- .../sdk/internal/wellknown/GetWellknownTask.kt | 1 + .../core/dialogs/UnrecognizedCertificateDialog.kt | 5 +++++ .../vector/app/core/intent/ExternalIntentData.kt | 12 +++++++----- .../im/vector/app/core/intent/VectorMimeType.kt | 1 + .../app/core/preference/PushRulePreference.kt | 2 +- .../vector/app/core/ui/views/KeysBackupBanner.kt | 1 + .../java/im/vector/app/core/utils/RingtoneUtils.kt | 1 + .../java/im/vector/app/core/utils/SystemUtils.kt | 2 ++ .../im/vector/app/core/utils/TemporaryStore.kt | 3 ++- .../app/features/call/audio/CallAudioManager.kt | 1 + .../vector/app/features/command/CommandParser.kt | 3 ++- .../timeline/factory/MergedHeaderItemFactory.kt | 7 +++++++ .../helper/TimelineEventVisibilityHelper.kt | 5 +++++ .../room/detail/timeline/url/PreviewUrlView.kt | 2 ++ .../features/notifications/NotificationUtils.kt | 14 +++++--------- .../vector/app/features/rageshake/BugReporter.kt | 6 +++++- .../im/vector/app/features/settings/FontScale.kt | 1 + .../im/vector/app/features/themes/ThemeUtils.kt | 5 ++++- .../app/features/widgets/WidgetPostAPIHandler.kt | 10 ++++++++++ 71 files changed, 179 insertions(+), 64 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/contentscanner/ContentScannerService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/contentscanner/ContentScannerService.kt index 7a85a89058..22250628d5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/contentscanner/ContentScannerService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/contentscanner/ContentScannerService.kt @@ -33,7 +33,7 @@ interface ContentScannerService { /** * Get the current public curve25519 key that the AV server is advertising. - * @param callback on success callback containing the server public key + * @param forceDownload true to force the SDK to download again the server public key */ suspend fun getServerPublicKey(forceDownload: Boolean = false): String? suspend fun getScanResultForAttachment(mxcUrl: String, fileInfo: ElementToDecrypt? = null): ScanStatusInfo diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/IncomingRoomKeyRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/IncomingRoomKeyRequest.kt index 0c19d275cc..4ff196dd07 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/IncomingRoomKeyRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/IncomingRoomKeyRequest.kt @@ -48,8 +48,7 @@ data class IncomingRoomKeyRequest( /** * Factory. * - * @param event the event - * @param currentTimeMillis the current time in milliseconds + * @param trail the AuditTrail data */ fun fromEvent(trail: AuditTrail): IncomingRoomKeyRequest? { return trail diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXUsersDevicesMap.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXUsersDevicesMap.kt index 744fe74d0d..c067a53dba 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXUsersDevicesMap.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXUsersDevicesMap.kt @@ -46,8 +46,8 @@ class MXUsersDevicesMap { /** * Provides the object for a device id and a user Id. * - * @param deviceId the device id * @param userId the object id + * @param deviceId the device id * @return the object */ fun getObject(userId: String?, deviceId: String?): E? { @@ -73,8 +73,8 @@ class MXUsersDevicesMap { /** * Defines the objects map for a user Id. * - * @param objectsPerDevices the objects maps * @param userId the user id + * @param objectsPerDevices the objects maps */ fun setObjects(userId: String?, objectsPerDevices: Map?) { if (!userId.isNullOrBlank()) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/file/FileService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/file/FileService.kt index 84a9990826..a7c81136e3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/file/FileService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/file/FileService.kt @@ -33,7 +33,7 @@ interface FileService { /** * The original file is in cache, but the decrypted files can be deleted for security reason. * To decrypt the file again, call [downloadFile], the encrypted file will not be downloaded again - * @param decryptedFileInCache true if the decrypted file is available. Always true for clear files. + * @property decryptedFileInCache true if the decrypted file is available. Always true for clear files. */ data class InCache(val decryptedFileInCache: Boolean) : FileState() object Downloading : FileState() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt index c03b42e6c8..2fb35d38e3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt @@ -74,6 +74,7 @@ interface IdentityService { /** * Submit the code that the identity server has sent to the user (in email or SMS). * Once successful, you will have to call [finalizeBindThreePid] + * @param threePid the three pid * @param code the code sent to the user */ suspend fun submitValidationToken(threePid: ThreePid, code: String) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/integrationmanager/IntegrationManagerService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/integrationmanager/IntegrationManagerService.kt index 60af93888e..5b15a0cb13 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/integrationmanager/IntegrationManagerService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/integrationmanager/IntegrationManagerService.kt @@ -99,6 +99,7 @@ interface IntegrationManagerService { * Offers to allow or disallow a native widget domain. * @param widgetType the widget type to check for * @param domain the domain to check for + * @param allowed true or false */ suspend fun setNativeWidgetDomainAllowed(widgetType: String, domain: String, allowed: Boolean) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixLinkify.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixLinkify.kt index c5d919407a..c428e40203 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixLinkify.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixLinkify.kt @@ -29,6 +29,7 @@ object MatrixLinkify { * Find the matrix spans i.e matrix id , user id ... to display them as URL. * * @param spannable the text in which the matrix items has to be clickable. + * @param callback listener to be notified when the span is clicked */ @Suppress("UNUSED_PARAMETER") fun addLinks(spannable: Spannable, callback: MatrixPermalinkSpan.Callback?): Boolean { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixPermalinkSpan.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixPermalinkSpan.kt index 2f8f5f99a5..48b30dfa21 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixPermalinkSpan.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixPermalinkSpan.kt @@ -22,8 +22,8 @@ import org.matrix.android.sdk.api.session.permalinks.MatrixPermalinkSpan.Callbac /** * This MatrixPermalinkSpan is a clickable span which use a [Callback] to communicate back. - * @param url the permalink url tied to the span - * @param callback the callback to use. + * @property url the permalink url tied to the span + * @property callback the callback to use. */ class MatrixPermalinkSpan(private val url: String, private val callback: Callback? = null) : ClickableSpan() { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt index 476ded2e16..7c4c570c1e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt @@ -60,6 +60,7 @@ interface PermalinkService { * Creates a permalink for a roomId, including the via parameters. * * @param roomId the room id + * @param viaServers the via parameter * @param forceMatrixTo whether we should force using matrix.to base URL * * @return the permalink, or null in case of error diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/PushRuleService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/PushRuleService.kt index bc4860be11..7ffbc89559 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/PushRuleService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/PushRuleService.kt @@ -34,10 +34,11 @@ interface PushRuleService { /** * Enables/Disables a push rule and updates the actions if necessary. + * @param kind the rule kind + * @param ruleId the rule id * @param enable Enables/Disables the rule * @param actions Actions to update if not null */ - suspend fun updatePushRuleActions(kind: RuleKind, ruleId: String, enable: Boolean, actions: List?) suspend fun removePushRule(kind: RuleKind, ruleId: String) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/crypto/RoomCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/crypto/RoomCryptoService.kt index 6967e0c455..6064643820 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/crypto/RoomCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/crypto/RoomCryptoService.kt @@ -28,7 +28,8 @@ interface RoomCryptoService { /** * Enable encryption of the room. - * @param Use force to ensure that this algorithm will be used. Otherwise this call + * @param algorithm the algorithm to set, default to [MXCRYPTO_ALGORITHM_MEGOLM] + * @param force Use force to ensure that this algorithm will be used. Otherwise this call * will throw if encryption is already setup or if the algorithm is not supported. Only to * be used by admins to fix misconfigured encryption. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/relation/RelationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/relation/RelationService.kt index 0d094b835b..02c597ee63 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/relation/RelationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/relation/RelationService.kt @@ -71,8 +71,8 @@ interface RelationService { /** * Edit a poll. - * @param pollType indicates open or closed polls * @param targetEvent The poll event to edit + * @param pollType indicates open or closed polls * @param question The edited question * @param options The edited options */ @@ -84,7 +84,9 @@ interface RelationService { /** * Edit a text message body. Limited to "m.text" contentType. * @param targetEvent The event to edit + * @param msgType the message type * @param newBodyText The edited body + * @param newBodyAutoMarkdown true to parse markdown on the new body * @param compatibilityBodyText The text that will appear on clients that don't support yet edition */ fun editTextMessage(targetEvent: TimelineEvent, @@ -153,8 +155,8 @@ interface RelationService { * @param rootThreadEventId the root thread eventId * @param replyInThreadText the reply text * @param msgType the message type: MessageType.MSGTYPE_TEXT (default) or MessageType.MSGTYPE_EMOTE - * @param formattedText The formatted body using MessageType#FORMAT_MATRIX_HTML * @param autoMarkdown If true, the SDK will generate a formatted HTML message from the body text if markdown syntax is present + * @param formattedText The formatted body using MessageType#FORMAT_MATRIX_HTML * @param eventReplied the event referenced by the reply within a thread */ fun replyInThread(rootThreadEventId: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendService.kt index 4bb8abef8a..c2e3ded2fa 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendService.kt @@ -62,6 +62,7 @@ interface SendService { * @param quotedEvent The event to which we will quote it's content. * @param text the text message to send * @param autoMarkdown If true, the SDK will generate a formatted HTML message from the body text if markdown syntax is present + * @param rootThreadEventId when this param is not null, the message will be sent in this specific thread * @return a [Cancelable] */ fun sendQuotedTextMessage(quotedEvent: TimelineEvent, text: String, autoMarkdown: Boolean, rootThreadEventId: String? = null): Cancelable diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt index f6b56128d3..c79171f156 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt @@ -90,23 +90,29 @@ interface StateService { /** * Get a state event of the room. + * @param eventType An eventType. + * @param stateKey the query which will be done on the stateKey */ fun getStateEvent(eventType: String, stateKey: QueryStringValue = QueryStringValue.NoCondition): Event? /** * Get a live state event of the room. + * @param eventType An eventType. + * @param stateKey the query which will be done on the stateKey */ fun getStateEventLive(eventType: String, stateKey: QueryStringValue = QueryStringValue.NoCondition): LiveData> /** * Get state events of the room. * @param eventTypes Set of eventType. If empty, all state events will be returned + * @param stateKey the query which will be done on the stateKey */ fun getStateEvents(eventTypes: Set, stateKey: QueryStringValue = QueryStringValue.NoCondition): List /** * Get live state events of the room. * @param eventTypes Set of eventType to observe. If empty, all state events will be observed + * @param stateKey the query which will be done on the stateKey */ fun getStateEventsLive(eventTypes: Set, stateKey: QueryStringValue = QueryStringValue.NoCondition): LiveData> diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineEvent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineEvent.kt index d05fdb951f..d4ade9b5b9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineEvent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineEvent.kt @@ -90,6 +90,7 @@ data class TimelineEvent( /** * Get the metadata associated with a key. + * @param T type to cast the metadata to * @param key the key to get the metadata * @return the metadata */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SharedSecretStorageService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SharedSecretStorageService.kt index 528e071966..e3a9860523 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SharedSecretStorageService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SharedSecretStorageService.kt @@ -92,7 +92,7 @@ interface SharedSecretStorageService { * Clients MUST ensure that the key is trusted before using it to encrypt secrets. * * @param name The name of the secret - * @param secret The secret contents. + * @param secretBase64 The secret contents. * @param keys The list of (ID,privateKey) of the keys to use to encrypt the secret. */ suspend fun storeSecret(name: String, secretBase64: String, keys: List) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt index 2ce00df856..38e55664d2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt @@ -44,8 +44,8 @@ interface SpaceService { roomAliasLocalPart: String? = null): String /** - * Get a space from a roomId. - * @param spaceId the roomId to look for. + * Get a space from a spaceId. + * @param spaceId the spaceId to look for. * @return a space with spaceId or null if room type is not space */ fun getSpace(spaceId: String): Space? @@ -54,21 +54,24 @@ interface SpaceService { * Try to resolve (peek) rooms and subspace in this space. * Use this call get preview of children of this space, particularly useful to get a * preview of rooms that you did not join yet. + * @param spaceId the spaceId to look for. */ suspend fun peekSpace(spaceId: String): SpacePeekResult /** * Get's information of a space by querying the server. + * + * @param spaceId the spaceId to look for. * @param suggestedOnly If true, return only child events and rooms where the m.space.child event has suggested: true. * @param limit a client-defined limit to the maximum number of rooms to return per page. Must be a non-negative integer. * @param from Optional. Pagination token given to retrieve the next set of rooms. Note that if a pagination token is provided, * then the parameters given for suggested_only and max_depth must be the same. + * @param knownStateList when paginating, pass back the m.space.child state events */ suspend fun querySpaceChildren(spaceId: String, suggestedOnly: Boolean? = null, limit: Int? = null, from: String? = null, - // when paginating, pass back the m.space.child state events knownStateList: List? = null): SpaceHierarchyData /** @@ -98,7 +101,10 @@ interface SpaceService { /** * Let this room declare that it has a parent. + * @param childRoomId the space to set as a child + * @param parentSpaceId the parentId which will be set * @param canonical true if it should be the main parent of this room + * @param viaServers list of candidate servers that can be used to set the parent * In practice, well behaved rooms should only have one canonical parent, but given this is not enforced: * if multiple are present the client should select the one with the lowest room ID, as determined via a lexicographic utf-8 ordering. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/widgets/WidgetPostAPIMediator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/widgets/WidgetPostAPIMediator.kt index edb49f4797..3d134b4775 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/widgets/WidgetPostAPIMediator.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/widgets/WidgetPostAPIMediator.kt @@ -65,7 +65,8 @@ interface WidgetPostAPIMediator { /** * Send an object response. * - * @param klass the class of the response + * @param T the generic type + * @param type the type of the response * @param response the response * @param eventData the modular data */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoSessionInfoProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoSessionInfoProvider.kt index b3e9eab988..eee1ee70aa 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoSessionInfoProvider.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoSessionInfoProvider.kt @@ -46,6 +46,7 @@ internal class CryptoSessionInfoProvider @Inject constructor( } /** + * @param roomId the room Id * @param allActive if true return joined as well as invited, if false, only joined */ fun getRoomUserIds(roomId: String, allActive: Boolean): List { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 11fa93dbe0..2c8db7e1e4 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -905,6 +905,7 @@ internal class DefaultCryptoService @Inject constructor( /** * Handle an m.room.encryption event. * + * @param roomId the room Id * @param event the encryption event. */ private fun onRoomEncryptionEvent(roomId: String, event: Event) { @@ -928,6 +929,7 @@ internal class DefaultCryptoService @Inject constructor( /** * Handle a change in the membership state of a member of a room. * + * @param roomId the room Id * @param event the membership event causing the change */ private fun onRoomMembershipEvent(roomId: String, event: Event) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXMegolmExportEncryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXMegolmExportEncryption.kt index e4a0f0376e..93f92f0bfd 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXMegolmExportEncryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXMegolmExportEncryption.kt @@ -140,7 +140,7 @@ internal object MXMegolmExportEncryption { * * @param data the data to encrypt. * @param password the password - * @param kdf_rounds the iteration count + * @param kdfRounds the iteration count * @return the encrypted data * @throws Exception the failure reason */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt index 5620cbf769..dc3d393f97 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt @@ -429,8 +429,8 @@ internal class MXOlmDevice @Inject constructor( * * @param ciphertext the base64-encoded body from the received message. * @param messageType message_type field from the received message. - * @param theirDeviceIdentityKey the Curve25519 identity key for the remote device. * @param sessionId the id of the active session. + * @param theirDeviceIdentityKey the Curve25519 identity key for the remote device. * @return the decrypted payload. */ @kotlin.jvm.Throws @@ -873,9 +873,9 @@ internal class MXOlmDevice @Inject constructor( * Extract an InboundGroupSession from the session store and do some check. * inboundGroupSessionWithIdError describes the failure reason. * - * @param roomId the room where the session is used. * @param sessionId the session identifier. * @param senderKey the base64-encoded curve25519 key of the sender. + * @param roomId the room where the session is used. * @return the inbound group session. */ fun getInboundGroupSession(sessionId: String?, senderKey: String?, roomId: String?): InboundGroupSessionHolder { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXDecrypting.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXDecrypting.kt index 34006ecfde..af53719829 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXDecrypting.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXDecrypting.kt @@ -40,6 +40,7 @@ internal interface IMXDecrypting { * Handle a key event. * * @param event the key event. + * @param defaultKeysBackupService the keys backup service */ fun onRoomKeyEvent(event: Event, defaultKeysBackupService: DefaultKeysBackupService) {} } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXGroupEncryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXGroupEncryption.kt index 6f488def0a..8cf01f1972 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXGroupEncryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXGroupEncryption.kt @@ -38,7 +38,7 @@ internal interface IMXGroupEncryption { * Re-shares a session key with devices if the key has already been * sent to them. * - * @param sessionId The id of the outbound session to share. + * @param groupSessionId The id of the outbound session to share. * @param userId The id of the user who owns the target device. * @param deviceId The id of the target device. * @param senderKey The key of the originating device for the session. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt index 8321b73b75..d15b18ec79 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt @@ -176,6 +176,7 @@ internal class MXMegolmDecryption( * Handle a key event. * * @param event the key event. + * @param defaultKeysBackupService the keys backup service */ override fun onRoomKeyEvent(event: Event, defaultKeysBackupService: DefaultKeysBackupService) { Timber.tag(loggerTag.value).v("onRoomKeyEvent()") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmDecryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmDecryption.kt index 1e66fe84c9..5daf221add 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmDecryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmDecryption.kt @@ -180,8 +180,8 @@ internal class MXOlmDecryption( /** * Attempt to decrypt an Olm message. * - * @param theirDeviceIdentityKey the Curve25519 identity key of the sender. * @param message message object, with 'type' and 'body' fields. + * @param theirDeviceIdentityKey the Curve25519 identity key of the sender. * @return payload, if decrypted successfully. */ private suspend fun decryptMessage(message: JsonDict, theirDeviceIdentityKey: String): String? { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt index f21f5e05e1..eb8a8a2990 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt @@ -103,7 +103,7 @@ internal interface CryptoApi { * Claim one-time keys. * Doc: https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-keys-claim * - * @param params the params. + * @param body the Json body. */ @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "keys/claim") suspend fun claimOneTimeKeysForUsersDevices(@Body body: KeysClaimBody): KeysClaimResponse diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt index b4cbd15109..5028704b90 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt @@ -159,6 +159,7 @@ internal object MXEncryptedAttachments { * Encrypt an attachment stream. * DO NOT USE for big files, it will load all in memory * @param attachmentStream the attachment stream. Will be closed after this method call. + * @param clock a clock to retrieve current time * @return the encryption file info */ fun encryptAttachment(attachmentStream: InputStream, clock: Clock): EncryptionResult { @@ -232,6 +233,7 @@ internal object MXEncryptedAttachments { * @param attachmentStream the attachment stream. Will be closed after this method call. * @param elementToDecrypt the elementToDecrypt info * @param outputStream the outputStream where the decrypted attachment will be write. + * @param clock a clock to retrieve current time * @return true in case of success, false in case of error */ fun decryptAttachment(attachmentStream: InputStream?, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt index 5ea4695da2..813adf7459 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt @@ -1105,6 +1105,7 @@ internal class DefaultKeysBackupService @Inject constructor( * * @param password the password. * @param keysBackupData the backup and its auth data. + * @param progressListener listener to track progress * * @return the recovery key if successful, null in other cases */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupPassword.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupPassword.kt index d5bab33180..f821fdcf6d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupPassword.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupPassword.kt @@ -44,6 +44,7 @@ internal data class GeneratePrivateKeyResult( * Compute a private key from a password. * * @param password the password to use. + * @param progressListener a listener to track progress * * @return a {privateKey, salt, iterations} tuple. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/api/RoomKeysApi.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/api/RoomKeysApi.kt index ea23be5923..9f9a5741e0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/api/RoomKeysApi.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/api/RoomKeysApi.kt @@ -72,7 +72,7 @@ internal interface RoomKeysApi { */ @PUT(NetworkConstants.URI_API_PREFIX_PATH_UNSTABLE + "room_keys/version/{version}") suspend fun updateKeysBackupVersion(@Path("version") version: String, - @Body keysBackupVersionBody: UpdateKeysBackupVersionBody) + @Body updateKeysBackupVersionBody: UpdateKeysBackupVersionBody) /* ========================================================================================== * Storing keys diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt index 480009dbce..01d71d2115 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt @@ -164,16 +164,14 @@ internal interface IMXCryptoStore { /** * Store the end to end account for the logged-in user. - * - * @param account the account to save */ fun saveOlmAccount() /** * Retrieve a device for a user. * - * @param deviceId the device id. * @param userId the user's id. + * @param deviceId the device id. * @return the device */ fun getUserDevice(userId: String, deviceId: String): CryptoDeviceInfo? @@ -331,7 +329,7 @@ internal interface IMXCryptoStore { /** * Mark inbound group sessions as backed up on the user homeserver. * - * @param sessions the sessions + * @param olmInboundGroupSessionWrappers the sessions */ fun markBackupDoneForInboundGroupSessions(olmInboundGroupSessionWrappers: List) @@ -380,7 +378,9 @@ internal interface IMXCryptoStore { /** * Look for an existing outgoing room key request, and if none is found, add a new one. * - * @param request the request + * @param requestBody the request + * @param recipients list of recipients + * @param fromIndex start index * @return either the same instance as passed in, or the existing one. */ fun getOrAddOutgoingRoomKeyRequest(requestBody: RoomKeyRequestBody, recipients: Map>, fromIndex: Int): OutgoingKeyRequest diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransport.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransport.kt index 8538e5a5af..69dec12ef3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransport.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransport.kt @@ -35,6 +35,11 @@ internal interface VerificationTransport { onDone: (() -> Unit)?) /** + * @param supportedMethods list of supported method by this client + * @param localId a local Id + * @param otherUserId the user id to send the verification request to + * @param roomId a room Id to use to send verification message + * @param toDevices list of device Ids * @param callback will be called with eventId and ValidVerificationInfoRequest in case of success */ fun sendVerificationRequest(supportedMethods: List, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadEventsHelper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadEventsHelper.kt index db3647c3fa..5db859bce2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadEventsHelper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadEventsHelper.kt @@ -96,7 +96,9 @@ internal fun EventEntity.markEventAsRoot( /** * Count the number of threads for the provided root thread eventId, and finds the latest event message. * Note: Redactions are handled by RedactionEventProcessor. + * @param realm the realm database * @param rootThreadEventId The root eventId that will find the number of threads + * @param chunkEntity the chunk entity * @return A ThreadSummary containing the counted threads and the latest event message */ internal fun EventEntity.threadSummaryInThread(realm: Realm, rootThreadEventId: String, chunkEntity: ChunkEntity?): Summary { @@ -184,6 +186,7 @@ private fun findLatestSortedChunkEvent(chunk: ChunkEntity, rootThreadEventId: St /** * Find all TimelineEventEntity that are root threads for the specified room. + * @param realm the realm instance * @param roomId The room that all stored root threads will be returned */ internal fun TimelineEventEntity.Companion.findAllThreadsForRoomId(realm: Realm, roomId: String): RealmQuery = @@ -218,6 +221,7 @@ internal fun List.mapEventsWithEdition(realm: Realm, roomId: Stri /** * Returns a list of all the marked unread threads that exists for the specified room. + * @param realm the realm instance * @param roomId The roomId that the user is currently in */ internal fun TimelineEventEntity.Companion.findAllLocalThreadNotificationsForRoomId(realm: Realm, roomId: String): RealmQuery = @@ -232,6 +236,7 @@ internal fun TimelineEventEntity.Companion.findAllLocalThreadNotificationsForRoo /** * Returns whether or not the given user is participating in a current thread. + * @param realm the realm instance * @param roomId the room that the thread exists * @param rootThreadEventId the thread that the search will be done * @param senderId the user that will try to find participation @@ -247,6 +252,7 @@ internal fun TimelineEventEntity.Companion.isUserParticipatingInThread(realm: Re /** * Returns whether or not the given user is mentioned in a current thread. + * @param realm the realm instance * @param roomId the room that the thread exists * @param rootThreadEventId the thread that the search will be done * @param userId the user that will try to find if there is a mention diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadSummaryHelper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadSummaryHelper.kt index 3bf574c207..5b4fe287cb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadSummaryHelper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadSummaryHelper.kt @@ -303,6 +303,7 @@ private fun getLatestEvent(rootThreadEvent: Event): Event? { /** * Find all ThreadSummaryEntity for the specified roomId, sorted by origin server. * note: Sorting cannot be provided by server, so we have to use that unstable property. + * @param realm the realm instance * @param roomId The id of the room */ internal fun ThreadSummaryEntity.Companion.findAllThreadsForRoomId(realm: Realm, roomId: String): RealmQuery = diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/Request.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/Request.kt index 695e7525af..87a98e03f6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/Request.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/Request.kt @@ -32,6 +32,7 @@ import java.io.IOException * Execute a request from the requestBlock and handle some of the Exception it could generate * Ref: https://github.com/matrix-org/matrix-js-sdk/blob/develop/src/scheduler.js#L138-L175 * + * @param DATA type of data return by the [requestBlock] * @param globalErrorReceiver will be use to notify error such as invalid token error. See [GlobalError] * @param canRetry if set to true, the request will be executed again in case of error, after a delay * @param maxDelayBeforeRetry the max delay to wait before a retry. Note that in the case of a 429, if the provided delay exceeds this value, the error will diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/RuntimeJsonAdapterFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/RuntimeJsonAdapterFactory.kt index 40d174ee2d..b5e5799f38 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/RuntimeJsonAdapterFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/RuntimeJsonAdapterFactory.kt @@ -119,9 +119,11 @@ internal class RuntimeJsonAdapterFactory( companion object { /** + * @param T the generic type to pass to [RuntimeJsonAdapterFactory] * @param baseType The base type for which this factory will create adapters. Cannot be Object. * @param labelKey The key in the JSON object whose value determines the type to which to map the * JSON object. + * @param fallbackType */ @CheckReturnValue fun of(baseType: Class, labelKey: String, fallbackType: Class): RuntimeJsonAdapterFactory { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/CertUtil.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/CertUtil.kt index 2ef40fe2a3..e5659fd76b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/CertUtil.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/CertUtil.kt @@ -94,6 +94,7 @@ internal object CertUtil { * Convert the fingerprint to an hexa string. * * @param fingerprint the fingerprint + * @param sep the separator character, default to space * @return the hexa string. */ fun fingerprintToHexString(fingerprint: ByteArray, sep: Char = ' '): String { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManager.kt index ccae5ad14f..e9e864b167 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManager.kt @@ -24,11 +24,9 @@ import javax.net.ssl.X509TrustManager /** * Implements a TrustManager that checks Certificates against an explicit list of known * fingerprints. - */ - -/** - * @param fingerprints Not empty array of SHA256 cert fingerprints - * @param defaultTrustManager Optional trust manager to fall back on if cert does not match + * + * @property fingerprints Not empty array of SHA256 cert fingerprints + * @property defaultTrustManager Optional trust manager to fall back on if cert does not match * any of the fingerprints. Can be null. */ internal class PinnedTrustManager(private val fingerprints: List, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManagerApi24.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManagerApi24.kt index 574f1ef81d..8e8db1ebab 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManagerApi24.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManagerApi24.kt @@ -28,11 +28,9 @@ import javax.net.ssl.X509ExtendedTrustManager /** * Implements a TrustManager that checks Certificates against an explicit list of known * fingerprints. - */ - -/** - * @param fingerprints An array of SHA256 cert fingerprints - * @param defaultTrustManager Optional trust manager to fall back on if cert does not match + * + * @property fingerprints An array of SHA256 cert fingerprints + * @property defaultTrustManager Optional trust manager to fall back on if cert does not match * any of the fingerprints. Can be null. */ @RequiresApi(Build.VERSION_CODES.N) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/directory/DirectoryAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/directory/DirectoryAPI.kt index 19b9130fc4..0db6812609 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/directory/DirectoryAPI.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/directory/DirectoryAPI.kt @@ -55,6 +55,7 @@ internal interface DirectoryAPI { /** * Add alias to the room. * @param roomAlias the room alias. + * @param body the Json body */ @PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "directory/room/{roomAlias}") suspend fun addRoomAlias(@Path("roomAlias") roomAlias: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/openid/OpenIdAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/openid/OpenIdAPI.kt index eb8c841d57..c3caaefdec 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/openid/OpenIdAPI.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/openid/OpenIdAPI.kt @@ -32,6 +32,7 @@ internal interface OpenIdAPI { * Ref: https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-user-userid-openid-request-token * * @param userId the user id + * @param body an empty json body */ @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "user/{userId}/openid/request_token") suspend fun openIdToken(@Path("userId") userId: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/PushRulesApi.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/PushRulesApi.kt index 40b4ee269a..93def22043 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/PushRulesApi.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/PushRulesApi.kt @@ -35,7 +35,7 @@ internal interface PushRulesApi { * * @param kind the notification kind (sender, room...) * @param ruleId the ruleId - * @param enable the new enable status + * @param enabledBody the new enable status */ @PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "pushrules/global/{kind}/{ruleId}/enabled") suspend fun updateEnableRuleStatus(@Path("kind") kind: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt index c44f88b93d..3efeef7688 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt @@ -364,6 +364,7 @@ internal class EventRelationsAggregationProcessor @Inject constructor( * Check if the edition is on the latest thread event, and update it accordingly. * @param editedEvent The event that will be changed * @param replaceEvent The new event + * @param editions list of edition of event */ private fun handleThreadSummaryEdition(editedEvent: EventEntity?, replaceEvent: TimelineEventEntity?, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt index 72f56ddf68..b3c7f7f058 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt @@ -179,6 +179,7 @@ internal interface RoomAPI { * Invite a user to a room, using a ThreePid * Ref: https://matrix.org/docs/spec/client_server/r0.6.1#id101 * @param roomId Required. The room identifier (not alias) to which to invite the user. + * @param body the Json body */ @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/invite") suspend fun invite3pid(@Path("roomId") roomId: String, @@ -221,8 +222,13 @@ internal interface RoomAPI { /** * Paginate relations for event based in normal topological order. + * @param roomId the room Id + * @param eventId the event Id * @param relationType filter for this relation type * @param eventType filter for this event type + * @param from from token + * @param to to token + * @param limit max number of Event to retrieve */ @GET(NetworkConstants.URI_API_PREFIX_PATH_UNSTABLE + "rooms/{roomId}/relations/{eventId}/{relationType}/{eventType}") suspend fun getRelations(@Path("roomId") roomId: String, @@ -236,7 +242,13 @@ internal interface RoomAPI { /** * Paginate relations for thread events based in normal topological order. + * + * @param roomId the room Id + * @param eventId the event Id * @param relationType filter for this relation type + * @param from from token + * @param to to token + * @param limit max number of Event to retrieve */ @GET(NetworkConstants.URI_API_PREFIX_PATH_UNSTABLE + "rooms/{roomId}/relations/{eventId}/{relationType}") suspend fun getThreadsRelations(@Path("roomId") roomId: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/QueuedTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/QueuedTask.kt index 948786677d..983701857f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/QueuedTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/queue/QueuedTask.kt @@ -21,8 +21,8 @@ import timber.log.Timber import java.util.concurrent.atomic.AtomicInteger /** - * @param queueIdentifier String value to identify a unique Queue - * @param taskIdentifier String value to identify a unique Task. Should be different from queueIdentifier + * @property queueIdentifier String value to identify a unique Queue + * @property taskIdentifier String value to identify a unique Task. Should be different from queueIdentifier */ internal abstract class QueuedTask( val queueIdentifier: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/SpaceApi.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/SpaceApi.kt index db3c9c3f5f..33c3c3929f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/SpaceApi.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/SpaceApi.kt @@ -24,6 +24,7 @@ import retrofit2.http.Query internal interface SpaceApi { /** + * @param spaceId the space Id * @param suggestedOnly Optional. If true, return only child events and rooms where the m.space.child event has suggested: true. * @param limit Optional: a client-defined limit to the maximum number of rooms to return per page. Must be a non-negative integer. * @param maxDepth Optional: The maximum depth in the tree (from the root room) to return. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ThreadsAwarenessHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ThreadsAwarenessHandler.kt index 03e076c217..9beb8333a4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ThreadsAwarenessHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ThreadsAwarenessHandler.kt @@ -206,6 +206,8 @@ internal class ThreadsAwarenessHandler @Inject constructor( /** * Handle for not thread events that we have marked them as root. * Find relations and inject them accordingly + * @param realm the realm instance + * @param roomId the current room Id * @param eventEntity the current eventEntity received * @param event the current event received * @return The content to inject in the roomSyncHandler live events @@ -229,9 +231,12 @@ internal class ThreadsAwarenessHandler @Inject constructor( * This function is responsible to check if there is any event that relates to our current event. * This is useful when we receive an event that relates to a missing parent, so when later we receive the parent * we can update the child as well. + * @param realm the realm instance + * @param roomId the current room Id * @param event the current event that we examine * @param eventBody the current body of the event * @param isFromCache determines whether or not we already know this is root thread event + * @param threadRelation the information about thread * @return The content to inject in the roomSyncHandler live events */ private fun handleEventsThatRelatesTo( @@ -291,9 +296,12 @@ internal class ThreadsAwarenessHandler @Inject constructor( } /** - * Injecting $eventToInject decrypted content as a reply to $event. - * @param eventToInject the event that will inject + * Injecting [eventToInject] decrypted content as a reply to event. + * @param roomId the room id * @param eventBody the actual event body + * @param eventToInject the event that will inject + * @param eventToInjectBody the event body to inject + * @param threadRelation the information about thread * @return The final content with the injected event */ private fun injectEvent(roomId: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetPostAPIMediator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetPostAPIMediator.kt index 1da6827916..5abc806823 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetPostAPIMediator.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetPostAPIMediator.kt @@ -116,6 +116,8 @@ internal class DefaultWidgetPostAPIMediator @Inject constructor(private val mosh /** * Send an object response. * + * @param T the Json type + * @param type the type * @param response the response * @param eventData the modular data */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetsAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetsAPI.kt index b871a317c8..97b40e545e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetsAPI.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetsAPI.kt @@ -27,6 +27,7 @@ internal interface WidgetsAPI { * Register to the server. * * @param body the body content (Ref: https://github.com/matrix-org/matrix-doc/pull/1961) + * @param version the widget API version */ @POST("register") suspend fun register(@Body body: OpenIdToken, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/task/CoroutineSequencer.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/task/CoroutineSequencer.kt index 80081e3186..dd4c5e7623 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/task/CoroutineSequencer.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/task/CoroutineSequencer.kt @@ -24,6 +24,7 @@ import kotlinx.coroutines.sync.withPermit */ internal interface CoroutineSequencer { /** + * @param T generic type * @param block the suspendable block to execute * @return the result of the block */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/JsonCanonicalizer.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/JsonCanonicalizer.kt index 94aa238789..c50b7fe675 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/JsonCanonicalizer.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/JsonCanonicalizer.kt @@ -53,7 +53,7 @@ internal object JsonCanonicalizer { /** * Canonicalize a JSON element. * - * @param src the src + * @param any the src * @return the canonicalize element */ private fun canonicalizeRecursive(any: Any): String { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/wellknown/GetWellknownTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/wellknown/GetWellknownTask.kt index c2e9b4e731..31549155d3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/wellknown/GetWellknownTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/wellknown/GetWellknownTask.kt @@ -76,6 +76,7 @@ internal class DefaultGetWellknownTask @Inject constructor( * - return action and .well-known data * * @param domain homeserver domain, deduced from mx userId (ex: "matrix.org" from userId "@user:matrix.org") + * @param client Http client to perform the request */ private suspend fun findClientConfig(domain: String, client: OkHttpClient): WellknownResult { val wellKnownAPI = retrofitFactory.create(client, "https://dummy.org") diff --git a/vector/src/main/java/im/vector/app/core/dialogs/UnrecognizedCertificateDialog.kt b/vector/src/main/java/im/vector/app/core/dialogs/UnrecognizedCertificateDialog.kt index c43b2e4f09..913b69605a 100644 --- a/vector/src/main/java/im/vector/app/core/dialogs/UnrecognizedCertificateDialog.kt +++ b/vector/src/main/java/im/vector/app/core/dialogs/UnrecognizedCertificateDialog.kt @@ -39,6 +39,7 @@ class UnrecognizedCertificateDialog @Inject constructor( * Display a certificate dialog box, asking the user about an unknown certificate * To use when user is currently logged in. * + * @param activity the Android activity * @param unrecognizedFingerprint the fingerprint for the unknown certificate * @param callback callback to fire when the user makes a decision */ @@ -80,9 +81,13 @@ class UnrecognizedCertificateDialog @Inject constructor( /** * Display a certificate dialog box, asking the user about an unknown certificate. * + * @param activity the Activity * @param unrecognizedFingerprint the fingerprint for the unknown certificate * @param existing the current session already exist, so it mean that something has changed server side * @param callback callback to fire when the user makes a decision + * @param userId the matrix userId + * @param homeServerUrl the homeserver url + * @param homeServerConnectionConfigHasFingerprints true if the homeServerConnectionConfig has fingerprint */ private fun internalShow(activity: Activity, unrecognizedFingerprint: Fingerprint, diff --git a/vector/src/main/java/im/vector/app/core/intent/ExternalIntentData.kt b/vector/src/main/java/im/vector/app/core/intent/ExternalIntentData.kt index 142a7a6782..4d74520095 100644 --- a/vector/src/main/java/im/vector/app/core/intent/ExternalIntentData.kt +++ b/vector/src/main/java/im/vector/app/core/intent/ExternalIntentData.kt @@ -29,9 +29,11 @@ sealed class ExternalIntentData { /** * Constructor for a text message. * - * @param text the text - * @param htmlText the HTML text - * @param format the formatted text format + * @property text the text + * @property htmlText the HTML text + * @property format the formatted text format + * @property clipDataItem the ClipData + * @property mimeType the mimetype */ data class IntentDataText( val text: CharSequence? = null, @@ -52,8 +54,8 @@ sealed class ExternalIntentData { /** * Constructor from a media Uri/. * - * @param uri the media uri - * @param filename the media file name + * @property uri the media uri + * @property filename the media file name */ data class IntentDataUri( val uri: Uri, diff --git a/vector/src/main/java/im/vector/app/core/intent/VectorMimeType.kt b/vector/src/main/java/im/vector/app/core/intent/VectorMimeType.kt index e68b5e1b07..38e304e1ce 100644 --- a/vector/src/main/java/im/vector/app/core/intent/VectorMimeType.kt +++ b/vector/src/main/java/im/vector/app/core/intent/VectorMimeType.kt @@ -27,6 +27,7 @@ import java.util.Locale * Returns the mimetype from a uri. * * @param context the context + * @param uri the uri * @return the mimetype */ fun getMimeTypeFromUri(context: Context, uri: Uri): String? { diff --git a/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt b/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt index dad7f26560..bea29195c9 100644 --- a/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt +++ b/vector/src/main/java/im/vector/app/core/preference/PushRulePreference.kt @@ -45,7 +45,7 @@ class PushRulePreference : VectorPreference { /** * Update the notification index. * - * @param pushRule + * @param notificationIndex the new notification index */ fun setIndex(notificationIndex: NotificationIndex?) { index = notificationIndex diff --git a/vector/src/main/java/im/vector/app/core/ui/views/KeysBackupBanner.kt b/vector/src/main/java/im/vector/app/core/ui/views/KeysBackupBanner.kt index f2ea79984e..80603aa3bf 100755 --- a/vector/src/main/java/im/vector/app/core/ui/views/KeysBackupBanner.kt +++ b/vector/src/main/java/im/vector/app/core/ui/views/KeysBackupBanner.kt @@ -54,6 +54,7 @@ class KeysBackupBanner @JvmOverloads constructor( * This methods is responsible for rendering the view according to the newState. * * @param newState the newState representing the view + * @param force true to force the rendering of the view */ fun render(newState: State, force: Boolean = false) { if (newState == state && !force) { diff --git a/vector/src/main/java/im/vector/app/core/utils/RingtoneUtils.kt b/vector/src/main/java/im/vector/app/core/utils/RingtoneUtils.kt index a0fd3addac..bbed2f6000 100644 --- a/vector/src/main/java/im/vector/app/core/utils/RingtoneUtils.kt +++ b/vector/src/main/java/im/vector/app/core/utils/RingtoneUtils.kt @@ -90,6 +90,7 @@ fun getCallRingtoneName(context: Context): String? { /** * Sets the selected ringtone for riot calls. * + * @param context Android context * @param ringtoneUri * @see Ringtone */ diff --git a/vector/src/main/java/im/vector/app/core/utils/SystemUtils.kt b/vector/src/main/java/im/vector/app/core/utils/SystemUtils.kt index 18a467d8d0..2463c39b71 100644 --- a/vector/src/main/java/im/vector/app/core/utils/SystemUtils.kt +++ b/vector/src/main/java/im/vector/app/core/utils/SystemUtils.kt @@ -83,6 +83,8 @@ fun requestDisablingBatteryOptimization(activity: Activity, activityResultLaunch * * @param context the context * @param text the text to copy + * @param showToast true to also show a Toast to the user + * @param toastMessage content of the toast message as a String resource */ fun copyToClipboard(context: Context, text: CharSequence, showToast: Boolean = true, @StringRes toastMessage: Int = R.string.copied_to_clipboard) { val clipboard = context.getSystemService()!! diff --git a/vector/src/main/java/im/vector/app/core/utils/TemporaryStore.kt b/vector/src/main/java/im/vector/app/core/utils/TemporaryStore.kt index fb386e0876..bd1e396126 100644 --- a/vector/src/main/java/im/vector/app/core/utils/TemporaryStore.kt +++ b/vector/src/main/java/im/vector/app/core/utils/TemporaryStore.kt @@ -23,7 +23,8 @@ const val THREE_MINUTES = 3 * 60_000L /** * Store an object T for a specific period of time. - * @param delay delay to keep the data, in millis + * @param T type of the data to store + * @property delay delay to keep the data, in millis */ open class TemporaryStore(private val delay: Long = THREE_MINUTES) { diff --git a/vector/src/main/java/im/vector/app/features/call/audio/CallAudioManager.kt b/vector/src/main/java/im/vector/app/features/call/audio/CallAudioManager.kt index d4793640d3..6577d0374d 100644 --- a/vector/src/main/java/im/vector/app/features/call/audio/CallAudioManager.kt +++ b/vector/src/main/java/im/vector/app/features/call/audio/CallAudioManager.kt @@ -122,6 +122,7 @@ class CallAudioManager(private val context: Context, val configChange: (() -> Un * Updates the audio route for the given mode. * * @param mode the audio mode to be used when computing the audio route. + * @param force true to force setting the audio route * @return `true` if the audio route was updated successfully; * `false`, otherwise. */ diff --git a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt index 49e35687f4..3723e3ce3e 100644 --- a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt @@ -31,6 +31,7 @@ class CommandParser @Inject constructor() { * Convert the text message into a Slash command. * * @param textMessage the text message + * @param isInThreadTimeline true if the user is currently typing in a thread * @return a parsed slash command (ok or error) */ fun parseSlashCommand(textMessage: CharSequence, isInThreadTimeline: Boolean): ParsedCommand { @@ -412,8 +413,8 @@ class CommandParser @Inject constructor() { /** * Checks whether or not the current command is not supported by threads. - * @param slashCommand the slash command that will be checked * @param isInThreadTimeline if its true we are in a thread timeline + * @param slashCommand the slash command that will be checked * @return The command that is not supported */ private fun getNotSupportedByThreads(isInThreadTimeline: Boolean, slashCommand: String): Command? { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt index aca2aab174..224c1cdbea 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt @@ -55,8 +55,15 @@ class MergedHeaderItemFactory @Inject constructor(private val activeSessionHolde private val mergeItemCollapseStates = HashMap() /** + * @param event the main timeline event * @param nextEvent is an older event than event * @param items all known items, sorted from newer event to oldest event + * @param partialState partial state data + * @param addDaySeparator true to add a day separator + * @param currentPosition the current position + * @param eventIdToHighlight if not null the event which has to be highlighted + * @param callback callback for user event + * @param requestModelBuild lambda to let the built Item request a model build when the collapse state is changed */ fun create(event: TimelineEvent, nextEvent: TimelineEvent?, diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineEventVisibilityHelper.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineEventVisibilityHelper.kt index f317eb4f9a..8ca999309a 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineEventVisibilityHelper.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineEventVisibilityHelper.kt @@ -36,6 +36,8 @@ class TimelineEventVisibilityHelper @Inject constructor(private val userPreferen * @param index the index to start computing (inclusive) * @param minSize the minimum number of same type events to have sequentially, otherwise will return an empty list * @param eventIdToHighlight used to compute visibility + * @param rootThreadEventId the root thread event id if in a thread timeline + * @param isFromThreadTimeline true if the timeline is a thread * * @return a list of timeline events which have sequentially the same type following the next direction. */ @@ -86,6 +88,8 @@ class TimelineEventVisibilityHelper @Inject constructor(private val userPreferen * @param index the index to start computing (inclusive) * @param minSize the minimum number of same type events to have sequentially, otherwise will return an empty list * @param eventIdToHighlight used to compute visibility + * @param rootThreadEventId the root thread eventId + * @param isFromThreadTimeline true if the timeline is a thread * * @return a list of timeline events which have sequentially the same type following the prev direction. */ @@ -107,6 +111,7 @@ class TimelineEventVisibilityHelper @Inject constructor(private val userPreferen /** * @param timelineEvent the event to check for visibility * @param highlightedEventId can be checked to force visibility to true + * @param isFromThreadTimeline true if the timeline is a thread * @param rootThreadEventId if this param is null it means we are in the original timeline * @return true if the event should be shown in the timeline. */ diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlView.kt index 3ae6a1fea5..69455c767e 100755 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlView.kt @@ -59,6 +59,8 @@ class PreviewUrlView @JvmOverloads constructor( * This methods is responsible for rendering the view according to the newState. * * @param newState the newState representing the view + * @param imageContentRenderer the tool to render the image + * @param force true to force refresh */ fun render(newState: PreviewUrlUiState, imageContentRenderer: ImageContentRenderer, diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt index d03fcadcfa..abfca1a64c 100755 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt @@ -233,6 +233,7 @@ class NotificationUtils @Inject constructor( * Build a polling thread listener notification. * * @param subTitleResId subtitle string resource Id of the notification + * @param withProgress true to show indeterminate progress on the notification * @return the polling thread listener notification */ @SuppressLint("NewApi") @@ -298,10 +299,8 @@ class NotificationUtils @Inject constructor( * Build an incoming call notification. * This notification starts the VectorHomeActivity which is in charge of centralizing the incoming call flow. * - * @param isVideo true if this is a video call, false for voice call - * @param roomName the room name in which the call is pending. - * @param matrixId the matrix id - * @param callId the call id. + * @param call information about the call + * @param title title of the notification * @param fromBg true if the app is in background when posting the notification * @return the call notification. */ @@ -430,11 +429,8 @@ class NotificationUtils @Inject constructor( /** * Build a pending call notification. * - * @param isVideo true if this is a video call, false for voice call - * @param roomName the room name in which the call is pending. - * @param roomId the room Id - * @param matrixId the matrix id - * @param callId the call id. + * @param call information about the call + * @param title title of the notification * @return the call notification. */ @SuppressLint("NewApi") diff --git a/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt b/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt index b7ce7ffdb4..9f0d5ff774 100755 --- a/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt +++ b/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt @@ -162,6 +162,9 @@ class BugReporter @Inject constructor( * @param withKeyRequestHistory true to include the crash logs * @param withScreenshot true to include the screenshot * @param theBugDescription the bug description + * @param serverVersion version of the server + * @param canContact true if the user opt in to be contacted directly + * @param customFields fields which will be sent with the report * @param listener the listener */ @SuppressLint("StaticFieldLeak") @@ -287,7 +290,8 @@ class BugReporter @Inject constructor( .addFormDataPart("app_language", VectorLocale.applicationLocale.toString()) .addFormDataPart("default_app_language", systemLocaleProvider.getSystemLocale().toString()) .addFormDataPart("theme", ThemeUtils.getApplicationTheme(context)) - .addFormDataPart("server_version", serverVersion).apply { + .addFormDataPart("server_version", serverVersion) + .apply { customFields?.forEach { (name, value) -> addFormDataPart(name, value) } diff --git a/vector/src/main/java/im/vector/app/features/settings/FontScale.kt b/vector/src/main/java/im/vector/app/features/settings/FontScale.kt index c4ea730afd..a1acef7d35 100644 --- a/vector/src/main/java/im/vector/app/features/settings/FontScale.kt +++ b/vector/src/main/java/im/vector/app/features/settings/FontScale.kt @@ -78,6 +78,7 @@ object FontScale { /** * Store the font scale value. * + * @param context the Android context * @param fontScaleValue the font scale value to store */ private fun saveFontScaleValue(context: Context, fontScaleValue: FontScaleValue) { diff --git a/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt b/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt index 3b1e8240fa..160aef27a9 100644 --- a/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt +++ b/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt @@ -108,6 +108,7 @@ object ThemeUtils { /** * Update the application theme. * + * @param context the Android context * @param aTheme the new theme */ fun setApplicationTheme(context: Context, aTheme: String) { @@ -126,9 +127,11 @@ object ThemeUtils { } /** - * Set the activity theme according to the selected one. + * Set the activity theme according to the selected one. Default is Light, so if this is the current + * theme, the theme is not changed. * * @param activity the activity + * @param otherThemes themes to apply for dark and black theme */ fun setActivityTheme(activity: Activity, otherThemes: ActivityOtherThemes) { when (getApplicationTheme(activity)) { diff --git a/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt b/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt index 3c88ea65a3..fc73e71b51 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt @@ -110,6 +110,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo /** * Retrieve the latest botOptions event. * + * @param widgetPostAPIMediator the post api mediator * @param eventData the modular data */ private fun getBotOptions(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict) { @@ -171,6 +172,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo /** * Provides the membership state. * + * @param widgetPostAPIMediator the post api mediator * @param eventData the modular data */ private fun getMembershipState(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict) { @@ -190,6 +192,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo /** * Request the latest joined room event. * + * @param widgetPostAPIMediator the post api mediator * @param eventData the modular data */ private fun getJoinRules(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict) { @@ -208,6 +211,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo /** * Provide the widgets list. * + * @param widgetPostAPIMediator the post api mediator * @param eventData the modular data */ private fun getWidgets(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict) { @@ -228,6 +232,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo /** * Set a new widget. * + * @param widgetPostAPIMediator the post api mediator * @param eventData the modular data */ private fun setWidget(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict) { @@ -303,6 +308,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo /** * Update the 'plumbing state". * + * @param widgetPostAPIMediator the post api mediator * @param eventData the modular data */ private fun setPlumbingState(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict) { @@ -328,6 +334,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo /** * Update the bot options. * + * @param widgetPostAPIMediator the post api mediator * @param eventData the modular data */ @Suppress("UNCHECKED_CAST") @@ -353,6 +360,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo /** * Update the bot power levels. * + * @param widgetPostAPIMediator the post api mediator * @param eventData the modular data */ private fun setBotPower(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict) { @@ -375,6 +383,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo /** * Invite an user to this room. * + * @param widgetPostAPIMediator the post api mediator * @param eventData the modular data */ private fun inviteUser(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict) { @@ -397,6 +406,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo /** * Provides the number of members in the rooms. * + * @param widgetPostAPIMediator the post api mediator * @param eventData the modular data */ private fun getMembershipCount(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict) { From dae0b66c90ad4f33189798dcaf7a37d5918af8a1 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 18 May 2022 16:09:15 +0200 Subject: [PATCH 047/125] PR review --- .../android/sdk/api/session/crypto/model/MXUsersDevicesMap.kt | 2 +- .../sdk/internal/network/parsing/RuntimeJsonAdapterFactory.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXUsersDevicesMap.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXUsersDevicesMap.kt index c067a53dba..58481d8316 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXUsersDevicesMap.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXUsersDevicesMap.kt @@ -46,7 +46,7 @@ class MXUsersDevicesMap { /** * Provides the object for a device id and a user Id. * - * @param userId the object id + * @param userId the user id * @param deviceId the device id * @return the object */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/RuntimeJsonAdapterFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/RuntimeJsonAdapterFactory.kt index b5e5799f38..dd41b9f6fc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/RuntimeJsonAdapterFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/RuntimeJsonAdapterFactory.kt @@ -123,7 +123,7 @@ internal class RuntimeJsonAdapterFactory( * @param baseType The base type for which this factory will create adapters. Cannot be Object. * @param labelKey The key in the JSON object whose value determines the type to which to map the * JSON object. - * @param fallbackType + * @param fallbackType alternative Type to try in case of the serialization fails */ @CheckReturnValue fun of(baseType: Class, labelKey: String, fallbackType: Class): RuntimeJsonAdapterFactory { From 5b185152c6312c4cf0212b4b7c9c4a38b6066891 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 18 May 2022 16:16:22 +0200 Subject: [PATCH 048/125] Remove non needed extra spaces: add a check --- tools/check/forbidden_strings_in_code.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/check/forbidden_strings_in_code.txt b/tools/check/forbidden_strings_in_code.txt index 7362ff2d10..962a14843d 100755 --- a/tools/check/forbidden_strings_in_code.txt +++ b/tools/check/forbidden_strings_in_code.txt @@ -177,3 +177,6 @@ R\.string\.template_ ### Use the Clock interface, or use `measureTimeMillis` System\.currentTimeMillis\(\)===2 + +### Remove extra space between the name and the description +\* @\w+ \w+ + From f5d0663b06b618e2ca3a55c8c7d5528d20bfb294 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 18 May 2022 16:17:34 +0200 Subject: [PATCH 049/125] Remove non needed extra spaces --- .../android/sdk/common/CommonTestHelper.kt | 28 ++++----- .../auth/data/HomeServerConnectionConfig.kt | 2 +- .../api/session/content/ContentUrlResolver.kt | 10 ++-- .../crypto/keysbackup/KeysBackupService.kt | 14 ++--- .../session/crypto/model/MXUsersDevicesMap.kt | 8 +-- .../session/permalinks/PermalinkService.kt | 2 +- .../sdk/api/session/pushers/PushersService.kt | 10 ++-- .../sdk/api/session/pushrules/rest/RuleSet.kt | 2 +- .../room/powerlevels/PowerLevelsHelper.kt | 2 +- .../session/widgets/WidgetPostAPIMediator.kt | 8 +-- .../internal/crypto/DefaultCryptoService.kt | 44 +++++++------- .../sdk/internal/crypto/DeviceListManager.kt | 12 ++-- .../sdk/internal/crypto/EventDecryptor.kt | 6 +- .../crypto/MXMegolmExportEncryption.kt | 12 ++-- .../sdk/internal/crypto/MXOlmDevice.kt | 52 ++++++++-------- .../sdk/internal/crypto/OlmSessionStore.kt | 2 +- .../internal/crypto/RoomDecryptorProvider.kt | 2 +- .../EnsureOlmSessionsForUsersAction.kt | 2 +- .../actions/MegolmSessionDataImporter.kt | 4 +- .../crypto/actions/MessageEncrypter.kt | 2 +- .../crypto/algorithms/IMXDecrypting.kt | 2 +- .../crypto/algorithms/IMXEncrypting.kt | 4 +- .../algorithms/megolm/MXMegolmEncryption.kt | 6 +- .../crypto/algorithms/olm/MXOlmDecryption.kt | 2 +- .../crypto/algorithms/olm/MXOlmEncryption.kt | 2 +- .../sdk/internal/crypto/api/CryptoApi.kt | 8 +-- .../attachments/MXEncryptedAttachments.kt | 4 +- .../crypto/keysbackup/api/RoomKeysApi.kt | 26 ++++---- .../sdk/internal/crypto/model/MXKey.kt | 2 +- .../internal/crypto/store/IMXCryptoStore.kt | 10 ++-- .../sdk/internal/crypto/tools/HkdfSha256.kt | 2 +- .../riot/HomeServerConnectionConfig.java | 4 +- .../network/ssl/PinnedTrustManager.kt | 2 +- .../network/ssl/PinnedTrustManagerApi24.kt | 2 +- .../sdk/internal/session/filter/FilterApi.kt | 4 +- .../sdk/internal/session/filter/FilterUtil.kt | 2 +- .../internal/session/pushers/PushRulesApi.kt | 12 ++-- .../sdk/internal/session/room/RoomAPI.kt | 60 +++++++++---------- .../session/sync/handler/CryptoSyncHandler.kt | 2 +- .../user/accountdata/AccountDataAPI.kt | 2 +- .../widgets/DefaultWidgetPostAPIMediator.kt | 14 ++--- .../android/sdk/internal/util/StringUtils.kt | 2 +- .../java/im/vector/app/push/fcm/FcmHelper.kt | 2 +- .../java/im/vector/app/push/fcm/FcmHelper.kt | 2 +- .../dialogs/UnrecognizedCertificateDialog.kt | 6 +- .../app/core/intent/ExternalIntentData.kt | 6 +- .../im/vector/app/core/resources/Resource.kt | 4 +- .../java/im/vector/app/core/utils/Dialogs.kt | 2 +- .../utils/EvenBetterLinkMovementMethod.kt | 6 +- .../core/utils/ExternalApplicationsUtil.kt | 8 +-- .../vector/app/core/utils/PermissionsTools.kt | 6 +- .../im/vector/app/core/utils/SystemUtils.kt | 2 +- .../app/features/command/CommandParser.kt | 2 +- .../VectorActivityLifecycleCallbacks.kt | 2 +- .../app/features/rageshake/BugReporter.kt | 18 +++--- .../rageshake/BugReporterMultipartBody.java | 4 +- .../VectorUncaughtExceptionHandler.kt | 2 +- .../app/features/settings/VectorLocale.kt | 4 +- .../features/settings/VectorPreferences.kt | 6 +- .../vector/app/features/themes/ThemeUtils.kt | 8 +-- .../features/webview/WebViewEventListener.kt | 8 +-- 61 files changed, 248 insertions(+), 248 deletions(-) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt index 6678b109a6..96ea99d92f 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt @@ -96,7 +96,7 @@ class CommonTestHelper(context: Context) { /** * This methods init the event stream and check for initial sync * - * @param session the session to sync + * @param session the session to sync */ fun syncSession(session: Session, timeout: Long = TestConstants.timeOutMillis * 10) { val lock = CountDownLatch(1) @@ -119,7 +119,7 @@ class CommonTestHelper(context: Context) { /** * This methods clear the cache and waits for initialSync * - * @param session the session to sync + * @param session the session to sync */ fun clearCacheAndSync(session: Session, timeout: Long = TestConstants.timeOutMillis) { waitWithLatch(timeout) { latch -> @@ -142,8 +142,8 @@ class CommonTestHelper(context: Context) { /** * Sends text messages in a room * - * @param room the room where to send the messages - * @param message the message to send + * @param room the room where to send the messages + * @param message the message to send * @param nbOfMessages the number of time the message will be sent */ fun sendTextMessage(room: Room, message: String, nbOfMessages: Int, timeout: Long = TestConstants.timeOutMillis): List { @@ -207,8 +207,8 @@ class CommonTestHelper(context: Context) { /** * Reply in a thread - * @param room the room where to send the messages - * @param message the message to send + * @param room the room where to send the messages + * @param message the message to send * @param numberOfMessages the number of time the message will be sent */ fun replyInThreadMessage( @@ -232,8 +232,8 @@ class CommonTestHelper(context: Context) { * Creates a unique account * * @param userNamePrefix the user name prefix - * @param password the password - * @param testParams test params about the session + * @param password the password + * @param testParams test params about the session * @return the session associated with the newly created account */ private fun createAccount(userNamePrefix: String, @@ -251,8 +251,8 @@ class CommonTestHelper(context: Context) { /** * Logs into an existing account * - * @param userId the userId to log in - * @param password the password to log in + * @param userId the userId to log in + * @param password the password to log in * @param testParams test params about the session * @return the session associated with the existing account */ @@ -267,8 +267,8 @@ class CommonTestHelper(context: Context) { /** * Create an account and a dedicated session * - * @param userName the account username - * @param password the password + * @param userName the account username + * @param password the password * @param sessionTestParams parameters for the test */ private fun createAccountAndSync(userName: String, @@ -305,8 +305,8 @@ class CommonTestHelper(context: Context) { /** * Start an account login * - * @param userName the account username - * @param password the password + * @param userName the account username + * @param password the password * @param sessionTestParams session test params */ private fun logAccountAndSync(userName: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/HomeServerConnectionConfig.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/HomeServerConnectionConfig.kt index c2c1f043bb..c3f0221bb8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/HomeServerConnectionConfig.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/HomeServerConnectionConfig.kt @@ -195,7 +195,7 @@ data class HomeServerConnectionConfig( * - https://www.ssi.gouv.fr/uploads/2017/07/anssi-guide-recommandations_de_securite_relatives_a_tls-v1.2.pdf * - https://developer.android.com/reference/javax/net/ssl/SSLEngine * - * @param tlsLimitations true to use Tls limitations + * @param tlsLimitations true to use Tls limitations * @param enableCompatibilityMode set to true for Android < 20 * @return this builder */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/content/ContentUrlResolver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/content/ContentUrlResolver.kt index e59e676ed9..20f977e86e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/content/ContentUrlResolver.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/content/ContentUrlResolver.kt @@ -36,7 +36,7 @@ interface ContentUrlResolver { /** * Get the actual URL for accessing the full-size image of a Matrix media content URI. * - * @param contentUrl the Matrix media content URI (in the form of "mxc://..."). + * @param contentUrl the Matrix media content URI (in the form of "mxc://..."). * @return the URL to access the described resource, or null if the url is invalid. */ fun resolveFullSize(contentUrl: String?): String? @@ -44,7 +44,7 @@ interface ContentUrlResolver { /** * Get the ResolvedMethod to download a URL. * - * @param contentUrl the Matrix media content URI (in the form of "mxc://..."). + * @param contentUrl the Matrix media content URI (in the form of "mxc://..."). * @param elementToDecrypt Encryption data may be required if you use a content scanner * @return the Method to access resource, or null if invalid */ @@ -54,9 +54,9 @@ interface ContentUrlResolver { * Get the actual URL for accessing the thumbnail image of a given Matrix media content URI. * * @param contentUrl the Matrix media content URI (in the form of "mxc://..."). - * @param width the desired width - * @param height the desired height - * @param method the desired method (METHOD_CROP or METHOD_SCALE) + * @param width the desired width + * @param height the desired height + * @param method the desired method (METHOD_CROP or METHOD_SCALE) * @return the URL to access the described resource, or null if the url is invalid. */ fun resolveThumbnail(contentUrl: String?, width: Int, height: Int, method: ThumbnailMethod): String? diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt index 0d40490c3e..9029c7f8a3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt @@ -34,7 +34,7 @@ interface KeysBackupService { * Create a new keys backup version and enable it, using the information return from [prepareKeysBackupVersion]. * * @param keysBackupCreationInfo the info object from [prepareKeysBackupVersion]. - * @param callback Asynchronous callback + * @param callback Asynchronous callback */ fun createKeysBackupVersion(keysBackupCreationInfo: MegolmBackupCreationInfo, callback: MatrixCallback) @@ -122,7 +122,7 @@ interface KeysBackupService { * Delete a keys backup version. It will delete all backed up keys on the server, and the backup itself. * If we are backing up to this version. Backup will be stopped. * - * @param version the backup version to delete. + * @param version the backup version to delete. * @param callback Asynchronous callback */ fun deleteBackup(version: String, @@ -173,12 +173,12 @@ interface KeysBackupService { /** * Restore a backup with a recovery key from a given backup version stored on the homeserver. * - * @param keysVersionResult the backup version to restore from. - * @param recoveryKey the recovery key to decrypt the retrieved backup. - * @param roomId the id of the room to get backup data from. - * @param sessionId the id of the session to restore. + * @param keysVersionResult the backup version to restore from. + * @param recoveryKey the recovery key to decrypt the retrieved backup. + * @param roomId the id of the room to get backup data from. + * @param sessionId the id of the session to restore. * @param stepProgressListener the step progress listener - * @param callback Callback. It provides the number of found keys and the number of successfully imported keys. + * @param callback Callback. It provides the number of found keys and the number of successfully imported keys. */ fun restoreKeysWithRecoveryKey(keysVersionResult: KeysVersionResult, recoveryKey: String, roomId: String?, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXUsersDevicesMap.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXUsersDevicesMap.kt index 58481d8316..736ae6b318 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXUsersDevicesMap.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXUsersDevicesMap.kt @@ -46,7 +46,7 @@ class MXUsersDevicesMap { /** * Provides the object for a device id and a user Id. * - * @param userId the user id + * @param userId the user id * @param deviceId the device id * @return the object */ @@ -59,9 +59,9 @@ class MXUsersDevicesMap { /** * Set an object for a dedicated user Id and device Id. * - * @param userId the user Id + * @param userId the user Id * @param deviceId the device id - * @param o the object to set + * @param o the object to set */ fun setObject(userId: String?, deviceId: String?, o: E?) { if (null != o && userId?.isNotBlank() == true && deviceId?.isNotBlank() == true) { @@ -73,7 +73,7 @@ class MXUsersDevicesMap { /** * Defines the objects map for a user Id. * - * @param userId the user id + * @param userId the user id * @param objectsPerDevices the objects maps */ fun setObjects(userId: String?, objectsPerDevices: Map?) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt index 7c4c570c1e..1788bf7bd2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt @@ -71,7 +71,7 @@ interface PermalinkService { * Creates a permalink for an event. If you have an event you can use [createPermalink] * Ex: "https://matrix.to/#/!nbzmcXAqpxBXjAdgoX:matrix.org/$1531497316352799BevdV:matrix.org?via=matrix.org" * - * @param roomId the id of the room + * @param roomId the id of the room * @param eventId the id of the event * @param forceMatrixTo whether we should force using matrix.to base URL * diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt index 5f9857eb2f..5cb7857021 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt @@ -47,12 +47,12 @@ interface PushersService { * Add a new Email pusher. * Ref: https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-pushers-set * - * @param email The email address to send notifications to. - * @param lang The preferred language for receiving notifications (e.g. "en" or "en-US"). - * @param emailBranding The branding placeholder to include in the email communications. - * @param appDisplayName A human readable string that will allow the user to identify what application owns this pusher. + * @param email The email address to send notifications to. + * @param lang The preferred language for receiving notifications (e.g. "en" or "en-US"). + * @param emailBranding The branding placeholder to include in the email communications. + * @param appDisplayName A human readable string that will allow the user to identify what application owns this pusher. * @param deviceDisplayName A human readable string that will allow the user to identify what device owns this pusher. - * @param append If true, the homeserver should add another pusher with the given pushkey and App ID in addition + * @param append If true, the homeserver should add another pusher with the given pushkey and App ID in addition * to any others with different user IDs. Otherwise, the homeserver must remove any other pushers * with the same App ID and pushkey for different users. Typically We always want to append for * email pushers since we don't want to stop other accounts notifying to the same email address. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/rest/RuleSet.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/rest/RuleSet.kt index 5bf42b8252..9498ed002c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/rest/RuleSet.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushrules/rest/RuleSet.kt @@ -67,7 +67,7 @@ data class RuleSet( /** * Find a rule from its rule Id. * - * @param rules the rules list. + * @param rules the rules list. * @param ruleId the rule Id. * @return the bing rule if it exists, else null. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/PowerLevelsHelper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/PowerLevelsHelper.kt index 165a912b7f..36993074aa 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/PowerLevelsHelper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/powerlevels/PowerLevelsHelper.kt @@ -58,7 +58,7 @@ class PowerLevelsHelper(private val powerLevelsContent: PowerLevelsContent) { /** * Tell if an user can send an event of a certain type. * - * @param userId the id of the user to check for. + * @param userId the id of the user to check for. * @param isState true if the event is a state event (ie. state key is not null) * @param eventType the event type to check for * @return true if the user can send this type of event diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/widgets/WidgetPostAPIMediator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/widgets/WidgetPostAPIMediator.kt index 3d134b4775..0c224ff17c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/widgets/WidgetPostAPIMediator.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/widgets/WidgetPostAPIMediator.kt @@ -49,7 +49,7 @@ interface WidgetPostAPIMediator { /** * Send a boolean response. * - * @param response the response + * @param response the response * @param eventData the modular data */ fun sendBoolResponse(response: Boolean, eventData: JsonDict) @@ -57,7 +57,7 @@ interface WidgetPostAPIMediator { /** * Send an integer response. * - * @param response the response + * @param response the response * @param eventData the modular data */ fun sendIntegerResponse(response: Int, eventData: JsonDict) @@ -67,7 +67,7 @@ interface WidgetPostAPIMediator { * * @param T the generic type * @param type the type of the response - * @param response the response + * @param response the response * @param eventData the modular data */ fun sendObjectResponse(type: Type, response: T?, eventData: JsonDict) @@ -82,7 +82,7 @@ interface WidgetPostAPIMediator { /** * Send an error. * - * @param message the error message + * @param message the error message * @param eventData the modular data */ fun sendError(message: String, eventData: JsonDict) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 2c8db7e1e4..824478f1d3 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -508,7 +508,7 @@ internal class DefaultCryptoService @Inject constructor( /** * Provides the device information for a user id and a device Id. * - * @param userId the user id + * @param userId the user id * @param deviceId the device id */ override fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? { @@ -538,7 +538,7 @@ internal class DefaultCryptoService @Inject constructor( /** * Set the devices as known. * - * @param devices the devices. Note that the verified member of the devices in this list will not be updated by this method. + * @param devices the devices. Note that the verified member of the devices in this list will not be updated by this method. * @param callback the asynchronous callback */ override fun setDevicesKnown(devices: List, callback: MatrixCallback?) { @@ -576,8 +576,8 @@ internal class DefaultCryptoService @Inject constructor( * Update the blocked/verified state of the given device. * * @param trustLevel the new trust level - * @param userId the owner of the device - * @param deviceId the unique identifier for the device. + * @param userId the owner of the device + * @param deviceId the unique identifier for the device. */ override fun setDeviceVerification(trustLevel: DeviceTrustLevel, userId: String, deviceId: String) { setDeviceVerificationAction.handle(trustLevel, userId, deviceId) @@ -586,10 +586,10 @@ internal class DefaultCryptoService @Inject constructor( /** * Configure a room to use encryption. * - * @param roomId the room id to enable encryption in. - * @param algorithm the encryption config for the room. + * @param roomId the room id to enable encryption in. + * @param algorithm the encryption config for the room. * @param inhibitDeviceQuery true to suppress device list query for users in the room (for now) - * @param membersId list of members to start tracking their devices + * @param membersId list of members to start tracking their devices * @return true if the operation succeeds. */ private suspend fun setEncryptionInRoom(roomId: String, @@ -687,9 +687,9 @@ internal class DefaultCryptoService @Inject constructor( * Encrypt an event content according to the configuration of the room. * * @param eventContent the content of the event. - * @param eventType the type of the event. - * @param roomId the room identifier the event will be sent. - * @param callback the asynchronous callback + * @param eventType the type of the event. + * @param roomId the room identifier the event will be sent. + * @param callback the asynchronous callback */ override fun encryptEventContent(eventContent: Content, eventType: String, @@ -742,7 +742,7 @@ internal class DefaultCryptoService @Inject constructor( /** * Decrypt an event. * - * @param event the raw event. + * @param event the raw event. * @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack. * @return the MXEventDecryptionResult data, or throw in case of error */ @@ -754,7 +754,7 @@ internal class DefaultCryptoService @Inject constructor( /** * Decrypt an event asynchronously. * - * @param event the raw event. + * @param event the raw event. * @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack. * @param callback the callback to return data or null */ @@ -765,7 +765,7 @@ internal class DefaultCryptoService @Inject constructor( /** * Decrypt an event. * - * @param event the raw event. + * @param event the raw event. * @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack. * @return the MXEventDecryptionResult data, or null in case of error */ @@ -998,7 +998,7 @@ internal class DefaultCryptoService @Inject constructor( /** * Export the crypto keys. * - * @param password the password + * @param password the password * @param anIterationCount the encryption iteration count (0 means no encryption) */ private suspend fun exportRoomKeys(password: String, anIterationCount: Int): ByteArray { @@ -1017,8 +1017,8 @@ internal class DefaultCryptoService @Inject constructor( /** * Import the room keys. * - * @param roomKeysAsArray the room keys as array. - * @param password the password + * @param roomKeysAsArray the room keys as array. + * @param password the password * @param progressListener the progress listener * @return the result ImportRoomKeysResult */ @@ -1068,7 +1068,7 @@ internal class DefaultCryptoService @Inject constructor( * A success means there is no unknown devices. * If there are some unknown devices, a MXCryptoError.UnknownDevice exception is triggered. * - * @param userIds the user ids list + * @param userIds the user ids list * @param callback the asynchronous callback. */ fun checkUnknownDevices(userIds: List, callback: MatrixCallback) { @@ -1091,7 +1091,7 @@ internal class DefaultCryptoService @Inject constructor( * If false, it can still be overridden per-room. * If true, it overrides the per-room settings. * - * @param block true to unilaterally blacklist all + * @param block true to unilaterally blacklist all */ override fun setGlobalBlacklistUnverifiedDevices(block: Boolean) { cryptoStore.setGlobalBlacklistUnverifiedDevices(block) @@ -1131,8 +1131,8 @@ internal class DefaultCryptoService @Inject constructor( /** * Manages the room black-listing for unverified devices. * - * @param roomId the room id - * @param add true to add the room id to the list, false to remove it. + * @param roomId the room id + * @param add true to add the room id to the list, false to remove it. */ private fun setRoomBlacklistUnverifiedDevices(roomId: String, add: Boolean) { val roomIds = cryptoStore.getRoomsListBlacklistUnverifiedDevices().toMutableList() @@ -1151,7 +1151,7 @@ internal class DefaultCryptoService @Inject constructor( /** * Add this room to the ones which don't encrypt messages to unverified devices. * - * @param roomId the room id + * @param roomId the room id */ override fun setRoomBlacklistUnverifiedDevices(roomId: String) { setRoomBlacklistUnverifiedDevices(roomId, true) @@ -1160,7 +1160,7 @@ internal class DefaultCryptoService @Inject constructor( /** * Remove this room to the ones which don't encrypt messages to unverified devices. * - * @param roomId the room id + * @param roomId the room id */ override fun setRoomUnBlacklistUnverifiedDevices(roomId: String) { setRoomBlacklistUnverifiedDevices(roomId, false) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt index cd4e2a6d52..18b815b3d8 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt @@ -170,7 +170,7 @@ internal class DeviceListManager @Inject constructor( * Update the devices list statuses. * * @param changed the user ids list which have new devices - * @param left the user ids list which left a room + * @param left the user ids list which left a room */ fun handleDeviceListsChanges(changed: Collection, left: Collection) { Timber.v("## CRYPTO: handleDeviceListsChanges changed: ${changed.logLimit()} / left: ${left.logLimit()}") @@ -223,7 +223,7 @@ internal class DeviceListManager @Inject constructor( /** * The keys download succeeded. * - * @param userIds the userIds list + * @param userIds the userIds list * @param failures the failure map. */ private fun onKeysDownloadSucceed(userIds: List, failures: Map>?): MXUsersDevicesMap { @@ -276,7 +276,7 @@ internal class DeviceListManager @Inject constructor( * Download the device keys for a list of users and stores the keys in the MXStore. * It must be called in getEncryptingThreadHandler() thread. * - * @param userIds The users to fetch. + * @param userIds The users to fetch. * @param forceDownload Always download the keys even if cached. */ suspend fun downloadKeys(userIds: List?, forceDownload: Boolean): MXUsersDevicesMap { @@ -421,9 +421,9 @@ internal class DeviceListManager @Inject constructor( * Validate device keys. * This method must called on getEncryptingThreadHandler() thread. * - * @param deviceKeys the device keys to validate. - * @param userId the id of the user of the device. - * @param deviceId the id of the device. + * @param deviceKeys the device keys to validate. + * @param userId the id of the user of the device. + * @param deviceId the id of the device. * @param previouslyStoredDeviceKeys the device keys we received before for this device * @return true if succeeds */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt index d6f881211c..cb61bbe1de 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt @@ -72,7 +72,7 @@ internal class EventDecryptor @Inject constructor( /** * Decrypt an event. * - * @param event the raw event. + * @param event the raw event. * @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack. * @return the MXEventDecryptionResult data, or throw in case of error */ @@ -84,7 +84,7 @@ internal class EventDecryptor @Inject constructor( /** * Decrypt an event asynchronously. * - * @param event the raw event. + * @param event the raw event. * @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack. * @param callback the callback to return data or null */ @@ -100,7 +100,7 @@ internal class EventDecryptor @Inject constructor( /** * Decrypt an event. * - * @param event the raw event. + * @param event the raw event. * @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack. * @return the MXEventDecryptionResult data, or null in case of error */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXMegolmExportEncryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXMegolmExportEncryption.kt index 93f92f0bfd..e0d6c25d70 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXMegolmExportEncryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXMegolmExportEncryption.kt @@ -68,7 +68,7 @@ internal object MXMegolmExportEncryption { /** * Decrypt a megolm key file. * - * @param data the data to decrypt + * @param data the data to decrypt * @param password the password. * @return the decrypted output. * @throws Exception the failure reason @@ -138,9 +138,9 @@ internal object MXMegolmExportEncryption { /** * Encrypt a string into the megolm export format. * - * @param data the data to encrypt. - * @param password the password - * @param kdfRounds the iteration count + * @param data the data to encrypt. + * @param password the password + * @param kdfRounds the iteration count * @return the encrypted data * @throws Exception the failure reason */ @@ -304,9 +304,9 @@ internal object MXMegolmExportEncryption { /** * Derive the AES and HMAC-SHA-256 keys for the file. * - * @param salt salt for pbkdf + * @param salt salt for pbkdf * @param iterations number of pbkdf iterations - * @param password password + * @param password password * @return the derived keys */ @Throws(Exception::class) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt index dc3d393f97..6c18f29307 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt @@ -260,7 +260,7 @@ internal class MXOlmDevice @Inject constructor( * The new session will be stored in the MXStore. * * @param theirIdentityKey the remote user's Curve25519 identity key - * @param theirOneTimeKey the remote user's one-time Curve25519 key + * @param theirOneTimeKey the remote user's one-time Curve25519 key * @return the session id for the outbound session. */ fun createOutboundSession(theirIdentityKey: String, theirOneTimeKey: String): String? { @@ -299,8 +299,8 @@ internal class MXOlmDevice @Inject constructor( * Generate a new inbound session, given an incoming message. * * @param theirDeviceIdentityKey the remote user's Curve25519 identity key. - * @param messageType the message_type field from the received message (must be 0). - * @param ciphertext base64-encoded body from the received message. + * @param messageType the message_type field from the received message (must be 0). + * @param ciphertext base64-encoded body from the received message. * @return {{payload: string, session_id: string}} decrypted payload, and session id of new session. */ fun createInboundSession(theirDeviceIdentityKey: String, messageType: Int, ciphertext: String): Map? { @@ -394,8 +394,8 @@ internal class MXOlmDevice @Inject constructor( * Encrypt an outgoing message using an existing session. * * @param theirDeviceIdentityKey the Curve25519 identity key for the remote device. - * @param sessionId the id of the active session - * @param payloadString the payload to be encrypted and sent + * @param sessionId the id of the active session + * @param payloadString the payload to be encrypted and sent * @return the cipher text */ suspend fun encryptMessage(theirDeviceIdentityKey: String, sessionId: String, payloadString: String): Map? { @@ -427,9 +427,9 @@ internal class MXOlmDevice @Inject constructor( /** * Decrypt an incoming message using an existing session. * - * @param ciphertext the base64-encoded body from the received message. - * @param messageType message_type field from the received message. - * @param sessionId the id of the active session. + * @param ciphertext the base64-encoded body from the received message. + * @param messageType message_type field from the received message. + * @param sessionId the id of the active session. * @param theirDeviceIdentityKey the Curve25519 identity key for the remote device. * @return the decrypted payload. */ @@ -460,9 +460,9 @@ internal class MXOlmDevice @Inject constructor( * Determine if an incoming messages is a prekey message matching an existing session. * * @param theirDeviceIdentityKey the Curve25519 identity key for the remote device. - * @param sessionId the id of the active session. - * @param messageType message_type field from the received message. - * @param ciphertext the base64-encoded body from the received message. + * @param sessionId the id of the active session. + * @param messageType message_type field from the received message. + * @param ciphertext the base64-encoded body from the received message. * @return YES if the received message is a prekey message which matchesthe given session. */ fun matchesSession(theirDeviceIdentityKey: String, sessionId: String, messageType: Int, ciphertext: String): Boolean { @@ -563,7 +563,7 @@ internal class MXOlmDevice @Inject constructor( /** * Encrypt an outgoing message with an outbound group session. * - * @param sessionId the id of the outbound group session. + * @param sessionId the id of the outbound group session. * @param payloadString the payload to be encrypted and sent. * @return ciphertext */ @@ -590,13 +590,13 @@ internal class MXOlmDevice @Inject constructor( /** * Add an inbound group session to the session store. * - * @param sessionId the session identifier. - * @param sessionKey base64-encoded secret key. - * @param roomId the id of the room in which this session will be used. - * @param senderKey the base64-encoded curve25519 key of the sender. + * @param sessionId the session identifier. + * @param sessionKey base64-encoded secret key. + * @param roomId the id of the room in which this session will be used. + * @param senderKey the base64-encoded curve25519 key of the sender. * @param forwardingCurve25519KeyChain Devices involved in forwarding this session to us. - * @param keysClaimed Other keys the sender claims. - * @param exportFormat true if the megolm keys are in export format + * @param keysClaimed Other keys the sender claims. + * @param exportFormat true if the megolm keys are in export format * @return true if the operation succeeds. */ fun addInboundGroupSession(sessionId: String, @@ -752,9 +752,9 @@ internal class MXOlmDevice @Inject constructor( /** * Decrypt a received message with an inbound group session. * - * @param body the base64-encoded body of the encrypted message. - * @param roomId the room in which the message was received. - * @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack. + * @param body the base64-encoded body of the encrypted message. + * @param roomId the room in which the message was received. + * @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack. * @param sessionId the session identifier. * @param senderKey the base64-encoded curve25519 key of the sender. * @return the decrypting result. Nil if the sessionId is unknown. @@ -834,9 +834,9 @@ internal class MXOlmDevice @Inject constructor( /** * Verify an ed25519 signature on a JSON object. * - * @param key the ed25519 key. + * @param key the ed25519 key. * @param jsonDictionary the JSON object which was signed. - * @param signature the base64-encoded signature to be checked. + * @param signature the base64-encoded signature to be checked. * @throws Exception the exception */ @Throws(Exception::class) @@ -859,7 +859,7 @@ internal class MXOlmDevice @Inject constructor( * Search an OlmSession. * * @param theirDeviceIdentityKey the device key - * @param sessionId the session Id + * @param sessionId the session Id * @return the olm session */ private fun getSessionForDevice(theirDeviceIdentityKey: String, sessionId: String): OlmSessionWrapper? { @@ -875,7 +875,7 @@ internal class MXOlmDevice @Inject constructor( * * @param sessionId the session identifier. * @param senderKey the base64-encoded curve25519 key of the sender. - * @param roomId the room where the session is used. + * @param roomId the room where the session is used. * @return the inbound group session. */ fun getInboundGroupSession(sessionId: String?, senderKey: String?, roomId: String?): InboundGroupSessionHolder { @@ -905,7 +905,7 @@ internal class MXOlmDevice @Inject constructor( /** * Determine if we have the keys for a given megolm session. * - * @param roomId room in which the message was received + * @param roomId room in which the message was received * @param senderKey base64-encoded curve25519 key of the sender * @param sessionId session identifier * @return true if the unbound session keys are known. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmSessionStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmSessionStore.kt index fe280416ea..4401a07192 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmSessionStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmSessionStore.kt @@ -39,7 +39,7 @@ internal class OlmSessionStore @Inject constructor(private val store: IMXCryptoS * Store a session between our own device and another device. * This will be called after the session has been created but also every time it has been used * in order to persist the correct state for next run - * @param olmSessionWrapper the end-to-end session. + * @param olmSessionWrapper the end-to-end session. * @param deviceKey the public key of the other device. */ @Synchronized diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RoomDecryptorProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RoomDecryptorProvider.kt index c2f494b4b3..a80bafbe79 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RoomDecryptorProvider.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RoomDecryptorProvider.kt @@ -49,7 +49,7 @@ internal class RoomDecryptorProvider @Inject constructor( * If we already have a decryptor for the given room and algorithm, return * it. Otherwise try to instantiate it. * - * @param roomId the room id + * @param roomId the room id * @param algorithm the crypto algorithm * @return the decryptor * // TODO Create another method for the case of roomId is null diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForUsersAction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForUsersAction.kt index fc211537a6..4c5720daf2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForUsersAction.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForUsersAction.kt @@ -29,7 +29,7 @@ internal class EnsureOlmSessionsForUsersAction @Inject constructor(private val o /** * Try to make sure we have established olm sessions for the given users. - * @param users a list of user ids. + * @param users a list of user ids. */ suspend fun handle(users: List): MXUsersDevicesMap { Timber.v("## ensureOlmSessionsForUsers() : ensureOlmSessionsForUsers $users") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MegolmSessionDataImporter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MegolmSessionDataImporter.kt index 22c4e59b18..67d73c21ed 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MegolmSessionDataImporter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MegolmSessionDataImporter.kt @@ -45,8 +45,8 @@ internal class MegolmSessionDataImporter @Inject constructor(private val olmDevi * Must be call on the crypto coroutine thread * * @param megolmSessionsData megolm sessions. - * @param fromBackup true if the imported keys are already backed up on the server. - * @param progressListener the progress listener + * @param fromBackup true if the imported keys are already backed up on the server. + * @param progressListener the progress listener * @return import room keys result */ @WorkerThread diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MessageEncrypter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MessageEncrypter.kt index 9bbbab4992..919e38c391 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MessageEncrypter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MessageEncrypter.kt @@ -42,7 +42,7 @@ internal class MessageEncrypter @Inject constructor( * This method must be called from the getCryptoHandler() thread. * * @param payloadFields fields to include in the encrypted payload. - * @param deviceInfos list of device infos to encrypt for. + * @param deviceInfos list of device infos to encrypt for. * @return the content for an m.room.encrypted event. */ suspend fun encryptMessage(payloadFields: Content, deviceInfos: List): EncryptedMessage { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXDecrypting.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXDecrypting.kt index af53719829..6847a46369 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXDecrypting.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXDecrypting.kt @@ -29,7 +29,7 @@ internal interface IMXDecrypting { /** * Decrypt an event. * - * @param event the raw event. + * @param event the raw event. * @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack. * @return the decryption information, or an error */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXEncrypting.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXEncrypting.kt index 1d84120208..73ce5a5004 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXEncrypting.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXEncrypting.kt @@ -27,8 +27,8 @@ internal interface IMXEncrypting { * Encrypt an event content according to the configuration of the room. * * @param eventContent the content of the event. - * @param eventType the type of the event. - * @param userIds the room members the event will be sent to. + * @param eventType the type of the event. + * @param userIds the room members the event will be sent to. * @return the encrypted content */ suspend fun encryptEventContent(eventContent: Content, eventType: String, userIds: List): Content diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt index 79e907945f..8b4e9df607 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt @@ -198,7 +198,7 @@ internal class MXMegolmEncryption( /** * Share the device key to a list of users. * - * @param session the session info + * @param session the session info * @param devicesByUsers the devices map */ private suspend fun shareKey(session: MXOutboundSessionInfo, @@ -227,7 +227,7 @@ internal class MXMegolmEncryption( /** * Share the device keys of a an user. * - * @param session the session info + * @param session the session info * @param devicesByUser the devices map */ private suspend fun shareUserDevicesKey(session: MXOutboundSessionInfo, @@ -387,7 +387,7 @@ internal class MXMegolmEncryption( * Get the list of devices which can encrypt data to. * This method must be called in getDecryptingThreadHandler() thread. * - * @param userIds the user ids whose devices must be checked. + * @param userIds the user ids whose devices must be checked. */ private suspend fun getDevicesInRoom(userIds: List): DeviceInRoomInfo { // We are happy to use a cached version here: we assume that if we already diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmDecryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmDecryption.kt index 5daf221add..23c8f0e905 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmDecryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmDecryption.kt @@ -180,7 +180,7 @@ internal class MXOlmDecryption( /** * Attempt to decrypt an Olm message. * - * @param message message object, with 'type' and 'body' fields. + * @param message message object, with 'type' and 'body' fields. * @param theirDeviceIdentityKey the Curve25519 identity key of the sender. * @return payload, if decrypted successfully. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmEncryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmEncryption.kt index 3c9706abe1..bde1d65093 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmEncryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmEncryption.kt @@ -70,7 +70,7 @@ internal class MXOlmEncryption( /** * Ensure that the session. * - * @param users the user ids list + * @param users the user ids list */ private suspend fun ensureSession(users: List) { deviceListManager.downloadKeys(users, false) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt index eb8a8a2990..f5ead35933 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt @@ -112,9 +112,9 @@ internal interface CryptoApi { * Send an event to a specific list of devices * Doc: https://matrix.org/docs/spec/client_server/r0.4.0.html#put-matrix-client-r0-sendtodevice-eventtype-txnid * - * @param eventType the type of event to send + * @param eventType the type of event to send * @param transactionId the transaction ID for this event - * @param body the body + * @param body the body */ @PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "sendToDevice/{eventType}/{txnId}") suspend fun sendToDevice(@Path("eventType") eventType: String, @@ -126,7 +126,7 @@ internal interface CryptoApi { * Doc: https://matrix.org/docs/spec/client_server/r0.4.0.html#delete-matrix-client-r0-devices-deviceid * * @param deviceId the device id - * @param params the deletion parameters + * @param params the deletion parameters */ @HTTP(path = NetworkConstants.URI_API_PREFIX_PATH_R0 + "devices/{device_id}", method = "DELETE", hasBody = true) suspend fun deleteDevice(@Path("device_id") deviceId: String, @@ -137,7 +137,7 @@ internal interface CryptoApi { * Doc: https://matrix.org/docs/spec/client_server/r0.4.0.html#put-matrix-client-r0-devices-deviceid * * @param deviceId the device id - * @param params the params + * @param params the params */ @PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "devices/{device_id}") suspend fun updateDeviceInfo(@Path("device_id") deviceId: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt index 5028704b90..7ff08cd127 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt @@ -232,8 +232,8 @@ internal object MXEncryptedAttachments { * * @param attachmentStream the attachment stream. Will be closed after this method call. * @param elementToDecrypt the elementToDecrypt info - * @param outputStream the outputStream where the decrypted attachment will be write. - * @param clock a clock to retrieve current time + * @param outputStream the outputStream where the decrypted attachment will be write. + * @param clock a clock to retrieve current time * @return true in case of success, false in case of error */ fun decryptAttachment(attachmentStream: InputStream?, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/api/RoomKeysApi.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/api/RoomKeysApi.kt index 9f9a5741e0..d9c63b46ab 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/api/RoomKeysApi.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/api/RoomKeysApi.kt @@ -60,14 +60,14 @@ internal interface RoomKeysApi { * Get information about the given version. * If not supported by the server, an error is returned: {"errcode":"M_NOT_FOUND","error":"No backup found"} * - * @param version version + * @param version version */ @GET(NetworkConstants.URI_API_PREFIX_PATH_UNSTABLE + "room_keys/version/{version}") suspend fun getKeysBackupVersion(@Path("version") version: String): KeysVersionResult /** * Update information about the given version. - * @param version version + * @param version version * @param updateKeysBackupVersionBody the body */ @PUT(NetworkConstants.URI_API_PREFIX_PATH_UNSTABLE + "room_keys/version/{version}") @@ -87,9 +87,9 @@ internal interface RoomKeysApi { * flag (true is better than false), then by the first_message_index (a lower number is better), and finally by * forwarded_count (a lower number is better). * - * @param roomId the room id - * @param sessionId the session id - * @param version the version of the backup + * @param roomId the room id + * @param sessionId the session id + * @param version the version of the backup * @param keyBackupData the data to send */ @PUT(NetworkConstants.URI_API_PREFIX_PATH_UNSTABLE + "room_keys/keys/{roomId}/{sessionId}") @@ -101,8 +101,8 @@ internal interface RoomKeysApi { /** * Store several keys for the given room, using the given backup version. * - * @param roomId the room id - * @param version the version of the backup + * @param roomId the room id + * @param version the version of the backup * @param roomKeysBackupData the data to send */ @PUT(NetworkConstants.URI_API_PREFIX_PATH_UNSTABLE + "room_keys/keys/{roomId}") @@ -113,7 +113,7 @@ internal interface RoomKeysApi { /** * Store several keys, using the given backup version. * - * @param version the version of the backup + * @param version the version of the backup * @param keysBackupData the data to send */ @PUT(NetworkConstants.URI_API_PREFIX_PATH_UNSTABLE + "room_keys/keys") @@ -127,9 +127,9 @@ internal interface RoomKeysApi { /** * Retrieve the key for the given session in the given room from the backup. * - * @param roomId the room id + * @param roomId the room id * @param sessionId the session id - * @param version the version of the backup, or empty String to retrieve the last version + * @param version the version of the backup, or empty String to retrieve the last version */ @GET(NetworkConstants.URI_API_PREFIX_PATH_UNSTABLE + "room_keys/keys/{roomId}/{sessionId}") suspend fun getRoomSessionData(@Path("roomId") roomId: String, @@ -139,8 +139,8 @@ internal interface RoomKeysApi { /** * Retrieve all the keys for the given room from the backup. * - * @param roomId the room id - * @param version the version of the backup, or empty String to retrieve the last version + * @param roomId the room id + * @param version the version of the backup, or empty String to retrieve the last version */ @GET(NetworkConstants.URI_API_PREFIX_PATH_UNSTABLE + "room_keys/keys/{roomId}") suspend fun getRoomSessionsData(@Path("roomId") roomId: String, @@ -149,7 +149,7 @@ internal interface RoomKeysApi { /** * Retrieve all the keys from the backup. * - * @param version the version of the backup, or empty String to retrieve the last version + * @param version the version of the backup, or empty String to retrieve the last version */ @GET(NetworkConstants.URI_API_PREFIX_PATH_UNSTABLE + "room_keys/keys") suspend fun getSessionsData(@Query("version") version: String): KeysBackupData diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXKey.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXKey.kt index 6bfa56ae8d..6b747d19f2 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXKey.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXKey.kt @@ -59,7 +59,7 @@ internal data class MXKey( /** * Returns a signature for an user Id and a signkey. * - * @param userId the user id + * @param userId the user id * @param signkey the sign key * @return the signature */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt index 01d71d2115..9b1c785059 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt @@ -170,7 +170,7 @@ internal interface IMXCryptoStore { /** * Retrieve a device for a user. * - * @param userId the user's id. + * @param userId the user's id. * @param deviceId the device id. * @return the device */ @@ -187,7 +187,7 @@ internal interface IMXCryptoStore { /** * Store the known devices for a user. * - * @param userId The user's id. + * @param userId The user's id. * @param devices A map from device id to 'MXDevice' object for the device. */ fun storeUserDevices(userId: String, devices: Map?) @@ -223,7 +223,7 @@ internal interface IMXCryptoStore { /** * Store the crypto algorithm for a room. * - * @param roomId the id of the room. + * @param roomId the id of the room. * @param algorithm the algorithm. */ fun storeRoomAlgorithm(roomId: String, algorithm: String?) @@ -251,7 +251,7 @@ internal interface IMXCryptoStore { /** * Store a session between the logged-in user and another device. * - * @param olmSessionWrapper the end-to-end session. + * @param olmSessionWrapper the end-to-end session. * @param deviceKey the public key of the other device. */ fun storeSession(olmSessionWrapper: OlmSessionWrapper, deviceKey: String) @@ -359,7 +359,7 @@ internal interface IMXCryptoStore { /** * Get the tracking status of a specified userId devices. * - * @param userId the user id + * @param userId the user id * @param defaultValue the default value * @return the tracking status */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tools/HkdfSha256.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tools/HkdfSha256.kt index 4ab7e0e30c..04fb6c4858 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tools/HkdfSha256.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tools/HkdfSha256.kt @@ -35,7 +35,7 @@ internal object HkdfSha256 { /** * HkdfSha256-Extract(salt, IKM) -> PRK. * - * @param salt optional salt value (a non-secret random value); + * @param salt optional salt value (a non-secret random value); * if not provided, it is set to a string of HashLen (size in octets) zeros. * @param ikm input keying material */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/HomeServerConnectionConfig.java b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/HomeServerConnectionConfig.java index a1b46f6c09..b2bb852cd1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/HomeServerConnectionConfig.java +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/HomeServerConnectionConfig.java @@ -612,7 +612,7 @@ public class HomeServerConnectionConfig { * - https://www.ssi.gouv.fr/uploads/2017/02/security-recommendations-for-tls_v1.1.pdf * - https://developer.android.com/reference/javax/net/ssl/SSLEngine * - * @param tlsLimitations true to use Tls limitations + * @param tlsLimitations true to use Tls limitations * @param enableCompatibilityMode set to true for Android < 20 * @return this builder */ @@ -649,7 +649,7 @@ public class HomeServerConnectionConfig { /** * @param proxyHostname Proxy Hostname - * @param proxyPort Proxy Port + * @param proxyPort Proxy Port * @return this builder */ public Builder withProxy(@Nullable String proxyHostname, int proxyPort) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManager.kt index e9e864b167..539570cdd9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManager.kt @@ -25,7 +25,7 @@ import javax.net.ssl.X509TrustManager * Implements a TrustManager that checks Certificates against an explicit list of known * fingerprints. * - * @property fingerprints Not empty array of SHA256 cert fingerprints + * @property fingerprints Not empty array of SHA256 cert fingerprints * @property defaultTrustManager Optional trust manager to fall back on if cert does not match * any of the fingerprints. Can be null. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManagerApi24.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManagerApi24.kt index 8e8db1ebab..191bb90a67 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManagerApi24.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManagerApi24.kt @@ -29,7 +29,7 @@ import javax.net.ssl.X509ExtendedTrustManager * Implements a TrustManager that checks Certificates against an explicit list of known * fingerprints. * - * @property fingerprints An array of SHA256 cert fingerprints + * @property fingerprints An array of SHA256 cert fingerprints * @property defaultTrustManager Optional trust manager to fall back on if cert does not match * any of the fingerprints. Can be null. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/FilterApi.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/FilterApi.kt index dab801360f..d1df77d14a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/FilterApi.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/FilterApi.kt @@ -28,7 +28,7 @@ internal interface FilterApi { * Upload FilterBody to get a filter_id which can be used for /sync requests. * * @param userId the user id - * @param body the Json representation of a FilterBody object + * @param body the Json representation of a FilterBody object */ @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "user/{userId}/filter") suspend fun uploadFilter(@Path("userId") userId: String, @@ -37,7 +37,7 @@ internal interface FilterApi { /** * Gets a filter with a given filterId from the homeserver. * - * @param userId the user id + * @param userId the user id * @param filterId the filterID * @return Filter */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/FilterUtil.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/FilterUtil.kt index 562fea88b6..2017a86c39 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/FilterUtil.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/FilterUtil.kt @@ -25,7 +25,7 @@ internal object FilterUtil { * FIXME New expected filter: * "{\"room\": {\"ephemeral\": {\"notTypes\": [\"m.typing\"]}}, \"presence\":{\"notTypes\": [\"*\"]}}" * - * @param filterBody filterBody to patch + * @param filterBody filterBody to patch * @param useDataSaveMode true to enable data save mode */ /* diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/PushRulesApi.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/PushRulesApi.kt index 93def22043..fbae04a1f1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/PushRulesApi.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/PushRulesApi.kt @@ -33,7 +33,7 @@ internal interface PushRulesApi { /** * Update the ruleID enable status. * - * @param kind the notification kind (sender, room...) + * @param kind the notification kind (sender, room...) * @param ruleId the ruleId * @param enabledBody the new enable status */ @@ -46,8 +46,8 @@ internal interface PushRulesApi { * Update the ruleID action. * Ref: https://matrix.org/docs/spec/client_server/latest#put-matrix-client-r0-pushrules-scope-kind-ruleid-actions * - * @param kind the notification kind (sender, room...) - * @param ruleId the ruleId + * @param kind the notification kind (sender, room...) + * @param ruleId the ruleId * @param actions the actions */ @PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "pushrules/global/{kind}/{ruleId}/actions") @@ -58,7 +58,7 @@ internal interface PushRulesApi { /** * Delete a rule. * - * @param kind the notification kind (sender, room...) + * @param kind the notification kind (sender, room...) * @param ruleId the ruleId */ @DELETE(NetworkConstants.URI_API_PREFIX_PATH_R0 + "pushrules/global/{kind}/{ruleId}") @@ -68,9 +68,9 @@ internal interface PushRulesApi { /** * Add the ruleID enable status. * - * @param kind the notification kind (sender, room...) + * @param kind the notification kind (sender, room...) * @param ruleId the ruleId. - * @param rule the rule to add. + * @param rule the rule to add. */ @PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "pushrules/global/{kind}/{ruleId}") suspend fun addRule(@Path("kind") kind: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt index b3c7f7f058..ba7f4cf5ad 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomAPI.kt @@ -78,9 +78,9 @@ internal interface RoomAPI { * Get a list of messages starting from a reference. * * @param roomId the room id - * @param from the token identifying where to start. Required. - * @param dir The direction to return messages from. Required. - * @param limit the maximum number of messages to retrieve. Optional. + * @param from the token identifying where to start. Required. + * @param dir The direction to return messages from. Required. + * @param limit the maximum number of messages to retrieve. Optional. * @param filter A JSON RoomEventFilter to filter returned events with. Optional. */ @GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/messages") @@ -94,9 +94,9 @@ internal interface RoomAPI { /** * Get all members of a room. * - * @param roomId the room id where to get the members - * @param syncToken the sync token (optional) - * @param membership to include only one type of membership (optional) + * @param roomId the room id where to get the members + * @param syncToken the sync token (optional) + * @param membership to include only one type of membership (optional) * @param notMembership to exclude one type of membership (optional) */ @GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/members") @@ -109,10 +109,10 @@ internal interface RoomAPI { /** * Send an event to a room. * - * @param txId the transaction Id - * @param roomId the room id + * @param txId the transaction Id + * @param roomId the room id * @param eventType the event type - * @param content the event content + * @param content the event content */ @PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/send/{eventType}/{txId}") suspend fun send(@Path("txId") txId: String, @@ -124,10 +124,10 @@ internal interface RoomAPI { /** * Get the context surrounding an event. * - * @param roomId the room id + * @param roomId the room id * @param eventId the event Id - * @param limit the maximum number of messages to retrieve - * @param filter A JSON RoomEventFilter to filter returned events with. Optional. + * @param limit the maximum number of messages to retrieve + * @param filter A JSON RoomEventFilter to filter returned events with. Optional. */ @GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/context/{eventId}") suspend fun getContextOfEvent(@Path("roomId") roomId: String, @@ -138,7 +138,7 @@ internal interface RoomAPI { /** * Retrieve an event from its room id / events id. * - * @param roomId the room id + * @param roomId the room id * @param eventId the event Id */ @GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/event/{eventId}") @@ -148,7 +148,7 @@ internal interface RoomAPI { /** * Send read markers. * - * @param roomId the room id + * @param roomId the room id * @param markers the read markers */ @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/read_markers") @@ -169,7 +169,7 @@ internal interface RoomAPI { * Ref: https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-rooms-roomid-invite * * @param roomId the room id - * @param body a object that just contains a user id + * @param body a object that just contains a user id */ @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/invite") suspend fun invite(@Path("roomId") roomId: String, @@ -188,9 +188,9 @@ internal interface RoomAPI { /** * Send a generic state event. * - * @param roomId the room id. + * @param roomId the room id. * @param stateEventType the state event type - * @param params the request parameters + * @param params the request parameters */ @PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/state/{state_event_type}") suspend fun sendStateEvent(@Path("roomId") roomId: String, @@ -201,10 +201,10 @@ internal interface RoomAPI { /** * Send a generic state event. * - * @param roomId the room id. + * @param roomId the room id. * @param stateEventType the state event type - * @param stateKey the state keys - * @param params the request parameters + * @param stateKey the state keys + * @param params the request parameters */ @PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/state/{state_event_type}/{state_key}") suspend fun sendStateEvent(@Path("roomId") roomId: String, @@ -274,7 +274,7 @@ internal interface RoomAPI { /** * Leave the given room. * - * @param roomId the room id + * @param roomId the room id * @param params the request body */ @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/leave") @@ -284,7 +284,7 @@ internal interface RoomAPI { /** * Ban a user from the given room. * - * @param roomId the room id + * @param roomId the room id * @param userIdAndReason the banned user object (userId and reason for ban) */ @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/ban") @@ -294,7 +294,7 @@ internal interface RoomAPI { /** * unban a user from the given room. * - * @param roomId the room id + * @param roomId the room id * @param userIdAndReason the unbanned user object (userId and reason for unban) */ @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/unban") @@ -304,7 +304,7 @@ internal interface RoomAPI { /** * Kick a user from the given room. * - * @param roomId the room id + * @param roomId the room id * @param userIdAndReason the kicked user object (userId and reason for kicking) */ @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/kick") @@ -316,10 +316,10 @@ internal interface RoomAPI { * This cannot be undone. * Users may redact their own events, and any user with a power level greater than or equal to the redact power level of the room may redact events there. * - * @param txId the transaction Id - * @param roomId the room id - * @param eventId the event to delete - * @param reason json containing reason key {"reason": "Indecent material"} + * @param txId the transaction Id + * @param roomId the room id + * @param eventId the event to delete + * @param reason json containing reason key {"reason": "Indecent material"} */ @PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/redact/{eventId}/{txnId}") suspend fun redactEvent( @@ -332,9 +332,9 @@ internal interface RoomAPI { /** * Reports an event as inappropriate to the server, which may then notify the appropriate people. * - * @param roomId the room id + * @param roomId the room id * @param eventId the event to report content - * @param body body containing score and reason + * @param body body containing score and reason */ @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/report/{eventId}") suspend fun reportContent(@Path("roomId") roomId: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/CryptoSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/CryptoSyncHandler.kt index dd95762166..e5a5a0bbad 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/CryptoSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/CryptoSyncHandler.kt @@ -62,7 +62,7 @@ internal class CryptoSyncHandler @Inject constructor(private val cryptoService: /** * Decrypt an encrypted event. * - * @param event the event to decrypt + * @param event the event to decrypt * @param timelineId the timeline identifier * @return true if the event has been decrypted */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/AccountDataAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/AccountDataAPI.kt index bbeff18c01..178f349ec8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/AccountDataAPI.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/AccountDataAPI.kt @@ -27,7 +27,7 @@ internal interface AccountDataAPI { * Set some account_data for the client. * * @param userId the user id - * @param type the type + * @param type the type * @param params the put params */ @PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "user/{userId}/account_data/{type}") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetPostAPIMediator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetPostAPIMediator.kt index 5abc806823..857105f6ef 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetPostAPIMediator.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetPostAPIMediator.kt @@ -95,7 +95,7 @@ internal class DefaultWidgetPostAPIMediator @Inject constructor(private val mosh /** * Send a boolean response. * - * @param response the response + * @param response the response * @param eventData the modular data */ override fun sendBoolResponse(response: Boolean, eventData: JsonDict) { @@ -106,7 +106,7 @@ internal class DefaultWidgetPostAPIMediator @Inject constructor(private val mosh /** * Send an integer response. * - * @param response the response + * @param response the response * @param eventData the modular data */ override fun sendIntegerResponse(response: Int, eventData: JsonDict) { @@ -116,9 +116,9 @@ internal class DefaultWidgetPostAPIMediator @Inject constructor(private val mosh /** * Send an object response. * - * @param T the Json type - * @param type the type - * @param response the response + * @param T the Json type + * @param type the type + * @param response the response * @param eventData the modular data */ override fun sendObjectResponse(type: Type, response: T?, eventData: JsonDict) { @@ -147,7 +147,7 @@ internal class DefaultWidgetPostAPIMediator @Inject constructor(private val mosh /** * Send an error. * - * @param message the error message + * @param message the error message * @param eventData the modular data */ override fun sendError(message: String, eventData: JsonDict) { @@ -164,7 +164,7 @@ internal class DefaultWidgetPostAPIMediator @Inject constructor(private val mosh /** * Send the response to the javascript. * - * @param jsString the response data + * @param jsString the response data * @param eventData the modular data */ private fun sendResponse(jsString: String, eventData: JsonDict) = uiHandler.post { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringUtils.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringUtils.kt index d9fd312a6f..c6a417f6eb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringUtils.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/StringUtils.kt @@ -54,7 +54,7 @@ internal fun convertFromUTF8(s: String): String { /** * Returns whether a string contains an occurrence of another, as a standalone word, regardless of case. * - * @param subString the string to search for + * @param subString the string to search for * @return whether a match was found */ internal fun String.caseInsensitiveFind(subString: String): Boolean { diff --git a/vector/src/fdroid/java/im/vector/app/push/fcm/FcmHelper.kt b/vector/src/fdroid/java/im/vector/app/push/fcm/FcmHelper.kt index 425fd1081a..6e36d5dd81 100755 --- a/vector/src/fdroid/java/im/vector/app/push/fcm/FcmHelper.kt +++ b/vector/src/fdroid/java/im/vector/app/push/fcm/FcmHelper.kt @@ -46,7 +46,7 @@ object FcmHelper { * Store FCM token to the SharedPrefs * * @param context android context - * @param token the token to store + * @param token the token to store */ fun storeFcmToken(context: Context, token: String?) { // No op diff --git a/vector/src/gplay/java/im/vector/app/push/fcm/FcmHelper.kt b/vector/src/gplay/java/im/vector/app/push/fcm/FcmHelper.kt index 3d44f10f76..74ab3b38f1 100755 --- a/vector/src/gplay/java/im/vector/app/push/fcm/FcmHelper.kt +++ b/vector/src/gplay/java/im/vector/app/push/fcm/FcmHelper.kt @@ -53,7 +53,7 @@ object FcmHelper { * TODO Store in realm * * @param context android context - * @param token the token to store + * @param token the token to store */ fun storeFcmToken(context: Context, token: String?) { diff --git a/vector/src/main/java/im/vector/app/core/dialogs/UnrecognizedCertificateDialog.kt b/vector/src/main/java/im/vector/app/core/dialogs/UnrecognizedCertificateDialog.kt index 913b69605a..8eaced1c48 100644 --- a/vector/src/main/java/im/vector/app/core/dialogs/UnrecognizedCertificateDialog.kt +++ b/vector/src/main/java/im/vector/app/core/dialogs/UnrecognizedCertificateDialog.kt @@ -41,7 +41,7 @@ class UnrecognizedCertificateDialog @Inject constructor( * * @param activity the Android activity * @param unrecognizedFingerprint the fingerprint for the unknown certificate - * @param callback callback to fire when the user makes a decision + * @param callback callback to fire when the user makes a decision */ fun show(activity: Activity, unrecognizedFingerprint: Fingerprint, @@ -83,8 +83,8 @@ class UnrecognizedCertificateDialog @Inject constructor( * * @param activity the Activity * @param unrecognizedFingerprint the fingerprint for the unknown certificate - * @param existing the current session already exist, so it mean that something has changed server side - * @param callback callback to fire when the user makes a decision + * @param existing the current session already exist, so it mean that something has changed server side + * @param callback callback to fire when the user makes a decision * @param userId the matrix userId * @param homeServerUrl the homeserver url * @param homeServerConnectionConfigHasFingerprints true if the homeServerConnectionConfig has fingerprint diff --git a/vector/src/main/java/im/vector/app/core/intent/ExternalIntentData.kt b/vector/src/main/java/im/vector/app/core/intent/ExternalIntentData.kt index 4d74520095..1d7247d758 100644 --- a/vector/src/main/java/im/vector/app/core/intent/ExternalIntentData.kt +++ b/vector/src/main/java/im/vector/app/core/intent/ExternalIntentData.kt @@ -29,9 +29,9 @@ sealed class ExternalIntentData { /** * Constructor for a text message. * - * @property text the text + * @property text the text * @property htmlText the HTML text - * @property format the formatted text format + * @property format the formatted text format * @property clipDataItem the ClipData * @property mimeType the mimetype */ @@ -54,7 +54,7 @@ sealed class ExternalIntentData { /** * Constructor from a media Uri/. * - * @property uri the media uri + * @property uri the media uri * @property filename the media file name */ data class IntentDataUri( diff --git a/vector/src/main/java/im/vector/app/core/resources/Resource.kt b/vector/src/main/java/im/vector/app/core/resources/Resource.kt index f14c9b834d..861dfdb781 100644 --- a/vector/src/main/java/im/vector/app/core/resources/Resource.kt +++ b/vector/src/main/java/im/vector/app/core/resources/Resource.kt @@ -56,8 +56,8 @@ data class Resource( /** * Get a resource stream and metadata about it given its URI returned from onActivityResult. * - * @param context the context. - * @param uri the URI + * @param context the context. + * @param uri the URI * @param providedMimetype the mimetype * @return a [Resource] encapsulating the opened resource stream and associated metadata * or `null` if opening the resource stream failed. diff --git a/vector/src/main/java/im/vector/app/core/utils/Dialogs.kt b/vector/src/main/java/im/vector/app/core/utils/Dialogs.kt index 10ab0fc027..9f3e6a91cf 100644 --- a/vector/src/main/java/im/vector/app/core/utils/Dialogs.kt +++ b/vector/src/main/java/im/vector/app/core/utils/Dialogs.kt @@ -30,7 +30,7 @@ import me.gujun.android.span.span /** * Open a web view above the current activity. * - * @param url the url to open + * @param url the url to open */ fun Context.displayInWebView(url: String) { val wv = WebView(this) diff --git a/vector/src/main/java/im/vector/app/core/utils/EvenBetterLinkMovementMethod.kt b/vector/src/main/java/im/vector/app/core/utils/EvenBetterLinkMovementMethod.kt index b9c1386933..a53c8161b1 100644 --- a/vector/src/main/java/im/vector/app/core/utils/EvenBetterLinkMovementMethod.kt +++ b/vector/src/main/java/im/vector/app/core/utils/EvenBetterLinkMovementMethod.kt @@ -26,9 +26,9 @@ class EvenBetterLinkMovementMethod(private val onLinkClickListener: OnLinkClickL interface OnLinkClickListener { /** - * @param textView The TextView on which a click was registered. - * @param span The ClickableSpan which is clicked on. - * @param url The clicked URL. + * @param textView The TextView on which a click was registered. + * @param span The ClickableSpan which is clicked on. + * @param url The clicked URL. * @param actualText The original text which is spanned. Can be used to compare actualText and target url to prevent misleading urls. * @return true if this click was handled, false to let Android handle the URL. */ diff --git a/vector/src/main/java/im/vector/app/core/utils/ExternalApplicationsUtil.kt b/vector/src/main/java/im/vector/app/core/utils/ExternalApplicationsUtil.kt index 8bfbcaeb92..9616e35840 100644 --- a/vector/src/main/java/im/vector/app/core/utils/ExternalApplicationsUtil.kt +++ b/vector/src/main/java/im/vector/app/core/utils/ExternalApplicationsUtil.kt @@ -170,9 +170,9 @@ fun openUri(activity: Activity, uri: String) { /** * Send media to a third party application. * - * @param activity the activity + * @param activity the activity * @param savedMediaPath the media path - * @param mimeType the media mime type. + * @param mimeType the media mime type. */ fun openMedia(activity: Activity, savedMediaPath: String, mimeType: String) { val file = File(savedMediaPath) @@ -415,8 +415,8 @@ fun selectTxtFileToWrite( * * ~~ This is copied from the old matrix sdk ~~ * - * @param sourceFile the file source path - * @param dstDirPath the dst path + * @param sourceFile the file source path + * @param dstDirPath the dst path * @param outputFilename optional the output filename * @param currentTimeMillis the current time in milliseconds * @return the created file diff --git a/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt b/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt index b4f8de2485..a41abba7ab 100644 --- a/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt +++ b/vector/src/main/java/im/vector/app/core/utils/PermissionsTools.kt @@ -101,9 +101,9 @@ private fun onPermissionResult(result: Map, lambda: (allGranted * explain why vector needs the corresponding permission. * * @param permissionsToBeGranted the permissions to be granted - * @param activity the calling Activity that is requesting the permissions (or fragment parent) + * @param activity the calling Activity that is requesting the permissions (or fragment parent) * @param activityResultLauncher from the calling fragment/Activity that is requesting the permissions - * @param rationaleMessage message to be displayed BEFORE requesting for the permission + * @param rationaleMessage message to be displayed BEFORE requesting for the permission * @return true if the permissions are granted (synchronous flow), false otherwise (asynchronous flow) */ fun checkPermissions(permissionsToBeGranted: List, @@ -145,7 +145,7 @@ fun checkPermissions(permissionsToBeGranted: List, * To be call after the permission request. * * @param permissionsToBeGranted the permissions to be granted - * @param activity the calling Activity that is requesting the permissions (or fragment parent) + * @param activity the calling Activity that is requesting the permissions (or fragment parent) * * @return true if one of the permission has been denied and the user check the do not ask again checkbox */ diff --git a/vector/src/main/java/im/vector/app/core/utils/SystemUtils.kt b/vector/src/main/java/im/vector/app/core/utils/SystemUtils.kt index 2463c39b71..1d9ac6c3ef 100644 --- a/vector/src/main/java/im/vector/app/core/utils/SystemUtils.kt +++ b/vector/src/main/java/im/vector/app/core/utils/SystemUtils.kt @@ -82,7 +82,7 @@ fun requestDisablingBatteryOptimization(activity: Activity, activityResultLaunch * Copy a text to the clipboard, and display a Toast when done. * * @param context the context - * @param text the text to copy + * @param text the text to copy * @param showToast true to also show a Toast to the user * @param toastMessage content of the toast message as a String resource */ diff --git a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt index 3723e3ce3e..17b8087601 100644 --- a/vector/src/main/java/im/vector/app/features/command/CommandParser.kt +++ b/vector/src/main/java/im/vector/app/features/command/CommandParser.kt @@ -30,7 +30,7 @@ class CommandParser @Inject constructor() { /** * Convert the text message into a Slash command. * - * @param textMessage the text message + * @param textMessage the text message * @param isInThreadTimeline true if the user is currently typing in a thread * @return a parsed slash command (ok or error) */ diff --git a/vector/src/main/java/im/vector/app/features/lifecycle/VectorActivityLifecycleCallbacks.kt b/vector/src/main/java/im/vector/app/features/lifecycle/VectorActivityLifecycleCallbacks.kt index 386e60359d..e453a347f5 100644 --- a/vector/src/main/java/im/vector/app/features/lifecycle/VectorActivityLifecycleCallbacks.kt +++ b/vector/src/main/java/im/vector/app/features/lifecycle/VectorActivityLifecycleCallbacks.kt @@ -136,7 +136,7 @@ class VectorActivityLifecycleCallbacks constructor(private val popupAlertManager * Detect potential malicious activity. * Check if the activity running in app task is declared in app manifest. * - * @param activity the activity of the task + * @param activity the activity of the task * @return true if the activity is potentially malicious */ private fun isPotentialMaliciousActivity(activity: ComponentName): Boolean = activitiesInfo.none { it.name == activity.className } diff --git a/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt b/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt index 9f0d5ff774..e2c1aaa2a4 100755 --- a/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt +++ b/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt @@ -156,16 +156,16 @@ class BugReporter @Inject constructor( /** * Send a bug report. * - * @param reportType The report type (bug, suggestion, feedback) - * @param withDevicesLogs true to include the device log - * @param withCrashLogs true to include the crash logs + * @param reportType The report type (bug, suggestion, feedback) + * @param withDevicesLogs true to include the device log + * @param withCrashLogs true to include the crash logs * @param withKeyRequestHistory true to include the crash logs - * @param withScreenshot true to include the screenshot + * @param withScreenshot true to include the screenshot * @param theBugDescription the bug description - * @param serverVersion version of the server - * @param canContact true if the user opt in to be contacted directly - * @param customFields fields which will be sent with the report - * @param listener the listener + * @param serverVersion version of the server + * @param canContact true if the user opt in to be contacted directly + * @param customFields fields which will be sent with the report + * @param listener the listener */ @SuppressLint("StaticFieldLeak") fun sendBugReport(reportType: ReportType, @@ -682,7 +682,7 @@ class BugReporter @Inject constructor( /** * Retrieves the logs. * - * @param streamWriter the stream writer + * @param streamWriter the stream writer * @param isErrorLogCat true to save the error logs */ private fun getLogCatError(streamWriter: OutputStreamWriter, isErrorLogCat: Boolean) { diff --git a/vector/src/main/java/im/vector/app/features/rageshake/BugReporterMultipartBody.java b/vector/src/main/java/im/vector/app/features/rageshake/BugReporterMultipartBody.java index a530b6e667..72cc63e5c7 100755 --- a/vector/src/main/java/im/vector/app/features/rageshake/BugReporterMultipartBody.java +++ b/vector/src/main/java/im/vector/app/features/rageshake/BugReporterMultipartBody.java @@ -39,7 +39,7 @@ public class BugReporterMultipartBody extends RequestBody { /** * Upload listener * - * @param totalWritten total written bytes + * @param totalWritten total written bytes * @param contentLength content length */ void onWrite(long totalWritten, long contentLength); @@ -296,4 +296,4 @@ public class BugReporterMultipartBody extends RequestBody { return new BugReporterMultipartBody(boundary, parts); } } -} \ No newline at end of file +} diff --git a/vector/src/main/java/im/vector/app/features/rageshake/VectorUncaughtExceptionHandler.kt b/vector/src/main/java/im/vector/app/features/rageshake/VectorUncaughtExceptionHandler.kt index bc78b84088..5496ff4a94 100644 --- a/vector/src/main/java/im/vector/app/features/rageshake/VectorUncaughtExceptionHandler.kt +++ b/vector/src/main/java/im/vector/app/features/rageshake/VectorUncaughtExceptionHandler.kt @@ -57,7 +57,7 @@ class VectorUncaughtExceptionHandler @Inject constructor( /** * An uncaught exception has been triggered. * - * @param thread the thread + * @param thread the thread * @param throwable the throwable * @return the exception description */ diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorLocale.kt b/vector/src/main/java/im/vector/app/features/settings/VectorLocale.kt index 3fb3d3f7c8..326f20845f 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorLocale.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorLocale.kt @@ -120,8 +120,8 @@ object VectorLocale { /** * Get String from a locale. * - * @param context the context - * @param locale the locale + * @param context the context + * @param locale the locale * @param resourceId the string resource id * @return the localized string */ diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt index b368ce021c..72f6080417 100755 --- a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt @@ -493,7 +493,7 @@ class VectorPreferences @Inject constructor( /** * Update the notification ringtone. * - * @param uri the new notification ringtone, or null for no RingTone + * @param uri the new notification ringtone, or null for no RingTone */ fun setNotificationRingTone(uri: Uri?) { defaultPrefs.edit { @@ -636,7 +636,7 @@ class VectorPreferences @Inject constructor( /** * Tells if the application is started on boot. * - * @param value true to start the application on boot + * @param value true to start the application on boot */ fun setAutoStartOnBoot(value: Boolean) { defaultPrefs.edit { @@ -656,7 +656,7 @@ class VectorPreferences @Inject constructor( /** * Updates the selected saving period. * - * @param index the selected period index + * @param index the selected period index */ fun setSelectedMediasSavingPeriod(index: Int) { defaultPrefs.edit { diff --git a/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt b/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt index 160aef27a9..3d1a224d0c 100644 --- a/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt +++ b/vector/src/main/java/im/vector/app/features/themes/ThemeUtils.kt @@ -146,7 +146,7 @@ object ThemeUtils { /** * Translates color attributes to colors. * - * @param c Context + * @param c Context * @param colorAttribute Color Attribute * @return Requested Color */ @@ -178,8 +178,8 @@ object ThemeUtils { /** * Tint the drawable with a theme attribute. * - * @param context the context - * @param drawable the drawable to tint + * @param context the context + * @param drawable the drawable to tint * @param attribute the theme color * @return the tinted drawable */ @@ -191,7 +191,7 @@ object ThemeUtils { * Tint the drawable with a color integer. * * @param drawable the drawable to tint - * @param color the color + * @param color the color * @return the tinted drawable */ fun tintDrawableWithColor(drawable: Drawable, @ColorInt color: Int): Drawable { diff --git a/vector/src/main/java/im/vector/app/features/webview/WebViewEventListener.kt b/vector/src/main/java/im/vector/app/features/webview/WebViewEventListener.kt index bd77283029..2f00ad07b9 100644 --- a/vector/src/main/java/im/vector/app/features/webview/WebViewEventListener.kt +++ b/vector/src/main/java/im/vector/app/features/webview/WebViewEventListener.kt @@ -48,8 +48,8 @@ interface WebViewEventListener { /** * Triggered when an error occurred while loading a page. * - * @param url The url that failed. - * @param errorCode The error code. + * @param url The url that failed. + * @param errorCode The error code. * @param description The error description. */ fun onPageError(url: String, errorCode: Int, description: String) { @@ -59,8 +59,8 @@ interface WebViewEventListener { /** * Triggered when an error occurred while loading a page. * - * @param url The url that failed. - * @param errorCode The error code. + * @param url The url that failed. + * @param errorCode The error code. * @param description The error description. */ fun onHttpError(url: String, errorCode: Int, description: String) { From 2b681a43c8f09dc94cd6747e64203af3d7225d6d Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Fri, 20 May 2022 12:16:35 +0300 Subject: [PATCH 050/125] Use current drawable while loading new map image. --- .../home/room/detail/timeline/item/AbsMessageLocationItem.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsMessageLocationItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsMessageLocationItem.kt index f7146c24e9..e7823845fa 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsMessageLocationItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsMessageLocationItem.kt @@ -75,6 +75,7 @@ abstract class AbsMessageLocationItem : AbsMe GlideApp.with(holder.staticMapImageView) .load(location) .apply(RequestOptions.centerCropTransform()) + .placeholder(holder.staticMapImageView.drawable) .listener(object : RequestListener { override fun onLoadFailed(e: GlideException?, model: Any?, From 468cc30019533cafb059f18ee43b295611aabd43 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Fri, 20 May 2022 12:22:24 +0300 Subject: [PATCH 051/125] Changelog added. --- changelog.d/6103.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/6103.bugfix diff --git a/changelog.d/6103.bugfix b/changelog.d/6103.bugfix new file mode 100644 index 0000000000..12e6836460 --- /dev/null +++ b/changelog.d/6103.bugfix @@ -0,0 +1 @@ +Glide - Use current drawable while loading new static map image From 13175212a0835e606afe81141423920fda52b0bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 May 2022 09:55:29 +0000 Subject: [PATCH 052/125] Bump constraintlayout from 2.1.3 to 2.1.4 Bumps [constraintlayout](https://github.com/androidx/constraintlayout) from 2.1.3 to 2.1.4. - [Release notes](https://github.com/androidx/constraintlayout/releases) - [Commits](https://github.com/androidx/constraintlayout/commits) --- updated-dependencies: - dependency-name: androidx.constraintlayout:constraintlayout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- dependencies.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies.gradle b/dependencies.gradle index 10f9539e5a..47dc8ddc03 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -50,7 +50,7 @@ ext.libs = [ 'recyclerview' : "androidx.recyclerview:recyclerview:1.2.1", 'exifinterface' : "androidx.exifinterface:exifinterface:1.3.3", 'fragmentKtx' : "androidx.fragment:fragment-ktx:1.4.1", - 'constraintLayout' : "androidx.constraintlayout:constraintlayout:2.1.3", + 'constraintLayout' : "androidx.constraintlayout:constraintlayout:2.1.4", 'work' : "androidx.work:work-runtime-ktx:2.7.1", 'autoFill' : "androidx.autofill:autofill:1.1.0", 'preferenceKtx' : "androidx.preference:preference-ktx:1.2.0", From 2081e2c45b859e2e0fc3f66838d4f8ab154a3439 Mon Sep 17 00:00:00 2001 From: ariskotsomitopoulos Date: Fri, 20 May 2022 13:32:55 +0300 Subject: [PATCH 053/125] Reduce log visibility to verbose --- .../android/sdk/internal/crypto/MXOlmDevice.kt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt index 87384b3fe2..a657d757fb 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt @@ -788,13 +788,13 @@ internal class MXOlmDevice @Inject constructor( } val messageIndexKey = senderKey + "|" + sessionId + "|" + roomId + "|" + decryptResult.mIndex - Timber.tag(loggerTag.value).d("##########################################################") - Timber.tag(loggerTag.value).d("## decryptGroupMessage() timeline: $timeline") - Timber.tag(loggerTag.value).d("## decryptGroupMessage() senderKey: $senderKey") - Timber.tag(loggerTag.value).d("## decryptGroupMessage() sessionId: $sessionId") - Timber.tag(loggerTag.value).d("## decryptGroupMessage() roomId: $roomId") - Timber.tag(loggerTag.value).d("## decryptGroupMessage() eventId: $eventId") - Timber.tag(loggerTag.value).d("## decryptGroupMessage() mIndex: ${decryptResult.mIndex}") + Timber.tag(loggerTag.value).v("##########################################################") + Timber.tag(loggerTag.value).v("## decryptGroupMessage() timeline: $timeline") + Timber.tag(loggerTag.value).v("## decryptGroupMessage() senderKey: $senderKey") + Timber.tag(loggerTag.value).v("## decryptGroupMessage() sessionId: $sessionId") + Timber.tag(loggerTag.value).v("## decryptGroupMessage() roomId: $roomId") + Timber.tag(loggerTag.value).v("## decryptGroupMessage() eventId: $eventId") + Timber.tag(loggerTag.value).v("## decryptGroupMessage() mIndex: ${decryptResult.mIndex}") if (timeline?.isNotBlank() == true) { val replayAttackMap = inboundGroupSessionMessageIndexes.getOrPut(timeline) { mutableMapOf() } From d4a5b71a4d571f95309331e1074965ecff38c5bb Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 26 Apr 2022 17:35:42 +0100 Subject: [PATCH 054/125] adding email input FTUE screen - lifts the threepid email error handling to the RegistrationActionHandler rather than having the UI infer success from a 401 --- .../im/vector/app/core/di/FragmentModule.kt | 6 + .../app/core/extensions/TextInputLayout.kt | 27 ++++ .../onboarding/OnboardingViewModel.kt | 7 +- .../onboarding/RegistrationActionHandler.kt | 68 +++++++-- .../FtueAuthChooseDisplayNameFragment.kt | 5 +- .../ftueauth/FtueAuthEmailEntryFragment.kt | 87 ++++++++++++ .../FtueAuthGenericTextInputFormFragment.kt | 7 +- .../onboarding/ftueauth/FtueAuthVariant.kt | 17 ++- vector/src/main/res/drawable/ic_email.xml | 10 ++ .../res/layout/fragment_ftue_email_input.xml | 133 ++++++++++++++++++ vector/src/main/res/values/donottranslate.xml | 4 + .../onboarding/OnboardingViewModelTest.kt | 13 +- .../RegistrationActionHandlerTest.kt | 23 ++- .../test/fakes/FakeRegisterActionHandler.kt | 2 +- .../app/test/fakes/FakeRegistrationWizard.kt | 5 + .../app/test/fixtures/FailureFixture.kt | 25 ++++ 16 files changed, 400 insertions(+), 39 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthEmailEntryFragment.kt create mode 100644 vector/src/main/res/drawable/ic_email.xml create mode 100644 vector/src/main/res/layout/fragment_ftue_email_input.xml create mode 100644 vector/src/test/java/im/vector/app/test/fixtures/FailureFixture.kt diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index c68a35f4e5..a9dcdc3700 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -101,6 +101,7 @@ import im.vector.app.features.onboarding.ftueauth.FtueAuthAccountCreatedFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthCaptchaFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthChooseDisplayNameFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthChooseProfilePictureFragment +import im.vector.app.features.onboarding.ftueauth.FtueAuthEmailEntryFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthGenericTextInputFormFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthLegacyStyleCaptchaFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthLoginFragment @@ -494,6 +495,11 @@ interface FragmentModule { @FragmentKey(FtueAuthAccountCreatedFragment::class) fun bindFtueAuthAccountCreatedFragment(fragment: FtueAuthAccountCreatedFragment): Fragment + @Binds + @IntoMap + @FragmentKey(FtueAuthEmailEntryFragment::class) + fun bindFtueAuthEmailEntryFragment(fragment: FtueAuthEmailEntryFragment): Fragment + @Binds @IntoMap @FragmentKey(FtueAuthChooseDisplayNameFragment::class) diff --git a/vector/src/main/java/im/vector/app/core/extensions/TextInputLayout.kt b/vector/src/main/java/im/vector/app/core/extensions/TextInputLayout.kt index d9b92e78b7..55e75af537 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/TextInputLayout.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/TextInputLayout.kt @@ -16,7 +16,11 @@ package im.vector.app.core.extensions +import android.text.Editable +import android.view.View +import android.view.inputmethod.EditorInfo import com.google.android.material.textfield.TextInputLayout +import im.vector.app.core.platform.SimpleTextWatcher import kotlinx.coroutines.flow.map import reactivecircus.flowbinding.android.widget.textChanges @@ -30,3 +34,26 @@ fun TextInputLayout.hasSurroundingSpaces() = editText().text.toString().let { it fun TextInputLayout.hasContentFlow(mapper: (CharSequence) -> CharSequence = { it }) = editText().textChanges().map { mapper(it).isNotEmpty() } fun TextInputLayout.content() = editText().text.toString() + +fun TextInputLayout.hasContent() = !editText?.text.isNullOrEmpty() + +fun TextInputLayout.associateContentStateWith(button: View) { + editText?.addTextChangedListener(object : SimpleTextWatcher() { + override fun afterTextChanged(s: Editable) { + val newContent = s.toString() + button.isEnabled = newContent.isNotEmpty() + } + }) +} + +fun TextInputLayout.setOnImeDone(action: () -> Unit) { + editText?.setOnEditorActionListener { _, actionId, _ -> + when (actionId) { + EditorInfo.IME_ACTION_DONE -> { + action() + true + } + else -> false + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index 03526b47a5..ccd7eebe87 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -50,7 +50,6 @@ import org.matrix.android.sdk.api.auth.HomeServerHistoryService import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig import org.matrix.android.sdk.api.auth.login.LoginWizard import org.matrix.android.sdk.api.auth.registration.FlowResult -import org.matrix.android.sdk.api.auth.registration.RegistrationResult import org.matrix.android.sdk.api.auth.registration.RegistrationWizard import org.matrix.android.sdk.api.auth.registration.Stage import org.matrix.android.sdk.api.session.Session @@ -275,8 +274,10 @@ class OnboardingViewModel @AssistedInject constructor( // do nothing } else -> when (it) { - is RegistrationResult.Success -> onSessionCreated(it.session, isAccountCreated = true) - is RegistrationResult.FlowResponse -> onFlowResponse(it.flowResult, onNextRegistrationStepAction) + is RegistrationResult.Complete -> onSessionCreated(it.session, isAccountCreated = true) + is RegistrationResult.NextStep -> onFlowResponse(it.flowResult, onNextRegistrationStepAction) + is RegistrationResult.SendEmailSuccess -> _viewEvents.post(OnboardingViewEvents.OnSendEmailSuccess(it.email)) + is RegistrationResult.Error -> _viewEvents.post(OnboardingViewEvents.Failure(it.cause)) } } }, diff --git a/vector/src/main/java/im/vector/app/features/onboarding/RegistrationActionHandler.kt b/vector/src/main/java/im/vector/app/features/onboarding/RegistrationActionHandler.kt index b4998d2ba0..2948b9f301 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/RegistrationActionHandler.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/RegistrationActionHandler.kt @@ -16,26 +16,73 @@ package im.vector.app.features.onboarding +import org.matrix.android.sdk.api.auth.registration.FlowResult import org.matrix.android.sdk.api.auth.registration.RegisterThreePid -import org.matrix.android.sdk.api.auth.registration.RegistrationResult +import org.matrix.android.sdk.api.auth.registration.RegistrationResult.FlowResponse +import org.matrix.android.sdk.api.auth.registration.RegistrationResult.Success import org.matrix.android.sdk.api.auth.registration.RegistrationWizard +import org.matrix.android.sdk.api.failure.is401 +import org.matrix.android.sdk.api.session.Session import javax.inject.Inject +import org.matrix.android.sdk.api.auth.registration.RegistrationResult as SdkRegistrationResult class RegistrationActionHandler @Inject constructor() { suspend fun handleRegisterAction(registrationWizard: RegistrationWizard, action: RegisterAction): RegistrationResult { return when (action) { - RegisterAction.StartRegistration -> registrationWizard.getRegistrationFlow() - is RegisterAction.CaptchaDone -> registrationWizard.performReCaptcha(action.captchaResponse) - is RegisterAction.AcceptTerms -> registrationWizard.acceptTerms() - is RegisterAction.RegisterDummy -> registrationWizard.dummy() - is RegisterAction.AddThreePid -> registrationWizard.addThreePid(action.threePid) - is RegisterAction.SendAgainThreePid -> registrationWizard.sendAgainThreePid() - is RegisterAction.ValidateThreePid -> registrationWizard.handleValidateThreePid(action.code) - is RegisterAction.CheckIfEmailHasBeenValidated -> registrationWizard.checkIfEmailHasBeenValidated(action.delayMillis) - is RegisterAction.CreateAccount -> registrationWizard.createAccount(action.username, action.password, action.initialDeviceName) + RegisterAction.StartRegistration -> resultOf { registrationWizard.getRegistrationFlow() } + is RegisterAction.CaptchaDone -> resultOf { registrationWizard.performReCaptcha(action.captchaResponse) } + is RegisterAction.AcceptTerms -> resultOf { registrationWizard.acceptTerms() } + is RegisterAction.RegisterDummy -> resultOf { registrationWizard.dummy() } + is RegisterAction.AddThreePid -> handleAddThreePid(registrationWizard, action) + is RegisterAction.SendAgainThreePid -> resultOf { registrationWizard.sendAgainThreePid() } + is RegisterAction.ValidateThreePid -> resultOf { registrationWizard.handleValidateThreePid(action.code) } + is RegisterAction.CheckIfEmailHasBeenValidated -> resultOf { registrationWizard.checkIfEmailHasBeenValidated(action.delayMillis) } + is RegisterAction.CreateAccount -> resultOf { + registrationWizard.createAccount( + action.username, + action.password, + action.initialDeviceName + ) + } } } + + private suspend fun handleAddThreePid(wizard: RegistrationWizard, action: RegisterAction.AddThreePid): RegistrationResult { + return runCatching { wizard.addThreePid(action.threePid) }.fold( + onSuccess = { + when (it) { + is Success -> RegistrationResult.Complete(it.session) + is FlowResponse -> RegistrationResult.NextStep(it.flowResult) + } + }, + onFailure = { + when { + action.threePid is RegisterThreePid.Email && it.is401() -> RegistrationResult.SendEmailSuccess(action.threePid.email) + else -> RegistrationResult.Error(it) + } + } + ) + } +} + +private inline fun resultOf(block: () -> SdkRegistrationResult): RegistrationResult { + return runCatching { block() }.fold( + onSuccess = { + when (it) { + is FlowResponse -> RegistrationResult.NextStep(it.flowResult) + is Success -> RegistrationResult.Complete(it.session) + } + }, + onFailure = { RegistrationResult.Error(it) } + ) +} + +sealed interface RegistrationResult { + data class Error(val cause: Throwable) : RegistrationResult + data class Complete(val session: Session) : RegistrationResult + data class NextStep(val flowResult: FlowResult) : RegistrationResult + data class SendEmailSuccess(val email: String) : RegistrationResult } sealed interface RegisterAction { @@ -56,7 +103,6 @@ sealed interface RegisterAction { } fun RegisterAction.ignoresResult() = when (this) { - is RegisterAction.AddThreePid -> true is RegisterAction.SendAgainThreePid -> true else -> false } diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthChooseDisplayNameFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthChooseDisplayNameFragment.kt index 1ce0c544e5..c64e22bc9c 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthChooseDisplayNameFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthChooseDisplayNameFragment.kt @@ -23,6 +23,7 @@ import android.view.View import android.view.ViewGroup import android.view.inputmethod.EditorInfo import com.google.android.material.textfield.TextInputLayout +import im.vector.app.core.extensions.hasContent import im.vector.app.core.platform.SimpleTextWatcher import im.vector.app.databinding.FragmentFtueDisplayNameBinding import im.vector.app.features.onboarding.OnboardingAction @@ -69,7 +70,7 @@ class FtueAuthChooseDisplayNameFragment @Inject constructor() : AbstractFtueAuth override fun updateWithState(state: OnboardingViewState) { views.displayNameInput.editText?.setText(state.personalizationState.displayName) - views.displayNameSubmit.isEnabled = views.displayNameInput.hasContentEmpty() + views.displayNameSubmit.isEnabled = views.displayNameInput.hasContent() } override fun resetViewModel() { @@ -81,5 +82,3 @@ class FtueAuthChooseDisplayNameFragment @Inject constructor() : AbstractFtueAuth return true } } - -private fun TextInputLayout.hasContentEmpty() = !editText?.text.isNullOrEmpty() diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthEmailEntryFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthEmailEntryFragment.kt new file mode 100644 index 0000000000..1dd99aa587 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthEmailEntryFragment.kt @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.onboarding.ftueauth + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.lifecycle.lifecycleScope +import im.vector.app.core.extensions.associateContentStateWith +import im.vector.app.core.extensions.content +import im.vector.app.core.extensions.editText +import im.vector.app.core.extensions.hasContent +import im.vector.app.core.extensions.isEmail +import im.vector.app.core.extensions.setOnImeDone +import im.vector.app.databinding.FragmentFtueEmailInputBinding +import im.vector.app.features.onboarding.OnboardingAction +import im.vector.app.features.onboarding.OnboardingViewEvents +import im.vector.app.features.onboarding.OnboardingViewState +import im.vector.app.features.onboarding.RegisterAction +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import org.matrix.android.sdk.api.auth.registration.RegisterThreePid +import org.matrix.android.sdk.api.failure.is401 +import reactivecircus.flowbinding.android.widget.textChanges +import javax.inject.Inject + +class FtueAuthEmailEntryFragment @Inject constructor() : AbstractFtueAuthFragment() { + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueEmailInputBinding { + return FragmentFtueEmailInputBinding.inflate(inflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setupViews() + } + + private fun setupViews() { + views.emailEntryInput.associateContentStateWith(button = views.emailEntrySubmit) + views.emailEntryInput.setOnImeDone { updateEmail() } + views.emailEntrySubmit.debouncedClicks { updateEmail() } + + views.emailEntryInput.editText().textChanges() + .onEach { + views.emailEntryInput.error = null + views.emailEntrySubmit.isEnabled = it.isEmail() + } + .launchIn(lifecycleScope) + } + + private fun updateEmail() { + val email = views.emailEntryInput.content() + viewModel.handle(OnboardingAction.PostRegisterAction(RegisterAction.AddThreePid(RegisterThreePid.Email(email)))) + } + + override fun onError(throwable: Throwable) { + views.emailEntryInput.error = errorFormatter.toHumanReadable(throwable) + } + + override fun updateWithState(state: OnboardingViewState) { + views.emailEntrySubmit.isEnabled = views.emailEntryInput.content().isEmail() + } + + override fun resetViewModel() { + // Nothing to do + } + + override fun onBackPressed(toolbarButton: Boolean): Boolean { + viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnTakeMeHome)) + return true + } +} diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthGenericTextInputFormFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthGenericTextInputFormFragment.kt index ce3dee7a19..fce1308d3c 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthGenericTextInputFormFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthGenericTextInputFormFragment.kt @@ -223,12 +223,7 @@ class FtueAuthGenericTextInputFormFragment @Inject constructor() : AbstractFtueA override fun onError(throwable: Throwable) { when (params.mode) { TextInputFormFragmentMode.SetEmail -> { - if (throwable.is401()) { - // This is normal use case, we go to the mail waiting screen - viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnSendEmailSuccess(viewModel.currentThreePid ?: ""))) - } else { - views.loginGenericTextInputFormTil.error = errorFormatter.toHumanReadable(throwable) - } + views.loginGenericTextInputFormTil.error = errorFormatter.toHumanReadable(throwable) } TextInputFormFragmentMode.SetMsisdn -> { if (throwable.is401()) { diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt index 6f1b85df4f..a232a6ddba 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt @@ -393,10 +393,7 @@ class FtueAuthVariant( when (stage) { is Stage.ReCaptcha -> onCaptcha(stage) - is Stage.Email -> addRegistrationStageFragmentToBackstack( - FtueAuthGenericTextInputFormFragment::class.java, - FtueAuthGenericTextInputFormFragmentArgument(TextInputFormFragmentMode.SetEmail, stage.mandatory), - ) + is Stage.Email -> onEmail(stage) is Stage.Msisdn -> addRegistrationStageFragmentToBackstack( FtueAuthGenericTextInputFormFragment::class.java, FtueAuthGenericTextInputFormFragmentArgument(TextInputFormFragmentMode.SetMsisdn, stage.mandatory), @@ -406,6 +403,18 @@ class FtueAuthVariant( } } + private fun onEmail(stage: Stage) { + when { + vectorFeatures.isOnboardingCombinedRegisterEnabled() -> addRegistrationStageFragmentToBackstack( + FtueAuthEmailEntryFragment::class.java + ) + else -> addRegistrationStageFragmentToBackstack( + FtueAuthGenericTextInputFormFragment::class.java, + FtueAuthGenericTextInputFormFragmentArgument(TextInputFormFragmentMode.SetEmail, stage.mandatory), + ) + } + } + private fun onTerms(stage: Stage.Terms) { when { vectorFeatures.isOnboardingCombinedRegisterEnabled() -> addRegistrationStageFragmentToBackstack( diff --git a/vector/src/main/res/drawable/ic_email.xml b/vector/src/main/res/drawable/ic_email.xml new file mode 100644 index 0000000000..48de7aec41 --- /dev/null +++ b/vector/src/main/res/drawable/ic_email.xml @@ -0,0 +1,10 @@ + + + diff --git a/vector/src/main/res/layout/fragment_ftue_email_input.xml b/vector/src/main/res/layout/fragment_ftue_email_input.xml new file mode 100644 index 0000000000..95740ec94b --- /dev/null +++ b/vector/src/main/res/layout/fragment_ftue_email_input.xml @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +