Skip to content

Commit

Permalink
Add "Min API" setting (#69)
Browse files Browse the repository at this point in the history
Changing min API can be useful when working with R8, when it changes the code for older APIs.

Example:
```kotlin
import java. lang. Thread
import android.os.Looper

fun test3() {
    Looper.getMainLooper().isCurrentThread()
}
```

DEX with min API 21 (R8 enabled):
```dex
class KotlinExplorerKt$$ExternalSyntheticApiModelOutline0
    void KotlinExplorerKt$$ExternalSyntheticApiModelOutline0.m(android.os.Looper)
        -- 2 instructions
        0000: invoke-virtual {v0}, Landroid/os/Looper;.isCurrentThread:()Z // method@0003
        0003: return-void

class KotlinExplorerKt
    void KotlinExplorerKt.test3()
        -- 4 instructions
        0000: invoke-static {}, Landroid/os/Looper;.getMainLooper:()Landroid/os/Looper; // method@0002
        0003: move-result-object v0
        0004: invoke-static {v0}, LKotlinExplorerKt$$ExternalSyntheticApiModelOutline0;.m:(Landroid/os/Looper;)V // method@0000
        0007: return-void
```

DEX with min API 26 (R8 enabled):
```dex
class KotlinExplorerKt
    void KotlinExplorerKt.test3()
        -- 4 instructions
        0000: invoke-static {}, Landroid/os/Looper;.getMainLooper:()Landroid/os/Looper; // method@0001
        0003: move-result-object v0
        0004: invoke-virtual {v0}, Landroid/os/Looper;.isCurrentThread:()Z // method@0002
        0007: return-void
```
  • Loading branch information
EpicDima authored Sep 3, 2024
1 parent 6074677 commit b6734a8
Show file tree
Hide file tree
Showing 5 changed files with 13 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ suspend fun buildAndDisassemble(
toolPaths: ToolPaths,
source: String,
r8rules: String,
minApi: Int,
instructionSets: Map<ISA, Boolean>,
onByteCode: (CodeContent) -> Unit,
onDex: (CodeContent) -> Unit,
Expand Down Expand Up @@ -150,7 +151,7 @@ suspend fun buildAndDisassemble(
launch(ui) { updater.advance("") }
}

val dexCompiler = DexCompiler(toolPaths, directory, r8rules)
val dexCompiler = DexCompiler(toolPaths, directory, r8rules, minApi)

val dex = dexCompiler.buildDex(optimize, keepEverything)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ private fun FrameWindowScope.MainMenu(
explorerState.toolPaths,
sourceTextArea.text,
explorerState.r8Rules,
explorerState.minApi,
instructionSets,
onByteCodeUpdate,
onDexUpdate,
Expand Down
5 changes: 5 additions & 0 deletions src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/Settings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ fun Settings(
val androidHome = rememberTextFieldState(state.androidHome)
val kotlinHome = rememberTextFieldState(state.kotlinHome)
val r8rules = rememberTextFieldState(state.r8Rules)
val minApi = rememberTextFieldState(state.minApi.toString())
val indent = rememberTextFieldState(state.indent.toString())
val lineNumberWidth = rememberTextFieldState(state.lineNumberWidth.toString())
val decompileHiddenIsa = remember { mutableStateOf(state.decompileHiddenIsa) }
Expand All @@ -47,6 +48,7 @@ fun Settings(
androidHome.text.toString(),
kotlinHome.text.toString(),
r8rules.text.toString(),
minApi.text.toString(),
indent.text.toString(),
lineNumberWidth.text.toString(),
decompileHiddenIsa.value
Expand All @@ -61,6 +63,7 @@ fun Settings(
IntSetting("Decompiled code indent: ", indent, minValue = 2)
IntSetting("Line number column width: ", lineNumberWidth, minValue = 1)
MultiLineStringSetting("R8 rules: ", r8rules)
IntSetting("Min API: ", minApi, minValue = 1)
BooleanSetting("Decompile hidden instruction sets", decompileHiddenIsa)
Spacer(modifier = Modifier.height(8.dp))
Buttons(saveEnabled = toolPaths.isValid, onSaveClick, onDismissRequest)
Expand All @@ -87,13 +90,15 @@ private fun ExplorerState.saveState(
androidHome: String,
kotlinHome: String,
r8Rules: String,
minApi: String,
indent: String,
lineNumberWidth: String,
decompileHiddenIsa: Boolean,
) {
this.androidHome = androidHome
this.kotlinHome = kotlinHome
this.r8Rules = r8Rules
this.minApi = minApi.toIntOrNull() ?: 21
this.indent = indent.toIntOrNull() ?: 4
this.lineNumberWidth = lineNumberWidth.toIntOrNull() ?: 4
this.decompileHiddenIsa = decompileHiddenIsa
Expand Down
5 changes: 3 additions & 2 deletions src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/State.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ private const val KotlinHome = "KOTLIN_HOME"
private const val Optimize = "OPTIMIZE"
private const val KeepEverything = "KEEP_EVERYTHING"
private const val R8Rules = "R8_RULES"
private const val MinApi = "MIN_API"
private const val AutoBuildOnStartup = "AUTO_BUILD_ON_STARTUP"
private const val Presentation = "PRESENTATION"
private const val ShowLineNumbers = "SHOW_LINE_NUMBERS"
Expand Down Expand Up @@ -58,6 +59,7 @@ class ExplorerState {
var optimize by BooleanState(Optimize, true)
var keepEverything by BooleanState(KeepEverything, true)
var r8Rules by StringState(R8Rules, "")
var minApi by IntState(MinApi, 21)
var autoBuildOnStartup by BooleanState(AutoBuildOnStartup, false)
var presentationMode by BooleanState(Presentation, false)
var showLineNumbers by BooleanState(ShowLineNumbers, false)
Expand All @@ -80,8 +82,7 @@ class ExplorerState {
toolPaths = createToolPaths()
}

private fun createToolPaths() =
ToolPaths(directory, Path.of(androidHome.toString()), Path.of(kotlinHome.toString()))
private fun createToolPaths() = ToolPaths(directory, Path.of(androidHome), Path.of(kotlinHome))

private inner class BooleanState(key: String, initialValue: Boolean) :
SettingsState<Boolean>(key, initialValue, { toBoolean() })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import java.nio.file.Files
import java.nio.file.Path
import kotlin.io.path.*

class DexCompiler(private val toolPaths: ToolPaths, private val outputDirectory: Path, private val r8rules: String) {
class DexCompiler(private val toolPaths: ToolPaths, private val outputDirectory: Path, private val r8rules: String, private val minApi: Int) {
suspend fun buildDex(optimize: Boolean, keepEverything: Boolean): ProcessResult {
return process(*buildDexCommand(optimize, keepEverything), directory = outputDirectory)
}
Expand All @@ -45,7 +45,7 @@ class DexCompiler(private val toolPaths: ToolPaths, private val outputDirectory:
add(toolPaths.d8.toString())
add(if (optimize) "com.android.tools.r8.R8" else "com.android.tools.r8.D8")
add("--min-api")
add("21")
add(minApi.toString())
if (optimize) {
add("--pg-conf")
add("rules.txt")
Expand Down

0 comments on commit b6734a8

Please sign in to comment.