tweaks to loading

also fix crash reporting

Signed-off-by: androidacy-user <opensource@androidacy.com>
pull/89/head
androidacy-user 2 years ago
parent f5874a9b1c
commit c42c2a2d33

@ -53,7 +53,11 @@ class CrashHandler : FoxActivity() {
} }
// force sentry to send all events // force sentry to send all events
Sentry.flush(2000) Sentry.flush(2000)
val lastEventId = MainApplication.getSharedPreferences("sentry")?.getString("lastEventId", "") var lastEventId = intent.getStringExtra("lastEventId")
// if event id is all zeros, set it to "". test this by matching the regex ^0+$ (all zeros)
if (lastEventId?.matches("^0+$".toRegex()) == true) {
lastEventId = ""
}
Timber.d( Timber.d(
"CrashHandler.onCreate: lastEventId=%s, crashReportingEnabled=%s", "CrashHandler.onCreate: lastEventId=%s, crashReportingEnabled=%s",
lastEventId, lastEventId,
@ -65,9 +69,11 @@ class CrashHandler : FoxActivity() {
val email = findViewById<EditText>(R.id.feedback_email) val email = findViewById<EditText>(R.id.feedback_email)
val description = findViewById<EditText>(R.id.feedback_message) val description = findViewById<EditText>(R.id.feedback_message)
val submit = findViewById<View>(R.id.feedback_submit) val submit = findViewById<View>(R.id.feedback_submit)
if (lastEventId == "" && crashReportingEnabled) { if (lastEventId.isNullOrEmpty() && crashReportingEnabled) {
// if lastEventId is null, hide the feedback button // if lastEventId is null, hide the feedback button
Timber.d("CrashHandler.onCreate: lastEventId is null but crash reporting is enabled. This may indicate a bug in the crash reporting system.") Timber.d("CrashHandler.onCreate: lastEventId is null but crash reporting is enabled. This may indicate a bug in the crash reporting system.")
submit.visibility = View.GONE
findViewById<MaterialTextView>(R.id.feedback_text).setText(R.string.no_sentry_id)
} else { } else {
// if lastEventId is not null, enable the feedback name, email, message, and submit button // if lastEventId is not null, enable the feedback name, email, message, and submit button
email.isEnabled = true email.isEnabled = true
@ -135,7 +141,7 @@ class CrashHandler : FoxActivity() {
finish() finish()
startActivity(packageManager.getLaunchIntentForPackage(packageName)) startActivity(packageManager.getLaunchIntentForPackage(packageName))
} }
} else { } else if (!crashReportingEnabled) {
// set feedback_text to "Crash reporting is disabled" // set feedback_text to "Crash reporting is disabled"
(findViewById<View>(R.id.feedback_text) as MaterialTextView).setText(R.string.sentry_enable_nag) (findViewById<View>(R.id.feedback_text) as MaterialTextView).setText(R.string.sentry_enable_nag)
submit.setOnClickListener { _: View? -> submit.setOnClickListener { _: View? ->

@ -54,7 +54,6 @@ import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Random import java.util.Random
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.max
@Suppress("unused", "MemberVisibilityCanBePrivate") @Suppress("unused", "MemberVisibilityCanBePrivate")
class MainApplication : FoxApplication(), Configuration.Provider { class MainApplication : FoxApplication(), Configuration.Provider {
@ -129,7 +128,7 @@ class MainApplication : FoxApplication(), Configuration.Provider {
markwonThemeContext = FoxThemeWrapper(this, managerThemeResId) markwonThemeContext = FoxThemeWrapper(this, managerThemeResId)
contextThemeWrapper = markwonThemeContext contextThemeWrapper = markwonThemeContext
} }
val markwon = this.markwon =
Markwon.builder(contextThemeWrapper!!).usePlugin(HtmlPlugin.create()).usePlugin( Markwon.builder(contextThemeWrapper!!).usePlugin(HtmlPlugin.create()).usePlugin(
ImagesPlugin.create().addSchemeHandler( ImagesPlugin.create().addSchemeHandler(
OkHttpNetworkSchemeHandler.create( OkHttpNetworkSchemeHandler.create(
@ -337,6 +336,7 @@ class MainApplication : FoxApplication(), Configuration.Provider {
Timber.w("ANDROIDACY_CLIENT_ID is empty, disabling AndroidacyRepoData 1") Timber.w("ANDROIDACY_CLIENT_ID is empty, disabling AndroidacyRepoData 1")
editor.apply() editor.apply()
} }
getMarkwon()
} }
private val intent: Intent? private val intent: Intent?
@ -538,44 +538,12 @@ class MainApplication : FoxApplication(), Configuration.Provider {
val mContext: Context? = INSTANCE val mContext: Context? = INSTANCE
name += "x" name += "x"
if (mSharedPrefs == null) { if (mSharedPrefs == null) {
Timber.d("Creating shared prefs map")
mSharedPrefs = HashMap() mSharedPrefs = HashMap()
} }
/*
this part is only here because with added encryption, parts of code that were previously calling this over and over again or on each invocation of a method are causing performance issues.
*/
if (BuildConfig.DEBUG) {
// get file, function, and line number
val stackTrace = Thread.currentThread().stackTrace
// get the caller of this method
val caller = stackTrace[3]
Timber.d(
"Shared prefs file: %s, caller: %s:%d in %s",
name,
caller.fileName,
caller.lineNumber,
caller.methodName
)
// add the caller to an array. if the last 3 callers are the same, then we are in a loop, log at error level
callers.add(name + ":" + caller.lineNumber + ":" + caller.methodName)
// get the last 3 callers
val last3: List<String> = callers.subList(max(callers.size - 3, 0), callers.size)
// if the last 3 callers are the same, then we are in a loop, log at error level
if (((last3.size == 3) && last3[0] == last3[1]) && last3[1] == last3[2]) {
Timber.e(
"Shared prefs loop detected. File: %s, caller: %s:%d",
name,
caller.methodName,
caller.lineNumber
)
}
}
if (mSharedPrefs!!.containsKey(name)) { if (mSharedPrefs!!.containsKey(name)) {
Timber.d("Returning cached shared prefs")
return mSharedPrefs!![name] as SharedPreferences? return mSharedPrefs!![name] as SharedPreferences?
} }
return try { return try {
Timber.d("Creating encrypted shared prefs")
val masterKey = val masterKey =
MasterKey.Builder(mContext!!).setKeyScheme(MasterKey.KeyScheme.AES256_GCM) MasterKey.Builder(mContext!!).setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build() .build()
@ -594,6 +562,10 @@ class MainApplication : FoxApplication(), Configuration.Provider {
} }
} }
fun clearCachedSharedPrefs() {
mSharedPrefs = null
}
fun checkSecret(intent: Intent?): Boolean { fun checkSecret(intent: Intent?): Boolean {
return intent != null && intent.getLongExtra("secret", secret.inv()) == secret return intent != null && intent.getLongExtra("secret", secret.inv()) == secret
} }

@ -108,7 +108,7 @@ class MarkdownActivity : FoxActivity() {
Timber.i("Done!") Timber.i("Done!")
runOnUiThread { runOnUiThread {
footer?.minimumHeight = this.navigationBarHeight footer?.minimumHeight = this.navigationBarHeight
MainApplication.INSTANCE!!.markwon!!.setMarkdown( MainApplication.INSTANCE!!.markwon?.setMarkdown(
textView, textView,
MarkdownUrlLinker.urlLinkify(markdown) MarkdownUrlLinker.urlLinkify(markdown)
) )

@ -207,7 +207,10 @@ class RepoManager private constructor(mainApplication: MainApplication) : SyncMa
Timber.e(e) Timber.e(e)
} }
updatedModules++ updatedModules++
updateListener.update(STEP1 + STEP2 / (if (moduleToUpdate != 0) moduleToUpdate else 1) * updatedModules) // update the update listener with step1 + computed step 2 (which is updated modules / total modules / total repos)
updateListener.update(
STEP1 + (STEP2 / (moduleToUpdate / updatedModules) / repoDatas.size)
)
} }
for (repoModule in repoUpdaters[i]!!.toApply()!!) { for (repoModule in repoUpdaters[i]!!.toApply()!!) {
if (repoModule.moduleInfo.flags and ModuleInfo.FLAG_METADATA_INVALID == 0) { if (repoModule.moduleInfo.flags and ModuleInfo.FLAG_METADATA_INVALID == 0) {
@ -268,11 +271,11 @@ class RepoManager private constructor(mainApplication: MainApplication) : SyncMa
} }
repoLastErrorName = repoUpdaters[i]!!.repoData.name repoLastErrorName = repoUpdaters[i]!!.repoData.name
} }
updateListener.update(STEP1 + STEP2 + STEP3 / repoDatas.size * (i + 1)) updateListener.update(STEP1 + (STEP2 * (i / repoUpdaters.size)))
} }
} }
Timber.i("Got " + modules.size + " modules!") Timber.i("Got " + modules.size + " modules!")
updateListener.update(1.0) updateListener.update(STEP1 + STEP2 + STEP3)
} }
fun updateEnabledStates() { fun updateEnabledStates() {

@ -29,6 +29,7 @@ import com.fox2code.mmm.installer.InstallerInitializer.Companion.peekMagiskPath
import com.fox2code.mmm.installer.InstallerInitializer.Companion.peekMagiskVersion import com.fox2code.mmm.installer.InstallerInitializer.Companion.peekMagiskVersion
import com.fox2code.mmm.utils.io.Files.Companion.makeBuffer import com.fox2code.mmm.utils.io.Files.Companion.makeBuffer
import com.google.net.cronet.okhttptransport.CronetInterceptor import com.google.net.cronet.okhttptransport.CronetInterceptor
import io.sentry.android.okhttp.SentryOkHttpInterceptor
import okhttp3.Cache import okhttp3.Cache
import okhttp3.Dns import okhttp3.Dns
import okhttp3.HttpUrl.* import okhttp3.HttpUrl.*
@ -351,6 +352,9 @@ enum class Http {;
httpclientBuilder.addInterceptor(loggingInterceptor) httpclientBuilder.addInterceptor(loggingInterceptor)
} }
// add sentry interceptor
httpclientBuilder.addInterceptor(SentryOkHttpInterceptor())
// Add cronet interceptor // Add cronet interceptor
// init cronet // init cronet
try { try {

@ -5,7 +5,6 @@
package com.fox2code.mmm.utils.sentry package com.fox2code.mmm.utils.sentry
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.net.Uri import android.net.Uri
@ -25,6 +24,7 @@ import io.sentry.android.core.SentryAndroid
import io.sentry.android.core.SentryAndroidOptions import io.sentry.android.core.SentryAndroidOptions
import io.sentry.android.fragment.FragmentLifecycleIntegration import io.sentry.android.fragment.FragmentLifecycleIntegration
import io.sentry.android.timber.SentryTimberIntegration import io.sentry.android.timber.SentryTimberIntegration
import io.sentry.protocol.SentryId
import org.matomo.sdk.extra.TrackHelper import org.matomo.sdk.extra.TrackHelper
import timber.log.Timber import timber.log.Timber
@ -32,6 +32,7 @@ object SentryMain {
const val IS_SENTRY_INSTALLED = true const val IS_SENTRY_INSTALLED = true
private var isCrashing = false private var isCrashing = false
private var isSentryEnabled = false private var isSentryEnabled = false
private var crashExceptionId: SentryId? = null
/** /**
* Initialize Sentry * Initialize Sentry
@ -42,6 +43,7 @@ object SentryMain {
fun initialize(mainApplication: MainApplication) { fun initialize(mainApplication: MainApplication) {
Thread.setDefaultUncaughtExceptionHandler { _: Thread?, throwable: Throwable -> Thread.setDefaultUncaughtExceptionHandler { _: Thread?, throwable: Throwable ->
isCrashing = true isCrashing = true
MainApplication.clearCachedSharedPrefs()
TrackHelper.track().exception(throwable).with(MainApplication.INSTANCE!!.tracker) TrackHelper.track().exception(throwable).with(MainApplication.INSTANCE!!.tracker)
// open crash handler and exit // open crash handler and exit
val intent = Intent(mainApplication, CrashHandler::class.java) val intent = Intent(mainApplication, CrashHandler::class.java)
@ -55,6 +57,12 @@ object SentryMain {
intent.putExtra("crashReportingEnabled", isSentryEnabled) intent.putExtra("crashReportingEnabled", isSentryEnabled)
// add isCrashing to intent // add isCrashing to intent
intent.putExtra("isCrashing", isCrashing) intent.putExtra("isCrashing", isCrashing)
// add crashExceptionId to intent
if (crashExceptionId != null) {
intent.putExtra("lastEventId", crashExceptionId!!.toString())
} else {
intent.putExtra("lastEventId", "")
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
Timber.e("Starting crash handler") Timber.e("Starting crash handler")
mainApplication.startActivity(intent) mainApplication.startActivity(intent)
@ -119,15 +127,7 @@ object SentryMain {
if (!isSentryEnabled) { if (!isSentryEnabled) {
return@BeforeSendCallback null return@BeforeSendCallback null
} }
// store eventid in prefs crashExceptionId = event?.eventId
val editor =
MainApplication.INSTANCE!!.getSharedPreferences(
"sentry",
Context.MODE_PRIVATE
)
.edit()
editor.putString("lastEventId", event!!.eventId.toString())
editor.commit() // commit so we immediately cache if crashing
event event
} }
// Filter breadcrumb content from crash report. // Filter breadcrumb content from crash report.

@ -387,4 +387,5 @@
<string name="error_opening_notes">Error in opening module notes. Logs may have the reason.</string> <string name="error_opening_notes">Error in opening module notes. Logs may have the reason.</string>
<string name="submit_feedback">Submit feedback</string> <string name="submit_feedback">Submit feedback</string>
<string name="ssl_error">Potential SSL interception detected.</string> <string name="ssl_error">Potential SSL interception detected.</string>
<string name="no_sentry_id">Unable to sumbit feedback - no event ID from Sentry. The last event may not have sent.</string>
</resources> </resources>

Loading…
Cancel
Save