Skip to content

Commit

Permalink
make module compatible
Browse files Browse the repository at this point in the history
  • Loading branch information
DerGoogler committed Oct 5, 2024
1 parent 25f9e1c commit 75c2631
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 69 deletions.
12 changes: 9 additions & 3 deletions app/schemas/com.dergoogler.mmrl.database.AppDatabase/1.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "48e744a8188bf09dc610ffe40bb08b4a",
"identityHash": "57b23e1158295bb6e9fac8230eee7245",
"entities": [
{
"tableName": "repos",
Expand Down Expand Up @@ -413,7 +413,7 @@
},
{
"tableName": "localModules",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `version` TEXT NOT NULL, `versionCode` INTEGER NOT NULL, `author` TEXT NOT NULL, `description` TEXT NOT NULL, `state` TEXT NOT NULL, `updateJson` TEXT NOT NULL, `lastUpdated` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `version` TEXT NOT NULL, `versionCode` INTEGER NOT NULL, `author` TEXT NOT NULL, `description` TEXT NOT NULL, `state` TEXT NOT NULL, `hasModConf` INTEGER NOT NULL, `updateJson` TEXT NOT NULL, `lastUpdated` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
Expand Down Expand Up @@ -457,6 +457,12 @@
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "hasModConf",
"columnName": "hasModConf",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "updateJson",
"columnName": "updateJson",
Expand All @@ -483,7 +489,7 @@
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '48e744a8188bf09dc610ffe40bb08b4a')"
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '57b23e1158295bb6e9fac8230eee7245')"
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ data class LocalModuleEntity(
val author: String,
val description: String,
val state: String,
val hasModConf: Boolean,
val updateJson: String,
val lastUpdated: Long
) {
Expand All @@ -25,6 +26,7 @@ data class LocalModuleEntity(
author = original.author,
description = original.description,
state = original.state.name,
hasModConf = original.hasModConf,
updateJson = original.updateJson,
lastUpdated = original.lastUpdated
)
Expand All @@ -38,6 +40,7 @@ data class LocalModuleEntity(
description = description,
updateJson = updateJson,
state = State.valueOf(state),
hasModConf = hasModConf,
lastUpdated = lastUpdated
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ fun LocalModule.Companion.example() =
description = "This is an example!",
updateJson = "",
state = State.ENABLE,
hasModConf = false,
lastUpdated = 0L
)
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import androidx.compose.runtime.Composer
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.currentComposer
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.dergoogler.mmrl.Compat
import com.dergoogler.mmrl.datastore.UserPreferencesCompat.Companion.isRoot
Expand All @@ -31,7 +32,6 @@ import javax.inject.Inject
class ModConfActivity : ComponentActivity() {
@Inject
lateinit var userPreferencesRepository: UserPreferencesRepository
private lateinit var pluginClass: Class<*>
private val viewModel: ModConfViewModel by viewModels()

override fun onCreate(savedInstanceState: Bundle?) {
Expand All @@ -43,6 +43,7 @@ class ModConfActivity : ComponentActivity() {

setContent {
val current = currentComposer
val context = LocalContext.current
val userPreferences by userPreferencesRepository.data.collectAsStateWithLifecycle(
initialValue = null
)
Expand All @@ -59,63 +60,17 @@ class ModConfActivity : ComponentActivity() {
AppTheme(
darkMode = preferences.isDarkMode(), themeColor = preferences.themeColor
) {
loadComposablePlugin(
viewModel.loadComposablePlugin(
context = context,
id = modId,
fixedModId = fixedModId,
composer = current,
dexPath = "$fixedModId.dex"
)
}
}
}
}

private fun loadComposablePlugin(
id: String, fixedModId: String, composer: Composer, dexPath: String
): Composable? {
return try {
val optimizedDir = File(this.cacheDir, "dex_optimized").apply { mkdirs() }

val dexFilePath = File(this.filesDir, dexPath)
dexFilePath.setReadOnly()

val classLoader = DexClassLoader(
dexFilePath.path, optimizedDir.absolutePath, null, this.classLoader
)

val pluginClassName = "com.dergoogler.modconf.$fixedModId.ModConfScreenKt"
pluginClass = classLoader.loadClass(pluginClassName)

setField("isProviderAlive", viewModel.isProviderAlive)
setField("managerName", viewModel.managerName)
setField("versionName", viewModel.versionName)
setField("versionCode", viewModel.versionCode)
setField("modId", id)
setField("fixedModId", fixedModId)

val pluginInstance = pluginClass.getDeclaredMethod(
"ModConfScreen", Composer::class.java, Int::class.java
)

pluginInstance.isAccessible = true

pluginInstance.invoke(null, composer, 0) as? Composable
} catch (e: Exception) {
e.printStackTrace()
null
}
}

private fun setField(fieldName: String, value: Any) {
try {
val field = pluginClass.getDeclaredField(fieldName)
field.isAccessible = true
field.set(null, value)
} catch (e: Exception) {
Timber.e(e, "Failed to set field $fieldName")
}
}

companion object {
fun start(context: Context, modId: String) {
val intent = Intent(context, ModConfActivity::class.java)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,16 @@ fun ModuleItem(
trailingButton = {


ModConf(
enabled = isProviderAlive,
onClick = {
ModConfActivity.start(context = context, modId = module.id)
}
)

Spacer(modifier = Modifier.width(12.dp))
if (module.hasModConf) {
ModConf(
enabled = isProviderAlive,
onClick = {
ModConfActivity.start(context = context, modId = module.id)
}
)

Spacer(modifier = Modifier.width(12.dp))
}

if (item != null) {
UpdateButton(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
package com.dergoogler.mmrl.viewmodel

import android.content.Context
import android.os.Build
import android.util.Log
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Composer
import androidx.lifecycle.ViewModel
import com.dergoogler.mmrl.Compat
import dagger.hilt.android.lifecycle.HiltViewModel
import dalvik.system.DexClassLoader
import timber.log.Timber
import java.io.File
import javax.inject.Inject

@HiltViewModel
class ModConfViewModel @Inject constructor(
) : ViewModel() {
val isProviderAlive get() = Compat.isAlive
private lateinit var pluginClass: Class<*>

val versionName: String
get() = Compat.get("") {
Expand All @@ -24,4 +33,63 @@ class ModConfViewModel @Inject constructor(
get() = Compat.get("") {
with(moduleManager) { managerName }
}

fun loadComposablePlugin(
context: Context,
id: String,
fixedModId: String,
composer: Composer,
): Composable? {
return try {
val optimizedDir = File(context.cacheDir, "dex_optimized").apply { mkdirs() }

val dexFilePath = if (Build.SUPPORTED_64_BIT_ABIS.isNotEmpty())
File("/system/lib64", "$fixedModId.dex")
else
File("/system/lib", "$fixedModId.dex")

try {
dexFilePath.setReadOnly()
} catch (e: Exception) {
Timber.e("Unable to set readonly to ${dexFilePath.path}")
}

val classLoader = DexClassLoader(
dexFilePath.path, optimizedDir.absolutePath, null, context.classLoader
)

val pluginClassName = "com.dergoogler.modconf.$fixedModId.ModConfScreenKt"
pluginClass = classLoader.loadClass(pluginClassName)

setField("isProviderAlive", isProviderAlive)
setField("managerName", managerName)
setField("versionName", versionName)
setField("versionCode", versionCode)
setField("modId", id)
setField("fixedModId", fixedModId)

val pluginInstance = pluginClass.getDeclaredMethod(
"ModConfScreen", Composer::class.java, Int::class.java
)

pluginInstance.isAccessible = true

pluginInstance.invoke(null, composer, 0) as? Composable
} catch (e: Exception) {
e.printStackTrace()
null
}
}

fun setField(fieldName: String, value: Any) {
try {
val field = pluginClass.getDeclaredField(fieldName)
field.isAccessible = true
field.set(null, value)
} catch (e: Exception) {
Log.e("BaseModuleManagerImpl", "Failed to set field $fieldName")
}
}


}
12 changes: 4 additions & 8 deletions app/src/main/res/drawable/wifi.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,24 @@
android:pathData="M12,18l0.01,0"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="currentColor"
android:strokeColor="#fff"
android:strokeLineCap="round"/>
<path
android:pathData="M9.172,15.172a4,4 0,0 1,5.656 0"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="currentColor"
android:strokeColor="#fff"
android:strokeLineCap="round"/>
<path
android:pathData="M6.343,12.343a8,8 0,0 1,11.314 0"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="currentColor"
android:strokeColor="#fff"
android:strokeLineCap="round"/>
<path
android:pathData="M3.515,9.515c4.686,-4.687 12.284,-4.687 17,0"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="currentColor"
android:strokeColor="#fff"
android:strokeLineCap="round"/>
</vector>
1 change: 1 addition & 0 deletions compat/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ android {
}

dependencies {
implementation(libs.androidx.runtime.android)
compileOnly(projects.hiddenApi)
implementation(libs.hiddenApiBypass)
implementation(libs.rikka.refine.runtime)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ data class LocalModule(
val description: String,
val updateJson: String,
val state: State,
val hasModConf: Boolean,
val lastUpdated: Long
) : Parcelable {
companion object
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.dergoogler.mmrl.compat.impl

import android.os.Build
import com.topjohnwu.superuser.CallbackList
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.ShellUtils
Expand Down Expand Up @@ -45,6 +46,16 @@ internal abstract class BaseModuleManagerImpl(
readProps(dir)?.toModule(dir)
}

private fun hasModConf(moduleDir: File, id: String): Boolean {
val mId = id.replace(Regex("[^a-zA-Z0-9._]"), "_")

if (Build.SUPPORTED_64_BIT_ABIS.isNotEmpty()) {
return moduleDir.resolve("/system/lib64/$mId.dex").exists()
}

return moduleDir.resolve("/system/lib/$mId.dex").exists()
}

override fun getModuleById(id: String): LocalModule? {
val dir = modulesDir.resolve(id)
return readProps(dir)?.toModule(dir)
Expand Down Expand Up @@ -112,13 +123,15 @@ internal abstract class BaseModuleManagerImpl(
) = toModule(
path = dir.name,
state = readState(dir),
hasModConf = hasModConf(dir, getOrDefault("id", dir.name)),
lastUpdated = readLastUpdated(dir)
)

private fun Map<String, String>.toModule(
path: String = "unknown",
state: State = State.ENABLE,
lastUpdated: Long = 0L
lastUpdated: Long = 0L,
hasModConf: Boolean = false
) = LocalModule(
id = getOrDefault("id", path),
name = getOrDefault("name", path),
Expand All @@ -128,6 +141,7 @@ internal abstract class BaseModuleManagerImpl(
description = getOrDefault("description", ""),
updateJson = getOrDefault("updateJson", ""),
state = state,
hasModConf = hasModConf,
lastUpdated = lastUpdated
)

Expand Down
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ shizuku = "13.1.5"
squareRetrofit = "2.11.0"
squareOkhttp = "4.12.0"
squareMoshi = "1.15.1"
runtimeAndroid = "1.7.3"

[libraries]
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "androidxActivity" }
Expand Down Expand Up @@ -94,6 +95,7 @@ android-gradle = { group = "com.android.tools.build", name = "gradle", version.r
compose-gradle= { module = "org.jetbrains.kotlin:compose-compiler-gradle-plugin", version.ref = "kotlin" }
kotlin-gradle = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" }
ksp-gradle = { group = "com.google.devtools.ksp", name = "com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" }
androidx-runtime-android = { group = "androidx.compose.runtime", name = "runtime-android", version.ref = "runtimeAndroid" }

[plugins]
android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }
Expand Down

0 comments on commit 75c2631

Please sign in to comment.