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
|
2018-08-14 15:23:37 +00:00
|
|
|
import android.util.Log
|
2018-08-13 23:32:02 +00:00
|
|
|
import com.github.mjdev.libaums.UsbMassStorageDevice
|
2018-08-15 17:04:45 +00:00
|
|
|
import eu.depau.etchdroid.abc.UsbWriteService
|
|
|
|
import eu.depau.etchdroid.utils.getFileName
|
|
|
|
import eu.depau.etchdroid.utils.getFileSize
|
|
|
|
import eu.depau.etchdroid.utils.name
|
2018-08-13 23:32:02 +00:00
|
|
|
import java.nio.ByteBuffer
|
|
|
|
|
|
|
|
class UsbAPIWriteService : UsbWriteService("UsbAPIWriteService") {
|
2018-08-14 17:55:29 +00:00
|
|
|
// 512 * 32 bytes = USB max transfer size
|
|
|
|
val DD_BLOCKSIZE = 512 * 32 * 64 // 1 MB
|
2018-08-14 12:05:30 +00:00
|
|
|
|
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
|
2018-08-14 12:05:30 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2018-08-14 15:23:37 +00:00
|
|
|
Log.d(TAG, "Written $writtenBytes bytes to ${usbDevice.name} using API")
|
|
|
|
return writtenBytes
|
2018-08-13 23:32:02 +00:00
|
|
|
}
|
|
|
|
}
|