remove ClassicPrefsFormat
This commit is contained in:
parent
fb49c93104
commit
29da63d264
|
@ -3,7 +3,6 @@ package info.nightscout.androidaps.dependencyInjection
|
|||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.formats.ClassicPrefsFormat
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.formats.EncryptedPrefsFormat
|
||||
import info.nightscout.androidaps.utils.CryptoUtil
|
||||
|
||||
|
@ -13,6 +12,5 @@ abstract class PreferencesModule {
|
|||
|
||||
@ContributesAndroidInjector abstract fun cryptoUtilInjector(): CryptoUtil
|
||||
@ContributesAndroidInjector abstract fun encryptedPrefsFormatInjector(): EncryptedPrefsFormat
|
||||
@ContributesAndroidInjector abstract fun classicPrefsFormatInjector(): ClassicPrefsFormat
|
||||
@ContributesAndroidInjector abstract fun prefImportListProviderInjector(): PrefFileListProvider
|
||||
}
|
|
@ -14,11 +14,11 @@ import androidx.fragment.app.FragmentActivity
|
|||
import androidx.work.*
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.BuildConfig
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.activities.DaggerAppCompatActivityWithResult
|
||||
import info.nightscout.androidaps.activities.PreferencesActivity
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.UserEntry
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.events.EventAppExit
|
||||
|
@ -42,6 +42,8 @@ import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
|||
import info.nightscout.androidaps.utils.protection.PasswordCheck
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import info.nightscout.androidaps.utils.storage.Storage
|
||||
import info.nightscout.androidaps.utils.userEntry.UserEntryPresentationHelper
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
|
@ -63,7 +65,6 @@ class ImportExportPrefsImpl @Inject constructor(
|
|||
private val passwordCheck: PasswordCheck,
|
||||
private val config: Config,
|
||||
private val androidPermission: AndroidPermission,
|
||||
private val classicPrefsFormat: ClassicPrefsFormat,
|
||||
private val encryptedPrefsFormat: EncryptedPrefsFormat,
|
||||
private val prefFileList: PrefFileListProvider,
|
||||
private val uel: UserEntryLogger,
|
||||
|
@ -103,12 +104,7 @@ class ImportExportPrefsImpl @Inject constructor(
|
|||
metadata[PrefsMetadataKey.AAPS_VERSION] = PrefMetadata(BuildConfig.VERSION_NAME, PrefsStatus.OK)
|
||||
metadata[PrefsMetadataKey.AAPS_FLAVOUR] = PrefMetadata(BuildConfig.FLAVOR, PrefsStatus.OK)
|
||||
metadata[PrefsMetadataKey.DEVICE_MODEL] = PrefMetadata(config.currentDeviceModelString, PrefsStatus.OK)
|
||||
|
||||
if (prefsEncryptionIsDisabled()) {
|
||||
metadata[PrefsMetadataKey.ENCRYPTION] = PrefMetadata("Disabled", PrefsStatus.DISABLED)
|
||||
} else {
|
||||
metadata[PrefsMetadataKey.ENCRYPTION] = PrefMetadata("Enabled", PrefsStatus.OK)
|
||||
}
|
||||
metadata[PrefsMetadataKey.ENCRYPTION] = PrefMetadata("Enabled", PrefsStatus.OK)
|
||||
|
||||
return metadata
|
||||
}
|
||||
|
@ -132,9 +128,6 @@ class ImportExportPrefsImpl @Inject constructor(
|
|||
return if (patientName.isNotEmpty() && patientName != defaultPatientName) patientName else systemName
|
||||
}
|
||||
|
||||
private fun prefsEncryptionIsDisabled() =
|
||||
buildHelper.isEngineeringMode() && !sp.getBoolean(R.string.key_maintenance_encrypt_exported_prefs, true)
|
||||
|
||||
private fun askForMasterPass(activity: FragmentActivity, @StringRes canceledMsg: Int, then: ((password: String) -> Unit)) {
|
||||
passwordCheck.queryPassword(activity, R.string.master_password, R.string.key_master_password, { password ->
|
||||
then(password)
|
||||
|
@ -155,11 +148,7 @@ class ImportExportPrefsImpl @Inject constructor(
|
|||
|
||||
@Suppress("SameParameterValue")
|
||||
private fun askForMasterPassIfNeeded(activity: FragmentActivity, @StringRes canceledMsg: Int, then: ((password: String) -> Unit)) {
|
||||
if (prefsEncryptionIsDisabled()) {
|
||||
then("")
|
||||
} else {
|
||||
askForMasterPass(activity, canceledMsg, then)
|
||||
}
|
||||
}
|
||||
|
||||
private fun assureMasterPasswordSet(activity: FragmentActivity, @StringRes wrongPwdTitle: Int): Boolean {
|
||||
|
@ -179,7 +168,7 @@ class ImportExportPrefsImpl @Inject constructor(
|
|||
}
|
||||
|
||||
private fun askToConfirmExport(activity: FragmentActivity, fileToExport: File, then: ((password: String) -> Unit)) {
|
||||
if (!prefsEncryptionIsDisabled() && !assureMasterPasswordSet(activity, R.string.nav_export)) return
|
||||
if (!assureMasterPasswordSet(activity, R.string.nav_export)) return
|
||||
|
||||
TwoMessagesAlertDialog.showAlert(activity, resourceHelper.gs(R.string.nav_export),
|
||||
resourceHelper.gs(R.string.export_to) + " " + fileToExport.name + " ?",
|
||||
|
@ -189,20 +178,12 @@ class ImportExportPrefsImpl @Inject constructor(
|
|||
}
|
||||
|
||||
private fun askToConfirmImport(activity: FragmentActivity, fileToImport: PrefsFile, then: ((password: String) -> Unit)) {
|
||||
|
||||
if (fileToImport.handler == PrefsFormatsHandler.ENCRYPTED) {
|
||||
if (!assureMasterPasswordSet(activity, R.string.nav_import)) return
|
||||
TwoMessagesAlertDialog.showAlert(activity, resourceHelper.gs(R.string.nav_import),
|
||||
resourceHelper.gs(R.string.import_from) + " " + fileToImport.name + " ?",
|
||||
resourceHelper.gs(R.string.password_preferences_decrypt_prompt), {
|
||||
askForMasterPass(activity, R.string.preferences_import_canceled, then)
|
||||
}, null, R.drawable.ic_header_import)
|
||||
|
||||
} else {
|
||||
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.nav_import),
|
||||
resourceHelper.gs(R.string.import_from) + " " + fileToImport.file + " ?",
|
||||
Runnable { then("") })
|
||||
}
|
||||
if (!assureMasterPasswordSet(activity, R.string.nav_import)) return
|
||||
TwoMessagesAlertDialog.showAlert(activity, resourceHelper.gs(R.string.nav_import),
|
||||
resourceHelper.gs(R.string.import_from) + " " + fileToImport.name + " ?",
|
||||
resourceHelper.gs(R.string.password_preferences_decrypt_prompt), {
|
||||
askForMasterPass(activity, R.string.preferences_import_canceled, then)
|
||||
}, null, R.drawable.ic_header_import)
|
||||
}
|
||||
|
||||
private fun promptForDecryptionPasswordIfNeeded(activity: FragmentActivity, prefs: Prefs, importOk: Boolean,
|
||||
|
@ -230,7 +211,6 @@ class ImportExportPrefsImpl @Inject constructor(
|
|||
private fun exportSharedPreferences(activity: FragmentActivity) {
|
||||
|
||||
prefFileList.ensureExportDirExists()
|
||||
val legacyFile = prefFileList.legacyFile()
|
||||
val newFile = prefFileList.newExportFile()
|
||||
|
||||
askToConfirmExport(activity, newFile) { password ->
|
||||
|
@ -242,9 +222,6 @@ class ImportExportPrefsImpl @Inject constructor(
|
|||
|
||||
val prefs = Prefs(entries, prepareMetadata(activity))
|
||||
|
||||
if (BuildConfig.DEBUG && buildHelper.isEngineeringMode()) {
|
||||
classicPrefsFormat.savePreferences(legacyFile, prefs)
|
||||
}
|
||||
encryptedPrefsFormat.savePreferences(newFile, prefs, password)
|
||||
|
||||
ToastUtils.okToast(activity, resourceHelper.gs(R.string.exported))
|
||||
|
@ -292,10 +269,7 @@ class ImportExportPrefsImpl @Inject constructor(
|
|||
|
||||
askToConfirmImport(activity, importFile) { password ->
|
||||
|
||||
val format: PrefsFormat = when (importFile.handler) {
|
||||
PrefsFormatsHandler.CLASSIC -> classicPrefsFormat
|
||||
PrefsFormatsHandler.ENCRYPTED -> encryptedPrefsFormat
|
||||
}
|
||||
val format: PrefsFormat = encryptedPrefsFormat
|
||||
|
||||
try {
|
||||
|
||||
|
@ -380,10 +354,11 @@ class ImportExportPrefsImpl @Inject constructor(
|
|||
@Inject lateinit var injector: HasAndroidInjector
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var classicPrefsFormat: ClassicPrefsFormat
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var prefFileList: PrefFileListProvider
|
||||
@Inject lateinit var mainApp: MainApp
|
||||
@Inject lateinit var context: Context
|
||||
@Inject lateinit var userEntryPresentationHelper: UserEntryPresentationHelper
|
||||
@Inject lateinit var storage: Storage
|
||||
|
||||
init {
|
||||
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||
|
@ -395,18 +370,30 @@ class ImportExportPrefsImpl @Inject constructor(
|
|||
val newFile = prefFileList.newExportCsvFile()
|
||||
var ret = Result.success()
|
||||
try {
|
||||
classicPrefsFormat.saveCsv(newFile, entries)
|
||||
ToastUtils.okToast(mainApp, resourceHelper.gs(R.string.ue_exported))
|
||||
saveCsv(newFile, entries)
|
||||
ToastUtils.okToast(context, resourceHelper.gs(R.string.ue_exported))
|
||||
} catch (e: FileNotFoundException) {
|
||||
ToastUtils.errorToast(mainApp, resourceHelper.gs(R.string.filenotfound) + " " + newFile)
|
||||
ToastUtils.errorToast(context, resourceHelper.gs(R.string.filenotfound) + " " + newFile)
|
||||
aapsLogger.error(LTag.CORE, "Unhandled exception", e)
|
||||
ret = Result.failure(workDataOf("Error" to "Error FileNotFoundException"))
|
||||
} catch (e: IOException) {
|
||||
ToastUtils.errorToast(mainApp, e.message)
|
||||
ToastUtils.errorToast(context, e.message)
|
||||
aapsLogger.error(LTag.CORE, "Unhandled exception", e)
|
||||
ret = Result.failure(workDataOf("Error" to "Error IOException"))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
private fun saveCsv(file: File, userEntries: List<UserEntry>) {
|
||||
try {
|
||||
val contents = userEntryPresentationHelper.userEntriesToCsv(userEntries)
|
||||
storage.putFileContents(file, contents)
|
||||
} catch (e: FileNotFoundException) {
|
||||
throw PrefFileNotFoundError(file.absolutePath)
|
||||
} catch (e: IOException) {
|
||||
throw PrefIOError(file.absolutePath)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -4,8 +4,6 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.SwitchPreference
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.BuildConfig
|
||||
import info.nightscout.androidaps.R
|
||||
|
@ -212,14 +210,4 @@ class MaintenancePlugin @Inject constructor(
|
|||
emailIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
return emailIntent
|
||||
}
|
||||
|
||||
override fun preprocessPreferences(preferenceFragment: PreferenceFragmentCompat) {
|
||||
super.preprocessPreferences(preferenceFragment)
|
||||
val encryptSwitch =
|
||||
preferenceFragment.findPreference(resourceHelper.gs(R.string.key_maintenance_encrypt_exported_prefs)) as SwitchPreference?
|
||||
?: return
|
||||
encryptSwitch.isVisible = buildHelper.isEngineeringMode()
|
||||
encryptSwitch.isEnabled = buildHelper.isEngineeringMode()
|
||||
}
|
||||
|
||||
}
|
|
@ -827,8 +827,6 @@
|
|||
<string name="error_adding_treatment_title">Treatment data incomplete</string>
|
||||
<string name="maintenance_settings">Maintenance Settings</string>
|
||||
<string name="maintenance_email">Email recipient</string>
|
||||
<string name="key_maintenance_encrypt_exported_prefs" translatable="false">maintenance_encrypt_exported_prefs</string>
|
||||
<string name="maintenance_encrypt_exported_prefs">Encrypt exported settings</string>
|
||||
<string name="key_maintenance_logs_email" translatable="false">maintenance_logs_email</string>
|
||||
<string name="key_maintenance_logs_amount" translatable="false">maintenance_logs_amount</string>
|
||||
<string name="key_logshipper_amount" translatable="false">logshipper_amount</string>
|
||||
|
|
|
@ -26,11 +26,6 @@
|
|||
validate:minNumber="1"
|
||||
validate:testType="numericRange"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_maintenance_encrypt_exported_prefs"
|
||||
android:title="@string/maintenance_encrypt_exported_prefs" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</androidx.preference.PreferenceScreen>
|
|
@ -24,7 +24,6 @@ import kotlin.math.abs
|
|||
class PrefFileListProvider @Inject constructor(
|
||||
private val resourceHelper: ResourceHelper,
|
||||
private val config: Config,
|
||||
private val classicPrefsFormat: ClassicPrefsFormat,
|
||||
private val encryptedPrefsFormat: EncryptedPrefsFormat,
|
||||
private val storage: Storage,
|
||||
private val versionCheckerUtils: VersionCheckerUtils
|
||||
|
@ -55,10 +54,8 @@ class PrefFileListProvider @Inject constructor(
|
|||
path.walk().maxDepth(1).filter { it.isFile && (it.name.endsWith(".json") || it.name.contains("Preferences")) }.forEach {
|
||||
val contents = storage.getFileContents(it)
|
||||
val detectedNew = encryptedPrefsFormat.isPreferencesFile(it, contents)
|
||||
val detectedOld = !detectedNew && classicPrefsFormat.isPreferencesFile(it, contents)
|
||||
if (detectedNew || detectedOld) {
|
||||
val formatHandler = if (detectedNew) PrefsFormatsHandler.ENCRYPTED else PrefsFormatsHandler.CLASSIC
|
||||
prefFiles.add(PrefsFile(it.name, it, path, PrefsImportDir.ROOT_DIR, formatHandler, metadataFor(loadMetadata, formatHandler, contents)))
|
||||
if (detectedNew) {
|
||||
prefFiles.add(PrefsFile(it.name, it, path, PrefsImportDir.ROOT_DIR, metadataFor(loadMetadata, contents)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,15 +63,14 @@ class PrefFileListProvider @Inject constructor(
|
|||
aapsPath.walk().filter { it.isFile && it.name.endsWith(".json") }.forEach {
|
||||
val contents = storage.getFileContents(it)
|
||||
if (encryptedPrefsFormat.isPreferencesFile(it, contents)) {
|
||||
prefFiles.add(PrefsFile(it.name, it, aapsPath, PrefsImportDir.AAPS_DIR, PrefsFormatsHandler.ENCRYPTED, metadataFor(loadMetadata, PrefsFormatsHandler.ENCRYPTED, contents)))
|
||||
prefFiles.add(PrefsFile(it.name, it, aapsPath, PrefsImportDir.AAPS_DIR, metadataFor(loadMetadata, contents)))
|
||||
}
|
||||
}
|
||||
|
||||
// we sort only if we have metadata to be used for that
|
||||
if (loadMetadata) {
|
||||
prefFiles.sortWith(
|
||||
compareByDescending<PrefsFile> { it.handler }
|
||||
.thenBy { it.metadata[PrefsMetadataKey.AAPS_FLAVOUR]?.status }
|
||||
compareByDescending<PrefsFile> { it.metadata[PrefsMetadataKey.AAPS_FLAVOUR]?.status }
|
||||
.thenByDescending { it.metadata[PrefsMetadataKey.CREATED_AT]?.value }
|
||||
)
|
||||
}
|
||||
|
@ -82,14 +78,11 @@ class PrefFileListProvider @Inject constructor(
|
|||
return prefFiles
|
||||
}
|
||||
|
||||
private fun metadataFor(loadMetadata: Boolean, formatHandler: PrefsFormatsHandler, contents: String): PrefMetadataMap {
|
||||
private fun metadataFor(loadMetadata: Boolean, contents: String): PrefMetadataMap {
|
||||
if (!loadMetadata) {
|
||||
return mapOf()
|
||||
}
|
||||
return checkMetadata(when (formatHandler) {
|
||||
PrefsFormatsHandler.CLASSIC -> classicPrefsFormat.loadMetadata(contents)
|
||||
PrefsFormatsHandler.ENCRYPTED -> encryptedPrefsFormat.loadMetadata(contents)
|
||||
})
|
||||
return checkMetadata(encryptedPrefsFormat.loadMetadata(contents))
|
||||
}
|
||||
|
||||
fun legacyFile(): File {
|
||||
|
|
|
@ -3,8 +3,8 @@ package info.nightscout.androidaps.plugins.general.maintenance
|
|||
import android.os.Parcelable
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefMetadata
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefsMetadataKey
|
||||
import kotlinx.parcelize.RawValue
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import kotlinx.parcelize.RawValue
|
||||
import java.io.File
|
||||
|
||||
@Parcelize
|
||||
|
@ -13,7 +13,6 @@ data class PrefsFile(
|
|||
val file: File,
|
||||
val baseDir: File,
|
||||
val dirKind: PrefsImportDir,
|
||||
val handler: PrefsFormatsHandler,
|
||||
|
||||
// metadata here is used only for list display
|
||||
val metadata: @RawValue Map<PrefsMetadataKey, PrefMetadata>
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.maintenance
|
||||
|
||||
enum class PrefsFormatsHandler {
|
||||
CLASSIC,
|
||||
ENCRYPTED
|
||||
}
|
|
@ -5,6 +5,7 @@ import android.content.Intent
|
|||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
|
@ -16,10 +17,8 @@ import info.nightscout.androidaps.core.databinding.MaintenanceImportListItemBind
|
|||
import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.PrefsFile
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.PrefsFileContract
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.PrefsFormatsHandler
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefsMetadataKey
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefsStatus
|
||||
import info.nightscout.androidaps.extensions.toVisibility
|
||||
import info.nightscout.androidaps.utils.locale.LocaleHelper
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import javax.inject.Inject
|
||||
|
@ -83,38 +82,30 @@ class PrefImportListActivity : DaggerAppCompatActivity() {
|
|||
|
||||
filelistDir.text = resourceHelper.gs(R.string.in_directory, prefFile.file.parentFile?.absolutePath)
|
||||
|
||||
val visible = (prefFile.handler != PrefsFormatsHandler.CLASSIC).toVisibility()
|
||||
metalineName.visibility = visible
|
||||
metaDateTimeIcon.visibility = visible
|
||||
metaAppVersion.visibility = visible
|
||||
|
||||
if (prefFile.handler == PrefsFormatsHandler.CLASSIC) {
|
||||
metaVariantFormat.text = resourceHelper.gs(R.string.metadata_format_old)
|
||||
metaVariantFormat.setTextColor(resourceHelper.gc(R.color.metadataTextWarning))
|
||||
metaDateTime.text = " "
|
||||
} else {
|
||||
|
||||
prefFile.metadata[PrefsMetadataKey.AAPS_FLAVOUR]?.let {
|
||||
metaVariantFormat.text = it.value
|
||||
val color = if (it.status == PrefsStatus.OK) R.color.metadataOk else R.color.metadataTextWarning
|
||||
metaVariantFormat.setTextColor(resourceHelper.gc(color))
|
||||
}
|
||||
|
||||
prefFile.metadata[PrefsMetadataKey.CREATED_AT]?.let {
|
||||
metaDateTime.text = prefFileListProvider.formatExportedAgo(it.value)
|
||||
}
|
||||
|
||||
prefFile.metadata[PrefsMetadataKey.AAPS_VERSION]?.let {
|
||||
metaAppVersion.text = it.value
|
||||
val color = if (it.status == PrefsStatus.OK) R.color.metadataOk else R.color.metadataTextWarning
|
||||
metaAppVersion.setTextColor(resourceHelper.gc(color))
|
||||
}
|
||||
|
||||
prefFile.metadata[PrefsMetadataKey.DEVICE_NAME]?.let {
|
||||
metaDeviceName.text = it.value
|
||||
}
|
||||
metalineName.visibility = View.VISIBLE
|
||||
metaDateTimeIcon.visibility = View.VISIBLE
|
||||
metaAppVersion.visibility = View.VISIBLE
|
||||
|
||||
prefFile.metadata[PrefsMetadataKey.AAPS_FLAVOUR]?.let {
|
||||
metaVariantFormat.text = it.value
|
||||
val color = if (it.status == PrefsStatus.OK) R.color.metadataOk else R.color.metadataTextWarning
|
||||
metaVariantFormat.setTextColor(resourceHelper.gc(color))
|
||||
}
|
||||
|
||||
prefFile.metadata[PrefsMetadataKey.CREATED_AT]?.let {
|
||||
metaDateTime.text = prefFileListProvider.formatExportedAgo(it.value)
|
||||
}
|
||||
|
||||
prefFile.metadata[PrefsMetadataKey.AAPS_VERSION]?.let {
|
||||
metaAppVersion.text = it.value
|
||||
val color = if (it.status == PrefsStatus.OK) R.color.metadataOk else R.color.metadataTextWarning
|
||||
metaAppVersion.setTextColor(resourceHelper.gc(color))
|
||||
}
|
||||
|
||||
prefFile.metadata[PrefsMetadataKey.DEVICE_NAME]?.let {
|
||||
metaDeviceName.text = it.value
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.maintenance.formats
|
||||
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.core.R
|
||||
import info.nightscout.androidaps.database.entities.UserEntry
|
||||
import info.nightscout.androidaps.utils.userEntry.UserEntryPresentationHelper
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.storage.Storage
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class ClassicPrefsFormat @Inject constructor(
|
||||
private var resourceHelper: ResourceHelper,
|
||||
private var userEntryPresentationHelper: UserEntryPresentationHelper,
|
||||
private var storage: Storage
|
||||
) : PrefsFormat {
|
||||
|
||||
companion object {
|
||||
|
||||
val FORMAT_KEY = "aaps_old"
|
||||
}
|
||||
|
||||
override fun isPreferencesFile(file: File, preloadedContents: String?): Boolean {
|
||||
val contents = preloadedContents ?: storage.getFileContents(file)
|
||||
return contents.contains("units::" + Constants.MGDL) || contents.contains("units::" + Constants.MMOL) || contents.contains("language::") || contents.contains("I_understand::")
|
||||
}
|
||||
|
||||
override fun savePreferences(file: File, prefs: Prefs, masterPassword: String?) {
|
||||
try {
|
||||
val contents = prefs.values.entries.joinToString("\n") { entry ->
|
||||
"${entry.key}::${entry.value}"
|
||||
}
|
||||
storage.putFileContents(file, contents)
|
||||
} catch (e: FileNotFoundException) {
|
||||
throw PrefFileNotFoundError(file.absolutePath)
|
||||
} catch (e: IOException) {
|
||||
throw PrefIOError(file.absolutePath)
|
||||
}
|
||||
}
|
||||
|
||||
override fun loadPreferences(file: File, masterPassword: String?): Prefs {
|
||||
var lineParts: Array<String>
|
||||
val entries: MutableMap<String, String> = mutableMapOf()
|
||||
try {
|
||||
|
||||
val rawLines = storage.getFileContents(file).split("\n")
|
||||
rawLines.forEach { line ->
|
||||
lineParts = line.split("::").toTypedArray()
|
||||
if (lineParts.size == 2) {
|
||||
entries[lineParts[0]] = lineParts[1]
|
||||
}
|
||||
}
|
||||
|
||||
return Prefs(entries, loadMetadata())
|
||||
|
||||
} catch (e: FileNotFoundException) {
|
||||
throw PrefFileNotFoundError(file.absolutePath)
|
||||
} catch (e: IOException) {
|
||||
throw PrefIOError(file.absolutePath)
|
||||
}
|
||||
}
|
||||
|
||||
override fun loadMetadata(contents: String?): PrefMetadataMap {
|
||||
val metadata: MutableMap<PrefsMetadataKey, PrefMetadata> = mutableMapOf()
|
||||
metadata[PrefsMetadataKey.FILE_FORMAT] = PrefMetadata(FORMAT_KEY, PrefsStatus.WARN, resourceHelper.gs(R.string.metadata_warning_outdated_format))
|
||||
return metadata
|
||||
}
|
||||
|
||||
fun saveCsv(file: File, userEntries: List<UserEntry>) {
|
||||
try {
|
||||
val contents = userEntryPresentationHelper.userEntriesToCsv(userEntries)
|
||||
storage.putFileContents(file, contents)
|
||||
} catch (e: FileNotFoundException) {
|
||||
throw PrefFileNotFoundError(file.absolutePath)
|
||||
} catch (e: IOException) {
|
||||
throw PrefIOError(file.absolutePath)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,28 +19,25 @@ enum class PrefsMetadataKey(val key: String, @DrawableRes val icon: Int, @String
|
|||
ENCRYPTION("encryption", R.drawable.ic_meta_encryption, R.string.metadata_label_encryption);
|
||||
|
||||
companion object {
|
||||
|
||||
private val keyToEnumMap = HashMap<String, PrefsMetadataKey>()
|
||||
|
||||
init {
|
||||
for (value in values()) {
|
||||
keyToEnumMap.put(value.key, value)
|
||||
}
|
||||
for (value in values()) keyToEnumMap[value.key] = value
|
||||
}
|
||||
|
||||
fun fromKey(key: String): PrefsMetadataKey? {
|
||||
fun fromKey(key: String): PrefsMetadataKey? =
|
||||
if (keyToEnumMap.containsKey(key)) {
|
||||
return keyToEnumMap.get(key)
|
||||
keyToEnumMap[key]
|
||||
} else {
|
||||
return null
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun formatForDisplay(context: Context, value: String): String {
|
||||
return when (this) {
|
||||
FILE_FORMAT -> when (value) {
|
||||
ClassicPrefsFormat.FORMAT_KEY -> context.getString(R.string.metadata_format_old)
|
||||
EncryptedPrefsFormat.FORMAT_KEY_ENC -> context.getString(R.string.metadata_format_new)
|
||||
EncryptedPrefsFormat.FORMAT_KEY_NOENC -> context.getString(R.string.metadata_format_debug)
|
||||
else -> context.getString(R.string.metadata_format_other)
|
||||
|
@ -60,6 +57,7 @@ typealias PrefMetadataMap = Map<PrefsMetadataKey, PrefMetadata>
|
|||
data class Prefs(val values: Map<String, String>, var metadata: PrefMetadataMap)
|
||||
|
||||
interface PrefsFormat {
|
||||
|
||||
fun savePreferences(file: File, prefs: Prefs, masterPassword: String? = null)
|
||||
fun loadPreferences(file: File, masterPassword: String? = null): Prefs
|
||||
fun loadMetadata(contents: String? = null): PrefMetadataMap
|
||||
|
|
|
@ -345,7 +345,6 @@
|
|||
<string name="metadata_label_device_name">Exporting device patient name</string>
|
||||
<string name="metadata_label_device_model">Exporting device model</string>
|
||||
<string name="metadata_label_encryption">File encryption</string>
|
||||
<string name="metadata_format_old">Old export format</string>
|
||||
<string name="metadata_format_new">New encrypted format</string>
|
||||
<string name="metadata_format_debug">New debug format (unencrypted)</string>
|
||||
<string name="metadata_format_other">Unknown export format</string>
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.maintenance.formats
|
||||
|
||||
import info.nightscout.androidaps.TestBase
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.userEntry.UserEntryPresentationHelper
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.`when`
|
||||
import java.io.File
|
||||
|
||||
class ClassicPrefsFormatTest : TestBase() {
|
||||
|
||||
@Mock lateinit var resourceHelper: ResourceHelper
|
||||
@Mock lateinit var userEntryPresentationHelper: UserEntryPresentationHelper
|
||||
@Mock lateinit var file: MockedFile
|
||||
|
||||
@Test
|
||||
fun preferenceLoadingTest() {
|
||||
val test = "key1::val1\nkeyB::valB"
|
||||
|
||||
val classicFormat = ClassicPrefsFormat(resourceHelper, userEntryPresentationHelper, SingleStringStorage(test))
|
||||
val prefs = classicFormat.loadPreferences(getMockedFile(), "")
|
||||
|
||||
Assert.assertEquals(prefs.values.size, 2)
|
||||
Assert.assertEquals(prefs.values["key1"], "val1")
|
||||
Assert.assertEquals(prefs.values["keyB"], "valB")
|
||||
Assert.assertNull(prefs.values["key3"])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun preferenceSavingTest() {
|
||||
val storage = SingleStringStorage("")
|
||||
val classicFormat = ClassicPrefsFormat(resourceHelper, userEntryPresentationHelper, storage)
|
||||
val prefs = Prefs(
|
||||
mapOf(
|
||||
"key1" to "A",
|
||||
"keyB" to "2"
|
||||
),
|
||||
mapOf()
|
||||
)
|
||||
|
||||
classicFormat.savePreferences(getMockedFile(), prefs)
|
||||
}
|
||||
|
||||
class MockedFile(s: String) : File(s)
|
||||
|
||||
private fun getMockedFile(): File {
|
||||
`when`(file.exists()).thenReturn(true)
|
||||
`when`(file.canRead()).thenReturn(true)
|
||||
`when`(file.canWrite()).thenReturn(true)
|
||||
return file
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue