diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d8a8e0e..edf6188 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -48,6 +48,8 @@
+
+
+ if (uri == null) {
+ Timber.d("invalid uri received")
+ callback?.onReceived(destination, null, IntentHelper.RESPONSE_ERROR)
+ return@registerForActivityResult
+ }
+ if (MainApplication.forceDebugLogging) Timber.i("FilePicker returned %s", uri)
+ if ("http" == uri.scheme || "https" == uri.scheme) {
+ callback?.onReceived(destination, uri, IntentHelper.RESPONSE_URL)
+ return@registerForActivityResult
+ }
+ if (ContentResolver.SCHEME_FILE == uri.scheme) {
+ Toast.makeText(
+ this@MainActivity, R.string.file_picker_wierd, Toast.LENGTH_SHORT
+ ).show()
+ }
+ var inputStream: InputStream? = null
+ var outputStream: OutputStream? = null
+ var success = false
+ try {
+ if (ContentResolver.SCHEME_FILE == uri.scheme) {
+ var path = uri.path
+ if (path!!.startsWith("/sdcard/")) { // Fix file paths
+ path =
+ Environment.getExternalStorageDirectory().absolutePath + path.substring(
+ 7
+ )
+ }
+ inputStream = SuFileInputStream.open(
+ File(path).absoluteFile
+ )
+ } else {
+ inputStream = this.contentResolver.openInputStream(uri)
+ }
+ // check if the file is a zip
+ if (inputStream == null) {
+ Toast.makeText(
+ this@MainActivity, R.string.file_picker_failure, Toast.LENGTH_SHORT
+ ).show()
+ callback?.onReceived(
+ destination,
+ uri,
+ IntentHelper.RESPONSE_ERROR
+ )
+ return@registerForActivityResult
+ }
+ // check if the file is a zip by reading the first 4 bytes
+ val bytes = ByteArray(4)
+ inputStream.read(bytes, 0, 4)
+ if (!(bytes[0] == 0x50.toByte() && bytes[1] == 0x4B.toByte() && bytes[2] == 0x03.toByte() && bytes[3] == 0x04.toByte())) {
+ Toast.makeText(
+ this@MainActivity, R.string.file_picker_not_zip, Toast.LENGTH_SHORT
+ ).show()
+ Timber.e("File is not a zip! Expected 0x504B0304, got %02X%02X%02X%02X", bytes[0], bytes[1], bytes[2], bytes[3])
+ callback?.onReceived(
+ destination,
+ uri,
+ IntentHelper.RESPONSE_ERROR
+ )
+ return@registerForActivityResult
+ }
+ outputStream = FileOutputStream(destination)
+ Files.copy(inputStream, outputStream)
+ if (MainApplication.forceDebugLogging) Timber.i("File saved at %s", destination)
+ success = true
+ } catch (e: Exception) {
+ Timber.e(e)
+ Toast.makeText(
+ this@MainActivity, R.string.file_picker_failure, Toast.LENGTH_SHORT
+ ).show()
+ } finally {
+ Files.closeSilently(inputStream)
+ Files.closeSilently(outputStream)
+ if (!success && destination?.exists() == true && !destination!!.delete()) Timber.e("Failed to delete artifact!")
+ }
+ callback?.onReceived(
+ destination,
+ uri,
+ if (success) IntentHelper.RESPONSE_FILE else IntentHelper.RESPONSE_ERROR
+ )
+ }
init {
moduleViewListBuilder.addNotification(NotificationType.INSTALL_FROM_STORAGE)
@@ -246,7 +346,10 @@ class MainActivity : AppCompatActivity(), OnRefreshListener, OverScrollHelper {
} as Map?, 1)
Thread {
if (moduleViewListBuilder.setQueryChange(query)) {
- Timber.i("Query submit: %s on offline list", query)
+ if (MainApplication.forceDebugLogging) Timber.i(
+ "Query submit: %s on offline list",
+ query
+ )
Thread(
{ moduleViewListBuilder.applyTo(moduleList!!, moduleViewAdapter!!) },
"Query update thread"
@@ -254,7 +357,10 @@ class MainActivity : AppCompatActivity(), OnRefreshListener, OverScrollHelper {
}
// same for online list
if (moduleViewListBuilderOnline.setQueryChange(query)) {
- Timber.i("Query submit: %s on online list", query)
+ if (MainApplication.forceDebugLogging) Timber.i(
+ "Query submit: %s on online list",
+ query
+ )
Thread({
moduleViewListBuilderOnline.applyTo(
moduleListOnline!!, moduleViewAdapterOnline!!
@@ -275,7 +381,10 @@ class MainActivity : AppCompatActivity(), OnRefreshListener, OverScrollHelper {
} as Map?, 1)
Thread {
if (moduleViewListBuilder.setQueryChange(query)) {
- Timber.i("Query submit: %s on offline list", query)
+ if (MainApplication.forceDebugLogging) Timber.i(
+ "Query submit: %s on offline list",
+ query
+ )
Thread(
{ moduleViewListBuilder.applyTo(moduleList!!, moduleViewAdapter!!) },
"Query update thread"
@@ -283,7 +392,10 @@ class MainActivity : AppCompatActivity(), OnRefreshListener, OverScrollHelper {
}
// same for online list
if (moduleViewListBuilderOnline.setQueryChange(query)) {
- Timber.i("Query submit: %s on online list", query)
+ if (MainApplication.forceDebugLogging) Timber.i(
+ "Query submit: %s on online list",
+ query
+ )
Thread({
moduleViewListBuilderOnline.applyTo(
moduleListOnline!!, moduleViewAdapterOnline!!
@@ -478,7 +590,7 @@ class MainActivity : AppCompatActivity(), OnRefreshListener, OverScrollHelper {
MainApplication.INSTANCE!!.resetUpdateModule()
tryGetMagiskPathAsync(object : InstallerInitializer.Callback {
override fun onPathReceived(path: String?) {
- Timber.i("Got magisk path: %s", path)
+ if (MainApplication.forceDebugLogging) Timber.i("Got magisk path: %s", path)
if (peekMagiskVersion() < Constants.MAGISK_VER_CODE_INSTALL_COMMAND) {
if (!InstallerInitializer.isKsu) {
moduleViewListBuilder.addNotification(
@@ -508,14 +620,14 @@ class MainActivity : AppCompatActivity(), OnRefreshListener, OverScrollHelper {
fun commonNext() {
if (BuildConfig.DEBUG) {
- if (BuildConfig.DEBUG) Timber.d("Common next")
+ if (MainApplication.forceDebugLogging) Timber.d("Common next")
moduleViewListBuilder.addNotification(NotificationType.DEBUG)
}
NotificationType.NO_INTERNET.autoAdd(moduleViewListBuilderOnline)
val progressIndicator = progressIndicator!!
// hide progress bar is repo-manager says we have no internet
if (!RepoManager.getINSTANCE()!!.hasConnectivity()) {
- Timber.i("No connection, hiding progress")
+ if (MainApplication.forceDebugLogging) Timber.i("No connection, hiding progress")
runOnUiThread {
progressIndicator.visibility = View.GONE
progressIndicator.isIndeterminate = false
@@ -524,7 +636,7 @@ class MainActivity : AppCompatActivity(), OnRefreshListener, OverScrollHelper {
}
val context: Context = this@MainActivity
if (runtimeUtils!!.waitInitialSetupFinished(context, this@MainActivity)) {
- if (BuildConfig.DEBUG) Timber.d("waiting...")
+ if (MainApplication.forceDebugLogging) Timber.d("waiting...")
return
}
swipeRefreshBlocker = System.currentTimeMillis() + 5000L
@@ -541,8 +653,8 @@ class MainActivity : AppCompatActivity(), OnRefreshListener, OverScrollHelper {
}
}
moduleViewListBuilder.applyTo(moduleList, moduleViewAdapter!!)
- Timber.i("Scanning for modules!")
- if (BuildConfig.DEBUG) Timber.i("Initialize Update")
+ if (MainApplication.forceDebugLogging) Timber.i("Scanning for modules!")
+ if (MainApplication.forceDebugLogging) Timber.i("Initialize Update")
val max = instance!!.getUpdatableModuleCount()
if (RepoManager.getINSTANCE()!!.customRepoManager != null && RepoManager.getINSTANCE()!!.customRepoManager!!.needUpdate()) {
Timber.w("Need update on create")
@@ -550,9 +662,9 @@ class MainActivity : AppCompatActivity(), OnRefreshListener, OverScrollHelper {
Timber.w("CustomRepoManager is null")
}
// update compat metadata
- if (BuildConfig.DEBUG) Timber.i("Check Update Compat")
+ if (MainApplication.forceDebugLogging) Timber.i("Check Update Compat")
appUpdateManager.checkUpdateCompat()
- if (BuildConfig.DEBUG) Timber.i("Check Update")
+ if (MainApplication.forceDebugLogging) Timber.i("Check Update")
// update repos
if (hasWebView()) {
val updateListener: SyncManager.UpdateListener =
@@ -588,11 +700,11 @@ class MainActivity : AppCompatActivity(), OnRefreshListener, OverScrollHelper {
}
// Compatibility data still needs to be updated
val appUpdateManager = appUpdateManager
- if (BuildConfig.DEBUG) Timber.i("Check App Update")
+ if (MainApplication.forceDebugLogging) Timber.i("Check App Update")
if (BuildConfig.ENABLE_AUTO_UPDATER && appUpdateManager.checkUpdate(true)) moduleViewListBuilder.addNotification(
NotificationType.UPDATE_AVAILABLE
)
- if (BuildConfig.DEBUG) Timber.i("Check Json Update")
+ if (MainApplication.forceDebugLogging) Timber.i("Check Json Update")
if (max != 0) {
var current = 0
for (localModuleInfo in instance!!.modules.values) {
@@ -601,7 +713,7 @@ class MainActivity : AppCompatActivity(), OnRefreshListener, OverScrollHelper {
// the reasoning is that remote repos are considered "validated" while local modules are not
// for instance, a potential attacker could hijack a perfectly legitimate module and inject an updateJson with a malicious update - thereby bypassing any checks repos may have, without anyone noticing until it's too late
if (localModuleInfo.updateJson != null && localModuleInfo.flags and ModuleInfo.FLAG_MM_REMOTE_MODULE == 0) {
- if (BuildConfig.DEBUG) Timber.i(localModuleInfo.id)
+ if (MainApplication.forceDebugLogging) Timber.i(localModuleInfo.id)
try {
localModuleInfo.checkModuleUpdate()
} catch (e: Exception) {
@@ -618,7 +730,7 @@ class MainActivity : AppCompatActivity(), OnRefreshListener, OverScrollHelper {
}
}
}
- if (BuildConfig.DEBUG) Timber.i("Apply")
+ if (MainApplication.forceDebugLogging) Timber.i("Apply")
RepoManager.getINSTANCE()
?.runAfterUpdate { moduleViewListBuilderOnline.appendRemoteModules() }
moduleViewListBuilder.applyTo(moduleList, moduleViewAdapter!!)
@@ -626,13 +738,13 @@ class MainActivity : AppCompatActivity(), OnRefreshListener, OverScrollHelper {
moduleViewListBuilderOnline.applyTo(moduleListOnline, moduleViewAdapterOnline!!)
// if moduleViewListBuilderOnline has the upgradeable notification, show a badge on the online repo nav item
if (MainApplication.INSTANCE!!.modulesHaveUpdates) {
- Timber.i("Applying badge")
+ if (MainApplication.forceDebugLogging) Timber.i("Applying badge")
Handler(Looper.getMainLooper()).post {
val badge = bottomNavigationView.getOrCreateBadge(R.id.online_menu_item)
badge.isVisible = true
badge.number = MainApplication.INSTANCE!!.updateModuleCount
badge.applyTheme(MainApplication.INSTANCE!!.theme)
- Timber.i("Badge applied")
+ if (MainApplication.forceDebugLogging) Timber.i("Badge applied")
}
}
runOnUiThread {
@@ -640,7 +752,7 @@ class MainActivity : AppCompatActivity(), OnRefreshListener, OverScrollHelper {
progressIndicator.visibility = View.GONE
}
maybeShowUpgrade()
- Timber.i("Finished app opening state!")
+ if (MainApplication.forceDebugLogging) Timber.i("Finished app opening state!")
}
}, true)
// if system lang is not in MainApplication.supportedLocales, show a snackbar to ask user to help translate
@@ -660,16 +772,19 @@ class MainActivity : AppCompatActivity(), OnRefreshListener, OverScrollHelper {
Handler(Looper.getMainLooper()).postDelayed({
showFeedback()
}, 5000)
- Timber.i("Should show feedback")
+ if (MainApplication.forceDebugLogging) Timber.i("Should show feedback")
} else {
- Timber.i("Should not show feedback")
+ if (MainApplication.forceDebugLogging) Timber.i("Should not show feedback")
}
}
private fun showFeedback() {
Countly.sharedInstance().feedback()
.getAvailableFeedbackWidgets { retrievedWidgets, error ->
- Timber.i("Got feedback widgets: %s", retrievedWidgets.size)
+ if (MainApplication.forceDebugLogging) Timber.i(
+ "Got feedback widgets: %s",
+ retrievedWidgets.size
+ )
if (error == null) {
if (retrievedWidgets.size > 0) {
val feedbackWidget = retrievedWidgets[0]
@@ -730,7 +845,7 @@ class MainActivity : AppCompatActivity(), OnRefreshListener, OverScrollHelper {
swipeRefreshLayout!!.isRefreshing = false
return // Do not double scan
}
- if (BuildConfig.DEBUG) Timber.i("Refresh")
+ if (MainApplication.forceDebugLogging) Timber.i("Refresh")
progressIndicator!!.visibility = View.VISIBLE
progressIndicator!!.setProgressCompat(0, false)
swipeRefreshBlocker = System.currentTimeMillis() + 5000L
@@ -764,16 +879,16 @@ class MainActivity : AppCompatActivity(), OnRefreshListener, OverScrollHelper {
} else {
// Compatibility data still needs to be updated
val appUpdateManager = appUpdateManager
- if (BuildConfig.DEBUG) Timber.i("Check App Update")
+ if (MainApplication.forceDebugLogging) Timber.i("Check App Update")
if (BuildConfig.ENABLE_AUTO_UPDATER && appUpdateManager.checkUpdate(true)) moduleViewListBuilder.addNotification(
NotificationType.UPDATE_AVAILABLE
)
- if (BuildConfig.DEBUG) Timber.i("Check Json Update")
+ if (MainApplication.forceDebugLogging) Timber.i("Check Json Update")
if (max != 0) {
var current = 0
for (localModuleInfo in instance!!.modules.values) {
if (localModuleInfo.updateJson != null && localModuleInfo.flags and ModuleInfo.FLAG_MM_REMOTE_MODULE == 0) {
- if (BuildConfig.DEBUG) Timber.i(localModuleInfo.id)
+ if (MainApplication.forceDebugLogging) Timber.i(localModuleInfo.id)
try {
localModuleInfo.checkModuleUpdate()
} catch (e: Exception) {
@@ -790,7 +905,7 @@ class MainActivity : AppCompatActivity(), OnRefreshListener, OverScrollHelper {
}
}
}
- if (BuildConfig.DEBUG) Timber.i("Apply")
+ if (MainApplication.forceDebugLogging) Timber.i("Apply")
runOnUiThread {
progressIndicator!!.visibility = View.GONE
swipeRefreshLayout!!.isRefreshing = false
@@ -811,7 +926,7 @@ class MainActivity : AppCompatActivity(), OnRefreshListener, OverScrollHelper {
// wait for up to 10 seconds for AndroidacyRepoData to be initialized
var i: Int
if (AndroidacyRepoData.instance.isEnabled && AndroidacyRepoData.instance.memberLevel == null) {
- if (BuildConfig.DEBUG) Timber.d("Member level is null, waiting for it to be initialized")
+ if (MainApplication.forceDebugLogging) Timber.d("Member level is null, waiting for it to be initialized")
i = 0
while (AndroidacyRepoData.instance.memberLevel == null && i < 20) {
i++
@@ -830,28 +945,28 @@ class MainActivity : AppCompatActivity(), OnRefreshListener, OverScrollHelper {
runtimeUtils!!.showUpgradeSnackbar(this, this)
} else {
if (!AndroidacyRepoData.instance.isEnabled) {
- Timber.i("AndroidacyRepoData is disabled, not showing upgrade snackbar 1")
+ if (MainApplication.forceDebugLogging) Timber.i("AndroidacyRepoData is disabled, not showing upgrade snackbar 1")
} else if (AndroidacyRepoData.instance.memberLevel != "Guest") {
- Timber.i(
+ if (MainApplication.forceDebugLogging) Timber.i(
"AndroidacyRepoData is not Guest, not showing upgrade snackbar 1. Level: %s",
AndroidacyRepoData.instance.memberLevel
)
} else {
- Timber.i("Unknown error, not showing upgrade snackbar 1")
+ if (MainApplication.forceDebugLogging) Timber.i("Unknown error, not showing upgrade snackbar 1")
}
}
} else if (AndroidacyRepoData.instance.isEnabled && AndroidacyRepoData.instance.memberLevel == "Guest") {
runtimeUtils!!.showUpgradeSnackbar(this, this)
} else {
if (!AndroidacyRepoData.instance.isEnabled) {
- Timber.i("AndroidacyRepoData is disabled, not showing upgrade snackbar 2")
+ if (MainApplication.forceDebugLogging) Timber.i("AndroidacyRepoData is disabled, not showing upgrade snackbar 2")
} else if (AndroidacyRepoData.instance.memberLevel != "Guest") {
- Timber.i(
+ if (MainApplication.forceDebugLogging) Timber.i(
"AndroidacyRepoData is not Guest, not showing upgrade snackbar 2. Level: %s",
AndroidacyRepoData.instance.memberLevel
)
} else {
- Timber.i("Unknown error, not showing upgrade snackbar 2")
+ if (MainApplication.forceDebugLogging) Timber.i("Unknown error, not showing upgrade snackbar 2")
}
}
}
diff --git a/app/src/main/kotlin/com/fox2code/mmm/MainApplication.kt b/app/src/main/kotlin/com/fox2code/mmm/MainApplication.kt
index 094cc56..310e869 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/MainApplication.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/MainApplication.kt
@@ -250,6 +250,18 @@ class MainApplication : Application(), Configuration.Provider, ActivityLifecycle
if (INSTANCE == null) INSTANCE = this
relPackageName = this.packageName
super.onCreate()
+ var output = Shell.cmd("echo $(id -u)").exec().out[0]
+ if (output != null) {
+ output = output.trim { it <= ' ' }
+ if (forceDebugLogging) Timber.d("UID: %s", output)
+ if (output == "0") {
+ if (forceDebugLogging) Timber.d("Root access granted")
+ setHasGottenRootAccess(true)
+ } else {
+ if (forceDebugLogging) Timber.d("Root access or we're not uid 0. Current uid: %s", output)
+ setHasGottenRootAccess(false)
+ }
+ }
if (!callbacksRegistered) {
try {
registerActivityLifecycleCallbacks(this)
@@ -260,7 +272,7 @@ class MainApplication : Application(), Configuration.Provider, ActivityLifecycle
}
// Initialize Timber
configTimber()
- Timber.i(
+ if (forceDebugLogging) Timber.i(
"Starting AMM version %s (%d) - commit %s",
BuildConfig.VERSION_NAME,
BuildConfig.VERSION_CODE,
@@ -275,13 +287,13 @@ class MainApplication : Application(), Configuration.Provider, ActivityLifecycle
fileUtils.ensureCacheDirs()
fileUtils.ensureURLHandler(this)
}
- if (BuildConfig.DEBUG) Timber.d("Initializing AMM")
- if (BuildConfig.DEBUG) Timber.d("Started from background: %s", !isInForeground)
- if (BuildConfig.DEBUG) Timber.d("AMM is running in debug mode")
+ if (forceDebugLogging) Timber.d("Initializing AMM")
+ if (forceDebugLogging) Timber.d("Started from background: %s", !isInForeground)
+ if (forceDebugLogging) Timber.d("AMM is running in debug mode")
// analytics
- if (BuildConfig.DEBUG) Timber.d("Initializing countly")
+ if (forceDebugLogging) Timber.d("Initializing countly")
if (!analyticsAllowed()) {
- if (BuildConfig.DEBUG) Timber.d("countly is not allowed")
+ if (forceDebugLogging) Timber.d("countly is not allowed")
} else {
val config = CountlyConfig(
this,
@@ -344,9 +356,9 @@ class MainApplication : Application(), Configuration.Provider, ActivityLifecycle
fontRequestEmojiCompatConfig.setMetadataLoadStrategy(EmojiCompat.LOAD_STRATEGY_MANUAL)
val emojiCompat = EmojiCompat.init(fontRequestEmojiCompatConfig)
Thread({
- Timber.i("Loading emoji compat...")
+ if (forceDebugLogging) Timber.i("Loading emoji compat...")
emojiCompat.load()
- Timber.i("Emoji compat loaded!")
+ if (forceDebugLogging) Timber.i("Emoji compat loaded!")
}, "Emoji compat init.").start()
}
@Suppress("KotlinConstantConditions") if ((BuildConfig.ANDROIDACY_CLIENT_ID == "")) {
@@ -386,7 +398,7 @@ class MainApplication : Application(), Configuration.Provider, ActivityLifecycle
// make sure the directory exists
if (!dataDir.exists()) {
if (!dataDir.mkdirs()) {
- if (BuildConfig.DEBUG) Timber.w(
+ if (forceDebugLogging) Timber.w(
"Failed to create directory %s", dataDir
)
}
@@ -397,7 +409,7 @@ class MainApplication : Application(), Configuration.Provider, ActivityLifecycle
// create the directory if it doesn't exist
if (!dataDir.exists()) {
if (!dataDir.mkdirs()) {
- if (BuildConfig.DEBUG) Timber.w("Failed to create directory %s", dataDir)
+ if (forceDebugLogging) Timber.w("Failed to create directory %s", dataDir)
}
}
}
@@ -422,12 +434,12 @@ class MainApplication : Application(), Configuration.Provider, ActivityLifecycle
val activityManager = this.getSystemService(ACTIVITY_SERVICE) as ActivityManager
val appProcesses = activityManager.runningAppProcesses
if (appProcesses == null) {
- if (BuildConfig.DEBUG) Timber.d("appProcesses is null")
+ if (forceDebugLogging) Timber.d("appProcesses is null")
return false
}
val packageName = this.packageName
for (appProcess in appProcesses) {
- if (BuildConfig.DEBUG) Timber.d(
+ if (forceDebugLogging) Timber.d(
"Process: %s, Importance: %d", appProcess.processName, appProcess.importance
)
if (appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName == packageName) {
@@ -456,6 +468,7 @@ class MainApplication : Application(), Configuration.Provider, ActivityLifecycle
}
class ReleaseTree : Timber.Tree() {
+ @SuppressLint("LogNotTimber")
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
// basically silently drop all logs below error, and write the rest to logcat
@Suppress("NAME_SHADOWING") var message = message
@@ -463,12 +476,20 @@ class MainApplication : Application(), Configuration.Provider, ActivityLifecycle
// prepend [TAINTED] to the message
message = "[TAINTED] $message"
}
- if (priority >= Log.ERROR) {
- if (t != null) {
- Log.println(priority, tag, message)
- t.printStackTrace()
- } else {
- Log.println(priority, tag, message)
+ if (forceDebugLogging) {
+ if (priority >= Log.DEBUG) {
+ when(priority) {
+ Log.DEBUG -> Log.d(tag, message, t)
+ Log.INFO -> Log.i(tag, message, t)
+ Log.WARN -> Log.w(tag, message, t)
+ Log.ERROR -> Log.e(tag, message, t)
+ Log.ASSERT -> Log.wtf(tag, message, t)
+ }
+ t?.printStackTrace()
+ }
+ } else {
+ if (priority >= Log.ERROR) {
+ Log.e(tag, message, t)
}
}
}
@@ -476,6 +497,8 @@ class MainApplication : Application(), Configuration.Provider, ActivityLifecycle
companion object {
+ var forceDebugLogging: Boolean = BuildConfig.DEBUG || getSharedPreferences("mmm")?.getBoolean("pref_force_debug_logging", false) ?: false
+
// Warning! Locales that don't exist will crash the app
// Anything that is commented out is supported but the translation is not complete to at least 60%
@JvmField
@@ -522,7 +545,7 @@ class MainApplication : Application(), Configuration.Provider, ActivityLifecycle
}
// prewarm shell
Shell.getShell {
- // do nothing
+ if (forceDebugLogging) Timber.d("Shell prewarmed")
}
val random = Random()
do {
@@ -574,8 +597,32 @@ class MainApplication : Application(), Configuration.Provider, ActivityLifecycle
mSharedPrefs!![name] = sharedPreferences
sharedPreferences
} catch (e: Exception) {
- Timber.e(e, "Failed to create encrypted shared preferences")
- mContext!!.getSharedPreferences(name, MODE_PRIVATE)
+ // try again five times, with a 250ms delay between each try. if we still can't get the shared preferences, throw an exception
+ var i = 0
+ while (i < 5) {
+ try {
+ Thread.sleep(250)
+ } catch (ignored: InterruptedException) {
+ }
+ try {
+ val masterKey =
+ MasterKey.Builder(mContext!!).setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
+ .build()
+ val sharedPreferences = EncryptedSharedPreferences.create(
+ mContext,
+ name,
+ masterKey,
+ EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
+ EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
+ )
+ mSharedPrefs!![name] = sharedPreferences
+ return sharedPreferences
+ } catch (e: Exception) {
+ Timber.e(e, "Failed to get shared preferences")
+ }
+ i++
+ }
+ throw IllegalStateException("Failed to get shared preferences")
}
}
@@ -683,7 +730,7 @@ class MainApplication : Application(), Configuration.Provider, ActivityLifecycle
// should not have been shown in 14 days and only 1 in 5 chance
val randChance = Random().nextInt(5)
val lastShown = getSharedPreferences("mmm")!!.getLong("last_feedback", 0)
- if (BuildConfig.DEBUG) Timber.d("Last feedback shown: %d, randChance: %d", lastShown, randChance)
+ if (forceDebugLogging) Timber.d("Last feedback shown: %d, randChance: %d", lastShown, randChance)
return System.currentTimeMillis() - lastShown > 1209600000 && randChance == 0
}
}
diff --git a/app/src/main/kotlin/com/fox2code/mmm/NotificationType.kt b/app/src/main/kotlin/com/fox2code/mmm/NotificationType.kt
index f2922c0..fe4320b 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/NotificationType.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/NotificationType.kt
@@ -205,7 +205,7 @@ enum class NotificationType(
val module = File(
compatActivity.cacheDir, "installer" + File.separator + "module.zip"
)
- IntentHelper.openFileTo(compatActivity, module, object :
+ IntentHelper.openFileTo(module, object :
OnFileReceivedCallback {
override fun onReceived(
diff --git a/app/src/main/kotlin/com/fox2code/mmm/SetupActivity.kt b/app/src/main/kotlin/com/fox2code/mmm/SetupActivity.kt
index 5c1c7a0..72f95d9 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/SetupActivity.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/SetupActivity.kt
@@ -196,31 +196,31 @@ class SetupActivity : AppCompatActivity(), LanguageActivity {
// On debug builds, log when a switch is toggled
if (BuildConfig.DEBUG) {
(Objects.requireNonNull(view.findViewById(R.id.setup_background_update_check)) as MaterialSwitch).setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
- Timber.i(
+ if (MainApplication.forceDebugLogging) Timber.i(
"Automatic update Check: %s",
isChecked
)
}
setupCrashReporting.setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
- Timber.i(
+ if (MainApplication.forceDebugLogging) Timber.i(
"Crash Reporting: %s",
isChecked
)
}
(Objects.requireNonNull(view.findViewById(R.id.setup_crash_reporting_pii)) as MaterialSwitch).setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
- Timber.i(
+ if (MainApplication.forceDebugLogging) Timber.i(
"Crash Reporting PII: %s",
isChecked
)
}
(Objects.requireNonNull(view.findViewById(R.id.setup_androidacy_repo)) as MaterialSwitch).setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
- Timber.i(
+ if (MainApplication.forceDebugLogging) Timber.i(
"Androidacy Repo: %s",
isChecked
)
}
(Objects.requireNonNull(view.findViewById(R.id.setup_magisk_alt_repo)) as MaterialSwitch).setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
- Timber.i(
+ if (MainApplication.forceDebugLogging) Timber.i(
"Magisk Alt Repo: %s",
isChecked
)
@@ -301,11 +301,11 @@ class SetupActivity : AppCompatActivity(), LanguageActivity {
).show()
return@setOnClickListener
}
- Timber.i("Setup button clicked")
+ if (MainApplication.forceDebugLogging) Timber.i("Setup button clicked")
// get instance of editor
- if (BuildConfig.DEBUG) Timber.d("Saving preferences")
+ if (MainApplication.forceDebugLogging) Timber.d("Saving preferences")
val editor = prefs.edit()
- if (BuildConfig.DEBUG) Timber.d("Got editor: %s", editor)
+ if (MainApplication.forceDebugLogging) Timber.d("Got editor: %s", editor)
// Set the Automatic update check pref
editor.putBoolean(
"pref_background_update_check", (Objects.requireNonNull(
@@ -347,7 +347,7 @@ class SetupActivity : AppCompatActivity(), LanguageActivity {
)
) as MaterialSwitch).isChecked
)
- if (BuildConfig.DEBUG) Timber.d("Saving preferences")
+ if (MainApplication.forceDebugLogging) Timber.d("Saving preferences")
// now basically do the same thing for room db
val db = Room.databaseBuilder(
applicationContext,
@@ -356,7 +356,7 @@ class SetupActivity : AppCompatActivity(), LanguageActivity {
val androidacyRepoRoom = andRepoView.isChecked
val magiskAltRepoRoom = magiskAltRepoView.isChecked
val reposListDao = db.reposListDao()
- if (BuildConfig.DEBUG) Timber.d(reposListDao.getAll().toString())
+ if (MainApplication.forceDebugLogging) Timber.d(reposListDao.getAll().toString())
val androidacyRepoRoomObj = reposListDao.getById("androidacy_repo")
val magiskAltRepoRoomObj = reposListDao.getById("magisk_alt_repo")
reposListDao.setEnabled(androidacyRepoRoomObj.id, androidacyRepoRoom)
@@ -366,11 +366,11 @@ class SetupActivity : AppCompatActivity(), LanguageActivity {
// Commit the changes
editor.commit()
// Log the changes
- if (BuildConfig.DEBUG) Timber.d("Setup finished. Preferences: %s", prefs.all)
- if (BuildConfig.DEBUG) Timber.d("Androidacy repo: %s", androidacyRepoRoom)
- if (BuildConfig.DEBUG) Timber.d("Magisk Alt repo: %s", magiskAltRepoRoom)
+ if (MainApplication.forceDebugLogging) Timber.d("Setup finished. Preferences: %s", prefs.all)
+ if (MainApplication.forceDebugLogging) Timber.d("Androidacy repo: %s", androidacyRepoRoom)
+ if (MainApplication.forceDebugLogging) Timber.d("Magisk Alt repo: %s", magiskAltRepoRoom)
// log last shown setup
- if (BuildConfig.DEBUG) Timber.d("Last shown setup: %s", prefs.getString("last_shown_setup", "v0"))
+ if (MainApplication.forceDebugLogging) Timber.d("Last shown setup: %s", prefs.getString("last_shown_setup", "v0"))
// Restart the activity
MainActivity.doSetupRestarting = true
val pendingIntent = PendingIntent.getActivity(
@@ -391,7 +391,7 @@ class SetupActivity : AppCompatActivity(), LanguageActivity {
// unselect the cancel button because it's selected by default
cancelButton.isSelected = false
cancelButton.setOnClickListener { _: View? ->
- Timber.i("Cancel button clicked")
+ if (MainApplication.forceDebugLogging) Timber.i("Cancel button clicked")
// close the app
finish()
}
@@ -450,7 +450,7 @@ class SetupActivity : AppCompatActivity(), LanguageActivity {
// creates the room database
private fun createDatabases() {
val thread = Thread {
- if (BuildConfig.DEBUG) Timber.d("Creating databases")
+ if (MainApplication.forceDebugLogging) Timber.d("Creating databases")
val startTime = System.currentTimeMillis()
val appContext = MainApplication.INSTANCE!!.applicationContext
val db = Room.databaseBuilder(appContext, ReposListDatabase::class.java, "ReposList.db")
@@ -532,7 +532,7 @@ class SetupActivity : AppCompatActivity(), LanguageActivity {
).show()
}
} else {
- if (BuildConfig.DEBUG) Timber.d("ReposList is updated with 2 entries")
+ if (MainApplication.forceDebugLogging) Timber.d("ReposList is updated with 2 entries")
}
// make sure modulelistcache is updated with 1 entry
if (moduleListCacheDao.getAll().size != 1) {
@@ -546,12 +546,12 @@ class SetupActivity : AppCompatActivity(), LanguageActivity {
).show()
}
} else {
- if (BuildConfig.DEBUG) Timber.d("ModuleListCache is updated with 1 entry")
+ if (MainApplication.forceDebugLogging) Timber.d("ModuleListCache is updated with 1 entry")
}
// close the databases
db.close()
db2.close()
- if (BuildConfig.DEBUG) Timber.d("Databases created in %s ms", System.currentTimeMillis() - startTime)
+ if (MainApplication.forceDebugLogging) Timber.d("Databases created in %s ms", System.currentTimeMillis() - startTime)
}
thread.start()
}
@@ -590,7 +590,7 @@ class SetupActivity : AppCompatActivity(), LanguageActivity {
val componentName = ComponentName(this, UpdateActivity::class.java)
val componentEnabledSetting = pm.getComponentEnabledSetting(componentName)
if (componentEnabledSetting == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
- if (BuildConfig.DEBUG) Timber.d("Disabling update activity for fdroid flavor")
+ if (MainApplication.forceDebugLogging) Timber.d("Disabling update activity for fdroid flavor")
// disable update activity through package manager
pm.setComponentEnabledSetting(
componentName,
diff --git a/app/src/main/kotlin/com/fox2code/mmm/androidacy/AndroidacyActivity.kt b/app/src/main/kotlin/com/fox2code/mmm/androidacy/AndroidacyActivity.kt
index 11b296b..3371fcc 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/androidacy/AndroidacyActivity.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/androidacy/AndroidacyActivity.kt
@@ -196,7 +196,7 @@ class AndroidacyActivity : AppCompatActivity() {
// sanitize url
@Suppress("NAME_SHADOWING") var url = request.url.toString()
url = AndroidacyUtil.hideToken(url)
- Timber.i("Exiting WebView %s", url)
+ if (MainApplication.forceDebugLogging) Timber.i("Exiting WebView %s", url)
IntentHelper.openUri(view.context, request.url.toString())
return true
}
@@ -311,17 +311,17 @@ class AndroidacyActivity : AppCompatActivity() {
override fun onProgressChanged(view: WebView, newProgress: Int) {
if (downloadMode) return
if (newProgress != 100 && prgInd.visibility != View.VISIBLE) {
- Timber.i("Progress: %d, showing progress bar", newProgress)
+ if (MainApplication.forceDebugLogging) Timber.i("Progress: %d, showing progress bar", newProgress)
prgInd.visibility = View.VISIBLE
}
// if progress is greater than one, set indeterminate to false
if (newProgress > 1) {
- Timber.i("Progress: %d, setting indeterminate to false", newProgress)
+ if (MainApplication.forceDebugLogging) Timber.i("Progress: %d, setting indeterminate to false", newProgress)
prgInd.isIndeterminate = false
}
prgInd.setProgress(newProgress, true)
if (newProgress == 100 && prgInd.visibility != View.GONE) {
- Timber.i("Progress: %d, hiding progress bar", newProgress)
+ if (MainApplication.forceDebugLogging) Timber.i("Progress: %d, hiding progress bar", newProgress)
prgInd.isIndeterminate = true
prgInd.visibility = View.GONE
}
@@ -332,9 +332,9 @@ class AndroidacyActivity : AppCompatActivity() {
if (downloadMode && isDownloadUrl(downloadUrl)) {
megaIntercept(pageUrl, downloadUrl)
}
- Timber.i("Download mode is on")
+ if (MainApplication.forceDebugLogging) Timber.i("Download mode is on")
if (AndroidacyUtil.isAndroidacyLink(downloadUrl) && !backOnResume) {
- Timber.i("Androidacy link detected")
+ if (MainApplication.forceDebugLogging) Timber.i("Androidacy link detected")
val androidacyWebAPI = androidacyWebAPI
if (androidacyWebAPI != null) {
if (!androidacyWebAPI.downloadMode) {
@@ -343,12 +343,12 @@ class AndroidacyActivity : AppCompatActivity() {
// Workaround Androidacy bug
val moduleId = moduleIdOfUrl(downloadUrl)
if (megaIntercept(wbv.url, downloadUrl)) {
- Timber.i("megaIntercept failure 2. Forcing onBackPress")
+ if (MainApplication.forceDebugLogging) Timber.i("megaIntercept failure 2. Forcing onBackPress")
// Block request as Androidacy doesn't allow duplicate requests
return@setDownloadListener
} else if (moduleId != null) {
// Download module
- Timber.i("megaIntercept failure. Forcing onBackPress")
+ if (MainApplication.forceDebugLogging) Timber.i("megaIntercept failure. Forcing onBackPress")
finish()
}
}
@@ -356,7 +356,7 @@ class AndroidacyActivity : AppCompatActivity() {
androidacyWebAPI.downloadMode = false
}
backOnResume = true
- Timber.i("Exiting WebView %s", AndroidacyUtil.hideToken(downloadUrl))
+ if (MainApplication.forceDebugLogging) Timber.i("Exiting WebView %s", AndroidacyUtil.hideToken(downloadUrl))
for (prefix in arrayOf(
"https://production-api.androidacy.com/magisk/file//",
"https://staging-api.androidacy.com/magisk/file/"
@@ -365,7 +365,7 @@ class AndroidacyActivity : AppCompatActivity() {
return@setDownloadListener
}
}
- IntentHelper.openCustomTab(this, downloadUrl)
+ IntentHelper.startDownloadUsingDownloadManager(this, downloadUrl, title)
}
})
androidacyWebAPI = AndroidacyWebAPI(this, allowInstall)
@@ -452,7 +452,7 @@ class AndroidacyActivity : AppCompatActivity() {
val androidacyWebAPI = androidacyWebAPI
val moduleId = AndroidacyUtil.getModuleId(fileUrl)
if (moduleId == null) {
- Timber.i("No module id?")
+ if (MainApplication.forceDebugLogging) Timber.i("No module id?")
// Re-open the page
webView!!.loadUrl(pageUrl + "&force_refresh=" + System.currentTimeMillis())
}
@@ -503,7 +503,7 @@ class AndroidacyActivity : AppCompatActivity() {
webView!!.removeAllViews()
webView!!.destroy() // fix memory leak
}
- Timber.i("onDestroy for %s", this)
+ if (MainApplication.forceDebugLogging) Timber.i("onDestroy for %s", this)
}
companion object {
diff --git a/app/src/main/kotlin/com/fox2code/mmm/androidacy/AndroidacyRepoData.kt b/app/src/main/kotlin/com/fox2code/mmm/androidacy/AndroidacyRepoData.kt
index 5ba2e41..6a8e214 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/androidacy/AndroidacyRepoData.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/androidacy/AndroidacyRepoData.kt
@@ -13,6 +13,7 @@ import android.widget.Toast
import com.fingerprintjs.android.fingerprint.Fingerprinter
import com.fingerprintjs.android.fingerprint.FingerprinterFactory.create
import com.fox2code.mmm.BuildConfig
+import com.fox2code.mmm.MainApplication
import com.fox2code.mmm.MainApplication.Companion.INSTANCE
import com.fox2code.mmm.MainApplication.Companion.getSharedPreferences
import com.fox2code.mmm.R
@@ -84,7 +85,7 @@ class AndroidacyRepoData(cacheRoot: File?, testMode: Boolean) : RepoData(
// response is JSON
val jsonObject = JSONObject(String(resp))
memberLevel = jsonObject.getString("role")
- if (BuildConfig.DEBUG) Timber.d("Member level: %s", memberLevel)
+ if (MainApplication.forceDebugLogging) Timber.d("Member level: %s", memberLevel)
val memberPermissions = jsonObject.getJSONArray("permissions")
// set role and permissions on userInfo property
userInfo = arrayOf(
@@ -209,16 +210,16 @@ class AndroidacyRepoData(cacheRoot: File?, testMode: Boolean) : RepoData(
token =
getSharedPreferences("androidacy")?.getString("pref_androidacy_api_token", null)
if (token != null && !isValidToken(token)) {
- Timber.i("Token expired or invalid, requesting new one...")
+ if (MainApplication.forceDebugLogging) Timber.i("Token expired or invalid, requesting new one...")
token = null
} else {
- Timber.i("Using cached token")
+ if (MainApplication.forceDebugLogging) Timber.i("Using cached token")
}
} else if (!isValidToken(token)) {
- Timber.i("Token expired, requesting new one...")
+ if (MainApplication.forceDebugLogging) Timber.i("Token expired, requesting new one...")
token = null
} else {
- Timber.i("Using validated cached token")
+ if (MainApplication.forceDebugLogging) Timber.i("Using validated cached token")
}
} catch (e: IOException) {
if (shouldTimeout(e)) {
@@ -228,9 +229,9 @@ class AndroidacyRepoData(cacheRoot: File?, testMode: Boolean) : RepoData(
return false
}
if (token == null) {
- Timber.i("Token is null, requesting new one...")
+ if (MainApplication.forceDebugLogging) Timber.i("Token is null, requesting new one...")
try {
- Timber.i("Requesting new token...")
+ if (MainApplication.forceDebugLogging) Timber.i("Requesting new token...")
token = requestNewToken()
// Parse token
// Ensure token is valid
@@ -252,7 +253,7 @@ class AndroidacyRepoData(cacheRoot: File?, testMode: Boolean) : RepoData(
val editor = getSharedPreferences("androidacy")!!.edit()
editor.putString("pref_androidacy_api_token", token)
editor.apply()
- Timber.i("Token saved to shared preference")
+ if (MainApplication.forceDebugLogging) Timber.i("Token saved to shared preference")
}
} catch (e: Exception) {
if (shouldTimeout(e)) {
@@ -270,7 +271,7 @@ class AndroidacyRepoData(cacheRoot: File?, testMode: Boolean) : RepoData(
@Throws(JSONException::class)
override fun populate(jsonObject: JSONObject): List? {
var jsonObject = jsonObject
- if (BuildConfig.DEBUG) Timber.d("AndroidacyRepoData populate start")
+ if (MainApplication.forceDebugLogging) Timber.d("AndroidacyRepoData populate start")
val name = jsonObject.optString("name", "Androidacy Modules Repo")
val nameForModules =
if (name.endsWith(" (Official)")) name.substring(0, name.length - 11) else name
@@ -297,7 +298,7 @@ class AndroidacyRepoData(cacheRoot: File?, testMode: Boolean) : RepoData(
if (!jsonArray.isNull(i)) {
jsonObject = jsonArray.getJSONObject(i)
} else {
- if (BuildConfig.DEBUG) Timber.d("Skipping null module at index %d", i)
+ if (MainApplication.forceDebugLogging) Timber.d("Skipping null module at index %d", i)
continue
}
} catch (e: JSONException) {
diff --git a/app/src/main/kotlin/com/fox2code/mmm/androidacy/AndroidacyWebAPI.kt b/app/src/main/kotlin/com/fox2code/mmm/androidacy/AndroidacyWebAPI.kt
index c213207..6d065da 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/androidacy/AndroidacyWebAPI.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/androidacy/AndroidacyWebAPI.kt
@@ -32,6 +32,7 @@ import com.fox2code.mmm.utils.ExternalHelper
import com.fox2code.mmm.utils.IntentHelper.Companion.openCustomTab
import com.fox2code.mmm.utils.IntentHelper.Companion.openInstaller
import com.fox2code.mmm.utils.IntentHelper.Companion.openUrl
+import com.fox2code.mmm.utils.IntentHelper.Companion.startDownloadUsingDownloadManager
import com.fox2code.mmm.utils.io.Files.Companion.readSU
import com.fox2code.mmm.utils.io.Files.Companion.writeSU
import com.fox2code.mmm.utils.io.Hashes.Companion.checkSumFormat
@@ -74,7 +75,7 @@ class AndroidacyWebAPI(
checksum: String?,
canInstall: Boolean
) {
- if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d(
+ if (MainApplication.forceDebugLogging) Timber.d(
"ModuleDialog, downloadUrl: " + hideToken(
moduleUrl!!
) + ", moduleId: " + moduleId + ", installTitle: " + installTitle + ", checksum: " + checksum + ", canInstall: " + canInstall
@@ -112,7 +113,9 @@ class AndroidacyWebAPI(
.setIcon(R.drawable.ic_baseline_extension_24)
builder.setNegativeButton(R.string.download_module) { _: DialogInterface?, _: Int ->
downloadMode = true
- openCustomTab(activity, moduleUrl)
+ startDownloadUsingDownloadManager(activity, moduleUrl, title)
+ // close activity
+ activity.runOnUiThread { activity.finishAndRemoveTask() }
}
if (canInstall) {
var hasUpdate = false
@@ -174,7 +177,7 @@ class AndroidacyWebAPI(
fun notifyCompatModeRaw(value: Int) {
var value = value
if (consumedAction) return
- if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d("Androidacy Compat mode: %s", value)
+ if (MainApplication.forceDebugLogging) Timber.d("Androidacy Compat mode: %s", value)
notifiedCompatMode = value
if (value < 0) {
value = 0
@@ -208,7 +211,7 @@ class AndroidacyWebAPI(
if (consumedAction) return
consumedAction = true
downloadMode = false
- if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d("Received openUrl request: %s", url)
+ if (MainApplication.forceDebugLogging) Timber.d("Received openUrl request: %s", url)
if (Uri.parse(url).scheme == "https") {
openUrl(activity, url)
}
@@ -222,7 +225,7 @@ class AndroidacyWebAPI(
if (consumedAction) return
consumedAction = true
downloadMode = false
- if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d("Received openCustomTab request: %s", url)
+ if (MainApplication.forceDebugLogging) Timber.d("Received openCustomTab request: %s", url)
if (Uri.parse(url).scheme == "https") {
openCustomTab(activity, url)
}
@@ -266,7 +269,7 @@ class AndroidacyWebAPI(
}
consumedAction = true
downloadMode = false
- if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d("Received install request: $moduleUrl $installTitle $checksum")
+ if (MainApplication.forceDebugLogging) Timber.d("Received install request: $moduleUrl $installTitle $checksum")
if (!isAndroidacyLink(moduleUrl)) {
forceQuitRaw("Non Androidacy module link used on Androidacy")
return
diff --git a/app/src/main/kotlin/com/fox2code/mmm/background/BackgroundUpdateChecker.kt b/app/src/main/kotlin/com/fox2code/mmm/background/BackgroundUpdateChecker.kt
index 92fd25e..873d973 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/background/BackgroundUpdateChecker.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/background/BackgroundUpdateChecker.kt
@@ -178,7 +178,7 @@ class BackgroundUpdateChecker(context: Context, workerParams: WorkerParameters)
builder.setContentText(context.getString(R.string.notification_channel_background_update_description))
notificationManager.notify(NOTIFICATION_ID_ONGOING, builder.build())
} else {
- if (BuildConfig.DEBUG) Timber.d("Not posting notification because of missing permission")
+ if (MainApplication.forceDebugLogging) Timber.d("Not posting notification because of missing permission")
}
ModuleManager.instance!!.scanAsync()
RepoManager.getINSTANCE()!!.update(null)
@@ -211,7 +211,7 @@ class BackgroundUpdateChecker(context: Context, workerParams: WorkerParameters)
for (s in stringSet!!) {
if (s.startsWith(localModuleInfo.id)) {
version = s
- if (BuildConfig.DEBUG) Timber.d("igV: %s", version)
+ if (MainApplication.forceDebugLogging) Timber.d("igV: %s", version)
break
}
}
@@ -222,7 +222,7 @@ class BackgroundUpdateChecker(context: Context, workerParams: WorkerParameters)
remoteVersionCode = repoModule.moduleInfo.versionCode.toString()
}
if (version.isNotEmpty()) {
- if (BuildConfig.DEBUG) Timber.d("igV found: %s", version)
+ if (MainApplication.forceDebugLogging) Timber.d("igV found: %s", version)
val remoteVersionCodeInt = remoteVersionCode.toInt()
val wantsVersion =
version.split(":".toRegex()).dropLastWhile { it.isEmpty() }
@@ -232,23 +232,23 @@ class BackgroundUpdateChecker(context: Context, workerParams: WorkerParameters)
version = version.split(":".toRegex()).dropLastWhile { it.isEmpty() }
.toTypedArray()[1]
if (version.startsWith("^")) {
- if (BuildConfig.DEBUG) Timber.d("igV: newer")
+ if (MainApplication.forceDebugLogging) Timber.d("igV: newer")
// the wantsversion and newer
if (remoteVersionCodeInt >= wantsVersion) {
- if (BuildConfig.DEBUG) Timber.d("igV: skipping")
+ if (MainApplication.forceDebugLogging) Timber.d("igV: skipping")
// if it is, we skip it
continue
}
} else if (version.endsWith("$")) {
- if (BuildConfig.DEBUG) Timber.d("igV: older")
+ if (MainApplication.forceDebugLogging) Timber.d("igV: older")
// this wantsversion and older
if (remoteVersionCodeInt <= wantsVersion) {
- if (BuildConfig.DEBUG) Timber.d("igV: skipping")
+ if (MainApplication.forceDebugLogging) Timber.d("igV: skipping")
// if it is, we skip it
continue
}
} else if (wantsVersion == remoteVersionCodeInt) {
- if (BuildConfig.DEBUG) Timber.d("igV: equal")
+ if (MainApplication.forceDebugLogging) Timber.d("igV: equal")
// if it is, we skip it
continue
}
@@ -272,7 +272,7 @@ class BackgroundUpdateChecker(context: Context, workerParams: WorkerParameters)
}
}
if (moduleUpdateCount != 0) {
- if (BuildConfig.DEBUG) Timber.d("Found %d updates", moduleUpdateCount)
+ if (MainApplication.forceDebugLogging) Timber.d("Found %d updates", moduleUpdateCount)
postNotification(context, updateableModules, moduleUpdateCount, false)
}
}
@@ -286,10 +286,10 @@ class BackgroundUpdateChecker(context: Context, workerParams: WorkerParameters)
try {
val shouldUpdate = AppUpdateManager.appUpdateManager.checkUpdate(true)
if (shouldUpdate) {
- if (BuildConfig.DEBUG) Timber.d("Found app update")
+ if (MainApplication.forceDebugLogging) Timber.d("Found app update")
postNotificationForAppUpdate(context)
} else {
- if (BuildConfig.DEBUG) Timber.d("No app update found")
+ if (MainApplication.forceDebugLogging) Timber.d("No app update found")
}
} catch (e: Exception) {
Timber.e("Failed to check for app update")
@@ -302,7 +302,7 @@ class BackgroundUpdateChecker(context: Context, workerParams: WorkerParameters)
Manifest.permission.POST_NOTIFICATIONS
) == PackageManager.PERMISSION_GRANTED
) {
- if (BuildConfig.DEBUG) Timber.d("Removing notification")
+ if (MainApplication.forceDebugLogging) Timber.d("Removing notification")
val notificationManager = NotificationManagerCompat.from(context)
notificationManager.cancel(NOTIFICATION_ID_ONGOING)
}
@@ -415,11 +415,11 @@ class BackgroundUpdateChecker(context: Context, workerParams: WorkerParameters)
).build()
)
notificationManagerCompat.cancel(NOTIFICATION_ID_ONGOING)
- if (BuildConfig.DEBUG) Timber.d("Scheduling periodic background check")
+ if (MainApplication.forceDebugLogging) Timber.d("Scheduling periodic background check")
// use pref_background_update_check_frequency to set frequency. value is in minutes
val frequency = MainApplication.getSharedPreferences("mmm")!!
.getInt("pref_background_update_check_frequency", 60).toLong()
- if (BuildConfig.DEBUG) Timber.d("Frequency: $frequency minutes")
+ if (MainApplication.forceDebugLogging) Timber.d("Frequency: $frequency minutes")
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
"background_checker",
ExistingPeriodicWorkPolicy.UPDATE,
diff --git a/app/src/main/kotlin/com/fox2code/mmm/installer/InstallerActivity.kt b/app/src/main/kotlin/com/fox2code/mmm/installer/InstallerActivity.kt
index ab8ed0e..8ae9c32 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/installer/InstallerActivity.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/installer/InstallerActivity.kt
@@ -202,7 +202,7 @@ class InstallerActivity : AppCompatActivity() {
// Set this to the error message if it's a HTTP error
var rawModule: ByteArray?
try {
- Timber.i(
+ if (MainApplication.forceDebugLogging) Timber.i(
"%s%s", if (urlMode) "Downloading: " else "Loading: ", AndroidacyUtil.hideToken(
target
)
@@ -225,7 +225,7 @@ class InstallerActivity : AppCompatActivity() {
}
if (canceled) return@Runnable
if (!checksum.isNullOrEmpty()) {
- Timber.i("Checking for checksum: %s", checksum.toString())
+ if (MainApplication.forceDebugLogging) Timber.i("Checking for checksum: %s", checksum.toString())
runOnUiThread { installerTerminal!!.addLine("- Checking file integrity") }
if (!checkSumMatch(rawModule, checksum)) {
setInstallStateFinished(false, "! File integrity check failed", "")
@@ -332,7 +332,7 @@ class InstallerActivity : AppCompatActivity() {
if (canceled) return
// disable back
runOnUiThread { cancelFloatingButton!!.isEnabled = false }
- Timber.i("Installing: %s", moduleCache!!.name)
+ if (MainApplication.forceDebugLogging) Timber.i("Installing: %s", moduleCache!!.name)
val installerController = InstallerController(
progressIndicator, installerTerminal, file!!.absoluteFile, noExtensions
)
@@ -361,7 +361,7 @@ class InstallerActivity : AppCompatActivity() {
}
}
} catch (e: Exception) {
- Timber.i(e)
+ if (MainApplication.forceDebugLogging) Timber.i(e)
}
installerMonitor = InstallerMonitor(installScript)
installJob = Shell.cmd(
@@ -690,7 +690,16 @@ class InstallerActivity : AppCompatActivity() {
override fun onAddElement(s: String?) {
var s = s ?: return
if (!enabled) return
- Timber.i("MSG: %s", s)
+ // sanitize string for logging
+ if (MainApplication.forceDebugLogging) {
+ var tempS = s
+ if (tempS.length > 100) tempS = tempS.substring(0, 100) + "..."
+ // remove ansii color codes
+ tempS = tempS.replace("\u001B\\[[;\\d]*m".toRegex(), "")
+ // remove non-printable characters and replace with ?
+ tempS = tempS.replace("[^\\p{Print}]".toRegex(), "?")
+ Timber.i("New line: %s", tempS)
+ }
if ("#!useExt" == s.trim { it <= ' ' } && !noExtension) {
useExt = true
return
@@ -816,7 +825,7 @@ class InstallerActivity : AppCompatActivity() {
override fun onAddElement(e: String?) {
val e = e ?: return
- Timber.i("Monitor: %s", e)
+ if (MainApplication.forceDebugLogging) Timber.i("Monitor: %s", e)
lastCommand = e
}
diff --git a/app/src/main/kotlin/com/fox2code/mmm/installer/InstallerInitializer.kt b/app/src/main/kotlin/com/fox2code/mmm/installer/InstallerInitializer.kt
index 574f795..6ba29dc 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/installer/InstallerInitializer.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/installer/InstallerInitializer.kt
@@ -139,7 +139,7 @@ class InstallerInitializer {
).to(output).exec().isSuccess
) {
if (BuildConfig.DEBUG) {
- Timber.i("Failed to search for ramdisk")
+ if (MainApplication.forceDebugLogging) Timber.i("Failed to search for ramdisk")
}
if (output.size != 0) {
hsRmdsk = "false" == output[0] || "true".equals(
@@ -150,8 +150,8 @@ class InstallerInitializer {
return null
}
if (BuildConfig.DEBUG) {
- Timber.i("Found ramdisk: %s", output[0])
- Timber.i("Searching for Magisk path. Current path: %s", mgskPth)
+ if (MainApplication.forceDebugLogging) Timber.i("Found ramdisk: %s", output[0])
+ if (MainApplication.forceDebugLogging) Timber.i("Searching for Magisk path. Current path: %s", mgskPth)
}
// reset output
output.clear()
@@ -161,7 +161,7 @@ class InstallerInitializer {
)) {
mgskPth = output[0]
if (BuildConfig.DEBUG) {
- Timber.i("Magisk path 1: %s", mgskPth)
+ if (MainApplication.forceDebugLogging) Timber.i("Magisk path 1: %s", mgskPth)
}
} else if (Shell.cmd("if [ -d /data/adb/ksu ]; then echo true; else echo false; fi", "su -V").to(
output
@@ -172,7 +172,7 @@ class InstallerInitializer {
Shell.cmd("su -v").to(suVer).exec()
if (suVer.size > 0 && suVer[0].contains("ksu") || suVer[0].contains("Kernelsu", true)) {
if (BuildConfig.DEBUG) {
- Timber.i("Kernelsu detected")
+ if (MainApplication.forceDebugLogging) Timber.i("Kernelsu detected")
}
mgskPth = "/data/adb"
isKsu = true
@@ -192,9 +192,9 @@ class InstallerInitializer {
}
return null
}
- Timber.i("Magisk runtime path: %s", mgskPth)
+ if (MainApplication.forceDebugLogging) Timber.i("Magisk runtime path: %s", mgskPth)
mgskVerCode = output[1].toInt()
- Timber.i("Magisk version code: %s", mgskVerCode)
+ if (MainApplication.forceDebugLogging) Timber.i("Magisk version code: %s", mgskVerCode)
if (mgskVerCode >= Constants.MAGISK_VER_CODE_FLAT_MODULES && mgskVerCode < Constants.MAGISK_VER_CODE_PATH_SUPPORT && (mgskPth.isEmpty() || !File(
mgskPth
).exists())
diff --git a/app/src/main/kotlin/com/fox2code/mmm/manager/ModuleManager.kt b/app/src/main/kotlin/com/fox2code/mmm/manager/ModuleManager.kt
index f0bff13..c90c7f1 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/manager/ModuleManager.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/manager/ModuleManager.kt
@@ -6,7 +6,6 @@ package com.fox2code.mmm.manager
import android.content.SharedPreferences
import androidx.room.Room
-import com.fox2code.mmm.BuildConfig
import com.fox2code.mmm.MainApplication
import com.fox2code.mmm.installer.InstallerInitializer.Companion.peekModulesPath
import com.fox2code.mmm.utils.SyncManager
@@ -56,10 +55,10 @@ class ModuleManager private constructor() : SyncManager() {
if (!FORCE_NEED_FALLBACK && needFallback) {
Timber.e("using fallback instead.")
}
- if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d("Scan")
+ if (MainApplication.forceDebugLogging) Timber.d("Scan")
val modulesList = StringBuilder()
if (modules != null) {
- Timber.i("Found %d modules on device in data", modules.size)
+ if (MainApplication.forceDebugLogging) Timber.i("Found %d modules on device in data", modules.size)
val db = Room.databaseBuilder(
MainApplication.INSTANCE!!,
ModuleListCacheDatabase::class.java,
@@ -69,7 +68,7 @@ class ModuleManager private constructor() : SyncManager() {
if (!SuFile("/data/adb/modules/$module").isDirectory) continue // Ignore non directory files inside modules folder
// don't care about lost+found (case insensitive)
if (module.equals("lost+found", ignoreCase = true)) continue
- if (BuildConfig.DEBUG) Timber.d("Found module %s", module)
+ if (MainApplication.forceDebugLogging) Timber.d("Found module %s", module)
var moduleInfo = moduleInfos[module]
// next, merge the module info with a record from ModuleListCache room db if it exists
// initialize modulelistcache db
@@ -80,7 +79,7 @@ class ModuleManager private constructor() : SyncManager() {
moduleInfo = LocalModuleInfo(module)
}
if (moduleListCacheDao.exists(module)) {
- if (BuildConfig.DEBUG) Timber.d("Found cache for %s", module)
+ if (MainApplication.forceDebugLogging) Timber.d("Found cache for %s", module)
val moduleListCache: ModuleListCache = moduleListCacheDao.getByCodename(module)
moduleInfo.name =
if (moduleListCache.name != "") moduleListCache.name else module
@@ -130,7 +129,7 @@ class ModuleManager private constructor() : SyncManager() {
moduleInfo, "/data/adb/modules/$module/module.prop", true
)
} catch (e: Exception) {
- if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d(e)
+ if (MainApplication.forceDebugLogging) Timber.d(e)
moduleInfo.flags = moduleInfo.flags or FLAG_MM_INVALID
}
moduleInfos[module] = moduleInfo
@@ -140,7 +139,7 @@ class ModuleManager private constructor() : SyncManager() {
}
db.close()
} else {
- Timber.i("No modules on device in data")
+ if (MainApplication.forceDebugLogging) Timber.i("No modules on device in data")
}
if (modulesList.isNotEmpty()) {
modulesList.deleteCharAt(modulesList.length - 1)
@@ -151,12 +150,12 @@ class ModuleManager private constructor() : SyncManager() {
put("modules", modulesList.toString())
})
}
- if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d("Scan update")
+ if (MainApplication.forceDebugLogging) Timber.d("Scan update")
val modulesUpdate = SuFile("/data/adb/modules_update").list()
if (modulesUpdate != null) {
for (module in modulesUpdate) {
if (!SuFile("/data/adb/modules_update/$module").isDirectory) continue // Ignore non directory files inside modules folder
- if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d(module)
+ if (MainApplication.forceDebugLogging) Timber.d(module)
var moduleInfo = moduleInfos[module]
if (moduleInfo == null) {
moduleInfo = LocalModuleInfo(module)
@@ -169,17 +168,17 @@ class ModuleManager private constructor() : SyncManager() {
moduleInfo, "/data/adb/modules_update/$module/module.prop", true
)
} catch (e: Exception) {
- if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d(e)
+ if (MainApplication.forceDebugLogging) Timber.d(e)
moduleInfo.flags = moduleInfo.flags or FLAG_MM_INVALID
}
}
}
- if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d("Finalize scan")
+ if (MainApplication.forceDebugLogging) Timber.d("Finalize scan")
updatableModuleCount = 0
val moduleInfoIterator = moduleInfos.values.iterator()
while (moduleInfoIterator.hasNext()) {
val moduleInfo = moduleInfoIterator.next()
- if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d(moduleInfo.id)
+ if (MainApplication.forceDebugLogging) Timber.d(moduleInfo.id)
if (moduleInfo.flags and FLAG_MM_UNPROCESSED != 0) {
moduleInfoIterator.remove()
continue // Don't process fallbacks if unreferenced
@@ -226,7 +225,7 @@ class ModuleManager private constructor() : SyncManager() {
}
fun setEnabledState(moduleInfo: ModuleInfo, checked: Boolean): Boolean {
- if (BuildConfig.DEBUG) Timber.d("setEnabledState(%s, %s)", moduleInfo.id, checked)
+ if (MainApplication.forceDebugLogging) Timber.d("setEnabledState(%s, %s)", moduleInfo.id, checked)
if (moduleInfo.hasFlag(ModuleInfo.FLAG_MODULE_UPDATING) && !checked) return false
val disable = SuFile("/data/adb/modules/" + moduleInfo.id + "/disable")
if (checked) {
diff --git a/app/src/main/kotlin/com/fox2code/mmm/markdown/MarkdownActivity.kt b/app/src/main/kotlin/com/fox2code/mmm/markdown/MarkdownActivity.kt
index 78325dd..191e868 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/markdown/MarkdownActivity.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/markdown/MarkdownActivity.kt
@@ -72,7 +72,7 @@ class MarkdownActivity : AppCompatActivity() {
finish()
return
}
- Timber.i("Url for markdown %s", url.toString())
+ if (MainApplication.forceDebugLogging) Timber.i("Url for markdown %s", url.toString())
setContentView(R.layout.markdown_view)
val markdownBackground = findViewById(R.id.markdownBackground)
val textView = findViewById(R.id.markdownView)
@@ -89,11 +89,11 @@ class MarkdownActivity : AppCompatActivity() {
if (maxApi != 0) this.addChip(MarkdownChip.MAX_SDK, parseAndroidVersion(maxApi))
Thread({
try {
- Timber.i("Downloading")
+ if (MainApplication.forceDebugLogging) Timber.i("Downloading")
val rawMarkdown = getRawMarkdown(url)
- Timber.i("Encoding")
+ if (MainApplication.forceDebugLogging) Timber.i("Encoding")
val markdown = String(rawMarkdown, StandardCharsets.UTF_8)
- Timber.i("Done!")
+ if (MainApplication.forceDebugLogging) Timber.i("Done!")
runOnUiThread {
MainApplication.INSTANCE!!.markwon?.setMarkdown(
textView, MarkdownUrlLinker.urlLinkify(markdown)
diff --git a/app/src/main/kotlin/com/fox2code/mmm/markdown/MarkdownUrlLinker.kt b/app/src/main/kotlin/com/fox2code/mmm/markdown/MarkdownUrlLinker.kt
index 3605b6d..40e5f81 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/markdown/MarkdownUrlLinker.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/markdown/MarkdownUrlLinker.kt
@@ -4,7 +4,7 @@
package com.fox2code.mmm.markdown
-import com.fox2code.mmm.BuildConfig
+import com.fox2code.mmm.MainApplication
import timber.log.Timber
enum class MarkdownUrlLinker {
@@ -33,7 +33,7 @@ enum class MarkdownUrlLinker {
if (endDomain != -1 && endDomain < end && endCh != '>' && endCh != ')' && endCh != ']') {
linkifyTasks.add(LinkifyTask(index, end))
extra += end - index + 4
- if (BuildConfig.DEBUG) Timber.d("Linkify url: %s", url.substring(end))
+ if (MainApplication.forceDebugLogging) Timber.d("Linkify url: %s", url.substring(end))
}
}
index = url.indexOf("https://", end)
@@ -48,7 +48,7 @@ enum class MarkdownUrlLinker {
prev = linkifyTask
}
if (prev.end != url.length) stringBuilder.append(url, prev.end, url.length)
- Timber.i("Added Markdown link to " + linkifyTasks.size + " urls")
+ if (MainApplication.forceDebugLogging) Timber.i("Added Markdown link to " + linkifyTasks.size + " urls")
return stringBuilder.toString()
}
}
diff --git a/app/src/main/kotlin/com/fox2code/mmm/module/ActionButtonType.kt b/app/src/main/kotlin/com/fox2code/mmm/module/ActionButtonType.kt
index 0f5cd73..2969321 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/module/ActionButtonType.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/module/ActionButtonType.kt
@@ -11,7 +11,6 @@ import android.text.Spanned
import android.widget.TextView
import android.widget.Toast
import androidx.annotation.DrawableRes
-import com.fox2code.mmm.BuildConfig
import com.fox2code.mmm.MainApplication
import com.fox2code.mmm.MainApplication.Companion.INSTANCE
import com.fox2code.mmm.MainApplication.Companion.isShowcaseMode
@@ -22,11 +21,11 @@ import com.fox2code.mmm.manager.ModuleInfo
import com.fox2code.mmm.manager.ModuleManager.Companion.instance
import com.fox2code.mmm.utils.ExternalHelper
import com.fox2code.mmm.utils.IntentHelper.Companion.openConfig
-import com.fox2code.mmm.utils.IntentHelper.Companion.openCustomTab
import com.fox2code.mmm.utils.IntentHelper.Companion.openInstaller
import com.fox2code.mmm.utils.IntentHelper.Companion.openMarkdown
import com.fox2code.mmm.utils.IntentHelper.Companion.openUrl
import com.fox2code.mmm.utils.IntentHelper.Companion.openUrlAndroidacy
+import com.fox2code.mmm.utils.IntentHelper.Companion.startDownloadUsingDownloadManager
import com.google.android.material.chip.Chip
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import io.noties.markwon.Markwon
@@ -198,12 +197,15 @@ enum class ActionButtonType {
} else {
builder.setMessage(desc)
}
- Timber.i("URL: %s", updateZipUrl)
- builder.setNegativeButton(R.string.download_module) { _: DialogInterface?, _: Int ->
- openCustomTab(
+ if (MainApplication.forceDebugLogging) Timber.i("URL: %s", updateZipUrl)
+ builder.setNegativeButton(R.string.download_module) { d: DialogInterface?, _: Int ->
+ startDownloadUsingDownloadManager(
button.context,
- updateZipUrl
+ updateZipUrl,
+ moduleInfo.name,
)
+ // close the dialog and finish
+ d?.cancel()
}
if (hasRoot) {
builder.setPositiveButton(if (moduleHolder.hasUpdate()) R.string.update_module else R.string.install_module) { _: DialogInterface?, _: Int ->
@@ -270,7 +272,7 @@ enum class ActionButtonType {
put("module", name ?: "null")
})
}
- Timber.i(Integer.toHexString(moduleHolder.moduleInfo?.flags ?: 0))
+ if (MainApplication.forceDebugLogging) Timber.i(Integer.toHexString(moduleHolder.moduleInfo?.flags ?: 0))
if (!instance!!.setUninstallState(
moduleHolder.moduleInfo!!, !moduleHolder.hasFlag(
ModuleInfo.FLAG_MODULE_UNINSTALLING
@@ -435,7 +437,7 @@ if (MainApplication.analyticsAllowed()) {
REMOTE {
@Suppress("NAME_SHADOWING")
override fun doAction(button: Chip, moduleHolder: ModuleHolder) {
- if (BuildConfig.DEBUG) Timber.d("doAction: remote module for %s", moduleHolder.moduleInfo?.name ?: "null")
+ if (MainApplication.forceDebugLogging) Timber.d("doAction: remote module for %s", moduleHolder.moduleInfo?.name ?: "null")
// that module is from remote repo
val name: String? = if (moduleHolder.moduleInfo != null) {
moduleHolder.moduleInfo!!.name
@@ -493,13 +495,13 @@ if (MainApplication.analyticsAllowed()) {
madb.setPositiveButton(
R.string.reinstall
) { _: DialogInterface?, _: Int ->
- if (BuildConfig.DEBUG) Timber.d("Set moduleinfo to %s", moduleInfo.name)
+ if (MainApplication.forceDebugLogging) Timber.d("Set moduleinfo to %s", moduleInfo.name)
val name: String? = if (moduleHolder.moduleInfo != null) {
moduleHolder.moduleInfo!!.name
} else {
moduleHolder.repoModule?.moduleInfo?.name
}
- if (BuildConfig.DEBUG) Timber.d("doAction: remote module for %s", name)
+ if (MainApplication.forceDebugLogging) Timber.d("doAction: remote module for %s", name)
if (MainApplication.analyticsAllowed()) {
Countly.sharedInstance().events().recordEvent("view_update_install", HashMap().apply {
put("module", name ?: "null")
@@ -507,7 +509,7 @@ if (MainApplication.analyticsAllowed()) {
}
// Androidacy manage the selection between download and install
if (isAndroidacyLink(updateZipUrl)) {
- if (BuildConfig.DEBUG) Timber.d("Androidacy link detected")
+ if (MainApplication.forceDebugLogging) Timber.d("Androidacy link detected")
openUrlAndroidacy(
button.context,
updateZipUrl,
@@ -534,12 +536,14 @@ if (MainApplication.analyticsAllowed()) {
} else {
builder.setMessage(desc)
}
- Timber.i("URL: %s", updateZipUrl)
- builder.setNegativeButton(R.string.download_module) { _: DialogInterface?, _: Int ->
- openCustomTab(
+ if (MainApplication.forceDebugLogging) Timber.i("URL: %s", updateZipUrl)
+ builder.setNegativeButton(R.string.download_module) { d: DialogInterface?, _: Int ->
+ startDownloadUsingDownloadManager(
button.context,
- updateZipUrl
+ updateZipUrl,
+ moduleInfo.name,
)
+ d?.cancel()
}
if (hasRoot) {
builder.setPositiveButton(if (moduleHolder.hasUpdate()) R.string.update_module else R.string.install_module) { _: DialogInterface?, _: Int ->
diff --git a/app/src/main/kotlin/com/fox2code/mmm/module/ModuleHolder.kt b/app/src/main/kotlin/com/fox2code/mmm/module/ModuleHolder.kt
index 0497a55..aee795e 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/module/ModuleHolder.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/module/ModuleHolder.kt
@@ -7,7 +7,7 @@ import android.content.Context
import android.content.pm.PackageManager
import android.view.View
import androidx.annotation.StringRes
-import com.fox2code.mmm.BuildConfig
+import com.fox2code.mmm.MainApplication
import com.fox2code.mmm.MainApplication.Companion.INSTANCE
import com.fox2code.mmm.MainApplication.Companion.formatTime
import com.fox2code.mmm.MainApplication.Companion.getSharedPreferences
@@ -117,7 +117,7 @@ class ModuleHolder : Comparable {
} else if (moduleInfo == null && repoModule != null) {
Type.INSTALLABLE
} else if (moduleInfo!!.versionCode < moduleInfo!!.updateVersionCode || repoModule != null && moduleInfo!!.versionCode < repoModule!!.moduleInfo.versionCode) {
- Timber.i("Module %s is updateable", moduleId)
+ if (MainApplication.forceDebugLogging) Timber.i("Module %s is updateable", moduleId)
var ignoreUpdate = false
try {
if (getSharedPreferences("mmm")?.getStringSet(
@@ -138,13 +138,13 @@ class ModuleHolder : Comparable {
HashSet()
)
var version = ""
- if (BuildConfig.DEBUG) Timber.d(stringSetT.toString())
+ if (MainApplication.forceDebugLogging) Timber.d(stringSetT.toString())
// unfortunately, stringset.contains() doesn't work for partial matches
// so we have to iterate through the set
for (s in stringSetT!!) {
if (s.startsWith(moduleInfo!!.id)) {
version = s
- if (BuildConfig.DEBUG) Timber.d("igV: %s", version)
+ if (MainApplication.forceDebugLogging) Timber.d("igV: %s", version)
break
}
}
@@ -158,34 +158,34 @@ class ModuleHolder : Comparable {
val wantsVersion = version.split(":".toRegex()).dropLastWhile { it.isEmpty() }
.toTypedArray()[1].replace("[^0-9]".toRegex(), "").toInt()
// now find out if user wants up to and including this version, or this version and newer
- if (BuildConfig.DEBUG) Timber.d("igV start with")
+ if (MainApplication.forceDebugLogging) Timber.d("igV start with")
version =
version.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[1]
// this version and newer
if (version.startsWith("^")) {
- if (BuildConfig.DEBUG) Timber.d("igV: newer")
+ if (MainApplication.forceDebugLogging) Timber.d("igV: newer")
// the wantsversion and newer
if (remoteVersionCodeInt >= wantsVersion) {
- if (BuildConfig.DEBUG) Timber.d("igV: skipping")
+ if (MainApplication.forceDebugLogging) Timber.d("igV: skipping")
// if it is, we skip it
ignoreUpdate = true
}
} else if (version.endsWith("$")) {
- if (BuildConfig.DEBUG) Timber.d("igV: older")
+ if (MainApplication.forceDebugLogging) Timber.d("igV: older")
// this wantsversion and older
if (remoteVersionCodeInt <= wantsVersion) {
- if (BuildConfig.DEBUG) Timber.d("igV: skipping")
+ if (MainApplication.forceDebugLogging) Timber.d("igV: skipping")
// if it is, we skip it
ignoreUpdate = true
}
} else if (wantsVersion == remoteVersionCodeInt) {
- if (BuildConfig.DEBUG) Timber.d("igV: equal")
+ if (MainApplication.forceDebugLogging) Timber.d("igV: equal")
// if it is, we skip it
ignoreUpdate = true
}
}
if (ignoreUpdate) {
- if (BuildConfig.DEBUG) Timber.d("Module %s has update, but is ignored", moduleId)
+ if (MainApplication.forceDebugLogging) Timber.d("Module %s has update, but is ignored", moduleId)
Type.INSTALLABLE
} else {
INSTANCE!!.modulesHaveUpdates = true
@@ -193,7 +193,7 @@ class ModuleHolder : Comparable {
INSTANCE!!.updateModules += moduleId
INSTANCE!!.updateModuleCount++
}
- if (BuildConfig.DEBUG) Timber.d(
+ if (MainApplication.forceDebugLogging) Timber.d(
"modulesHaveUpdates = %s, updateModuleCount = %s",
INSTANCE!!.modulesHaveUpdates,
INSTANCE!!.updateModuleCount
@@ -250,16 +250,16 @@ class ModuleHolder : Comparable {
// set updatezipurl on moduleholder
if (localModuleInfo.updateZipUrl != null) {
- if (BuildConfig.DEBUG) Timber.d("localModuleInfo: %s", localModuleInfo.updateZipUrl)
+ if (MainApplication.forceDebugLogging) Timber.d("localModuleInfo: %s", localModuleInfo.updateZipUrl)
updateZipUrl = localModuleInfo.updateZipUrl
}
if (repoModule != null) {
- if (BuildConfig.DEBUG) Timber.d("repoModule: %s", repoModule!!.zipUrl)
+ if (MainApplication.forceDebugLogging) Timber.d("repoModule: %s", repoModule!!.zipUrl)
updateZipUrl = repoModule!!.zipUrl
}
// last ditch effort, try to get remoteModuleInfo from localModuleInfo
if (rInfo != null) {
- if (BuildConfig.DEBUG) Timber.d("remoteModuleInfo: %s", rInfo.zipUrl)
+ if (MainApplication.forceDebugLogging) Timber.d("remoteModuleInfo: %s", rInfo.zipUrl)
updateZipUrl = rInfo.zipUrl
moduleInfo?.updateZipUrl = rInfo.zipUrl
}
diff --git a/app/src/main/kotlin/com/fox2code/mmm/module/ModuleViewAdapter.kt b/app/src/main/kotlin/com/fox2code/mmm/module/ModuleViewAdapter.kt
index d89d451..679408b 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/module/ModuleViewAdapter.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/module/ModuleViewAdapter.kt
@@ -26,7 +26,6 @@ import androidx.annotation.StringRes
import androidx.cardview.widget.CardView
import androidx.core.graphics.ColorUtils
import androidx.recyclerview.widget.RecyclerView
-import com.fox2code.mmm.BuildConfig
import com.fox2code.mmm.MainApplication
import com.fox2code.mmm.R
import com.fox2code.mmm.manager.ModuleInfo
@@ -400,7 +399,7 @@ ${getString(R.string.module_repo)} ${moduleHolder.repoName}""" + if ((repoModule
// get string value of Theme
val themeName = theme.toString()
if (theme.resources.getBoolean(R.bool.force_transparency) || themeName.contains("transparent")) {
- if (BuildConfig.DEBUG) Timber.d("Theme is transparent, fixing bgColor")
+ if (MainApplication.forceDebugLogging) Timber.d("Theme is transparent, fixing bgColor")
bgColor = ColorUtils.setAlphaComponent(bgColor, 0x70)
}
titleText.setTextColor(fgColor)
diff --git a/app/src/main/kotlin/com/fox2code/mmm/module/ModuleViewListBuilder.kt b/app/src/main/kotlin/com/fox2code/mmm/module/ModuleViewListBuilder.kt
index aea7c77..25596af 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/module/ModuleViewListBuilder.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/module/ModuleViewListBuilder.kt
@@ -41,22 +41,22 @@ class ModuleViewListBuilder(private val activity: Activity) {
Timber.w("addNotification(null) called!")
return
} else {
- Timber.i("addNotification(%s) called", notificationType)
+ if (MainApplication.forceDebugLogging) Timber.i("addNotification(%s) called", notificationType)
}
synchronized(updateLock) { notifications.add(notificationType) }
}
fun appendInstalledModules() {
- Timber.i("appendInstalledModules() called")
+ if (MainApplication.forceDebugLogging) Timber.i("appendInstalledModules() called")
synchronized(updateLock) {
for (moduleHolder in mappedModuleHolders.values) {
- Timber.i("zeroing module %s", moduleHolder.moduleInfo?.id)
+ if (MainApplication.forceDebugLogging) Timber.i("zeroing module %s", moduleHolder.moduleInfo?.id)
moduleHolder.moduleInfo = null
}
val moduleManager = instance
moduleManager?.runAfterScan {
- Timber.i("A0: runAfterScan %s", moduleManager.modules.size)
- Timber.i("A1: %s", moduleManager.modules.size)
+ if (MainApplication.forceDebugLogging) Timber.i("A0: runAfterScan %s", moduleManager.modules.size)
+ if (MainApplication.forceDebugLogging) Timber.i("A1: %s", moduleManager.modules.size)
for (moduleInfo in moduleManager.modules.values) {
// add the local module to the list in MainActivity
MainActivity.localModuleInfoList += moduleInfo
@@ -74,10 +74,10 @@ class ModuleViewListBuilder(private val activity: Activity) {
fun appendRemoteModules() {
if (BuildConfig.DEBUG) {
- Timber.i("appendRemoteModules() called")
+ if (MainApplication.forceDebugLogging) Timber.i("appendRemoteModules() called")
}
synchronized(updateLock) {
- Timber.i("appendRemoteModules() started")
+ if (MainApplication.forceDebugLogging) Timber.i("appendRemoteModules() started")
val startTime = System.currentTimeMillis()
val showIncompatible = MainApplication.isShowIncompatibleModules
for (moduleHolder in mappedModuleHolders.values) {
@@ -85,7 +85,7 @@ class ModuleViewListBuilder(private val activity: Activity) {
}
val repoManager = RepoManager.getINSTANCE()
repoManager?.runAfterUpdate {
- Timber.i("A2: %s", repoManager.modules.size)
+ if (MainApplication.forceDebugLogging) Timber.i("A2: %s", repoManager.modules.size)
val no32bitSupport = Build.SUPPORTED_32_BIT_ABIS.isEmpty()
try {
for (repoModule in repoManager.modules.values) {
@@ -97,7 +97,7 @@ class ModuleViewListBuilder(private val activity: Activity) {
continue
}
if (!repoModule.repoData.isEnabled) {
- Timber.i(
+ if (MainApplication.forceDebugLogging) Timber.i(
"Repo %s is disabled, skipping module %s",
repoModule.repoData.preferenceId,
repoModule.id
@@ -130,7 +130,7 @@ class ModuleViewListBuilder(private val activity: Activity) {
// retry up to five times, waiting i * 100ms between each try
if (tries < 5) {
tries++
- Timber.i("appendRemoteModules() retrying in %dms", tries * 100)
+ if (MainApplication.forceDebugLogging) Timber.i("appendRemoteModules() retrying in %dms", tries * 100)
Handler(Looper.getMainLooper()).postDelayed({
appendRemoteModules()
}, tries * 100.toLong())
@@ -139,7 +139,7 @@ class ModuleViewListBuilder(private val activity: Activity) {
tries = 0
}
}
- Timber.i(
+ if (MainApplication.forceDebugLogging) Timber.i(
"appendRemoteModules() finished in %dms",
System.currentTimeMillis() - startTime
)
@@ -247,7 +247,7 @@ class ModuleViewListBuilder(private val activity: Activity) {
// Footer is always last
//moduleHolders.add(headerFooter[1] =
// new ModuleHolder(this.footerPx * 2, false));
- Timber.i("Got " + moduleHolders.size + " entries!")
+ if (MainApplication.forceDebugLogging) Timber.i("Got " + moduleHolders.size + " entries!")
}
} finally {
updating = false
@@ -321,7 +321,7 @@ class ModuleViewListBuilder(private val activity: Activity) {
fun setQueryChange(query: String?): Boolean {
synchronized(queryLock) {
val newQuery = query?.trim { it <= ' ' }?.lowercase() ?: ""
- Timber.i("Query change " + this.query + " -> " + newQuery)
+ if (MainApplication.forceDebugLogging) Timber.i("Query change " + this.query + " -> " + newQuery)
if (this.query == newQuery) return false
this.query = newQuery
}
@@ -333,7 +333,7 @@ class ModuleViewListBuilder(private val activity: Activity) {
private fun notifySizeChanged(
moduleViewAdapter: ModuleViewAdapter, index: Int, oldLen: Int, newLen: Int
) {
- // Timber.i("A: " + index + " " + oldLen + " " + newLen);
+ // if (MainApplication.forceDebugLogging) Timber.i("A: " + index + " " + oldLen + " " + newLen);
if (oldLen == newLen) {
if (newLen != 0) moduleViewAdapter.notifyItemRangeChanged(index, newLen)
} else if (oldLen < newLen) {
diff --git a/app/src/main/kotlin/com/fox2code/mmm/repo/RepoData.kt b/app/src/main/kotlin/com/fox2code/mmm/repo/RepoData.kt
index 973233f..f300c28 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/repo/RepoData.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/repo/RepoData.kt
@@ -8,6 +8,7 @@ import androidx.room.Room
import com.fox2code.mmm.AppUpdateManager.Companion.shouldForceHide
import com.fox2code.mmm.BuildConfig
import com.fox2code.mmm.MainActivity
+import com.fox2code.mmm.MainApplication
import com.fox2code.mmm.MainApplication.Companion.INSTANCE
import com.fox2code.mmm.R
import com.fox2code.mmm.XRepo
@@ -342,7 +343,7 @@ open class RepoData(url: String, cacheRoot: File) : XRepo() {
}
}
} else {
- if (BuildConfig.DEBUG) Timber.d("Metadata file not found for %s", repoModule.id)
+ if (MainApplication.forceDebugLogging) Timber.d("Metadata file not found for %s", repoModule.id)
}
repoModule.moduleInfo.flags =
repoModule.moduleInfo.flags or ModuleInfo.FLAG_METADATA_INVALID
diff --git a/app/src/main/kotlin/com/fox2code/mmm/repo/RepoManager.kt b/app/src/main/kotlin/com/fox2code/mmm/repo/RepoManager.kt
index d3fe7e4..ff9f7ac 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/repo/RepoManager.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/repo/RepoManager.kt
@@ -9,7 +9,6 @@ import android.content.DialogInterface
import android.os.Handler
import android.os.Looper
import android.widget.Toast
-import com.fox2code.mmm.BuildConfig
import com.fox2code.mmm.MainActivity
import com.fox2code.mmm.MainApplication
import com.fox2code.mmm.MainApplication.Companion.getSharedPreferences
@@ -152,18 +151,18 @@ class RepoManager private constructor(mainApplication: MainApplication) : SyncMa
}
for (i in repoDatas.indices) {
updateListener.update(STEP1 * (i / repoDatas.size))
- if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d("Preparing to fetch: %s", repoDatas[i].name)
+ if (MainApplication.forceDebugLogging) Timber.d("Preparing to fetch: %s", repoDatas[i].name)
moduleToUpdate += RepoUpdater(repoDatas[i]).also { repoUpdaters[i] = it }.fetchIndex()
// divvy the 40 of step1 to each repo
updateListener.update(STEP1 * ((i + 1) / repoDatas.size))
}
- if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d("Updating meta-data")
+ if (MainApplication.forceDebugLogging) Timber.d("Updating meta-data")
var updatedModules = 0
val allowLowQualityModules = isDisableLowQualityModuleFilter
for (i in repoUpdaters.indices) {
// Check if the repo is enabled
if (!repoUpdaters[i]!!.repoData.isEnabled) {
- if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d(
+ if (MainApplication.forceDebugLogging) Timber.d(
"Skipping disabled repo: %s",
repoUpdaters[i]!!.repoData.name
)
@@ -171,7 +170,7 @@ class RepoManager private constructor(mainApplication: MainApplication) : SyncMa
}
val repoModules = repoUpdaters[i]!!.toUpdate()
val repoData = repoDatas[i]
- if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d("Registering %s", repoData.name)
+ if (MainApplication.forceDebugLogging) Timber.d("Registering %s", repoData.name)
for (repoModule in repoModules!!) {
try {
if (repoModule.propUrl != null && repoModule.propUrl!!.isNotEmpty()) {
@@ -229,15 +228,15 @@ class RepoManager private constructor(mainApplication: MainApplication) : SyncMa
}
MainApplication.INSTANCE!!.repoModules.putAll(modules)
}
- if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d("Finishing update")
+ if (MainApplication.forceDebugLogging) Timber.d("Finishing update")
if (hasConnectivity()) {
for (i in repoDatas.indices) {
// If repo is not enabled, skip
if (!repoDatas[i].isEnabled) {
- if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d("Skipping ${repoDatas[i].name} because it's disabled")
+ if (MainApplication.forceDebugLogging) Timber.d("Skipping ${repoDatas[i].name} because it's disabled")
continue
}
- if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d("Finishing: %s", repoUpdaters[i]!!.repoData.name)
+ if (MainApplication.forceDebugLogging) Timber.d("Finishing: %s", repoUpdaters[i]!!.repoData.name)
isLastUpdateSuccess = repoUpdaters[i]!!.finish()
if (!isLastUpdateSuccess || modules.isEmpty()) {
Timber.e("Failed to update %s", repoUpdaters[i]!!.repoData.name)
@@ -280,7 +279,7 @@ class RepoManager private constructor(mainApplication: MainApplication) : SyncMa
updateListener.update(STEP1 + (STEP2 * (i / repoUpdaters.size)))
}
}
- Timber.i("Got " + modules.size + " modules!")
+ if (MainApplication.forceDebugLogging) Timber.i("Got " + modules.size + " modules!")
updateListener.update(STEP1 + STEP2 + STEP3)
}
diff --git a/app/src/main/kotlin/com/fox2code/mmm/repo/RepoUpdater.kt b/app/src/main/kotlin/com/fox2code/mmm/repo/RepoUpdater.kt
index b17ab73..a2e08cc 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/repo/RepoUpdater.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/repo/RepoUpdater.kt
@@ -5,7 +5,6 @@
package com.fox2code.mmm.repo
import androidx.room.Room
-import com.fox2code.mmm.BuildConfig
import com.fox2code.mmm.MainApplication
import com.fox2code.mmm.utils.io.net.Http.Companion.doHttpGet
import com.fox2code.mmm.utils.room.ModuleListCacheDatabase
@@ -37,7 +36,7 @@ class RepoUpdater(repoData2: RepoData) {
}
// if MainApplication.repoModules is not empty, return it
/*if (MainApplication.INSTANCE!!.repoModules.isNotEmpty()) {
- if (BuildConfig.DEBUG) Timber.d("Returning MainApplication.repoModules for %s", repoData.preferenceId)
+ if (MainApplication.forceDebugLogging) Timber.d("Returning MainApplication.repoModules for %s", repoData.preferenceId)
// convert to list for toUpdate
val toUpdateList = ArrayList()
for (module in MainApplication.INSTANCE!!.repoModules) {
@@ -50,7 +49,7 @@ class RepoUpdater(repoData2: RepoData) {
}*/
// if we shouldn't update, get the values from the ModuleListCache realm
if (!repoData.shouldUpdate() && repoData.preferenceId == "androidacy_repo") { // for now, only enable cache reading for androidacy repo, until we handle storing module prop file values in cache
- if (BuildConfig.DEBUG) Timber.d("Fetching index from cache for %s", repoData.preferenceId)
+ if (MainApplication.forceDebugLogging) Timber.d("Fetching index from cache for %s", repoData.preferenceId)
// now the above but for room
val db = Room.databaseBuilder(
MainApplication.INSTANCE!!,
@@ -85,7 +84,7 @@ class RepoUpdater(repoData2: RepoData) {
)
)
}
- if (BuildConfig.DEBUG) Timber.d(
+ if (MainApplication.forceDebugLogging) Timber.d(
"Fetched %d modules from cache for %s, from %s records",
(toApply as HashSet).size,
repoData.preferenceId,
@@ -118,11 +117,11 @@ class RepoUpdater(repoData2: RepoData) {
}
// log first 100 chars of indexRaw
indexRaw = jsonObject.toString().toByteArray()
- if (BuildConfig.DEBUG) Timber.d(
+ if (MainApplication.forceDebugLogging) Timber.d(
"Index raw: %s",
String(indexRaw!!, StandardCharsets.UTF_8).subSequence(0, 100)
)
- if (BuildConfig.DEBUG) Timber.d("Returning %d modules for %s", toUpdate!!.size, repoData.preferenceId)
+ if (MainApplication.forceDebugLogging) Timber.d("Returning %d modules for %s", toUpdate!!.size, repoData.preferenceId)
// Return repo to update
return toUpdate!!.size
}
@@ -167,11 +166,11 @@ class RepoUpdater(repoData2: RepoData) {
fun finish(): Boolean {
// If repo is not enabled we don't need to do anything, just return true
if (!repoData.isEnabled) {
- if (BuildConfig.DEBUG) Timber.d("Repo %s is disabled, skipping", repoData.preferenceId)
+ if (MainApplication.forceDebugLogging) Timber.d("Repo %s is disabled, skipping", repoData.preferenceId)
return true
}
val success = AtomicBoolean(false)
- if (BuildConfig.DEBUG) Timber.d("Finishing update for %s", repoData.preferenceId)
+ if (MainApplication.forceDebugLogging) Timber.d("Finishing update for %s", repoData.preferenceId)
if (indexRaw != null) {
// set lastUpdate
val db = Room.databaseBuilder(
@@ -184,7 +183,7 @@ class RepoUpdater(repoData2: RepoData) {
db.close()
success.set(true)
} else {
- if (BuildConfig.DEBUG) Timber.d("No index file found for %s", repoData.preferenceId)
+ if (MainApplication.forceDebugLogging) Timber.d("No index file found for %s", repoData.preferenceId)
success.set(true) // assume we're reading from cache. this may be unsafe but it's better than nothing
}
return success.get()
diff --git a/app/src/main/kotlin/com/fox2code/mmm/settings/AppearanceFragment.kt b/app/src/main/kotlin/com/fox2code/mmm/settings/AppearanceFragment.kt
index ddc1c10..300551d 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/settings/AppearanceFragment.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/settings/AppearanceFragment.kt
@@ -17,7 +17,6 @@ import androidx.preference.PreferenceFragmentCompat
import androidx.preference.TwoStatePreference
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
-import com.fox2code.mmm.BuildConfig
import com.fox2code.mmm.MainApplication
import com.fox2code.mmm.R
import com.fox2code.rosettax.LanguageSwitcher
@@ -57,7 +56,7 @@ class AppearanceFragment : PreferenceFragmentCompat() {
val themePreference = findPreference("pref_theme")
// If transparent theme(s) are set, disable monet
if (themePreference!!.value == "transparent_light") {
- if (BuildConfig.DEBUG) Timber.d("disabling monet")
+ if (MainApplication.forceDebugLogging) Timber.d("disabling monet")
findPreference("pref_enable_monet")!!.isEnabled = false
// Toggle monet off
(findPreference("pref_enable_monet") as TwoStatePreference?)!!.isChecked =
@@ -76,11 +75,11 @@ class AppearanceFragment : PreferenceFragmentCompat() {
Preference.SummaryProvider { _: Preference? -> themePreference.entry }
themePreference.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
- if (BuildConfig.DEBUG) Timber.d("refreshing activity. New value: %s", newValue)
+ if (MainApplication.forceDebugLogging) Timber.d("refreshing activity. New value: %s", newValue)
editor.putString("pref_theme", newValue as String).apply()
// If theme contains "transparent" then disable monet
if (newValue.toString().contains("transparent")) {
- if (BuildConfig.DEBUG) Timber.d("disabling monet")
+ if (MainApplication.forceDebugLogging) Timber.d("disabling monet")
// Show a dialogue warning the user about issues with transparent themes and
// that blur/monet will be disabled
MaterialAlertDialogBuilder(requireContext()).setTitle(R.string.transparent_theme_dialogue_title)
diff --git a/app/src/main/kotlin/com/fox2code/mmm/settings/DebugFragment.kt b/app/src/main/kotlin/com/fox2code/mmm/settings/DebugFragment.kt
index 65c88ac..83407e3 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/settings/DebugFragment.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/settings/DebugFragment.kt
@@ -9,6 +9,7 @@ import android.widget.Toast
import androidx.core.content.FileProvider
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
+import androidx.preference.SwitchPreferenceCompat
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
import com.fox2code.mmm.BuildConfig
@@ -91,7 +92,7 @@ class DebugFragment : PreferenceFragmentCompat() {
}
if (!BuildConfig.DEBUG || InstallerInitializer.peekMagiskPath() == null) {
// Hide the pref_crash option if not in debug mode - stop users from purposely crashing the app
- Timber.i(InstallerInitializer.peekMagiskPath())
+ if (MainApplication.forceDebugLogging) Timber.i(InstallerInitializer.peekMagiskPath())
findPreference("pref_test_crash")!!.isVisible = false
} else {
if (findPreference("pref_test_crash") != null && findPreference(
@@ -206,6 +207,19 @@ class DebugFragment : PreferenceFragmentCompat() {
startActivity(Intent.createChooser(shareIntent, getString(R.string.share_logs)))
true
}
+ // handle pref_force_debug_logging, which is always on in debug mode and off by default in release mode
+ val forceDebugLogging = findPreference("pref_force_debug_logging")
+ forceDebugLogging!!.onPreferenceChangeListener =
+ Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any? ->
+ // set the debug logging flag
+ MainApplication.forceDebugLogging = newValue as Boolean
+ true
+ }
+ // force enable the pref_force_debug_logging if we're in debug mode and prevent users from disabling it
+ if (BuildConfig.DEBUG) {
+ forceDebugLogging.isEnabled = false
+ forceDebugLogging.isChecked = true
+ }
}
}
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/fox2code/mmm/settings/InfoFragment.kt b/app/src/main/kotlin/com/fox2code/mmm/settings/InfoFragment.kt
index c5b81a1..2429fea 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/settings/InfoFragment.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/settings/InfoFragment.kt
@@ -78,7 +78,7 @@ class InfoFragment : PreferenceFragmentCompat() {
var userRepo = BuildConfig.REMOTE_URL
// remove .git
userRepo = userRepo.replace("\\.git$".toRegex(), "")
- if (BuildConfig.DEBUG) Timber.d("userRepo: %s", userRepo)
+ if (MainApplication.forceDebugLogging) Timber.d("userRepo: %s", userRepo)
// finalUserRepo is the user/repo part of REMOTE_URL
// get everything after .com/ or .org/ or .io/ or .me/ or .net/ or .xyz/ or .tk/ or .co/ minus .git
@@ -89,7 +89,7 @@ class InfoFragment : PreferenceFragmentCompat() {
linkClickable!!.summary = String.format(
getString(R.string.source_code_summary), BuildConfig.COMMIT_HASH, finalUserRepo
)
- if (BuildConfig.DEBUG) Timber.d("finalUserRepo: %s", finalUserRepo)
+ if (MainApplication.forceDebugLogging) Timber.d("finalUserRepo: %s", finalUserRepo)
val finalUserRepo1 = userRepo
linkClickable.onPreferenceClickListener =
Preference.OnPreferenceClickListener setOnPreferenceClickListener@{ p: Preference ->
diff --git a/app/src/main/kotlin/com/fox2code/mmm/settings/PrivacyFragment.kt b/app/src/main/kotlin/com/fox2code/mmm/settings/PrivacyFragment.kt
index 7777d83..1e23cca 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/settings/PrivacyFragment.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/settings/PrivacyFragment.kt
@@ -13,7 +13,6 @@ import androidx.preference.PreferenceFragmentCompat
import androidx.preference.TwoStatePreference
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
-import com.fox2code.mmm.BuildConfig
import com.fox2code.mmm.MainActivity
import com.fox2code.mmm.MainApplication
import com.fox2code.mmm.R
@@ -76,7 +75,7 @@ class PrivacyFragment : PreferenceFragmentCompat() {
val mgr =
requireContext().getSystemService(AppCompatActivity.ALARM_SERVICE) as AlarmManager
mgr[AlarmManager.RTC, System.currentTimeMillis() + 100] = mPendingIntent
- if (BuildConfig.DEBUG) Timber.d("Restarting app to save crash reporting preference: %s", newValue)
+ if (MainApplication.forceDebugLogging) Timber.d("Restarting app to save crash reporting preference: %s", newValue)
exitProcess(0) // Exit app process
}
// Do not reverse the change if the user cancels the dialog
diff --git a/app/src/main/kotlin/com/fox2code/mmm/settings/RepoFragment.kt b/app/src/main/kotlin/com/fox2code/mmm/settings/RepoFragment.kt
index c8edea2..ca99ed3 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/settings/RepoFragment.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/settings/RepoFragment.kt
@@ -88,7 +88,7 @@ class RepoFragment : PreferenceFragmentCompat() {
requireContext().getSystemService(ALARM_SERVICE) as AlarmManager
mgr[AlarmManager.RTC, System.currentTimeMillis() + 100] =
mPendingIntent
- if (BuildConfig.DEBUG) Timber.d(
+ if (MainApplication.forceDebugLogging) Timber.d(
"Restarting app to save staging endpoint preference: %s",
newValue
)
@@ -130,7 +130,7 @@ class RepoFragment : PreferenceFragmentCompat() {
requireContext().getSystemService(ALARM_SERVICE) as AlarmManager
mgr[AlarmManager.RTC, System.currentTimeMillis() + 100] =
mPendingIntent
- if (BuildConfig.DEBUG) Timber.d(
+ if (MainApplication.forceDebugLogging) Timber.d(
"Restarting app to save staging endpoint preference: %s",
newValue
)
@@ -315,7 +315,7 @@ class RepoFragment : PreferenceFragmentCompat() {
requireContext().getSystemService(ALARM_SERVICE) as AlarmManager
mgr[AlarmManager.RTC, System.currentTimeMillis() + 100] =
mPendingIntent
- if (BuildConfig.DEBUG) Timber.d(
+ if (MainApplication.forceDebugLogging) Timber.d(
"Restarting app to save token preference: %s",
newValue
)
@@ -405,7 +405,7 @@ class RepoFragment : PreferenceFragmentCompat() {
) as AlarmManager
mgr[AlarmManager.RTC, System.currentTimeMillis() + 100] =
mPendingIntent
- if (BuildConfig.DEBUG) Timber.d(
+ if (MainApplication.forceDebugLogging) Timber.d(
"Restarting app to save token preference: %s",
newValue
)
@@ -463,13 +463,13 @@ class RepoFragment : PreferenceFragmentCompat() {
customRepos.add(id)
}
}
- if (BuildConfig.DEBUG) Timber.d("%d repos: %s", custRepoEntries, customRepos)
+ if (MainApplication.forceDebugLogging) Timber.d("%d repos: %s", custRepoEntries, customRepos)
val customRepoManager = RepoManager.getINSTANCE()!!.customRepoManager
for (i in 0 until custRepoEntries) {
// get the id of the repo at current index in customRepos
val repoData = customRepoManager!!.getRepo(customRepos[i])
// convert repoData to a json string for logging
- if (BuildConfig.DEBUG) Timber.d("RepoData for %d is %s", i, repoData.toJSON())
+ if (MainApplication.forceDebugLogging) Timber.d("RepoData for %d is %s", i, repoData.toJSON())
setRepoData(repoData, "pref_custom_repo_$i")
if (initial) {
val preference = findPreference("pref_custom_repo_" + i + "_delete")
@@ -591,29 +591,29 @@ class RepoFragment : PreferenceFragmentCompat() {
before: Int,
count: Int
) {
- Timber.i("checking repo url validity")
+ if (MainApplication.forceDebugLogging) Timber.i("checking repo url validity")
// show error if string is empty, does not start with https://, or contains spaces
if (charSequence.toString().isEmpty()) {
input.error = getString(R.string.empty_field)
- if (BuildConfig.DEBUG) Timber.d("No input for repo")
+ if (MainApplication.forceDebugLogging) Timber.d("No input for repo")
positiveButton.isEnabled = false
} else if (!charSequence.toString()
.matches("^https://.*".toRegex())
) {
input.error = getString(R.string.invalid_repo_url)
- if (BuildConfig.DEBUG) Timber.d("Non https link for repo")
+ if (MainApplication.forceDebugLogging) Timber.d("Non https link for repo")
positiveButton.isEnabled = false
} else if (charSequence.toString().contains(" ")) {
input.error = getString(R.string.invalid_repo_url)
- if (BuildConfig.DEBUG) Timber.d("Repo url has space")
+ if (MainApplication.forceDebugLogging) Timber.d("Repo url has space")
positiveButton.isEnabled = false
} else if (!customRepoManager.canAddRepo(charSequence.toString())) {
input.error = getString(R.string.repo_already_added)
- if (BuildConfig.DEBUG) Timber.d("Could not add repo for misc reason")
+ if (MainApplication.forceDebugLogging) Timber.d("Could not add repo for misc reason")
positiveButton.isEnabled = false
} else {
// enable ok button
- if (BuildConfig.DEBUG) Timber.d("Repo URL is ok")
+ if (MainApplication.forceDebugLogging) Timber.d("Repo URL is ok")
positiveButton.isEnabled = true
}
}
@@ -647,7 +647,7 @@ class RepoFragment : PreferenceFragmentCompat() {
private fun setRepoData(repoData: RepoData?, preferenceName: String) {
if (repoData == null) return
- if (BuildConfig.DEBUG) Timber.d("Setting preference $preferenceName to $repoData")
+ if (MainApplication.forceDebugLogging) Timber.d("Setting preference $preferenceName to $repoData")
val clipboard = requireContext().getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
var preference = findPreference(preferenceName) ?: return
if (!preferenceName.contains("androidacy") && !preferenceName.contains("magisk_alt_repo")) {
@@ -658,13 +658,13 @@ class RepoFragment : PreferenceFragmentCompat() {
"ReposList.db"
).allowMainThreadQueries().build()
val reposList = db.reposListDao().getById(repoData.preferenceId!!)
- if (BuildConfig.DEBUG) Timber.d("Setting preference $preferenceName because it is not the Androidacy repo or the Magisk Alt Repo")
+ if (MainApplication.forceDebugLogging) Timber.d("Setting preference $preferenceName because it is not the Androidacy repo or the Magisk Alt Repo")
if (repoData.isForceHide || reposList == null) {
- if (BuildConfig.DEBUG) Timber.d("Hiding preference $preferenceName because it is null or force hidden")
+ if (MainApplication.forceDebugLogging) Timber.d("Hiding preference $preferenceName because it is null or force hidden")
hideRepoData(preferenceName)
return
} else {
- if (BuildConfig.DEBUG) Timber.d(
+ if (MainApplication.forceDebugLogging) Timber.d(
"Showing preference %s because the forceHide status is %s and the RealmResults is %s",
preferenceName,
repoData.isForceHide,
@@ -727,7 +727,7 @@ class RepoFragment : PreferenceFragmentCompat() {
}
}
} else {
- if (BuildConfig.DEBUG) Timber.d("Hiding preference $preferenceName because it's data is null")
+ if (MainApplication.forceDebugLogging) Timber.d("Hiding preference $preferenceName because it's data is null")
hideRepoData(preferenceName)
return
}
diff --git a/app/src/main/kotlin/com/fox2code/mmm/settings/SecurityFragment.kt b/app/src/main/kotlin/com/fox2code/mmm/settings/SecurityFragment.kt
index e116fdc..ed6dfbe 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/settings/SecurityFragment.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/settings/SecurityFragment.kt
@@ -13,7 +13,6 @@ import androidx.preference.PreferenceFragmentCompat
import androidx.preference.TwoStatePreference
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
-import com.fox2code.mmm.BuildConfig
import com.fox2code.mmm.MainActivity
import com.fox2code.mmm.MainApplication
import com.fox2code.mmm.R
@@ -89,7 +88,7 @@ class SecurityFragment : PreferenceFragmentCompat() {
requireContext().getSystemService(AppCompatActivity.ALARM_SERVICE) as AlarmManager
mgr[AlarmManager.RTC, System.currentTimeMillis() + 100] =
mPendingIntent
- if (BuildConfig.DEBUG) Timber.d("Restarting app to save showcase mode preference: %s", v)
+ if (MainApplication.forceDebugLogging) Timber.d("Restarting app to save showcase mode preference: %s", v)
exitProcess(0) // Exit app process
}.setNegativeButton(R.string.cancel) { _: DialogInterface?, _: Int ->
// Revert to showcase mode on
@@ -112,7 +111,7 @@ class SecurityFragment : PreferenceFragmentCompat() {
requireContext().getSystemService(AppCompatActivity.ALARM_SERVICE) as AlarmManager
mgr[AlarmManager.RTC, System.currentTimeMillis() + 100] =
mPendingIntent
- if (BuildConfig.DEBUG) Timber.d("Restarting app to save showcase mode preference: %s", v)
+ if (MainApplication.forceDebugLogging) Timber.d("Restarting app to save showcase mode preference: %s", v)
exitProcess(0) // Exit app process
}.show()
}
diff --git a/app/src/main/kotlin/com/fox2code/mmm/settings/SettingsActivity.kt b/app/src/main/kotlin/com/fox2code/mmm/settings/SettingsActivity.kt
index ecde152..7ea9257 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/settings/SettingsActivity.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/settings/SettingsActivity.kt
@@ -71,7 +71,7 @@ class SettingsActivity : AppCompatActivity(), LanguageActivity,
}
- @SuppressLint("RestrictedApi")
+ @SuppressLint("RestrictedApi", "CommitTransaction")
override fun onCreate(savedInstanceState: Bundle?) {
devModeStep = 0
super.onCreate(savedInstanceState)
@@ -194,7 +194,7 @@ class SettingsActivity : AppCompatActivity(), LanguageActivity,
findPreference("pref_pkg_info")!!.onPreferenceClickListener =
Preference.OnPreferenceClickListener { p: Preference ->
versionClicks++
- if (BuildConfig.DEBUG) Timber.d("Version clicks: %d", versionClicks)
+ if (MainApplication.forceDebugLogging) Timber.d("Version clicks: %d", versionClicks)
if (versionClicks == 7) {
versionClicks = 0
openUrl(p.context, "https://www.youtube.com/watch?v=dQw4w9WgXcQ")
@@ -262,7 +262,7 @@ class SettingsActivity : AppCompatActivity(), LanguageActivity,
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
points += 1
}
- if (BuildConfig.DEBUG) Timber.d("Device performance class: %d", points)
+ if (MainApplication.forceDebugLogging) Timber.d("Device performance class: %d", points)
return if (points <= 7) {
PERFORMANCE_CLASS_LOW
} else if (points <= 12) {
@@ -274,6 +274,7 @@ class SettingsActivity : AppCompatActivity(), LanguageActivity,
}
+ @SuppressLint("CommitTransaction")
override fun onPreferenceStartFragment(
caller: PreferenceFragmentCompat, pref: Preference
): Boolean {
diff --git a/app/src/main/kotlin/com/fox2code/mmm/settings/SharedPreferenceDataStore.kt b/app/src/main/kotlin/com/fox2code/mmm/settings/SharedPreferenceDataStore.kt
index f0535d7..ec2df3a 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/settings/SharedPreferenceDataStore.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/settings/SharedPreferenceDataStore.kt
@@ -6,20 +6,20 @@ package com.fox2code.mmm.settings
import android.content.SharedPreferences
import androidx.preference.PreferenceDataStore
-import com.fox2code.mmm.BuildConfig
+import com.fox2code.mmm.MainApplication
import timber.log.Timber
class SharedPreferenceDataStore(sharedPreferences: SharedPreferences) : PreferenceDataStore() {
private val mSharedPreferences: SharedPreferences
init {
- if (BuildConfig.DEBUG) Timber.d("SharedPreferenceDataStore: %s", sharedPreferences)
+ if (MainApplication.forceDebugLogging) Timber.d("SharedPreferenceDataStore: %s", sharedPreferences)
mSharedPreferences = sharedPreferences
}
val sharedPreferences: SharedPreferences
get() {
- if (BuildConfig.DEBUG) Timber.d("getSharedPreferences: %s", mSharedPreferences)
+ if (MainApplication.forceDebugLogging) Timber.d("getSharedPreferences: %s", mSharedPreferences)
return mSharedPreferences
}
diff --git a/app/src/main/kotlin/com/fox2code/mmm/settings/UpdateFragment.kt b/app/src/main/kotlin/com/fox2code/mmm/settings/UpdateFragment.kt
index 53a6d2a..a608781 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/settings/UpdateFragment.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/settings/UpdateFragment.kt
@@ -85,7 +85,7 @@ class UpdateFragment : PreferenceFragmentCompat() {
do {
fakeVersion = random.nextInt(10)
} while (fakeVersion == 0)
- if (BuildConfig.DEBUG) Timber.d("Fake version: %s, count: %s", fakeVersion, i)
+ if (MainApplication.forceDebugLogging) Timber.d("Fake version: %s, count: %s", fakeVersion, i)
updateableModules["FakeModule $i"] = "1.0.$fakeVersion"
}
BackgroundUpdateChecker.postNotification(
@@ -157,7 +157,7 @@ class UpdateFragment : PreferenceFragmentCompat() {
moduleNames[i] = localModuleInfo!!.name
// Stringset uses id, we show name
checkedItems[i] = stringSet.contains(localModuleInfo.id)
- if (BuildConfig.DEBUG) Timber.d("name: %s, checked: %s", moduleNames[i], checkedItems[i])
+ if (MainApplication.forceDebugLogging) Timber.d("name: %s, checked: %s", moduleNames[i], checkedItems[i])
}
MaterialAlertDialogBuilder(requireContext()).setTitle(R.string.background_update_check_excludes)
.setMultiChoiceItems(
@@ -204,7 +204,7 @@ class UpdateFragment : PreferenceFragmentCompat() {
val stringSet = sharedPreferences.getStringSet(
"pref_background_update_check_excludes_version", HashSet()
)
- if (BuildConfig.DEBUG) Timber.d("stringSet: %s", stringSet)
+ if (MainApplication.forceDebugLogging) Timber.d("stringSet: %s", stringSet)
// for every module, add it's name and a text field to the dialog. the text field should accept a comma separated list of versions
val localModuleInfos: Collection =
ModuleManager.instance!!.modules.values
@@ -262,7 +262,7 @@ class UpdateFragment : PreferenceFragmentCompat() {
.setView(scrollView).setPositiveButton(
R.string.ok
) { _: DialogInterface?, _: Int ->
- if (BuildConfig.DEBUG) Timber.d("ok clicked")
+ if (MainApplication.forceDebugLogging) Timber.d("ok clicked")
// for every module, get the text field and save it to the stringset
val stringSetTemp: MutableSet = HashSet()
var prevMod = ""
@@ -286,9 +286,9 @@ class UpdateFragment : PreferenceFragmentCompat() {
localModuleInfo!!.name.equals(finalprevMod)
}.findFirst().orElse(null)!!.id + ":" + text
)
- if (BuildConfig.DEBUG) Timber.d("text is %s for %s", text, editText.hint.toString())
+ if (MainApplication.forceDebugLogging) Timber.d("text is %s for %s", text, editText.hint.toString())
} else {
- if (BuildConfig.DEBUG) Timber.d("text is empty for %s", editText.hint.toString())
+ if (MainApplication.forceDebugLogging) Timber.d("text is empty for %s", editText.hint.toString())
}
}
sharedPreferences.edit().putStringSet(
diff --git a/app/src/main/kotlin/com/fox2code/mmm/utils/ExternalHelper.kt b/app/src/main/kotlin/com/fox2code/mmm/utils/ExternalHelper.kt
index 35a133f..95d2af8 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/utils/ExternalHelper.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/utils/ExternalHelper.kt
@@ -17,6 +17,7 @@ import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.core.util.Supplier
import com.fox2code.mmm.Constants
+import com.fox2code.mmm.MainApplication
import com.topjohnwu.superuser.internal.UiThreadHandler
import timber.log.Timber
@@ -40,13 +41,13 @@ class ExternalHelper private constructor() {
)
}
if (resolveInfos.isEmpty()) {
- Timber.i("No external provider installed!")
+ if (MainApplication.forceDebugLogging) Timber.i("No external provider installed!")
label = if (TEST_MODE) "External" else null
multi = TEST_MODE
fallback = null
} else {
val resolveInfo = resolveInfos[0]
- Timber.i("Found external provider: %s", resolveInfo.activityInfo.packageName)
+ if (MainApplication.forceDebugLogging) Timber.i("Found external provider: %s", resolveInfo.activityInfo.packageName)
fallback =
ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name)
label = resolveInfo.loadLabel(context.packageManager)
diff --git a/app/src/main/kotlin/com/fox2code/mmm/utils/IntentHelper.kt b/app/src/main/kotlin/com/fox2code/mmm/utils/IntentHelper.kt
index b5f1b09..65a474a 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/utils/IntentHelper.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/utils/IntentHelper.kt
@@ -8,8 +8,8 @@ package com.fox2code.mmm.utils
import android.annotation.SuppressLint
import android.app.Activity
+import android.app.DownloadManager
import android.content.ActivityNotFoundException
-import android.content.ContentResolver
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
@@ -18,11 +18,12 @@ import android.os.Bundle
import android.os.Environment
import android.util.TypedValue
import android.widget.Toast
-import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityOptionsCompat
+import androidx.core.content.ContextCompat.getSystemService
import com.fox2code.mmm.BuildConfig
import com.fox2code.mmm.Constants
+import com.fox2code.mmm.MainActivity
import com.fox2code.mmm.MainApplication
import com.fox2code.mmm.R
import com.fox2code.mmm.XHooks.Companion.getConfigIntent
@@ -30,17 +31,11 @@ import com.fox2code.mmm.XHooks.Companion.isModuleActive
import com.fox2code.mmm.androidacy.AndroidacyActivity
import com.fox2code.mmm.installer.InstallerActivity
import com.fox2code.mmm.markdown.MarkdownActivity
-import com.fox2code.mmm.utils.io.Files.Companion.closeSilently
-import com.fox2code.mmm.utils.io.Files.Companion.copy
import com.fox2code.mmm.utils.io.net.Http.Companion.hasWebView
import com.topjohnwu.superuser.CallbackList
import com.topjohnwu.superuser.Shell
-import com.topjohnwu.superuser.io.SuFileInputStream
import timber.log.Timber
import java.io.File
-import java.io.FileOutputStream
-import java.io.InputStream
-import java.io.OutputStream
import java.net.URISyntaxException
@Suppress("unused")
@@ -75,7 +70,7 @@ enum class IntentHelper {;
@JvmOverloads
fun openUrl(context: Context, url: String?, forceBrowser: Boolean = false) {
- if (BuildConfig.DEBUG) Timber.d("Opening url: %s, forced browser %b", url, forceBrowser)
+ if (MainApplication.forceDebugLogging) Timber.d("Opening url: %s, forced browser %b", url, forceBrowser)
try {
val myIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
myIntent.flags = FLAG_GRANT_URI_PERMISSION
@@ -84,7 +79,7 @@ enum class IntentHelper {;
}
startActivity(context, myIntent, false)
} catch (e: ActivityNotFoundException) {
- if (BuildConfig.DEBUG) Timber.d(e, "Could not find suitable activity to handle url")
+ if (MainApplication.forceDebugLogging) Timber.d(e, "Could not find suitable activity to handle url")
Toast.makeText(
context, MainApplication.INSTANCE!!.lastActivity!!.getString(
R.string.no_browser
@@ -94,7 +89,7 @@ enum class IntentHelper {;
}
fun openCustomTab(context: Context, url: String?) {
- if (BuildConfig.DEBUG) Timber.d("Opening url: %s in custom tab", url)
+ if (MainApplication.forceDebugLogging) Timber.d("Opening url: %s in custom tab", url)
try {
val viewIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
viewIntent.flags = FLAG_GRANT_URI_PERMISSION
@@ -103,7 +98,7 @@ enum class IntentHelper {;
tabIntent.addCategory(Intent.CATEGORY_BROWSABLE)
startActivityEx(context, tabIntent, viewIntent)
} catch (e: ActivityNotFoundException) {
- if (BuildConfig.DEBUG) Timber.d(e, "Could not find suitable activity to handle url")
+ if (MainApplication.forceDebugLogging) Timber.d(e, "Could not find suitable activity to handle url")
Toast.makeText(
context, MainApplication.INSTANCE!!.lastActivity!!.getString(
R.string.no_browser
@@ -112,6 +107,56 @@ enum class IntentHelper {;
}
}
+ @SuppressLint("Range")
+ fun startDownloadUsingDownloadManager(context: Context, url: String?, title: String?) {
+ if (MainApplication.forceDebugLogging) Timber.d("Downloading url: %s", url)
+ val request = DownloadManager.Request(Uri.parse(url))
+ .setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI or DownloadManager.Request.NETWORK_MOBILE)
+ .setTitle((title?.replace(" ", "_") ?: "Module") + ".zip")
+ .setDescription(MainApplication.INSTANCE!!.lastActivity!!.getString(R.string.download_module_description, title))
+ .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
+ .setAllowedOverMetered(true)
+ .setAllowedOverRoaming(false)
+ .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, (title?.replace(" ", "_") ?: "Module") + ".zip")
+ val downloadManager= getSystemService(MainApplication.INSTANCE!!.lastActivity!!.applicationContext, DownloadManager::class.java)!!
+ val downloadID = downloadManager.enqueue(request)
+ Toast.makeText(
+ context, MainApplication.INSTANCE!!.lastActivity!!.getString(
+ R.string.download_started
+ ), Toast.LENGTH_LONG
+ ).show()
+ // listen for error
+ val query = DownloadManager.Query()
+ query.setFilterById(downloadID)
+ var downloading = true
+ while (downloading) {
+ try {
+ val cursor = downloadManager.query(query)
+ cursor.moveToFirst()
+ if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_FAILED) {
+ downloading = false
+ Toast.makeText(
+ context, MainApplication.INSTANCE!!.lastActivity!!.getString(
+ R.string.download_failed
+ ), Toast.LENGTH_LONG
+ ).show()
+ } else {
+ if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) {
+ downloading = false
+ Toast.makeText(
+ context, MainApplication.INSTANCE!!.lastActivity!!.getString(
+ R.string.download_finished
+ ), Toast.LENGTH_LONG
+ ).show()
+ }
+ }
+ cursor.close()
+ } catch (e: Exception) {
+ Timber.e(e)
+ }
+ }
+ }
+
@JvmOverloads
fun openUrlAndroidacy(
context: Context,
@@ -174,7 +219,7 @@ enum class IntentHelper {;
"am start -a android.intent.action.MAIN " + "-c org.lsposed.manager.LAUNCH_MANAGER " + "com.android.shell/.BugreportWarningActivity"
).to(object : CallbackList() {
override fun onAddElement(str: String?) {
- Timber.i("LSPosed: %s", str)
+ if (MainApplication.forceDebugLogging) Timber.i("LSPosed: %s", str)
}
}).submit()
return
@@ -355,13 +400,13 @@ enum class IntentHelper {;
return context
}
- private const val RESPONSE_ERROR = 0
+ const val RESPONSE_ERROR = 0
const val RESPONSE_FILE = 1
const val RESPONSE_URL = 2
@SuppressLint("SdCardPath")
fun openFileTo(
- compatActivity: AppCompatActivity, destination: File?, callback: OnFileReceivedCallback
+ destination: File?, callback: OnFileReceivedCallback
) {
var destinationFolder: File? = null
if ((destination == null) || (destination.parentFile.also {
@@ -371,61 +416,9 @@ enum class IntentHelper {;
callback.onReceived(destination, null, RESPONSE_ERROR)
return
}
- val getContent = compatActivity.registerForActivityResult(
- ActivityResultContracts.GetContent()
- ) { uri: Uri? ->
- if (uri == null) {
- Timber.d("invalid uri received")
- callback.onReceived(destination, null, RESPONSE_ERROR)
- return@registerForActivityResult
- }
- Timber.i("FilePicker returned %s", uri)
- if ("http" == uri.scheme || "https" == uri.scheme) {
- callback.onReceived(destination, uri, RESPONSE_URL)
- return@registerForActivityResult
- }
- if (ContentResolver.SCHEME_FILE == uri.scheme) {
- Toast.makeText(
- compatActivity, R.string.file_picker_wierd, Toast.LENGTH_SHORT
- ).show()
- }
- var inputStream: InputStream? = null
- var outputStream: OutputStream? = null
- var success = false
- try {
- if (ContentResolver.SCHEME_FILE == uri.scheme) {
- var path = uri.path
- if (path!!.startsWith("/sdcard/")) { // Fix file paths
- path =
- Environment.getExternalStorageDirectory().absolutePath + path.substring(
- 7
- )
- }
- inputStream = SuFileInputStream.open(
- File(path).absoluteFile
- )
- } else {
- inputStream = compatActivity.contentResolver.openInputStream(uri)
- }
- outputStream = FileOutputStream(destination)
- copy(inputStream!!, outputStream)
- Timber.i("File saved at %s", destination)
- success = true
- } catch (e: Exception) {
- Timber.e(e)
- Toast.makeText(
- compatActivity, R.string.file_picker_failure, Toast.LENGTH_SHORT
- ).show()
- } finally {
- closeSilently(inputStream)
- closeSilently(outputStream)
- if (!success && destination.exists() && !destination.delete()) Timber.e("Failed to delete artifact!")
- }
- callback.onReceived(
- destination, uri, if (success) RESPONSE_FILE else RESPONSE_ERROR
- )
- }
- getContent.launch("application/zip")
+ MainActivity.INSTANCE?.callback = callback
+ MainActivity.INSTANCE?.destination = destination
+ MainActivity.INSTANCE?.getContent?.launch("*/*")
}
}
}
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/fox2code/mmm/utils/RuntimeUtils.kt b/app/src/main/kotlin/com/fox2code/mmm/utils/RuntimeUtils.kt
index 13b9196..84871fd 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/utils/RuntimeUtils.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/utils/RuntimeUtils.kt
@@ -39,7 +39,7 @@ class RuntimeUtils {
@SuppressLint("RestrictedApi")
private fun ensurePermissions(context: Context, activity: MainActivity) {
- if (BuildConfig.DEBUG) Timber.i("Ensure Permissions")
+ if (MainApplication.forceDebugLogging) Timber.i("Ensure Permissions")
// First, check if user has said don't ask again by checking if pref_dont_ask_again_notification_permission is true
if (!PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean("pref_dont_ask_again_notification_permission", false)
@@ -48,14 +48,14 @@ class RuntimeUtils {
context, Manifest.permission.POST_NOTIFICATIONS
) != PackageManager.PERMISSION_GRANTED
) {
- if (BuildConfig.DEBUG) Timber.i("Request Notification Permission")
+ if (MainApplication.forceDebugLogging) Timber.i("Request Notification Permission")
if (MainApplication.INSTANCE!!.lastActivity!!
.shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)
) {
// Show a dialog explaining why we need context permission, which is to show
// notifications for updates
activity.runOnUiThread {
- if (BuildConfig.DEBUG) Timber.i("Show Notification Permission Dialog")
+ if (MainApplication.forceDebugLogging) Timber.i("Show Notification Permission Dialog")
val builder = MaterialAlertDialogBuilder(context)
builder.setTitle(R.string.permission_notification_title)
builder.setMessage(R.string.permission_notification_message)
@@ -87,18 +87,18 @@ class RuntimeUtils {
MainActivity.doSetupNowRunning = false
}
builder.show()
- if (BuildConfig.DEBUG) Timber.i("Show Notification Permission Dialog Done")
+ if (MainApplication.forceDebugLogging) Timber.i("Show Notification Permission Dialog Done")
}
} else {
// Request the permission
- if (BuildConfig.DEBUG) Timber.i("Request Notification Permission")
+ if (MainApplication.forceDebugLogging) Timber.i("Request Notification Permission")
activity.requestPermissions(arrayOf(Manifest.permission.POST_NOTIFICATIONS), 0)
if (BuildConfig.DEBUG) {
// Log if granted via onRequestPermissionsResult
val granted = ContextCompat.checkSelfPermission(
context, Manifest.permission.POST_NOTIFICATIONS
) == PackageManager.PERMISSION_GRANTED
- Timber.i("Request Notification Permission Done. Result: %s", granted)
+ if (MainApplication.forceDebugLogging) Timber.i("Request Notification Permission Done. Result: %s", granted)
}
MainActivity.doSetupNowRunning = false
}
@@ -145,7 +145,7 @@ class RuntimeUtils {
MainActivity.doSetupNowRunning = false
}
} else {
- if (BuildConfig.DEBUG) Timber.i("Notification Permission Already Granted or Don't Ask Again")
+ if (MainApplication.forceDebugLogging) Timber.i("Notification Permission Already Granted or Don't Ask Again")
MainActivity.doSetupNowRunning = false
}
}
@@ -156,7 +156,7 @@ class RuntimeUtils {
// Method to show a setup box on first launch
@SuppressLint("InflateParams", "RestrictedApi", "UnspecifiedImmutableFlag", "ApplySharedPref")
fun checkShowInitialSetup(context: Context, activity: MainActivity) {
- if (BuildConfig.DEBUG) Timber.i("Checking if we need to run setup")
+ if (MainApplication.forceDebugLogging) Timber.i("Checking if we need to run setup")
// Check if context is the first launch using prefs and if doSetupRestarting was passed in the intent
val prefs = MainApplication.getSharedPreferences("mmm")!!
var firstLaunch = prefs.getString("last_shown_setup", null) != "v5"
@@ -167,7 +167,7 @@ class RuntimeUtils {
firstLaunch = false
}
if (BuildConfig.DEBUG) {
- Timber.i(
+ if (MainApplication.forceDebugLogging) Timber.i(
"First launch: %s, pref value: %s",
firstLaunch,
prefs.getString("last_shown_setup", null)
@@ -176,7 +176,7 @@ class RuntimeUtils {
if (firstLaunch) {
MainActivity.doSetupNowRunning = true
// Launch setup wizard
- if (BuildConfig.DEBUG) Timber.i("Launching setup wizard")
+ if (MainApplication.forceDebugLogging) Timber.i("Launching setup wizard")
// Show setup activity
val intent = Intent(context, SetupActivity::class.java)
activity.finish()
@@ -190,7 +190,7 @@ class RuntimeUtils {
* @return true if the load workflow must be stopped.
*/
fun waitInitialSetupFinished(context: Context, activity: MainActivity): Boolean {
- if (BuildConfig.DEBUG) Timber.i("waitInitialSetupFinished")
+ if (MainApplication.forceDebugLogging) Timber.i("waitInitialSetupFinished")
try {
// Wait for doSetupNow to finish
while (MainActivity.doSetupNowRunning) {
@@ -244,7 +244,7 @@ class RuntimeUtils {
*/
@SuppressLint("RestrictedApi")
fun showUpgradeSnackbar(context: Context, activity: MainActivity) {
- Timber.i("showUpgradeSnackbar start")
+ if (MainApplication.forceDebugLogging) Timber.i("showUpgradeSnackbar start")
// if sb is already showing, wait 4 seconds and try again
if (MainActivity.isShowingWeblateSb) {
Handler(Looper.getMainLooper()).postDelayed({
@@ -271,7 +271,7 @@ class RuntimeUtils {
snackbar.show()
// do not show for another 7 days
prefs.edit().putLong("ugsns4", System.currentTimeMillis()).apply()
- Timber.i("showUpgradeSnackbar done")
+ if (MainApplication.forceDebugLogging) Timber.i("showUpgradeSnackbar done")
}
companion object {
diff --git a/app/src/main/kotlin/com/fox2code/mmm/utils/ZipFileOpener.kt b/app/src/main/kotlin/com/fox2code/mmm/utils/ZipFileOpener.kt
index 780f129..ec118fd 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/utils/ZipFileOpener.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/utils/ZipFileOpener.kt
@@ -10,6 +10,7 @@ import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import com.fox2code.mmm.BuildConfig
+import com.fox2code.mmm.MainApplication
import com.fox2code.mmm.R
import com.fox2code.mmm.installer.InstallerInitializer.Companion.peekMagiskPath
import com.fox2code.mmm.utils.IntentHelper.Companion.openInstaller
@@ -40,7 +41,7 @@ class ZipFileOpener : AppCompatActivity() {
}
.show()
Thread(Runnable {
- if (BuildConfig.DEBUG) Timber.d("onCreate: %s", intent)
+ if (MainApplication.forceDebugLogging) Timber.d("onCreate: %s", intent)
val zipFile: File
val uri = intent.data
if (uri == null) {
@@ -108,7 +109,7 @@ class ZipFileOpener : AppCompatActivity() {
}
return@Runnable
} else {
- if (BuildConfig.DEBUG) Timber.d("onCreate: Zip file is " + zipFile.length() + " bytes")
+ if (MainApplication.forceDebugLogging) Timber.d("onCreate: Zip file is " + zipFile.length() + " bytes")
}
var entry: ZipEntry?
var zip: ZipFile? = null
@@ -120,7 +121,7 @@ class ZipFileOpener : AppCompatActivity() {
if (zip.getEntry("module.prop").also { entry = it } == null) {
Timber.e("onCreate: Zip file is not a valid magisk module")
if (BuildConfig.DEBUG) {
- if (BuildConfig.DEBUG) Timber.d(
+ if (MainApplication.forceDebugLogging) Timber.d(
"onCreate: Zip file contents: %s",
zip.stream().map { obj: ZipEntry -> obj.name }
.reduce { a: String, b: String -> "$a, $b" }.orElse("empty")
@@ -147,7 +148,7 @@ class ZipFileOpener : AppCompatActivity() {
}
return@Runnable
}
- if (BuildConfig.DEBUG) Timber.d("onCreate: Zip file is valid")
+ if (MainApplication.forceDebugLogging) Timber.d("onCreate: Zip file is valid")
var moduleInfo: String?
try {
moduleInfo = readModulePropSimple(zip.getInputStream(entry), "name")
diff --git a/app/src/main/kotlin/com/fox2code/mmm/utils/io/Files.kt b/app/src/main/kotlin/com/fox2code/mmm/utils/io/Files.kt
index 1b7bc4c..9642f6e 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/utils/io/Files.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/utils/io/Files.kt
@@ -9,7 +9,6 @@ import android.net.Uri
import android.os.Build
import android.provider.OpenableColumns
import android.util.Log
-import com.fox2code.mmm.BuildConfig
import com.fox2code.mmm.MainApplication
import com.topjohnwu.superuser.io.SuFile
import com.topjohnwu.superuser.io.SuFileInputStream
@@ -222,7 +221,7 @@ enum class Files {
throw IOException("Unable to create temp unzip dir")
}
// unzip
- if (BuildConfig.DEBUG) Timber.d("Unzipping module to %s", tempUnzipDir.absolutePath)
+ if (MainApplication.forceDebugLogging) Timber.d("Unzipping module to %s", tempUnzipDir.absolutePath)
try {
ZipFile(tempFile).use { zipFile ->
var files = zipFile.entries
@@ -280,7 +279,7 @@ enum class Files {
Timber.e(e, "Unable to zip up module")
}
} else {
- if (BuildConfig.DEBUG) Timber.d("Module does not have a single folder in the top level, skipping")
+ if (MainApplication.forceDebugLogging) Timber.d("Module does not have a single folder in the top level, skipping")
}
}
} catch (e: IOException) {
diff --git a/app/src/main/kotlin/com/fox2code/mmm/utils/io/GMSProviderInstaller.kt b/app/src/main/kotlin/com/fox2code/mmm/utils/io/GMSProviderInstaller.kt
index bc24019..e6400c2 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/utils/io/GMSProviderInstaller.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/utils/io/GMSProviderInstaller.kt
@@ -5,6 +5,7 @@ package com.fox2code.mmm.utils.io
import android.content.Context
import android.content.pm.PackageManager
+import com.fox2code.mmm.MainApplication
import timber.log.Timber
/**
@@ -34,7 +35,7 @@ enum class GMSProviderInstaller {
val cl =
remote.classLoader.loadClass("com.google.android.gms.common.security.ProviderInstallerImpl")
cl.getDeclaredMethod("insertProvider", Context::class.java).invoke(null, remote)
- Timber.i("Installed GMS security providers!")
+ if (MainApplication.forceDebugLogging) Timber.i("Installed GMS security providers!")
} catch (e: PackageManager.NameNotFoundException) {
Timber.w("No GMS Implementation are installed on this device")
} catch (e: Exception) {
diff --git a/app/src/main/kotlin/com/fox2code/mmm/utils/io/Hashes.kt b/app/src/main/kotlin/com/fox2code/mmm/utils/io/Hashes.kt
index e926453..5fe1429 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/utils/io/Hashes.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/utils/io/Hashes.kt
@@ -2,10 +2,9 @@
* Copyright (c) 2023 to present Androidacy and contributors. Names, logos, icons, and the Androidacy name are all trademarks of Androidacy and may not be used without license. See LICENSE for more information.
*/
-@file:Suppress("UNUSED_PARAMETER")
-
package com.fox2code.mmm.utils.io
+import com.fox2code.mmm.MainApplication
import timber.log.Timber
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
@@ -66,7 +65,7 @@ enum class Hashes {;
return false
}
}
- Timber.i("Checksum result (data: $hash,expected: $checksum)")
+ if (MainApplication.forceDebugLogging) Timber.i("Checksum result (data: $hash,expected: $checksum)")
return hash == checksum.lowercase()
}
diff --git a/app/src/main/kotlin/com/fox2code/mmm/utils/io/PropUtils.kt b/app/src/main/kotlin/com/fox2code/mmm/utils/io/PropUtils.kt
index e4796f2..66bd816 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/utils/io/PropUtils.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/utils/io/PropUtils.kt
@@ -7,6 +7,7 @@ package com.fox2code.mmm.utils.io
import android.os.Build
import android.text.TextUtils
import com.fox2code.mmm.AppUpdateManager
+import com.fox2code.mmm.MainApplication
import com.fox2code.mmm.manager.ModuleInfo
import com.topjohnwu.superuser.io.SuFileInputStream
import timber.log.Timber
@@ -392,7 +393,7 @@ enum class PropUtils {
}
}
} catch (e: IOException) {
- Timber.i(e)
+ if (MainApplication.forceDebugLogging) Timber.i(e)
}
return moduleId
}
diff --git a/app/src/main/kotlin/com/fox2code/mmm/utils/io/net/Http.kt b/app/src/main/kotlin/com/fox2code/mmm/utils/io/net/Http.kt
index f176e51..20aa046 100644
--- a/app/src/main/kotlin/com/fox2code/mmm/utils/io/net/Http.kt
+++ b/app/src/main/kotlin/com/fox2code/mmm/utils/io/net/Http.kt
@@ -247,7 +247,7 @@ enum class Http {;
0, dot
).toInt()
}
- if (BuildConfig.DEBUG) Timber.d(
+ if (MainApplication.forceDebugLogging) Timber.d(
"Webview version: %s (%d)", webviewVersion, webviewVersionCode
)
hasWebView =
@@ -414,7 +414,7 @@ enum class Http {;
httpClientWithCache = followRedirects(httpclientBuilder, true).build()
httpclientBuilder.dns(fallbackDNS!!)
httpClientWithCacheDoH = followRedirects(httpclientBuilder, true).build()
- Timber.i("Initialized Http successfully!")
+ if (MainApplication.forceDebugLogging) Timber.i("Initialized Http successfully!")
doh = MainApplication.isDohEnabled
}
@@ -481,7 +481,7 @@ enum class Http {;
throw HttpException(e.message, 0)
}
if (BuildConfig.DEBUG_HTTP) {
- if (BuildConfig.DEBUG) Timber.d("doHttpGet: request executed")
+ if (MainApplication.forceDebugLogging) Timber.d("doHttpGet: request executed")
}
// 200/204 == success, 304 == cache valid
if (response != null) {
@@ -502,7 +502,7 @@ enum class Http {;
if (retryAfter != null) {
try {
val seconds = Integer.parseInt(retryAfter)
- if (BuildConfig.DEBUG) Timber.d("Sleeping for $seconds seconds")
+ if (MainApplication.forceDebugLogging) Timber.d("Sleeping for $seconds seconds")
Thread.sleep(seconds * 1000L)
} catch (e: NumberFormatException) {
Timber.e(e, "Failed to parse Retry-After header")
@@ -512,7 +512,7 @@ enum class Http {;
} else {// start with one second and try up to five times
if (limitedRetries < 5) {
limitedRetries++
- if (BuildConfig.DEBUG) Timber.d("Sleeping for 1 second")
+ if (MainApplication.forceDebugLogging) Timber.d("Sleeping for 1 second")
try {
Thread.sleep(1000L * limitedRetries)
} catch (e: InterruptedException) {
@@ -528,7 +528,7 @@ enum class Http {;
}
}
if (BuildConfig.DEBUG_HTTP) {
- if (BuildConfig.DEBUG) Timber.d("doHttpGet: " + url.replace("=[^&]*".toRegex(), "=****") + " succeeded")
+ if (MainApplication.forceDebugLogging) Timber.d("doHttpGet: " + url.replace("=[^&]*".toRegex(), "=****") + " succeeded")
}
var responseBody = response?.body
// Use cache api if used cached response
@@ -540,7 +540,7 @@ enum class Http {;
}
if (BuildConfig.DEBUG_HTTP) {
if (responseBody != null) {
- if (BuildConfig.DEBUG) Timber.d("doHttpGet: returning " + responseBody.contentLength() + " bytes")
+ if (MainApplication.forceDebugLogging) Timber.d("doHttpGet: returning " + responseBody.contentLength() + " bytes")
}
}
if (MainApplication.analyticsAllowed() && MainApplication.isCrashReportingEnabled) {
@@ -559,7 +559,7 @@ enum class Http {;
@Throws(IOException::class)
private fun doHttpPostRaw(url: String, data: String, allowCache: Boolean): Any {
- if (BuildConfig.DEBUG) Timber.d("POST %s", url)
+ if (MainApplication.forceDebugLogging) Timber.d("POST %s", url)
val uniqid = randomUUID().toString()
if (MainApplication.analyticsAllowed() && MainApplication.isCrashReportingEnabled) {
@@ -588,7 +588,7 @@ enum class Http {;
}
if (response.isRedirect) {
// follow redirect with same method
- if (BuildConfig.DEBUG) Timber.d("doHttpPostRaw: following redirect: %s", response.header("Location"))
+ if (MainApplication.forceDebugLogging) Timber.d("doHttpPostRaw: following redirect: %s", response.header("Location"))
response =
(if (allowCache) getHttpClientWithCache() else getHttpClient())!!.newCall(
Request.Builder().url(
@@ -607,7 +607,7 @@ enum class Http {;
if (retryAfter != null) {
try {
val seconds = Integer.parseInt(retryAfter)
- if (BuildConfig.DEBUG) Timber.d("Sleeping for $seconds seconds")
+ if (MainApplication.forceDebugLogging) Timber.d("Sleeping for $seconds seconds")
Thread.sleep(seconds * 1000L)
} catch (e: NumberFormatException) {
Timber.e(e, "Failed to parse Retry-After header")
@@ -617,7 +617,7 @@ enum class Http {;
} else {// start with one second and try up to five times
if (limitedRetries < 5) {
limitedRetries++
- if (BuildConfig.DEBUG) Timber.d("Sleeping for 1 second")
+ if (MainApplication.forceDebugLogging) Timber.d("Sleeping for 1 second")
try {
Thread.sleep(1000L * limitedRetries)
} catch (e: InterruptedException) {
@@ -678,7 +678,7 @@ enum class Http {;
if (retryAfter != null) {
try {
val seconds = Integer.parseInt(retryAfter)
- if (BuildConfig.DEBUG) Timber.d("Sleeping for $seconds seconds")
+ if (MainApplication.forceDebugLogging) Timber.d("Sleeping for $seconds seconds")
Thread.sleep(seconds * 1000L)
} catch (e: NumberFormatException) {
Timber.e(e, "Failed to parse Retry-After header")
@@ -688,7 +688,7 @@ enum class Http {;
} else {// start with one second and try up to five times
if (limitedRetries < 5) {
limitedRetries++
- if (BuildConfig.DEBUG) Timber.d("Sleeping for 1 second")
+ if (MainApplication.forceDebugLogging) Timber.d("Sleeping for 1 second")
try {
Thread.sleep(1000L * limitedRetries)
} catch (e: InterruptedException) {
@@ -716,7 +716,7 @@ enum class Http {;
val updateInterval: Long = 100
var nextUpdate = System.currentTimeMillis() + updateInterval
var currentUpdate: Long
- Timber.i("Target: $target Divider: $divider")
+ if (MainApplication.forceDebugLogging) Timber.i("Target: $target Divider: $divider")
progressListener.onUpdate(0, (target / divider).toInt(), false)
while (true) {
val read = inputStream.read(buff)
@@ -758,7 +758,7 @@ enum class Http {;
}
fun setDoh(doh: Boolean) {
- Timber.i("DoH: " + Companion.doh + " -> " + doh)
+ if (MainApplication.forceDebugLogging) Timber.i("DoH: " + Companion.doh + " -> " + doh)
Companion.doh = doh
}
@@ -780,19 +780,19 @@ enum class Http {;
val systemSaysYes = networkCapabilities != null && networkCapabilities.hasCapability(
NetworkCapabilities.NET_CAPABILITY_INTERNET
)
- if (BuildConfig.DEBUG) Timber.d("System says we have internet: $systemSaysYes")
+ if (MainApplication.forceDebugLogging) Timber.d("System says we have internet: $systemSaysYes")
// if we don't already have a listener, add one, so we can invalidate the cache when the network changes
if (connectivityListener == null) {
connectivityListener = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
- if (BuildConfig.DEBUG) Timber.d("Network became available")
+ if (MainApplication.forceDebugLogging) Timber.d("Network became available")
lastConnectivityCheck = 0
}
override fun onLost(network: Network) {
super.onLost(network)
- if (BuildConfig.DEBUG) Timber.d("Network became unavailable")
+ if (MainApplication.forceDebugLogging) Timber.d("Network became unavailable")
lastConnectivityCheck = 0
}
}
@@ -809,7 +809,7 @@ enum class Http {;
Timber.e(e, "Failed to check internet connection")
false
}
- if (BuildConfig.DEBUG) Timber.d("We say we have internet: $hasInternet")
+ if (MainApplication.forceDebugLogging) Timber.d("We say we have internet: $hasInternet")
lastConnectivityCheck = System.currentTimeMillis()
@Suppress("KotlinConstantConditions")
lastConnectivityResult =
diff --git a/app/src/main/res/layout/module_entry.xml b/app/src/main/res/layout/module_entry.xml
index 8a897ab..9091669 100644
--- a/app/src/main/res/layout/module_entry.xml
+++ b/app/src/main/res/layout/module_entry.xml
@@ -12,7 +12,7 @@
android:layout_height="wrap_content"
android:layout_margin="4dp"
app:cardCornerRadius="8dp"
- app:cardElevation="4dp"
+ app:cardElevation="1dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 84fb056..bcd6e5e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -404,4 +404,12 @@
An Androidacy app
v0.x by Fox2Code
Versions before 0.6.8 were developed by Fox2Code and versions up to 1.1 were contributed to by him. We thank him for his work.
+ Forces debug logging in release builds. CAUTION: this may slow down the app significantly. Please do not turn on unless requested by support.
+ Force debug logging
+ Started downloading
+ Downloading Module %s
+ Download finished and saved to default download folder
+ Failed to download!
+ Finished downloading and saved to downloads folder
+ The file you picked is not a valid zip file.
diff --git a/app/src/main/res/xml/debugging_preferences.xml b/app/src/main/res/xml/debugging_preferences.xml
index 019664b..4ff4004 100644
--- a/app/src/main/res/xml/debugging_preferences.xml
+++ b/app/src/main/res/xml/debugging_preferences.xml
@@ -30,6 +30,15 @@
app:singleLineTitle="false"
app:summary="@string/use_magisk_install_command_desc"
app:title="@string/use_magisk_install_command_pref" />
+
+