EtchDroid/app/src/main/java/eu/depau/etchdroid/activities/ConfirmationActivity.kt

193 lines
7.2 KiB
Kotlin

package eu.depau.etchdroid.activities
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import eu.depau.etchdroid.R
import eu.depau.etchdroid.StateKeeper
import eu.depau.etchdroid.adapters.PartitionTableRecyclerViewAdapter
import eu.depau.etchdroid.enums.FlashMethod
import eu.depau.etchdroid.img_types.DMGImage
import eu.depau.etchdroid.kotlin_exts.*
import eu.depau.etchdroid.services.UsbApiDmgWriteService
import eu.depau.etchdroid.services.UsbApiImgWriteService
import eu.depau.etchdroid.utils.DoNotShowAgainDialogFragment
import kotlinx.android.synthetic.main.activity_confirmation.*
import java.io.IOException
class ConfirmationActivity : ActivityBase() {
var canContinue: Boolean = false
var issuesFound: String? = null
var shouldShowDataLossAlertDialog: Boolean
get() {
val settings = getSharedPreferences(DISMISSED_DIALOGS_PREFS, 0)
return !settings.getBoolean("data_loss_alert", false)
}
set(value) {
val settings = getSharedPreferences(DISMISSED_DIALOGS_PREFS, 0)
val editor = settings.edit()
editor.putBoolean("data_loss_alert", !value)
editor.apply()
}
fun showDataLossAlertDialog() {
val dialogFragment = DoNotShowAgainDialogFragment(nightModeHelper.nightMode)
dialogFragment.title = getString(R.string.warning)
dialogFragment.message = getString(R.string.dataloss_confirmation_dialog_message)
dialogFragment.positiveButton = getString(R.string.confirm_flash_image)
dialogFragment.negativeButton = getString(R.string.cancel)
dialogFragment.listener = object : DoNotShowAgainDialogFragment.DialogListener {
override fun onDialogNegative(dialog: DoNotShowAgainDialogFragment, showAgain: Boolean) {}
override fun onDialogPositive(dialog: DoNotShowAgainDialogFragment, showAgain: Boolean) {
shouldShowDataLossAlertDialog = showAgain
nextStep(false)
}
}
dialogFragment.show(supportFragmentManager, "DataLossAlertDialogFragment")
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_confirmation)
actionBar?.setDisplayHomeAsUpEnabled(true)
confirm_fab.setOnClickListener(this::onButtonClicked)
// displayImageLayout must be called before displayDetails
// to ensure uncompressed image size is available
displayImageLayout()
displayDetails()
}
fun displayDetails() {
confirm_sel_method.text = when (StateKeeper.flashMethod) {
FlashMethod.FLASH_API -> getString(R.string.flash_dd_usb_api)
FlashMethod.FLASH_DMG_API -> getString(R.string.flash_dmg_api)
FlashMethod.FLASH_UNETBOOTIN -> getString(R.string.flash_unetbootin)
FlashMethod.FLASH_WOEUSB -> getString(R.string.flash_woeusb)
else -> null
}
confirm_sel_image.text = StateKeeper.imageFile?.getFileName(this)
if (confirm_sel_image.text == null)
confirm_sel_image.text = getString(R.string.unknown_filename)
val imgSize: Long?
val sizeStr: String?
if (StateKeeper.imageRepr?.size != null) {
imgSize = StateKeeper.imageRepr?.size
sizeStr = imgSize?.toHRSize() + " " + getString(R.string.uncompressed)
} else {
imgSize = StateKeeper.imageFile?.getFileSize(this)
sizeStr = imgSize?.toHRSize()
}
confirm_sel_image_size.text = sizeStr
confirm_sel_usbdev.text = StateKeeper.usbDevice?.name
for (trial in 0..1) {
try {
StateKeeper.usbMassStorageDevice!!.init()
val blockDev = StateKeeper.usbMassStorageDevice!!.blockDevice
if (blockDev != null) {
val devSize = (blockDev.size.toLong() * blockDev.blockSize.toLong())
confirm_sel_usbdev_size.text = devSize.toHRSize()
if (imgSize!! > devSize)
confirm_extra_info.text = getString(R.string.image_bigger_than_usb)
else {
val text = getString(R.string.tap_next_to_write)
confirm_extra_info.text = text
canContinue = true
}
} else {
confirm_extra_info.text = getString(R.string.cant_read_usbdev)
}
} catch (e: IOException) {
if (trial == 0) {
continue
} else {
confirm_extra_info.text = getString(R.string.could_not_access_usb_error)
break
}
} finally {
StateKeeper.usbMassStorageDevice!!.close()
}
}
}
fun displayImageLayout() {
val uri = StateKeeper.imageFile ?: return
val text = uri.getFileName(this)
if (StateKeeper.flashMethod == FlashMethod.FLASH_DMG_API) {
StateKeeper.imageRepr = DMGImage(uri, this)
val imgRepr = StateKeeper.imageRepr as DMGImage
if (imgRepr.tableType == null && (imgRepr.partitionTable == null || imgRepr.partitionTable?.size == 0)) {
issuesFound = getString(R.string.image_is_not_dmg)
part_table_header.text = issuesFound
return
} else {
part_table_header.text = if (imgRepr.tableType != null) getString(R.string.partition_table_title) else ""
part_table_header_side.text = imgRepr.tableType?.getString(this) ?: ""
issuesFound = null
val viewAdapter = PartitionTableRecyclerViewAdapter(imgRepr.partitionTable!!)
part_table_recycler.apply {
setHasFixedSize(true)
layoutManager = LinearLayoutManager(context)
adapter = viewAdapter
}
}
}
}
fun nextStep(showDialog: Boolean = true) {
if (!canContinue || issuesFound != null) {
confirm_fab.snackbar(issuesFound ?: getString(R.string.cannot_write))
return
}
if (showDialog && shouldShowDataLossAlertDialog) {
showDataLossAlertDialog()
return
}
toast(getString(R.string.check_notification_progress), Toast.LENGTH_LONG)
val intent: Intent = when (StateKeeper.flashMethod) {
FlashMethod.FLASH_API -> Intent(this, UsbApiImgWriteService::class.java)
FlashMethod.FLASH_DMG_API -> Intent(this, UsbApiDmgWriteService::class.java)
else -> null!!
}
intent.setDataAndType(StateKeeper.imageFile, "application/octet-stream")
intent.putExtra("usbDevice", StateKeeper.usbDevice)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
startForegroundService(intent)
else
startService(intent)
moveTaskToBack(true)
finish()
}
fun onButtonClicked(view: View) {
when (view.id) {
R.id.confirm_fab -> nextStep()
}
}
}