Skip to content

Commit 9ca946b

Browse files
fun fact: 9/10 devs have no idea why this works
Signed-off-by: androidacy-user <opensource@androidacy.com>
1 parent 71acd0b commit 9ca946b

27 files changed

Lines changed: 288 additions & 90 deletions

app/build.gradle.kts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -499,12 +499,12 @@ dependencies {
499499
implementation("com.github.Fox2Code:AndroidANSI:1.2.1")
500500

501501
// sentry
502-
implementation("io.sentry:sentry-android:6.28.0")
503-
implementation("io.sentry:sentry-android-timber:6.28.0")
504-
implementation("io.sentry:sentry-android-fragment:6.28.0")
505-
implementation("io.sentry:sentry-android-okhttp:6.28.0")
506-
implementation("io.sentry:sentry-kotlin-extensions:6.28.0")
507-
implementation("io.sentry:sentry-android-ndk:6.28.0")
502+
implementation("io.sentry:sentry-android:6.29.0")
503+
implementation("io.sentry:sentry-android-timber:6.29.0")
504+
implementation("io.sentry:sentry-android-fragment:6.29.0")
505+
implementation("io.sentry:sentry-android-okhttp:6.29.0")
506+
implementation("io.sentry:sentry-kotlin-extensions:6.29.0")
507+
implementation("io.sentry:sentry-android-ndk:6.29.0")
508508

509509
// Markdown
510510
// TODO: switch to an updated implementation
@@ -554,6 +554,8 @@ dependencies {
554554

555555
// optional - Kotlin Extensions and Coroutines support for Room
556556
implementation("androidx.room:room-ktx:2.5.2")
557+
558+
implementation("pl.droidsonroids.gif:android-gif-drawable:1.2.28")
557559
}
558560

559561
android {
@@ -563,7 +565,7 @@ android {
563565
}
564566
}
565567

566-
ndkVersion = "25.2.9519653"
568+
ndkVersion = "26.0.10636728 rc2"
567569
dependenciesInfo {
568570
includeInApk = false
569571
includeInBundle = false

app/src/main/kotlin/com/fox2code/mmm/NotificationType.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import com.fox2code.mmm.utils.IntentHelper
2727
import com.fox2code.mmm.utils.io.Files.Companion.patchModuleSimple
2828
import com.fox2code.mmm.utils.io.Files.Companion.read
2929
import com.fox2code.mmm.utils.io.net.Http
30+
import com.google.android.material.dialog.MaterialAlertDialogBuilder
3031
import timber.log.Timber
3132
import java.io.BufferedReader
3233
import java.io.File
@@ -195,6 +196,15 @@ enum class NotificationType(
195196
androidx.appcompat.R.attr.colorBackgroundFloating,
196197
com.google.android.material.R.attr.colorOnBackground,
197198
View.OnClickListener { v: View? ->
199+
if (MainApplication.getSharedPreferences("mmm")?.getBoolean("pref_require_security", false) == true) {
200+
// block local install for safety
201+
MaterialAlertDialogBuilder(v!!.context)
202+
.setTitle(R.string.install_from_storage)
203+
.setMessage(R.string.install_from_storage_safe_modules)
204+
.setPositiveButton(android.R.string.ok, null)
205+
.show()
206+
return@OnClickListener
207+
}
198208
val compatActivity = FoxActivity.getFoxActivity(v)
199209
val module = File(
200210
compatActivity.cacheDir, "installer" + File.separator + "module.zip"

app/src/main/kotlin/com/fox2code/mmm/SetupActivity.kt

Lines changed: 84 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import android.content.DialogInterface
1111
import android.content.Intent
1212
import android.content.pm.PackageManager
1313
import android.content.res.Resources.Theme
14+
import android.net.Uri
1415
import android.os.Bundle
1516
import android.os.Process
1617
import android.view.View
@@ -46,6 +47,7 @@ class SetupActivity : FoxActivity(), LanguageActivity {
4647
private var cachedTheme = 0
4748

4849
@SuppressLint("ApplySharedPref", "RestrictedApi")
50+
@Suppress("KotlinConstantConditions", "NAME_SHADOWING")
4951
override fun onCreate(savedInstanceState: Bundle?) {
5052
super.onCreate(savedInstanceState)
5153
this.setTitle(R.string.setup_title)
@@ -69,7 +71,7 @@ class SetupActivity : FoxActivity(), LanguageActivity {
6971
if (ts.time > buildTime.time) {
7072
val pm = packageManager
7173
val intent = Intent(this, ExpiredActivity::class.java)
72-
@Suppress("DEPRECATION") val resolveInfo = pm.queryIntentActivities(intent, 0)
74+
val resolveInfo = pm.queryIntentActivities(intent, 0)
7375
if (resolveInfo.size > 0) {
7476
startActivity(intent)
7577
finish()
@@ -85,6 +87,67 @@ class SetupActivity : FoxActivity(), LanguageActivity {
8587
}
8688
}
8789
val view: View = binding.root
90+
// if our application id is "com.androidacy.mmm" or begins with it, check if com.fox2code.mmm is installed and offer to uninstall it. if we're com.fox2code.mmm, check if com.fox2code.mmm.fdroid or com.fox2code.mmm.debug is installed and offer to uninstall it
91+
val ourPackageName = BuildConfig.APPLICATION_ID
92+
val foxPkgName = "com.fox2code.mmm"
93+
val foxPkgNameFdroid = "com.fox2code.mmm.fdroid"
94+
val foxPkgNameDebug = "com.fox2code.mmm.debug"
95+
val foxPkgNamePlay = "com.androidacy.mmm.play"
96+
val androidacyPkgName = "com.androidacy.mmm"
97+
val pm = packageManager
98+
val intent = Intent(Intent.ACTION_MAIN, null)
99+
intent.addCategory(Intent.CATEGORY_LAUNCHER)
100+
val resolveInfoList = pm.queryIntentActivities(intent, 0)
101+
for (resolveInfo in resolveInfoList) {
102+
val packageName = resolveInfo.activityInfo.packageName
103+
if (packageName == ourPackageName) {
104+
continue
105+
}
106+
when (ourPackageName) {
107+
foxPkgName -> {
108+
if (packageName == foxPkgNameDebug || packageName == foxPkgNameFdroid || packageName == foxPkgNamePlay) {
109+
val materialAlertDialogBuilder = MaterialAlertDialogBuilder(this)
110+
materialAlertDialogBuilder.setTitle(R.string.setup_uninstall_title)
111+
materialAlertDialogBuilder.setMessage(getString(R.string.setup_uninstall_message, packageName))
112+
materialAlertDialogBuilder.setPositiveButton(R.string.uninstall) { _: DialogInterface?, _: Int ->
113+
// start uninstall intent
114+
val intent = Intent(Intent.ACTION_DELETE)
115+
intent.data = Uri.parse("package:$packageName")
116+
startActivity(intent)
117+
}
118+
materialAlertDialogBuilder.setNegativeButton(R.string.cancel) { _: DialogInterface?, _: Int -> }
119+
}
120+
}
121+
androidacyPkgName -> {
122+
if (packageName == foxPkgName || packageName == foxPkgNameFdroid || packageName == foxPkgNameDebug || packageName == foxPkgNamePlay) {
123+
val materialAlertDialogBuilder = MaterialAlertDialogBuilder(this)
124+
materialAlertDialogBuilder.setTitle(R.string.setup_uninstall_title)
125+
materialAlertDialogBuilder.setMessage(getString(R.string.setup_uninstall_message, packageName))
126+
materialAlertDialogBuilder.setPositiveButton(R.string.uninstall) { _: DialogInterface?, _: Int ->
127+
// start uninstall intent
128+
val intent = Intent(Intent.ACTION_DELETE)
129+
intent.data = Uri.parse("package:$packageName")
130+
startActivity(intent)
131+
}
132+
materialAlertDialogBuilder.setNegativeButton(R.string.cancel) { _: DialogInterface?, _: Int -> }
133+
}
134+
}
135+
else -> {
136+
if (packageName == foxPkgNameDebug) {
137+
val materialAlertDialogBuilder = MaterialAlertDialogBuilder(this)
138+
materialAlertDialogBuilder.setTitle(R.string.setup_uninstall_title)
139+
materialAlertDialogBuilder.setMessage(getString(R.string.setup_uninstall_message, packageName))
140+
materialAlertDialogBuilder.setPositiveButton(R.string.uninstall) { _: DialogInterface?, _: Int ->
141+
// start uninstall intent
142+
val intent = Intent(Intent.ACTION_DELETE)
143+
intent.data = Uri.parse("package:$packageName")
144+
startActivity(intent)
145+
}
146+
materialAlertDialogBuilder.setNegativeButton(R.string.cancel) { _: DialogInterface?, _: Int -> }
147+
}
148+
}
149+
}
150+
}
88151
(Objects.requireNonNull<Any>(view.findViewById(R.id.setup_background_update_check)) as MaterialSwitch).isChecked =
89152
BuildConfig.ENABLE_AUTO_UPDATER
90153
(Objects.requireNonNull<Any>(view.findViewById(R.id.setup_crash_reporting)) as MaterialSwitch).isChecked =
@@ -205,10 +268,16 @@ class SetupActivity : FoxActivity(), LanguageActivity {
205268
val setupButton = view.findViewById<BottomNavigationItemView>(R.id.setup_finish)
206269
// on clicking setup_agree_eula, enable the setup button if it's checked, if it's not, disable it
207270
val agreeEula = view.findViewById<MaterialCheckBox>(R.id.setup_agree_eula)
208-
agreeEula.setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
209-
setupButton.isEnabled = isChecked
210-
}
211271
setupButton.setOnClickListener { _: View? ->
272+
// if agreeEula is not checked, show a toast and return
273+
if (!agreeEula.isChecked) {
274+
Toast.makeText(
275+
this,
276+
R.string.setup_agree_eula_toast,
277+
Toast.LENGTH_LONG
278+
).show()
279+
return@setOnClickListener
280+
}
212281
Timber.i("Setup button clicked")
213282
// get instance of editor
214283
if (BuildConfig.DEBUG) Timber.d("Saving preferences")
@@ -247,6 +316,14 @@ class SetupActivity : FoxActivity(), LanguageActivity {
247316
"pref_analytics_enabled",
248317
(Objects.requireNonNull<Any>(view.findViewById(R.id.setup_app_analytics)) as MaterialSwitch).isChecked
249318
)
319+
// setup_require_security -> pref_require_security
320+
editor.putBoolean(
321+
"pref_require_security", (Objects.requireNonNull<Any>(
322+
view.findViewById(
323+
R.id.setup_require_security
324+
)
325+
) as MaterialSwitch).isChecked
326+
)
250327
if (BuildConfig.DEBUG) Timber.d("Saving preferences")
251328
// now basically do the same thing for room db
252329
val db = Room.databaseBuilder(
@@ -262,7 +339,7 @@ class SetupActivity : FoxActivity(), LanguageActivity {
262339
reposListDao.setEnabled(androidacyRepoRoomObj.id, androidacyRepoRoom)
263340
reposListDao.setEnabled(magiskAltRepoRoomObj.id, magiskAltRepoRoom)
264341
db.close()
265-
editor.putString("last_shown_setup", "v3")
342+
editor.putString("last_shown_setup", "v4")
266343
// Commit the changes
267344
editor.commit()
268345
// Log the changes
@@ -415,11 +492,11 @@ class SetupActivity : FoxActivity(), LanguageActivity {
415492
safe = false,
416493
stats = 0,
417494
)
495+
moduleListCacheDao.deleteAll()
418496
// insert the modulelistcache into the database
419497
moduleListCacheDao.insert(moduleListCache)
420498
// now make sure reposlist is updated with 2 entries and modulelistcache is updated with 1 entry
421499
val reposList = reposListDao.getAll()
422-
val moduleListCacheList = moduleListCacheDao.getAll()
423500
// make sure reposlist is updated with 2 entries
424501
if (reposList.size != 2) {
425502
Timber.e("ReposList is not updated with 2 entries")
@@ -435,7 +512,7 @@ class SetupActivity : FoxActivity(), LanguageActivity {
435512
if (BuildConfig.DEBUG) Timber.d("ReposList is updated with 2 entries")
436513
}
437514
// make sure modulelistcache is updated with 1 entry
438-
if (moduleListCacheList.size != 1) {
515+
if (moduleListCacheDao.getAll().size != 1) {
439516
Timber.e("ModuleListCache is not updated with 1 entry")
440517
// show a toast
441518
runOnUiThread {

app/src/main/kotlin/com/fox2code/mmm/background/BackgroundUpdateChecker.kt

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import android.content.Intent
1414
import android.content.pm.PackageManager
1515
import android.net.ConnectivityManager
1616
import android.net.NetworkCapabilities
17-
import android.os.Build
1817
import androidx.core.app.NotificationChannelCompat
1918
import androidx.core.app.NotificationCompat
2019
import androidx.core.app.NotificationManagerCompat
@@ -381,19 +380,17 @@ class BackgroundUpdateChecker(context: Context, workerParams: WorkerParameters)
381380
fun onMainActivityCreate(context: Context) {
382381
// Refuse to run if first_launch pref is not false
383382
if (MainApplication.getSharedPreferences("mmm")!!
384-
.getString("last_shown_setup", null) != "v3"
383+
.getString("last_shown_setup", null) != "v4"
385384
) return
386385
// create notification channel group
387-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
388-
val groupName: CharSequence = context.getString(R.string.notification_group_updates)
389-
val mNotificationManager =
390-
ContextCompat.getSystemService(context, NotificationManager::class.java)
391-
mNotificationManager?.createNotificationChannelGroup(
392-
NotificationChannelGroup(
393-
NOTFIICATION_GROUP, groupName
394-
)
386+
val groupName: CharSequence = context.getString(R.string.notification_group_updates)
387+
val mNotificationManager =
388+
ContextCompat.getSystemService(context, NotificationManager::class.java)
389+
mNotificationManager?.createNotificationChannelGroup(
390+
NotificationChannelGroup(
391+
NOTFIICATION_GROUP, groupName
395392
)
396-
}
393+
)
397394
val notificationManagerCompat = NotificationManagerCompat.from(context)
398395
notificationManagerCompat.createNotificationChannel(
399396
NotificationChannelCompat.Builder(

app/src/main/kotlin/com/fox2code/mmm/manager/ModuleManager.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ class ModuleManager private constructor() : SyncManager() {
3232
private var updatableModuleCount = 0
3333

3434
override fun scanInternal(updateListener: UpdateListener) {
35-
// if last_shown_setup is not "v3", then refuse to continue
35+
// if last_shown_setup is not "v4", then refuse to continue
3636
if (MainApplication.getSharedPreferences("mmm")!!
37-
.getString("last_shown_setup", "") != "v3"
37+
.getString("last_shown_setup", "") != "v4"
3838
) {
3939
return
4040
}

app/src/main/kotlin/com/fox2code/mmm/module/ActionButtonType.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import androidx.annotation.DrawableRes
1414
import com.fox2code.foxcompat.app.FoxActivity
1515
import com.fox2code.foxcompat.view.FoxDisplay
1616
import com.fox2code.mmm.BuildConfig
17+
import com.fox2code.mmm.MainApplication
1718
import com.fox2code.mmm.MainApplication.Companion.INSTANCE
1819
import com.fox2code.mmm.MainApplication.Companion.isShowcaseMode
1920
import com.fox2code.mmm.R
@@ -121,6 +122,19 @@ enum class ActionButtonType {
121122
}
122123

123124
override fun doAction(button: Chip, moduleHolder: ModuleHolder) {
125+
if (MainApplication.getSharedPreferences("mmm")?.getBoolean("pref_require_security", false) == true) {
126+
// get safe status from either mainmoduleinfo or repo module
127+
val safe = moduleHolder.mainModuleInfo.safe || moduleHolder.repoModule?.moduleInfo?.safe ?: false
128+
if (!safe) {
129+
// block local install for safety
130+
MaterialAlertDialogBuilder(button.context)
131+
.setTitle(R.string.install_blocked)
132+
.setMessage(R.string.install_blocked_message)
133+
.setPositiveButton(android.R.string.ok, null)
134+
.show()
135+
return
136+
}
137+
}
124138
// if mainmoduleinfo is null, we are in repo mode
125139
val moduleInfo: ModuleInfo = if (moduleHolder.mainModuleInfo != null) {
126140
moduleHolder.mainModuleInfo

app/src/main/kotlin/com/fox2code/mmm/repo/CustomRepoManager.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class CustomRepoManager internal constructor(
3030
init {
3131
repoCount = 0
3232
// refuse to load if setup is not complete
33-
if (getSharedPreferences("mmm")!!.getString("last_shown_setup", "") == "v3") {
33+
if (getSharedPreferences("mmm")!!.getString("last_shown_setup", "") == "v4") {
3434
val i = 0
3535
val lastFilled = intArrayOf(0)
3636
// now the same as above but for room database

app/src/main/kotlin/com/fox2code/mmm/repo/RepoManager.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class RepoManager private constructor(mainApplication: MainApplication) : SyncMa
5656
repoData = LinkedHashMap()
5757
modules = HashMap()
5858
// refuse to load if setup is not complete
59-
if (getSharedPreferences("mmm")!!.getString("last_shown_setup", "") == "v3") {
59+
if (getSharedPreferences("mmm")!!.getString("last_shown_setup", "") == "v4") {
6060
// We do not have repo list config yet.
6161
androidacyRepoData = addAndroidacyRepoData()
6262
val altRepo = addRepoData(MAGISK_ALT_REPO, "Magisk Modules Alt Repo")
@@ -82,8 +82,8 @@ class RepoManager private constructor(mainApplication: MainApplication) : SyncMa
8282
}
8383

8484
private fun populateDefaultCache(repoData: RepoData?) {
85-
// if last_shown_setup is not "v3", them=n refuse to continue
86-
if (getSharedPreferences("mmm")!!.getString("last_shown_setup", "") != "v3") {
85+
// if last_shown_setup is not "v4", them=n refuse to continue
86+
if (getSharedPreferences("mmm")!!.getString("last_shown_setup", "") != "v4") {
8787
return
8888
}
8989
// make sure repodata is not null

app/src/main/kotlin/com/fox2code/mmm/settings/DebugFragment.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import java.io.File
2525
import java.io.FileOutputStream
2626
import java.io.IOException
2727
import java.io.InputStreamReader
28+
import java.util.Date
2829

2930
class DebugFragment : PreferenceFragmentCompat() {
3031
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
@@ -182,6 +183,17 @@ class DebugFragment : PreferenceFragmentCompat() {
182183
}
183184
}
184185
}
186+
// save logs to our external storage - name is current date and time
187+
try {
188+
val extStorage = File(requireContext().getExternalFilesDir(null), "logs" + File.separator + "log-" + Date().toString() + ".txt")
189+
FileUtils.copyFile(logsFile, extStorage)
190+
} catch (e: IOException) {
191+
e.printStackTrace()
192+
Toast.makeText(
193+
requireContext(), R.string.error_saving_logs, Toast.LENGTH_SHORT
194+
).show()
195+
return@setOnPreferenceClickListener true
196+
}
185197
// Share logs
186198
val shareIntent = Intent()
187199
// create a new intent and grantUriPermission to the file provider

app/src/main/kotlin/com/fox2code/mmm/utils/RuntimeUtils.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ class RuntimeUtils {
159159
if (BuildConfig.DEBUG) Timber.i("Checking if we need to run setup")
160160
// Check if context is the first launch using prefs and if doSetupRestarting was passed in the intent
161161
val prefs = MainApplication.getSharedPreferences("mmm")!!
162-
var firstLaunch = prefs.getString("last_shown_setup", null) != "v3"
162+
var firstLaunch = prefs.getString("last_shown_setup", null) != "v4"
163163
// First launch
164164
// context is intentionally separate from the above if statement, because it needs to be checked even if the first launch check is true due to some weird edge cases
165165
if (activity.intent.getBooleanExtra("doSetupRestarting", false)) {

0 commit comments

Comments
 (0)