Skip to content

Commit

Permalink
Merge branch 'develop' into feat/user-folders
Browse files Browse the repository at this point in the history
  • Loading branch information
Garzas committed Dec 6, 2024
2 parents a0d3f9f + 06c284a commit 7fa79d5
Show file tree
Hide file tree
Showing 49 changed files with 1,169 additions and 166 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
fetch-depth: 0

- name: Cherry pick to `develop`
uses: wireapp/[email protected].0
uses: wireapp/[email protected].2
with:
target-branch: develop
pr-title-suffix: '🍒'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import com.wire.crypto.CoreCrypto
import com.wire.crypto.CoreCryptoException
import com.wire.crypto.client.toByteArray
import com.wire.kalium.cryptography.exceptions.ProteusException
import com.wire.kalium.cryptography.exceptions.ProteusStorageMigrationException
import io.ktor.util.decodeBase64Bytes
import io.ktor.util.encodeBase64
import kotlinx.coroutines.sync.Mutex
Expand Down Expand Up @@ -178,36 +179,44 @@ class ProteusClientCoreCryptoImpl private constructor(
acc && File(rootDir).resolve(file).deleteRecursively()
}

private suspend fun migrateFromCryptoBoxIfNecessary(coreCrypto: CoreCrypto, rootDir: String) {
if (cryptoBoxFilesExists(File(rootDir))) {
kaliumLogger.i("migrating from crypto box at: $rootDir")
coreCrypto.proteusCryptoboxMigrate(rootDir)
kaliumLogger.i("migration successful")

if (deleteCryptoBoxFiles(rootDir)) {
kaliumLogger.i("successfully deleted old crypto box files")
} else {
kaliumLogger.e("Failed to deleted old crypto box files at $rootDir")
}
}
}

@Suppress("TooGenericExceptionCaught")
@Suppress("TooGenericExceptionCaught", "ThrowsCount")
suspend operator fun invoke(coreCrypto: CoreCrypto, rootDir: String): ProteusClientCoreCryptoImpl {
try {
migrateFromCryptoBoxIfNecessary(coreCrypto, rootDir)
coreCrypto.proteusInit()
return ProteusClientCoreCryptoImpl(coreCrypto)
} catch (exception: ProteusStorageMigrationException) {
throw exception
} catch (e: CoreCryptoException) {
throw ProteusException(
e.message,
ProteusException.fromProteusCode(coreCrypto.proteusLastErrorCode().toInt()),
coreCrypto.proteusLastErrorCode().toInt(),
e.cause
message = e.message,
code = ProteusException.fromProteusCode(coreCrypto.proteusLastErrorCode().toInt()),
intCode = coreCrypto.proteusLastErrorCode().toInt(),
cause = e.cause
)
} catch (e: Exception) {
throw ProteusException(e.message, ProteusException.Code.UNKNOWN_ERROR, null, e.cause)
}
}

