From 24a7d0c60a021747087ba49b34478b57c5c9a5eb Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Wed, 2 May 2018 03:48:26 +0200
Subject: [PATCH] Improve settings migration logic

Signed-off-by: Janne Koschinski <janne@kuschku.de>
---
 .../de/kuschku/quasseldroid/Quasseldroid.kt   | 141 +++++++++---------
 .../settings/SettingsMigrationManager.kt      |  34 +++--
 2 files changed, 94 insertions(+), 81 deletions(-)

diff --git a/app/src/main/java/de/kuschku/quasseldroid/Quasseldroid.kt b/app/src/main/java/de/kuschku/quasseldroid/Quasseldroid.kt
index 99f06b0a5..55eacdd04 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/Quasseldroid.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/Quasseldroid.kt
@@ -21,7 +21,6 @@ package de.kuschku.quasseldroid
 
 import android.os.Build
 import android.os.StrictMode
-import android.support.v7.preference.PreferenceManager
 import com.squareup.leakcanary.LeakCanary
 import dagger.android.AndroidInjector
 import dagger.android.support.DaggerApplication
@@ -66,92 +65,94 @@ class Quasseldroid : DaggerApplication() {
     applicationInjector().inject(this)
 
     // Migrate preferences
-    SettingsMigrationManager(listOf(
-      SettingsMigration.migrationOf(0, 1) { prefs, edit ->
-        // Migrating database
-        val database = LegacyAccountDatabase.Creator.init(this)
-        val accounts = database.accounts().all()
-        database.close()
-
-        val accountDatabase = AccountDatabase.Creator.init(this)
-        accountDatabase.accounts().create(*accounts.map {
-          AccountDatabase.Account(
-            id = it.id,
-            host = it.host,
-            port = it.port,
-            user = it.user,
-            pass = it.pass,
-            name = it.name,
-            lastUsed = 0
-          )
-        }.toTypedArray())
-        Thread(Runnable {
-          deleteDatabase("data")
-        }).start()
-
-        // Migrating actual settings
-        if (prefs.contains("selectedtheme")) {
-          prefs.getString("selectedtheme", "").let { theme ->
-            when (theme) {
-              "light" -> AppearanceSettings.Theme.MATERIAL_LIGHT
-              "dark"  -> AppearanceSettings.Theme.MATERIAL_DARK
-              else    -> null
-            }?.let {
-              edit.putString(getString(R.string.preference_theme_key), it.name)
+    SettingsMigrationManager(
+      R.xml.preferences,
+      listOf(
+        SettingsMigration.migrationOf(0, 1) { prefs, edit ->
+          // Migrating database
+          val database = LegacyAccountDatabase.Creator.init(this)
+          val accounts = database.accounts().all()
+          database.close()
+
+          val accountDatabase = AccountDatabase.Creator.init(this)
+          accountDatabase.accounts().create(*accounts.map {
+            AccountDatabase.Account(
+              id = it.id,
+              host = it.host,
+              port = it.port,
+              user = it.user,
+              pass = it.pass,
+              name = it.name,
+              lastUsed = 0
+            )
+          }.toTypedArray())
+          Thread(Runnable {
+            deleteDatabase("data")
+          }).start()
+
+          // Migrating actual settings
+          if (prefs.contains("selectedtheme")) {
+            prefs.getString("selectedtheme", "").let { theme ->
+              when (theme) {
+                "light" -> AppearanceSettings.Theme.MATERIAL_LIGHT
+                "dark"  -> AppearanceSettings.Theme.MATERIAL_DARK
+                else    -> null
+              }?.let {
+                edit.putString(getString(R.string.preference_theme_key), it.name)
+              }
             }
+            edit.remove("selectedtheme")
           }
-          edit.remove("selectedtheme")
-        }
 
-        if (prefs.contains("timestamp")) {
-          prefs.getString("timestamp", "").let { timestamp ->
-            edit.putBoolean(getString(R.string.preference_show_seconds_key),
-                            timestamp.contains("ss"))
-            edit.putBoolean(getString(R.string.preference_show_seconds_key),
-                            timestamp.contains("hh") || timestamp.contains("a"))
+          if (prefs.contains("timestamp")) {
+            prefs.getString("timestamp", "").let { timestamp ->
+              edit.putBoolean(getString(R.string.preference_show_seconds_key),
+                              timestamp.contains("ss"))
+              edit.putBoolean(getString(R.string.preference_show_seconds_key),
+                              timestamp.contains("hh") || timestamp.contains("a"))
+            }
+            edit.remove("timestamp")
           }
-          edit.remove("timestamp")
-        }
 
-        if (prefs.contains("fontsizeChannelList")) {
-          prefs.getString("fontsizeChannelList", "").toIntOrNull()?.let { fontSize ->
-            edit.putInt(getString(R.string.preference_textsize_key), fontSize)
+          if (prefs.contains("fontsizeChannelList")) {
+            prefs.getString("fontsizeChannelList", "").toIntOrNull()?.let { fontSize ->
+              edit.putInt(getString(R.string.preference_textsize_key), fontSize)
+            }
+            edit.remove("fontsizeChannelList")
           }
-          edit.remove("fontsizeChannelList")
-        }
 
-        if (prefs.contains("allowcoloredtext")) {
-          prefs.getBoolean("allowcoloredtext", false).let {
-            edit.putBoolean(getString(R.string.preference_colorize_mirc_key), it)
+          if (prefs.contains("allowcoloredtext")) {
+            prefs.getBoolean("allowcoloredtext", false).let {
+              edit.putBoolean(getString(R.string.preference_colorize_mirc_key), it)
+            }
+            edit.remove("allowcoloredtext")
           }
-          edit.remove("allowcoloredtext")
-        }
 
-        if (prefs.contains("monospace")) {
-          prefs.getBoolean("monospace", false).let {
-            edit.putBoolean(getString(R.string.preference_monospace_key), it)
+          if (prefs.contains("monospace")) {
+            prefs.getBoolean("monospace", false).let {
+              edit.putBoolean(getString(R.string.preference_monospace_key), it)
+            }
+            edit.remove("monospace")
           }
-          edit.remove("monospace")
-        }
 
-        if (prefs.contains("detailed_actions")) {
-          prefs.getBoolean("detailed_actions", false).let {
-            edit.putBoolean(getString(R.string.preference_hostmask_actions_key), it)
+          if (prefs.contains("detailed_actions")) {
+            prefs.getBoolean("detailed_actions", false).let {
+              edit.putBoolean(getString(R.string.preference_hostmask_actions_key), it)
+            }
+            edit.remove("detailed_actions")
           }
-          edit.remove("detailed_actions")
-        }
 
-        if (prefs.contains("showlag")) {
-          prefs.getBoolean("showlag", false).let {
-            edit.putBoolean(getString(R.string.preference_show_lag_key), it)
+          if (prefs.contains("showlag")) {
+            prefs.getBoolean("showlag", false).let {
+              edit.putBoolean(getString(R.string.preference_show_lag_key), it)
+            }
+            edit.remove("showlag")
           }
-          edit.remove("showlag")
         }
-      }
-    )).migrate(PreferenceManager.getDefaultSharedPreferences(this))
+      )
+    ).migrate(this)
 
     // Initialize preferences unless already set
-    PreferenceManager.setDefaultValues(this, R.xml.preferences, false)
 
     /*
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/settings/SettingsMigrationManager.kt b/app/src/main/java/de/kuschku/quasseldroid/settings/SettingsMigrationManager.kt
index 0adb6975d..c5ae9f9e9 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/settings/SettingsMigrationManager.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/settings/SettingsMigrationManager.kt
@@ -20,9 +20,14 @@
 package de.kuschku.quasseldroid.settings
 
 import android.annotation.SuppressLint
-import android.content.SharedPreferences
+import android.content.Context
+import android.support.annotation.XmlRes
+import android.support.v7.preference.PreferenceManager
+import android.support.v7.preference.PreferenceManager.KEY_HAS_SET_DEFAULT_VALUES
+import de.kuschku.quasseldroid.R.xml.preferences
 
 class SettingsMigrationManager(
+  @XmlRes preferences: Int,
   migrations: List<SettingsMigration>
 ) {
   private val migrationMap = migrations.associateBy(SettingsMigration::from)
@@ -30,17 +35,24 @@ class SettingsMigrationManager(
 
   // This runs during initial start and has to run synchronously
   @SuppressLint("ApplySharedPref")
-  fun migrate(preferences: SharedPreferences) {
-    var version = preferences.getInt(SETTINGS_VERSION, 0)
-    while (version != currentVersion) {
-      val migration = migrationMap[version]
-                      ?: throw IllegalArgumentException("Migration not available")
-      val editor = preferences.edit()
-      migration.migrate(preferences, editor)
-      version = migration.to
-      editor.putInt(SETTINGS_VERSION, version)
-      editor.commit()
+  fun migrate(context: Context) {
+    val defaultValueSp = context.getSharedPreferences(KEY_HAS_SET_DEFAULT_VALUES,
+                                                      Context.MODE_PRIVATE)
+
+    if (!defaultValueSp.getBoolean(KEY_HAS_SET_DEFAULT_VALUES, false)) {
+      val preferences = PreferenceManager.getDefaultSharedPreferences(context)
+      var version = preferences.getInt(SETTINGS_VERSION, 0)
+      while (version != currentVersion) {
+        val migration = migrationMap[version]
+                        ?: throw IllegalArgumentException("Migration not available")
+        val editor = preferences.edit()
+        migration.migrate(preferences, editor)
+        version = migration.to
+        editor.putInt(SETTINGS_VERSION, version)
+        editor.commit()
+      }
     }
+    PreferenceManager.setDefaultValues(context, preferences, false)
   }
 
   companion object {
-- 
GitLab