From 5a1951b495ae9ae05d1fd84032dffef1962525ee Mon Sep 17 00:00:00 2001 From: Nicholas Wallace Date: Thu, 6 Feb 2025 18:26:13 -0700 Subject: [PATCH] InternalDownloadManager autoformatting and comments --- .../app/managers/InternalDownloadManager.kt | 109 ++++++++++++------ 1 file changed, 76 insertions(+), 33 deletions(-) diff --git a/android/app/src/main/java/com/audiobookshelf/app/managers/InternalDownloadManager.kt b/android/app/src/main/java/com/audiobookshelf/app/managers/InternalDownloadManager.kt index a9282666..cf742a7a 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/managers/InternalDownloadManager.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/managers/InternalDownloadManager.kt @@ -1,60 +1,98 @@ package com.audiobookshelf.app.managers import android.util.Log -import com.google.common.net.HttpHeaders.CONTENT_LENGTH -import okhttp3.* import java.io.* -import java.util.* +import java.util.concurrent.TimeUnit +import okhttp3.* + +/** + * Manages the internal download process. + * + * @property outputStream The output stream to write the downloaded data. + * @property progressCallback The callback to report download progress. + */ +class InternalDownloadManager( + private val outputStream: FileOutputStream, + private val progressCallback: DownloadItemManager.InternalProgressCallback +) : AutoCloseable { -class InternalDownloadManager(outputStream:FileOutputStream, private val progressCallback: DownloadItemManager.InternalProgressCallback) : AutoCloseable { private val tag = "InternalDownloadManager" - - private val client: OkHttpClient = OkHttpClient() + private val client: OkHttpClient = + OkHttpClient.Builder() + .connectTimeout(30, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .build() private val writer = BinaryFileWriter(outputStream, progressCallback) + /** + * Downloads a file from the given URL. + * + * @param url The URL to download the file from. + * @throws IOException If an I/O error occurs. + */ @Throws(IOException::class) - fun download(url:String) { + fun download(url: String) { val request: Request = Request.Builder().url(url).build() - client.newCall(request).enqueue(object : Callback { - override fun onFailure(call: Call, e: IOException) { - Log.e(tag, "download URL $url FAILED") - progressCallback.onComplete(true) - } + client.newCall(request) + .enqueue( + object : Callback { + override fun onFailure(call: Call, e: IOException) { + Log.e(tag, "Download URL $url FAILED", e) + progressCallback.onComplete(true) + } - override fun onResponse(call: Call, response: Response) { - val responseBody: ResponseBody = response.body - ?: throw IllegalStateException("Response doesn't contain a file") - - val length: Long = (response.header(CONTENT_LENGTH, "1") ?: "0").toLong() - writer.write(responseBody.byteStream(), length) - } - }) + override fun onResponse(call: Call, response: Response) { + response.body?.let { responseBody -> + val length: Long = response.header("Content-Length")?.toLongOrNull() ?: 0L + writer.write(responseBody.byteStream(), length) + } + ?: run { + Log.e(tag, "Response doesn't contain a file") + progressCallback.onComplete(true) + } + } + } + ) } + /** + * Closes the download manager and releases resources. + * + * @throws Exception If an error occurs during closing. + */ @Throws(Exception::class) override fun close() { writer.close() } } -class BinaryFileWriter(outputStream: OutputStream, progressCallback: DownloadItemManager.InternalProgressCallback) : - AutoCloseable { - private val outputStream: OutputStream - private val progressCallback: DownloadItemManager.InternalProgressCallback - - init { - this.outputStream = outputStream - this.progressCallback = progressCallback - } +/** + * Writes binary data to an output stream. + * + * @property outputStream The output stream to write the data to. + * @property progressCallback The callback to report write progress. + */ +class BinaryFileWriter( + private val outputStream: OutputStream, + private val progressCallback: DownloadItemManager.InternalProgressCallback +) : AutoCloseable { + /** + * Writes data from the input stream to the output stream. + * + * @param inputStream The input stream to read the data from. + * @param length The total length of the data to be written. + * @return The total number of bytes written. + * @throws IOException If an I/O error occurs. + */ @Throws(IOException::class) - fun write(inputStream: InputStream?, length: Long): Long { + fun write(inputStream: InputStream, length: Long): Long { BufferedInputStream(inputStream).use { input -> val dataBuffer = ByteArray(CHUNK_SIZE) - var readBytes: Int var totalBytes: Long = 0 + var readBytes: Int while (input.read(dataBuffer).also { readBytes = it } != -1) { - totalBytes += readBytes.toLong() + totalBytes += readBytes outputStream.write(dataBuffer, 0, readBytes) progressCallback.onProgress(totalBytes, (totalBytes * 100L) / length) } @@ -63,12 +101,17 @@ class BinaryFileWriter(outputStream: OutputStream, progressCallback: DownloadIte } } + /** + * Closes the writer and releases resources. + * + * @throws IOException If an error occurs during closing. + */ @Throws(IOException::class) override fun close() { outputStream.close() } companion object { - private const val CHUNK_SIZE = 1024 + private const val CHUNK_SIZE = 8192 // Increased chunk size for better performance } }