From 533649a6b6fc05324adc068972d0c6568f4345a7 Mon Sep 17 00:00:00 2001 From: James Power Date: Fri, 13 Mar 2026 23:02:15 -0400 Subject: [PATCH] Migrate SharedPreferences to DataStore for app state keys. --- gradle/libs.versions.toml | 1 + lib/build.gradle | 1 + .../ncmud/mudwammer/launcher/Launcher.java | 52 ++------------ .../ncmud/mudwammer/service/Connection.java | 9 ++- .../mudwammer/service/StellarService.java | 12 ++-- .../ncmud/mudwammer/window/MainWindow.java | 16 ++--- .../org/ncmud/mudwammer/data/AppStateStore.kt | 69 +++++++++++++++++++ 7 files changed, 89 insertions(+), 71 deletions(-) create mode 100644 lib/src/main/kotlin/org/ncmud/mudwammer/data/AppStateStore.kt diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ec7e125a..db6b5ee6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -35,6 +35,7 @@ room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" } room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" } coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutines" } +datastore-core = { module = "androidx.datastore:datastore-core", version.ref = "datastore" } datastore-preferences = { module = "androidx.datastore:datastore-preferences", version.ref = "datastore" } junit5-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit5" } junit5-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit5" } diff --git a/lib/build.gradle b/lib/build.gradle index ed62983e..d072c0f6 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -71,6 +71,7 @@ dependencies { api libs.coroutines.core api libs.coroutines.android + api libs.datastore.core api libs.datastore.preferences api 'com.github.ncmud:mth:2.0.4' diff --git a/lib/src/main/java/org/ncmud/mudwammer/launcher/Launcher.java b/lib/src/main/java/org/ncmud/mudwammer/launcher/Launcher.java index a0d77f40..eb151bc3 100644 --- a/lib/src/main/java/org/ncmud/mudwammer/launcher/Launcher.java +++ b/lib/src/main/java/org/ncmud/mudwammer/launcher/Launcher.java @@ -11,7 +11,8 @@ import android.content.Intent; import android.content.ServiceConnection; import android.content.SharedPreferences; -import android.content.SharedPreferences.Editor; +import org.ncmud.mudwammer.data.AppStateKeys; +import org.ncmud.mudwammer.data.AppStateStore; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; @@ -426,8 +427,7 @@ public void onClick(View v) { // if(mode == LAUNCH_MODE.TEST) { if (ConfigurationLoader.isTestMode(this)) { int readver = - this.getSharedPreferences("TEST_VERSION_DOWHATSNEW", Context.MODE_PRIVATE) - .getInt("TEST_VERSION", 0); + AppStateStore.getInt(this, AppStateKeys.INSTANCE.getTEST_VERSION(), 0); int testVersion = 0; try { testVersion = @@ -442,11 +442,7 @@ public void onClick(View v) { if (testVersion != readver) { dowhatsnew = true; - SharedPreferences.Editor edit = - this.getSharedPreferences("TEST_VERSION_DOWHATSNEW", Context.MODE_PRIVATE) - .edit(); - edit.putInt("TEST_VERSION", testVersion); - edit.apply(); + AppStateStore.putInt(this, AppStateKeys.INSTANCE.getTEST_VERSION(), testVersion); } } @@ -628,11 +624,8 @@ public void onItemClick(AdapterView arg0, View arg1, int arg2, long arg3) { // titleBarHeight += statusBarHeight; // } - SharedPreferences pref = Launcher.this.getSharedPreferences("STATUS_BAR_HEIGHT", 0); - Editor e = pref.edit(); - e.putInt("STATUS_BAR_HEIGHT", statusBarHeight); - e.putInt("TITLE_BAR_HEIGHT", titleBarHeight); - e.apply(); + AppStateStore.putInt(Launcher.this, AppStateKeys.INSTANCE.getSTATUS_BAR_HEIGHT(), statusBarHeight); + AppStateStore.putInt(Launcher.this, AppStateKeys.INSTANCE.getTITLE_BAR_HEIGHT(), titleBarHeight); MudConnection muc = apdapter.getItem(arg2); @@ -1247,29 +1240,6 @@ public void onClick(DialogInterface dialog, int which) { } private void DoNewStartup() { - Pattern invalidchars = Pattern.compile("\\W"); - Matcher replacebadchars = invalidchars.matcher(launch.getDisplayName()); - String prefsname = replacebadchars.replaceAll("") + ".PREFS"; - // prefsname = prefsname.replaceAll("/", ""); - - SharedPreferences sprefs = Launcher.this.getSharedPreferences(prefsname, 0); - // servicestarted = prefs.getBoolean("CONNECTED", false); - // finishStart = prefs.getBoolean("FINISHSTART", true); - SharedPreferences.Editor editor = sprefs.edit(); - editor.putBoolean("CONNECTED", false); - editor.putBoolean("FINISHSTART", true); - editor.apply(); - // Log.e("LAUNCHER","SERVICE NOT STARTED, AM RESETTING THE INITIALIZER BOOLS IN " + - // prefsname); - - // Launcher.this.startActivity(the_intent); - // SharedPreferences sprefs = Launcher.this.getSharedPreferences(prefsname,0); - // SharedPreferences.Editor editor = sprefs.edit(); - // editor.putBoolean("CONNECTED", false); - // editor.putBoolean("FINISHSTART", true); - editor.apply(); - - // launch = muc; DoFinalStartup(); } @@ -1304,12 +1274,6 @@ private void DoFinalStartup() { // Log.e("LAUNCHER","SERVICE NOT STARTED, AM RESETTING THE INITIALIZER BOOLS IN " + // prefsname); - SharedPreferences prefs = Launcher.this.getSharedPreferences("SERVICE_INFO", 0); - Editor edit = prefs.edit(); - - edit.putString("SETTINGS_PATH", launch.getDisplayName()); - edit.apply(); - // this.unbindService(connectionChecker); Launcher.this.startActivity(the_intent); @@ -1991,10 +1955,6 @@ public void handleMessage(Message msg) { if (outer == null) return; switch (msg.what) { case MESSAGE_USERNAME: - SharedPreferences.Editor edit = - outer.getSharedPreferences("TEST_USER", Context.MODE_PRIVATE).edit(); - edit.putString("USER_NAME", (String) msg.obj); - edit.apply(); break; case MESSAGE_WHATSNEW: break; diff --git a/lib/src/main/java/org/ncmud/mudwammer/service/Connection.java b/lib/src/main/java/org/ncmud/mudwammer/service/Connection.java index 1be395ad..2e404e05 100644 --- a/lib/src/main/java/org/ncmud/mudwammer/service/Connection.java +++ b/lib/src/main/java/org/ncmud/mudwammer/service/Connection.java @@ -4,7 +4,8 @@ package org.ncmud.mudwammer.service; import android.content.Context; -import android.content.SharedPreferences; +import org.ncmud.mudwammer.data.AppStateKeys; +import org.ncmud.mudwammer.data.AppStateStore; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; @@ -447,17 +448,15 @@ public Connection( }, () -> self.mPump != null && self.mPump.isConnected()); - SharedPreferences sprefs = this.getContext().getSharedPreferences("STATUS_BAR_HEIGHT", 0); mStatusBarHeight = - sprefs.getInt( - "STATUS_BAR_HEIGHT", + AppStateStore.getInt(this.getContext(), AppStateKeys.INSTANCE.getSTATUS_BAR_HEIGHT(), (int) (STATUS_BAR_DEFAULT_SIZE * this.getContext() .getResources() .getDisplayMetrics() .density)); - mTitleBarHeight = sprefs.getInt("TITLE_BAR_HEIGHT", 0); + mTitleBarHeight = AppStateStore.getInt(this.getContext(), AppStateKeys.INSTANCE.getTITLE_BAR_HEIGHT(), 0); mLoaded = true; diff --git a/lib/src/main/java/org/ncmud/mudwammer/service/StellarService.java b/lib/src/main/java/org/ncmud/mudwammer/service/StellarService.java index 0e61820d..0a11f5f3 100644 --- a/lib/src/main/java/org/ncmud/mudwammer/service/StellarService.java +++ b/lib/src/main/java/org/ncmud/mudwammer/service/StellarService.java @@ -11,7 +11,8 @@ import android.app.Service; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; +import org.ncmud.mudwammer.data.AppStateKeys; +import org.ncmud.mudwammer.data.AppStateStore; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; @@ -171,9 +172,7 @@ public final void onCreate() { mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); mNotificationManager.cancelAll(); - SharedPreferences prefs = this.getSharedPreferences("SERVICE_INFO", 0); - - int libsver = prefs.getInt("CURRENT_LUA_LIBS_VERSION", 0); + int libsver = AppStateStore.getInt(this, AppStateKeys.INSTANCE.getLUA_LIBS_VERSION(), 0); Bundle meta = null; try { meta = @@ -188,10 +187,7 @@ public final void onCreate() { // copy new libs. try { updateLibs(); - // updatelibsver needs to be incremented and saved back into the shared preferences - SharedPreferences.Editor editor = prefs.edit(); - editor.putInt("CURRENT_LUA_LIBS_VERSION", packagever); - editor.apply(); + AppStateStore.putInt(this, AppStateKeys.INSTANCE.getLUA_LIBS_VERSION(), packagever); } catch (NameNotFoundException e) { e.printStackTrace(); } catch (IOException e) { diff --git a/lib/src/main/java/org/ncmud/mudwammer/window/MainWindow.java b/lib/src/main/java/org/ncmud/mudwammer/window/MainWindow.java index 48b27b17..5557c656 100644 --- a/lib/src/main/java/org/ncmud/mudwammer/window/MainWindow.java +++ b/lib/src/main/java/org/ncmud/mudwammer/window/MainWindow.java @@ -11,6 +11,8 @@ import android.content.Intent; import android.content.ServiceConnection; import android.content.SharedPreferences; +import org.ncmud.mudwammer.data.AppStateKeys; +import org.ncmud.mudwammer.data.AppStateStore; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; @@ -330,12 +332,10 @@ public void onCreate(Bundle icicle) { // org.ncmud.mudwammer.crashreport.CrashReporter(this.getApplicationContext())); } - SharedPreferences sprefs = this.getSharedPreferences("STATUS_BAR_HEIGHT", 0); statusBarHeight = - sprefs.getInt( - "STATUS_BAR_HEIGHT", + AppStateStore.getInt(this, AppStateKeys.INSTANCE.getSTATUS_BAR_HEIGHT(), (int) (25 * this.getResources().getDisplayMetrics().density)); - titleBarHeight = sprefs.getInt("TITLE_BAR_HEIGHT", 0); + titleBarHeight = AppStateStore.getInt(this, AppStateKeys.INSTANCE.getTITLE_BAR_HEIGHT(), 0); setContentView(R.layout.window_layout); androidx.appcompat.widget.Toolbar myToolbar = @@ -951,10 +951,6 @@ private void handleMainMessage(Message msg) { String serviceBindAction = ConfigurationLoader.getConfigurationValue( "serviceBindAction", MainWindow.this); - SharedPreferences.Editor edit = - getSharedPreferences("CONNECT_TO", Context.MODE_PRIVATE).edit(); - edit.putString("CONNECT_TO", getIntent().getStringExtra("DISPLAY")); - edit.apply(); bindService( new Intent( serviceBindAction, @@ -2359,10 +2355,6 @@ public void onResume() { //this.startService(new Intent(org.ncmud.mudwammer.service.IStellarService.class.getName() + ".MODE_TEST")); this.bindService(new Intent(org.ncmud.mudwammer.service.IStellarService.class.getName()+".MODE_TEST"), mConnection, 0); }*/ - SharedPreferences.Editor edit = - MainWindow.this.getSharedPreferences("CONNECT_TO", Context.MODE_PRIVATE).edit(); - edit.putString("CONNECT_TO", MainWindow.this.getIntent().getStringExtra("DISPLAY")); - edit.apply(); String serviceBindAction = ConfigurationLoader.getConfigurationValue("serviceBindAction", this); this.bindService( diff --git a/lib/src/main/kotlin/org/ncmud/mudwammer/data/AppStateStore.kt b/lib/src/main/kotlin/org/ncmud/mudwammer/data/AppStateStore.kt new file mode 100644 index 00000000..26a2d046 --- /dev/null +++ b/lib/src/main/kotlin/org/ncmud/mudwammer/data/AppStateStore.kt @@ -0,0 +1,69 @@ +package org.ncmud.mudwammer.data + +import android.content.Context +import androidx.datastore.core.DataStore +import androidx.datastore.core.MultiProcessDataStoreFactory +import androidx.datastore.core.Serializer +import androidx.datastore.preferences.core.MutablePreferences +import androidx.datastore.preferences.core.Preferences +import androidx.datastore.preferences.core.PreferencesSerializer +import androidx.datastore.preferences.core.edit +import androidx.datastore.preferences.core.intPreferencesKey +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking +import okio.buffer +import okio.sink +import okio.source +import java.io.InputStream +import java.io.OutputStream + +object AppStateKeys { + val STATUS_BAR_HEIGHT = intPreferencesKey("status_bar_height") + val TITLE_BAR_HEIGHT = intPreferencesKey("title_bar_height") + val TEST_VERSION = intPreferencesKey("test_version") + val LUA_LIBS_VERSION = intPreferencesKey("lua_libs_version") +} + +private object PreferencesJavaIoSerializer : Serializer { + override val defaultValue: Preferences = PreferencesSerializer.defaultValue + + override suspend fun readFrom(input: InputStream): Preferences = + PreferencesSerializer.readFrom(input.source().buffer()) + + override suspend fun writeTo(t: Preferences, output: OutputStream) { + val sink = output.sink().buffer() + PreferencesSerializer.writeTo(t, sink) + sink.flush() + } +} + +object AppStateStore { + @Volatile + private var instance: DataStore? = null + + fun getInstance(context: Context): DataStore { + return instance ?: synchronized(this) { + instance ?: MultiProcessDataStoreFactory.create( + serializer = PreferencesJavaIoSerializer, + produceFile = { + context.applicationContext.filesDir.resolve("datastore/app_state.preferences_pb") + } + ).also { instance = it } + } + } + + @JvmStatic + fun getInt(context: Context, key: Preferences.Key, defaultValue: Int): Int = runBlocking { + getInstance(context).data.first()[key] ?: defaultValue + } + + @JvmStatic + fun putInt(context: Context, key: Preferences.Key, value: Int): Unit = runBlocking { + getInstance(context).edit { it[key] = value } + } + + @JvmStatic + fun getAll(context: Context): Preferences = runBlocking { + getInstance(context).data.first() + } +}