From 54983bc92e4a5d99d49c464f4bbaf9617c9a06c0 Mon Sep 17 00:00:00 2001 From: David Perez Date: Wed, 23 Apr 2025 14:53:05 -0500 Subject: [PATCH] Add helper for concurrent map (#5086) --- .../flightrecorder/FlightRecorderManagerImpl.kt | 4 ++-- .../data/vault/manager/VaultLockManagerImpl.kt | 4 ++-- .../platform/components/coachmark/CoachMarkState.kt | 4 ++-- .../kotlin/com/bitwarden/core/data/util/MapUtil.kt | 13 +++++++++++++ 4 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 core/src/main/kotlin/com/bitwarden/core/data/util/MapUtil.kt diff --git a/app/src/main/java/com/x8bit/bitwarden/data/platform/manager/flightrecorder/FlightRecorderManagerImpl.kt b/app/src/main/java/com/x8bit/bitwarden/data/platform/manager/flightrecorder/FlightRecorderManagerImpl.kt index 5e84793138..88c9961cdc 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/platform/manager/flightrecorder/FlightRecorderManagerImpl.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/platform/manager/flightrecorder/FlightRecorderManagerImpl.kt @@ -4,6 +4,7 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter +import com.bitwarden.core.data.util.concurrentMapOf import com.bitwarden.data.manager.DispatcherManager import com.x8bit.bitwarden.data.platform.datasource.disk.SettingsDiskSource import com.x8bit.bitwarden.data.platform.datasource.disk.model.FlightRecorderDataSet @@ -23,7 +24,6 @@ import timber.log.Timber import java.time.Clock import java.time.temporal.ChronoUnit import java.util.UUID -import java.util.concurrent.ConcurrentHashMap private const val EXPIRATION_DURATION_DAYS: Long = 30 @@ -40,7 +40,7 @@ internal class FlightRecorderManagerImpl( private val unconfinedScope = CoroutineScope(context = dispatcherManager.unconfined) private val ioScope = CoroutineScope(context = dispatcherManager.io) private var cancellationJob: Job = Job().apply { complete() } - private val expirationJobMap: ConcurrentHashMap = ConcurrentHashMap() + private val expirationJobMap: MutableMap = concurrentMapOf() private val flightRecorderTree = FlightRecorderTree() override val flightRecorderData: FlightRecorderDataSet diff --git a/app/src/main/java/com/x8bit/bitwarden/data/vault/manager/VaultLockManagerImpl.kt b/app/src/main/java/com/x8bit/bitwarden/data/vault/manager/VaultLockManagerImpl.kt index 121f9ea67b..ac1b0f3b87 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/vault/manager/VaultLockManagerImpl.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/vault/manager/VaultLockManagerImpl.kt @@ -9,6 +9,7 @@ import com.bitwarden.core.InitUserCryptoMethod import com.bitwarden.core.InitUserCryptoRequest import com.bitwarden.core.data.repository.util.bufferedMutableSharedFlow import com.bitwarden.core.data.util.asSuccess +import com.bitwarden.core.data.util.concurrentMapOf import com.bitwarden.core.data.util.flatMap import com.bitwarden.crypto.HashPurpose import com.bitwarden.crypto.Kdf @@ -58,7 +59,6 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import java.time.Clock -import java.util.concurrent.ConcurrentHashMap import kotlin.time.Duration.Companion.minutes /** @@ -88,7 +88,7 @@ class VaultLockManagerImpl( * This [Map] tracks all active timeout [Job]s that are running and their associated data using * the user ID as the key. */ - private val userIdTimerJobMap: MutableMap = ConcurrentHashMap() + private val userIdTimerJobMap: MutableMap = concurrentMapOf() private val activeUserId: String? get() = authDiskSource.userState?.activeUserId diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/coachmark/CoachMarkState.kt b/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/coachmark/CoachMarkState.kt index d9df759cd1..baa187081f 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/coachmark/CoachMarkState.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/coachmark/CoachMarkState.kt @@ -8,10 +8,10 @@ import androidx.compose.runtime.saveable.Saver import androidx.compose.runtime.saveable.listSaver import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.geometry.Rect +import com.bitwarden.core.data.util.concurrentMapOf import com.x8bit.bitwarden.ui.platform.components.coachmark.model.CoachMarkHighlightShape import com.x8bit.bitwarden.ui.platform.components.coachmark.model.CoachMarkHighlightState import com.x8bit.bitwarden.ui.platform.components.tooltip.BitwardenToolTipState -import java.util.concurrent.ConcurrentHashMap import kotlin.math.max import kotlin.math.min @@ -33,7 +33,7 @@ open class CoachMarkState>( initialCoachMarkHighlight: T? = null, isCoachMarkVisible: Boolean = false, ) { - private val highlights: MutableMap?> = ConcurrentHashMap() + private val highlights: MutableMap?> = concurrentMapOf() private val mutableCurrentHighlight = mutableStateOf(initialCoachMarkHighlight) val currentHighlight: State = mutableCurrentHighlight private val mutableCurrentHighlightBounds = mutableStateOf(Rect.Zero) diff --git a/core/src/main/kotlin/com/bitwarden/core/data/util/MapUtil.kt b/core/src/main/kotlin/com/bitwarden/core/data/util/MapUtil.kt new file mode 100644 index 0000000000..e542e74387 --- /dev/null +++ b/core/src/main/kotlin/com/bitwarden/core/data/util/MapUtil.kt @@ -0,0 +1,13 @@ +@file:OmitFromCoverage + +package com.bitwarden.core.data.util + +import com.bitwarden.core.annotation.OmitFromCoverage +import java.util.concurrent.ConcurrentHashMap + +/** + * Creates a thread-safe [MutableMap]. + */ +fun concurrentMapOf( + vararg items: Pair, +): MutableMap = ConcurrentHashMap().apply { this.putAll(items) }