From 22cdcc0aecb5fe8bdf5230926cf4042ba69e9fba Mon Sep 17 00:00:00 2001 From: Andre Rosado Date: Tue, 3 Mar 2026 13:46:42 +0000 Subject: [PATCH 1/3] Improved pre-polutated data on the FlightRecorder logs --- .../feature/settings/about/AboutViewModel.kt | 2 +- .../settings/about/AboutViewModelTest.kt | 2 +- .../util/BuildInfoManagerExtensions.kt | 2 +- .../data/manager/di/DataManagerModule.kt | 3 ++ .../FlightRecorderWriterImpl.kt | 28 +++++++++++++++++-- .../ui/platform/manager/IntentManagerImpl.kt | 4 +-- 6 files changed, 33 insertions(+), 8 deletions(-) rename {ui/src/main/kotlin/com/bitwarden/ui/platform => core/src/main/kotlin/com/bitwarden/core/data}/manager/util/BuildInfoManagerExtensions.kt (95%) diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/about/AboutViewModel.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/about/AboutViewModel.kt index e94358e78e5..9037a71cf83 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/about/AboutViewModel.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/about/AboutViewModel.kt @@ -7,8 +7,8 @@ import com.bitwarden.core.data.manager.BuildInfoManager import com.bitwarden.data.datasource.disk.model.FlightRecorderDataSet import com.bitwarden.data.repository.ServerConfigRepository import com.bitwarden.data.repository.util.baseWebVaultUrlOrDefault +import com.bitwarden.core.data.manager.util.deviceData import com.bitwarden.ui.platform.base.BaseViewModel -import com.bitwarden.ui.platform.manager.util.deviceData import com.bitwarden.ui.util.Text import com.bitwarden.ui.util.asText import com.bitwarden.ui.util.concat diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/about/AboutViewModelTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/about/AboutViewModelTest.kt index 5d0cc29009f..cafa2a74ae8 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/about/AboutViewModelTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/about/AboutViewModelTest.kt @@ -6,9 +6,9 @@ import com.bitwarden.core.data.manager.BuildInfoManager import com.bitwarden.data.datasource.disk.model.FlightRecorderDataSet import com.bitwarden.data.datasource.disk.model.ServerConfig import com.bitwarden.data.repository.ServerConfigRepository +import com.bitwarden.core.data.manager.util.deviceData import com.bitwarden.data.repository.util.baseWebVaultUrlOrDefault import com.bitwarden.ui.platform.base.BaseViewModelTest -import com.bitwarden.ui.platform.manager.util.deviceData import com.bitwarden.ui.util.asText import com.bitwarden.ui.util.concat import com.x8bit.bitwarden.data.platform.manager.LogsManager diff --git a/ui/src/main/kotlin/com/bitwarden/ui/platform/manager/util/BuildInfoManagerExtensions.kt b/core/src/main/kotlin/com/bitwarden/core/data/manager/util/BuildInfoManagerExtensions.kt similarity index 95% rename from ui/src/main/kotlin/com/bitwarden/ui/platform/manager/util/BuildInfoManagerExtensions.kt rename to core/src/main/kotlin/com/bitwarden/core/data/manager/util/BuildInfoManagerExtensions.kt index 995ad42c412..c789159fba0 100644 --- a/ui/src/main/kotlin/com/bitwarden/ui/platform/manager/util/BuildInfoManagerExtensions.kt +++ b/core/src/main/kotlin/com/bitwarden/core/data/manager/util/BuildInfoManagerExtensions.kt @@ -1,6 +1,6 @@ @file:OmitFromCoverage -package com.bitwarden.ui.platform.manager.util +package com.bitwarden.core.data.manager.util import android.os.Build import com.bitwarden.annotation.OmitFromCoverage diff --git a/data/src/main/kotlin/com/bitwarden/data/manager/di/DataManagerModule.kt b/data/src/main/kotlin/com/bitwarden/data/manager/di/DataManagerModule.kt index d7bf729e572..a5dfca3e178 100644 --- a/data/src/main/kotlin/com/bitwarden/data/manager/di/DataManagerModule.kt +++ b/data/src/main/kotlin/com/bitwarden/data/manager/di/DataManagerModule.kt @@ -17,6 +17,7 @@ import com.bitwarden.data.manager.flightrecorder.FlightRecorderManager import com.bitwarden.data.manager.flightrecorder.FlightRecorderManagerImpl import com.bitwarden.data.manager.flightrecorder.FlightRecorderWriter import com.bitwarden.data.manager.flightrecorder.FlightRecorderWriterImpl +import com.bitwarden.data.repository.ServerConfigRepository import com.bitwarden.network.service.DownloadService import dagger.Module import dagger.Provides @@ -80,11 +81,13 @@ object DataManagerModule { fileManager: FileManager, dispatcherManager: DispatcherManager, buildInfoManager: BuildInfoManager, + serverConfigRepository: ServerConfigRepository, ): FlightRecorderWriter = FlightRecorderWriterImpl( clock = clock, fileManager = fileManager, dispatcherManager = dispatcherManager, buildInfoManager = buildInfoManager, + serverConfigRepository = serverConfigRepository, ) @Provides diff --git a/data/src/main/kotlin/com/bitwarden/data/manager/flightrecorder/FlightRecorderWriterImpl.kt b/data/src/main/kotlin/com/bitwarden/data/manager/flightrecorder/FlightRecorderWriterImpl.kt index 974a87ce437..43657516ce1 100644 --- a/data/src/main/kotlin/com/bitwarden/data/manager/flightrecorder/FlightRecorderWriterImpl.kt +++ b/data/src/main/kotlin/com/bitwarden/data/manager/flightrecorder/FlightRecorderWriterImpl.kt @@ -5,9 +5,11 @@ import android.util.Log import com.bitwarden.annotation.OmitFromCoverage import com.bitwarden.core.data.manager.BuildInfoManager import com.bitwarden.core.data.manager.dispatcher.DispatcherManager +import com.bitwarden.core.data.manager.util.deviceData import com.bitwarden.core.data.util.toFormattedPattern import com.bitwarden.data.datasource.disk.model.FlightRecorderDataSet import com.bitwarden.data.manager.file.FileManager +import com.bitwarden.data.repository.ServerConfigRepository import kotlinx.coroutines.withContext import timber.log.Timber import java.io.BufferedWriter @@ -30,6 +32,7 @@ internal class FlightRecorderWriterImpl( private val fileManager: FileManager, private val dispatcherManager: DispatcherManager, private val buildInfoManager: BuildInfoManager, + private val serverConfigRepository: ServerConfigRepository, ) : FlightRecorderWriter { override suspend fun deleteLog(data: FlightRecorderDataSet.FlightRecorderData) { fileManager.delete(File(File(fileManager.logsDirectory), data.fileName)) @@ -56,7 +59,6 @@ internal class FlightRecorderWriterImpl( val startTime = Instant .ofEpochMilli(data.startTimeMs) .toFormattedPattern(pattern = LOG_TIME_PATTERN, clock = clock) - val operatingSystem = "${Build.VERSION.RELEASE} (${Build.VERSION.SDK_INT})" // Upon creating the new file, we pre-populate it with basic data BufferedWriter(FileWriter(logFile, true)).use { bw -> bw.append("Bitwarden Android - ${buildInfoManager.applicationName}") @@ -69,10 +71,30 @@ internal class FlightRecorderWriterImpl( bw.newLine() bw.append("Build: ${buildInfoManager.buildAndFlavor}") bw.newLine() - bw.append("Operating System: $operatingSystem") + bw.append("SDK Version: \uD83E\uDD80 ${buildInfoManager.sdkData}") bw.newLine() - bw.append("Device: ${Build.BRAND} ${Build.MODEL}") + buildInfoManager.ciBuildInfo?.takeIf { it.isNotBlank() }?.let { ciInfo -> + bw.append("CI Build Info: $ciInfo") + bw.newLine() + } + bw.append("Device: ${buildInfoManager.deviceData}") + bw.newLine() + + // Server configuration data + val serverConfig = serverConfigRepository.serverConfigStateFlow.value + val serverData = serverConfig?.serverData + val serverInfo = StringBuilder() + .append("\uD83C\uDF29 Server:") + .apply { + serverData?.server?.name?.let { append(" $it") } + ?: append(" Bitwarden Cloud") + serverData?.version?.let { append(" $it") } + serverData?.environment?.cloudRegion?.let { append(" @ $it") } + } + .toString() + bw.append(serverInfo) bw.newLine() + bw.append("Fingerprint: ${Build.FINGERPRINT}") bw.newLine() } diff --git a/ui/src/main/kotlin/com/bitwarden/ui/platform/manager/IntentManagerImpl.kt b/ui/src/main/kotlin/com/bitwarden/ui/platform/manager/IntentManagerImpl.kt index f4aadf22749..1d0f3dd409e 100644 --- a/ui/src/main/kotlin/com/bitwarden/ui/platform/manager/IntentManagerImpl.kt +++ b/ui/src/main/kotlin/com/bitwarden/ui/platform/manager/IntentManagerImpl.kt @@ -26,10 +26,10 @@ import androidx.credentials.CredentialManager import com.bitwarden.annotation.OmitFromCoverage import com.bitwarden.core.data.manager.BuildInfoManager import com.bitwarden.core.data.util.toFormattedPattern +import com.bitwarden.core.data.manager.util.deviceData +import com.bitwarden.core.data.manager.util.fileProviderAuthority import com.bitwarden.core.util.isBuildVersionAtLeast import com.bitwarden.ui.platform.manager.intent.model.AuthTabData -import com.bitwarden.ui.platform.manager.util.deviceData -import com.bitwarden.ui.platform.manager.util.fileProviderAuthority import com.bitwarden.ui.platform.model.FileData import com.bitwarden.ui.platform.resource.BitwardenString import com.bitwarden.ui.platform.util.getLocalFileData From fc71ec27d83d005ee6ef9fee35f5ef7075cdaf92 Mon Sep 17 00:00:00 2001 From: Andre Rosado Date: Thu, 5 Mar 2026 12:16:25 +0000 Subject: [PATCH 2/3] removed extra breakline --- .../data/manager/flightrecorder/FlightRecorderWriterImpl.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/data/src/main/kotlin/com/bitwarden/data/manager/flightrecorder/FlightRecorderWriterImpl.kt b/data/src/main/kotlin/com/bitwarden/data/manager/flightrecorder/FlightRecorderWriterImpl.kt index 43657516ce1..e9794c6da40 100644 --- a/data/src/main/kotlin/com/bitwarden/data/manager/flightrecorder/FlightRecorderWriterImpl.kt +++ b/data/src/main/kotlin/com/bitwarden/data/manager/flightrecorder/FlightRecorderWriterImpl.kt @@ -94,7 +94,6 @@ internal class FlightRecorderWriterImpl( .toString() bw.append(serverInfo) bw.newLine() - bw.append("Fingerprint: ${Build.FINGERPRINT}") bw.newLine() } From 4500539cc746ca4072d5ecf4260236d9285c3f8f Mon Sep 17 00:00:00 2001 From: Andre Rosado Date: Wed, 11 Mar 2026 10:32:23 +0000 Subject: [PATCH 3/3] Improved code readibility --- .../FlightRecorderWriterImpl.kt | 55 +++++++------------ 1 file changed, 20 insertions(+), 35 deletions(-) diff --git a/data/src/main/kotlin/com/bitwarden/data/manager/flightrecorder/FlightRecorderWriterImpl.kt b/data/src/main/kotlin/com/bitwarden/data/manager/flightrecorder/FlightRecorderWriterImpl.kt index e9794c6da40..9ba25ecab57 100644 --- a/data/src/main/kotlin/com/bitwarden/data/manager/flightrecorder/FlightRecorderWriterImpl.kt +++ b/data/src/main/kotlin/com/bitwarden/data/manager/flightrecorder/FlightRecorderWriterImpl.kt @@ -56,46 +56,31 @@ internal class FlightRecorderWriterImpl( val logFile = File(logFolder, data.fileName) if (!logFile.exists()) { logFile.createNewFile() + + val ciInfo = buildInfoManager.ciBuildInfo?.takeIf { it.isNotBlank() } + val serverData = serverConfigRepository.serverConfigStateFlow.value?.serverData + val serverInfo = StringBuilder() + .append(serverData?.server?.name ?: "Bitwarden Cloud") + .apply { + serverData?.version?.let { append(" $it") } + serverData?.environment?.cloudRegion?.let { append(" @ $it") } + } + .toString() val startTime = Instant .ofEpochMilli(data.startTimeMs) .toFormattedPattern(pattern = LOG_TIME_PATTERN, clock = clock) // Upon creating the new file, we pre-populate it with basic data BufferedWriter(FileWriter(logFile, true)).use { bw -> - bw.append("Bitwarden Android - ${buildInfoManager.applicationName}") - bw.newLine() - bw.append("Log Start Time: $startTime") - bw.newLine() - bw.append("Log Duration: ${data.durationMs.milliseconds}") - bw.newLine() - bw.append("App Version: ${buildInfoManager.versionData}") - bw.newLine() - bw.append("Build: ${buildInfoManager.buildAndFlavor}") - bw.newLine() - bw.append("SDK Version: \uD83E\uDD80 ${buildInfoManager.sdkData}") - bw.newLine() - buildInfoManager.ciBuildInfo?.takeIf { it.isNotBlank() }?.let { ciInfo -> - bw.append("CI Build Info: $ciInfo") - bw.newLine() - } - bw.append("Device: ${buildInfoManager.deviceData}") - bw.newLine() - - // Server configuration data - val serverConfig = serverConfigRepository.serverConfigStateFlow.value - val serverData = serverConfig?.serverData - val serverInfo = StringBuilder() - .append("\uD83C\uDF29 Server:") - .apply { - serverData?.server?.name?.let { append(" $it") } - ?: append(" Bitwarden Cloud") - serverData?.version?.let { append(" $it") } - serverData?.environment?.cloudRegion?.let { append(" @ $it") } - } - .toString() - bw.append(serverInfo) - bw.newLine() - bw.append("Fingerprint: ${Build.FINGERPRINT}") - bw.newLine() + bw.appendLine("Bitwarden Android - ${buildInfoManager.applicationName}") + bw.appendLine("Log Start Time: $startTime") + bw.appendLine("Log Duration: ${data.durationMs.milliseconds}") + bw.appendLine("App Version: ${buildInfoManager.versionData}") + bw.appendLine("Build: ${buildInfoManager.buildAndFlavor}") + bw.appendLine("SDK Version: \uD83E\uDD80 ${buildInfoManager.sdkData}") + ciInfo.let { bw.appendLine("CI Build Info: $it") } + bw.appendLine("Device: ${buildInfoManager.deviceData}") + bw.appendLine("\uD83C\uDF29 Server: $serverInfo") + bw.appendLine("Fingerprint: ${Build.FINGERPRINT}") } } logFile