EtchDroid/app/src/main/java/eu/depau/etchdroid/services/UsbAPIWriteService.kt

80 lines
2.6 KiB
Kotlin
Raw Normal View History

2018-08-15 17:04:45 +00:00
package eu.depau.etchdroid.services
2018-08-13 23:32:02 +00:00
import android.content.Intent
import android.hardware.usb.UsbDevice
import android.net.Uri
import android.util.Log
2018-08-13 23:32:02 +00:00
import com.github.mjdev.libaums.UsbMassStorageDevice
import eu.depau.etchdroid.kotlin_exts.getFileName
import eu.depau.etchdroid.kotlin_exts.getFileSize
import eu.depau.etchdroid.kotlin_exts.name
2018-08-13 23:32:02 +00:00
import java.nio.ByteBuffer
class UsbAPIWriteService : UsbWriteService("UsbAPIWriteService") {
// 512 * 32 bytes = USB max transfer size
val DD_BLOCKSIZE = 512 * 32 * 64 // 1 MB
2018-08-13 23:32:02 +00:00
class Action {
2018-08-15 17:04:45 +00:00
val WRITE_IMAGE = "eu.depau.etchdroid.action.API_WRITE_IMAGE"
val WRITE_CANCEL = "eu.depau.etchdroid.action.API_WRITE_CANCEL"
2018-08-13 23:32:02 +00:00
}
private fun getUsbMSDevice(usbDevice: UsbDevice): UsbMassStorageDevice? {
val msDevs = UsbMassStorageDevice.getMassStorageDevices(this)
for (dev in msDevs) {
if (dev.usbDevice == usbDevice)
return dev
}
return null
}
2018-08-14 16:49:22 +00:00
override fun writeImage(intent: Intent): Long {
val uri: Uri = intent.data!!
val usbDevice: UsbDevice = intent.getParcelableExtra("usbDevice")
2018-08-13 23:32:02 +00:00
val msDev = getUsbMSDevice(usbDevice)!!
msDev.init()
val blockDev = msDev.blockDevice
2018-08-14 16:49:22 +00:00
val bsFactor = DD_BLOCKSIZE / blockDev.blockSize
val byteBuffer = ByteBuffer.allocate(blockDev.blockSize * bsFactor)
2018-08-13 23:32:02 +00:00
val imageSize = uri.getFileSize(this)
val inputStream = contentResolver.openInputStream(uri)!!
2018-08-14 16:49:22 +00:00
val startTime = System.currentTimeMillis()
2018-08-13 23:32:02 +00:00
var readBytes: Int
var offset = 0L
2018-08-14 16:49:22 +00:00
var writtenBytes: Long = 0
2018-08-13 23:32:02 +00:00
2018-08-14 16:49:22 +00:00
try {
while (true) {
wakeLock(true)
readBytes = inputStream.read(byteBuffer.array()!!)
if (readBytes < 0)
break
byteBuffer.position(0)
blockDev.write(offset, byteBuffer)
offset += bsFactor
writtenBytes += readBytes
updateNotification(usbDevice.name, uri.getFileName(this), offset * blockDev.blockSize, imageSize)
}
resultNotification(usbDevice.name, uri.getFileName(this)!!, true, writtenBytes, startTime)
} catch (e: Exception) {
resultNotification(usbDevice.name, uri.getFileName(this)!!, false, writtenBytes, startTime)
Log.e(TAG, "Could't write image to ${usbDevice.name}")
throw e
} finally {
wakeLock(false)
msDev.close()
2018-08-13 23:32:02 +00:00
}
Log.d(TAG, "Written $writtenBytes bytes to ${usbDevice.name} using API")
return writtenBytes
2018-08-13 23:32:02 +00:00
}
}