فهرست منبع

Bugfixes and extension installation improvements

inorichi 7 سال پیش
والد
کامیت
8e50ac67bc

+ 1 - 1
app/build.gradle

@@ -102,7 +102,7 @@ android {
 dependencies {
 
     // Modified dependencies
-    implementation 'com.github.inorichi:subsampling-scale-image-view:c19b883'
+    implementation 'com.github.inorichi:subsampling-scale-image-view:81b9d68'
     implementation 'com.github.inorichi:junrar-android:634c1f5'
 
     // Android support library

+ 3 - 0
app/src/main/AndroidManifest.xml

@@ -52,6 +52,9 @@
                     android:scheme="tachiyomi" />
             </intent-filter>
         </activity>
+        <activity
+            android:name=".extension.util.ExtensionInstallActivity"
+            android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
 
         <provider
             android:name="android.support.v4.content.FileProvider"

+ 10 - 3
app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionManager.kt

@@ -201,6 +201,16 @@ class ExtensionManager(
         return installExtension(availableExt)
     }
 
+    /**
+     * Sets the result of the installation of an extension.
+     *
+     * @param downloadId The id of the download.
+     * @param result Whether the extension was installed or not.
+     */
+    fun setInstallationResult(downloadId: Long, result: Boolean) {
+        installer.setInstallationResult(downloadId, result)
+    }
+
     /**
      * Uninstalls the extension that matches the given package name.
      *
@@ -295,17 +305,14 @@ class ExtensionManager(
 
         override fun onExtensionInstalled(extension: Extension.Installed) {
             registerNewExtension(extension.withUpdateCheck())
-            installer.onApkInstalled(extension.pkgName)
         }
 
         override fun onExtensionUpdated(extension: Extension.Installed) {
             registerUpdatedExtension(extension.withUpdateCheck())
-            installer.onApkInstalled(extension.pkgName)
         }
 
         override fun onExtensionUntrusted(extension: Extension.Untrusted) {
             untrustedExtensions += extension
-            installer.onApkInstalled(extension.pkgName)
         }
 
         override fun onPackageUninstalled(pkgName: String) {

+ 45 - 0
app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstallActivity.kt

@@ -0,0 +1,45 @@
+package eu.kanade.tachiyomi.extension.util
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
+import eu.kanade.tachiyomi.extension.ExtensionManager
+import uy.kohesive.injekt.Injekt
+import uy.kohesive.injekt.api.get
+
+/**
+ * Activity used to install extensions, because we can only receive the result of the installation
+ * with [startActivityForResult], which we need to update the UI.
+ */
+class ExtensionInstallActivity : Activity() {
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+        val installIntent = Intent(Intent.ACTION_INSTALL_PACKAGE)
+                .setDataAndType(intent.data, intent.type)
+                .putExtra(Intent.EXTRA_RETURN_RESULT, true)
+                .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
+
+        startActivityForResult(installIntent, INSTALL_REQUEST_CODE)
+    }
+
+    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+        if (requestCode == INSTALL_REQUEST_CODE) {
+            checkInstallationResult(resultCode)
+        }
+        finish()
+    }
+
+    private fun checkInstallationResult(resultCode: Int) {
+        val downloadId = intent.extras.getLong(ExtensionInstaller.EXTRA_DOWNLOAD_ID)
+        val success = resultCode == RESULT_OK
+
+        val extensionManager = Injekt.get<ExtensionManager>()
+        extensionManager.setInstallationResult(downloadId, success)
+    }
+
+    private companion object {
+        const val INSTALL_REQUEST_CODE = 500
+    }
+}

+ 13 - 25
app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstaller.kt

@@ -77,8 +77,6 @@ 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 { Observable.just(it).mergeWith(timeoutWhenInstalling(it)) }
                 // Stop when the application is installed or errors
                 .takeUntil { it.isCompleted() }
                 // Always notify on main thread
@@ -118,27 +116,15 @@ 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<InstallStep> {
-        return Observable.just(currentStep)
-                .filter { it == InstallStep.Installing }
-                .delay(10, TimeUnit.SECONDS)
-                .map { InstallStep.Error }
-    }
-
     /**
      * Starts an intent to install the extension at the given uri.
      *
      * @param uri The uri of the extension to install.
      */
