From eb8479ac9ac5a4d60ddf5f40246a91189617c5ee Mon Sep 17 00:00:00 2001 From: inorichi Date: Tue, 6 Feb 2018 22:11:36 +0100 Subject: [PATCH] Timeout the installation of extensions after 10s --- .../extension/util/ExtensionInstaller.kt | 32 +++++++++++++++---- .../ui/extension/ExtensionPresenter.kt | 2 +- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstaller.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstaller.kt index cf57e159ef..37dbcfc1fc 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstaller.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstaller.kt @@ -65,7 +65,7 @@ internal class ExtensionInstaller(private val context: Context) { .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) val id = downloadManager.enqueue(request) - activeDownloads.put(pkgName, id) + activeDownloads[pkgName] = id downloadsRelay.filter { it.first == id } .map { it.second } @@ -73,6 +73,8 @@ internal class ExtensionInstaller(private val context: Context) { .mergeWith(pollStatus(id)) // Force an error if the download takes more than 3 minutes .mergeWith(Observable.timer(3, TimeUnit.MINUTES).map { InstallStep.Error }) + // Force an error if the install process takes more than 10 seconds + .flatMap { timeoutWhenInstalling(it) } // Stop when the application is installed or errors .takeUntil { it.isCompleted() } // Always notify on main thread @@ -112,6 +114,22 @@ internal class ExtensionInstaller(private val context: Context) { } } + /** + * Returns an observable that timeouts the installation after a specified time when the apk has + * been downloaded. + * + * @param currentStep The current step of the installation process. + */ + private fun timeoutWhenInstalling(currentStep: InstallStep): Observable { + return if (currentStep == InstallStep.Installing) { + Observable.timer(10, TimeUnit.SECONDS) + .map { InstallStep.Error } + .startWith(currentStep) + } else { + Observable.just(currentStep) + } + } + /** * Starts an intent to install the extension at the given uri. * @@ -221,12 +239,12 @@ internal class ExtensionInstaller(private val context: Context) { // it fails. try { installApk(uri) - } catch (e: ActivityNotFoundException) { - val query = DownloadManager.Query() - query.setFilterById(id) - downloadManager.query(query).use { - if (it.moveToFirst()) { - val uriCompat = File(it.getString(it.getColumnIndex( + } catch (_: ActivityNotFoundException) { + val query = DownloadManager.Query().setFilterById(id) + downloadManager.query(query).use { cursor -> + if (cursor.moveToFirst()) { + @Suppress("DEPRECATION") + val uriCompat = File(cursor.getString(cursor.getColumnIndex( DownloadManager.COLUMN_LOCAL_FILENAME))).getUriCompat(context) installApk(uriCompat) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionPresenter.kt index 2f0b81fda0..36ea367003 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionPresenter.kt @@ -105,7 +105,7 @@ open class ExtensionPresenter( } private fun Observable.subscribeToInstallUpdate(extension: Extension) { - this.doOnNext { currentDownloads.put(extension.pkgName, it) } + this.doOnNext { currentDownloads[extension.pkgName] = it } .doOnUnsubscribe { currentDownloads.remove(extension.pkgName) } .map { state -> updateInstallStep(extension, state) } .subscribeWithView({ view, item ->