Merge PR #7849: Mark the recovery key as sensitive when copying it to the clipboard

This commit is contained in:
Benoit Marty
2026-10-05 10:44:39 +02:00
3 changed files with 27 additions and 5 deletions
@@ -122,6 +122,7 @@ private fun Content(
context.copyToClipboard( context.copyToClipboard(
text = formattedRecoveryKey, text = formattedRecoveryKey,
toastMessage = toastMessage, toastMessage = toastMessage,
isSensitive = true,
) )
state.eventSink.invoke(SecureBackupSetupEvent.RecoveryKeyHasBeenSaved) state.eventSink.invoke(SecureBackupSetupEvent.RecoveryKeyHasBeenSaved)
} }
@@ -9,15 +9,35 @@
package io.element.android.libraries.androidutils.system package io.element.android.libraries.androidutils.system
import android.content.ClipData import android.content.ClipData
import android.content.ClipDescription
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.Context import android.content.Context
import android.os.Build
import android.os.PersistableBundle
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
class CopyToClipboardUseCase( class CopyToClipboardUseCase(
private val context: Context, private val context: Context,
) { ) {
fun execute(text: CharSequence) { /**
context.getSystemService<ClipboardManager>() * @param isSensitive if true, the clip is flagged so the system clipboard preview (Android 13+) and keyboards hide its content.
?.setPrimaryClip(ClipData.newPlainText("", text)) */
fun execute(text: CharSequence, isSensitive: Boolean = false) {
val clipData = ClipData.newPlainText("", text)
if (isSensitive) {
clipData.description.extras = PersistableBundle().apply {
putBoolean(EXTRA_IS_SENSITIVE, true)
}
}
context.getSystemService<ClipboardManager>()?.setPrimaryClip(clipData)
}
private companion object {
// The constant only exists from API 33, but the documentation recommends using its value on older versions too.
val EXTRA_IS_SENSITIVE = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
ClipDescription.EXTRA_IS_SENSITIVE
} else {
"android.content.extra.IS_SENSITIVE"
}
} }
} }
@@ -63,9 +63,10 @@ fun Context.getVersionCodeFromManifest(): Long {
*/ */
fun Context.copyToClipboard( fun Context.copyToClipboard(
text: CharSequence, text: CharSequence,
toastMessage: String? = null toastMessage: String? = null,
isSensitive: Boolean = false,
) { ) {
CopyToClipboardUseCase(this).execute(text) CopyToClipboardUseCase(this).execute(text, isSensitive)
toastMessage?.let { toast(it) } toastMessage?.let { toast(it) }
} }