From 48a67e51a676a16d04169b45b19c04a693b35f4c Mon Sep 17 00:00:00 2001 From: Koen J Date: Wed, 7 May 2025 20:57:55 +0200 Subject: [PATCH] Various fixes. --- .../activities/SyncHomeActivity.kt | 11 ++++++ .../futo/platformplayer/states/StateApp.kt | 39 ++++++++++++++----- .../platformplayer/states/StatePlaylists.kt | 13 ++++--- .../futo/platformplayer/states/StateSync.kt | 3 +- .../stores/FragmentedStorage.kt | 7 +--- .../sync/internal/SyncSocketSession.kt | 4 +- 6 files changed, 53 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/com/futo/platformplayer/activities/SyncHomeActivity.kt b/app/src/main/java/com/futo/platformplayer/activities/SyncHomeActivity.kt index ed79832c..e8e95f66 100644 --- a/app/src/main/java/com/futo/platformplayer/activities/SyncHomeActivity.kt +++ b/app/src/main/java/com/futo/platformplayer/activities/SyncHomeActivity.kt @@ -9,6 +9,7 @@ import android.widget.LinearLayout import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope import com.futo.platformplayer.R +import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.setNavigationBarColorAndIcons import com.futo.platformplayer.states.StateApp import com.futo.platformplayer.states.StateSync @@ -29,6 +30,16 @@ class SyncHomeActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + + if (StateApp.instance.contextOrNull == null) { + Logger.w(TAG, "No main activity, restarting main.") + val intent = Intent(this, MainActivity::class.java) + intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) + startActivity(intent) + finish() + return + } + setContentView(R.layout.activity_sync_home) setNavigationBarColorAndIcons() diff --git a/app/src/main/java/com/futo/platformplayer/states/StateApp.kt b/app/src/main/java/com/futo/platformplayer/states/StateApp.kt index cdfb308d..2988b217 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StateApp.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StateApp.kt @@ -530,10 +530,17 @@ class StateApp { //Migration Logger.i(TAG, "MainApp Started: Check [Migrations]"); - migrateStores(context, listOf( - StateSubscriptions.instance.toMigrateCheck(), - StatePlaylists.instance.toMigrateCheck() - ).flatten(), 0); + + scopeOrNull?.launch(Dispatchers.IO) { + try { + migrateStores(context, listOf( + StateSubscriptions.instance.toMigrateCheck(), + StatePlaylists.instance.toMigrateCheck() + ).flatten(), 0) + } catch (e: Throwable) { + Logger.e(TAG, "Failed to migrate stores") + } + } if(Settings.instance.subscriptions.fetchOnAppBoot) { scope.launch(Dispatchers.IO) { @@ -700,15 +707,27 @@ class StateApp { } - private fun migrateStores(context: Context, managedStores: List>, index: Int) { + private suspend fun migrateStores(context: Context, managedStores: List>, index: Int) { if(managedStores.size <= index) return; val store = managedStores[index]; - if(store.hasMissingReconstructions()) - UIDialogs.showMigrateDialog(context, store) { - migrateStores(context, managedStores, index + 1); - }; - else + if(store.hasMissingReconstructions()) { + withContext(Dispatchers.Main) { + try { + UIDialogs.showMigrateDialog(context, store) { + scopeOrNull?.launch(Dispatchers.IO) { + try { + migrateStores(context, managedStores, index + 1); + } catch (e: Throwable) { + Logger.e(TAG, "Failed to migrate store", e) + } + } + } + } catch (e: Throwable) { + Logger.e(TAG, "Failed to migrate stores", e) + } + } + } else migrateStores(context, managedStores, index + 1); } diff --git a/app/src/main/java/com/futo/platformplayer/states/StatePlaylists.kt b/app/src/main/java/com/futo/platformplayer/states/StatePlaylists.kt index fe194b2d..c20375f2 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StatePlaylists.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StatePlaylists.kt @@ -401,12 +401,15 @@ class StatePlaylists { companion object { val TAG = "StatePlaylists"; private var _instance : StatePlaylists? = null; + private var _lockObject = Object() val instance : StatePlaylists - get(){ - if(_instance == null) - _instance = StatePlaylists(); - return _instance!!; - }; + get() { + synchronized(_lockObject) { + if (_instance == null) + _instance = StatePlaylists(); + return _instance!!; + } + } fun finish() { _instance?.let { diff --git a/app/src/main/java/com/futo/platformplayer/states/StateSync.kt b/app/src/main/java/com/futo/platformplayer/states/StateSync.kt index f0ac4456..10aaa24d 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StateSync.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StateSync.kt @@ -57,6 +57,7 @@ import kotlinx.coroutines.withContext import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import java.io.ByteArrayInputStream +import java.net.Inet4Address import java.net.InetAddress import java.net.InetSocketAddress import java.net.ServerSocket @@ -438,7 +439,7 @@ class StateSync { Logger.v(TAG, "Received ${connectionInfos.size} devices connection information") for ((targetKey, connectionInfo) in connectionInfos) { - val potentialLocalAddresses = connectionInfo.ipv4Addresses.union(connectionInfo.ipv6Addresses) + val potentialLocalAddresses = connectionInfo.ipv4Addresses .filter { it != connectionInfo.remoteIp } if (connectionInfo.allowLocalDirect && Settings.instance.synchronization.connectLocalDirectThroughRelay) { Thread { diff --git a/app/src/main/java/com/futo/platformplayer/stores/FragmentedStorage.kt b/app/src/main/java/com/futo/platformplayer/stores/FragmentedStorage.kt index b943d01c..c5ff802a 100644 --- a/app/src/main/java/com/futo/platformplayer/stores/FragmentedStorage.kt +++ b/app/src/main/java/com/futo/platformplayer/stores/FragmentedStorage.kt @@ -125,12 +125,7 @@ class FragmentedStorage { } inline fun load(fileName: String): T where T : FragmentedStorageFile { if (_filesDir == null) { - if(StateApp.instance.contextOrNull == null) - StateApp.instance.initializeFiles(); - - if (_filesDir == null) { - throw Exception("Files dir should be initialized before loading a file.") - } + throw Exception("Files dir should be initialized before loading a file.") } val storageFile = File(_filesDir, "${fileName}.json"); diff --git a/app/src/main/java/com/futo/platformplayer/sync/internal/SyncSocketSession.kt b/app/src/main/java/com/futo/platformplayer/sync/internal/SyncSocketSession.kt index bd6f70db..5c3bdb9d 100644 --- a/app/src/main/java/com/futo/platformplayer/sync/internal/SyncSocketSession.kt +++ b/app/src/main/java/com/futo/platformplayer/sync/internal/SyncSocketSession.kt @@ -316,7 +316,7 @@ class SyncSocketSession { val appId = messageBuffer.int.toUInt() val pairingMessageLength = messageBuffer.int val pairingMessage = if (pairingMessageLength > 0) ByteArray(pairingMessageLength).also { messageBuffer.get(it) } else byteArrayOf() - val mainLength = messageSize - 4 - 4 - pairingMessageLength + val mainLength = messageBuffer.remaining() val mainMessage = ByteArray(mainLength).also { messageBuffer.get(it) } var pairingCode: String? = null @@ -333,7 +333,7 @@ class SyncSocketSession { responder.readMessage(mainMessage, 0, mainLength, plaintext, 0) val remoteKeyBytes = ByteArray(responder.remotePublicKey.publicKeyLength) responder.remotePublicKey.getPublicKey(remoteKeyBytes, 0) - val remotePublicKey = Base64.getEncoder().encodeToString(remoteKeyBytes) + val remotePublicKey = remoteKeyBytes.toBase64() val isAllowedToConnect = remotePublicKey != _localPublicKey && (_isHandshakeAllowed?.invoke(LinkType.Direct, this, remotePublicKey, pairingCode, appId) ?: true) if (!isAllowedToConnect) {