kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
firmware update progress bar kinda works
rodzic
5044c5393f
commit
3c338aec61
|
@ -21,6 +21,7 @@ import com.geeksville.analytics.DataPair
|
||||||
import com.geeksville.android.GeeksvilleApplication
|
import com.geeksville.android.GeeksvilleApplication
|
||||||
import com.geeksville.android.Logging
|
import com.geeksville.android.Logging
|
||||||
import com.geeksville.android.ServiceClient
|
import com.geeksville.android.ServiceClient
|
||||||
|
import com.geeksville.concurrent.handledLaunch
|
||||||
import com.geeksville.mesh.*
|
import com.geeksville.mesh.*
|
||||||
import com.geeksville.mesh.MeshProtos.MeshPacket
|
import com.geeksville.mesh.MeshProtos.MeshPacket
|
||||||
import com.geeksville.mesh.MeshProtos.ToRadio
|
import com.geeksville.mesh.MeshProtos.ToRadio
|
||||||
|
@ -35,21 +36,8 @@ import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.JsonConfiguration
|
import kotlinx.serialization.json.JsonConfiguration
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
import kotlin.coroutines.EmptyCoroutineContext
|
|
||||||
|
|
||||||
|
|
||||||
private val errorHandler = CoroutineExceptionHandler { _, exception ->
|
|
||||||
Exceptions.report(exception, "MeshService-coroutine", "coroutine-exception")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Wrap launch with an exception handler, FIXME, move into a utility lib
|
|
||||||
fun CoroutineScope.handledLaunch(
|
|
||||||
context: CoroutineContext = EmptyCoroutineContext,
|
|
||||||
start: CoroutineStart = CoroutineStart.DEFAULT,
|
|
||||||
block: suspend CoroutineScope.() -> Unit
|
|
||||||
) = this.launch(context = context + errorHandler, start = start, block = block)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles all the communication with android apps. Also keeps an internal model
|
* Handles all the communication with android apps. Also keeps an internal model
|
||||||
* of the network state.
|
* of the network state.
|
||||||
|
@ -67,7 +55,7 @@ class MeshService : Service(), Logging {
|
||||||
|
|
||||||
class IdNotFoundException(id: String) : Exception("ID not found $id")
|
class IdNotFoundException(id: String) : Exception("ID not found $id")
|
||||||
class NodeNumNotFoundException(id: Int) : Exception("NodeNum not found $id")
|
class NodeNumNotFoundException(id: Int) : Exception("NodeNum not found $id")
|
||||||
class NotInMeshException() : Exception("We are not yet in a mesh")
|
// class NotInMeshException() : Exception("We are not yet in a mesh")
|
||||||
|
|
||||||
/** A little helper that just calls startService
|
/** A little helper that just calls startService
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -17,6 +17,7 @@ import com.geeksville.android.BinaryLogFile
|
||||||
import com.geeksville.android.GeeksvilleApplication
|
import com.geeksville.android.GeeksvilleApplication
|
||||||
import com.geeksville.android.Logging
|
import com.geeksville.android.Logging
|
||||||
import com.geeksville.concurrent.DeferredExecution
|
import com.geeksville.concurrent.DeferredExecution
|
||||||
|
import com.geeksville.concurrent.handledLaunch
|
||||||
import com.geeksville.mesh.IRadioInterfaceService
|
import com.geeksville.mesh.IRadioInterfaceService
|
||||||
import com.geeksville.mesh.anonymized
|
import com.geeksville.mesh.anonymized
|
||||||
import com.geeksville.util.exceptionReporter
|
import com.geeksville.util.exceptionReporter
|
||||||
|
|
|
@ -25,6 +25,7 @@ import androidx.lifecycle.Observer
|
||||||
import com.geeksville.android.GeeksvilleApplication
|
import com.geeksville.android.GeeksvilleApplication
|
||||||
import com.geeksville.android.Logging
|
import com.geeksville.android.Logging
|
||||||
import com.geeksville.android.hideKeyboard
|
import com.geeksville.android.hideKeyboard
|
||||||
|
import com.geeksville.concurrent.handledLaunch
|
||||||
import com.geeksville.mesh.MainActivity
|
import com.geeksville.mesh.MainActivity
|
||||||
import com.geeksville.mesh.R
|
import com.geeksville.mesh.R
|
||||||
import com.geeksville.mesh.anonymized
|
import com.geeksville.mesh.anonymized
|
||||||
|
@ -34,6 +35,10 @@ import com.geeksville.mesh.service.RadioInterfaceService
|
||||||
import com.geeksville.util.exceptionReporter
|
import com.geeksville.util.exceptionReporter
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import kotlinx.android.synthetic.main.settings_fragment.*
|
import kotlinx.android.synthetic.main.settings_fragment.*
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
object SLogging : Logging {}
|
object SLogging : Logging {}
|
||||||
|
@ -290,6 +295,11 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
|
||||||
private val scanModel: BTScanModel by activityViewModels()
|
private val scanModel: BTScanModel by activityViewModels()
|
||||||
private val model: UIViewModel by activityViewModels()
|
private val model: UIViewModel by activityViewModels()
|
||||||
|
|
||||||
|
// FIXME - move this into a standard GUI helper class
|
||||||
|
private val guiJob = Job()
|
||||||
|
private val mainScope = CoroutineScope(Dispatchers.Main + guiJob)
|
||||||
|
|
||||||
|
|
||||||
private val hasCompanionDeviceApi: Boolean by lazy {
|
private val hasCompanionDeviceApi: Boolean by lazy {
|
||||||
RadioInterfaceService.hasCompanionDeviceApi(requireContext())
|
RadioInterfaceService.hasCompanionDeviceApi(requireContext())
|
||||||
}
|
}
|
||||||
|
@ -298,6 +308,33 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
|
||||||
requireContext().getSystemService(CompanionDeviceManager::class.java)
|
requireContext().getSystemService(CompanionDeviceManager::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
guiJob.cancel()
|
||||||
|
super.onDestroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun doFirmwareUpdate() {
|
||||||
|
model.meshService?.let { service ->
|
||||||
|
|
||||||
|
mainScope.handledLaunch {
|
||||||
|
debug("User started firmware update")
|
||||||
|
updateFirmwareButton.isEnabled = false // Disable until things complete
|
||||||
|
updateProgressBar.visibility = View.VISIBLE
|
||||||
|
|
||||||
|
scanStatusText.text = "Updating firmware, wait up to eight minutes..."
|
||||||
|
service.startFirmwareUpdate()
|
||||||
|
while (service.updateStatus >= 0) {
|
||||||
|
updateProgressBar.progress = service.updateStatus
|
||||||
|
delay(2000) // Only check occasionally
|
||||||
|
}
|
||||||
|
scanStatusText.text =
|
||||||
|
if (service.updateStatus == -1) "Update successful" else "Update failed"
|
||||||
|
updateProgressBar.isEnabled = false
|
||||||
|
updateFirmwareButton.isEnabled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
|
@ -340,11 +377,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
|
||||||
})
|
})
|
||||||
|
|
||||||
updateFirmwareButton.setOnClickListener {
|
updateFirmwareButton.setOnClickListener {
|
||||||
debug("User started firmware update")
|
doFirmwareUpdate()
|
||||||
updateFirmwareButton.isEnabled = false // Disable until things complete
|
|
||||||
updateProgressBar.visibility = View.VISIBLE
|
|
||||||
model.meshService?.startFirmwareUpdate()
|
|
||||||
scanStatusText.text = "Updating firmware, wait up to eight minutes..."
|
|
||||||
}
|
}
|
||||||
|
|
||||||
usernameEditText.on(EditorInfo.IME_ACTION_DONE) {
|
usernameEditText.on(EditorInfo.IME_ACTION_DONE) {
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 1c729d801162380f2db9c2a3c681458f4a719bd1
|
Subproject commit b53b7f90b326ef6b1dedca32a2472784e63d10e6
|
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 102 KiB |
Ładowanie…
Reference in New Issue