diff --git a/app/src/main/kotlin/com/dergoogler/mmrl/ui/activity/ModConfActivity.kt b/app/src/main/kotlin/com/dergoogler/mmrl/ui/activity/ModConfActivity.kt index e7658a36..bfbc6178 100644 --- a/app/src/main/kotlin/com/dergoogler/mmrl/ui/activity/ModConfActivity.kt +++ b/app/src/main/kotlin/com/dergoogler/mmrl/ui/activity/ModConfActivity.kt @@ -21,15 +21,15 @@ class ModConfActivity : MMRLComponentActivity() { val isDebug = intent.getBooleanExtra("DEBUG", false) - val modId = intent.getStringExtra("MOD_ID") ?: return + val modId = intent.getStringExtra("MOD_ID") ?: "null" val fixedModId = modId.replace(Regex("[^a-zA-Z0-9._]"), "_") - setBaseContent { val context = LocalContext.current viewModel.loadComposablePlugin( context = context, + standaloneData = intent.data, isDebug = isDebug, id = modId, fixedModId = fixedModId, diff --git a/app/src/main/kotlin/com/dergoogler/mmrl/viewmodel/ModConfViewModel.kt b/app/src/main/kotlin/com/dergoogler/mmrl/viewmodel/ModConfViewModel.kt index fcc876af..85344a45 100644 --- a/app/src/main/kotlin/com/dergoogler/mmrl/viewmodel/ModConfViewModel.kt +++ b/app/src/main/kotlin/com/dergoogler/mmrl/viewmodel/ModConfViewModel.kt @@ -2,19 +2,32 @@ package com.dergoogler.mmrl.viewmodel import android.annotation.SuppressLint import android.content.Context +import android.net.Uri import android.os.Build import androidx.compose.runtime.Composable import androidx.compose.runtime.Composer +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import com.dergoogler.mmrl.BuildConfig import com.dergoogler.mmrl.Compat +import com.dergoogler.mmrl.app.Event +import com.dergoogler.mmrl.compat.MediaStoreCompat.copyToDir +import com.dergoogler.mmrl.compat.MediaStoreCompat.getPathForUri import dagger.hilt.android.lifecycle.HiltViewModel import dalvik.system.DexClassLoader import ext.dergoogler.mmrl.ext.findFileGlob +import ext.dergoogler.mmrl.ext.tmpDir +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.withContext import timber.log.Timber import java.io.File import java.nio.file.Path import javax.inject.Inject +import kotlin.io.path.Path +import kotlin.io.path.nameWithoutExtension @HiltViewModel @@ -41,6 +54,7 @@ class ModConfViewModel @Inject constructor( @SuppressLint("PrivateApi") fun loadComposablePlugin( context: Context, + standaloneData: Uri? = null, isDebug: Boolean, id: String, fixedModId: String, @@ -48,18 +62,32 @@ class ModConfViewModel @Inject constructor( hash: Int ): Composable? { return try { + + var modId by mutableStateOf(fixedModId) + val optimizedDir = File(context.cacheDir, "dex_optimized").apply { mkdirs() } - val dexFilePath: Path = if (isDebug) { - context.filesDir.path.findFileGlob(fixedModId) - } else { - if (Build.SUPPORTED_64_BIT_ABIS.isNotEmpty()) { - "/system/lib64".findFileGlob(fixedModId) - } else { - "/system/lib".findFileGlob(fixedModId) + val isStandalone = standaloneData != null + + val dexFilePath: Path = when { + isStandalone -> { + val tmpFile = context.copyToDir(standaloneData!!, context.filesDir) + val cr = context.contentResolver + cr.openInputStream(standaloneData)?.use { input -> + tmpFile.outputStream().use { output -> + input.copyTo(output) + } + } + + val name = Path(context.getPathForUri(standaloneData)).nameWithoutExtension + modId = name + context.tmpDir.path.findFileGlob(modId) } - } ?: return null + isDebug -> context.filesDir.path.findFileGlob(modId) + Build.SUPPORTED_64_BIT_ABIS.isNotEmpty() -> "/system/lib64".findFileGlob(modId) + else -> "/system/lib".findFileGlob(modId) + } ?: return null val dexFile = dexFilePath.toFile() val isAPK = getFileExtension(dexFile).equals("apk", ignoreCase = true) @@ -77,7 +105,7 @@ class ModConfViewModel @Inject constructor( dexFile.path, optimizedDir.absolutePath, null, context.classLoader ) - val pluginClassName = "com.dergoogler.modconf.$fixedModId.ModConfScreenKt" + val pluginClassName = "com.dergoogler.modconf.$modId.ModConfScreenKt" pluginClass = classLoader.loadClass(pluginClassName) setField("isProviderAlive", isProviderAlive) @@ -85,7 +113,7 @@ class ModConfViewModel @Inject constructor( setField("versionName", versionName) setField("versionCode", versionCode) setField("modId", id) - setField("fixedModId", fixedModId) + setField("fixedModId", modId) setField("mmrlPackageName", BuildConfig.APPLICATION_ID) setField("dexFilePath", dexFile.path) diff --git a/app/src/main/kotlin/ext/dergoogler/mmrl/activity/MMRLComponentActivity.kt b/app/src/main/kotlin/ext/dergoogler/mmrl/activity/MMRLComponentActivity.kt index facf087a..e9821cc1 100644 --- a/app/src/main/kotlin/ext/dergoogler/mmrl/activity/MMRLComponentActivity.kt +++ b/app/src/main/kotlin/ext/dergoogler/mmrl/activity/MMRLComponentActivity.kt @@ -1,12 +1,9 @@ package ext.dergoogler.mmrl.activity -import android.app.AlarmManager -import android.app.PendingIntent import android.content.Context import android.content.Intent import android.net.Uri import android.os.Bundle -import android.os.SystemClock import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge