From 6765505ff07b5607eb2bd13cfae547f0273131c7 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 28 Jun 2023 17:32:18 +0200 Subject: [PATCH] Fixed ANR when opening a PDF inside linphone (VFS enabled for example) --- .../main/files/fragments/PdfViewerFragment.kt | 8 ++- .../main/files/viewmodels/PdfFileViewModel.kt | 71 +++++++++++++------ .../files/viewmodels/TextFileViewModel.kt | 9 +-- 3 files changed, 56 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/main/files/fragments/PdfViewerFragment.kt b/app/src/main/java/org/linphone/activities/main/files/fragments/PdfViewerFragment.kt index 799543fc4..2e123d104 100644 --- a/app/src/main/java/org/linphone/activities/main/files/fragments/PdfViewerFragment.kt +++ b/app/src/main/java/org/linphone/activities/main/files/fragments/PdfViewerFragment.kt @@ -54,7 +54,11 @@ class PdfViewerFragment : GenericViewerFragment() )[PdfFileViewModel::class.java] binding.viewModel = viewModel - adapter = PdfPagesListAdapter(viewModel) - binding.pdfViewPager.adapter = adapter + viewModel.rendererReady.observe(viewLifecycleOwner) { + it.consume { + adapter = PdfPagesListAdapter(viewModel) + binding.pdfViewPager.adapter = adapter + } + } } } diff --git a/app/src/main/java/org/linphone/activities/main/files/viewmodels/PdfFileViewModel.kt b/app/src/main/java/org/linphone/activities/main/files/viewmodels/PdfFileViewModel.kt index 34df29d60..259957fac 100644 --- a/app/src/main/java/org/linphone/activities/main/files/viewmodels/PdfFileViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/files/viewmodels/PdfFileViewModel.kt @@ -26,10 +26,15 @@ import android.widget.ImageView import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.viewModelScope import java.io.File +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.core.Content import org.linphone.core.tools.Log +import org.linphone.utils.Event class PdfFileViewModelFactory(private val content: Content) : ViewModelProvider.NewInstanceFactory() { @@ -43,45 +48,67 @@ class PdfFileViewModelFactory(private val content: Content) : class PdfFileViewModel(content: Content) : FileViewerViewModel(content) { val operationInProgress = MutableLiveData() - private val pdfRenderer: PdfRenderer + val rendererReady = MutableLiveData>() + + private lateinit var pdfRenderer: PdfRenderer init { operationInProgress.value = false - val input = ParcelFileDescriptor.open(File(filePath), ParcelFileDescriptor.MODE_READ_ONLY) - pdfRenderer = PdfRenderer(input) - Log.i("[PDF Viewer] ${pdfRenderer.pageCount} pages in file $filePath") + viewModelScope.launch { + withContext(Dispatchers.IO) { + val input = ParcelFileDescriptor.open( + File(filePath), + ParcelFileDescriptor.MODE_READ_ONLY + ) + pdfRenderer = PdfRenderer(input) + Log.i("[PDF Viewer] ${pdfRenderer.pageCount} pages in file $filePath") + rendererReady.postValue(Event(true)) + } + } } override fun onCleared() { - pdfRenderer.close() + if (this::pdfRenderer.isInitialized) { + pdfRenderer.close() + } super.onCleared() } fun getPagesCount(): Int { - return pdfRenderer.pageCount + if (this::pdfRenderer.isInitialized) { + return pdfRenderer.pageCount + } + return 0 } fun loadPdfPageInto(index: Int, view: ImageView) { - try { - operationInProgress.value = true + viewModelScope.launch { + withContext(Dispatchers.IO) { + try { + operationInProgress.postValue(true) - val page: PdfRenderer.Page = pdfRenderer.openPage(index) - val width = if (coreContext.screenWidth <= coreContext.screenHeight) coreContext.screenWidth else coreContext.screenHeight - val bm = Bitmap.createBitmap( - width.toInt(), - (width / page.width * page.height).toInt(), - Bitmap.Config.ARGB_8888 - ) - page.render(bm, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY) - page.close() + val page: PdfRenderer.Page = pdfRenderer.openPage(index) + val width = + if (coreContext.screenWidth <= coreContext.screenHeight) coreContext.screenWidth else coreContext.screenHeight + val bm = Bitmap.createBitmap( + width.toInt(), + (width / page.width * page.height).toInt(), + Bitmap.Config.ARGB_8888 + ) + page.render(bm, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY) + page.close() - view.setImageBitmap(bm) + withContext(Dispatchers.Main) { + view.setImageBitmap(bm) + } - operationInProgress.value = false - } catch (e: Exception) { - Log.e("[PDF Viewer] Exception: $e") - operationInProgress.value = false + operationInProgress.postValue(false) + } catch (e: Exception) { + Log.e("[PDF Viewer] Exception: $e") + operationInProgress.postValue(false) + } + } } } } diff --git a/app/src/main/java/org/linphone/activities/main/files/viewmodels/TextFileViewModel.kt b/app/src/main/java/org/linphone/activities/main/files/viewmodels/TextFileViewModel.kt index fd79d5f6f..56aa44dbc 100644 --- a/app/src/main/java/org/linphone/activities/main/files/viewmodels/TextFileViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/files/viewmodels/TextFileViewModel.kt @@ -47,17 +47,10 @@ class TextFileViewModel(content: Content) : FileViewerViewModel(content) { val text = MutableLiveData() init { - operationInProgress.value = false - - openFile() - } - - private fun openFile() { - operationInProgress.value = true - viewModelScope.launch { withContext(Dispatchers.IO) { try { + operationInProgress.postValue(true) val br = BufferedReader(FileReader(filePath)) var line: String? val textBuilder = StringBuilder()