secant-android-wallet/crash-android-lib/src/main/kotlin/co/electriccoin/zcash/crash/android/internal/local/AndroidUncaughtExceptionHan...

51 lines
1.9 KiB
Kotlin

package co.electriccoin.zcash.crash.android.internal.local
import android.content.Context
import android.os.Looper
import androidx.annotation.MainThread
import co.electriccoin.zcash.crash.ReportableException
import co.electriccoin.zcash.crash.android.R
import kotlinx.coroutines.runBlocking
import java.util.concurrent.atomic.AtomicBoolean
internal class AndroidUncaughtExceptionHandler(
context: Context,
private val defaultUncaughtExceptionHandler: Thread.UncaughtExceptionHandler
) : Thread.UncaughtExceptionHandler {
private val applicationContext = context.applicationContext
override fun uncaughtException(t: Thread, e: Throwable) {
val reportableException = ReportableException.new(applicationContext, e, true)
val isUseSecondaryProcess = applicationContext.resources
.getBoolean(R.bool.co_electriccoin_zcash_crash_is_use_secondary_process)
if (isUseSecondaryProcess) {
applicationContext.sendBroadcast(ExceptionReceiver.newIntent(applicationContext, reportableException))
} else {
runBlocking { AndroidExceptionReporter.reportException(applicationContext, reportableException) }
}
defaultUncaughtExceptionHandler.uncaughtException(t, e)
}
companion object {
private val isInitialized = AtomicBoolean(false)
/**
* Call to register writing uncaught exceptions to external storage.
*/
@MainThread
internal fun register(context: Context) {
check(Looper.myLooper() == Looper.getMainLooper()) { "Must be called from the main thread" }
check(!isInitialized.getAndSet(true)) { "Uncaught exception handler can only be set once" }
Thread.getDefaultUncaughtExceptionHandler()?.let { previous ->
Thread.setDefaultUncaughtExceptionHandler(AndroidUncaughtExceptionHandler(context, previous))
}
}
}
}