srctree

Robin Linden parent d708b8d5 e4101207
Bless SaveManager with an interface

This is both for potential future multi-platform aTox, and to allow usto use something like Mockito instead of MockK should we want to.

inlinesplit
atox/src/androidTest/kotlin/IntegrationTest.kt added: 32, removed: 12, total 20
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2020-2021 aTox contributors
// SPDX-FileCopyrightText: 2020-2022 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: GPL-3.0-only
 
@@ -25,12 +25,15 @@ import dagger.Module
import dagger.Provides
import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import ltd.evilcorp.atox.di.AndroidModule
import ltd.evilcorp.atox.di.AppComponent
import ltd.evilcorp.atox.di.AppModule
import ltd.evilcorp.atox.di.DaoModule
import ltd.evilcorp.atox.di.ViewModelModule
import ltd.evilcorp.atox.tox.BootstrapNodeRegistryImpl
import ltd.evilcorp.core.db.Database
import ltd.evilcorp.domain.tox.BootstrapNodeRegistry
import ltd.evilcorp.domain.tox.PublicKey
import ltd.evilcorp.domain.tox.SaveManager
import org.hamcrest.core.AllOf.allOf
@@ -62,12 +65,17 @@ class TestModule {
every { load(PublicKey("workaround")) } returns null
// Am I using mockk wrong or something? `every { save(any(), any() }` crashes.
}
 
@Provides
fun provideBootstrapNodeRegistry(nodeRegistry: BootstrapNodeRegistryImpl): BootstrapNodeRegistry = nodeRegistry
 
@Provides
fun provideCoroutineScope(): CoroutineScope = CoroutineScope(Dispatchers.Default)
}
 
@Singleton
@Component(
modules = [
AppModule::class,
AndroidModule::class,
TestModule::class,
DaoModule::class,
 
atox/src/main/kotlin/di/AppModule.kt added: 32, removed: 12, total 20
@@ -1,15 +1,18 @@
// SPDX-FileCopyrightText: 2021 aTox contributors
// SPDX-FileCopyrightText: 2021-2022 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: GPL-3.0-only
 
package ltd.evilcorp.atox.di
 
import android.content.Context
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import ltd.evilcorp.atox.tox.BootstrapNodeRegistryImpl
import ltd.evilcorp.domain.tox.AndroidSaveManager
import ltd.evilcorp.domain.tox.BootstrapNodeRegistry
import ltd.evilcorp.domain.tox.SaveManager
 
@Module
class AppModule {
@@ -18,4 +21,7 @@ class AppModule {
 
@Provides
fun provideCoroutineScope(): CoroutineScope = CoroutineScope(Dispatchers.Default)
 
@Provides
fun provideSaveManager(ctx: Context): SaveManager = AndroidSaveManager(ctx)
}
 
domain/src/main/kotlin/tox/SaveManager.kt added: 32, removed: 12, total 20
@@ -11,9 +11,15 @@ import androidx.core.util.writeBytes
import java.io.File
import javax.inject.Inject
 
private const val TAG = "SaveManager"
private const val TAG = "AndroidSaveManager"
 
class SaveManager @Inject constructor(val context: Context) {
interface SaveManager {
fun list(): List<String>
fun save(pk: PublicKey, saveData: ByteArray)
fun load(pk: PublicKey): ByteArray?
}
 
class AndroidSaveManager @Inject constructor(val context: Context) : SaveManager {
private val saveDir = context.filesDir
 
init {
@@ -22,16 +28,16 @@ class SaveManager @Inject constructor(val context: Context) {
}
}
 
fun list(): List<String> = saveDir.listFiles()?.let { saves ->
override fun list(): List<String> = saveDir.listFiles()?.let { saves ->
saves.filter { it.extension == "tox" }.map { it.nameWithoutExtension }
} ?: listOf()
 
fun save(publicKey: PublicKey, saveData: ByteArray) = AtomicFile(File("$saveDir/${publicKey.string()}.tox")).run {
override fun save(pk: PublicKey, saveData: ByteArray) = AtomicFile(File("$saveDir/${pk.string()}.tox")).run {
Log.i(TAG, "Saving profile to $baseFile")
writeBytes(saveData)
}
 
fun load(publicKey: PublicKey): ByteArray? = tryReadBytes(File(pathTo(publicKey)))
override fun load(pk: PublicKey): ByteArray? = tryReadBytes(File(pathTo(pk)))
 
private fun tryReadBytes(saveFile: File): ByteArray? =
if (saveFile.exists()) {