mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Add cancellation to binary uploading
This commit is contained in:
@@ -221,7 +221,9 @@ class EntryActivity : LockingActivity() {
|
|||||||
registerProgressTask()
|
registerProgressTask()
|
||||||
onActionTaskListener = object : AttachmentFileNotificationService.ActionTaskListener {
|
onActionTaskListener = object : AttachmentFileNotificationService.ActionTaskListener {
|
||||||
override fun onAttachmentAction(fileUri: Uri, entryAttachmentState: EntryAttachmentState) {
|
override fun onAttachmentAction(fileUri: Uri, entryAttachmentState: EntryAttachmentState) {
|
||||||
entryContentsView?.putAttachment(entryAttachmentState)
|
if (entryAttachmentState.streamDirection != StreamDirection.UPLOAD) {
|
||||||
|
entryContentsView?.putAttachment(entryAttachmentState)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -372,6 +372,9 @@ class EntryEditActivity : LockingActivity(),
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
AttachmentState.CANCELED -> {
|
||||||
|
entryEditFragment?.removeAttachment(entryAttachmentState)
|
||||||
|
}
|
||||||
AttachmentState.ERROR -> {
|
AttachmentState.ERROR -> {
|
||||||
entryEditFragment?.removeAttachment(entryAttachmentState)
|
entryEditFragment?.removeAttachment(entryAttachmentState)
|
||||||
coordinatorLayout?.let {
|
coordinatorLayout?.let {
|
||||||
@@ -525,6 +528,7 @@ class EntryEditActivity : LockingActivity(),
|
|||||||
* Saves the new entry or update an existing entry in the database
|
* Saves the new entry or update an existing entry in the database
|
||||||
*/
|
*/
|
||||||
private fun saveEntry() {
|
private fun saveEntry() {
|
||||||
|
mAttachmentFileBinderManager?.stopUploadAllAttachments()
|
||||||
// Get the temp entry
|
// Get the temp entry
|
||||||
entryEditFragment?.getEntryInfo()?.let { newEntryInfo ->
|
entryEditFragment?.getEntryInfo()?.let { newEntryInfo ->
|
||||||
|
|
||||||
@@ -542,6 +546,7 @@ class EntryEditActivity : LockingActivity(),
|
|||||||
when (attachmentState.downloadState) {
|
when (attachmentState.downloadState) {
|
||||||
AttachmentState.START,
|
AttachmentState.START,
|
||||||
AttachmentState.IN_PROGRESS,
|
AttachmentState.IN_PROGRESS,
|
||||||
|
AttachmentState.CANCELED,
|
||||||
AttachmentState.ERROR -> {
|
AttachmentState.ERROR -> {
|
||||||
// Remove attachment not finished from info
|
// Remove attachment not finished from info
|
||||||
newEntryInfo.attachments = newEntryInfo.attachments.toMutableList().apply {
|
newEntryInfo.attachments = newEntryInfo.attachments.toMutableList().apply {
|
||||||
@@ -785,6 +790,7 @@ class EntryEditActivity : LockingActivity(),
|
|||||||
.setMessage(R.string.discard_changes)
|
.setMessage(R.string.discard_changes)
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
.setPositiveButton(R.string.discard) { _, _ ->
|
.setPositiveButton(R.string.discard) { _, _ ->
|
||||||
|
mAttachmentFileBinderManager?.stopUploadAllAttachments()
|
||||||
backPressedAlreadyApproved = true
|
backPressedAlreadyApproved = true
|
||||||
approved.invoke()
|
approved.invoke()
|
||||||
}.create().show()
|
}.create().show()
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ class EntryAttachmentsItemsAdapter(context: Context)
|
|||||||
}
|
}
|
||||||
AttachmentState.NULL,
|
AttachmentState.NULL,
|
||||||
AttachmentState.ERROR,
|
AttachmentState.ERROR,
|
||||||
|
AttachmentState.CANCELED,
|
||||||
AttachmentState.COMPLETE -> {
|
AttachmentState.COMPLETE -> {
|
||||||
holder.binaryFileProgressContainer.visibility = View.GONE
|
holder.binaryFileProgressContainer.visibility = View.GONE
|
||||||
holder.binaryFileProgress.visibility = View.GONE
|
holder.binaryFileProgress.visibility = View.GONE
|
||||||
@@ -159,8 +160,13 @@ class EntryAttachmentsItemsAdapter(context: Context)
|
|||||||
holder.binaryFileDeleteButton.visibility = View.GONE
|
holder.binaryFileDeleteButton.visibility = View.GONE
|
||||||
holder.binaryFileProgress.apply {
|
holder.binaryFileProgress.apply {
|
||||||
visibility = when (entryAttachmentState.downloadState) {
|
visibility = when (entryAttachmentState.downloadState) {
|
||||||
AttachmentState.NULL, AttachmentState.COMPLETE, AttachmentState.ERROR -> View.GONE
|
AttachmentState.NULL,
|
||||||
AttachmentState.START, AttachmentState.IN_PROGRESS -> View.VISIBLE
|
AttachmentState.COMPLETE,
|
||||||
|
AttachmentState.CANCELED,
|
||||||
|
AttachmentState.ERROR -> View.GONE
|
||||||
|
|
||||||
|
AttachmentState.START,
|
||||||
|
AttachmentState.IN_PROGRESS -> View.VISIBLE
|
||||||
}
|
}
|
||||||
progress = entryAttachmentState.downloadProgression
|
progress = entryAttachmentState.downloadProgression
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,5 +76,5 @@ data class EntryAttachmentState(var attachment: Attachment,
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum class AttachmentState {
|
enum class AttachmentState {
|
||||||
NULL, START, IN_PROGRESS, COMPLETE, ERROR
|
NULL, START, IN_PROGRESS, COMPLETE, CANCELED, ERROR
|
||||||
}
|
}
|
||||||
@@ -35,10 +35,8 @@ import com.kunzisoft.keepass.model.AttachmentState
|
|||||||
import com.kunzisoft.keepass.model.EntryAttachmentState
|
import com.kunzisoft.keepass.model.EntryAttachmentState
|
||||||
import com.kunzisoft.keepass.model.StreamDirection
|
import com.kunzisoft.keepass.model.StreamDirection
|
||||||
import com.kunzisoft.keepass.stream.readAllBytes
|
import com.kunzisoft.keepass.stream.readAllBytes
|
||||||
import com.kunzisoft.keepass.timeout.TimeoutHelper
|
|
||||||
import com.kunzisoft.keepass.utils.UriUtil
|
import com.kunzisoft.keepass.utils.UriUtil
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import java.io.BufferedInputStream
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.CopyOnWriteArrayList
|
import java.util.concurrent.CopyOnWriteArrayList
|
||||||
|
|
||||||
@@ -101,12 +99,15 @@ class AttachmentFileNotificationService: LockNotificationService() {
|
|||||||
|
|
||||||
when(intent?.action) {
|
when(intent?.action) {
|
||||||
ACTION_ATTACHMENT_FILE_START_UPLOAD -> {
|
ACTION_ATTACHMENT_FILE_START_UPLOAD -> {
|
||||||
actionUploadOrDownload(downloadFileUri,
|
actionStartUploadOrDownload(downloadFileUri,
|
||||||
intent,
|
intent,
|
||||||
StreamDirection.UPLOAD)
|
StreamDirection.UPLOAD)
|
||||||
}
|
}
|
||||||
|
ACTION_ATTACHMENT_FILE_STOP_UPLOAD -> {
|
||||||
|
actionStopUpload()
|
||||||
|
}
|
||||||
ACTION_ATTACHMENT_FILE_START_DOWNLOAD -> {
|
ACTION_ATTACHMENT_FILE_START_DOWNLOAD -> {
|
||||||
actionUploadOrDownload(downloadFileUri,
|
actionStartUploadOrDownload(downloadFileUri,
|
||||||
intent,
|
intent,
|
||||||
StreamDirection.DOWNLOAD)
|
StreamDirection.DOWNLOAD)
|
||||||
}
|
}
|
||||||
@@ -216,15 +217,22 @@ class AttachmentFileNotificationService: LockNotificationService() {
|
|||||||
setDeleteIntent(pendingDeleteIntent)
|
setDeleteIntent(pendingDeleteIntent)
|
||||||
setOngoing(false)
|
setOngoing(false)
|
||||||
}
|
}
|
||||||
|
AttachmentState.CANCELED -> {
|
||||||
|
setContentText(getString(R.string.download_canceled))
|
||||||
|
setDeleteIntent(pendingDeleteIntent)
|
||||||
|
setOngoing(false)
|
||||||
|
}
|
||||||
AttachmentState.ERROR -> {
|
AttachmentState.ERROR -> {
|
||||||
setContentText(getString(R.string.error_file_not_create))
|
setContentText(getString(R.string.error_file_not_create))
|
||||||
|
setDeleteIntent(pendingDeleteIntent)
|
||||||
setOngoing(false)
|
setOngoing(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
when (attachmentNotification.entryAttachmentState.downloadState) {
|
when (attachmentNotification.entryAttachmentState.downloadState) {
|
||||||
AttachmentState.ERROR,
|
AttachmentState.COMPLETE,
|
||||||
AttachmentState.COMPLETE -> {
|
AttachmentState.CANCELED,
|
||||||
|
AttachmentState.ERROR -> {
|
||||||
stopForeground(false)
|
stopForeground(false)
|
||||||
notificationManager?.notify(attachmentNotification.notificationId, builder.build())
|
notificationManager?.notify(attachmentNotification.notificationId, builder.build())
|
||||||
} else -> {
|
} else -> {
|
||||||
@@ -235,6 +243,7 @@ class AttachmentFileNotificationService: LockNotificationService() {
|
|||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
attachmentNotificationList.forEach { attachmentNotification ->
|
attachmentNotificationList.forEach { attachmentNotification ->
|
||||||
|
attachmentNotification.attachmentFileAction?.cancel()
|
||||||
attachmentNotification.attachmentFileAction?.listener = null
|
attachmentNotification.attachmentFileAction?.listener = null
|
||||||
notificationManager?.cancel(attachmentNotification.notificationId)
|
notificationManager?.cancel(attachmentNotification.notificationId)
|
||||||
}
|
}
|
||||||
@@ -263,10 +272,10 @@ class AttachmentFileNotificationService: LockNotificationService() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun actionUploadOrDownload(downloadFileUri: Uri?,
|
private fun actionStartUploadOrDownload(fileUri: Uri?,
|
||||||
intent: Intent,
|
intent: Intent,
|
||||||
streamDirection: StreamDirection) {
|
streamDirection: StreamDirection) {
|
||||||
if (downloadFileUri != null
|
if (fileUri != null
|
||||||
&& intent.hasExtra(ATTACHMENT_KEY)) {
|
&& intent.hasExtra(ATTACHMENT_KEY)) {
|
||||||
try {
|
try {
|
||||||
intent.getParcelableExtra<Attachment>(ATTACHMENT_KEY)?.let { entryAttachment ->
|
intent.getParcelableExtra<Attachment>(ATTACHMENT_KEY)?.let { entryAttachment ->
|
||||||
@@ -274,7 +283,7 @@ class AttachmentFileNotificationService: LockNotificationService() {
|
|||||||
val nextNotificationId = (attachmentNotificationList.maxByOrNull { it.notificationId }
|
val nextNotificationId = (attachmentNotificationList.maxByOrNull { it.notificationId }
|
||||||
?.notificationId ?: notificationId) + 1
|
?.notificationId ?: notificationId) + 1
|
||||||
val entryAttachmentState = EntryAttachmentState(entryAttachment, streamDirection)
|
val entryAttachmentState = EntryAttachmentState(entryAttachment, streamDirection)
|
||||||
val attachmentNotification = AttachmentNotification(downloadFileUri, nextNotificationId, entryAttachmentState)
|
val attachmentNotification = AttachmentNotification(fileUri, nextNotificationId, entryAttachmentState)
|
||||||
|
|
||||||
// Add action to the list on start
|
// Add action to the list on start
|
||||||
attachmentNotificationList.add(attachmentNotification)
|
attachmentNotificationList.add(attachmentNotification)
|
||||||
@@ -287,11 +296,24 @@ class AttachmentFileNotificationService: LockNotificationService() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Unable to upload/download $downloadFileUri", e)
|
Log.e(TAG, "Unable to upload/download $fileUri", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun actionStopUpload() {
|
||||||
|
try {
|
||||||
|
// Stop each upload
|
||||||
|
attachmentNotificationList.filter {
|
||||||
|
it.entryAttachmentState.streamDirection == StreamDirection.UPLOAD
|
||||||
|
}.forEach {
|
||||||
|
it.attachmentFileAction?.cancel()
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "Unable to stop upload", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class AttachmentFileAction(
|
private class AttachmentFileAction(
|
||||||
private val attachmentNotification: AttachmentNotification,
|
private val attachmentNotification: AttachmentNotification,
|
||||||
private val contentResolver: ContentResolver) {
|
private val contentResolver: ContentResolver) {
|
||||||
@@ -308,8 +330,6 @@ class AttachmentFileNotificationService: LockNotificationService() {
|
|||||||
|
|
||||||
// on pre execute
|
// on pre execute
|
||||||
CoroutineScope(Dispatchers.Main).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
TimeoutHelper.temporarilyDisableTimeout()
|
|
||||||
|
|
||||||
attachmentNotification.attachmentFileAction = this@AttachmentFileAction
|
attachmentNotification.attachmentFileAction = this@AttachmentFileAction
|
||||||
attachmentNotification.entryAttachmentState.apply {
|
attachmentNotification.entryAttachmentState.apply {
|
||||||
downloadState = AttachmentState.START
|
downloadState = AttachmentState.START
|
||||||
@@ -320,53 +340,62 @@ class AttachmentFileNotificationService: LockNotificationService() {
|
|||||||
|
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
// on Progress with thread
|
// on Progress with thread
|
||||||
val asyncResult: Deferred<Boolean> = async {
|
val asyncAction = launch {
|
||||||
var progressResult = true
|
attachmentNotification.entryAttachmentState.apply {
|
||||||
try {
|
try {
|
||||||
attachmentNotification.entryAttachmentState.apply {
|
downloadState = AttachmentState.IN_PROGRESS
|
||||||
downloadState = AttachmentState.IN_PROGRESS
|
|
||||||
|
|
||||||
when (streamDirection) {
|
when (streamDirection) {
|
||||||
StreamDirection.UPLOAD -> {
|
StreamDirection.UPLOAD -> {
|
||||||
uploadToDatabase(
|
uploadToDatabase(
|
||||||
attachmentNotification.uri,
|
attachmentNotification.uri,
|
||||||
attachment.binaryAttachment,
|
attachment.binaryAttachment,
|
||||||
contentResolver, 1024) { percent ->
|
contentResolver, 1024,
|
||||||
publishProgress(percent)
|
{ // Cancellation
|
||||||
|
downloadState == AttachmentState.CANCELED
|
||||||
|
}
|
||||||
|
) { percent ->
|
||||||
|
publishProgress(percent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StreamDirection.DOWNLOAD -> {
|
||||||
|
downloadFromDatabase(
|
||||||
|
attachmentNotification.uri,
|
||||||
|
attachment.binaryAttachment,
|
||||||
|
contentResolver, 1024) { percent ->
|
||||||
|
publishProgress(percent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StreamDirection.DOWNLOAD -> {
|
} catch (e: Exception) {
|
||||||
downloadFromDatabase(
|
e.printStackTrace()
|
||||||
attachmentNotification.uri,
|
downloadState = AttachmentState.ERROR
|
||||||
attachment.binaryAttachment,
|
|
||||||
contentResolver, 1024) { percent ->
|
|
||||||
publishProgress(percent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
progressResult = false
|
|
||||||
}
|
}
|
||||||
progressResult
|
attachmentNotification.entryAttachmentState.downloadState
|
||||||
}
|
}
|
||||||
|
|
||||||
// on post execute
|
// on post execute
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
val result = asyncResult.await()
|
asyncAction.join()
|
||||||
attachmentNotification.attachmentFileAction = null
|
|
||||||
attachmentNotification.entryAttachmentState.apply {
|
attachmentNotification.entryAttachmentState.apply {
|
||||||
downloadState = if (result) AttachmentState.COMPLETE else AttachmentState.ERROR
|
if (downloadState != AttachmentState.CANCELED
|
||||||
downloadProgression = 100
|
&& downloadState != AttachmentState.ERROR) {
|
||||||
|
downloadState = AttachmentState.COMPLETE
|
||||||
|
downloadProgression = 100
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
attachmentNotification.attachmentFileAction = null
|
||||||
listener?.onUpdate(attachmentNotification)
|
listener?.onUpdate(attachmentNotification)
|
||||||
TimeoutHelper.releaseTemporarilyDisableTimeout()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun cancel() {
|
||||||
|
attachmentNotification.entryAttachmentState.downloadState = AttachmentState.CANCELED
|
||||||
|
}
|
||||||
|
|
||||||
fun downloadFromDatabase(attachmentToUploadUri: Uri,
|
fun downloadFromDatabase(attachmentToUploadUri: Uri,
|
||||||
binaryAttachment: BinaryAttachment,
|
binaryAttachment: BinaryAttachment,
|
||||||
contentResolver: ContentResolver,
|
contentResolver: ContentResolver,
|
||||||
@@ -396,13 +425,14 @@ class AttachmentFileNotificationService: LockNotificationService() {
|
|||||||
binaryAttachment: BinaryAttachment,
|
binaryAttachment: BinaryAttachment,
|
||||||
contentResolver: ContentResolver,
|
contentResolver: ContentResolver,
|
||||||
bufferSize: Int = DEFAULT_BUFFER_SIZE,
|
bufferSize: Int = DEFAULT_BUFFER_SIZE,
|
||||||
|
canceled: ()-> Boolean = { false },
|
||||||
update: ((percent: Int)->Unit)? = null) {
|
update: ((percent: Int)->Unit)? = null) {
|
||||||
var dataUploaded = 0L
|
var dataUploaded = 0L
|
||||||
val fileSize = contentResolver.openFileDescriptor(attachmentFromDownloadUri, "r")?.statSize ?: 0
|
val fileSize = contentResolver.openFileDescriptor(attachmentFromDownloadUri, "r")?.statSize ?: 0
|
||||||
UriUtil.getUriInputStream(contentResolver, attachmentFromDownloadUri)?.use { inputStream ->
|
UriUtil.getUriInputStream(contentResolver, attachmentFromDownloadUri)?.use { inputStream ->
|
||||||
Database.getInstance().loadedCipherKey?.let { binaryCipherKey ->
|
Database.getInstance().loadedCipherKey?.let { binaryCipherKey ->
|
||||||
binaryAttachment.getGzipOutputDataStream(binaryCipherKey).use { outputStream ->
|
binaryAttachment.getGzipOutputDataStream(binaryCipherKey).use { outputStream ->
|
||||||
inputStream.readAllBytes(bufferSize) { buffer ->
|
inputStream.readAllBytes(bufferSize, canceled) { buffer ->
|
||||||
outputStream.write(buffer)
|
outputStream.write(buffer)
|
||||||
dataUploaded += buffer.size
|
dataUploaded += buffer.size
|
||||||
try {
|
try {
|
||||||
@@ -422,7 +452,9 @@ class AttachmentFileNotificationService: LockNotificationService() {
|
|||||||
val currentTime = System.currentTimeMillis()
|
val currentTime = System.currentTimeMillis()
|
||||||
if (previousSaveTime + updateMinFrequency < currentTime) {
|
if (previousSaveTime + updateMinFrequency < currentTime) {
|
||||||
attachmentNotification.entryAttachmentState.apply {
|
attachmentNotification.entryAttachmentState.apply {
|
||||||
downloadState = AttachmentState.IN_PROGRESS
|
if (downloadState != AttachmentState.CANCELED) {
|
||||||
|
downloadState = AttachmentState.IN_PROGRESS
|
||||||
|
}
|
||||||
downloadProgression = percent
|
downloadProgression = percent
|
||||||
}
|
}
|
||||||
CoroutineScope(Dispatchers.Main).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
@@ -444,6 +476,7 @@ class AttachmentFileNotificationService: LockNotificationService() {
|
|||||||
private const val CHANNEL_ATTACHMENT_ID = "com.kunzisoft.keepass.notification.channel.attachment"
|
private const val CHANNEL_ATTACHMENT_ID = "com.kunzisoft.keepass.notification.channel.attachment"
|
||||||
|
|
||||||
const val ACTION_ATTACHMENT_FILE_START_UPLOAD = "ACTION_ATTACHMENT_FILE_START_UPLOAD"
|
const val ACTION_ATTACHMENT_FILE_START_UPLOAD = "ACTION_ATTACHMENT_FILE_START_UPLOAD"
|
||||||
|
const val ACTION_ATTACHMENT_FILE_STOP_UPLOAD = "ACTION_ATTACHMENT_FILE_STOP_UPLOAD"
|
||||||
const val ACTION_ATTACHMENT_FILE_START_DOWNLOAD = "ACTION_ATTACHMENT_FILE_START_DOWNLOAD"
|
const val ACTION_ATTACHMENT_FILE_START_DOWNLOAD = "ACTION_ATTACHMENT_FILE_START_DOWNLOAD"
|
||||||
const val ACTION_ATTACHMENT_REMOVE = "ACTION_ATTACHMENT_REMOVE"
|
const val ACTION_ATTACHMENT_REMOVE = "ACTION_ATTACHMENT_REMOVE"
|
||||||
|
|
||||||
|
|||||||
@@ -31,10 +31,11 @@ import java.util.*
|
|||||||
*/
|
*/
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun InputStream.readAllBytes(bufferSize: Int = DEFAULT_BUFFER_SIZE,
|
fun InputStream.readAllBytes(bufferSize: Int = DEFAULT_BUFFER_SIZE,
|
||||||
|
cancelCondition: ()-> Boolean = { false },
|
||||||
readBytes: (bytesRead: ByteArray) -> Unit) {
|
readBytes: (bytesRead: ByteArray) -> Unit) {
|
||||||
val buffer = ByteArray(bufferSize)
|
val buffer = ByteArray(bufferSize)
|
||||||
var read = 0
|
var read = 0
|
||||||
while (read != -1) {
|
while (read != -1 && !cancelCondition()) {
|
||||||
read = this.read(buffer, 0, buffer.size)
|
read = this.read(buffer, 0, buffer.size)
|
||||||
if (read != -1) {
|
if (read != -1) {
|
||||||
val optimizedBuffer: ByteArray = if (buffer.size == read) {
|
val optimizedBuffer: ByteArray = if (buffer.size == read) {
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import com.kunzisoft.keepass.model.EntryAttachmentState
|
|||||||
import com.kunzisoft.keepass.services.AttachmentFileNotificationService
|
import com.kunzisoft.keepass.services.AttachmentFileNotificationService
|
||||||
import com.kunzisoft.keepass.services.AttachmentFileNotificationService.Companion.ACTION_ATTACHMENT_FILE_START_DOWNLOAD
|
import com.kunzisoft.keepass.services.AttachmentFileNotificationService.Companion.ACTION_ATTACHMENT_FILE_START_DOWNLOAD
|
||||||
import com.kunzisoft.keepass.services.AttachmentFileNotificationService.Companion.ACTION_ATTACHMENT_FILE_START_UPLOAD
|
import com.kunzisoft.keepass.services.AttachmentFileNotificationService.Companion.ACTION_ATTACHMENT_FILE_START_UPLOAD
|
||||||
|
import com.kunzisoft.keepass.services.AttachmentFileNotificationService.Companion.ACTION_ATTACHMENT_FILE_STOP_UPLOAD
|
||||||
import com.kunzisoft.keepass.services.AttachmentFileNotificationService.Companion.ACTION_ATTACHMENT_REMOVE
|
import com.kunzisoft.keepass.services.AttachmentFileNotificationService.Companion.ACTION_ATTACHMENT_REMOVE
|
||||||
|
|
||||||
class AttachmentFileBinderManager(private val activity: FragmentActivity) {
|
class AttachmentFileBinderManager(private val activity: FragmentActivity) {
|
||||||
@@ -120,6 +121,10 @@ class AttachmentFileBinderManager(private val activity: FragmentActivity) {
|
|||||||
}, ACTION_ATTACHMENT_FILE_START_UPLOAD)
|
}, ACTION_ATTACHMENT_FILE_START_UPLOAD)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun stopUploadAllAttachments() {
|
||||||
|
start(null, ACTION_ATTACHMENT_FILE_STOP_UPLOAD)
|
||||||
|
}
|
||||||
|
|
||||||
fun startDownloadAttachment(downloadFileUri: Uri,
|
fun startDownloadAttachment(downloadFileUri: Uri,
|
||||||
attachment: Attachment) {
|
attachment: Attachment) {
|
||||||
start(Bundle().apply {
|
start(Bundle().apply {
|
||||||
|
|||||||
@@ -514,6 +514,7 @@
|
|||||||
<string name="download_progression">In progress: %1$d%%</string>
|
<string name="download_progression">In progress: %1$d%%</string>
|
||||||
<string name="download_finalization">Finalizing…</string>
|
<string name="download_finalization">Finalizing…</string>
|
||||||
<string name="download_complete">Complete!</string>
|
<string name="download_complete">Complete!</string>
|
||||||
|
<string name="download_canceled">Canceled!</string>
|
||||||
<string name="encryption_rijndael">Rijndael (AES)</string>
|
<string name="encryption_rijndael">Rijndael (AES)</string>
|
||||||
<string name="encryption_twofish">Twofish</string>
|
<string name="encryption_twofish">Twofish</string>
|
||||||
<string name="encryption_chacha20">ChaCha20</string>
|
<string name="encryption_chacha20">ChaCha20</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user