From 8924d36925eb2cac7e9caa4cdb833124d20326d2 Mon Sep 17 00:00:00 2001 From: tarsin Date: Wed, 22 Mar 2023 17:48:10 +0800 Subject: [PATCH] Tidy native function namespace --- app/src/main/cpp/archive.c | 22 +++--- app/src/main/cpp/gifutils.c | 4 +- app/src/main/java/com/hippo/Native.kt | 35 ---------- .../main/java/com/hippo/UriArchiveAccessor.kt | 70 ------------------- app/src/main/java/com/hippo/ehviewer/EhDB.kt | 2 +- .../ehviewer/gallery/ArchivePageLoader.kt | 68 ++++++++++++------ .../com/hippo/ehviewer/spider/SpiderDen.kt | 6 +- app/src/main/java/com/hippo/image/Image.kt | 9 +-- app/src/main/java/com/hippo/util/FDUtils.kt | 18 +++++ .../tachiyomi/ui/reader/ReaderActivity.kt | 2 +- 10 files changed, 90 insertions(+), 146 deletions(-) delete mode 100644 app/src/main/java/com/hippo/Native.kt delete mode 100644 app/src/main/java/com/hippo/UriArchiveAccessor.kt create mode 100644 app/src/main/java/com/hippo/util/FDUtils.kt diff --git a/app/src/main/cpp/archive.c b/app/src/main/cpp/archive.c index a1fa6f026..b9072a878 100644 --- a/app/src/main/cpp/archive.c +++ b/app/src/main/cpp/archive.c @@ -279,7 +279,8 @@ static int archive_get_ctx(archive_ctx **ctxptr, int idx) { } JNIEXPORT jint JNICALL -Java_com_hippo_UriArchiveAccessor_openArchive(JNIEnv *env, jobject thiz, jint fd, jlong size) { +Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_openArchive(JNIEnv *env, jclass thiz, jint fd, + jlong size) { EH_UNUSED(env); EH_UNUSED(thiz); archive_ctx *ctx = NULL; @@ -359,7 +360,8 @@ Java_com_hippo_UriArchiveAccessor_openArchive(JNIEnv *env, jobject thiz, jint fd #pragma ide diagnostic ignored "UnreachableCode" JNIEXPORT jobject JNICALL -Java_com_hippo_UriArchiveAccessor_extractToByteBuffer(JNIEnv *env, jobject thiz, jint index) { +Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_extractToByteBuffer(JNIEnv *env, jclass thiz, + jint index) { EH_UNUSED(env); EH_UNUSED(thiz); void *addr = MEMPOOL_ADDR_BY_SORTED_IDX(index); @@ -388,7 +390,7 @@ Java_com_hippo_UriArchiveAccessor_extractToByteBuffer(JNIEnv *env, jobject thiz, #pragma clang diagnostic pop JNIEXPORT void JNICALL -Java_com_hippo_UriArchiveAccessor_closeArchive(JNIEnv *env, jobject thiz) { +Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_closeArchive(JNIEnv *env, jclass thiz) { EH_UNUSED(env); EH_UNUSED(thiz); for (int i = 0; i < CTX_POOL_SIZE; i++) @@ -408,14 +410,15 @@ Java_com_hippo_UriArchiveAccessor_closeArchive(JNIEnv *env, jobject thiz) { } JNIEXPORT jboolean JNICALL -Java_com_hippo_UriArchiveAccessor_needPassword(JNIEnv *env, jobject thiz) { +Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_needPassword(JNIEnv *env, jclass thiz) { EH_UNUSED(env); EH_UNUSED(thiz); return need_encrypt; } JNIEXPORT jboolean JNICALL -Java_com_hippo_UriArchiveAccessor_providePassword(JNIEnv *env, jobject thiz, jstring str) { +Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_providePassword(JNIEnv *env, jclass thiz, + jstring str) { EH_UNUSED(thiz); struct archive_entry *entry; archive_ctx *ctx; @@ -445,7 +448,8 @@ Java_com_hippo_UriArchiveAccessor_providePassword(JNIEnv *env, jobject thiz, jst } JNIEXPORT jstring JNICALL -Java_com_hippo_UriArchiveAccessor_getFilename(JNIEnv *env, jobject thiz, jint index) { +Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_getFilename(JNIEnv *env, jclass thiz, + jint index) { EH_UNUSED(env); EH_UNUSED(thiz); index = entries[index].index; @@ -460,7 +464,8 @@ Java_com_hippo_UriArchiveAccessor_getFilename(JNIEnv *env, jobject thiz, jint in } JNIEXPORT void JNICALL -Java_com_hippo_UriArchiveAccessor_extractToFd(JNIEnv *env, jobject thiz, jint index, jint fd) { +Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_extractToFd(JNIEnv *env, jclass thiz, + jint index, jint fd) { EH_UNUSED(env); EH_UNUSED(thiz); index = entries[index].index; @@ -474,7 +479,8 @@ Java_com_hippo_UriArchiveAccessor_extractToFd(JNIEnv *env, jobject thiz, jint in } JNIEXPORT void JNICALL -Java_com_hippo_UriArchiveAccessor_releaseByteBuffer(JNIEnv *env, jobject thiz, jobject buffer) { +Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_releaseByteBuffer(JNIEnv *env, jclass thiz, + jobject buffer) { EH_UNUSED(thiz); void *addr = (*env)->GetDirectBufferAddress(env, buffer); size_t size = (*env)->GetDirectBufferCapacity(env, buffer); diff --git a/app/src/main/cpp/gifutils.c b/app/src/main/cpp/gifutils.c index 37e194b62..cf8177497 100644 --- a/app/src/main/cpp/gifutils.c +++ b/app/src/main/cpp/gifutils.c @@ -43,14 +43,14 @@ static void doRewrite(byte *addr, size_t size) { } JNIEXPORT void JNICALL -Java_com_hippo_image_Image_rewriteGifSource(JNIEnv *env, jclass clazz, jobject buffer) { +Java_com_hippo_image_ImageKt_rewriteGifSource(JNIEnv *env, jclass clazz, jobject buffer) { byte *addr = (*env)->GetDirectBufferAddress(env, buffer); size_t size = (*env)->GetDirectBufferCapacity(env, buffer); doRewrite(addr, size); } JNIEXPORT void JNICALL -Java_com_hippo_image_Image_rewriteGifSource2(JNIEnv *env, jclass clazz, jint fd) { +Java_com_hippo_image_ImageKt_rewriteGifSource2(JNIEnv *env, jclass clazz, jint fd) { struct stat64 st; fstat64(fd, &st); size_t size = st.st_size; diff --git a/app/src/main/java/com/hippo/Native.kt b/app/src/main/java/com/hippo/Native.kt deleted file mode 100644 index 3385a3679..000000000 --- a/app/src/main/java/com/hippo/Native.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2022 Tarsin Norbin - * - * This file is part of EhViewer - * - * EhViewer is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * EhViewer is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with EhViewer. - * If not, see . - */ -package com.hippo - -import android.os.ParcelFileDescriptor -import android.system.Int64Ref -import android.system.Os -import java.io.FileDescriptor - -private fun sendFileTotally(from: FileDescriptor, to: FileDescriptor) { - Os.sendfile(to, from, Int64Ref(0), Long.MAX_VALUE) -} - -infix fun ParcelFileDescriptor.sendTo(fd: FileDescriptor) { - sendFileTotally(fileDescriptor, fd) -} - -infix fun ParcelFileDescriptor.sendTo(fd: ParcelFileDescriptor) { - sendFileTotally(fileDescriptor, fd.fileDescriptor) -} diff --git a/app/src/main/java/com/hippo/UriArchiveAccessor.kt b/app/src/main/java/com/hippo/UriArchiveAccessor.kt deleted file mode 100644 index 3aa0edc99..000000000 --- a/app/src/main/java/com/hippo/UriArchiveAccessor.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2022 Tarsin Norbin - * - * This file is part of EhViewer - * - * EhViewer is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * EhViewer is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with EhViewer. - * If not, see . - */ -package com.hippo - -import android.content.Context -import android.graphics.ImageDecoder -import android.net.Uri -import android.util.Log -import com.hippo.image.Image -import java.io.FileDescriptor -import java.nio.ByteBuffer - -class UriArchiveAccessor(ctx: Context, private val uri: Uri) { - val pfd by lazy { ctx.contentResolver.openFileDescriptor(uri, "r")!! } - fun open(): Int { - Log.d(DEBUG_TAG, "Open archive $uri") - return openArchive(pfd.fd, pfd.statSize) - } - - private external fun openArchive(fd: Int, size: Long): Int - private external fun extractToByteBuffer(index: Int): ByteBuffer? - external fun extractToFd(index: Int, fd: Int) - external fun getFilename(index: Int): String - external fun needPassword(): Boolean - external fun providePassword(str: String): Boolean - private external fun closeArchive() - fun close() { - closeArchive() - pfd.close() - Log.d(DEBUG_TAG, "Close archive $uri successfully!") - } - - fun getImageSource(index: Int): Image.CloseableSource? { - val buffer = extractToByteBuffer(index) - buffer ?: return null - check(buffer.isDirect) - Image.rewriteGifSource(buffer) - val source = ImageDecoder.createSource(buffer) - return object : Image.CloseableSource { - override val source: ImageDecoder.Source - get() = source - - override fun close() { - releaseByteBuffer(buffer) - } - } - } - - companion object { - @JvmStatic - private external fun releaseByteBuffer(buffer: ByteBuffer) - } -} - -private const val DEBUG_TAG = "UriArchiveAccessor" diff --git a/app/src/main/java/com/hippo/ehviewer/EhDB.kt b/app/src/main/java/com/hippo/ehviewer/EhDB.kt index 7dcc3d8b5..2eafda973 100644 --- a/app/src/main/java/com/hippo/ehviewer/EhDB.kt +++ b/app/src/main/java/com/hippo/ehviewer/EhDB.kt @@ -33,7 +33,7 @@ import com.hippo.ehviewer.dao.HistoryInfo import com.hippo.ehviewer.dao.LocalFavoriteInfo import com.hippo.ehviewer.dao.QuickSearch import com.hippo.ehviewer.download.DownloadManager -import com.hippo.sendTo +import com.hippo.util.sendTo object EhDB { private const val CUR_DB_VER = 4 diff --git a/app/src/main/java/com/hippo/ehviewer/gallery/ArchivePageLoader.kt b/app/src/main/java/com/hippo/ehviewer/gallery/ArchivePageLoader.kt index 6ad4f4ef4..6aad70c0c 100644 --- a/app/src/main/java/com/hippo/ehviewer/gallery/ArchivePageLoader.kt +++ b/app/src/main/java/com/hippo/ehviewer/gallery/ArchivePageLoader.kt @@ -16,10 +16,13 @@ package com.hippo.ehviewer.gallery import android.content.Context +import android.graphics.ImageDecoder import android.net.Uri -import com.hippo.UriArchiveAccessor +import android.os.ParcelFileDescriptor +import android.util.Log import com.hippo.ehviewer.Settings import com.hippo.image.Image +import com.hippo.image.rewriteGifSource import com.hippo.unifile.UniFile import com.hippo.yorozuya.FileUtils import kotlinx.coroutines.CoroutineScope @@ -35,26 +38,26 @@ import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Semaphore import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withPermit +import java.nio.ByteBuffer -class ArchivePageLoader(context: Context, uri: Uri, passwdFlow: Flow) : PageLoader2(), - CoroutineScope { +class ArchivePageLoader(context: Context, private val uri: Uri, passwdFlow: Flow) : PageLoader2(), CoroutineScope { override val coroutineContext = Dispatchers.IO + Job() - private val archiveAccessor by lazy { UriArchiveAccessor(context, uri) } + private lateinit var pfd: ParcelFileDescriptor private val hostJob = launch(start = CoroutineStart.LAZY) { - size = archiveAccessor.open() + Log.d(DEBUG_TAG, "Open archive $uri") + pfd = context.contentResolver.openFileDescriptor(uri, "r")!! + size = openArchive(pfd.fd, pfd.statSize) if (size == 0) { return@launch } - archiveAccessor.run { - if (needPassword()) { - Settings.archivePasswds?.forEach { - if (providePassword(it)) return@launch - } - passwdFlow.collect { - if (providePassword(it)) { - Settings.putPasswdToArchivePasswds(it) - currentCoroutineContext().cancel() - } + if (needPassword()) { + Settings.archivePasswds?.forEach { + if (providePassword(it)) return@launch + } + passwdFlow.collect { + if (providePassword(it)) { + Settings.putPasswdToArchivePasswds(it) + currentCoroutineContext().cancel() } } } @@ -69,7 +72,9 @@ class ArchivePageLoader(context: Context, uri: Uri, passwdFlow: Flow) : override fun stop() { cancel() - archiveAccessor.close() + closeArchive() + pfd.close() + Log.d(DEBUG_TAG, "Close archive $uri successfully!") super.stop() } @@ -93,7 +98,19 @@ class ArchivePageLoader(context: Context, uri: Uri, passwdFlow: Flow) : } private suspend fun doRealWork(index: Int) { - val src = archiveAccessor.getImageSource(index) ?: return + val buffer = extractToByteBuffer(index) + buffer ?: return + check(buffer.isDirect) + rewriteGifSource(buffer) + val source = ImageDecoder.createSource(buffer) + val src = object : Image.CloseableSource { + override val source: ImageDecoder.Source + get() = source + + override fun close() { + releaseByteBuffer(buffer) + } + } runCatching { currentCoroutineContext().ensureActive() }.onFailure { @@ -131,13 +148,13 @@ class ArchivePageLoader(context: Context, uri: Uri, passwdFlow: Flow) : } override fun getImageFilenameWithExtension(index: Int): String { - return FileUtils.sanitizeFilename(archiveAccessor.getFilename(index)) + return FileUtils.sanitizeFilename(getFilename(index)) } override fun save(index: Int, file: UniFile): Boolean { runCatching { file.openFileDescriptor("w").use { - archiveAccessor.extractToFd(index, it.fd) + extractToFd(index, it.fd) } }.onFailure { it.printStackTrace() @@ -154,4 +171,15 @@ class ArchivePageLoader(context: Context, uri: Uri, passwdFlow: Flow) : } override fun preloadPages(pages: List, pair: Pair) {} -} \ No newline at end of file +} + +private const val DEBUG_TAG = "ArchivePageLoader" + +private external fun releaseByteBuffer(buffer: ByteBuffer) +private external fun openArchive(fd: Int, size: Long): Int +private external fun extractToByteBuffer(index: Int): ByteBuffer? +private external fun extractToFd(index: Int, fd: Int) +private external fun getFilename(index: Int): String +private external fun needPassword(): Boolean +private external fun providePassword(str: String): Boolean +private external fun closeArchive() diff --git a/app/src/main/java/com/hippo/ehviewer/spider/SpiderDen.kt b/app/src/main/java/com/hippo/ehviewer/spider/SpiderDen.kt index fb498ed74..d067b3389 100644 --- a/app/src/main/java/com/hippo/ehviewer/spider/SpiderDen.kt +++ b/app/src/main/java/com/hippo/ehviewer/spider/SpiderDen.kt @@ -28,9 +28,9 @@ import com.hippo.ehviewer.client.referer import com.hippo.ehviewer.coil.edit import com.hippo.ehviewer.coil.read import com.hippo.ehviewer.gallery.SUPPORT_IMAGE_EXTENSIONS -import com.hippo.image.Image import com.hippo.image.Image.CloseableSource -import com.hippo.sendTo +import com.hippo.image.rewriteGifSource2 +import com.hippo.util.sendTo import com.hippo.unifile.UniFile import com.hippo.unifile.openOutputStream import com.hippo.yorozuya.FileUtils @@ -163,7 +163,7 @@ class SpiderDen(private val mGalleryInfo: GalleryInfo) { } if (contentType == ContentType.Image.GIF) outFile.openFileDescriptor("rw").use { - Image.rewriteGifSource2(it.fd) + rewriteGifSource2(it.fd) } return ret } diff --git a/app/src/main/java/com/hippo/image/Image.kt b/app/src/main/java/com/hippo/image/Image.kt index e9d8c967a..3e5a93da9 100644 --- a/app/src/main/java/com/hippo/image/Image.kt +++ b/app/src/main/java/com/hippo/image/Image.kt @@ -95,15 +95,12 @@ class Image private constructor(private val src: CloseableSource) { it.printStackTrace() }.getOrNull() } - - @JvmStatic - external fun rewriteGifSource(buffer: ByteBuffer) - - @JvmStatic - external fun rewriteGifSource2(fd: Int) } interface CloseableSource : AutoCloseable { val source: Source } } + +external fun rewriteGifSource(buffer: ByteBuffer) +external fun rewriteGifSource2(fd: Int) diff --git a/app/src/main/java/com/hippo/util/FDUtils.kt b/app/src/main/java/com/hippo/util/FDUtils.kt new file mode 100644 index 000000000..690f90e8a --- /dev/null +++ b/app/src/main/java/com/hippo/util/FDUtils.kt @@ -0,0 +1,18 @@ +package com.hippo.util + +import android.os.ParcelFileDescriptor +import android.system.Int64Ref +import android.system.Os +import java.io.FileDescriptor + +private fun sendFileTotally(from: FileDescriptor, to: FileDescriptor) { + Os.sendfile(to, from, Int64Ref(0), Long.MAX_VALUE) +} + +infix fun ParcelFileDescriptor.sendTo(fd: FileDescriptor) { + sendFileTotally(fileDescriptor, fd) +} + +infix fun ParcelFileDescriptor.sendTo(fd: ParcelFileDescriptor) { + sendFileTotally(fileDescriptor, fd.fileDescriptor) +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index 41e4c477c..d9ddbbc00 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -73,7 +73,7 @@ import com.hippo.ehviewer.gallery.EhPageLoader import com.hippo.ehviewer.gallery.PageLoader2 import com.hippo.ehviewer.ui.EhActivity import com.hippo.image.Image -import com.hippo.sendTo +import com.hippo.util.sendTo import com.hippo.unifile.UniFile import com.hippo.util.ExceptionUtils import com.hippo.util.getParcelableCompat