From 8b8764adbe2bc3aae20d470bac2e499b12d3243d Mon Sep 17 00:00:00 2001 From: Sean Mac Gillicuddy Date: Tue, 1 Oct 2019 16:11:43 +0100 Subject: [PATCH] cherry pick 3.0.4 --- CHANGELOG | 6 ++ app/build.gradle | 3 +- .../play/release-notes/en-US/default.txt | 17 ++--- .../kiwixmobile/core/main/MainActivity.java | 33 +++++----- .../kiwixmobile/core/utils/files/FileUtils.kt | 63 +++++++++++-------- .../core/zim_manager/ZimFileReader.kt | 9 ++- .../fileselect_view/StorageObserver.kt | 8 ++- 7 files changed, 79 insertions(+), 60 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 81311c303..a185dd081 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +3.0.4 +BUGFIX: Some users language was causing a crash due to unstable ISO codes +BUGFIX: Some unstable zim files were crashing when opened +BUGFIX: Long titles were rendering off screen on home page +BUGFIX: Issues when opening a file externally + 3.0.0 NEW: Androidx support NEW: In app error reporting diff --git a/app/build.gradle b/app/build.gradle index 79b096b78..a11b70e92 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,7 +29,7 @@ def buildNumber = System.getenv('TRAVIS_BUILD_NUMBER') ?: "dev" ext { versionMajor = 3 versionMinor = 0 - versionPatch = 3 + versionPatch = 4 } private String generateVersionName() { @@ -260,5 +260,4 @@ dependencies { // RxJava implementation(Libs.rxandroid) implementation(Libs.rxjava) - } diff --git a/app/src/kiwix/play/release-notes/en-US/default.txt b/app/src/kiwix/play/release-notes/en-US/default.txt index 9668a427f..0d134254f 100644 --- a/app/src/kiwix/play/release-notes/en-US/default.txt +++ b/app/src/kiwix/play/release-notes/en-US/default.txt @@ -1,13 +1,4 @@ -NEW: Androidx support -NEW: In app error reporting -NEW: Improved bookmarks -NEW: Help screen -NEW: Home page -NEW: Zim history -NEW: Introductory screen -NEW: Improved language selection -NEW: Add note to articles -NEW: Tabs -NEW: Share zim files to other Kiwix users -NEW: Host zim files on your phone -+ Bugfixes & Lots More +BUGFIX: Some users language was causing a crash due to unstable ISO codes +BUGFIX: Some unstable zim files were crashing when opened +BUGFIX: Long titles were rendering off screen on home page +BUGFIX: Issues when opening a file externally diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/main/MainActivity.java b/core/src/main/java/org/kiwix/kiwixmobile/core/main/MainActivity.java index 33332cca6..3711d0700 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/main/MainActivity.java +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/main/MainActivity.java @@ -99,6 +99,7 @@ import org.kiwix.kiwixmobile.core.R2; import org.kiwix.kiwixmobile.core.base.BaseActivity; import org.kiwix.kiwixmobile.core.bookmark.BookmarkItem; import org.kiwix.kiwixmobile.core.bookmark.BookmarksActivity; +import org.kiwix.kiwixmobile.core.extensions.ContextExtensionsKt; import org.kiwix.kiwixmobile.core.help.HelpActivity; import org.kiwix.kiwixmobile.core.history.HistoryActivity; import org.kiwix.kiwixmobile.core.history.HistoryListItem; @@ -1067,24 +1068,26 @@ public class MainActivity extends BaseActivity implements WebViewCallback, && Build.VERSION.SDK_INT != 23)) { if (file.exists()) { zimReaderContainer.setZimFile(file); - if (clearHistory) { - requestClearHistoryAfterLoad = true; - } - if (menu != null) { - initAllMenuItems(); + if (zimReaderContainer.getZimFileReader() != null) { + if (clearHistory) { + requestClearHistoryAfterLoad = true; + } + if (menu != null) { + initAllMenuItems(); + } else { + // Menu may not be initialized yet. In this case + // signal to menu create to show + requestInitAllMenuItems = true; + } + openMainPage(); + presenter.loadCurrentZimBookmarksUrl(); } else { - // Menu may not be initialized yet. In this case - // signal to menu create to show - requestInitAllMenuItems = true; + ContextExtensionsKt.toast(this, R.string.error_file_invalid, Toast.LENGTH_LONG); + showHomePage(); } - openMainPage(); - presenter.loadCurrentZimBookmarksUrl(); } else { Log.w(TAG_KIWIX, "ZIM file doesn't exist at " + file.getAbsolutePath()); - - Toast.makeText(this, getResources().getString(R.string.error_file_not_found), - Toast.LENGTH_LONG) - .show(); + ContextExtensionsKt.toast(this, R.string.error_file_not_found, Toast.LENGTH_LONG); showHomePage(); } } else { @@ -1638,7 +1641,7 @@ public class MainActivity extends BaseActivity implements WebViewCallback, toggleActionItemsConfig(); this.menu = menu; - if (tabSwitcherRoot.getVisibility() == View.VISIBLE) { + if (tabSwitcherRoot != null && tabSwitcherRoot.getVisibility() == View.VISIBLE) { menu.findItem(R.id.menu_search).setVisible(false); menu.findItem(R.id.menu_fullscreen).setVisible(false); menu.findItem(R.id.menu_random_article).setVisible(false); diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/utils/files/FileUtils.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/utils/files/FileUtils.kt index 631f96b4f..cf798479c 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/utils/files/FileUtils.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/utils/files/FileUtils.kt @@ -17,10 +17,12 @@ */ package org.kiwix.kiwixmobile.core.utils.files +import android.annotation.TargetApi import android.content.ContentUris import android.content.Context import android.net.Uri import android.os.Build +import android.os.Build.VERSION_CODES import android.os.Environment import android.provider.DocumentsContract import android.util.Log @@ -40,15 +42,15 @@ object FileUtils { "${Environment.getExternalStorageDirectory()}${File.separator}Android" + "${File.separator}obb${File.separator}${KiwixApplication.getInstance().packageName}" - @JvmStatic fun getFileCacheDir(context: Context): File = + @JvmStatic fun getFileCacheDir(context: Context): File? = if (Environment.MEDIA_MOUNTED == Environment.getExternalStorageState()) { - context.externalCacheDir!! + context.externalCacheDir } else { context.cacheDir } @JvmStatic @Synchronized fun deleteCachedFiles(context: Context) { - getFileCacheDir(context).deleteRecursively() + getFileCacheDir(context)?.deleteRecursively() } @JvmStatic @Synchronized fun deleteZimFile(path: String) { @@ -147,12 +149,12 @@ object FileUtils { } @JvmStatic fun getLocalFilePathByUri( - ctx: Context, + context: Context, uri: Uri ): String? { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && - DocumentsContract.isDocumentUri(ctx, uri) + DocumentsContract.isDocumentUri(context, uri) ) { if ("com.android.externalstorage.documents" == uri.authority) { val documentId = DocumentsContract.getDocumentId(uri) @@ -161,38 +163,49 @@ object FileUtils { if (documentId[0] == "primary") { return "${Environment.getExternalStorageDirectory()}/${documentId[1]}" } - } else if ("com.android.providers.downloads.documents" == uri.authority - ) - return contentQuery( - ctx, - ContentUris.withAppendedId( - Uri.parse("content://downloads/public_downloads"), - try { - DocumentsContract.getDocumentId(uri).toLong() - } catch (ignore: NumberFormatException) { - 0L - } - ) - ) + } else if ("com.android.providers.downloads.documents" == uri.authority) + return try { + documentProviderContentQuery(context, uri) + } catch (ignore: IllegalArgumentException) { + null + } } else if ("content".equals(uri.scheme!!, ignoreCase = true)) { - return contentQuery(ctx, uri) + return contentQuery(context, uri) } else if ("file".equals(uri.scheme!!, ignoreCase = true)) { return uri.path } return null } + @TargetApi(VERSION_CODES.KITKAT) + private fun documentProviderContentQuery(context: Context, uri: Uri) = + contentQuery( + context, + ContentUris.withAppendedId( + Uri.parse("content://downloads/public_downloads"), + try { + DocumentsContract.getDocumentId(uri).toLong() + } catch (ignore: NumberFormatException) { + 0L + } + ) + ) + private fun contentQuery( context: Context, uri: Uri ): String? { val columnName = "_data" - return context.contentResolver.query(uri, arrayOf(columnName), null, null, null) - ?.use { - if (it.moveToFirst() && it.getColumnIndex(columnName) != -1) { - it[columnName] - } else null - } + return try { + context.contentResolver.query(uri, arrayOf(columnName), null, null, null) + ?.use { + if (it.moveToFirst() && it.getColumnIndex(columnName) != -1) { + it[columnName] + } else null + } + } catch (ignore: SecurityException) { + null + } } @JvmStatic fun readLocalesFromAssets(context: Context) = diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/ZimFileReader.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/ZimFileReader.kt index cafd24e02..471c0752c 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/ZimFileReader.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/ZimFileReader.kt @@ -26,6 +26,7 @@ import android.webkit.MimeTypeMap import androidx.core.net.toUri import io.reactivex.Single import io.reactivex.schedulers.Schedulers +import org.kiwix.kiwixlib.JNIKiwixException import org.kiwix.kiwixlib.JNIKiwixInt import org.kiwix.kiwixlib.JNIKiwixReader import org.kiwix.kiwixlib.JNIKiwixString @@ -50,11 +51,15 @@ class ZimFileReader( private val sharedPreferenceUtil: SharedPreferenceUtil ) { interface Factory { - fun create(file: File): ZimFileReader + fun create(file: File): ZimFileReader? class Impl @Inject constructor(val sharedPreferenceUtil: SharedPreferenceUtil) : Factory { override fun create(file: File) = - ZimFileReader(file, sharedPreferenceUtil = sharedPreferenceUtil) + try { + ZimFileReader(file, sharedPreferenceUtil = sharedPreferenceUtil) + } catch (ignore: JNIKiwixException) { + null + } } } diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/fileselect_view/StorageObserver.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/fileselect_view/StorageObserver.kt index 312f094f8..a11b7cb70 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/fileselect_view/StorageObserver.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/zim_manager/fileselect_view/StorageObserver.kt @@ -18,6 +18,7 @@ package org.kiwix.kiwixmobile.core.zim_manager.fileselect_view +import io.reactivex.Flowable import io.reactivex.functions.BiFunction import io.reactivex.schedulers.Schedulers import org.kiwix.kiwixmobile.core.downloader.model.DownloadModel @@ -34,10 +35,10 @@ class StorageObserver @Inject constructor( private val zimReaderFactory: ZimFileReader.Factory ) { - val booksOnFileSystem + val booksOnFileSystem: Flowable> get() = scanFiles() .withLatestFrom(downloadDao.downloads(), BiFunction(::toFilesThatAreNotDownloading)) - .map { it.map(::convertToBookOnDisk) } + .map { it.mapNotNull(::convertToBookOnDisk) } private fun scanFiles() = fileSearch.scan().subscribeOn(Schedulers.io()) @@ -47,5 +48,6 @@ class StorageObserver @Inject constructor( private fun fileHasNoMatchingDownload(downloads: List, file: File) = downloads.firstOrNull { file.absolutePath.endsWith(it.fileNameFromUrl) } == null - private fun convertToBookOnDisk(file: File) = BookOnDisk(file, zimReaderFactory.create(file)) + private fun convertToBookOnDisk(file: File) = + zimReaderFactory.create(file)?.let { BookOnDisk(file, it) } }