From 047666ce689cfa58505a35f24b68c86a7ee1fca0 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Tue, 29 Sep 2026 12:59:00 +0200 Subject: [PATCH 1/2] Rename .java to .kt Signed-off-by: alperozturk96 --- .../ui/adapter/{DiskLruImageCache.java => DiskLruImageCache.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename app/src/main/java/com/owncloud/android/ui/adapter/{DiskLruImageCache.java => DiskLruImageCache.kt} (100%) diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/DiskLruImageCache.java b/app/src/main/java/com/owncloud/android/ui/adapter/DiskLruImageCache.kt similarity index 100% rename from app/src/main/java/com/owncloud/android/ui/adapter/DiskLruImageCache.java rename to app/src/main/java/com/owncloud/android/ui/adapter/DiskLruImageCache.kt From e731292aa85a1925c7b14b9d0b90845d9442965c Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Tue, 29 Sep 2026 12:59:01 +0200 Subject: [PATCH 2/2] refactor(disk-lru-image-cache): kotlin Signed-off-by: alperozturk96 --- .../android/ui/adapter/DiskLruImageCache.kt | 300 ++++++------------ 1 file changed, 96 insertions(+), 204 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/DiskLruImageCache.kt b/app/src/main/java/com/owncloud/android/ui/adapter/DiskLruImageCache.kt index 0900d6704343..6670da978211 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/DiskLruImageCache.kt +++ b/app/src/main/java/com/owncloud/android/ui/adapter/DiskLruImageCache.kt @@ -1,239 +1,131 @@ /* * Nextcloud - Android Client * - * SPDX-FileCopyrightText: 2022 Unpublished - * SPDX-FileCopyrightText: 2014-2017 Tobias Kaminsky - * SPDX-FileCopyrightText: 2017 Nextcloud GmbH - * SPDX-FileCopyrightText: 2016 Iskra Delta - * SPDX-FileCopyrightText: 2015 ownCloud Inc. - * SPDX-FileCopyrightText: 2015 MarĂ­a Asensio Valverde - * SPDX-FileCopyrightText: 2014 David A. Velasco - * SPDX-FileCopyrightText: 2014 Jose Antonio Barros Ramos - * SPDX-License-Identifier: GPL-2.0-only AND (AGPL-3.0-or-later OR GPL-2.0-only) + * SPDX-FileCopyrightText: 2026 Alper Ozturk + * SPDX-License-Identifier: AGPL-3.0-or-later */ -package com.owncloud.android.ui.adapter; - -import android.graphics.Bitmap; -import android.graphics.Bitmap.CompressFormat; -import android.graphics.BitmapFactory; - -import com.jakewharton.disklrucache.DiskLruCache; -import com.owncloud.android.BuildConfig; -import com.owncloud.android.lib.common.utils.Log_OC; -import com.owncloud.android.utils.BitmapUtils; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public class DiskLruImageCache { - - private DiskLruCache mDiskCache; - private CompressFormat mCompressFormat; - private int mCompressQuality; - private static final int CACHE_VERSION = 1; - private static final int VALUE_COUNT = 1; - private static final int IO_BUFFER_SIZE = 8 * 1024; - private static final String CACHE_TEST_DISK = "cache_test_DISK_"; - - private static final String TAG = DiskLruImageCache.class.getSimpleName(); - - public DiskLruImageCache(File diskCacheDir, int diskCacheSize, CompressFormat compressFormat, int quality) - throws IOException { - mDiskCache = DiskLruCache.open(diskCacheDir, CACHE_VERSION, VALUE_COUNT, diskCacheSize); - mCompressFormat = compressFormat; - mCompressQuality = quality; - } - - private boolean writeBitmapToFile(Bitmap bitmap, DiskLruCache.Editor editor) throws IOException { - try (OutputStream out = new BufferedOutputStream(editor.newOutputStream(0), IO_BUFFER_SIZE)) { - return bitmap.compress(mCompressFormat, mCompressQuality, out); - } - } - - public void put(String key, Bitmap data) { - - DiskLruCache.Editor editor = null; - String validKey = convertToValidKey(key); +package com.owncloud.android.ui.adapter + +import android.graphics.Bitmap +import android.graphics.Bitmap.CompressFormat +import android.graphics.BitmapFactory +import com.jakewharton.disklrucache.DiskLruCache +import com.owncloud.android.lib.common.utils.Log_OC +import com.owncloud.android.utils.BitmapUtils +import java.io.BufferedInputStream +import java.io.BufferedOutputStream +import java.io.File +import java.io.IOException +import java.io.InputStream + +class DiskLruImageCache +@Throws(IOException::class) +constructor( + diskCacheDir: File, + diskCacheSize: Int, + private val compressFormat: CompressFormat, + private val compressQuality: Int +) { + private val diskCache: DiskLruCache = + DiskLruCache.open(diskCacheDir, CACHE_VERSION, VALUE_COUNT, diskCacheSize.toLong()) + + fun put(key: String, data: Bitmap) { + var editor: DiskLruCache.Editor? = null try { - editor = mDiskCache.edit(validKey); - if (editor == null) { - return; - } - - if (writeBitmapToFile(data, editor)) { - mDiskCache.flush(); - editor.commit(); - if (BuildConfig.DEBUG) { - Log_OC.d(CACHE_TEST_DISK, "image put on disk cache " + validKey); - } + editor = diskCache.edit(key.toValidKey()) ?: return + if (writeBitmap(data, editor)) { + editor.commit() } else { - editor.abort(); - if (BuildConfig.DEBUG) { - Log_OC.d(CACHE_TEST_DISK, "ERROR on: image put on disk cache " + validKey); - } - } - } catch (IOException e) { - if (BuildConfig.DEBUG) { - Log_OC.d(CACHE_TEST_DISK, "ERROR on: image put on disk cache " + validKey); - } - try { - if (editor != null) { - editor.abort(); - } - } catch (IOException ex) { - Log_OC.d(TAG, "Error aborting editor", ex); + editor.abort() } + } catch (_: IOException) { + editor?.abortQuietly() } } - public Bitmap getScaledBitmap(String key, int width, int height) { - Bitmap bitmap = null; - String validKey = convertToValidKey(key); + @Suppress("TooGenericExceptionCaught") + fun getScaledBitmap(key: String, width: Int, height: Int): Bitmap? = try { + decodeScaled(key.toValidKey(), width, height) + } catch (e: Exception) { + Log_OC.e(TAG, e.message, e) + null + } - try (DiskLruCache.Snapshot snapshot = mDiskCache.get(validKey)) { - if (snapshot == null) { - return null; - } + fun getBitmap(key: String): Bitmap? = try { + readEntry(key.toValidKey()) { BitmapFactory.decodeStream(it) } + } catch (e: IOException) { + Log_OC.e(TAG, e.message, e) + null + } - InputStream inputStream = snapshot.getInputStream(0); - if (inputStream != null) { - // First decode with inJustDecodeBounds=true to check dimensions - final BitmapFactory.Options options = new BitmapFactory.Options(); - try (BufferedInputStream buffIn = new BufferedInputStream(inputStream, IO_BUFFER_SIZE)) { - options.inScaled = true; - options.inPurgeable = true; - options.inPreferQualityOverSpeed = false; - options.inMutable = false; - options.inJustDecodeBounds = true; - - BitmapFactory.decodeStream(buffIn, null, options); - } - - try (DiskLruCache.Snapshot snapshot2 = mDiskCache.get(validKey)) { - inputStream = snapshot2.getInputStream(0); - - try (BufferedInputStream buffIn = new BufferedInputStream(inputStream, IO_BUFFER_SIZE)) { - // Calculate inSampleSize - options.inSampleSize = BitmapUtils.calculateSampleFactor(options, width, height); - - // Decode bitmap with inSampleSize set - options.inJustDecodeBounds = false; - bitmap = BitmapFactory.decodeStream(buffIn, null, options); - } - } - } - } catch (Exception e) { - Log_OC.e(TAG, e.getMessage(), e); - } + fun containsKey(key: String): Boolean = try { + diskCache.get(key.toValidKey())?.use { true } == true + } catch (e: IOException) { + Log_OC.d(TAG, e.message, e) + false + } - if (BuildConfig.DEBUG) { - Log_OC.d(CACHE_TEST_DISK, bitmap == null ? "not found" : "image read from disk " + validKey); + fun clearCache() { + try { + diskCache.delete() + } catch (e: IOException) { + Log_OC.d(TAG, e.message, e) } - - return bitmap; } - public Bitmap getBitmap(String key) { - Bitmap bitmap = null; - DiskLruCache.Snapshot snapshot = null; - InputStream in = null; - BufferedInputStream buffIn = null; - String validKey = convertToValidKey(key); - + fun removeKey(key: String) { + val validKey = key.toValidKey() try { - snapshot = mDiskCache.get(validKey); - if (snapshot == null) { - return null; - } - in = snapshot.getInputStream(0); - if (in != null) { - buffIn = new BufferedInputStream(in, IO_BUFFER_SIZE); - bitmap = BitmapFactory.decodeStream(buffIn); - } - } catch (IOException e) { - Log_OC.e(TAG, e.getMessage(), e); - } finally { - if (snapshot != null) { - snapshot.close(); - } - if (buffIn != null) { - try { - buffIn.close(); - } catch (IOException e) { - Log_OC.e(TAG, e.getMessage(), e); - } - } - if (in != null) { - try { - in.close(); - } catch (IOException e) { - Log_OC.e(TAG, e.getMessage(), e); - } - } + diskCache.remove(validKey) + Log_OC.d(TAG, "removeKey from cache: $validKey") + } catch (e: IOException) { + Log_OC.d(TAG, e.message, e) } + } - if (BuildConfig.DEBUG) { - Log_OC.d(CACHE_TEST_DISK, bitmap == null ? "not found" : "image read from disk " + validKey); + @Throws(IOException::class) + private fun writeBitmap(bitmap: Bitmap, editor: DiskLruCache.Editor): Boolean = + BufferedOutputStream(editor.newOutputStream(VALUE_INDEX), IO_BUFFER_SIZE).use { + bitmap.compress(compressFormat, compressQuality, it) } - return bitmap; + @Throws(IOException::class) + private fun decodeScaled(validKey: String, width: Int, height: Int): Bitmap? { + val options = readBounds(validKey) ?: return null + options.inSampleSize = BitmapUtils.calculateSampleFactor(options, width, height) + options.inJustDecodeBounds = false + return readEntry(validKey) { BitmapFactory.decodeStream(it, null, options) } } - public boolean containsKey(String key) { - - boolean contained = false; - DiskLruCache.Snapshot snapshot = null; - String validKey = convertToValidKey(key); - try { - snapshot = mDiskCache.get(validKey); - contained = snapshot != null; - } catch (IOException e) { - Log_OC.d(TAG, e.getMessage(), e); - } finally { - if (snapshot != null) { - snapshot.close(); - } + @Throws(IOException::class) + private fun readBounds(validKey: String): BitmapFactory.Options? = readEntry(validKey) { stream -> + BitmapFactory.Options().apply { + inJustDecodeBounds = true + BitmapFactory.decodeStream(stream, null, this) } + } - return contained; - + @Throws(IOException::class) + private fun readEntry(validKey: String, read: (InputStream) -> T): T? = diskCache.get(validKey)?.use { + BufferedInputStream(it.getInputStream(VALUE_INDEX), IO_BUFFER_SIZE).use(read) } - public void clearCache() { - if (BuildConfig.DEBUG) { - Log_OC.d(CACHE_TEST_DISK, "disk cache CLEARED"); - } + private fun DiskLruCache.Editor.abortQuietly() { try { - mDiskCache.delete(); - } catch (IOException e) { - Log_OC.d(TAG, e.getMessage(), e); + abort() + } catch (e: IOException) { + Log_OC.d(TAG, "Error aborting editor", e) } } - public File getCacheFolder() { - return mDiskCache.getDirectory(); - } + private fun String.toValidKey(): String = hashCode().toString() - private String convertToValidKey(String key) { - return Integer.toString(key.hashCode()); - } + companion object { + private const val CACHE_VERSION = 1 + private const val VALUE_COUNT = 1 + private const val VALUE_INDEX = 0 + private const val IO_BUFFER_SIZE = 8 * 1024 - /** - * Remove passed key from cache - * - * @param key - */ - public void removeKey(String key) { - String validKey = convertToValidKey(key); - try { - mDiskCache.remove(validKey); - Log_OC.d(TAG, "removeKey from cache: " + validKey); - } catch (IOException e) { - Log_OC.d(TAG, e.getMessage(), e); - } + private val TAG = DiskLruImageCache::class.java.simpleName } }