kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
refactor: move `IMeshService` instance to repository
rodzic
e93fac2ae3
commit
37dad9b6fa
|
@ -56,6 +56,7 @@ import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.cancel
|
import kotlinx.coroutines.cancel
|
||||||
import java.text.DateFormat
|
import java.text.DateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
/*
|
/*
|
||||||
UI design
|
UI design
|
||||||
|
@ -117,6 +118,9 @@ class MainActivity : AppCompatActivity(), Logging {
|
||||||
private val bluetoothViewModel: BluetoothViewModel by viewModels()
|
private val bluetoothViewModel: BluetoothViewModel by viewModels()
|
||||||
private val model: UIViewModel by viewModels()
|
private val model: UIViewModel by viewModels()
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
internal lateinit var serviceRepository: ServiceRepository
|
||||||
|
|
||||||
private val bluetoothPermissionsLauncher =
|
private val bluetoothPermissionsLauncher =
|
||||||
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { result ->
|
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { result ->
|
||||||
if (result.entries.all { it.value }) {
|
if (result.entries.all { it.value }) {
|
||||||
|
@ -351,7 +355,7 @@ class MainActivity : AppCompatActivity(), Logging {
|
||||||
debug("connchange $oldConnection -> $newConnection")
|
debug("connchange $oldConnection -> $newConnection")
|
||||||
|
|
||||||
if (newConnection == MeshService.ConnectionState.CONNECTED) {
|
if (newConnection == MeshService.ConnectionState.CONNECTED) {
|
||||||
model.meshService?.let { service ->
|
serviceRepository.meshService?.let { service ->
|
||||||
|
|
||||||
model.setConnectionState(newConnection)
|
model.setConnectionState(newConnection)
|
||||||
|
|
||||||
|
@ -506,44 +510,8 @@ class MainActivity : AppCompatActivity(), Logging {
|
||||||
IMeshService.Stub.asInterface(it)
|
IMeshService.Stub.asInterface(it)
|
||||||
}) {
|
}) {
|
||||||
override fun onConnected(service: IMeshService) {
|
override fun onConnected(service: IMeshService) {
|
||||||
|
|
||||||
/*
|
|
||||||
Note: we must call this callback in a coroutine. Because apparently there is only a single activity looper thread. and if that onConnected override
|
|
||||||
also tries to do a service operation we can deadlock.
|
|
||||||
|
|
||||||
Old buggy stack trace:
|
|
||||||
|
|
||||||
at sun.misc.Unsafe.park (Unsafe.java)
|
|
||||||
- waiting on an unknown object
|
|
||||||
at java.util.concurrent.locks.LockSupport.park (LockSupport.java:190)
|
|
||||||
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await (AbstractQueuedSynchronizer.java:2067)
|
|
||||||
at com.geeksville.mesh.android.ServiceClient.waitConnect (ServiceClient.java:46)
|
|
||||||
at com.geeksville.mesh.android.ServiceClient.getService (ServiceClient.java:27)
|
|
||||||
at com.geeksville.mesh.service.MeshService$binder$1$setDeviceAddress$1.invoke (MeshService.java:1519)
|
|
||||||
at com.geeksville.mesh.service.MeshService$binder$1$setDeviceAddress$1.invoke (MeshService.java:1514)
|
|
||||||
at com.geeksville.mesh.util.ExceptionsKt.toRemoteExceptions (ExceptionsKt.java:56)
|
|
||||||
at com.geeksville.mesh.service.MeshService$binder$1.setDeviceAddress (MeshService.java:1516)
|
|
||||||
at com.geeksville.mesh.MainActivity$mesh$1$onConnected$1.invoke (MainActivity.java:743)
|
|
||||||
at com.geeksville.mesh.MainActivity$mesh$1$onConnected$1.invoke (MainActivity.java:734)
|
|
||||||
at com.geeksville.mesh.util.ExceptionsKt.exceptionReporter (ExceptionsKt.java:34)
|
|
||||||
at com.geeksville.mesh.MainActivity$mesh$1.onConnected (MainActivity.java:738)
|
|
||||||
at com.geeksville.mesh.MainActivity$mesh$1.onConnected (MainActivity.java:734)
|
|
||||||
at com.geeksville.mesh.android.ServiceClient$connection$1$onServiceConnected$1.invoke (ServiceClient.java:89)
|
|
||||||
at com.geeksville.mesh.android.ServiceClient$connection$1$onServiceConnected$1.invoke (ServiceClient.java:84)
|
|
||||||
at com.geeksville.mesh.util.ExceptionsKt.exceptionReporter (ExceptionsKt.java:34)
|
|
||||||
at com.geeksville.mesh.android.ServiceClient$connection$1.onServiceConnected (ServiceClient.java:85)
|
|
||||||
at android.app.LoadedApk$ServiceDispatcher.doConnected (LoadedApk.java:2067)
|
|
||||||
at android.app.LoadedApk$ServiceDispatcher$RunConnection.run (LoadedApk.java:2099)
|
|
||||||
at android.os.Handler.handleCallback (Handler.java:883)
|
|
||||||
at android.os.Handler.dispatchMessage (Handler.java:100)
|
|
||||||
at android.os.Looper.loop (Looper.java:237)
|
|
||||||
at android.app.ActivityThread.main (ActivityThread.java:8016)
|
|
||||||
at java.lang.reflect.Method.invoke (Method.java)
|
|
||||||
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:493)
|
|
||||||
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1076)
|
|
||||||
*/
|
|
||||||
connectionJob = mainScope.handledLaunch {
|
connectionJob = mainScope.handledLaunch {
|
||||||
model.meshService = service
|
serviceRepository.setMeshService(service)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
usbDevice?.let { usb ->
|
usbDevice?.let { usb ->
|
||||||
|
@ -582,14 +550,14 @@ class MainActivity : AppCompatActivity(), Logging {
|
||||||
|
|
||||||
override fun onDisconnected() {
|
override fun onDisconnected() {
|
||||||
unregisterMeshReceiver()
|
unregisterMeshReceiver()
|
||||||
model.meshService = null
|
serviceRepository.setMeshService(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun bindMeshService() {
|
private fun bindMeshService() {
|
||||||
debug("Binding to mesh service!")
|
debug("Binding to mesh service!")
|
||||||
// we bind using the well known name, to make sure 3rd party apps could also
|
// we bind using the well known name, to make sure 3rd party apps could also
|
||||||
if (model.meshService != null) {
|
if (serviceRepository.meshService != null) {
|
||||||
/* This problem can occur if we unbind, but there is already an onConnected job waiting to run. That job runs and then makes meshService != null again
|
/* This problem can occur if we unbind, but there is already an onConnected job waiting to run. That job runs and then makes meshService != null again
|
||||||
I think I've fixed this by cancelling connectionJob. We'll see!
|
I think I've fixed this by cancelling connectionJob. We'll see!
|
||||||
*/
|
*/
|
||||||
|
@ -622,7 +590,7 @@ class MainActivity : AppCompatActivity(), Logging {
|
||||||
job.cancel("unbinding")
|
job.cancel("unbinding")
|
||||||
}
|
}
|
||||||
mesh.close()
|
mesh.close()
|
||||||
model.meshService = null
|
serviceRepository.setMeshService(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStop() {
|
override fun onStop() {
|
||||||
|
|
|
@ -106,7 +106,7 @@ class UIViewModel @Inject constructor(
|
||||||
) : ViewModel(), Logging {
|
) : ViewModel(), Logging {
|
||||||
|
|
||||||
var actionBarMenu: Menu? = null
|
var actionBarMenu: Menu? = null
|
||||||
var meshService: IMeshService? = null
|
val meshService: IMeshService? get() = radioConfigRepository.meshService
|
||||||
val nodeDB = NodeDB(this)
|
val nodeDB = NodeDB(this)
|
||||||
|
|
||||||
val bondedAddress get() = radioInterfaceService.getBondedDeviceAddress()
|
val bondedAddress get() = radioInterfaceService.getBondedDeviceAddress()
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.geeksville.mesh.AppOnlyProtos.ChannelSet
|
||||||
import com.geeksville.mesh.ChannelProtos.Channel
|
import com.geeksville.mesh.ChannelProtos.Channel
|
||||||
import com.geeksville.mesh.ChannelProtos.ChannelSettings
|
import com.geeksville.mesh.ChannelProtos.ChannelSettings
|
||||||
import com.geeksville.mesh.ConfigProtos.Config
|
import com.geeksville.mesh.ConfigProtos.Config
|
||||||
|
import com.geeksville.mesh.IMeshService
|
||||||
import com.geeksville.mesh.LocalOnlyProtos.LocalConfig
|
import com.geeksville.mesh.LocalOnlyProtos.LocalConfig
|
||||||
import com.geeksville.mesh.LocalOnlyProtos.LocalModuleConfig
|
import com.geeksville.mesh.LocalOnlyProtos.LocalModuleConfig
|
||||||
import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig
|
import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig
|
||||||
|
@ -11,6 +12,7 @@ import com.geeksville.mesh.MyNodeInfo
|
||||||
import com.geeksville.mesh.NodeInfo
|
import com.geeksville.mesh.NodeInfo
|
||||||
import com.geeksville.mesh.database.dao.MyNodeInfoDao
|
import com.geeksville.mesh.database.dao.MyNodeInfoDao
|
||||||
import com.geeksville.mesh.database.dao.NodeInfoDao
|
import com.geeksville.mesh.database.dao.NodeInfoDao
|
||||||
|
import com.geeksville.mesh.service.ServiceRepository
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.firstOrNull
|
import kotlinx.coroutines.flow.firstOrNull
|
||||||
|
@ -23,12 +25,15 @@ import javax.inject.Inject
|
||||||
* and [ChannelSet], [LocalConfig] & [LocalModuleConfig] data stores.
|
* and [ChannelSet], [LocalConfig] & [LocalModuleConfig] data stores.
|
||||||
*/
|
*/
|
||||||
class RadioConfigRepository @Inject constructor(
|
class RadioConfigRepository @Inject constructor(
|
||||||
|
private val serviceRepository: ServiceRepository,
|
||||||
private val myNodeInfoDao: MyNodeInfoDao,
|
private val myNodeInfoDao: MyNodeInfoDao,
|
||||||
private val nodeInfoDao: NodeInfoDao,
|
private val nodeInfoDao: NodeInfoDao,
|
||||||
private val channelSetRepository: ChannelSetRepository,
|
private val channelSetRepository: ChannelSetRepository,
|
||||||
private val localConfigRepository: LocalConfigRepository,
|
private val localConfigRepository: LocalConfigRepository,
|
||||||
private val moduleConfigRepository: ModuleConfigRepository,
|
private val moduleConfigRepository: ModuleConfigRepository,
|
||||||
) {
|
) {
|
||||||
|
val meshService: IMeshService? get() = serviceRepository.meshService
|
||||||
|
|
||||||
suspend fun clearNodeDB() = withContext(Dispatchers.IO) {
|
suspend fun clearNodeDB() = withContext(Dispatchers.IO) {
|
||||||
myNodeInfoDao.clearMyNodeInfo()
|
myNodeInfoDao.clearMyNodeInfo()
|
||||||
nodeInfoDao.clearNodeInfo()
|
nodeInfoDao.clearNodeInfo()
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.geeksville.mesh.service
|
||||||
|
|
||||||
|
import com.geeksville.mesh.IMeshService
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class ServiceRepository @Inject constructor() {
|
||||||
|
var meshService: IMeshService? = null
|
||||||
|
private set
|
||||||
|
|
||||||
|
fun setMeshService(service: IMeshService?) {
|
||||||
|
meshService = service
|
||||||
|
}
|
||||||
|
}
|
Ładowanie…
Reference in New Issue