prepare work for 2.3.0

- initial work on UNTESTED ksu support
- prepare for play release
- don't try to get magisk path if no root
- remove debug logging entirely on release builds
  - if we set an if condition to a constant falsey value, r8 is nice enough to remove it for us
- more that i really don't care to document

Signed-off-by: androidacy-user <opensource@androidacy.com>
pull/89/head
androidacy-user 2 years ago
parent 33383f2656
commit 3f38a8db0f

@ -34,7 +34,7 @@ android {
val timestamp = System.currentTimeMillis()
namespace = "com.fox2code.mmm"
compileSdk = 33
compileSdk = 34
ndkVersion = "25.2.9519653"
signingConfigs {
create("release") {
@ -52,9 +52,9 @@ android {
defaultConfig {
applicationId = "com.fox2code.mmm"
minSdk = 24
targetSdk = 33
versionCode = 81
versionName = "2.2.3"
targetSdk = 34
versionCode = 82
versionName = "2.3.0"
vectorDrawables {
useSupportLibrary = true
}
@ -460,11 +460,11 @@ dependencies {
// UI
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("androidx.activity:activity-ktx:1.7.2")
implementation("androidx.emoji2:emoji2:1.3.0")
implementation("androidx.emoji2:emoji2-views-helper:1.3.0")
implementation("androidx.preference:preference-ktx:1.2.0")
implementation("androidx.emoji2:emoji2:1.4.0")
implementation("androidx.emoji2:emoji2-views-helper:1.4.0")
implementation("androidx.preference:preference-ktx:1.2.1")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("androidx.recyclerview:recyclerview:1.3.0")
implementation("androidx.recyclerview:recyclerview:1.3.1")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
implementation("androidx.webkit:webkit:1.7.0")
implementation("com.google.android.material:material:1.9.0")
@ -498,12 +498,12 @@ dependencies {
implementation("com.github.Fox2Code:AndroidANSI:1.2.1")
// sentry
implementation("io.sentry:sentry-android:6.25.2")
implementation("io.sentry:sentry-android-timber:6.25.2")
implementation("io.sentry:sentry-android-fragment:6.25.2")
implementation("io.sentry:sentry-android-okhttp:6.25.2")
implementation("io.sentry:sentry-kotlin-extensions:6.25.2")
implementation("io.sentry:sentry-android-ndk:6.25.2")
implementation("io.sentry:sentry-android:6.28.0")
implementation("io.sentry:sentry-android-timber:6.28.0")
implementation("io.sentry:sentry-android-fragment:6.28.0")
implementation("io.sentry:sentry-android-okhttp:6.28.0")
implementation("io.sentry:sentry-kotlin-extensions:6.28.0")
implementation("io.sentry:sentry-android-ndk:6.28.0")
// Markdown
// TODO: switch to an updated implementation
@ -543,7 +543,7 @@ dependencies {
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.3")
// yes
implementation("com.github.fingerprintjs:fingerprint-android:2.0.0")
implementation("com.github.fingerprintjs:fingerprint-android:2.0.2")
// room
implementation("androidx.room:room-runtime:2.5.2")

@ -44,7 +44,7 @@ class AppUpdateManager private constructor() {
lastChecked < System.currentTimeMillis() - 60000L
) return force && peekShouldUpdate()
synchronized(updateLock) {
Timber.d("Checking for app updates")
if (BuildConfig.DEBUG) Timber.d("Checking for app updates")
if (lastChecked != this.lastChecked) return peekShouldUpdate()
// make a request to https://production-api.androidacy.com/amm/updates/check with appVersionCode and token/device_id/client_id
var token = AndroidacyRepoData.token
@ -59,7 +59,7 @@ class AppUpdateManager private constructor() {
val response = doHttpGet(url, false)
// convert response to string
val responseString = String(response, Charsets.UTF_8)
Timber.d("Response: $responseString")
if (BuildConfig.DEBUG) Timber.d("Response: $responseString")
// json response has a boolean shouldUpdate and an int latestVersion
JSONObject(responseString).let {
if (it.getBoolean("shouldUpdate")) {
@ -105,7 +105,7 @@ class AppUpdateManager private constructor() {
@Throws(IOException::class)
private fun parseCompatibilityFlags(inputStream: InputStream) {
compatDataId.clear()
Timber.d("Not implemented")
if (BuildConfig.DEBUG) Timber.d("Not implemented")
}
fun getCompatibilityFlags(moduleId: String): Int {

@ -28,7 +28,7 @@ class CrashHandler : FoxActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
Timber.i("CrashHandler.onCreate(%s)", savedInstanceState)
// log intent with extras
Timber.d("CrashHandler.onCreate: intent=%s", intent)
if (BuildConfig.DEBUG) Timber.d("CrashHandler.onCreate: intent=%s", intent)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_crash_handler)
// set crash_details MaterialTextView to the exception passed in the intent or unknown if null
@ -58,7 +58,7 @@ class CrashHandler : FoxActivity() {
if (lastEventId?.matches("^0+$".toRegex()) == true) {
lastEventId = ""
}
Timber.d(
if (BuildConfig.DEBUG) Timber.d(
"CrashHandler.onCreate: lastEventId=%s, crashReportingEnabled=%s",
lastEventId,
crashReportingEnabled
@ -71,7 +71,7 @@ class CrashHandler : FoxActivity() {
val submit = findViewById<View>(R.id.feedback_submit)
if (lastEventId.isNullOrEmpty() && crashReportingEnabled) {
// if lastEventId is null, hide the feedback button
Timber.d("CrashHandler.onCreate: lastEventId is null but crash reporting is enabled. This may indicate a bug in the crash reporting system.")
if (BuildConfig.DEBUG) Timber.d("CrashHandler.onCreate: lastEventId is null but crash reporting is enabled. This may indicate a bug in the crash reporting system.")
submit.visibility = View.GONE
findViewById<MaterialTextView>(R.id.feedback_text).setText(R.string.no_sentry_id)
} else {

@ -139,7 +139,7 @@ class MainActivity : FoxActivity(), OnRefreshListener, SearchView.OnQueryTextLis
if (ts.time > buildTime.time) {
val pm = packageManager
val intent = Intent(this, ExpiredActivity::class.java)
@Suppress("DEPRECATION") val resolveInfo = pm.queryIntentActivities(intent, 0)
val resolveInfo = pm.queryIntentActivities(intent, 0)
if (resolveInfo.size > 0) {
startActivity(intent)
finish()
@ -231,11 +231,8 @@ class MainActivity : FoxActivity(), OnRefreshListener, SearchView.OnQueryTextLis
.create()
rebootDialog.show()
}
// get background color and elevation of reboot fab
val searchCard = searchCard!!
// copy reboot fab style to search card
searchCard.elevation = rebootFab.elevation
searchCard.translationY = rebootFab.translationY
searchCard.foreground = rebootFab.foreground
moduleList.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
if (newState != RecyclerView.SCROLL_STATE_IDLE) searchView.clearFocus()
@ -307,8 +304,6 @@ class MainActivity : FoxActivity(), OnRefreshListener, SearchView.OnQueryTextLis
TrackHelper.track().event("view_list", "settings")
.with(MainApplication.INSTANCE!!.tracker)
startActivity(Intent(this@MainActivity, SettingsActivity::class.java))
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
finish()
}
R.id.online_menu_item -> {
@ -388,9 +383,17 @@ class MainActivity : FoxActivity(), OnRefreshListener, SearchView.OnQueryTextLis
tryGetMagiskPathAsync(object : InstallerInitializer.Callback {
override fun onPathReceived(path: String?) {
Timber.i("Got magisk path: %s", path)
if (peekMagiskVersion() < Constants.MAGISK_VER_CODE_INSTALL_COMMAND) moduleViewListBuilder.addNotification(
NotificationType.MAGISK_OUTDATED
)
if (peekMagiskVersion() < Constants.MAGISK_VER_CODE_INSTALL_COMMAND) {
if (!InstallerInitializer.isKsu) {
moduleViewListBuilder.addNotification(
NotificationType.MAGISK_OUTDATED
)
} else {
moduleViewListBuilder.addNotification(
NotificationType.KSU_EXPERIMENTAL
)
}
}
if (!MainApplication.isShowcaseMode) moduleViewListBuilder.addNotification(
NotificationType.INSTALL_FROM_STORAGE
)
@ -409,7 +412,7 @@ class MainActivity : FoxActivity(), OnRefreshListener, SearchView.OnQueryTextLis
fun commonNext() {
if (BuildConfig.DEBUG) {
Timber.d("Common next")
if (BuildConfig.DEBUG) Timber.d("Common next")
moduleViewListBuilder.addNotification(NotificationType.DEBUG)
}
NotificationType.NO_INTERNET.autoAdd(moduleViewListBuilderOnline)
@ -426,7 +429,7 @@ class MainActivity : FoxActivity(), OnRefreshListener, SearchView.OnQueryTextLis
updateScreenInsets() // Fix an edge case
val context: Context = this@MainActivity
if (runtimeUtils!!.waitInitialSetupFinished(context, this@MainActivity)) {
Timber.d("waiting...")
if (BuildConfig.DEBUG) Timber.d("waiting...")
return
}
swipeRefreshBlocker = System.currentTimeMillis() + 5000L
@ -869,7 +872,7 @@ class MainActivity : FoxActivity(), OnRefreshListener, SearchView.OnQueryTextLis
// wait for up to 10 seconds for AndroidacyRepoData to be initialized
var i: Int
if (AndroidacyRepoData.instance.isEnabled && AndroidacyRepoData.instance.memberLevel == null) {
Timber.d("Member level is null, waiting for it to be initialized")
if (BuildConfig.DEBUG) Timber.d("Member level is null, waiting for it to be initialized")
i = 0
while (AndroidacyRepoData.instance.memberLevel == null && i < 20) {
i++

@ -264,24 +264,24 @@ class MainApplication : FoxApplication(), Configuration.Provider {
fileUtils.ensureCacheDirs()
fileUtils.ensureURLHandler(this)
}
Timber.d("Initializing AMM")
Timber.d("Started from background: %s", !isInForeground)
Timber.d("AMM is running in debug mode")
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")
// analytics
Timber.d("Initializing matomo")
if (BuildConfig.DEBUG) Timber.d("Initializing matomo")
getTracker()
if (!isMatomoAllowed()) {
Timber.d("Matomo is not allowed")
if (BuildConfig.DEBUG) Timber.d("Matomo is not allowed")
tracker!!.isOptOut = true
} else {
tracker!!.isOptOut = false
}
if (getSharedPreferences("matomo")!!.getBoolean("install_tracked", false)) {
TrackHelper.track().download().with(INSTANCE!!.getTracker())
Timber.d("Sent install event to matomo")
if (BuildConfig.DEBUG) Timber.d("Sent install event to matomo")
getSharedPreferences("matomo")!!.edit().putBoolean("install_tracked", true).apply()
} else {
Timber.d("Matomo already has install")
if (BuildConfig.DEBUG) Timber.d("Matomo already has install")
}
try {
@Suppress("DEPRECATION") @SuppressLint("PackageManagerGetSignatures") val s =
@ -413,12 +413,12 @@ class MainApplication : FoxApplication(), Configuration.Provider {
val activityManager = this.getSystemService(ACTIVITY_SERVICE) as ActivityManager
val appProcesses = activityManager.runningAppProcesses
if (appProcesses == null) {
Timber.d("appProcesses is null")
if (BuildConfig.DEBUG) Timber.d("appProcesses is null")
return false
}
val packageName = this.packageName
for (appProcess in appProcesses) {
Timber.d(
if (BuildConfig.DEBUG) Timber.d(
"Process: %s, Importance: %d", appProcess.processName, appProcess.importance
)
if (appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName == packageName) {
@ -503,6 +503,14 @@ class MainApplication : FoxApplication(), Configuration.Provider {
init {
Shell.setDefaultBuilder(Shell.Builder.create()
.setFlags(Shell.FLAG_REDIRECT_STDERR or Shell.FLAG_MOUNT_MASTER).setTimeout(15))
// set verbose logging for debug builds
if (BuildConfig.DEBUG) {
Shell.enableVerboseLogging = true
}
// prewarm shell
Shell.getShell {
// do nothing
}
val random = Random()
do {
secret = random.nextLong()

@ -3,12 +3,16 @@
*/
@file:Suppress(
"KotlinConstantConditions", "UNINITIALIZED_ENUM_COMPANION_WARNING",
"ktConcatNullable", "BlockingMethodInNonBlockingContext", "UnusedEquals"
"KotlinConstantConditions",
"UNINITIALIZED_ENUM_COMPANION_WARNING",
"ktConcatNullable",
"BlockingMethodInNonBlockingContext",
"UnusedEquals"
)
package com.fox2code.mmm
import android.content.Intent
import android.net.Uri
import android.view.View
import android.widget.Toast
@ -33,7 +37,7 @@ import java.util.Date
import java.util.zip.ZipFile
enum class NotificationType constructor(
enum class NotificationType(
@field:StringRes @param:StringRes @JvmField val textId: Int,
@field:DrawableRes @JvmField val iconId: Int,
@field:AttrRes @JvmField val backgroundAttr: Int = androidx.appcompat.R.attr.colorError,
@ -43,10 +47,10 @@ enum class NotificationType constructor(
) : NotificationTypeCst {
@JvmStatic
DEBUG(
R.string.debug_build,
DEBUG(R.string.debug_build,
R.drawable.ic_baseline_bug_report_24,
com.google.android.material.R.attr.colorPrimary, com.google.android.material.R.attr.colorOnPrimary,
com.google.android.material.R.attr.colorPrimary,
com.google.android.material.R.attr.colorOnPrimary,
// on click show a toast formatted with commit hash and build date, plus number of days before expiration (builds expire 30 days after build date)
View.OnClickListener { v: View ->
val buildTime = BuildConfig.BUILD_TIME
@ -62,12 +66,9 @@ enum class NotificationType constructor(
30 - buildTimeDays
)
Toast.makeText(
v.context,
toastText,
Toast.LENGTH_LONG
v.context, toastText, Toast.LENGTH_LONG
).show()
}
) {
}) {
override fun shouldRemove(): Boolean {
return !BuildConfig.DEBUG
}
@ -75,8 +76,10 @@ enum class NotificationType constructor(
@JvmStatic
SHOWCASE_MODE(
R.string.showcase_mode, R.drawable.ic_baseline_lock_24,
com.google.android.material.R.attr.colorPrimary, com.google.android.material.R.attr.colorOnPrimary
R.string.showcase_mode,
R.drawable.ic_baseline_lock_24,
com.google.android.material.R.attr.colorPrimary,
com.google.android.material.R.attr.colorOnPrimary
) {
override fun shouldRemove(): Boolean {
return !MainApplication.isShowcaseMode
@ -84,13 +87,11 @@ enum class NotificationType constructor(
},
@JvmStatic
NO_MAGISK(
R.string.fail_magisk_missing,
NO_MAGISK(R.string.fail_magisk_missing,
R.drawable.ic_baseline_numbers_24,
View.OnClickListener { v: View ->
IntentHelper.openUrl(
v.context,
"https://github.com/topjohnwu/Magisk/blob/master/docs/install.md"
v.context, "https://github.com/topjohnwu/Magisk/blob/master/docs/install.md"
)
}) {
override fun shouldRemove(): Boolean {
@ -111,19 +112,15 @@ enum class NotificationType constructor(
},
@JvmStatic
MAGISK_OUTDATED(
R.string.magisk_outdated,
MAGISK_OUTDATED(R.string.magisk_outdated,
R.drawable.ic_baseline_update_24,
View.OnClickListener { v: View ->
IntentHelper.openUrl(
v.context,
"https://github.com/topjohnwu/Magisk/releases"
v.context, "https://github.com/topjohnwu/Magisk/releases"
)
}) {
override fun shouldRemove(): Boolean {
return InstallerInitializer.peekMagiskPath() == null ||
InstallerInitializer.peekMagiskVersion() >=
Constants.MAGISK_VER_CODE_INSTALL_COMMAND
return InstallerInitializer.peekMagiskPath() == null || InstallerInitializer.peekMagiskVersion() >= Constants.MAGISK_VER_CODE_INSTALL_COMMAND
}
},
@ -142,18 +139,15 @@ enum class NotificationType constructor(
},
@JvmStatic
NEED_CAPTCHA_ANDROIDACY(
R.string.androidacy_need_captcha,
NEED_CAPTCHA_ANDROIDACY(R.string.androidacy_need_captcha,
R.drawable.ic_baseline_refresh_24,
View.OnClickListener { v: View ->
IntentHelper.openUrlAndroidacy(
v.context,
"https://" + Http.needCaptchaAndroidacyHost() + "/", false
v.context, "https://" + Http.needCaptchaAndroidacyHost() + "/", false
)
}) {
override fun shouldRemove(): Boolean {
return (!RepoManager.isAndroidacyRepoEnabled
|| !Http.needCaptchaAndroidacy())
return (!RepoManager.isAndroidacyRepoEnabled || !Http.needCaptchaAndroidacy())
}
},
@ -171,10 +165,21 @@ enum class NotificationType constructor(
androidx.appcompat.R.attr.colorPrimary,
com.google.android.material.R.attr.colorOnPrimary,
View.OnClickListener { v: View ->
IntentHelper.openUrl(
// launch update activity with action download
val pendingIntent = android.app.PendingIntent.getActivity(
v.context,
"https://github.com/Androidacy/MagiskModuleManager/releases"
0,
Intent(
v.context,
UpdateActivity::class.java
).setAction(UpdateActivity.ACTIONS.DOWNLOAD.toString()),
android.app.PendingIntent.FLAG_UPDATE_CURRENT
)
try {
pendingIntent.send()
} catch (e: android.app.PendingIntent.CanceledException) {
Timber.e(e)
}
},
false
) {
@ -192,30 +197,31 @@ enum class NotificationType constructor(
View.OnClickListener { v: View? ->
val compatActivity = FoxActivity.getFoxActivity(v)
val module = File(
compatActivity.cacheDir,
"installer" + File.separator + "module.zip"
compatActivity.cacheDir, "installer" + File.separator + "module.zip"
)
IntentHelper.openFileTo(compatActivity, module) { d: File, u: Uri, s: Int ->
if (s == IntentHelper.RESPONSE_FILE) {
try {
if (needPatch(d)) {
patchModuleSimple(
read(d),
FileOutputStream(d)
read(d), FileOutputStream(d)
)
}
if (needPatch(d)) {
if (d.exists() && !d.delete()) Timber.w("Failed to delete non module zip")
Toast.makeText(
compatActivity,
R.string.invalid_format, Toast.LENGTH_SHORT
compatActivity, R.string.invalid_format, Toast.LENGTH_SHORT
).show()
} else {
IntentHelper.openInstaller(
compatActivity, d.absolutePath,
compatActivity,
d.absolutePath,
compatActivity.getString(
R.string.local_install_title
), null, null, false,
),
null,
null,
false,
BuildConfig.DEBUG && // Use debug mode if no root
InstallerInitializer.peekMagiskPath() == null
)
@ -223,17 +229,14 @@ enum class NotificationType constructor(
} catch (ignored: IOException) {
if (d.exists() && !d.delete()) Timber.w("Failed to delete invalid module")
Toast.makeText(
compatActivity,
R.string.invalid_format, Toast.LENGTH_SHORT
compatActivity, R.string.invalid_format, Toast.LENGTH_SHORT
).show()
}
} else if (s == IntentHelper.RESPONSE_URL) {
IntentHelper.openInstaller(
compatActivity, u.toString(),
compatActivity.getString(
compatActivity, u.toString(), compatActivity.getString(
R.string.remote_install_title
), null, null, false,
BuildConfig.DEBUG && // Use debug mode if no root
), null, null, false, BuildConfig.DEBUG && // Use debug mode if no root
InstallerInitializer.peekMagiskPath() == null
)
}
@ -242,9 +245,19 @@ enum class NotificationType constructor(
false
) {
override fun shouldRemove(): Boolean {
return !BuildConfig.DEBUG &&
(MainApplication.isShowcaseMode ||
InstallerInitializer.peekMagiskPath() == null)
return !BuildConfig.DEBUG && (MainApplication.isShowcaseMode || InstallerInitializer.peekMagiskPath() == null)
}
},
KSU_EXPERIMENTAL(
R.string.ksu_experimental,
R.drawable.ic_baseline_warning_24,
androidx.appcompat.R.attr.colorError,
com.google.android.material.R.attr.colorOnPrimary,
null,
false
) {
override fun shouldRemove(): Boolean {
return !BuildConfig.DEBUG && (MainApplication.isShowcaseMode || InstallerInitializer.peekMagiskPath() == null || !InstallerInitializer.isKsu)
}
};

@ -211,9 +211,9 @@ class SetupActivity : FoxActivity(), LanguageActivity {
setupButton.setOnClickListener { _: View? ->
Timber.i("Setup button clicked")
// get instance of editor
Timber.d("Saving preferences")
if (BuildConfig.DEBUG) Timber.d("Saving preferences")
val editor = prefs.edit()
Timber.d("Got editor: %s", editor)
if (BuildConfig.DEBUG) Timber.d("Got editor: %s", editor)
// Set the Automatic update check pref
editor.putBoolean(
"pref_background_update_check", (Objects.requireNonNull<Any>(
@ -247,7 +247,7 @@ class SetupActivity : FoxActivity(), LanguageActivity {
"pref_analytics_enabled",
(Objects.requireNonNull<Any>(view.findViewById(R.id.setup_app_analytics)) as MaterialSwitch).isChecked
)
Timber.d("Saving preferences")
if (BuildConfig.DEBUG) Timber.d("Saving preferences")
// now basically do the same thing for room db
val db = Room.databaseBuilder(
applicationContext,
@ -256,7 +256,7 @@ class SetupActivity : FoxActivity(), LanguageActivity {
val androidacyRepoRoom = andRepoView.isChecked
val magiskAltRepoRoom = magiskAltRepoView.isChecked
val reposListDao = db.reposListDao()
Timber.d(reposListDao.getAll().toString())
if (BuildConfig.DEBUG) Timber.d(reposListDao.getAll().toString())
val androidacyRepoRoomObj = reposListDao.getById("androidacy_repo")
val magiskAltRepoRoomObj = reposListDao.getById("magisk_alt_repo")
reposListDao.setEnabled(androidacyRepoRoomObj.id, androidacyRepoRoom)
@ -266,11 +266,11 @@ class SetupActivity : FoxActivity(), LanguageActivity {
// Commit the changes
editor.commit()
// Log the changes
Timber.d("Setup finished. Preferences: %s", prefs.all)
Timber.d("Androidacy repo: %s", androidacyRepoRoom)
Timber.d("Magisk Alt repo: %s", magiskAltRepoRoom)
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)
// log last shown setup
Timber.d("Last shown setup: %s", prefs.getString("last_shown_setup", "v0"))
if (BuildConfig.DEBUG) Timber.d("Last shown setup: %s", prefs.getString("last_shown_setup", "v0"))
// Restart the activity
MainActivity.doSetupRestarting = true
val pendingIntent = PendingIntent.getActivity(
@ -350,7 +350,7 @@ class SetupActivity : FoxActivity(), LanguageActivity {
// creates the room database
private fun createDatabases() {
val thread = Thread {
Timber.d("Creating databases")
if (BuildConfig.DEBUG) Timber.d("Creating databases")
val startTime = System.currentTimeMillis()
val appContext = MainApplication.INSTANCE!!.applicationContext
val db = Room.databaseBuilder(appContext, ReposListDatabase::class.java, "ReposList.db")
@ -432,7 +432,7 @@ class SetupActivity : FoxActivity(), LanguageActivity {
).show()
}
} else {
Timber.d("ReposList is updated with 2 entries")
if (BuildConfig.DEBUG) Timber.d("ReposList is updated with 2 entries")
}
// make sure modulelistcache is updated with 1 entry
if (moduleListCacheList.size != 1) {
@ -446,12 +446,12 @@ class SetupActivity : FoxActivity(), LanguageActivity {
).show()
}
} else {
Timber.d("ModuleListCache is updated with 1 entry")
if (BuildConfig.DEBUG) Timber.d("ModuleListCache is updated with 1 entry")
}
// close the databases
db.close()
db2.close()
Timber.d("Databases created in %s ms", System.currentTimeMillis() - startTime)
if (BuildConfig.DEBUG) Timber.d("Databases created in %s ms", System.currentTimeMillis() - startTime)
}
thread.start()
}
@ -490,7 +490,7 @@ class SetupActivity : FoxActivity(), LanguageActivity {
val componentName = ComponentName(this, UpdateActivity::class.java)
val componentEnabledSetting = pm.getComponentEnabledSetting(componentName)
if (componentEnabledSetting == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
Timber.d("Disabling update activity for fdroid flavor")
if (BuildConfig.DEBUG) Timber.d("Disabling update activity for fdroid flavor")
// disable update activity through package manager
pm.setComponentEnabledSetting(
componentName,

@ -82,7 +82,7 @@ class AndroidacyRepoData(cacheRoot: File?, testMode: Boolean) : RepoData(
// response is JSON
val jsonObject = JSONObject(String(resp))
memberLevel = jsonObject.getString("role")
Timber.d("Member level: %s", memberLevel)
if (BuildConfig.DEBUG) Timber.d("Member level: %s", memberLevel)
val memberPermissions = jsonObject.getJSONArray("permissions")
// set role and permissions on userInfo property
userInfo = arrayOf(
@ -133,13 +133,12 @@ class AndroidacyRepoData(cacheRoot: File?, testMode: Boolean) : RepoData(
"https://" + host + "/auth/register?fmt=json&device_id=" + deviceId + "&client_id=" + BuildConfig.ANDROIDACY_CLIENT_ID,
false
)
var token: String
try {
val token: String = try {
val jsonObject = JSONObject(String(resp))
token = jsonObject.getString("token")
jsonObject.getString("token")
} catch (e: JSONException) {
if (String(resp).count() == 64) {
token = String(resp)
String(resp)
} else {
return ""
}
@ -264,7 +263,7 @@ class AndroidacyRepoData(cacheRoot: File?, testMode: Boolean) : RepoData(
@Throws(JSONException::class)
override fun populate(jsonObject: JSONObject): List<RepoModule>? {
var jsonObject = jsonObject
Timber.d("AndroidacyRepoData populate start")
if (BuildConfig.DEBUG) 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
@ -285,18 +284,16 @@ class AndroidacyRepoData(cacheRoot: File?, testMode: Boolean) : RepoData(
}
val newModules = ArrayList<RepoModule>()
val len = jsonArray.length()
// stringify json array for logging but only log the first 200 characters
val tempJsonArray = jsonArray.toString()
Timber.d(
"AndroidacyRepoData populate loop start with json %s",
if (tempJsonArray.length > 200) tempJsonArray.substring(0, 200) else tempJsonArray
)
var lastLastUpdate: Long = 0
for (i in 0 until len) {
try {
jsonObject = jsonArray.getJSONObject(i)
if (!jsonArray.isNull(i)) {
jsonObject = jsonArray.getJSONObject(i)
} else {
if (BuildConfig.DEBUG) Timber.d("Skipping null module at index %d", i)
continue
}
} catch (e: JSONException) {
Timber.e(e, "Failed to parse module")
continue
}
val moduleId: String = try {

@ -74,7 +74,7 @@ class AndroidacyWebAPI(
checksum: String?,
canInstall: Boolean
) {
if (BuildConfig.DEBUG) Timber.d(
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d(
"ModuleDialog, downloadUrl: " + hideToken(
moduleUrl!!
) + ", moduleId: " + moduleId + ", installTitle: " + installTitle + ", checksum: " + checksum + ", canInstall: " + canInstall
@ -174,7 +174,7 @@ class AndroidacyWebAPI(
fun notifyCompatModeRaw(value: Int) {
var value = value
if (consumedAction) return
if (BuildConfig.DEBUG) Timber.d("Androidacy Compat mode: %s", value)
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d("Androidacy Compat mode: %s", value)
notifiedCompatMode = value
if (value < 0) {
value = 0
@ -208,7 +208,7 @@ class AndroidacyWebAPI(
if (consumedAction) return
consumedAction = true
downloadMode = false
if (BuildConfig.DEBUG) Timber.d("Received openUrl request: %s", url)
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d("Received openUrl request: %s", url)
if (Uri.parse(url).scheme == "https") {
openUrl(activity, url)
}
@ -222,7 +222,7 @@ class AndroidacyWebAPI(
if (consumedAction) return
consumedAction = true
downloadMode = false
if (BuildConfig.DEBUG) Timber.d("Received openCustomTab request: %s", url)
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d("Received openCustomTab request: %s", url)
if (Uri.parse(url).scheme == "https") {
openCustomTab(activity, url)
}
@ -266,7 +266,7 @@ class AndroidacyWebAPI(
}
consumedAction = true
downloadMode = false
if (BuildConfig.DEBUG) Timber.d("Received install request: $moduleUrl $installTitle $checksum")
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d("Received install request: $moduleUrl $installTitle $checksum")
if (!isAndroidacyLink(moduleUrl)) {
forceQuitRaw("Non Androidacy module link used on Androidacy")
return

@ -179,7 +179,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 {
Timber.d("Not posting notification because of missing permission")
if (BuildConfig.DEBUG) Timber.d("Not posting notification because of missing permission")
}
ModuleManager.instance!!.scanAsync()
RepoManager.getINSTANCE()!!.update(null)
@ -212,7 +212,7 @@ class BackgroundUpdateChecker(context: Context, workerParams: WorkerParameters)
for (s in stringSet!!) {
if (s.startsWith(localModuleInfo.id)) {
version = s
Timber.d("igV: %s", version)
if (BuildConfig.DEBUG) Timber.d("igV: %s", version)
break
}
}
@ -223,7 +223,7 @@ class BackgroundUpdateChecker(context: Context, workerParams: WorkerParameters)
remoteVersionCode = repoModule.moduleInfo.versionCode.toString()
}
if (version.isNotEmpty()) {
Timber.d("igV found: %s", version)
if (BuildConfig.DEBUG) Timber.d("igV found: %s", version)
val remoteVersionCodeInt = remoteVersionCode.toInt()
val wantsVersion =
version.split(":".toRegex()).dropLastWhile { it.isEmpty() }
@ -233,23 +233,23 @@ class BackgroundUpdateChecker(context: Context, workerParams: WorkerParameters)
version = version.split(":".toRegex()).dropLastWhile { it.isEmpty() }
.toTypedArray()[1]
if (version.startsWith("^")) {
Timber.d("igV: newer")
if (BuildConfig.DEBUG) Timber.d("igV: newer")
// the wantsversion and newer
if (remoteVersionCodeInt >= wantsVersion) {
Timber.d("igV: skipping")
if (BuildConfig.DEBUG) Timber.d("igV: skipping")
// if it is, we skip it
continue
}
} else if (version.endsWith("$")) {
Timber.d("igV: older")
if (BuildConfig.DEBUG) Timber.d("igV: older")
// this wantsversion and older
if (remoteVersionCodeInt <= wantsVersion) {
Timber.d("igV: skipping")
if (BuildConfig.DEBUG) Timber.d("igV: skipping")
// if it is, we skip it
continue
}
} else if (wantsVersion == remoteVersionCodeInt) {
Timber.d("igV: equal")
if (BuildConfig.DEBUG) Timber.d("igV: equal")
// if it is, we skip it
continue
}
@ -273,7 +273,7 @@ class BackgroundUpdateChecker(context: Context, workerParams: WorkerParameters)
}
}
if (moduleUpdateCount != 0) {
Timber.d("Found %d updates", moduleUpdateCount)
if (BuildConfig.DEBUG) Timber.d("Found %d updates", moduleUpdateCount)
postNotification(context, updateableModules, moduleUpdateCount, false)
}
}
@ -287,10 +287,10 @@ class BackgroundUpdateChecker(context: Context, workerParams: WorkerParameters)
try {
val shouldUpdate = AppUpdateManager.appUpdateManager.checkUpdate(true)
if (shouldUpdate) {
Timber.d("Found app update")
if (BuildConfig.DEBUG) Timber.d("Found app update")
postNotificationForAppUpdate(context)
} else {
Timber.d("No app update found")
if (BuildConfig.DEBUG) Timber.d("No app update found")
}
} catch (e: Exception) {
Timber.e("Failed to check for app update")
@ -303,7 +303,7 @@ class BackgroundUpdateChecker(context: Context, workerParams: WorkerParameters)
Manifest.permission.POST_NOTIFICATIONS
) == PackageManager.PERMISSION_GRANTED
) {
Timber.d("Removing notification")
if (BuildConfig.DEBUG) Timber.d("Removing notification")
val notificationManager = NotificationManagerCompat.from(context)
notificationManager.cancel(NOTIFICATION_ID_ONGOING)
}
@ -420,11 +420,11 @@ class BackgroundUpdateChecker(context: Context, workerParams: WorkerParameters)
).build()
)
notificationManagerCompat.cancel(NOTIFICATION_ID_ONGOING)
Timber.d("Scheduling periodic background check")
if (BuildConfig.DEBUG) 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()
Timber.d("Frequency: $frequency minutes")
if (BuildConfig.DEBUG) Timber.d("Frequency: $frequency minutes")
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
"background_checker",
ExistingPeriodicWorkPolicy.UPDATE,

@ -4,6 +4,7 @@
package com.fox2code.mmm.installer
import com.fox2code.mmm.BuildConfig
import com.fox2code.mmm.Constants
import com.fox2code.mmm.MainApplication
import com.fox2code.mmm.NotificationType
@ -21,6 +22,7 @@ class InstallerInitializer {
}
companion object {
var isKsu: Boolean = false
private val MAGISK_SBIN = File("/sbin/magisk")
private val MAGISK_SYSTEM = File("/system/bin/magisk")
private val MAGISK_SYSTEM_EX = File("/system/xbin/magisk")
@ -120,13 +122,18 @@ class InstallerInitializer {
var hsRmdsk = hsRmdsk
if (mgskPth != null && !forceCheck) return mgskPth
val output = ArrayList<String>()
if (Shell.isAppGrantedRoot() == null || !Shell.isAppGrantedRoot()!!) {
return null
}
try {
if (!Shell.cmd(
"if grep ' / ' /proc/mounts | grep -q '/dev/root' &> /dev/null; " + "then echo true; else echo false; fi",
"magisk -V",
"magisk --path"
"su -V",
).to(output).exec().isSuccess
) {
if (BuildConfig.DEBUG) {
Timber.i("Failed to search for ramdisk")
}
if (output.size != 0) {
hsRmdsk = "false" == output[0] || "true".equals(
System.getProperty("ro.build.ab_update"), ignoreCase = true
@ -135,21 +142,45 @@ class InstallerInitializer {
Companion.hsRmdsk = hsRmdsk
return null
}
mgskPth = if (output.size < 3) "" else output[2]
if (BuildConfig.DEBUG) {
Timber.i("Found ramdisk: %s", output[0])
Timber.i("Searching for Magisk path. Current path: %s", mgskPth)
}
// reset output
output.clear()
// try to use magisk --path. if that fails, check for /data/adb/ksu for kernelsu support
if (Shell.cmd("magisk --path", "su -V").to(output).exec().isSuccess) {
mgskPth = output[0]
if (BuildConfig.DEBUG) {
Timber.i("Magisk path 1: %s", mgskPth)
}
} else if (Shell.cmd("if [ -f /data/adb/ksu ]; then echo true; else echo false; fi").to(
output
).exec().isSuccess && "true" == output[0]
) {
mgskPth = "/data/adb"
isKsu = true
}
Timber.i("Magisk runtime path: %s", mgskPth)
mgskVerCode = output[1].toInt()
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())
) {
mgskPth = "/sbin"
if (mgskPth != null) {
if (mgskVerCode >= Constants.MAGISK_VER_CODE_FLAT_MODULES && mgskVerCode < Constants.MAGISK_VER_CODE_PATH_SUPPORT && (mgskPth.isEmpty() || !File(
mgskPth
).exists())
) {
mgskPth = "/sbin"
}
}
if (mgskPth.isNotEmpty() && existsSU(File(mgskPth))) {
Companion.mgskPth = mgskPth
if (mgskPth != null) {
if (mgskPth.isNotEmpty() && existsSU(File(mgskPth))) {
Companion.mgskPth = mgskPth
} else {
Timber.e("Failed to get Magisk path (Got $mgskPth)")
mgskPth = null
}
} else {
Timber.e("Failed to get Magisk path (Got $mgskPth)")
mgskPth = null
Timber.e("Failed to get Magisk path (Got null)")
}
Companion.mgskVerCode = mgskVerCode
return mgskPth

@ -58,7 +58,7 @@ class ModuleManager private constructor() : SyncManager() {
if (!FORCE_NEED_FALLBACK && needFallback) {
Timber.e("using fallback instead.")
}
if (BuildConfig.DEBUG) Timber.d("Scan")
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d("Scan")
val modulesList = StringBuilder()
if (modules != null) {
Timber.i("Found %d modules on device in data", modules.size)
@ -69,7 +69,7 @@ class ModuleManager private constructor() : SyncManager() {
).allowMainThreadQueries().build()
for (module in modules) {
if (!SuFile("/data/adb/modules/$module").isDirectory) continue // Ignore non directory files inside modules folder
Timber.d("Found module %s", module)
if (BuildConfig.DEBUG) 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 +80,7 @@ class ModuleManager private constructor() : SyncManager() {
moduleInfo = LocalModuleInfo(module)
}
if (moduleListCacheDao.exists(module)) {
Timber.d("Found cache for %s", module)
if (BuildConfig.DEBUG) Timber.d("Found cache for %s", module)
val moduleListCache: ModuleListCache = moduleListCacheDao.getByCodename(module)
moduleInfo.name =
if (moduleListCache.name != "") moduleListCache.name else module
@ -130,7 +130,7 @@ class ModuleManager private constructor() : SyncManager() {
moduleInfo, "/data/adb/modules/$module/module.prop", true
)
} catch (e: Exception) {
if (BuildConfig.DEBUG) Timber.d(e)
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d(e)
moduleInfo.flags = moduleInfo.flags or FLAG_MM_INVALID
}
moduleInfos[module] = moduleInfo
@ -148,12 +148,12 @@ class ModuleManager private constructor() : SyncManager() {
// send list to matomo
TrackHelper.track().event("installed_modules", modulesList.toString())
.with(MainApplication.INSTANCE!!.tracker)
if (BuildConfig.DEBUG) Timber.d("Scan update")
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) 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) Timber.d(module)
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d(module)
var moduleInfo = moduleInfos[module]
if (moduleInfo == null) {
moduleInfo = LocalModuleInfo(module)
@ -166,17 +166,17 @@ class ModuleManager private constructor() : SyncManager() {
moduleInfo, "/data/adb/modules_update/$module/module.prop", true
)
} catch (e: Exception) {
if (BuildConfig.DEBUG) Timber.d(e)
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d(e)
moduleInfo.flags = moduleInfo.flags or FLAG_MM_INVALID
}
}
}
if (BuildConfig.DEBUG) Timber.d("Finalize scan")
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d("Finalize scan")
updatableModuleCount = 0
val moduleInfoIterator = moduleInfos.values.iterator()
while (moduleInfoIterator.hasNext()) {
val moduleInfo = moduleInfoIterator.next()
if (BuildConfig.DEBUG) Timber.d(moduleInfo.id)
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d(moduleInfo.id)
if (moduleInfo.flags and FLAG_MM_UNPROCESSED != 0) {
moduleInfoIterator.remove()
continue // Don't process fallbacks if unreferenced
@ -225,7 +225,7 @@ class ModuleManager private constructor() : SyncManager() {
@Suppress("unused")
fun setEnabledState(moduleInfo: ModuleInfo, checked: Boolean): Boolean {
Timber.d("setEnabledState(%s, %s)", moduleInfo.id, checked)
if (BuildConfig.DEBUG) 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) {

@ -4,6 +4,7 @@
package com.fox2code.mmm.markdown
import com.fox2code.mmm.BuildConfig
import timber.log.Timber
enum class MarkdownUrlLinker {
@ -33,7 +34,7 @@ enum class MarkdownUrlLinker {
if (endDomain != -1 && endDomain < end && endCh != '>' && endCh != ')' && endCh != ']') {
linkifyTasks.add(LinkifyTask(index, end))
extra += end - index + 4
Timber.d("Linkify url: %s", url.substring(end))
if (BuildConfig.DEBUG) Timber.d("Linkify url: %s", url.substring(end))
}
}
index = url.indexOf("https://", end)

@ -13,6 +13,7 @@ import android.widget.Toast
import androidx.annotation.DrawableRes
import com.fox2code.foxcompat.app.FoxActivity
import com.fox2code.foxcompat.view.FoxDisplay
import com.fox2code.mmm.BuildConfig
import com.fox2code.mmm.MainApplication.Companion.INSTANCE
import com.fox2code.mmm.MainApplication.Companion.isShowcaseMode
import com.fox2code.mmm.R
@ -387,7 +388,7 @@ enum class ActionButtonType {
REMOTE {
@Suppress("NAME_SHADOWING")
override fun doAction(button: Chip, moduleHolder: ModuleHolder) {
Timber.d("doAction: remote module for %s", moduleHolder.moduleInfo?.name ?: "null")
if (BuildConfig.DEBUG) 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
@ -441,18 +442,18 @@ enum class ActionButtonType {
madb.setPositiveButton(
R.string.reinstall
) { _: DialogInterface?, _: Int ->
Timber.d("Set moduleinfo to %s", moduleInfo.name)
if (BuildConfig.DEBUG) Timber.d("Set moduleinfo to %s", moduleInfo.name)
val name: String? = if (moduleHolder.moduleInfo != null) {
moduleHolder.moduleInfo!!.name
} else {
moduleHolder.repoModule?.moduleInfo?.name
}
Timber.d("doAction: remote module for %s", name)
if (BuildConfig.DEBUG) Timber.d("doAction: remote module for %s", name)
TrackHelper.track().event("view_update_install", name)
.with(INSTANCE!!.getTracker())
// Androidacy manage the selection between download and install
if (isAndroidacyLink(updateZipUrl)) {
Timber.d("Androidacy link detected")
if (BuildConfig.DEBUG) Timber.d("Androidacy link detected")
openUrlAndroidacy(
button.context,
updateZipUrl,

@ -7,6 +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.Companion.INSTANCE
import com.fox2code.mmm.MainApplication.Companion.formatTime
import com.fox2code.mmm.MainApplication.Companion.getSharedPreferences
@ -136,13 +137,13 @@ class ModuleHolder : Comparable<ModuleHolder?> {
HashSet()
)
var version = ""
Timber.d(stringSetT.toString())
if (BuildConfig.DEBUG) 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
Timber.d("igV: %s", version)
if (BuildConfig.DEBUG) Timber.d("igV: %s", version)
break
}
}
@ -156,34 +157,34 @@ class ModuleHolder : Comparable<ModuleHolder?> {
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
Timber.d("igV start with")
if (BuildConfig.DEBUG) Timber.d("igV start with")
version =
version.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[1]
// this version and newer
if (version.startsWith("^")) {
Timber.d("igV: newer")
if (BuildConfig.DEBUG) Timber.d("igV: newer")
// the wantsversion and newer
if (remoteVersionCodeInt >= wantsVersion) {
Timber.d("igV: skipping")
if (BuildConfig.DEBUG) Timber.d("igV: skipping")
// if it is, we skip it
ignoreUpdate = true
}
} else if (version.endsWith("$")) {
Timber.d("igV: older")
if (BuildConfig.DEBUG) Timber.d("igV: older")
// this wantsversion and older
if (remoteVersionCodeInt <= wantsVersion) {
Timber.d("igV: skipping")
if (BuildConfig.DEBUG) Timber.d("igV: skipping")
// if it is, we skip it
ignoreUpdate = true
}
} else if (wantsVersion == remoteVersionCodeInt) {
Timber.d("igV: equal")
if (BuildConfig.DEBUG) Timber.d("igV: equal")
// if it is, we skip it
ignoreUpdate = true
}
}
if (ignoreUpdate) {
Timber.d("Module %s has update, but is ignored", moduleId)
if (BuildConfig.DEBUG) Timber.d("Module %s has update, but is ignored", moduleId)
Type.INSTALLABLE
} else {
INSTANCE!!.modulesHaveUpdates = true
@ -191,7 +192,7 @@ class ModuleHolder : Comparable<ModuleHolder?> {
INSTANCE!!.updateModules += moduleId
INSTANCE!!.updateModuleCount++
}
Timber.d(
if (BuildConfig.DEBUG) Timber.d(
"modulesHaveUpdates = %s, updateModuleCount = %s",
INSTANCE!!.modulesHaveUpdates,
INSTANCE!!.updateModuleCount
@ -248,16 +249,16 @@ class ModuleHolder : Comparable<ModuleHolder?> {
// set updatezipurl on moduleholder
if (localModuleInfo.updateZipUrl != null) {
Timber.d("localModuleInfo: %s", localModuleInfo.updateZipUrl)
if (BuildConfig.DEBUG) Timber.d("localModuleInfo: %s", localModuleInfo.updateZipUrl)
updateZipUrl = localModuleInfo.updateZipUrl
}
if (repoModule != null) {
Timber.d("repoModule: %s", repoModule!!.zipUrl)
if (BuildConfig.DEBUG) Timber.d("repoModule: %s", repoModule!!.zipUrl)
updateZipUrl = repoModule!!.zipUrl
}
// last ditch effort, try to get remoteModuleInfo from localModuleInfo
if (rInfo != null) {
Timber.d("remoteModuleInfo: %s", rInfo.zipUrl)
if (BuildConfig.DEBUG) Timber.d("remoteModuleInfo: %s", rInfo.zipUrl)
updateZipUrl = rInfo.zipUrl
moduleInfo?.updateZipUrl = rInfo.zipUrl
}

@ -27,6 +27,7 @@ import androidx.cardview.widget.CardView
import androidx.core.graphics.ColorUtils
import androidx.recyclerview.widget.RecyclerView
import com.fox2code.foxcompat.view.FoxDisplay
import com.fox2code.mmm.BuildConfig
import com.fox2code.mmm.MainApplication
import com.fox2code.mmm.R
import com.fox2code.mmm.manager.ModuleInfo
@ -406,7 +407,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")) {
Timber.d("Theme is transparent, fixing bgColor")
if (BuildConfig.DEBUG) Timber.d("Theme is transparent, fixing bgColor")
bgColor = ColorUtils.setAlphaComponent(bgColor, 0x70)
}
titleText.setTextColor(fgColor)

@ -15,6 +15,7 @@ import com.fox2code.mmm.BuildConfig
import com.fox2code.mmm.MainActivity
import com.fox2code.mmm.MainApplication
import com.fox2code.mmm.NotificationType
import com.fox2code.mmm.installer.InstallerInitializer
import com.fox2code.mmm.installer.InstallerInitializer.Companion.peekHasRamdisk
import com.fox2code.mmm.installer.InstallerInitializer.Companion.peekMagiskPath
import com.fox2code.mmm.installer.InstallerInitializer.Companion.peekMagiskVersion
@ -106,7 +107,7 @@ class ModuleViewListBuilder(private val activity: Activity) {
continue
}
val moduleInfo = repoModule.moduleInfo
if (!showIncompatible && (moduleInfo.minApi > Build.VERSION.SDK_INT || moduleInfo.maxApi != 0 && moduleInfo.maxApi < Build.VERSION.SDK_INT || peekMagiskPath() != null) && repoModule.moduleInfo.minMagisk > peekMagiskVersion() || no32bitSupport && (AppUpdateManager.getFlagsForModule(
if (!showIncompatible && (moduleInfo.minApi > Build.VERSION.SDK_INT || moduleInfo.maxApi != 0 && moduleInfo.maxApi < Build.VERSION.SDK_INT || peekMagiskPath() != null) && (!InstallerInitializer.isKsu && repoModule.moduleInfo.minMagisk > peekMagiskVersion()) || no32bitSupport && (AppUpdateManager.getFlagsForModule(
repoModule.id
) and AppUpdateManager.FLAG_COMPAT_NEED_32BIT) != 0 || repoModule.moduleInfo.needRamdisk && !peekHasRamdisk()
) continue // Skip adding incompatible modules

@ -357,7 +357,7 @@ open class RepoData(url: String, cacheRoot: File) : XRepo() {
}
}
} else {
Timber.d("Metadata file not found for %s", repoModule.id)
if (BuildConfig.DEBUG) Timber.d("Metadata file not found for %s", repoModule.id)
}
repoModule.moduleInfo.flags =
repoModule.moduleInfo.flags or ModuleInfo.FLAG_METADATA_INVALID
@ -412,7 +412,7 @@ open class RepoData(url: String, cacheRoot: File) : XRepo() {
// should update (lastUpdate > 15 minutes)
fun shouldUpdate(): Boolean {
Timber.d("Repo $preferenceId should update check called")
if (BuildConfig.DEBUG) Timber.d("Repo $preferenceId should update check called")
val db = Room.databaseBuilder(
INSTANCE!!.applicationContext,
ReposListDatabase::class.java,
@ -432,12 +432,12 @@ open class RepoData(url: String, cacheRoot: File) : XRepo() {
val currentTime = System.currentTimeMillis()
val diff = currentTime - lastUpdate
val diffMinutes = diff / (60 * 1000) % 60
Timber.d("Repo $preferenceId updated: $diffMinutes minutes ago")
if (BuildConfig.DEBUG) Timber.d("Repo $preferenceId updated: $diffMinutes minutes ago")
db.close()
db2.close()
diffMinutes > if (BuildConfig.DEBUG) 15 else 30
} else {
Timber.d("Repo $preferenceId shouldUpdate true: lastUpdate is " + repo.lastUpdate + " and moduleListCache is " + moduleListCache.size)
if (BuildConfig.DEBUG) Timber.d("Repo $preferenceId shouldUpdate true: lastUpdate is " + repo.lastUpdate + " and moduleListCache is " + moduleListCache.size)
db.close()
db2.close()
true

@ -152,18 +152,18 @@ class RepoManager private constructor(mainApplication: MainApplication) : SyncMa
}
for (i in repoDatas.indices) {
updateListener.update(STEP1 * (i / repoDatas.size))
if (BuildConfig.DEBUG) Timber.d("Preparing to fetch: %s", repoDatas[i].name)
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) 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) Timber.d("Updating meta-data")
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) 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) Timber.d(
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d(
"Skipping disabled repo: %s",
repoUpdaters[i]!!.repoData.name
)
@ -171,7 +171,7 @@ class RepoManager private constructor(mainApplication: MainApplication) : SyncMa
}
val repoModules = repoUpdaters[i]!!.toUpdate()
val repoData = repoDatas[i]
if (BuildConfig.DEBUG) Timber.d("Registering %s", repoData.name)
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d("Registering %s", repoData.name)
for (repoModule in repoModules!!) {
try {
if (repoModule.propUrl != null && repoModule.propUrl!!.isNotEmpty()) {
@ -229,15 +229,15 @@ class RepoManager private constructor(mainApplication: MainApplication) : SyncMa
}
MainApplication.INSTANCE!!.repoModules.putAll(modules)
}
if (BuildConfig.DEBUG) Timber.d("Finishing update")
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d("Finishing update")
if (hasConnectivity()) {
for (i in repoDatas.indices) {
// If repo is not enabled, skip
if (!repoDatas[i].isEnabled) {
if (BuildConfig.DEBUG) Timber.d("Skipping ${repoDatas[i].name} because it's disabled")
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) Timber.d("Skipping ${repoDatas[i].name} because it's disabled")
continue
}
if (BuildConfig.DEBUG) Timber.d("Finishing: %s", repoUpdaters[i]!!.repoData.name)
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG) 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)

@ -5,6 +5,7 @@
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.ModuleListCache
@ -38,7 +39,7 @@ class RepoUpdater(repoData2: RepoData) {
}
// if MainApplication.repoModules is not empty, return it
/*if (MainApplication.INSTANCE!!.repoModules.isNotEmpty()) {
Timber.d("Returning MainApplication.repoModules for %s", repoData.preferenceId)
if (BuildConfig.DEBUG) Timber.d("Returning MainApplication.repoModules for %s", repoData.preferenceId)
// convert to list for toUpdate
val toUpdateList = ArrayList<RepoModule>()
for (module in MainApplication.INSTANCE!!.repoModules) {
@ -51,7 +52,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
Timber.d("Fetching index from cache for %s", repoData.preferenceId)
if (BuildConfig.DEBUG) Timber.d("Fetching index from cache for %s", repoData.preferenceId)
// now the above but for room
val db = Room.databaseBuilder(
MainApplication.INSTANCE!!,
@ -60,10 +61,15 @@ class RepoUpdater(repoData2: RepoData) {
).allowMainThreadQueries().build()
val moduleListCacheDao = db.moduleListCacheDao()
// now we have the cache, we need to check if it's up to date
val results = moduleListCacheDao.getByRepoId(repoData.preferenceId!!)
var results = moduleListCacheDao.getByRepoId(repoData.preferenceId!!)
if (results.isNotEmpty()) {
toUpdate = emptyList()
toApply = HashSet()
// if results is not empty, check each module to see if it's null. this should never happen, but if it does, remove it from the cache
// copy results to a new list so we can remove items from the original list, then set results to the new list
val resultsCopy = ArrayList(results)
resultsCopy.removeIf { it == null }
results = resultsCopy
for (moduleListCache in results) {
(toApply as HashSet<RepoModule>).add(
RepoModule(
@ -80,7 +86,7 @@ class RepoUpdater(repoData2: RepoData) {
)
)
}
Timber.d(
if (BuildConfig.DEBUG) Timber.d(
"Fetched %d modules from cache for %s, from %s records",
(toApply as HashSet<RepoModule>).size,
repoData.preferenceId,
@ -96,7 +102,7 @@ class RepoUpdater(repoData2: RepoData) {
}
// log first 100 chars of indexRaw
indexRaw = jsonObject.toString().toByteArray()
Timber.d(
if (BuildConfig.DEBUG) Timber.d(
"Index raw: %s",
String(indexRaw!!, StandardCharsets.UTF_8).subSequence(0, 100)
)
@ -147,18 +153,18 @@ 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) {
Timber.d("Repo %s is disabled, skipping", repoData.preferenceId)
if (BuildConfig.DEBUG) Timber.d("Repo %s is disabled, skipping", repoData.preferenceId)
return true
}
val success = AtomicBoolean(false)
Timber.d("Finishing update for %s", repoData.preferenceId)
if (BuildConfig.DEBUG) Timber.d("Finishing update for %s", repoData.preferenceId)
if (indexRaw != null) {
val tmpIndexRaw = indexRaw!!
Timber.d("Updating database for %s", repoData.preferenceId)
if (BuildConfig.DEBUG) Timber.d("Updating database for %s", repoData.preferenceId)
// new thread to update the database
val thread = Thread {
val startTime = System.currentTimeMillis()
Timber.d("Updating database thread for %s", repoData.preferenceId)
if (BuildConfig.DEBUG) Timber.d("Updating database thread for %s", repoData.preferenceId)
try {
// iterate over modules, using this.supportedProperties as a template to attempt to get each property from the module. everything that is not null is added to the module
// use room to insert to
@ -179,21 +185,21 @@ class RepoUpdater(repoData2: RepoData) {
} catch (e: Exception) {
Timber.e(e)
Timber.w("No modules were found in the index file for %s", repoData.preferenceId)
Timber.d("Finished updating database for %s in %dms", repoData.preferenceId, System.currentTimeMillis() - startTime)
if (BuildConfig.DEBUG) Timber.d("Finished updating database for %s in %dms", repoData.preferenceId, System.currentTimeMillis() - startTime)
success.set(false)
return@Thread
}
Timber.d("Got modules for %s", repoData.preferenceId)
if (BuildConfig.DEBUG) Timber.d("Got modules for %s", repoData.preferenceId)
val moduleListCacheDao = db.moduleListCacheDao()
moduleListCacheDao.deleteByRepoId(repoData.preferenceId!!)
Timber.d("Deleted old modules for %s", repoData.preferenceId)
if (BuildConfig.DEBUG) Timber.d("Deleted old modules for %s", repoData.preferenceId)
if (modulesArray.length() == 0) {
Timber.w("No modules were found in the index file for %s", repoData.preferenceId)
Timber.d("Finished updating database for %s in %dms", repoData.preferenceId, System.currentTimeMillis() - startTime)
if (BuildConfig.DEBUG) Timber.d("Finished updating database for %s in %dms", repoData.preferenceId, System.currentTimeMillis() - startTime)
success.set(false)
return@Thread
}
Timber.d("Iterating over modules for %s", repoData.preferenceId)
if (BuildConfig.DEBUG) Timber.d("Iterating over modules for %s", repoData.preferenceId)
// iterate over modules
for (n in 0 until modulesArray.length()) {
// get module
@ -335,7 +341,7 @@ class RepoUpdater(repoData2: RepoData) {
db.close()
val endTime = System.currentTimeMillis()
val timeTaken = endTime - startTime
Timber.d("Time taken to parse modules: $timeTaken ms")
if (BuildConfig.DEBUG) Timber.d("Time taken to parse modules: $timeTaken ms")
} catch (ignored: Exception) {
}
}
@ -352,7 +358,7 @@ class RepoUpdater(repoData2: RepoData) {
db.close()
success.set(true)
} else {
Timber.d("No index file found for %s", repoData.preferenceId)
if (BuildConfig.DEBUG) 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()

@ -17,6 +17,7 @@ import androidx.preference.TwoStatePreference
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
import com.fox2code.foxcompat.app.FoxActivity
import com.fox2code.mmm.BuildConfig
import com.fox2code.mmm.MainApplication
import com.fox2code.mmm.R
import com.fox2code.rosettax.LanguageSwitcher
@ -58,7 +59,7 @@ class AppearanceFragment : PreferenceFragmentCompat() {
val themePreference = findPreference<ListPreference>("pref_theme")
// If transparent theme(s) are set, disable monet
if (themePreference!!.value == "transparent_light") {
Timber.d("disabling monet")
if (BuildConfig.DEBUG) Timber.d("disabling monet")
findPreference<Preference>("pref_enable_monet")!!.isEnabled = false
// Toggle monet off
(findPreference<Preference>("pref_enable_monet") as TwoStatePreference?)!!.isChecked =
@ -77,11 +78,11 @@ class AppearanceFragment : PreferenceFragmentCompat() {
Preference.SummaryProvider { _: Preference? -> themePreference.entry }
themePreference.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
Timber.d("refreshing activity. New value: %s", newValue)
if (BuildConfig.DEBUG) 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")) {
Timber.d("disabling monet")
if (BuildConfig.DEBUG) 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)

@ -123,7 +123,7 @@ class DebugFragment : PreferenceFragmentCompat() {
)
}
}
if (InstallerInitializer.peekMagiskVersion() < Constants.MAGISK_VER_CODE_INSTALL_COMMAND || !MainApplication.isDeveloper) {
if (InstallerInitializer.peekMagiskVersion() < Constants.MAGISK_VER_CODE_INSTALL_COMMAND || !MainApplication.isDeveloper || InstallerInitializer.isKsu) {
findPreference<Preference>("pref_use_magisk_install_command")!!.isVisible = false
}

@ -78,7 +78,7 @@ class InfoFragment : PreferenceFragmentCompat() {
var userRepo = BuildConfig.REMOTE_URL
// remove .git
userRepo = userRepo.replace("\\.git$".toRegex(), "")
Timber.d("userRepo: %s", userRepo)
if (BuildConfig.DEBUG) 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
)
Timber.d("finalUserRepo: %s", finalUserRepo)
if (BuildConfig.DEBUG) Timber.d("finalUserRepo: %s", finalUserRepo)
val finalUserRepo1 = userRepo
linkClickable.onPreferenceClickListener =
Preference.OnPreferenceClickListener setOnPreferenceClickListener@{ p: Preference ->
@ -179,7 +179,6 @@ class InfoFragment : PreferenceFragmentCompat() {
prefDonateAndroidacy!!.isVisible = false
}
linkClickable = findPreference("pref_support")
linkClickable!!.onPreferenceClickListener =
Preference.OnPreferenceClickListener { p: Preference ->

@ -13,6 +13,7 @@ import androidx.preference.TwoStatePreference
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
import com.fox2code.foxcompat.app.FoxActivity
import com.fox2code.mmm.BuildConfig
import com.fox2code.mmm.MainActivity
import com.fox2code.mmm.MainApplication
import com.fox2code.mmm.R
@ -77,7 +78,7 @@ class PrivacyFragment : PreferenceFragmentCompat() {
val mgr =
requireContext().getSystemService(FoxActivity.ALARM_SERVICE) as AlarmManager
mgr[AlarmManager.RTC, System.currentTimeMillis() + 100] = mPendingIntent
Timber.d("Restarting app to save crash reporting preference: %s", newValue)
if (BuildConfig.DEBUG) 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

@ -92,7 +92,7 @@ class RepoFragment : PreferenceFragmentCompat() {
requireContext().getSystemService(ALARM_SERVICE) as AlarmManager
mgr[AlarmManager.RTC, System.currentTimeMillis() + 100] =
mPendingIntent
Timber.d(
if (BuildConfig.DEBUG) Timber.d(
"Restarting app to save staging endpoint preference: %s",
newValue
)
@ -134,7 +134,7 @@ class RepoFragment : PreferenceFragmentCompat() {
requireContext().getSystemService(ALARM_SERVICE) as AlarmManager
mgr[AlarmManager.RTC, System.currentTimeMillis() + 100] =
mPendingIntent
Timber.d(
if (BuildConfig.DEBUG) Timber.d(
"Restarting app to save staging endpoint preference: %s",
newValue
)
@ -319,7 +319,7 @@ class RepoFragment : PreferenceFragmentCompat() {
requireContext().getSystemService(ALARM_SERVICE) as AlarmManager
mgr[AlarmManager.RTC, System.currentTimeMillis() + 100] =
mPendingIntent
Timber.d(
if (BuildConfig.DEBUG) Timber.d(
"Restarting app to save token preference: %s",
newValue
)
@ -407,7 +407,7 @@ class RepoFragment : PreferenceFragmentCompat() {
) as AlarmManager
mgr[AlarmManager.RTC, System.currentTimeMillis() + 100] =
mPendingIntent
Timber.d(
if (BuildConfig.DEBUG) Timber.d(
"Restarting app to save token preference: %s",
newValue
)
@ -462,13 +462,13 @@ class RepoFragment : PreferenceFragmentCompat() {
customRepos.add(id)
}
}
Timber.d("%d repos: %s", custRepoEntries, customRepos)
if (BuildConfig.DEBUG) 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
Timber.d("RepoData for %d is %s", i, repoData.toJSON())
if (BuildConfig.DEBUG) Timber.d("RepoData for %d is %s", i, repoData.toJSON())
setRepoData(repoData, "pref_custom_repo_$i")
if (initial) {
val preference = findPreference<Preference>("pref_custom_repo_" + i + "_delete")
@ -594,25 +594,25 @@ class RepoFragment : PreferenceFragmentCompat() {
// 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)
Timber.d("No input for repo")
if (BuildConfig.DEBUG) Timber.d("No input for repo")
positiveButton.isEnabled = false
} else if (!charSequence.toString()
.matches("^https://.*".toRegex())
) {
input.error = getString(R.string.invalid_repo_url)
Timber.d("Non https link for repo")
if (BuildConfig.DEBUG) Timber.d("Non https link for repo")
positiveButton.isEnabled = false
} else if (charSequence.toString().contains(" ")) {
input.error = getString(R.string.invalid_repo_url)
Timber.d("Repo url has space")
if (BuildConfig.DEBUG) Timber.d("Repo url has space")
positiveButton.isEnabled = false
} else if (!customRepoManager.canAddRepo(charSequence.toString())) {
input.error = getString(R.string.repo_already_added)
Timber.d("Could not add repo for misc reason")
if (BuildConfig.DEBUG) Timber.d("Could not add repo for misc reason")
positiveButton.isEnabled = false
} else {
// enable ok button
Timber.d("Repo URL is ok")
if (BuildConfig.DEBUG) Timber.d("Repo URL is ok")
positiveButton.isEnabled = true
}
}
@ -638,7 +638,7 @@ class RepoFragment : PreferenceFragmentCompat() {
private fun setRepoData(repoData: RepoData?, preferenceName: String) {
if (repoData == null) return
Timber.d("Setting preference $preferenceName to $repoData")
if (BuildConfig.DEBUG) Timber.d("Setting preference $preferenceName to $repoData")
val clipboard = requireContext().getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
var preference = findPreference<Preference>(preferenceName) ?: return
if (!preferenceName.contains("androidacy") && !preferenceName.contains("magisk_alt_repo")) {
@ -649,13 +649,13 @@ class RepoFragment : PreferenceFragmentCompat() {
"ReposList.db"
).allowMainThreadQueries().build()
val reposList = db.reposListDao().getById(repoData.preferenceId!!)
Timber.d("Setting preference $preferenceName because it is not the Androidacy repo or the Magisk Alt Repo")
if (BuildConfig.DEBUG) Timber.d("Setting preference $preferenceName because it is not the Androidacy repo or the Magisk Alt Repo")
if (repoData.isForceHide || reposList == null) {
Timber.d("Hiding preference $preferenceName because it is null or force hidden")
if (BuildConfig.DEBUG) Timber.d("Hiding preference $preferenceName because it is null or force hidden")
hideRepoData(preferenceName)
return
} else {
Timber.d(
if (BuildConfig.DEBUG) Timber.d(
"Showing preference %s because the forceHide status is %s and the RealmResults is %s",
preferenceName,
repoData.isForceHide,
@ -718,7 +718,7 @@ class RepoFragment : PreferenceFragmentCompat() {
}
}
} else {
Timber.d("Hiding preference $preferenceName because it's data is null")
if (BuildConfig.DEBUG) Timber.d("Hiding preference $preferenceName because it's data is null")
hideRepoData(preferenceName)
return
}

@ -13,6 +13,7 @@ import androidx.preference.TwoStatePreference
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
import com.fox2code.foxcompat.app.FoxActivity
import com.fox2code.mmm.BuildConfig
import com.fox2code.mmm.MainActivity
import com.fox2code.mmm.MainApplication
import com.fox2code.mmm.R
@ -88,7 +89,7 @@ class SecurityFragment : PreferenceFragmentCompat() {
requireContext().getSystemService(FoxActivity.ALARM_SERVICE) as AlarmManager
mgr[AlarmManager.RTC, System.currentTimeMillis() + 100] =
mPendingIntent
Timber.d("Restarting app to save showcase mode preference: %s", v)
if (BuildConfig.DEBUG) 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
@ -111,7 +112,7 @@ class SecurityFragment : PreferenceFragmentCompat() {
requireContext().getSystemService(FoxActivity.ALARM_SERVICE) as AlarmManager
mgr[AlarmManager.RTC, System.currentTimeMillis() + 100] =
mPendingIntent
Timber.d("Restarting app to save showcase mode preference: %s", v)
if (BuildConfig.DEBUG) Timber.d("Restarting app to save showcase mode preference: %s", v)
exitProcess(0) // Exit app process
}.show()
}

@ -38,7 +38,8 @@ import timber.log.Timber
import java.sql.Timestamp
@Suppress("SENSELESS_COMPARISON")
class SettingsActivity : FoxActivity(), LanguageActivity {
class SettingsActivity : FoxActivity(), LanguageActivity,
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
lateinit var sharedPreferences: SharedPreferences
@SuppressLint("RestrictedApi")
@ -94,7 +95,7 @@ class SettingsActivity : FoxActivity(), LanguageActivity {
if (ts.time > buildTime.time) {
val pm = packageManager
val intent = Intent(this, ExpiredActivity::class.java)
@Suppress("DEPRECATION") val resolveInfo = pm.queryIntentActivities(intent, 0)
val resolveInfo = pm.queryIntentActivities(intent, 0)
if (resolveInfo.size > 0) {
startActivity(intent)
finish()
@ -192,7 +193,7 @@ class SettingsActivity : FoxActivity(), LanguageActivity {
findPreference<Preference>("pref_pkg_info")!!.onPreferenceClickListener =
Preference.OnPreferenceClickListener { p: Preference ->
versionClicks++
Timber.d("Version clicks: %d", versionClicks)
if (BuildConfig.DEBUG) Timber.d("Version clicks: %d", versionClicks)
if (versionClicks == 7) {
versionClicks = 0
openUrl(p.context, "https://www.youtube.com/watch?v=dQw4w9WgXcQ")
@ -266,7 +267,7 @@ class SettingsActivity : FoxActivity(), LanguageActivity {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
points += 1
}
Timber.d("Device performance class: %d", points)
if (BuildConfig.DEBUG) Timber.d("Device performance class: %d", points)
return if (points <= 7) {
PERFORMANCE_CLASS_LOW
} else if (points <= 12) {
@ -276,4 +277,19 @@ class SettingsActivity : FoxActivity(), LanguageActivity {
}
}
}
override fun onPreferenceStartFragment(
caller: PreferenceFragmentCompat,
pref: Preference
): Boolean {
val fragment = supportFragmentManager.fragmentFactory.instantiate(
classLoader, pref.fragment.toString()
)
fragment.arguments = pref.extras
@Suppress("DEPRECATION") fragment.setTargetFragment(caller, 0)
supportFragmentManager.beginTransaction().replace(R.id.settings, fragment)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN).addToBackStack(null)
.commit()
return true
}
}

@ -6,19 +6,20 @@ package com.fox2code.mmm.settings
import android.content.SharedPreferences
import androidx.preference.PreferenceDataStore
import com.fox2code.mmm.BuildConfig
import timber.log.Timber
class SharedPreferenceDataStore(sharedPreferences: SharedPreferences) : PreferenceDataStore() {
private val mSharedPreferences: SharedPreferences
init {
Timber.d("SharedPreferenceDataStore: %s", sharedPreferences)
if (BuildConfig.DEBUG) Timber.d("SharedPreferenceDataStore: %s", sharedPreferences)
mSharedPreferences = sharedPreferences
}
val sharedPreferences: SharedPreferences
get() {
Timber.d("getSharedPreferences: %s", mSharedPreferences)
if (BuildConfig.DEBUG) Timber.d("getSharedPreferences: %s", mSharedPreferences)
return mSharedPreferences
}

@ -86,7 +86,7 @@ class UpdateFragment : PreferenceFragmentCompat() {
do {
fakeVersion = random.nextInt(10)
} while (fakeVersion == 0)
Timber.d("Fake version: %s, count: %s", fakeVersion, i)
if (BuildConfig.DEBUG) Timber.d("Fake version: %s, count: %s", fakeVersion, i)
updateableModules["FakeModule $i"] = "1.0.$fakeVersion"
}
BackgroundUpdateChecker.postNotification(
@ -158,7 +158,7 @@ class UpdateFragment : PreferenceFragmentCompat() {
moduleNames[i] = localModuleInfo!!.name
// Stringset uses id, we show name
checkedItems[i] = stringSet.contains(localModuleInfo.id)
Timber.d("name: %s, checked: %s", moduleNames[i], checkedItems[i])
if (BuildConfig.DEBUG) Timber.d("name: %s, checked: %s", moduleNames[i], checkedItems[i])
}
MaterialAlertDialogBuilder(requireContext()).setTitle(R.string.background_update_check_excludes)
.setMultiChoiceItems(
@ -205,7 +205,7 @@ class UpdateFragment : PreferenceFragmentCompat() {
val stringSet = sharedPreferences.getStringSet(
"pref_background_update_check_excludes_version", HashSet()
)
Timber.d("stringSet: %s", stringSet)
if (BuildConfig.DEBUG) 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<LocalModuleInfo?> =
ModuleManager.instance!!.modules.values
@ -263,7 +263,7 @@ class UpdateFragment : PreferenceFragmentCompat() {
.setView(scrollView).setPositiveButton(
R.string.ok
) { _: DialogInterface?, _: Int ->
Timber.d("ok clicked")
if (BuildConfig.DEBUG) Timber.d("ok clicked")
// for every module, get the text field and save it to the stringset
val stringSetTemp: MutableSet<String> = HashSet()
var prevMod = ""
@ -287,9 +287,9 @@ class UpdateFragment : PreferenceFragmentCompat() {
localModuleInfo!!.name.equals(finalprevMod)
}.findFirst().orElse(null)!!.id + ":" + text
)
Timber.d("text is %s for %s", text, editText.hint.toString())
if (BuildConfig.DEBUG) Timber.d("text is %s for %s", text, editText.hint.toString())
} else {
Timber.d("text is empty for %s", editText.hint.toString())
if (BuildConfig.DEBUG) Timber.d("text is empty for %s", editText.hint.toString())
}
}
sharedPreferences.edit().putStringSet(

@ -76,7 +76,7 @@ enum class IntentHelper {;
@JvmOverloads
fun openUrl(context: Context, url: String?, forceBrowser: Boolean = false) {
Timber.d("Opening url: %s, forced browser %b", url, forceBrowser)
if (BuildConfig.DEBUG) 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
@ -85,7 +85,7 @@ enum class IntentHelper {;
}
startActivity(context, myIntent, false)
} catch (e: ActivityNotFoundException) {
Timber.d(e, "Could not find suitable activity to handle url")
if (BuildConfig.DEBUG) Timber.d(e, "Could not find suitable activity to handle url")
Toast.makeText(
context, FoxActivity.getFoxActivity(context).getString(
R.string.no_browser
@ -96,7 +96,7 @@ enum class IntentHelper {;
@JvmStatic
fun openCustomTab(context: Context, url: String?) {
Timber.d("Opening url: %s in custom tab", url)
if (BuildConfig.DEBUG) 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
@ -105,7 +105,7 @@ enum class IntentHelper {;
tabIntent.addCategory(Intent.CATEGORY_BROWSABLE)
startActivityEx(context, tabIntent, viewIntent)
} catch (e: ActivityNotFoundException) {
Timber.d(e, "Could not find suitable activity to handle url")
if (BuildConfig.DEBUG) Timber.d(e, "Could not find suitable activity to handle url")
Toast.makeText(
context, FoxActivity.getFoxActivity(context).getString(
R.string.no_browser
@ -389,7 +389,7 @@ enum class IntentHelper {;
compatActivity.startActivityForResult(intent, param) { result: Int, data: Intent? ->
val uri = data?.data
if (uri == null || result == Activity.RESULT_CANCELED) {
Timber.d("invalid uri recieved")
if (BuildConfig.DEBUG) Timber.d("invalid uri recieved")
callback.onReceived(destination, null, RESPONSE_ERROR)
return@startActivityForResult
}

@ -27,8 +27,8 @@ object TimberUtils {
plant(
SentryTimberTree(
Sentry.getCurrentHub(),
SentryLevel.ERROR,
SentryLevel.ERROR
SentryLevel.WARNING,
SentryLevel.WARNING
)
)
} else {

@ -35,7 +35,7 @@ class ZipFileOpener : FoxActivity() {
super.onCreate(savedInstanceState)
loading = build(this, R.string.loading, R.string.zip_unpacking)
Thread(Runnable {
Timber.d("onCreate: %s", intent)
if (BuildConfig.DEBUG) Timber.d("onCreate: %s", intent)
val zipFile: File
val uri = intent.data
if (uri == null) {
@ -103,7 +103,7 @@ class ZipFileOpener : FoxActivity() {
}
return@Runnable
} else {
Timber.d("onCreate: Zip file is " + zipFile.length() + " bytes")
if (BuildConfig.DEBUG) Timber.d("onCreate: Zip file is " + zipFile.length() + " bytes")
}
var entry: ZipEntry?
var zip: ZipFile? = null
@ -116,13 +116,13 @@ class ZipFileOpener : FoxActivity() {
Timber.e("onCreate: Zip file is not a valid magisk module")
if (BuildConfig.DEBUG) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Timber.d(
if (BuildConfig.DEBUG) Timber.d(
"onCreate: Zip file contents: %s",
zip.stream().map { obj: ZipEntry -> obj.name }
.reduce { a: String, b: String -> "$a, $b" }.orElse("empty")
)
} else {
Timber.d("onCreate: Zip file contents cannot be listed on this version of android")
if (BuildConfig.DEBUG) Timber.d("onCreate: Zip file contents cannot be listed on this version of android")
}
}
runOnUiThread {
@ -146,7 +146,7 @@ class ZipFileOpener : FoxActivity() {
}
return@Runnable
}
Timber.d("onCreate: Zip file is valid")
if (BuildConfig.DEBUG) Timber.d("onCreate: Zip file is valid")
var moduleInfo: String?
try {
moduleInfo = readModulePropSimple(zip.getInputStream(entry), "name")

@ -9,6 +9,7 @@ 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
@ -235,7 +236,7 @@ enum class Files {
throw IOException("Unable to create temp unzip dir")
}
// unzip
Timber.d("Unzipping module to %s", tempUnzipDir.absolutePath)
if (BuildConfig.DEBUG) Timber.d("Unzipping module to %s", tempUnzipDir.absolutePath)
try {
ZipFile(tempFile).use { zipFile ->
var files = zipFile.entries
@ -293,7 +294,7 @@ enum class Files {
Timber.e(e, "Unable to zip up module")
}
} else {
Timber.d("Module does not have a single folder in the top level, skipping")
if (BuildConfig.DEBUG) Timber.d("Module does not have a single folder in the top level, skipping")
}
}
} catch (e: IOException) {

@ -248,7 +248,7 @@ enum class Http {;
0, dot
).toInt()
}
Timber.d(
if (BuildConfig.DEBUG) Timber.d(
"Webview version: %s (%d)", webviewVersion, webviewVersionCode
)
hasWebView =
@ -492,7 +492,7 @@ enum class Http {;
throw HttpException(e.message, 0)
}
if (BuildConfig.DEBUG_HTTP) {
Timber.d("doHttpGet: request executed")
if (BuildConfig.DEBUG) Timber.d("doHttpGet: request executed")
}
// 200/204 == success, 304 == cache valid
if (response != null) {
@ -513,7 +513,7 @@ enum class Http {;
if (retryAfter != null) {
try {
val seconds = Integer.parseInt(retryAfter)
Timber.d("Sleeping for $seconds seconds")
if (BuildConfig.DEBUG) Timber.d("Sleeping for $seconds seconds")
Thread.sleep(seconds * 1000L)
} catch (e: NumberFormatException) {
Timber.e(e, "Failed to parse Retry-After header")
@ -523,7 +523,7 @@ enum class Http {;
} else {// start with one second and try up to five times
if (limitedRetries < 5) {
limitedRetries++
Timber.d("Sleeping for 1 second")
if (BuildConfig.DEBUG) Timber.d("Sleeping for 1 second")
try {
Thread.sleep(1000L * limitedRetries)
} catch (e: InterruptedException) {
@ -539,7 +539,7 @@ enum class Http {;
}
}
if (BuildConfig.DEBUG_HTTP) {
Timber.d("doHttpGet: " + url.replace("=[^&]*".toRegex(), "=****") + " succeeded")
if (BuildConfig.DEBUG) Timber.d("doHttpGet: " + url.replace("=[^&]*".toRegex(), "=****") + " succeeded")
}
var responseBody = response?.body
// Use cache api if used cached response
@ -551,7 +551,7 @@ enum class Http {;
}
if (BuildConfig.DEBUG_HTTP) {
if (responseBody != null) {
Timber.d("doHttpGet: returning " + responseBody.contentLength() + " bytes")
if (BuildConfig.DEBUG) Timber.d("doHttpGet: returning " + responseBody.contentLength() + " bytes")
}
}
return responseBody?.bytes() ?: ByteArray(0)
@ -566,7 +566,7 @@ enum class Http {;
@Throws(IOException::class)
private fun doHttpPostRaw(url: String, data: String, allowCache: Boolean): Any {
Timber.d("POST %s", url)
if (BuildConfig.DEBUG) Timber.d("POST %s", url)
var response: Response?
try {
response =
@ -590,7 +590,7 @@ enum class Http {;
}
if (response.isRedirect) {
// follow redirect with same method
Timber.d("doHttpPostRaw: following redirect: %s", response.header("Location"))
if (BuildConfig.DEBUG) Timber.d("doHttpPostRaw: following redirect: %s", response.header("Location"))
response =
(if (allowCache) getHttpClientWithCache() else getHttpClient())!!.newCall(
Request.Builder().url(
@ -609,7 +609,7 @@ enum class Http {;
if (retryAfter != null) {
try {
val seconds = Integer.parseInt(retryAfter)
Timber.d("Sleeping for $seconds seconds")
if (BuildConfig.DEBUG) Timber.d("Sleeping for $seconds seconds")
Thread.sleep(seconds * 1000L)
} catch (e: NumberFormatException) {
Timber.e(e, "Failed to parse Retry-After header")
@ -619,7 +619,7 @@ enum class Http {;
} else {// start with one second and try up to five times
if (limitedRetries < 5) {
limitedRetries++
Timber.d("Sleeping for 1 second")
if (BuildConfig.DEBUG) Timber.d("Sleeping for 1 second")
try {
Thread.sleep(1000L * limitedRetries)
} catch (e: InterruptedException) {
@ -672,7 +672,7 @@ enum class Http {;
if (retryAfter != null) {
try {
val seconds = Integer.parseInt(retryAfter)
Timber.d("Sleeping for $seconds seconds")
if (BuildConfig.DEBUG) Timber.d("Sleeping for $seconds seconds")
Thread.sleep(seconds * 1000L)
} catch (e: NumberFormatException) {
Timber.e(e, "Failed to parse Retry-After header")
@ -682,7 +682,7 @@ enum class Http {;
} else {// start with one second and try up to five times
if (limitedRetries < 5) {
limitedRetries++
Timber.d("Sleeping for 1 second")
if (BuildConfig.DEBUG) Timber.d("Sleeping for 1 second")
try {
Thread.sleep(1000L * limitedRetries)
} catch (e: InterruptedException) {
@ -774,19 +774,19 @@ enum class Http {;
val systemSaysYes = networkCapabilities != null && networkCapabilities.hasCapability(
NetworkCapabilities.NET_CAPABILITY_INTERNET
)
Timber.d("System says we have internet: $systemSaysYes")
if (BuildConfig.DEBUG) 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)
Timber.d("Network became available")
if (BuildConfig.DEBUG) Timber.d("Network became available")
lastConnectivityCheck = 0
}
override fun onLost(network: Network) {
super.onLost(network)
Timber.d("Network became unavailable")
if (BuildConfig.DEBUG) Timber.d("Network became unavailable")
lastConnectivityCheck = 0
}
}
@ -803,7 +803,7 @@ enum class Http {;
Timber.e(e, "Failed to check internet connection")
false
}
Timber.d("We say we have internet: $hasInternet")
if (BuildConfig.DEBUG) Timber.d("We say we have internet: $hasInternet")
lastConnectivityCheck = System.currentTimeMillis()
@Suppress("KotlinConstantConditions")
lastConnectivityResult =

@ -18,6 +18,7 @@ import io.sentry.Breadcrumb
import io.sentry.Hint
import io.sentry.Sentry
import io.sentry.SentryEvent
import io.sentry.SentryLevel
import io.sentry.SentryOptions.BeforeBreadcrumbCallback
import io.sentry.SentryOptions.BeforeSendCallback
import io.sentry.android.core.SentryAndroid
@ -76,8 +77,8 @@ object SentryMain {
}
isSentryEnabled = sharedPreferences.getBoolean("pref_crash_reporting_enabled", false)
// set sentryEnabled on preference change of pref_crash_reporting_enabled
sharedPreferences.registerOnSharedPreferenceChangeListener { sharedPreferences1: SharedPreferences, s: String ->
if (s == "pref_crash_reporting_enabled") {
sharedPreferences.registerOnSharedPreferenceChangeListener { sharedPreferences1: SharedPreferences, s: String? ->
if (s!== null && s == "pref_crash_reporting_enabled") {
isSentryEnabled = sharedPreferences1.getBoolean(s, false)
}
}
@ -128,6 +129,16 @@ object SentryMain {
return@BeforeSendCallback null
}
crashExceptionId = event?.eventId
// if debug build, log everything, but for release only log warnings and errors
if (!BuildConfig.DEBUG) {
if (event?.level == SentryLevel.DEBUG || event?.level == SentryLevel.INFO) {
return@BeforeSendCallback null
}
}
// remove all failed to fetch data messages
if (event?.message?.message?.contains("Failed to fetch") == true) {
return@BeforeSendCallback null
}
event
}
// Filter breadcrumb content from crash report.

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/system_accent1_100"/>
<corners android:radius="20dp"/>
<padding android:left="0dp"
android:bottom="0dp"
android:right="0dp"
android:top="0dp"/>
</shape>

@ -401,4 +401,5 @@
<string name="update_frequency_360">6 hours</string>
<string name="update_frequency_720">12 hours</string>
<string name="update_frequency_1440">Daily</string>
<string name="ksu_experimental"><![CDATA[KernelSU support is currently <b>experimental</b> and may have issues. Compatibility with modules is not guaraunteed.]]></string>
</resources>

@ -13,7 +13,7 @@ buildscript {
gradlePluginPortal()
}
dependencies {
classpath("com.android.tools.build:gradle:8.0.2")
classpath("com.android.tools.build:gradle:8.1.1")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.22")
classpath("com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:10.8.3")

Loading…
Cancel
Save