mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-08-27 13:39:54 +00:00
desktop: fix linking mobile and connecting after onboarding. Also fixes other cases when core controller changes in android/desktop. (#6489)
This commit is contained in:
+2
-2
@@ -21,7 +21,7 @@ sealed class WriteFileResult {
|
||||
* */
|
||||
|
||||
fun writeCryptoFile(path: String, data: ByteArray): CryptoFileArgs {
|
||||
val ctrl = ChatController.ctrl ?: throw Exception("Controller is not initialized")
|
||||
val ctrl = ChatController.getChatCtrl() ?: throw Exception("Controller is not initialized")
|
||||
val buffer = ByteBuffer.allocateDirect(data.size)
|
||||
buffer.put(data)
|
||||
buffer.rewind()
|
||||
@@ -44,7 +44,7 @@ fun readCryptoFile(path: String, cryptoArgs: CryptoFileArgs): ByteArray {
|
||||
}
|
||||
|
||||
fun encryptCryptoFile(fromPath: String, toPath: String): CryptoFileArgs {
|
||||
val ctrl = ChatController.ctrl ?: throw Exception("Controller is not initialized")
|
||||
val ctrl = ChatController.getChatCtrl() ?: throw Exception("Controller is not initialized")
|
||||
val str = chatEncryptFile(ctrl, fromPath, toPath)
|
||||
val d = json.decodeFromString(WriteFileResult.serializer(), str)
|
||||
return when (d) {
|
||||
|
||||
+27
-10
@@ -482,17 +482,26 @@ class AppPreferences {
|
||||
private const val MESSAGE_TIMEOUT: Int = 300_000_000
|
||||
|
||||
object ChatController {
|
||||
var ctrl: ChatCtrl? = -1
|
||||
private var chatCtrl: ChatCtrl? = -1
|
||||
val appPrefs: AppPreferences by lazy { AppPreferences() }
|
||||
|
||||
val messagesChannel: Channel<API> = Channel()
|
||||
|
||||
val chatModel = ChatModel
|
||||
private var receiverStarted = false
|
||||
private var receiverJob: Job? = null
|
||||
var lastMsgReceivedTimestamp: Long = System.currentTimeMillis()
|
||||
private set
|
||||
|
||||
fun hasChatCtrl() = ctrl != -1L && ctrl != null
|
||||
fun hasChatCtrl() = chatCtrl != -1L && chatCtrl != null
|
||||
|
||||
fun getChatCtrl(): ChatCtrl? = chatCtrl
|
||||
|
||||
fun setChatCtrl(ctrl: ChatCtrl?) {
|
||||
val wasRunning = receiverJob != null
|
||||
stopReceiver()
|
||||
chatCtrl = ctrl
|
||||
if (wasRunning && ctrl != null) startReceiver()
|
||||
}
|
||||
|
||||
suspend fun getAgentSubsTotal(rh: Long?): Pair<SMPServerSubs, Boolean>? {
|
||||
val userId = currentUserId("getAgentSubsTotal")
|
||||
@@ -639,17 +648,16 @@ object ChatController {
|
||||
|
||||
private fun startReceiver() {
|
||||
Log.d(TAG, "ChatController startReceiver")
|
||||
if (receiverStarted) return
|
||||
receiverStarted = true
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
if (receiverJob != null || chatCtrl == null) return
|
||||
receiverJob = CoroutineScope(Dispatchers.IO).launch {
|
||||
var releaseLock: (() -> Unit) = {}
|
||||
while (true) {
|
||||
while (isActive) {
|
||||
/** Global [ctrl] can be null. It's needed for having the same [ChatModel] that already made in [ChatController] without the need
|
||||
* to change it everywhere in code after changing a database.
|
||||
* Since it can be changed in background thread, making this check to prevent NullPointerException */
|
||||
val ctrl = ctrl
|
||||
val ctrl = chatCtrl
|
||||
if (ctrl == null) {
|
||||
receiverStarted = false
|
||||
stopReceiver()
|
||||
break
|
||||
}
|
||||
try {
|
||||
@@ -689,6 +697,15 @@ object ChatController {
|
||||
}
|
||||
}
|
||||
|
||||
private fun stopReceiver() {
|
||||
Log.d(TAG, "ChatController stopReceiver")
|
||||
val job = receiverJob
|
||||
if (job != null) {
|
||||
receiverJob = null
|
||||
job.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun sendCmdWithRetry(rhId: Long?, cmd: CC, inProgress: MutableState<Boolean>? = null, retryNum: Int = 0): API? {
|
||||
val r = sendCmd(rhId, cmd, retryNum = retryNum)
|
||||
val alert = if (r is API.Error) retryableNetworkErrorAlert(r.err) else null
|
||||
@@ -773,7 +790,7 @@ object ChatController {
|
||||
}
|
||||
|
||||
suspend fun sendCmd(rhId: Long?, cmd: CC, otherCtrl: ChatCtrl? = null, retryNum: Int = 0, log: Boolean = true): API {
|
||||
val ctrl = otherCtrl ?: ctrl ?: throw Exception("Controller is not initialized")
|
||||
val ctrl = otherCtrl ?: chatCtrl ?: throw Exception("Controller is not initialized")
|
||||
|
||||
return withContext(Dispatchers.IO) {
|
||||
val c = cmd.cmdString
|
||||
|
||||
+3
-2
@@ -56,6 +56,7 @@ fun initChatControllerOnStart() {
|
||||
}
|
||||
|
||||
suspend fun initChatController(useKey: String? = null, confirmMigrations: MigrationConfirmation? = null, startChat: () -> CompletableDeferred<Boolean> = { CompletableDeferred(true) }) {
|
||||
Log.d(TAG, "initChatController")
|
||||
try {
|
||||
if (chatModel.ctrlInitInProgress.value) return
|
||||
chatModel.ctrlInitInProgress.value = true
|
||||
@@ -92,7 +93,7 @@ suspend fun initChatController(useKey: String? = null, confirmMigrations: Migrat
|
||||
val ctrl = if (res is DBMigrationResult.OK) {
|
||||
migrated[1] as Long
|
||||
} else null
|
||||
chatController.ctrl = ctrl
|
||||
chatController.setChatCtrl(ctrl)
|
||||
chatModel.chatDbEncrypted.value = dbKey != ""
|
||||
chatModel.chatDbStatus.value = res
|
||||
if (res != DBMigrationResult.OK) {
|
||||
@@ -206,7 +207,7 @@ fun chatInitControllerRemovingDatabases() {
|
||||
}.getOrElse { DBMigrationResult.Unknown(migrated[0] as String) }
|
||||
|
||||
val ctrl = migrated[1] as Long
|
||||
chatController.ctrl = ctrl
|
||||
chatController.setChatCtrl(ctrl)
|
||||
// We need only controller, not databases
|
||||
File(dbPath + "_chat.db").delete()
|
||||
File(dbPath + "_agent.db").delete()
|
||||
|
||||
+2
-1
@@ -804,7 +804,8 @@ fun SimpleXTheme(darkTheme: Boolean? = null, content: @Composable () -> Unit) {
|
||||
LocalAppColors provides rememberedAppColors,
|
||||
LocalAppWallpaper provides rememberedWallpaper,
|
||||
LocalDensity provides density,
|
||||
content = content)
|
||||
content = content
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
+1
-1
@@ -131,7 +131,7 @@ fun UserPicker(
|
||||
}
|
||||
LaunchedEffect(Unit) {
|
||||
// Controller.ctrl can be null when self-destructing activates
|
||||
if (controller.ctrl != null && controller.ctrl != -1L) {
|
||||
if (controller.hasChatCtrl()) {
|
||||
withBGApi {
|
||||
controller.reloadRemoteHosts()
|
||||
}
|
||||
|
||||
+2
-1
@@ -366,6 +366,7 @@ fun startChat(
|
||||
chatDbChanged: MutableState<Boolean>,
|
||||
progressIndicator: MutableState<Boolean>? = null
|
||||
) {
|
||||
Log.d(TAG, "startChat")
|
||||
withLongRunningApi {
|
||||
try {
|
||||
progressIndicator?.value = true
|
||||
@@ -532,7 +533,7 @@ fun deleteChatDatabaseFilesAndState() {
|
||||
appPrefs.newDatabaseInitialized.set(false)
|
||||
chatModel.desktopOnboardingRandomPassword.value = false
|
||||
controller.appPrefs.storeDBPassphrase.set(true)
|
||||
controller.ctrl = null
|
||||
controller.setChatCtrl(null)
|
||||
|
||||
// Clear sensitive data on screen just in case ModalManager will fail to prevent hiding its modals while database encrypts itself
|
||||
chatModel.chatId.value = null
|
||||
|
||||
+2
-2
@@ -33,7 +33,7 @@ fun LocalAuthView(m: ChatModel, authRequest: LocalAuthRequest) {
|
||||
}
|
||||
} else {
|
||||
val r: LAResult = if (passcode.value == authRequest.password) {
|
||||
if (authRequest.selfDestruct && sdPassword != null && controller.ctrl == -1L) {
|
||||
if (authRequest.selfDestruct && sdPassword != null && controller.getChatCtrl() == -1L) {
|
||||
initChatControllerOnStart()
|
||||
}
|
||||
LAResult.Success
|
||||
@@ -58,7 +58,7 @@ private fun deleteStorageAndRestart(m: ChatModel, password: String, completed: (
|
||||
if (m.chatRunning.value == true) {
|
||||
stopChatAsync(m)
|
||||
}
|
||||
val ctrl = m.controller.ctrl
|
||||
val ctrl = m.controller.getChatCtrl()
|
||||
if (ctrl != null && ctrl != -1L) {
|
||||
/**
|
||||
* The following sequence can bring a user here:
|
||||
|
||||
+1
-1
@@ -633,7 +633,7 @@ private fun MutableState<MigrationToState?>.startDownloading(
|
||||
private fun MutableState<MigrationToState?>.importArchive(archivePath: String, netCfg: NetCfg, networkProxy: NetworkProxy?) {
|
||||
withLongRunningApi {
|
||||
try {
|
||||
if (ChatController.ctrl == null || ChatController.ctrl == -1L) {
|
||||
if (!ChatController.hasChatCtrl()) {
|
||||
chatInitControllerRemovingDatabases()
|
||||
}
|
||||
controller.apiDeleteStorage()
|
||||
|
||||
Reference in New Issue
Block a user