-    fun installApk(uri: Uri) {
-        val intent = Intent(Intent.ACTION_VIEW)
+    fun installApk(downloadId: Long, uri: Uri) {
+        val intent = Intent(context, ExtensionInstallActivity::class.java)
                 .setDataAndType(uri, APK_MIME)
+                .putExtra(EXTRA_DOWNLOAD_ID, downloadId)
                 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION)
 
         context.startActivity(intent)
@@ -158,13 +144,14 @@ internal class ExtensionInstaller(private val context: Context) {
     }
 
     /**
-     * Called when an extension is installed, allowing to update its installation step.
+     * Sets the result of the installation of an extension.
      *
-     * @param pkgName The package name of the installed application.
+     * @param downloadId The id of the download.
+     * @param result Whether the extension was installed or not.
      */
-    fun onApkInstalled(pkgName: String) {
-        val id = activeDownloads[pkgName] ?: return
-        downloadsRelay.call(id to InstallStep.Installed)
+    fun setInstallationResult(downloadId: Long, result: Boolean) {
+        val step = if (result) InstallStep.Installed else InstallStep.Error
+        downloadsRelay.call(downloadId to step)
     }
 
     /**
@@ -243,17 +230,18 @@ internal class ExtensionInstaller(private val context: Context) {
                         @Suppress("DEPRECATION")
                         val uriCompat = File(cursor.getString(cursor.getColumnIndex(
                                 DownloadManager.COLUMN_LOCAL_FILENAME))).getUriCompat(context)
-                        installApk(uriCompat)
+                        installApk(id, uriCompat)
                     }
                 }
             } else {
-                installApk(uri)
+                installApk(id, uri)
             }
         }
     }
 
-    private companion object {
+    companion object {
         const val APK_MIME = "application/vnd.android.package-archive"
+        const val EXTRA_DOWNLOAD_ID = "ExtensionInstaller.extra.DOWNLOAD_ID"
     }
 
 }

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDetailsController.kt

@@ -57,7 +57,7 @@ class ExtensionDetailsController(bundle: Bundle? = null) :
     override fun onViewCreated(view: View) {
         super.onViewCreated(view)
 
-        val extension = presenter.extension
+        val extension = presenter.extension ?: return
         val context = view.context
 
         extension_title.text = extension.name

+ 2 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDetailsPresenter.kt

@@ -12,7 +12,7 @@ class ExtensionDetailsPresenter(
         private val extensionManager: ExtensionManager = Injekt.get()
 ) : BasePresenter<ExtensionDetailsController>() {
 
-    val extension = extensionManager.installedExtensions.first { it.pkgName == pkgName }
+    val extension = extensionManager.installedExtensions.find { it.pkgName == pkgName }
 
     override fun onCreate(savedState: Bundle?) {
         super.onCreate(savedState)
@@ -33,6 +33,7 @@ class ExtensionDetailsPresenter(
     }
 
     fun uninstallExtension() {
+        val extension = extension ?: return
         extensionManager.uninstallExtension(extension.pkgName)
     }
 }

+ 4 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt

@@ -148,7 +148,10 @@ class MainActivity : BaseActivity() {
             SHORTCUT_RECENTLY_UPDATED -> setSelectedDrawerItem(R.id.nav_drawer_recent_updates)
             SHORTCUT_RECENTLY_READ -> setSelectedDrawerItem(R.id.nav_drawer_recently_read)
             SHORTCUT_CATALOGUES -> setSelectedDrawerItem(R.id.nav_drawer_catalogues)
-            SHORTCUT_MANGA -> router.setRoot(RouterTransaction.with(MangaController(intent.extras)))
+            SHORTCUT_MANGA -> {
+                val extras = intent.extras ?: return false
+                router.setRoot(RouterTransaction.with(MangaController(extras)))
+            }
             SHORTCUT_DOWNLOADS -> {
                 if (router.backstack.none { it.controller() is DownloadController }) {
                     setSelectedDrawerItem(R.id.nav_drawer_downloads)

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt

@@ -39,7 +39,7 @@ import java.util.*
 class MangaController : RxController, TabbedController {
 
     constructor(manga: Manga?, fromCatalogue: Boolean = false) : super(Bundle().apply {
-        putLong(MANGA_EXTRA, manga?.id!!)
+        putLong(MANGA_EXTRA, manga?.id ?: 0)
         putBoolean(FROM_CATALOGUE_EXTRA, fromCatalogue)
     }) {
         this.manga = manga

+ 9 - 12
app/src/main/res/layout/catalogue_main_controller_card_item.xml

@@ -14,25 +14,22 @@
 
         <ImageView
             android:id="@+id/image"
-            android:layout_width="48dp"
-            android:layout_height="56dp"
-            android:clickable="true"
-            android:paddingLeft="8dp"
-            android:paddingStart="8dp"
-            android:paddingRight="0dp"
-            android:paddingEnd="0dp"
-            app:layout_constraintTop_toTopOf="parent"
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:padding="8dp"
             app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintDimensionRatio="1:1"
             app:layout_constraintLeft_toLeftOf="parent"
-            tools:src="@mipmap/ic_launcher_round"/>
+            app:layout_constraintTop_toTopOf="parent"
+            tools:src="@mipmap/ic_launcher_round" />
 
         <TextView
             android:id="@+id/title"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
             android:maxLines="1"
-            android:paddingLeft="16dp"
-            android:paddingStart="16dp"
+            android:paddingLeft="0dp"
+            android:paddingStart="0dp"
             android:paddingRight="8dp"
             android:paddingEnd="8dp"
             android:ellipsize="end"
@@ -65,4 +62,4 @@
 
     </android.support.constraint.ConstraintLayout>
 
-</FrameLayout>
+</FrameLayout>

+ 5 - 4
app/src/main/res/layout/extension_card_item.xml

@@ -14,14 +14,15 @@
 
         <ImageView
             android:id="@+id/image"
-            android:layout_width="64dp"
-            android:layout_height="match_parent"
-            android:padding="16dp"
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:padding="12dp"
             app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintDimensionRatio="h,1:1"
             app:layout_constraintLeft_toLeftOf="parent"
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toTopOf="parent"
-            tools:src="@mipmap/ic_launcher_round"/>
+            tools:src="@mipmap/ic_launcher_round" />
 
         <TextView
             android:id="@+id/ext_title"