Replace volatile cancel flag with coroutine Job cancellation in EspFlasher
This commit is contained in:
parent
ece115fbd6
commit
71b13c51ee
2 changed files with 13 additions and 24 deletions
|
|
@ -24,20 +24,13 @@ class EspFlasher(private val context: Context) {
|
||||||
fun onProgress(percent: Int, message: String)
|
fun onProgress(percent: Int, message: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Volatile
|
|
||||||
private var cancelled = false
|
|
||||||
|
|
||||||
fun cancel() {
|
|
||||||
cancelled = true
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun flashDevice(usbManager: UsbManager, device: UsbDevice, callback: FlashCallback) {
|
suspend fun flashDevice(usbManager: UsbManager, device: UsbDevice, callback: FlashCallback) {
|
||||||
cancelled = false
|
|
||||||
try {
|
try {
|
||||||
withContext(kotlinx.coroutines.Dispatchers.IO) {
|
withContext(kotlinx.coroutines.Dispatchers.IO) {
|
||||||
doFlash(usbManager, device, callback)
|
doFlash(usbManager, device, callback)
|
||||||
}
|
}
|
||||||
} catch (e: CancellationException) {
|
} catch (e: CancellationException) {
|
||||||
|
Log.i(TAG, "Flash cancelled")
|
||||||
throw e
|
throw e
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Flash failed", e)
|
Log.e(TAG, "Flash failed", e)
|
||||||
|
|
@ -56,7 +49,7 @@ class EspFlasher(private val context: Context) {
|
||||||
|
|
||||||
private suspend fun doFlash(usbManager: UsbManager, device: UsbDevice, callback: FlashCallback) {
|
private suspend fun doFlash(usbManager: UsbManager, device: UsbDevice, callback: FlashCallback) {
|
||||||
kotlinx.coroutines.delay(500)
|
kotlinx.coroutines.delay(500)
|
||||||
checkCancelled()
|
coroutineContext.ensureActive()
|
||||||
|
|
||||||
val connection = usbManager.openDevice(device)
|
val connection = usbManager.openDevice(device)
|
||||||
?: throw IOException("Kan USB-apparaat niet openen")
|
?: throw IOException("Kan USB-apparaat niet openen")
|
||||||
|
|
@ -77,7 +70,7 @@ class EspFlasher(private val context: Context) {
|
||||||
callback.onProgress(0, "Verbinden met ESP bootloader...")
|
callback.onProgress(0, "Verbinden met ESP bootloader...")
|
||||||
|
|
||||||
val transport = UsbSerialTransport(connection, epOut, epIn)
|
val transport = UsbSerialTransport(connection, epOut, epIn)
|
||||||
checkCancelled()
|
coroutineContext.ensureActive()
|
||||||
|
|
||||||
val assets = context.assets
|
val assets = context.assets
|
||||||
val bootloader = assets.open("firmware/bootloader.bin").readBytes()
|
val bootloader = assets.open("firmware/bootloader.bin").readBytes()
|
||||||
|
|
@ -116,7 +109,7 @@ class EspFlasher(private val context: Context) {
|
||||||
stub.eraseFlash()
|
stub.eraseFlash()
|
||||||
|
|
||||||
for (step in steps) {
|
for (step in steps) {
|
||||||
checkCancelled()
|
coroutineContext.ensureActive()
|
||||||
val sizeStr = if (step.data.size > 1024) "${step.data.size / 1024}KB" else "${step.data.size} bytes"
|
val sizeStr = if (step.data.size > 1024) "${step.data.size / 1024}KB" else "${step.data.size} bytes"
|
||||||
callback.onProgress(step.baseProgress, "${step.name} schrijven ($sizeStr)...")
|
callback.onProgress(step.baseProgress, "${step.name} schrijven ($sizeStr)...")
|
||||||
|
|
||||||
|
|
@ -136,9 +129,4 @@ class EspFlasher(private val context: Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun checkCancelled() {
|
|
||||||
if (cancelled) {
|
|
||||||
coroutineContext.ensureActive()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@ import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
import java.security.SecureRandom
|
import java.security.SecureRandom
|
||||||
|
|
||||||
|
|
@ -47,7 +47,7 @@ class SettingsActivity : AppCompatActivity() {
|
||||||
private var currentAction = UsbAction.NONE
|
private var currentAction = UsbAction.NONE
|
||||||
private var progressDialog: AlertDialog? = null
|
private var progressDialog: AlertDialog? = null
|
||||||
private var dialog: AlertDialog? = null
|
private var dialog: AlertDialog? = null
|
||||||
private var flasher: EspFlasher? = null
|
private var flasherJob: Job? = null
|
||||||
|
|
||||||
private val usbAttachedReceiver = object : BroadcastReceiver() {
|
private val usbAttachedReceiver = object : BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
|
@ -124,8 +124,8 @@ class SettingsActivity : AppCompatActivity() {
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
currentAction = UsbAction.NONE
|
currentAction = UsbAction.NONE
|
||||||
flasher?.cancel()
|
flasherJob?.cancel()
|
||||||
flasher = null
|
flasherJob = null
|
||||||
try { unregisterReceiver(usbAttachedReceiver) } catch (_: Exception) {}
|
try { unregisterReceiver(usbAttachedReceiver) } catch (_: Exception) {}
|
||||||
try { unregisterReceiver(usbPermissionReceiver) } catch (_: Exception) {}
|
try { unregisterReceiver(usbPermissionReceiver) } catch (_: Exception) {}
|
||||||
try { unregisterReceiver(usbDetachedReceiver) } catch (_: Exception) {}
|
try { unregisterReceiver(usbDetachedReceiver) } catch (_: Exception) {}
|
||||||
|
|
@ -211,7 +211,7 @@ class SettingsActivity : AppCompatActivity() {
|
||||||
dialog = null
|
dialog = null
|
||||||
showProgressDialog("Firmware Flashen", "Initialiseren...", STYLE_HORIZONTAL)
|
showProgressDialog("Firmware Flashen", "Initialiseren...", STYLE_HORIZONTAL)
|
||||||
|
|
||||||
flasher = EspFlasher(this)
|
val flasher = EspFlasher(this)
|
||||||
val progressCallback = object : EspFlasher.FlashCallback {
|
val progressCallback = object : EspFlasher.FlashCallback {
|
||||||
override fun onProgress(percent: Int, message: String) {
|
override fun onProgress(percent: Int, message: String) {
|
||||||
lifecycleScope.launch(Dispatchers.Main) {
|
lifecycleScope.launch(Dispatchers.Main) {
|
||||||
|
|
@ -221,9 +221,9 @@ class SettingsActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lifecycleScope.launch {
|
flasherJob = lifecycleScope.launch {
|
||||||
try {
|
try {
|
||||||
flasher?.flashDevice(usbManager, device, progressCallback)
|
flasher.flashDevice(usbManager, device, progressCallback)
|
||||||
if (isFinishing || isDestroyed) return@launch
|
if (isFinishing || isDestroyed) return@launch
|
||||||
currentAction = UsbAction.NONE
|
currentAction = UsbAction.NONE
|
||||||
progressDialog?.dismiss()
|
progressDialog?.dismiss()
|
||||||
|
|
@ -240,6 +240,7 @@ class SettingsActivity : AppCompatActivity() {
|
||||||
.show()
|
.show()
|
||||||
} catch (e: kotlinx.coroutines.CancellationException) {
|
} catch (e: kotlinx.coroutines.CancellationException) {
|
||||||
cleanupAction()
|
cleanupAction()
|
||||||
|
throw e
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
progressDialog?.dismiss()
|
progressDialog?.dismiss()
|
||||||
progressDialog = null
|
progressDialog = null
|
||||||
|
|
@ -290,7 +291,7 @@ class SettingsActivity : AppCompatActivity() {
|
||||||
.setTitle(title)
|
.setTitle(title)
|
||||||
.setView(view)
|
.setView(view)
|
||||||
.setNegativeButton("Annuleren") { _, _ ->
|
.setNegativeButton("Annuleren") { _, _ ->
|
||||||
flasher?.cancel()
|
flasherJob?.cancel()
|
||||||
cleanupAction()
|
cleanupAction()
|
||||||
}
|
}
|
||||||
.setCancelable(false)
|
.setCancelable(false)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue