Fix extensions installer on old Android versions. Fix deadlock on devices with 1-2 cores

This commit is contained in:
inorichi 2018-02-06 11:42:38 +01:00
parent 02e187f066
commit 636c027298
2 changed files with 40 additions and 14 deletions

View file

@ -11,7 +11,8 @@ import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.extension.ExtensionManager import eu.kanade.tachiyomi.extension.ExtensionManager
import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import kotlinx.coroutines.experimental.async import rx.Observable
import rx.schedulers.Schedulers
import uy.kohesive.injekt.api.* import uy.kohesive.injekt.api.*
class AppModule(val app: Application) : InjektModule { class AppModule(val app: Application) : InjektModule {
@ -42,16 +43,20 @@ class AppModule(val app: Application) : InjektModule {
// Asynchronously init expensive components for a faster cold start // Asynchronously init expensive components for a faster cold start
async { get<PreferencesHelper>() } rxAsync { get<PreferencesHelper>() }
async { get<NetworkHelper>() } rxAsync { get<NetworkHelper>() }
async { get<SourceManager>() } rxAsync { get<SourceManager>() }
async { get<DatabaseHelper>() } rxAsync { get<DatabaseHelper>() }
async { get<DownloadManager>() } rxAsync { get<DownloadManager>() }
} }
} private fun rxAsync(block: () -> Unit) {
Observable.fromCallable { block() }.subscribeOn(Schedulers.computation()).subscribe()
}
}

View file

@ -1,17 +1,16 @@
package eu.kanade.tachiyomi.extension.util package eu.kanade.tachiyomi.extension.util
import android.app.DownloadManager import android.app.DownloadManager
import android.content.BroadcastReceiver import android.content.*
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.Uri import android.net.Uri
import com.jakewharton.rxrelay.PublishRelay import com.jakewharton.rxrelay.PublishRelay
import eu.kanade.tachiyomi.extension.model.Extension import eu.kanade.tachiyomi.extension.model.Extension
import eu.kanade.tachiyomi.extension.model.InstallStep import eu.kanade.tachiyomi.extension.model.InstallStep
import eu.kanade.tachiyomi.util.getUriCompat
import rx.Observable import rx.Observable
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
import timber.log.Timber import timber.log.Timber
import java.io.File
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
/** /**
@ -133,8 +132,10 @@ internal class ExtensionInstaller(private val context: Context) {
*/ */
fun uninstallApk(pkgName: String) { fun uninstallApk(pkgName: String) {
val packageUri = Uri.parse("package:$pkgName") val packageUri = Uri.parse("package:$pkgName")
val uninstallIntent = Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri) val intent = Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri)
context.startActivity(uninstallIntent) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
} }
/** /**
@ -204,12 +205,32 @@ internal class ExtensionInstaller(private val context: Context) {
if (id !in activeDownloads.values) return if (id !in activeDownloads.values) return
val uri = downloadManager.getUriForDownloadedFile(id) val uri = downloadManager.getUriForDownloadedFile(id)
// Set next installation step
if (uri != null) { if (uri != null) {
downloadsRelay.call(id to InstallStep.Installing) downloadsRelay.call(id to InstallStep.Installing)
installApk(uri)
} else { } else {
Timber.e("Couldn't locate downloaded APK") Timber.e("Couldn't locate downloaded APK")
downloadsRelay.call(id to InstallStep.Error) downloadsRelay.call(id to InstallStep.Error)
return
}
// Due to a bug in older Android versions (L and M at least), the installer can't open
// files that do not contain the apk extension, even if you specify the correct MIME.
// We workaround it by querying the actual file path and using the file provider when
// 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(
DownloadManager.COLUMN_LOCAL_FILENAME))).getUriCompat(context)
installApk(uriCompat)
}
}
} }
} }
} }