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

71 lines
2.1 KiB
Kotlin

package eu.depau.ddroid.services
import android.content.Intent
import android.hardware.usb.UsbDevice
import android.net.Uri
import com.github.mjdev.libaums.UsbMassStorageDevice
import eu.depau.ddroid.abc.UsbWriteService
import eu.depau.ddroid.utils.getFileSize
import eu.depau.ddroid.utils.name
import java.nio.ByteBuffer
class UsbAPIWriteService : UsbWriteService("UsbAPIWriteService") {
class Action {
val WRITE_IMAGE = "eu.depau.ddroid.action.API_WRITE_IMAGE"
val WRITE_CANCEL = "eu.depau.ddroid.action.API_WRITE_CANCEL"
}
override fun onHandleIntent(intent: Intent?) {
val uri: Uri = intent!!.data!!
val usbDevice: UsbDevice = intent.getParcelableExtra("usbDevice")
startForeground(FOREGROUND_ID, buildForegroundNotification(usbDevice.name, uri, -1, -1))
try {
val notify = { bytes: Long, total: Long -> updateNotification(usbDevice.name, uri, bytes, total) }
writeImage(usbDevice, uri, notify)
} finally {
stopForeground(true)
}
}
private fun getUsbMSDevice(usbDevice: UsbDevice): UsbMassStorageDevice? {
val msDevs = UsbMassStorageDevice.getMassStorageDevices(this)
for (dev in msDevs) {
if (dev.usbDevice == usbDevice)
return dev
}
return null
}
private fun writeImage(usbDevice: UsbDevice, uri: Uri, notify: (Long, Long) -> Unit): Long {
val msDev = getUsbMSDevice(usbDevice)!!
msDev.init()
val blockDev = msDev.blockDevice
val byteBuffer = ByteBuffer.allocate(blockDev.blockSize)
val imageSize = uri.getFileSize(this)
val inputStream = contentResolver.openInputStream(uri)!!
var readBytes: Int
var offset = 0L
while (true) {
readBytes = inputStream.read(byteBuffer.array()!!)
if (readBytes < 0)
break
byteBuffer.position(readBytes)
blockDev.write(offset, byteBuffer)
offset++
notify(offset * blockDev.blockSize, imageSize)
}
msDev.close()
return offset * blockDev.blockSize
}
}