Skip to content

Commit 74e3a74

Browse files
migrate to room db pt1/?
WARNING: does not compile as-is. tests are expected to fail. [skip actions] Signed-off-by: androidacy-user <opensource@androidacy.com>
1 parent 0265e39 commit 74e3a74

19 files changed

Lines changed: 136 additions & 598 deletions

app/build.gradle.kts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ plugins {
1919
id("io.sentry.android.gradle")
2020
}
2121

22-
// apply realm-android
23-
apply(plugin = "realm-android")
2422
val hasSentryConfig = File(rootProject.projectDir, "sentry.properties").exists()
2523
android {
2624
// functions to get git info: gitCommitHash, gitBranch, gitRemote
@@ -527,6 +525,9 @@ dependencies {
527525
// yes
528526
implementation("com.github.fingerprintjs:fingerprint-android:2.0.0")
529527

528+
// encryption for room
529+
implementation("net.zetetic:android-database-sqlcipher:4.5.4")
530+
530531
// room
531532
implementation("androidx.room:room-runtime:2.5.1")
532533

app/proguard-rules.pro

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,9 @@
195195

196196
-keepclassmembers class org.apache.commons.compress.archivers.zip.* { *; }
197197

198+
-keep,includedescriptorclasses class net.sqlcipher.** { *; }
199+
-keep,includedescriptorclasses interface net.sqlcipher.** { *; }
200+
198201
# dontwarn
199202
-dontwarn android.os.SystemProperties
200203
-dontwarn android.view.ThreadedRenderer
8 KB
Binary file not shown.

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

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import androidx.appcompat.widget.SearchView
2828
import androidx.cardview.widget.CardView
2929
import androidx.recyclerview.widget.LinearLayoutManager
3030
import androidx.recyclerview.widget.RecyclerView
31+
import androidx.room.Room
3132
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
3233
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener
3334
import com.fox2code.foxcompat.app.FoxActivity
@@ -54,11 +55,9 @@ import com.fox2code.mmm.utils.RuntimeUtils
5455
import com.fox2code.mmm.utils.SyncManager
5556
import com.fox2code.mmm.utils.io.net.Http.Companion.cleanDnsCache
5657
import com.fox2code.mmm.utils.io.net.Http.Companion.hasWebView
57-
import com.fox2code.mmm.utils.realm.ReposList
58+
import com.fox2code.mmm.utils.room.ReposListDatabase
5859
import com.google.android.material.bottomnavigation.BottomNavigationView
5960
import com.google.android.material.progressindicator.LinearProgressIndicator
60-
import io.realm.Realm
61-
import io.realm.RealmConfiguration
6261
import org.matomo.sdk.extra.TrackHelper
6362
import timber.log.Timber
6463
import java.sql.Timestamp
@@ -104,25 +103,24 @@ class MainActivity : FoxActivity(), OnRefreshListener, SearchView.OnQueryTextLis
104103
super.onCreate(savedInstanceState)
105104
TrackHelper.track().screen(this).with(MainApplication.INSTANCE!!.tracker)
106105
// track enabled repos
107-
val realmConfig = RealmConfiguration.Builder().name("ReposList.realm")
108-
.encryptionKey(MainApplication.INSTANCE!!.key)
109-
.directory(MainApplication.INSTANCE!!.getDataDirWithPath("realms")).schemaVersion(1)
110-
.allowQueriesOnUiThread(true).allowWritesOnUiThread(true).build()
111-
val realm = Realm.getInstance(realmConfig)
106+
val db = Room.databaseBuilder(
107+
applicationContext,
108+
ReposListDatabase::class.java,
109+
"reposlist.db"
110+
).build()
111+
val repoDao = db.reposListDao()
112+
val repos = repoDao.getAll()
112113
val enabledRepos = StringBuilder()
113-
realm.executeTransaction { r: Realm ->
114-
for (r2 in r.where(
115-
ReposList::class.java
116-
).equalTo("enabled", true).findAll()) {
117-
enabledRepos.append(r2.url).append(":").append(r2.name).append(",")
114+
for (repo in repos) {
115+
if (repo.enabled) {
116+
enabledRepos.append(repo.url).append(", ")
118117
}
119118
}
120119
if (enabledRepos.isNotEmpty()) {
121-
enabledRepos.setLength(enabledRepos.length - 1)
120+
enabledRepos.delete(enabledRepos.length - 2, enabledRepos.length)
121+
TrackHelper.track().event("Enabled Repos", enabledRepos.toString())
122+
.with(MainApplication.INSTANCE!!.tracker)
122123
}
123-
TrackHelper.track().event("enabled_repos", enabledRepos.toString())
124-
.with(MainApplication.INSTANCE!!.tracker)
125-
realm.close()
126124
// hide this behind a buildconfig flag for now, but crash the app if it's not an official build and not debug
127125
if (BuildConfig.ENABLE_PROTECTION && !MainApplication.o && !BuildConfig.DEBUG) {
128126
throw RuntimeException("This is not an official build of AMM")

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@ import android.webkit.CookieManager
1818
import android.widget.CompoundButton
1919
import android.widget.Toast
2020
import androidx.fragment.app.FragmentActivity
21+
import androidx.room.Room
2122
import com.fox2code.foxcompat.app.FoxActivity
2223
import com.fox2code.mmm.databinding.ActivitySetupBinding
2324
import com.fox2code.mmm.utils.IntentHelper
2425
import com.fox2code.mmm.utils.realm.ReposList
26+
import com.fox2code.mmm.utils.room.ModuleListCacheDatabase
27+
import com.fox2code.mmm.utils.room.ReposListDatabase
2528
import com.fox2code.rosettax.LanguageActivity
2629
import com.fox2code.rosettax.LanguageSwitcher
2730
import com.google.android.material.bottomnavigation.BottomNavigationItemView
@@ -254,7 +257,7 @@ class SetupActivity : FoxActivity(), LanguageActivity {
254257
r.close()
255258
Timber.d("Realm transaction committed")
256259
}
257-
editor.putString("last_shown_setup", "v2")
260+
editor.putString("last_shown_setup", "v3")
258261
// Commit the changes
259262
editor.commit()
260263
// sleep to allow the realm transaction to finish
@@ -347,7 +350,18 @@ class SetupActivity : FoxActivity(), LanguageActivity {
347350

348351
// creates the room database
349352
private fun createDatabases() {
353+
val startTime = System.currentTimeMillis()
350354
val appContext = MainApplication.INSTANCE!!.applicationContext
355+
Room.databaseBuilder(appContext, ReposListDatabase::class.java, "reposlist.db")
356+
.createFromAsset("assets/reposlist.db")
357+
.fallbackToDestructiveMigration()
358+
.build()
359+
// same for modulelistcache
360+
Room.databaseBuilder(appContext, ModuleListCacheDatabase::class.java, "modulelistcache.db")
361+
.createFromAsset("assets/modulelistcache.db")
362+
.fallbackToDestructiveMigration()
363+
.build()
364+
Timber.d("Databases created in %s ms", System.currentTimeMillis() - startTime)
351365
}
352366

353367
private fun createFiles() {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ class BackgroundUpdateChecker(context: Context, workerParams: WorkerParameters)
374374
fun onMainActivityCreate(context: Context) {
375375
// Refuse to run if first_launch pref is not false
376376
if (MainApplication.getSharedPreferences("mmm")!!
377-
.getString("last_shown_setup", null) != "v2"
377+
.getString("last_shown_setup", null) != "v3"
378378
) return
379379
// create notification channel group
380380
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

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

Lines changed: 36 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,34 @@
77
package com.fox2code.mmm.manager
88

99
import android.content.SharedPreferences
10+
import androidx.room.Room
1011
import com.fox2code.mmm.BuildConfig
1112
import com.fox2code.mmm.MainApplication
1213
import com.fox2code.mmm.installer.InstallerInitializer.Companion.peekModulesPath
1314
import com.fox2code.mmm.utils.SyncManager
1415
import com.fox2code.mmm.utils.io.PropUtils
15-
import com.fox2code.mmm.utils.realm.ModuleListCache
16+
import com.fox2code.mmm.utils.room.ModuleListCache
17+
import com.fox2code.mmm.utils.room.ModuleListCacheDao
18+
import com.fox2code.mmm.utils.room.ModuleListCacheDatabase
1619
import com.topjohnwu.superuser.Shell
1720
import com.topjohnwu.superuser.io.SuFile
1821
import com.topjohnwu.superuser.io.SuFileInputStream
19-
import io.realm.Realm
20-
import io.realm.RealmConfiguration
2122
import org.matomo.sdk.extra.TrackHelper
2223
import timber.log.Timber
2324
import java.io.BufferedReader
24-
import java.io.File
2525
import java.io.IOException
2626
import java.io.InputStreamReader
2727
import java.nio.charset.StandardCharsets
28-
import java.util.Objects
2928

3029
class ModuleManager private constructor() : SyncManager() {
3130
private val moduleInfos: HashMap<String, LocalModuleInfo> = HashMap()
3231
private val bootPrefs: SharedPreferences = MainApplication.bootSharedPreferences!!
3332
private var updatableModuleCount = 0
3433

3534
override fun scanInternal(updateListener: UpdateListener) {
36-
// if last_shown_setup is not "v2", then refuse to continue
35+
// if last_shown_setup is not "v3", then refuse to continue
3736
if (MainApplication.getSharedPreferences("mmm")!!
38-
.getString("last_shown_setup", "") != "v2"
37+
.getString("last_shown_setup", "") != "v3"
3938
) {
4039
return
4140
}
@@ -65,60 +64,36 @@ class ModuleManager private constructor() : SyncManager() {
6564
for (module in modules) {
6665
if (!SuFile("/data/adb/modules/$module").isDirectory) continue // Ignore non directory files inside modules folder
6766
var moduleInfo = moduleInfos[module]
68-
// next, merge the module info with a record from ModuleListCache if it exists
69-
var realmConfiguration: RealmConfiguration?
70-
// get all dirs under the realms/repos/ dir under app's data dir
71-
val cacheRoot =
72-
File(MainApplication.INSTANCE!!.getDataDirWithPath("realms/repos/").toURI())
73-
var moduleListCache: ModuleListCache?
74-
for (dir in Objects.requireNonNull<Array<File>>(cacheRoot.listFiles())) {
75-
if (dir.isDirectory) {
76-
// if the dir name matches the module name, use it as the cache dir
77-
val tempCacheRoot = File(dir.toString())
78-
Timber.d("Looking for cache in %s", tempCacheRoot)
79-
realmConfiguration =
80-
RealmConfiguration.Builder().name("ModuleListCache.realm")
81-
.encryptionKey(MainApplication.INSTANCE!!.key).schemaVersion(1)
82-
.deleteRealmIfMigrationNeeded().allowWritesOnUiThread(true)
83-
.allowQueriesOnUiThread(true).directory(tempCacheRoot).build()
84-
val realm = Realm.getInstance(realmConfiguration!!)
85-
Timber.d(
86-
"Looking for cache for %s out of %d", module, realm.where(
87-
ModuleListCache::class.java
88-
).count()
89-
)
90-
moduleListCache =
91-
realm.where(ModuleListCache::class.java).equalTo("codename", module)
92-
.findFirst()
93-
Timber.d("Found cache for %s", module)
94-
// get module info from cache
95-
if (moduleInfo == null) {
96-
moduleInfo = LocalModuleInfo(module)
97-
}
98-
if (moduleListCache != null) {
99-
moduleInfo.name =
100-
if (moduleListCache.name != "") moduleListCache.name else module
101-
moduleInfo.description =
102-
if (moduleListCache.description != "") moduleListCache.description else moduleInfo.description
103-
moduleInfo.author =
104-
if (moduleListCache.author != "") moduleListCache.author else moduleInfo.author
105-
moduleInfo.safe = moduleListCache.isSafe == true
106-
moduleInfo.support =
107-
if (moduleListCache.support != "") moduleListCache.support else null
108-
moduleInfo.donate =
109-
if (moduleListCache.donate != "") moduleListCache.donate else null
110-
moduleInfo.flags = moduleInfo.flags or FLAG_MM_REMOTE_MODULE
111-
moduleInfos[module] = moduleInfo
112-
}
113-
realm.close()
114-
break
115-
}
116-
}
67+
// next, merge the module info with a record from ModuleListCache room db if it exists
68+
// initialize modulelistcache db
69+
// DO NOT USE REALM ANYMORE
70+
val db = Room.databaseBuilder(
71+
MainApplication.INSTANCE!!,
72+
ModuleListCacheDatabase::class.java,
73+
"ModuleListCache"
74+
).build()
75+
// get module info from cache
76+
val moduleListCacheDao: ModuleListCacheDao = db.moduleListCacheDao()
77+
Timber.d("Found cache for %s", module)
78+
// get module info from cache
11779
if (moduleInfo == null) {
11880
moduleInfo = LocalModuleInfo(module)
81+
}
82+
if (moduleListCacheDao.exists(module)) {
83+
val moduleListCache: ModuleListCache = moduleListCacheDao.getByCodename(module)
84+
moduleInfo.name =
85+
if (moduleListCache.name != "") moduleListCache.name else module
86+
moduleInfo.description =
87+
if (moduleListCache.description != "") moduleListCache.description else moduleInfo.description
88+
moduleInfo.author =
89+
if (moduleListCache.author != "") moduleListCache.author else moduleInfo.author
90+
moduleInfo.safe = moduleListCache.safe == true
91+
moduleInfo.support =
92+
if (moduleListCache.support != "") moduleListCache.support else null
93+
moduleInfo.donate =
94+
if (moduleListCache.donate != "") moduleListCache.donate else null
95+
moduleInfo.flags = moduleInfo.flags or FLAG_MM_REMOTE_MODULE
11996
moduleInfos[module] = moduleInfo
120-
// This should not really happen, but let's handles theses cases anyway
121-
moduleInfo.flags = moduleInfo.flags or ModuleInfo.FLAG_MODULE_UPDATING_ONLY
12297
}
12398
moduleInfo.flags = moduleInfo.flags and FLAGS_RESET_UPDATE.inv()
12499
if (SuFile("/data/adb/modules/$module/disable").exists()) {
@@ -131,8 +106,7 @@ class ModuleManager private constructor() : SyncManager() {
131106
moduleInfo.flags = moduleInfo.flags or ModuleInfo.FLAG_MODULE_UNINSTALLING
132107
}
133108
if (firstScan && !needFallback && SuFile(
134-
modulesPath,
135-
module
109+
modulesPath, module
136110
).exists() || bootPrefs.getBoolean("module_" + moduleInfo.id + "_active", false)
137111
) {
138112
moduleInfo.flags = moduleInfo.flags or ModuleInfo.FLAG_MODULE_ACTIVE
@@ -152,9 +126,7 @@ class ModuleManager private constructor() : SyncManager() {
152126
}
153127
try {
154128
PropUtils.readProperties(
155-
moduleInfo,
156-
"/data/adb/modules/$module/module.prop",
157-
true
129+
moduleInfo, "/data/adb/modules/$module/module.prop", true
158130
)
159131
} catch (e: Exception) {
160132
if (BuildConfig.DEBUG) Timber.d(e)
@@ -186,9 +158,7 @@ class ModuleManager private constructor() : SyncManager() {
186158
moduleInfo.flags = moduleInfo.flags or ModuleInfo.FLAG_MODULE_UPDATING
187159
try {
188160
PropUtils.readProperties(
189-
moduleInfo,
190-
"/data/adb/modules_update/$module/module.prop",
191-
true
161+
moduleInfo, "/data/adb/modules_update/$module/module.prop", true
192162
)
193163
} catch (e: Exception) {
194164
if (BuildConfig.DEBUG) Timber.d(e)

0 commit comments

Comments
 (0)