proton-mail-android/app/src/main/java/ch/protonmail/android/details/data/MessageFlagsToEncryptionMap...

99 lines
3.8 KiB
Kotlin

/*
* Copyright (c) 2022 Proton AG
*
* This file is part of Proton Mail.
*
* Proton Mail is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Proton Mail is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Proton Mail. If not, see https://www.gnu.org/licenses/.
*/
package ch.protonmail.android.details.data
import ch.protonmail.android.api.models.enumerations.MessageEncryption
import ch.protonmail.android.api.models.enumerations.MessageFlag
import me.proton.core.domain.arch.Mapper
import javax.inject.Inject
/**
* Maps a Long number representing a bitmap of `MessageFlags` to the corresponding `MessageEncryption` value.
* The input `messageFlags` long should be the value that API returns for the `Message.Flags` field.
*
* To better understand how the flags work, here's an example:
* A message that is "Sent" and "E2EE" is represented with a "flags" value of "10",
* which is the sum of the individual values for `MessageFlags.SENT` (2L) and `MessageFlags.E2E` (8L).
*
* The conversion is done performing a bitwise `AND` operation between the aggregated flags value and each of
* the individual flags we want to check.
* Using the above message as example the binary value of the aggregated flags is `1010`.
* Given that the value for SENT flag is `0010` (decimal 2) and the value for E2EE flag is `1000` (decimal 8),
* performing an `AND` operations between the aggregated flags and SENT / E2EE will in both cases return
* a value equal to the right side operand (SENT / E2EE), which will let us know that flag is "true".
*
* Please refer to `MessageFlag` class for a complete list of all of the flags' values
*/
class MessageFlagsToEncryptionMapper @Inject constructor() : Mapper<Long, MessageEncryption> {
fun flagsToMessageEncryption(messageFlags: Long): MessageEncryption {
val internal = messageFlags and MessageFlag.INTERNAL.flagValue == MessageFlag.INTERNAL.flagValue
val e2e = messageFlags and MessageFlag.E2E.flagValue == MessageFlag.E2E.flagValue
val received = messageFlags and MessageFlag.RECEIVED.flagValue == MessageFlag.RECEIVED.flagValue
val sent = messageFlags and MessageFlag.SENT.flagValue == MessageFlag.SENT.flagValue
val auto = messageFlags and MessageFlag.AUTO.flagValue == MessageFlag.AUTO.flagValue
return when {
internal -> handleInternalMessage(e2e, received, sent, auto)
received -> handleReceivedMessage(e2e)
e2e -> MessageEncryption.MIME_PGP
else -> MessageEncryption.EXTERNAL
}
}
private fun handleReceivedMessage(
e2e: Boolean
) = if (e2e) {
MessageEncryption.EXTERNAL_PGP
} else {
MessageEncryption.EXTERNAL
}
private fun handleInternalMessage(
e2e: Boolean,
received: Boolean,
sent: Boolean,
auto: Boolean
): MessageEncryption {
if (e2e) {
if (received && sent) {
return MessageEncryption.INTERNAL
}
if (received && auto) {
return MessageEncryption.AUTO_RESPONSE
}
return MessageEncryption.INTERNAL
}
if (auto) {
return MessageEncryption.AUTO_RESPONSE
}
if (sent) {
return MessageEncryption.SENT_TO_EXTERNAL
}
return MessageEncryption.INTERNAL
}
}