From 6cd34614f607c51a62eed68d98996990969e5909 Mon Sep 17 00:00:00 2001
From: arkon <eugcheung94@gmail.com>
Date: Sat, 2 May 2020 19:03:48 -0400
Subject: [PATCH] More extreme method for enforcing WebView availability

---
 app/src/main/AndroidManifest.xml              |  5 ++++
 app/src/main/java/eu/kanade/tachiyomi/App.kt  | 10 +++++++
 .../tachiyomi/ui/main/ForceCloseActivity.kt   | 28 +++++++++++++++++++
 .../kanade/tachiyomi/ui/main/MainActivity.kt  |  7 -----
 .../tachiyomi/util/system/WebViewUtil.kt      | 11 +++++++-
 5 files changed, 53 insertions(+), 8 deletions(-)
 create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/main/ForceCloseActivity.kt

diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 261df31e81..95e93bd147 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -40,6 +40,11 @@
                 android:name="android.app.shortcuts"
                 android:resource="@xml/shortcuts" />
         </activity>
+        <activity
+            android:name=".ui.main.ForceCloseActivity"
+            android:clearTaskOnLaunch="true"
+            android:noHistory="true"
+            android:theme="@android:style/Theme.NoDisplay" />
         <activity
             android:name=".ui.main.DeepLinkActivity"
             android:launchMode="singleTask"
diff --git a/app/src/main/java/eu/kanade/tachiyomi/App.kt b/app/src/main/java/eu/kanade/tachiyomi/App.kt
index f782c0b7a5..1b0622604b 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/App.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/App.kt
@@ -3,6 +3,7 @@ package eu.kanade.tachiyomi
 import android.app.Application
 import android.content.Context
 import android.content.res.Configuration
+import android.widget.Toast
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.LifecycleObserver
 import androidx.lifecycle.OnLifecycleEvent
@@ -10,8 +11,11 @@ import androidx.lifecycle.ProcessLifecycleOwner
 import androidx.multidex.MultiDex
 import eu.kanade.tachiyomi.data.notification.Notifications
 import eu.kanade.tachiyomi.data.preference.PreferencesHelper
+import eu.kanade.tachiyomi.ui.main.ForceCloseActivity
 import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
 import eu.kanade.tachiyomi.util.system.LocaleHelper
+import eu.kanade.tachiyomi.util.system.WebViewUtil
+import eu.kanade.tachiyomi.util.system.toast
 import org.acra.ACRA
 import org.acra.annotation.AcraCore
 import org.acra.annotation.AcraHttpSender
@@ -36,6 +40,12 @@ open class App : Application(), LifecycleObserver {
         super.onCreate()
         if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree())
 
+        // Enforce WebView availability
+        if (!WebViewUtil.supportsWebView(this)) {
+            toast(R.string.information_webview_required, Toast.LENGTH_LONG)
+            ForceCloseActivity.closeApp(this)
+        }
+
         Injekt = InjektScope(DefaultRegistrar())
         Injekt.importModule(AppModule(this))
 
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/ForceCloseActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/ForceCloseActivity.kt
new file mode 100644
index 0000000000..efcae017a9
--- /dev/null
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/ForceCloseActivity.kt
@@ -0,0 +1,28 @@
+package eu.kanade.tachiyomi.ui.main
+
+import android.content.Context
+import android.content.Intent
+import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+
+/**
+ * Activity that in conjunction with its configuration in the manifest allows for a way to
+ * "force close" the application from the main [App] class.
+ */
+class ForceCloseActivity : AppCompatActivity() {
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        finish()
+    }
+
+    companion object {
+        fun closeApp(context: Context) {
+            val intent = Intent(context, ForceCloseActivity::class.java).apply {
+                addCategory(Intent.CATEGORY_HOME)
+                addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
+            }
+            context.startActivity(intent)
+        }
+    }
+}
diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
index 21471938ea..8f9e087b75 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt
@@ -36,7 +36,6 @@ import eu.kanade.tachiyomi.ui.more.MoreController
 import eu.kanade.tachiyomi.ui.recent.history.HistoryController
 import eu.kanade.tachiyomi.ui.recent.updates.UpdatesController
 import eu.kanade.tachiyomi.util.lang.launchUI
-import eu.kanade.tachiyomi.util.system.WebViewUtil
 import eu.kanade.tachiyomi.util.system.toast
 import java.util.Date
 import java.util.concurrent.TimeUnit
@@ -71,12 +70,6 @@ class MainActivity : BaseActivity<MainActivityBinding>() {
 
         binding = MainActivityBinding.inflate(layoutInflater)
 
-        // Enforce WebView availability
-        if (!WebViewUtil.supportsWebView(this)) {
-            toast(R.string.information_webview_required, Toast.LENGTH_LONG)
-            finishAndRemoveTask()
-        }
-
         // Do not let the launcher create a new activity http://stackoverflow.com/questions/16283079
         if (!isTaskRoot) {
             finish()
diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/system/WebViewUtil.kt b/app/src/main/java/eu/kanade/tachiyomi/util/system/WebViewUtil.kt
index 3eeb60bc3a..6eaf6bc9f5 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/util/system/WebViewUtil.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/util/system/WebViewUtil.kt
@@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.util.system
 
 import android.content.Context
 import android.content.pm.PackageManager
+import android.webkit.CookieManager
 import android.webkit.WebView
 
 object WebViewUtil {
@@ -9,9 +10,17 @@ object WebViewUtil {
         Regex(""".*Chrome/(\d+)\..*""")
     }
 
-    const val MINIMUM_WEBVIEW_VERSION = 79
+    const val MINIMUM_WEBVIEW_VERSION = 80
 
     fun supportsWebView(context: Context): Boolean {
+        try {
+            // May throw android.webkit.WebViewFactory$MissingWebViewPackageException if WebView
+            // is not installed
+            CookieManager.getInstance()
+        } catch (e: Exception) {
+            return false
+        }
+
         return context.packageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)
     }
 }