Preferences Encryption - export as JSON
This commit is contained in:
parent
f4b7f642c9
commit
fde84207ab
8 changed files with 291 additions and 135 deletions
|
@ -36,6 +36,7 @@ import info.nightscout.androidaps.plugins.general.automation.actions.*
|
||||||
import info.nightscout.androidaps.plugins.general.automation.elements.*
|
import info.nightscout.androidaps.plugins.general.automation.elements.*
|
||||||
import info.nightscout.androidaps.plugins.general.automation.triggers.*
|
import info.nightscout.androidaps.plugins.general.automation.triggers.*
|
||||||
import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData
|
import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData
|
||||||
|
import info.nightscout.androidaps.plugins.general.maintenance.ImportExportPrefs
|
||||||
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction
|
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction
|
||||||
import info.nightscout.androidaps.plugins.general.smsCommunicator.AuthRequest
|
import info.nightscout.androidaps.plugins.general.smsCommunicator.AuthRequest
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensData
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensData
|
||||||
|
@ -249,6 +250,8 @@ open class AppModule {
|
||||||
|
|
||||||
@ContributesAndroidInjector fun graphDataInjector(): GraphData
|
@ContributesAndroidInjector fun graphDataInjector(): GraphData
|
||||||
|
|
||||||
|
@ContributesAndroidInjector fun importExportPrefsInjector(): ImportExportPrefs
|
||||||
|
|
||||||
@Binds fun bindContext(mainApp: MainApp): Context
|
@Binds fun bindContext(mainApp: MainApp): Context
|
||||||
@Binds fun bindInjector(mainApp: MainApp): HasAndroidInjector
|
@Binds fun bindInjector(mainApp: MainApp): HasAndroidInjector
|
||||||
|
|
||||||
|
|
|
@ -1,129 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.general.maintenance;
|
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.os.Environment;
|
|
||||||
import androidx.preference.PreferenceManager;
|
|
||||||
|
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.R;
|
|
||||||
import info.nightscout.androidaps.events.EventAppExit;
|
|
||||||
import info.nightscout.androidaps.logging.L;
|
|
||||||
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper;
|
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus;
|
|
||||||
import info.nightscout.androidaps.utils.OKDialog;
|
|
||||||
import info.nightscout.androidaps.utils.SP;
|
|
||||||
import info.nightscout.androidaps.utils.ToastUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by mike on 03.07.2016.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class ImportExportPrefs {
|
|
||||||
private static Logger log = StacktraceLoggerWrapper.getLogger(L.CORE);
|
|
||||||
private static File path = new File(Environment.getExternalStorageDirectory().toString());
|
|
||||||
static public final File file = new File(path, MainApp.gs(R.string.app_name) + "Preferences");
|
|
||||||
|
|
||||||
private static final int REQUEST_EXTERNAL_STORAGE = 1;
|
|
||||||
private static String[] PERMISSIONS_STORAGE = {
|
|
||||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
|
||||||
};
|
|
||||||
|
|
||||||
static void verifyStoragePermissions(Fragment fragment) {
|
|
||||||
int permission = ContextCompat.checkSelfPermission(fragment.getContext(),
|
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
|
||||||
|
|
||||||
if (permission != PackageManager.PERMISSION_GRANTED) {
|
|
||||||
// We don't have permission so prompt the user
|
|
||||||
fragment.requestPermissions(PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void exportSharedPreferences(final Fragment f) {
|
|
||||||
exportSharedPreferences(f.getContext());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void exportSharedPreferences(final Context context) {
|
|
||||||
OKDialog.showConfirmation(context, MainApp.gs(R.string.maintenance), MainApp.gs(R.string.export_to) + " " + file + " ?", () -> {
|
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
|
||||||
try {
|
|
||||||
FileWriter fw = new FileWriter(file);
|
|
||||||
PrintWriter pw = new PrintWriter(fw);
|
|
||||||
Map<String, ?> prefsMap = prefs.getAll();
|
|
||||||
for (Map.Entry<String, ?> entry : prefsMap.entrySet()) {
|
|
||||||
pw.println(entry.getKey() + "::" + entry.getValue().toString());
|
|
||||||
}
|
|
||||||
pw.close();
|
|
||||||
fw.close();
|
|
||||||
ToastUtils.showToastInUiThread(context, MainApp.gs(R.string.exported));
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
ToastUtils.showToastInUiThread(context, MainApp.gs(R.string.filenotfound) + " " + file);
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
static void importSharedPreferences(final Fragment fragment) {
|
|
||||||
importSharedPreferences(fragment.getContext());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void importSharedPreferences(final Context context) {
|
|
||||||
OKDialog.showConfirmation(context, MainApp.gs(R.string.maintenance), MainApp.gs(R.string.import_from) + " " + file + " ?", () -> {
|
|
||||||
String line;
|
|
||||||
String[] lineParts;
|
|
||||||
try {
|
|
||||||
SP.clear();
|
|
||||||
|
|
||||||
BufferedReader reader = new BufferedReader(new FileReader(file));
|
|
||||||
while ((line = reader.readLine()) != null) {
|
|
||||||
lineParts = line.split("::");
|
|
||||||
if (lineParts.length == 2) {
|
|
||||||
if (lineParts[1].equals("true") || lineParts[1].equals("false")) {
|
|
||||||
SP.putBoolean(lineParts[0], Boolean.parseBoolean(lineParts[1]));
|
|
||||||
} else {
|
|
||||||
SP.putString(lineParts[0], lineParts[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reader.close();
|
|
||||||
SP.putBoolean(R.string.key_setupwizard_processed, true);
|
|
||||||
OKDialog.show(context, MainApp.gs(R.string.setting_imported), MainApp.gs(R.string.restartingapp), () -> {
|
|
||||||
log.debug("Exiting");
|
|
||||||
RxBus.Companion.getINSTANCE().send(new EventAppExit());
|
|
||||||
if (context instanceof Activity) {
|
|
||||||
((Activity) context).finish();
|
|
||||||
}
|
|
||||||
System.runFinalization();
|
|
||||||
System.exit(0);
|
|
||||||
});
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
ToastUtils.showToastInUiThread(context, MainApp.gs(R.string.filenotfound) + " " + file);
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.maintenance
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.os.Environment
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.events.EventAppExit
|
||||||
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
|
import info.nightscout.androidaps.logging.LTag
|
||||||
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||||
|
import info.nightscout.androidaps.plugins.general.maintenance.formats.*
|
||||||
|
import info.nightscout.androidaps.utils.OKDialog.show
|
||||||
|
import info.nightscout.androidaps.utils.OKDialog.showConfirmation
|
||||||
|
import info.nightscout.androidaps.utils.ToastUtils
|
||||||
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileNotFoundException
|
||||||
|
import java.io.IOException
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mike on 03.07.2016.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private const val REQUEST_EXTERNAL_STORAGE = 1
|
||||||
|
private val PERMISSIONS_STORAGE = arrayOf(
|
||||||
|
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||||
|
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||||
|
)
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class ImportExportPrefs @Inject constructor (
|
||||||
|
private var log: AAPSLogger,
|
||||||
|
private val resourceHelper: ResourceHelper,
|
||||||
|
private val sp : SP,
|
||||||
|
private val rxBus: RxBusWrapper
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
val TAG = LTag.CORE
|
||||||
|
|
||||||
|
private val path = File(Environment.getExternalStorageDirectory().toString())
|
||||||
|
|
||||||
|
private val file = File(path, resourceHelper.gs(R.string.app_name) + "Preferences")
|
||||||
|
private val encFile = File(path, resourceHelper.gs(R.string.app_name) + "Preferences.json")
|
||||||
|
|
||||||
|
fun prefsImportFile() : File {
|
||||||
|
return if (encFile.exists()) encFile else file
|
||||||
|
}
|
||||||
|
|
||||||
|
fun prefsFileExists() : Boolean {
|
||||||
|
return encFile.exists() || file.exists()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun exportSharedPreferences(f: Fragment) {
|
||||||
|
exportSharedPreferences(f.context)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun verifyStoragePermissions(fragment: Fragment) {
|
||||||
|
val permission = ContextCompat.checkSelfPermission(fragment.context!!,
|
||||||
|
Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
|
if (permission != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
// We don't have permission so prompt the user
|
||||||
|
fragment.requestPermissions(PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun exportSharedPreferences(context: Context?) {
|
||||||
|
showConfirmation(context!!, resourceHelper.gs(R.string.maintenance), resourceHelper.gs(R.string.export_to) + " " + encFile + " ?", Runnable {
|
||||||
|
try {
|
||||||
|
val entries: MutableMap<String, String> = mutableMapOf()
|
||||||
|
for ((key, value) in sp.getAll()) {
|
||||||
|
entries[key] = value.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
val prefs = Prefs(entries, mapOf())
|
||||||
|
|
||||||
|
ClassicPrefsFormat.savePreferences(file, prefs)
|
||||||
|
EncryptedPrefsFormat.savePreferences(encFile, prefs)
|
||||||
|
|
||||||
|
ToastUtils.showToastInUiThread(context, resourceHelper.gs(R.string.exported))
|
||||||
|
} catch (e: FileNotFoundException) {
|
||||||
|
ToastUtils.showToastInUiThread(context, resourceHelper.gs(R.string.filenotfound) + " " + encFile)
|
||||||
|
log.error(TAG,"Unhandled exception", e)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
log.error(TAG,"Unhandled exception", e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun importSharedPreferences(fragment: Fragment) {
|
||||||
|
importSharedPreferences(fragment.context)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun importSharedPreferences(context: Context?) {
|
||||||
|
|
||||||
|
val importFile = prefsImportFile()
|
||||||
|
|
||||||
|
showConfirmation(context!!, resourceHelper.gs(R.string.maintenance), resourceHelper.gs(R.string.import_from) + " " + importFile + " ?", Runnable {
|
||||||
|
|
||||||
|
val format : PrefsFormat = if (encFile.exists()) EncryptedPrefsFormat else ClassicPrefsFormat
|
||||||
|
|
||||||
|
try {
|
||||||
|
val prefs = format.loadPreferences(importFile)
|
||||||
|
|
||||||
|
sp.clear()
|
||||||
|
for ((key, value) in prefs.values) {
|
||||||
|
if (value == "true" || value == "false") {
|
||||||
|
sp.putBoolean(key, value.toBoolean())
|
||||||
|
} else {
|
||||||
|
sp.putString(key, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sp.putBoolean(R.string.key_setupwizard_processed, true)
|
||||||
|
show(context, resourceHelper.gs(R.string.setting_imported), resourceHelper.gs(R.string.restartingapp), Runnable {
|
||||||
|
log.debug(TAG,"Exiting")
|
||||||
|
rxBus.send(EventAppExit())
|
||||||
|
if (context is Activity) {
|
||||||
|
context.finish()
|
||||||
|
}
|
||||||
|
System.runFinalization()
|
||||||
|
System.exit(0)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
} catch (e: PrefFileNotFoundError) {
|
||||||
|
ToastUtils.showToastInUiThread(context, resourceHelper.gs(R.string.filenotfound) + " " + importFile)
|
||||||
|
log.error(TAG,"Unhandled exception", e)
|
||||||
|
} catch (e: PrefIOError) {
|
||||||
|
log.error(TAG,"Unhandled exception", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ class MaintenanceFragment : DaggerFragment() {
|
||||||
@Inject lateinit var resourceHelper: ResourceHelper
|
@Inject lateinit var resourceHelper: ResourceHelper
|
||||||
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
|
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
|
||||||
@Inject lateinit var foodPlugin: FoodPlugin
|
@Inject lateinit var foodPlugin: FoodPlugin
|
||||||
|
@Inject lateinit var importExportPrefs: ImportExportPrefs
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
return inflater.inflate(R.layout.maintenance_fragment, container, false)
|
return inflater.inflate(R.layout.maintenance_fragment, container, false)
|
||||||
|
@ -45,13 +46,13 @@ class MaintenanceFragment : DaggerFragment() {
|
||||||
}
|
}
|
||||||
nav_export.setOnClickListener {
|
nav_export.setOnClickListener {
|
||||||
// start activity for checking permissions...
|
// start activity for checking permissions...
|
||||||
ImportExportPrefs.verifyStoragePermissions(this)
|
importExportPrefs.verifyStoragePermissions(this)
|
||||||
ImportExportPrefs.exportSharedPreferences(this)
|
importExportPrefs.exportSharedPreferences(this)
|
||||||
}
|
}
|
||||||
nav_import.setOnClickListener {
|
nav_import.setOnClickListener {
|
||||||
// start activity for checking permissions...
|
// start activity for checking permissions...
|
||||||
ImportExportPrefs.verifyStoragePermissions(this)
|
importExportPrefs.verifyStoragePermissions(this)
|
||||||
ImportExportPrefs.importSharedPreferences(this)
|
importExportPrefs.importSharedPreferences(this)
|
||||||
}
|
}
|
||||||
nav_logsettings.setOnClickListener { startActivity(Intent(activity, LogSettingActivity::class.java)) }
|
nav_logsettings.setOnClickListener { startActivity(Intent(activity, LogSettingActivity::class.java)) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.maintenance.formats
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.plugins.general.maintenance.ImportExportPrefs
|
||||||
|
import java.io.*
|
||||||
|
|
||||||
|
|
||||||
|
object ClassicPrefsFormat : PrefsFormat {
|
||||||
|
|
||||||
|
const val FORMAT_KEY = "old"
|
||||||
|
|
||||||
|
override fun savePreferences(file:File, prefs: Prefs) {
|
||||||
|
try {
|
||||||
|
val fw = FileWriter(file)
|
||||||
|
val pw = PrintWriter(fw)
|
||||||
|
for ((key, value) in prefs.values) {
|
||||||
|
pw.println(key + "::" + value)
|
||||||
|
}
|
||||||
|
pw.close()
|
||||||
|
fw.close()
|
||||||
|
} catch (e: FileNotFoundException) {
|
||||||
|
throw PrefFileNotFoundError(file.absolutePath)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
throw PrefIOError(file.absolutePath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun loadPreferences(file:File): Prefs {
|
||||||
|
var line: String
|
||||||
|
var lineParts: Array<String>
|
||||||
|
val entries: MutableMap<String, String> = mutableMapOf()
|
||||||
|
val metadata: MutableMap<PrefsMetadataKey, PrefMetadata> = mutableMapOf()
|
||||||
|
try {
|
||||||
|
val reader = BufferedReader(FileReader(file))
|
||||||
|
while (reader.readLine().also { line = it } != null) {
|
||||||
|
lineParts = line.split("::").toTypedArray()
|
||||||
|
if (lineParts.size == 2) {
|
||||||
|
entries[lineParts[0]] = lineParts[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.close()
|
||||||
|
|
||||||
|
metadata[PrefsMetadataKey.FILE_FORMAT] = PrefMetadata(FORMAT_KEY, PrefsStatus.WARN)
|
||||||
|
|
||||||
|
return Prefs(entries, metadata)
|
||||||
|
|
||||||
|
} catch (e: FileNotFoundException) {
|
||||||
|
throw PrefFileNotFoundError(file.absolutePath)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
throw PrefIOError(file.absolutePath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.maintenance.formats
|
||||||
|
|
||||||
|
import org.json.JSONException
|
||||||
|
import org.json.JSONObject
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileNotFoundException
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
object EncryptedPrefsFormat : PrefsFormat {
|
||||||
|
|
||||||
|
const val FORMAT_KEY = "new_v1"
|
||||||
|
|
||||||
|
override fun savePreferences(file:File, prefs: Prefs) {
|
||||||
|
|
||||||
|
val container = JSONObject()
|
||||||
|
|
||||||
|
try {
|
||||||
|
for ((key, value) in prefs.values) {
|
||||||
|
container.put(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
file.writeText(container.toString(2));
|
||||||
|
|
||||||
|
} catch (e: FileNotFoundException) {
|
||||||
|
throw PrefFileNotFoundError(file.absolutePath)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
throw PrefIOError(file.absolutePath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun loadPreferences(file:File): Prefs {
|
||||||
|
|
||||||
|
val entries: MutableMap<String, String> = mutableMapOf()
|
||||||
|
val metadata: MutableMap<PrefsMetadataKey, PrefMetadata> = mutableMapOf()
|
||||||
|
try {
|
||||||
|
|
||||||
|
val jsonBody = file.readText()
|
||||||
|
val container = JSONObject(jsonBody)
|
||||||
|
|
||||||
|
for (key in container.keys()) {
|
||||||
|
entries.put(key, container[key].toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
metadata[PrefsMetadataKey.FILE_FORMAT] = PrefMetadata(FORMAT_KEY, PrefsStatus.OK)
|
||||||
|
|
||||||
|
return Prefs(entries, metadata)
|
||||||
|
|
||||||
|
} catch (e: FileNotFoundException) {
|
||||||
|
throw PrefFileNotFoundError(file.absolutePath)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
throw PrefIOError(file.absolutePath)
|
||||||
|
} catch (e: JSONException){
|
||||||
|
throw PrefFormatError("Mallformed preferences JSON file: "+e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.maintenance.formats
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
enum class PrefsMetadataKey(val key: String) {
|
||||||
|
FILE_FORMAT("fileFormat")
|
||||||
|
}
|
||||||
|
|
||||||
|
data class PrefMetadata(var value : String, var status : PrefsStatus)
|
||||||
|
|
||||||
|
data class Prefs(val values : Map<String, String>, val metadata : Map<PrefsMetadataKey, PrefMetadata>)
|
||||||
|
|
||||||
|
interface PrefsFormat {
|
||||||
|
fun savePreferences(file: File, prefs: Prefs)
|
||||||
|
fun loadPreferences(file: File) : Prefs
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class PrefsStatus {
|
||||||
|
OK,
|
||||||
|
WARN,
|
||||||
|
ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
class PrefFileNotFoundError(message: String) : Exception(message)
|
||||||
|
class PrefIOError(message: String) : Exception(message)
|
||||||
|
class PrefFormatError(message: String) : Exception(message)
|
|
@ -59,6 +59,7 @@ class SWDefinition @Inject constructor(
|
||||||
private val nsClientPlugin: NSClientPlugin,
|
private val nsClientPlugin: NSClientPlugin,
|
||||||
private val nsProfilePlugin: NSProfilePlugin,
|
private val nsProfilePlugin: NSProfilePlugin,
|
||||||
private val protectionCheck: ProtectionCheck,
|
private val protectionCheck: ProtectionCheck,
|
||||||
|
private val importExportPrefs: ImportExportPrefs,
|
||||||
private val androidPermission: AndroidPermission
|
private val androidPermission: AndroidPermission
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
@ -160,8 +161,8 @@ class SWDefinition @Inject constructor(
|
||||||
.add(SWBreak(injector))
|
.add(SWBreak(injector))
|
||||||
.add(SWButton(injector)
|
.add(SWButton(injector)
|
||||||
.text(R.string.nav_import)
|
.text(R.string.nav_import)
|
||||||
.action(Runnable { ImportExportPrefs.importSharedPreferences(activity) }))
|
.action(Runnable { importExportPrefs.importSharedPreferences(activity) }))
|
||||||
.visibility(SWValidator { ImportExportPrefs.file.exists() && !androidPermission.permissionNotGranted(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) })
|
.visibility(SWValidator { importExportPrefs.prefsFileExists() && !androidPermission.permissionNotGranted(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) })
|
||||||
private val screenNsClient = SWScreen(injector, R.string.nsclientinternal_title)
|
private val screenNsClient = SWScreen(injector, R.string.nsclientinternal_title)
|
||||||
.skippable(true)
|
.skippable(true)
|
||||||
.add(SWInfotext(injector)
|
.add(SWInfotext(injector)
|
||||||
|
|
Loading…
Reference in a new issue