@Suppress("TooGenericExceptionCaught")
private suspend fun migrateFromCryptoBoxIfNecessary(coreCrypto: CoreCrypto, rootDir: String) {
try {
if (cryptoBoxFilesExists(File(rootDir))) {
kaliumLogger.i("migrating from crypto box at: $rootDir")
coreCrypto.proteusCryptoboxMigrate(rootDir)
kaliumLogger.i("migration successful")

if (deleteCryptoBoxFiles(rootDir)) {
kaliumLogger.i("successfully deleted old crypto box files")
} else {
kaliumLogger.e("Failed to deleted old crypto box files at $rootDir")
}
}
} catch (exception: Exception) {
kaliumLogger.e("Failed to migrate from crypto box to core crypto, exception: $exception")
throw ProteusStorageMigrationException("Failed to migrate from crypto box at $rootDir", exception)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

package com.wire.kalium.cryptography.exceptions

class ProteusException(message: String?, val code: Code, val intCode: Int?, cause: Throwable? = null) : Exception(message, cause) {
open class ProteusException(message: String?, val code: Code, val intCode: Int?, cause: Throwable? = null) : Exception(message, cause) {

constructor(message: String?, code: Int, cause: Throwable? = null) : this(
message,
Expand Down Expand Up @@ -199,3 +199,6 @@ class ProteusException(message: String?, val code: Code, val intCode: Int?, caus
}
}
}

class ProteusStorageMigrationException(override val message: String, val rootCause: Throwable? = null) :
ProteusException(message, Int.MIN_VALUE, null)
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import com.wire.kalium.logic.data.id.QualifiedID
import com.wire.kalium.logic.data.user.OtherUserMinimized
import com.wire.kalium.logic.data.user.UserId
import com.wire.kalium.logic.data.user.type.UserType
import kotlinx.datetime.Instant

data class CallMetadataProfile(
val data: Map<ConversationId, CallMetadata>
Expand All @@ -46,7 +47,8 @@ data class CallMetadata(
val maxParticipants: Int = 0, // Was used for tracking
val protocol: Conversation.ProtocolInfo,
val activeSpeakers: Map<UserId, List<String>> = mapOf(),
val users: List<OtherUserMinimized> = listOf()
val users: List<OtherUserMinimized> = listOf(),
val screenShareMetadata: CallScreenSharingMetadata = CallScreenSharingMetadata()
) {
fun getFullParticipants(): List<Participant> = participants.map { participant ->
val user = users.firstOrNull { it.id == participant.userId }
Expand All @@ -66,3 +68,14 @@ data class CallMetadata(
)
}
}

/**
* [activeScreenShares] - map of user ids that share screen with the start timestamp
* [completedScreenShareDurationInMillis] - total time of already ended screen shares in milliseconds
* [uniqueSharingUsers] - set of users that were sharing a screen at least once
*/
data class CallScreenSharingMetadata(
val activeScreenShares: Map<QualifiedID, Instant> = emptyMap(),
val completedScreenShareDurationInMillis: Long = 0L,
val uniqueSharingUsers: Set<String> = emptySet()
)
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ import com.wire.kalium.logic.data.user.UserId
import com.wire.kalium.logic.data.user.type.UserType
import com.wire.kalium.util.serialization.toJsonElement
import kotlinx.datetime.Instant
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlin.time.Duration

/**
Expand Down Expand Up @@ -258,11 +260,23 @@ data class Conversation(
fun toLogMap(): Map<String, Any?>
}

data class Member(val id: UserId, val role: Role) {
@Serializable
data class Member(
@SerialName("id") val id: UserId,
@SerialName("role") val role: Role
) {

@Serializable
sealed class Role {

@Serializable
data object Member : Role()

@Serializable
data object Admin : Role()
data class Unknown(val name: String) : Role()

@Serializable
data class Unknown(@SerialName("name") val name: String) : Role()

override fun toString(): String =
when (this) {
Expand Down Expand Up @@ -300,7 +314,6 @@ sealed class ConversationDetails(open val conversation: Conversation) {
override val conversation: Conversation,
val hasOngoingCall: Boolean = false,
val isSelfUserMember: Boolean,
val isSelfUserCreator: Boolean,
val selfRole: Conversation.Member.Role?,
val isFavorite: Boolean = false
// val isTeamAdmin: Boolean, TODO kubaz
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,29 @@

package com.wire.kalium.logic.data.conversation

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

/**
* Conversation muting settings type
*/
sealed class MutedConversationStatus(open val status: Int = 0) {
@Serializable
sealed class MutedConversationStatus(@SerialName("status") open val status: Int = 0) {
/**
* 0 -> All notifications are displayed
*/
@Serializable
data object AllAllowed : MutedConversationStatus(0)

/**
* 1 -> Only mentions and replies are displayed (normal messages muted)
*/
@Serializable
data object OnlyMentionsAndRepliesAllowed : MutedConversationStatus(1)

/**
* 3 -> No notifications are displayed
*/
@Serializable
data object AllMuted : MutedConversationStatus(3)
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,11 @@ enum class LogoutReason {
/**
* Session Expired.
*/
SESSION_EXPIRED;
SESSION_EXPIRED,

/**
* The migration to CC failed.
* This will trigger a cleanup of the local client data and prepare for a fresh start without losing data.
*/
MIGRATION_TO_CC_FAILED
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import com.wire.kalium.util.DateTimeUtil.toIsoDateTimeString
import com.wire.kalium.util.serialization.toJsonElement
import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlin.time.Duration
Expand Down Expand Up @@ -473,15 +475,20 @@ sealed interface Message {
}
}

@Serializable
data class ExpirationData(
val expireAfter: Duration,
val selfDeletionStatus: SelfDeletionStatus = SelfDeletionStatus.NotStarted
@SerialName("expire_after") val expireAfter: Duration,
@SerialName("self_deletion_status") val selfDeletionStatus: SelfDeletionStatus = SelfDeletionStatus.NotStarted
) {

@Serializable
sealed class SelfDeletionStatus {

@Serializable
data object NotStarted : SelfDeletionStatus()

data class Started(val selfDeletionEndDate: Instant) : SelfDeletionStatus()
@Serializable
data class Started(@SerialName("self_deletion_end_date") val selfDeletionEndDate: Instant) : SelfDeletionStatus()

fun toLogMap(): Map<String, String> = when (this) {
is NotStarted -> mutableMapOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@
package com.wire.kalium.logic.data.message.mention

import com.wire.kalium.logic.data.user.UserId
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class MessageMention(
val start: Int,
val length: Int,
val userId: UserId,
val isSelfMention: Boolean
@SerialName("start") val start: Int,
@SerialName("length") val length: Int,
@SerialName("userId") val userId: UserId,
@SerialName("isSelfMention") val isSelfMention: Boolean
)
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package com.wire.kalium.logic.data.user

data class CreateUserTeam(val teamName: String)
data class CreateUserTeam(val teamId: String, val teamName: String)
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ moduleGraph = "0.7.0"
# if you update sqlDelight check if https://github.com/cashapp/sqldelight/issues/4154 is fixed
# and delete the workaround in the dev.mk file
sqldelight = "2.0.1"
sqlcipher-android = "4.6.1"
sqlcipher-android = "4.5.6"
pbandk = "0.14.2"
turbine = "1.1.0"
avs = "10.0.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import com.wire.kalium.logic.data.id.ConversationId
import com.wire.kalium.logic.data.id.FederatedIdMapper
import com.wire.kalium.logic.data.id.GroupID
import com.wire.kalium.logic.data.id.QualifiedClientID
import com.wire.kalium.logic.data.id.QualifiedID
import com.wire.kalium.logic.data.id.QualifiedIdMapper
import com.wire.kalium.logic.data.id.SubconversationId
import com.wire.kalium.logic.data.id.toCrypto
Expand Down Expand Up @@ -441,6 +442,8 @@ internal class CallDataSource(

val currentParticipantIds = call.participants.map { it.userId }.toSet()
val newParticipantIds = participants.map { it.userId }.toSet()
val sharingScreenParticipantIds = participants.filter { it.isSharingScreen }
.map { participant -> participant.id }

val updatedUsers = call.users.toMutableList()

Expand All @@ -456,7 +459,11 @@ internal class CallDataSource(
this[conversationId] = call.copy(
participants = participants,
maxParticipants = max(call.maxParticipants, participants.size + 1),
users = updatedUsers
users = updatedUsers,
screenShareMetadata = updateScreenSharingMetadata(
metadata = call.screenShareMetadata,
usersCurrentlySharingScreen = sharingScreenParticipantIds
)
)
}

Expand All @@ -479,6 +486,43 @@ internal class CallDataSource(
}
}

/**
* Manages call sharing metadata for analytical purposes by tracking the following:
* - **Active Screen Shares**: Maintains a record of currently active screen shares with their start times (local to the device).
* - **Completed Screen Share Duration**: Accumulates the total duration of screen shares that have already ended.
* - **Unique Sharing Users**: Keeps a unique list of all users who have shared their screen during the call.
*
* To update the metadata, the following steps are performed:
* 1. **Calculate Ended Screen Share Time**: Determine the total time for users who stopped sharing since the last update.
* 2. **Update Active Shares**: Filter out inactive shares and add any new ones, associating them with the current start time.
* 3. **Track Unique Users**: Append ids to current set in order to keep track of unique users.
*/
private fun updateScreenSharingMetadata(
metadata: CallScreenSharingMetadata,
usersCurrentlySharingScreen: List<QualifiedID>
): CallScreenSharingMetadata {
val now = DateTimeUtil.currentInstant()

val alreadyEndedScreenSharesTimeInMillis = metadata.activeScreenShares
.filterKeys { id -> id !in usersCurrentlySharingScreen }
.values
.sumOf { startTime -> DateTimeUtil.calculateMillisDifference(startTime, now) }

val updatedShares = metadata.activeScreenShares
.filterKeys { id -> id in usersCurrentlySharingScreen }
.plus(
usersCurrentlySharingScreen
.filterNot { id -> metadata.activeScreenShares.containsKey(id) }
.associateWith { now }
)

return metadata.copy(
activeScreenShares = updatedShares,
completedScreenShareDurationInMillis = metadata.completedScreenShareDurationInMillis + alreadyEndedScreenSharesTimeInMillis,
uniqueSharingUsers = metadata.uniqueSharingUsers.plus(usersCurrentlySharingScreen.map { id -> id.toString() })
)
}

private fun clearStaleParticipantTimeout(participant: ParticipantMinimized) {
callingLogger.i("Clear stale participant timer")
val qualifiedClient = QualifiedClientID(ClientId(participant.clientId), participant.id)
Expand Down
Loading

0 comments on commit 7fa79d5

Please sign in to comment.