diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/auth/feature/environment/EnvironmentViewModel.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/auth/feature/environment/EnvironmentViewModel.kt index c34082cd14..e18738936d 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/auth/feature/environment/EnvironmentViewModel.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/auth/feature/environment/EnvironmentViewModel.kt @@ -11,6 +11,7 @@ import com.bitwarden.ui.platform.base.BaseViewModel import com.bitwarden.ui.platform.base.util.isValidUri import com.bitwarden.ui.platform.base.util.orNullIfBlank import com.bitwarden.ui.platform.base.util.prefixHttpsIfNecessaryOrNull +import com.bitwarden.ui.platform.model.FileData import com.bitwarden.ui.platform.resource.BitwardenString import com.bitwarden.ui.util.Text import com.bitwarden.ui.util.asText @@ -20,7 +21,6 @@ import com.x8bit.bitwarden.data.platform.manager.model.ImportPrivateKeyResult import com.x8bit.bitwarden.data.platform.repository.EnvironmentRepository import com.x8bit.bitwarden.data.vault.manager.FileManager import com.x8bit.bitwarden.ui.platform.components.snackbar.BitwardenSnackbarData -import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager import com.x8bit.bitwarden.ui.platform.manager.keychain.model.PrivateKeyAliasSelectionResult import com.x8bit.bitwarden.ui.platform.manager.snackbar.SnackbarRelay import com.x8bit.bitwarden.ui.platform.manager.snackbar.SnackbarRelayManager @@ -481,7 +481,7 @@ data class EnvironmentState( * Show a dialog to capture the certificate alias and password. */ data class SetCertificateData( - val certificateBytes: IntentManager.FileData, + val certificateBytes: FileData, ) : DialogState() /** @@ -626,7 +626,7 @@ sealed class EnvironmentAction { * Indicates that the certificate file selection result was received. */ data class ImportCertificateFilePickerResultReceive( - val certificateFileData: IntentManager.FileData, + val certificateFileData: FileData, ) : EnvironmentAction() /** @@ -634,7 +634,7 @@ sealed class EnvironmentAction { */ @Parcelize data class SetCertificateInfoResultReceive( - val certificateFileData: IntentManager.FileData, + val certificateFileData: FileData, val password: String, val alias: String, ) : EnvironmentAction(), Parcelable diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/manager/intent/IntentManager.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/manager/intent/IntentManager.kt index 946f3c7dc3..2b7386cd31 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/manager/intent/IntentManager.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/manager/intent/IntentManager.kt @@ -8,6 +8,7 @@ import androidx.activity.compose.ManagedActivityResultLauncher import androidx.activity.result.ActivityResult import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable +import com.bitwarden.ui.platform.model.FileData import com.x8bit.bitwarden.data.autofill.model.browser.BrowserPackage import kotlinx.parcelize.Parcelize @@ -82,11 +83,6 @@ interface IntentManager { */ fun getFileDataFromActivityResult(activityResult: ActivityResult): FileData? - /** - * Processes the [intent] and attempts to get the relevant file data from it. - */ - fun getFileDataFromIntent(intent: Intent): FileData? - /** * Processes the [intent] and attempts to derive [ShareData] information from it. */ @@ -107,16 +103,6 @@ interface IntentManager { */ fun startDefaultEmailApplication() - /** - * Represents file information. - */ - @Parcelize - data class FileData( - val fileName: String, - val uri: Uri, - val sizeBytes: Long, - ) : Parcelable - /** * Represents data for a share request coming from outside the app. */ diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/manager/intent/IntentManagerImpl.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/manager/intent/IntentManagerImpl.kt index e002f68f8b..73f57cb331 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/manager/intent/IntentManagerImpl.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/manager/intent/IntentManagerImpl.kt @@ -25,6 +25,7 @@ import androidx.credentials.CredentialManager import com.bitwarden.annotation.OmitFromCoverage import com.bitwarden.core.data.util.toFormattedPattern import com.bitwarden.core.util.isBuildVersionAtLeast +import com.bitwarden.ui.platform.model.FileData import com.bitwarden.ui.platform.resource.BitwardenString import com.x8bit.bitwarden.BuildConfig import com.x8bit.bitwarden.data.autofill.model.browser.BrowserPackage @@ -175,15 +176,15 @@ class IntentManagerImpl( override fun getFileDataFromActivityResult( activityResult: ActivityResult, - ): IntentManager.FileData? { + ): FileData? { if (activityResult.resultCode != Activity.RESULT_OK) return null val uri = activityResult.data?.data return if (uri != null) getLocalFileData(uri) else getCameraFileData() } - override fun getFileDataFromIntent( + private fun getFileDataFromIntent( intent: Intent, - ): IntentManager.FileData? = intent + ): FileData? = intent .clipData ?.getItemAt(0) ?.uri @@ -275,19 +276,19 @@ class IntentManagerImpl( return Intent(Intent.ACTION_VIEW, playStoreUri) } - private fun getCameraFileData(): IntentManager.FileData { + private fun getCameraFileData(): FileData { val tmpDir = File(context.filesDir, TEMP_CAMERA_IMAGE_DIR) val file = File(tmpDir, TEMP_CAMERA_IMAGE_NAME) val uri = FileProvider.getUriForFile(context, FILE_PROVIDER_AUTHORITY, file) val fileName = "photo_${clock.instant().toFormattedPattern(pattern = "yyyyMMddHHmmss")}.jpg" - return IntentManager.FileData( + return FileData( fileName = fileName, uri = uri, sizeBytes = file.length(), ) } - private fun getLocalFileData(uri: Uri): IntentManager.FileData? = + private fun getLocalFileData(uri: Uri): FileData? = context .contentResolver .query( @@ -306,12 +307,13 @@ class IntentManagerImpl( .getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME) .takeIf { it >= 0 } ?.let { cursor.getString(it) } + ?: return@use null val fileSize = cursor .getColumnIndex(MediaStore.MediaColumns.SIZE) .takeIf { it >= 0 } ?.let { cursor.getLong(it) } - if (fileName == null || fileSize == null) return@use null - IntentManager.FileData( + ?: return@use null + FileData( fileName = fileName, uri = uri, sizeBytes = fileSize, diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendViewModel.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendViewModel.kt index f67225bed8..01f39b5388 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendViewModel.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendViewModel.kt @@ -11,6 +11,7 @@ import com.bitwarden.network.model.PolicyTypeJson import com.bitwarden.send.SendView import com.bitwarden.ui.platform.base.BackgroundEvent import com.bitwarden.ui.platform.base.BaseViewModel +import com.bitwarden.ui.platform.model.FileData import com.bitwarden.ui.platform.resource.BitwardenString import com.bitwarden.ui.util.Text import com.bitwarden.ui.util.asText @@ -29,7 +30,6 @@ import com.x8bit.bitwarden.data.vault.repository.model.DeleteSendResult import com.x8bit.bitwarden.data.vault.repository.model.RemovePasswordSendResult import com.x8bit.bitwarden.data.vault.repository.model.UpdateSendResult import com.x8bit.bitwarden.ui.platform.components.snackbar.BitwardenSnackbarData -import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager import com.x8bit.bitwarden.ui.platform.manager.snackbar.SnackbarRelay import com.x8bit.bitwarden.ui.platform.manager.snackbar.SnackbarRelayManager import com.x8bit.bitwarden.ui.tools.feature.send.addedit.model.AddEditSendType @@ -889,7 +889,7 @@ sealed class AddEditSendAction { /** * User has chosen a file to be part of the send. */ - data class FileChoose(val fileData: IntentManager.FileData) : AddEditSendAction() + data class FileChoose(val fileData: FileData) : AddEditSendAction() /** * User clicked the remove password button. diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/handlers/AddEditSendHandlers.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/handlers/AddEditSendHandlers.kt index 369c2622a7..d51c2b4fca 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/handlers/AddEditSendHandlers.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/handlers/AddEditSendHandlers.kt @@ -1,6 +1,6 @@ package com.x8bit.bitwarden.ui.tools.feature.send.addedit.handlers -import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager +import com.bitwarden.ui.platform.model.FileData import com.x8bit.bitwarden.ui.tools.feature.send.addedit.AddEditSendAction import com.x8bit.bitwarden.ui.tools.feature.send.addedit.AddEditSendViewModel import java.time.ZonedDateTime @@ -12,7 +12,7 @@ import java.time.ZonedDateTime data class AddEditSendHandlers( val onNameChange: (String) -> Unit, val onChooseFileClick: (hasPermission: Boolean) -> Unit, - val onFileChoose: (IntentManager.FileData) -> Unit, + val onFileChoose: (FileData) -> Unit, val onTextChange: (String) -> Unit, val onIsHideByDefaultToggle: (Boolean) -> Unit, val onMaxAccessCountChange: (Int) -> Unit, diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/attachments/AttachmentsViewModel.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/attachments/AttachmentsViewModel.kt index 7531a9cb43..53d00a93d5 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/attachments/AttachmentsViewModel.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/attachments/AttachmentsViewModel.kt @@ -6,6 +6,7 @@ import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.viewModelScope import com.bitwarden.core.data.repository.model.DataState import com.bitwarden.ui.platform.base.BaseViewModel +import com.bitwarden.ui.platform.model.FileData import com.bitwarden.ui.platform.resource.BitwardenString import com.bitwarden.ui.util.Text import com.bitwarden.ui.util.asText @@ -17,7 +18,6 @@ import com.x8bit.bitwarden.data.vault.repository.VaultRepository import com.x8bit.bitwarden.data.vault.repository.model.CreateAttachmentResult import com.x8bit.bitwarden.data.vault.repository.model.DeleteAttachmentResult import com.x8bit.bitwarden.ui.platform.components.snackbar.BitwardenSnackbarData -import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager import com.x8bit.bitwarden.ui.vault.feature.attachments.util.toViewState import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.launchIn @@ -488,7 +488,7 @@ sealed class AttachmentsAction { * User has chosen the file attachment. */ data class FileChoose( - val fileData: IntentManager.FileData, + val fileData: FileData, ) : AttachmentsAction() /** diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/attachments/handlers/AttachmentsHandlers.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/attachments/handlers/AttachmentsHandlers.kt index a166d1e488..cf0f64c8b6 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/attachments/handlers/AttachmentsHandlers.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/attachments/handlers/AttachmentsHandlers.kt @@ -1,6 +1,6 @@ package com.x8bit.bitwarden.ui.vault.feature.attachments.handlers -import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager +import com.bitwarden.ui.platform.model.FileData import com.x8bit.bitwarden.ui.vault.feature.attachments.AttachmentsAction import com.x8bit.bitwarden.ui.vault.feature.attachments.AttachmentsViewModel @@ -11,7 +11,7 @@ data class AttachmentsHandlers( val onBackClick: () -> Unit, val onSaveClick: () -> Unit, val onChooseFileClick: () -> Unit, - val onFileChoose: (IntentManager.FileData) -> Unit, + val onFileChoose: (FileData) -> Unit, val onDeleteClick: (attachmentId: String) -> Unit, val onDismissRequest: () -> Unit, ) { diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/auth/feature/environment/EnvironmentScreenTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/auth/feature/environment/EnvironmentScreenTest.kt index 4a9c4790cc..e6cc8d4d0b 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/auth/feature/environment/EnvironmentScreenTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/auth/feature/environment/EnvironmentScreenTest.kt @@ -13,6 +13,7 @@ import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performScrollTo import androidx.compose.ui.test.performTextInput import com.bitwarden.core.data.repository.util.bufferedMutableSharedFlow +import com.bitwarden.ui.platform.model.FileData import com.bitwarden.ui.util.asText import com.x8bit.bitwarden.ui.auth.feature.environment.EnvironmentState.DialogState import com.x8bit.bitwarden.ui.platform.base.BitwardenComposeTest @@ -366,7 +367,7 @@ class EnvironmentScreenTest : BitwardenComposeTest() { @Suppress("MaxLineLength") @Test fun `ConfirmOverwriteCertificate dialog Replace certificate click should send ConfirmOverwriteCertificate action`() { - val mockFileData = mockk() + val mockFileData = mockk() mutableStateFlow.update { it.copy( dialog = DialogState.ConfirmOverwriteAlias( diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/auth/feature/environment/EnvironmentViewModelTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/auth/feature/environment/EnvironmentViewModelTest.kt index 8719e5dd3e..20aee92007 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/auth/feature/environment/EnvironmentViewModelTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/auth/feature/environment/EnvironmentViewModelTest.kt @@ -7,6 +7,7 @@ import com.bitwarden.core.data.util.asSuccess import com.bitwarden.data.datasource.disk.model.EnvironmentUrlDataJson import com.bitwarden.data.repository.model.Environment import com.bitwarden.ui.platform.base.BaseViewModelTest +import com.bitwarden.ui.platform.model.FileData import com.bitwarden.ui.platform.resource.BitwardenString import com.bitwarden.ui.util.asText import com.x8bit.bitwarden.data.platform.datasource.disk.model.MutualTlsKeyHost @@ -15,7 +16,6 @@ import com.x8bit.bitwarden.data.platform.manager.model.ImportPrivateKeyResult import com.x8bit.bitwarden.data.platform.repository.util.FakeEnvironmentRepository import com.x8bit.bitwarden.data.vault.manager.FileManager import com.x8bit.bitwarden.ui.platform.components.snackbar.BitwardenSnackbarData -import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager import com.x8bit.bitwarden.ui.platform.manager.keychain.model.PrivateKeyAliasSelectionResult import com.x8bit.bitwarden.ui.platform.manager.snackbar.SnackbarRelay import com.x8bit.bitwarden.ui.platform.manager.snackbar.SnackbarRelayManager @@ -423,7 +423,7 @@ class EnvironmentViewModelTest : BaseViewModelTest() { fun `ImportCertificateFilePickerResultReceive should show SetCertificateData dialog`() = runTest { val viewModel = createViewModel() - val mockFileData = mockk() + val mockFileData = mockk() viewModel.trySendAction( EnvironmentAction.ImportCertificateFilePickerResultReceive( certificateFileData = mockFileData, @@ -587,7 +587,7 @@ class EnvironmentViewModelTest : BaseViewModelTest() { runTest { val viewModel = createViewModel() val mockUri = mockk() - val mockFileData = IntentManager.FileData( + val mockFileData = FileData( fileName = "mockFileName", uri = mockUri, sizeBytes = 0, @@ -708,7 +708,7 @@ class EnvironmentViewModelTest : BaseViewModelTest() { runTest { val viewModel = createViewModel() val mockUri = mockk() - val mockFileData = IntentManager.FileData( + val mockFileData = FileData( fileName = "mockFileName", uri = mockUri, sizeBytes = 0, @@ -740,7 +740,7 @@ class EnvironmentViewModelTest : BaseViewModelTest() { fun `ConfirmOverwriteCertificateClick should clear dialog and import certificate`() = runTest { val viewModel = createViewModel() val mockUri = mockk() - val mockFileData = IntentManager.FileData( + val mockFileData = FileData( fileName = "mockFileName", uri = mockUri, sizeBytes = 0, diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendViewModelTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendViewModelTest.kt index 8feb6b5985..462cf6e829 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendViewModelTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendViewModelTest.kt @@ -9,6 +9,7 @@ import com.bitwarden.network.model.PolicyTypeJson import com.bitwarden.network.model.SyncResponseJson import com.bitwarden.send.SendView import com.bitwarden.ui.platform.base.BaseViewModelTest +import com.bitwarden.ui.platform.model.FileData import com.bitwarden.ui.platform.resource.BitwardenString import com.bitwarden.ui.util.Text import com.bitwarden.ui.util.asText @@ -29,7 +30,6 @@ import com.x8bit.bitwarden.data.vault.repository.model.DeleteSendResult import com.x8bit.bitwarden.data.vault.repository.model.RemovePasswordSendResult import com.x8bit.bitwarden.data.vault.repository.model.UpdateSendResult import com.x8bit.bitwarden.ui.platform.components.snackbar.BitwardenSnackbarData -import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager import com.x8bit.bitwarden.ui.platform.manager.snackbar.SnackbarRelay import com.x8bit.bitwarden.ui.platform.manager.snackbar.SnackbarRelayManager import com.x8bit.bitwarden.ui.tools.feature.send.addedit.model.AddEditSendType @@ -799,7 +799,7 @@ class AddEditSendViewModelTest : BaseViewModelTest() { val fileName = "test.png" val uri = mockk() val size = 50L - val fileData = IntentManager.FileData( + val fileData = FileData( fileName = fileName, uri = uri, sizeBytes = size, diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/util/SpecialCircumstanceExtensionsTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/util/SpecialCircumstanceExtensionsTest.kt index f4cb414417..e45c02fcc0 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/util/SpecialCircumstanceExtensionsTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/util/SpecialCircumstanceExtensionsTest.kt @@ -1,6 +1,7 @@ package com.x8bit.bitwarden.ui.tools.feature.send.addedit.util import android.net.Uri +import com.bitwarden.ui.platform.model.FileData import com.x8bit.bitwarden.data.platform.manager.model.SpecialCircumstance import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager import com.x8bit.bitwarden.ui.tools.feature.send.addedit.AddEditSendState @@ -46,7 +47,7 @@ class SpecialCircumstanceExtensionsTest { ) val specialCircumstance = SpecialCircumstance.ShareNewSend( data = IntentManager.ShareData.FileSend( - fileData = IntentManager.FileData( + fileData = FileData( fileName = fileName, uri = uri, sizeBytes = sizeBytes, @@ -87,7 +88,7 @@ class SpecialCircumstanceExtensionsTest { val fileName = "File Name" val specialCircumstance = SpecialCircumstance.ShareNewSend( data = IntentManager.ShareData.FileSend( - fileData = IntentManager.FileData( + fileData = FileData( fileName = fileName, uri = mockk(), sizeBytes = 0L, diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/attachments/AttachmentsViewModelTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/attachments/AttachmentsViewModelTest.kt index 8fd8152f35..6e92ec9c9e 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/attachments/AttachmentsViewModelTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/attachments/AttachmentsViewModelTest.kt @@ -6,6 +6,7 @@ import app.cash.turbine.test import com.bitwarden.core.data.repository.model.DataState import com.bitwarden.data.repository.model.Environment import com.bitwarden.ui.platform.base.BaseViewModelTest +import com.bitwarden.ui.platform.model.FileData import com.bitwarden.ui.platform.resource.BitwardenString import com.bitwarden.ui.util.asText import com.bitwarden.ui.util.concat @@ -19,7 +20,6 @@ import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockCipherView import com.x8bit.bitwarden.data.vault.repository.VaultRepository import com.x8bit.bitwarden.data.vault.repository.model.CreateAttachmentResult import com.x8bit.bitwarden.data.vault.repository.model.DeleteAttachmentResult -import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager import com.x8bit.bitwarden.ui.vault.feature.attachments.util.toViewState import io.mockk.coEvery import io.mockk.coVerify @@ -159,7 +159,7 @@ class AttachmentsViewModelTest : BaseViewModelTest() { ), isPremiumUser = true, ) - val fileData = IntentManager.FileData( + val fileData = FileData( fileName = fileName, uri = uri, sizeBytes = sizeToBig, @@ -204,7 +204,7 @@ class AttachmentsViewModelTest : BaseViewModelTest() { ), isPremiumUser = true, ) - val fileData = IntentManager.FileData( + val fileData = FileData( fileName = fileName, uri = uri, sizeBytes = sizeJustRight, @@ -279,7 +279,7 @@ class AttachmentsViewModelTest : BaseViewModelTest() { ), isPremiumUser = true, ) - val fileData = IntentManager.FileData( + val fileData = FileData( fileName = fileName, uri = uri, sizeBytes = sizeJustRight, @@ -350,7 +350,7 @@ class AttachmentsViewModelTest : BaseViewModelTest() { ), isPremiumUser = true, ) - val fileData = IntentManager.FileData( + val fileData = FileData( fileName = fileName, uri = uri, sizeBytes = sizeJustRight, @@ -414,7 +414,7 @@ class AttachmentsViewModelTest : BaseViewModelTest() { @Test fun `ChooseFile should update state with new file data`() = runTest { val uri = createMockUri() - val fileData = IntentManager.FileData( + val fileData = FileData( fileName = "filename-1", uri = uri, sizeBytes = 100L, diff --git a/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/authenticator/repository/AuthenticatorRepository.kt b/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/authenticator/repository/AuthenticatorRepository.kt index 2ee141ce4a..740c7af44e 100644 --- a/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/authenticator/repository/AuthenticatorRepository.kt +++ b/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/authenticator/repository/AuthenticatorRepository.kt @@ -11,8 +11,8 @@ import com.bitwarden.authenticator.data.authenticator.repository.model.TotpCodeR import com.bitwarden.authenticator.data.platform.manager.imports.model.ImportDataResult import com.bitwarden.authenticator.data.platform.manager.imports.model.ImportFileFormat import com.bitwarden.authenticator.ui.platform.feature.settings.export.model.ExportVaultFormat -import com.bitwarden.authenticator.ui.platform.manager.intent.IntentManager import com.bitwarden.core.data.repository.model.DataState +import com.bitwarden.ui.platform.model.FileData import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow @@ -82,7 +82,7 @@ interface AuthenticatorRepository { */ suspend fun importVaultData( format: ImportFileFormat, - fileData: IntentManager.FileData, + fileData: FileData, ): ImportDataResult /** diff --git a/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/authenticator/repository/AuthenticatorRepositoryImpl.kt b/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/authenticator/repository/AuthenticatorRepositoryImpl.kt index 017ad997c1..1b22a829c1 100644 --- a/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/authenticator/repository/AuthenticatorRepositoryImpl.kt +++ b/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/authenticator/repository/AuthenticatorRepositoryImpl.kt @@ -21,13 +21,13 @@ import com.bitwarden.authenticator.data.platform.manager.imports.model.ImportDat import com.bitwarden.authenticator.data.platform.manager.imports.model.ImportFileFormat import com.bitwarden.authenticator.data.platform.repository.SettingsRepository import com.bitwarden.authenticator.ui.platform.feature.settings.export.model.ExportVaultFormat -import com.bitwarden.authenticator.ui.platform.manager.intent.IntentManager import com.bitwarden.authenticatorbridge.manager.AuthenticatorBridgeManager import com.bitwarden.authenticatorbridge.manager.model.AccountSyncState import com.bitwarden.core.data.repository.model.DataState import com.bitwarden.core.data.repository.util.bufferedMutableSharedFlow import com.bitwarden.core.data.repository.util.map import com.bitwarden.data.manager.DispatcherManager +import com.bitwarden.ui.platform.model.FileData import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.Channel @@ -248,7 +248,7 @@ class AuthenticatorRepositoryImpl @Inject constructor( override suspend fun importVaultData( format: ImportFileFormat, - fileData: IntentManager.FileData, + fileData: FileData, ): ImportDataResult = fileManager.uriToByteArray(fileData.uri) .map { importManager diff --git a/authenticator/src/main/kotlin/com/bitwarden/authenticator/ui/platform/feature/settings/importing/ImportingScreen.kt b/authenticator/src/main/kotlin/com/bitwarden/authenticator/ui/platform/feature/settings/importing/ImportingScreen.kt index a60c75983f..2a9033457e 100644 --- a/authenticator/src/main/kotlin/com/bitwarden/authenticator/ui/platform/feature/settings/importing/ImportingScreen.kt +++ b/authenticator/src/main/kotlin/com/bitwarden/authenticator/ui/platform/feature/settings/importing/ImportingScreen.kt @@ -38,6 +38,7 @@ import com.bitwarden.authenticator.ui.platform.composition.LocalIntentManager import com.bitwarden.authenticator.ui.platform.manager.intent.IntentManager import com.bitwarden.authenticator.ui.platform.util.displayLabel import com.bitwarden.ui.platform.base.util.EventsEffect +import com.bitwarden.ui.platform.model.FileData import com.bitwarden.ui.platform.resource.BitwardenDrawable import com.bitwarden.ui.platform.resource.BitwardenString import kotlinx.collections.immutable.toImmutableList @@ -54,7 +55,7 @@ fun ImportingScreen( onNavigateBack: () -> Unit, ) { val state by viewModel.stateFlow.collectAsStateWithLifecycle() - val importLocationReceive: (IntentManager.FileData) -> Unit = remember { + val importLocationReceive: (FileData) -> Unit = remember { { viewModel.trySendAction(ImportAction.ImportLocationReceive(it)) } diff --git a/authenticator/src/main/kotlin/com/bitwarden/authenticator/ui/platform/feature/settings/importing/ImportingViewModel.kt b/authenticator/src/main/kotlin/com/bitwarden/authenticator/ui/platform/feature/settings/importing/ImportingViewModel.kt index 7e2f2b40c2..7350bb537d 100644 --- a/authenticator/src/main/kotlin/com/bitwarden/authenticator/ui/platform/feature/settings/importing/ImportingViewModel.kt +++ b/authenticator/src/main/kotlin/com/bitwarden/authenticator/ui/platform/feature/settings/importing/ImportingViewModel.kt @@ -5,8 +5,8 @@ import androidx.lifecycle.viewModelScope import com.bitwarden.authenticator.data.authenticator.repository.AuthenticatorRepository import com.bitwarden.authenticator.data.platform.manager.imports.model.ImportDataResult import com.bitwarden.authenticator.data.platform.manager.imports.model.ImportFileFormat -import com.bitwarden.authenticator.ui.platform.manager.intent.IntentManager import com.bitwarden.ui.platform.base.BaseViewModel +import com.bitwarden.ui.platform.model.FileData import com.bitwarden.ui.platform.resource.BitwardenString import com.bitwarden.ui.util.Text import com.bitwarden.ui.util.asText @@ -202,7 +202,7 @@ sealed class ImportAction { /** * Indicates the user selected a file to import. */ - data class ImportLocationReceive(val fileUri: IntentManager.FileData) : ImportAction() + data class ImportLocationReceive(val fileUri: FileData) : ImportAction() /** * Models actions the [ImportingScreen] itself may send. diff --git a/authenticator/src/main/kotlin/com/bitwarden/authenticator/ui/platform/manager/intent/IntentManager.kt b/authenticator/src/main/kotlin/com/bitwarden/authenticator/ui/platform/manager/intent/IntentManager.kt index ce4b54d52e..7c0a724a0f 100644 --- a/authenticator/src/main/kotlin/com/bitwarden/authenticator/ui/platform/manager/intent/IntentManager.kt +++ b/authenticator/src/main/kotlin/com/bitwarden/authenticator/ui/platform/manager/intent/IntentManager.kt @@ -2,12 +2,11 @@ package com.bitwarden.authenticator.ui.platform.manager.intent import android.content.Intent import android.net.Uri -import android.os.Parcelable import androidx.activity.compose.ManagedActivityResultLauncher import androidx.activity.result.ActivityResult import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable -import kotlinx.parcelize.Parcelize +import com.bitwarden.ui.platform.model.FileData /** * A manager class for simplifying the handling of Android Intents within a given context. @@ -58,14 +57,4 @@ interface IntentManager { * Creates an intent to use when selecting to save an item with [fileName] to disk. */ fun createDocumentIntent(fileName: String): Intent - - /** - * Represents file information. - */ - @Parcelize - data class FileData( - val fileName: String, - val uri: Uri, - val sizeBytes: Long, - ) : Parcelable } diff --git a/authenticator/src/main/kotlin/com/bitwarden/authenticator/ui/platform/manager/intent/IntentManagerImpl.kt b/authenticator/src/main/kotlin/com/bitwarden/authenticator/ui/platform/manager/intent/IntentManagerImpl.kt index 0445a105b6..021aaf7aa7 100644 --- a/authenticator/src/main/kotlin/com/bitwarden/authenticator/ui/platform/manager/intent/IntentManagerImpl.kt +++ b/authenticator/src/main/kotlin/com/bitwarden/authenticator/ui/platform/manager/intent/IntentManagerImpl.kt @@ -16,6 +16,7 @@ import androidx.compose.runtime.Composable import androidx.core.content.ContextCompat import androidx.core.net.toUri import com.bitwarden.annotation.OmitFromCoverage +import com.bitwarden.ui.platform.model.FileData import com.bitwarden.ui.platform.resource.BitwardenString /** @@ -45,7 +46,7 @@ class IntentManagerImpl( override fun getFileDataFromActivityResult( activityResult: ActivityResult, - ): IntentManager.FileData? { + ): FileData? { if (activityResult.resultCode != Activity.RESULT_OK) return null val uri = activityResult.data?.data ?: return null return getLocalFileData(uri) @@ -66,9 +67,8 @@ class IntentManagerImpl( Intent(Intent.ACTION_CREATE_DOCUMENT).apply { // Attempt to get the MIME type from the file extension val extension = MimeTypeMap.getFileExtensionFromUrl(fileName) - type = extension?.let { - MimeTypeMap.getSingleton().getMimeTypeFromExtension(it) - } + type = extension + ?.let { MimeTypeMap.getSingleton().getMimeTypeFromExtension(it) } ?: "*/*" addCategory(Intent.CATEGORY_OPENABLE) @@ -77,7 +77,7 @@ class IntentManagerImpl( override fun startApplicationDetailsSettingsActivity() { val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) - intent.data = Uri.parse("package:" + context.packageName) + intent.data = "package:$context.packageName".toUri() startActivity(intent = intent) } @@ -101,7 +101,7 @@ class IntentManagerImpl( ) } - private fun getLocalFileData(uri: Uri): IntentManager.FileData? = + private fun getLocalFileData(uri: Uri): FileData? = context .contentResolver .query( @@ -120,12 +120,13 @@ class IntentManagerImpl( .getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME) .takeIf { it >= 0 } ?.let { cursor.getString(it) } + ?: return@use null val fileSize = cursor .getColumnIndex(MediaStore.MediaColumns.SIZE) .takeIf { it >= 0 } ?.let { cursor.getLong(it) } - if (fileName == null || fileSize == null) return@use null - IntentManager.FileData( + ?: return@use null + FileData( fileName = fileName, uri = uri, sizeBytes = fileSize, diff --git a/ui/src/main/kotlin/com/bitwarden/ui/platform/model/FileData.kt b/ui/src/main/kotlin/com/bitwarden/ui/platform/model/FileData.kt new file mode 100644 index 0000000000..33f17f7521 --- /dev/null +++ b/ui/src/main/kotlin/com/bitwarden/ui/platform/model/FileData.kt @@ -0,0 +1,15 @@ +package com.bitwarden.ui.platform.model + +import android.net.Uri +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +/** + * Represents file information. + */ +@Parcelize +data class FileData( + val fileName: String, + val uri: Uri, + val sizeBytes: Long, +) : Parcelable