Fix crashes
This commit is contained in:
@@ -14,7 +14,6 @@ import androidx.core.view.isVisible
|
|||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.core.ui.BaseActivity
|
import org.koitharu.kotatsu.core.ui.BaseActivity
|
||||||
import org.koitharu.kotatsu.core.util.ext.catchingWebViewUnavailability
|
|
||||||
import org.koitharu.kotatsu.databinding.ActivityBrowserBinding
|
import org.koitharu.kotatsu.databinding.ActivityBrowserBinding
|
||||||
import org.koitharu.kotatsu.parsers.network.UserAgents
|
import org.koitharu.kotatsu.parsers.network.UserAgents
|
||||||
import com.google.android.material.R as materialR
|
import com.google.android.material.R as materialR
|
||||||
@@ -26,7 +25,7 @@ class BrowserActivity : BaseActivity<ActivityBrowserBinding>(), BrowserCallback
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
if (!catchingWebViewUnavailability { setContentView(ActivityBrowserBinding.inflate(layoutInflater)) }) {
|
if (!setContentViewWebViewSafe { ActivityBrowserBinding.inflate(layoutInflater) }) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
supportActionBar?.run {
|
supportActionBar?.run {
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import org.koitharu.kotatsu.core.network.CommonHeaders
|
|||||||
import org.koitharu.kotatsu.core.network.cookies.MutableCookieJar
|
import org.koitharu.kotatsu.core.network.cookies.MutableCookieJar
|
||||||
import org.koitharu.kotatsu.core.ui.BaseActivity
|
import org.koitharu.kotatsu.core.ui.BaseActivity
|
||||||
import org.koitharu.kotatsu.core.util.TaggedActivityResult
|
import org.koitharu.kotatsu.core.util.TaggedActivityResult
|
||||||
import org.koitharu.kotatsu.core.util.ext.catchingWebViewUnavailability
|
|
||||||
import org.koitharu.kotatsu.databinding.ActivityBrowserBinding
|
import org.koitharu.kotatsu.databinding.ActivityBrowserBinding
|
||||||
import org.koitharu.kotatsu.parsers.network.UserAgents
|
import org.koitharu.kotatsu.parsers.network.UserAgents
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -45,13 +44,7 @@ class CloudFlareActivity : BaseActivity<ActivityBrowserBinding>(), CloudFlareCal
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
if (!catchingWebViewUnavailability {
|
if (!setContentViewWebViewSafe { ActivityBrowserBinding.inflate(layoutInflater) }) {
|
||||||
setContentView(
|
|
||||||
ActivityBrowserBinding.inflate(
|
|
||||||
layoutInflater,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
supportActionBar?.run {
|
supportActionBar?.run {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import android.os.Bundle
|
|||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.annotation.CallSuper
|
import androidx.annotation.CallSuper
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.view.ActionMode
|
import androidx.appcompat.view.ActionMode
|
||||||
@@ -29,6 +30,7 @@ import org.koitharu.kotatsu.core.ui.util.ActionModeDelegate
|
|||||||
import org.koitharu.kotatsu.core.ui.util.BaseActivityEntryPoint
|
import org.koitharu.kotatsu.core.ui.util.BaseActivityEntryPoint
|
||||||
import org.koitharu.kotatsu.core.ui.util.WindowInsetsDelegate
|
import org.koitharu.kotatsu.core.ui.util.WindowInsetsDelegate
|
||||||
import org.koitharu.kotatsu.core.util.ext.getThemeColor
|
import org.koitharu.kotatsu.core.util.ext.getThemeColor
|
||||||
|
import org.koitharu.kotatsu.core.util.ext.isWebViewUnavailable
|
||||||
|
|
||||||
@Suppress("LeakingThis")
|
@Suppress("LeakingThis")
|
||||||
abstract class BaseActivity<B : ViewBinding> :
|
abstract class BaseActivity<B : ViewBinding> :
|
||||||
@@ -164,6 +166,21 @@ abstract class BaseActivity<B : ViewBinding> :
|
|||||||
intent?.putExtra(EXTRA_DATA, intent.data)
|
intent?.putExtra(EXTRA_DATA, intent.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected fun setContentViewWebViewSafe(viewBindingProducer: () -> B): Boolean {
|
||||||
|
return try {
|
||||||
|
setContentView(viewBindingProducer())
|
||||||
|
true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
if (e.isWebViewUnavailable()) {
|
||||||
|
Toast.makeText(this, R.string.web_view_unavailable, Toast.LENGTH_LONG).show()
|
||||||
|
finishAfterTransition()
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
const val EXTRA_DATA = "data"
|
const val EXTRA_DATA = "data"
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import android.provider.Settings
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewPropertyAnimator
|
import android.view.ViewPropertyAnimator
|
||||||
import android.view.Window
|
import android.view.Window
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
import androidx.annotation.IntegerRes
|
import androidx.annotation.IntegerRes
|
||||||
import androidx.annotation.WorkerThread
|
import androidx.annotation.WorkerThread
|
||||||
@@ -216,21 +215,6 @@ fun Context.findActivity(): Activity? = when (this) {
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun Activity.catchingWebViewUnavailability(block: () -> Unit): Boolean {
|
|
||||||
return try {
|
|
||||||
block()
|
|
||||||
true
|
|
||||||
} catch (e: Exception) {
|
|
||||||
if (e.isWebViewUnavailable()) {
|
|
||||||
Toast.makeText(this, R.string.web_view_unavailable, Toast.LENGTH_LONG).show()
|
|
||||||
finishAfterTransition()
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
throw e
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Context.checkNotificationPermission(): Boolean = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
fun Context.checkNotificationPermission(): Boolean = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED
|
ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package org.koitharu.kotatsu.core.util.ext
|
|||||||
|
|
||||||
import android.content.ActivityNotFoundException
|
import android.content.ActivityNotFoundException
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.util.AndroidRuntimeException
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.collection.arraySetOf
|
import androidx.collection.arraySetOf
|
||||||
import coil.network.HttpException
|
import coil.network.HttpException
|
||||||
@@ -115,8 +114,8 @@ private val reportableExceptions = arraySetOf<Class<*>>(
|
|||||||
)
|
)
|
||||||
|
|
||||||
fun Throwable.isWebViewUnavailable(): Boolean {
|
fun Throwable.isWebViewUnavailable(): Boolean {
|
||||||
return (this is AndroidRuntimeException && message?.contains("WebView") == true) ||
|
val trace = stackTraceToString()
|
||||||
cause?.isWebViewUnavailable() == true
|
return trace.contains("android.webkit.WebView.<init>")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("FunctionName")
|
@Suppress("FunctionName")
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ class TapGridDispatcher(
|
|||||||
if (!isDispatching) {
|
if (!isDispatching) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return listener.onGridTouch(getArea(event.rawX, event.rawY))
|
val area = getArea(event.rawX, event.rawY) ?: return false
|
||||||
|
return listener.onGridTouch(area)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDoubleTapEvent(e: MotionEvent): Boolean {
|
override fun onDoubleTapEvent(e: MotionEvent): Boolean {
|
||||||
@@ -42,11 +43,12 @@ class TapGridDispatcher(
|
|||||||
|
|
||||||
override fun onLongPress(event: MotionEvent) {
|
override fun onLongPress(event: MotionEvent) {
|
||||||
if (isDispatching) {
|
if (isDispatching) {
|
||||||
listener.onGridLongTouch(getArea(event.rawX, event.rawY))
|
val area = getArea(event.rawX, event.rawY) ?: return
|
||||||
|
listener.onGridLongTouch(area)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getArea(x: Float, y: Float): TapGridArea {
|
private fun getArea(x: Float, y: Float): TapGridArea? {
|
||||||
val xIndex = (x * 2f / width).roundToInt()
|
val xIndex = (x * 2f / width).roundToInt()
|
||||||
val yIndex = (y * 2f / height).roundToInt()
|
val yIndex = (y * 2f / height).roundToInt()
|
||||||
val area = when (xIndex) {
|
val area = when (xIndex) {
|
||||||
@@ -73,7 +75,8 @@ class TapGridDispatcher(
|
|||||||
|
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
return checkNotNull(area) { "Invalid area ($xIndex, $yIndex)" }
|
assert(area != null) { "Invalid area ($xIndex, $yIndex)" }
|
||||||
|
return area
|
||||||
}
|
}
|
||||||
|
|
||||||
interface OnGridTouchListener {
|
interface OnGridTouchListener {
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import org.koitharu.kotatsu.core.parser.MangaRepository
|
|||||||
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
|
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
|
||||||
import org.koitharu.kotatsu.core.ui.BaseActivity
|
import org.koitharu.kotatsu.core.ui.BaseActivity
|
||||||
import org.koitharu.kotatsu.core.util.TaggedActivityResult
|
import org.koitharu.kotatsu.core.util.TaggedActivityResult
|
||||||
import org.koitharu.kotatsu.core.util.ext.catchingWebViewUnavailability
|
|
||||||
import org.koitharu.kotatsu.core.util.ext.getSerializableExtraCompat
|
import org.koitharu.kotatsu.core.util.ext.getSerializableExtraCompat
|
||||||
import org.koitharu.kotatsu.databinding.ActivityBrowserBinding
|
import org.koitharu.kotatsu.databinding.ActivityBrowserBinding
|
||||||
import org.koitharu.kotatsu.parsers.MangaParserAuthProvider
|
import org.koitharu.kotatsu.parsers.MangaParserAuthProvider
|
||||||
@@ -43,7 +42,7 @@ class SourceAuthActivity : BaseActivity<ActivityBrowserBinding>(), BrowserCallba
|
|||||||
@SuppressLint("SetJavaScriptEnabled")
|
@SuppressLint("SetJavaScriptEnabled")
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
if (!catchingWebViewUnavailability { setContentView(ActivityBrowserBinding.inflate(layoutInflater)) }) {
|
if (!setContentViewWebViewSafe { ActivityBrowserBinding.inflate(layoutInflater) }) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val source = intent?.getSerializableExtraCompat<MangaSource>(EXTRA_SOURCE)
|
val source = intent?.getSerializableExtraCompat<MangaSource>(EXTRA_SOURCE)
|
||||||
|
|||||||
Reference in New Issue
Block a user