Skip to content
This repository was archived by the owner on Mar 19, 2024. It is now read-only.

Commit ba37bce

Browse files
committed
Add transfer listeners to content uri worker
1 parent dc7022c commit ba37bce

File tree

1 file changed

+62
-8
lines changed

1 file changed

+62
-8
lines changed

owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/network/ContentUriRequestBody.kt

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,33 +31,87 @@ import okhttp3.MediaType
3131
import okhttp3.MediaType.Companion.toMediaTypeOrNull
3232
import okhttp3.RequestBody
3333
import okio.BufferedSink
34+
import okio.Source
3435
import okio.source
36+
import timber.log.Timber
3537
import java.io.IOException
3638

3739
class ContentUriRequestBody(
3840
private val contentResolver: ContentResolver,
3941
private val contentUri: Uri
40-
) : RequestBody() {
42+
) : RequestBody(), ProgressiveDataTransferer {
43+
44+
private val dataTransferListeners: MutableSet<OnDatatransferProgressListener> = HashSet()
45+
46+
val fileSize: Long = contentResolver.query(contentUri, null, null, null, null)?.use { cursor ->
47+
val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE)
48+
cursor.moveToFirst()
49+
cursor.getLong(sizeIndex)
50+
} ?: -1
4151

4252
override fun contentType(): MediaType? {
4353
val contentType = contentResolver.getType(contentUri) ?: return null
4454
return contentType.toMediaTypeOrNull()
4555
}
4656

4757
override fun contentLength(): Long {
48-
contentResolver.query(contentUri, null, null, null, null)?.use { cursor ->
49-
val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE)
50-
cursor.moveToFirst()
51-
return cursor.getLong(sizeIndex)
52-
} ?: return -1
58+
return fileSize
5359
}
5460

5561
override fun writeTo(sink: BufferedSink) {
5662
val inputStream = contentResolver.openInputStream(contentUri)
5763
?: throw IOException("Couldn't open content URI for reading: $contentUri")
5864

59-
inputStream.source().use { source ->
60-
sink.writeAll(source)
65+
val previousTime = System.currentTimeMillis()
66+
67+
sink.writeAndUpdateProgress(inputStream.source())
68+
inputStream.source().close()
69+
70+
val laterTime = System.currentTimeMillis()
71+
72+
Timber.d("Difference - ${laterTime - previousTime} milliseconds")
73+
}
74+
75+
private fun BufferedSink.writeAndUpdateProgress(source: Source) {
76+
var iterator: Iterator<OnDatatransferProgressListener>
77+
78+
try {
79+
var totalBytesRead = 0L
80+
var read: Long
81+
while (source.read(this.buffer, BYTES_TO_READ).also { read = it } != -1L) {
82+
totalBytesRead += read
83+
this.flush()
84+
synchronized(dataTransferListeners) {
85+
iterator = dataTransferListeners.iterator()
86+
while (iterator.hasNext()) {
87+
iterator.next().onTransferProgress(read, totalBytesRead, fileSize, contentUri.toString())
88+
}
89+
}
90+
}
91+
} catch (e: Exception) {
92+
Timber.e(e)
6193
}
6294
}
95+
96+
override fun addDatatransferProgressListener(listener: OnDatatransferProgressListener) {
97+
synchronized(dataTransferListeners) {
98+
dataTransferListeners.add(listener)
99+
}
100+
}
101+
102+
override fun addDatatransferProgressListeners(listeners: MutableCollection<OnDatatransferProgressListener>) {
103+
synchronized(dataTransferListeners) {
104+
dataTransferListeners.addAll(listeners)
105+
}
106+
}
107+
108+
override fun removeDatatransferProgressListener(listener: OnDatatransferProgressListener) {
109+
synchronized(dataTransferListeners) {
110+
dataTransferListeners.remove(listener)
111+
}
112+
}
113+
114+
companion object {
115+
private const val BYTES_TO_READ = 4_096L
116+
}
63117
}

0 commit comments

Comments
 (0)