@@ -3,7 +3,9 @@ package kotlinx.benchmark.gradle
33import kotlinx.benchmark.gradle.internal.KotlinxBenchmarkPluginInternalApi
44import org.gradle.api.*
55import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmAndroidCompilation
6+ import java.io.InputStream
67import java.util.*
8+ import java.util.concurrent.TimeUnit
79
810
911@KotlinxBenchmarkPluginInternalApi
@@ -12,7 +14,7 @@ fun Project.processAndroidCompilation(target: KotlinJvmAndroidCompilation) {
1214 println (" processAndroidCompilation: ${target.name} " )
1315 val compilation = target.target.compilations.names.let (::println)
1416
15- tasks.register(" process ${target.name.capitalize(Locale .getDefault())} Compilation" , DefaultTask ::class .java) {
17+ tasks.register(" processAndroid ${target.name.capitalize(Locale .getDefault())} Compilation" , DefaultTask ::class .java) {
1618 it.group = " benchmark"
1719 it.description = " Processes the Android compilation '${target.name} ' for benchmarks"
1820 it.dependsOn(" bundle${target.name.capitalize(Locale .getDefault())} Aar" )
@@ -21,11 +23,13 @@ fun Project.processAndroidCompilation(target: KotlinJvmAndroidCompilation) {
2123 generateBenchmarkSourceFiles(classDescriptors)
2224 }
2325 detectAndroidDevice()
26+ createAndroidBenchmarkExecTask()
2427 }
2528 }
2629}
2730
2831fun Project.detectAndroidDevice () {
32+ println (" Detect running Android devices..." )
2933 val devices = ProcessBuilder (" adb" , " devices" )
3034 .start()
3135 .inputStream
@@ -39,4 +43,47 @@ fun Project.detectAndroidDevice() {
3943 ?.let {
4044 println (" Connected Android devices/emulators:\n\t ${it.joinToString(" \n\t " )} " )
4145 } ? : throw RuntimeException (" No Android devices/emulators found, please start an emulator or connect a device." )
46+ }
47+
48+
49+ // Use shell command to execute separate project gradle task
50+ fun Project.createAndroidBenchmarkExecTask () {
51+ // TODO: Project path needs to execute benchmark task
52+ val executeBenchmarkPath = " E:/Android/AndroidProjects/kotlin-qualification-task"
53+ // Using ./gradlew on Windows shows error:
54+ // CreateProcess error=193, %1 is not a valid Win32 application
55+ val osName = System .getProperty(" os.name" ).toLowerCase(Locale .ROOT )
56+ val gradlewPath = " $executeBenchmarkPath /gradlew" + if (osName.contains(" win" )) " .bat" else " "
57+ val args = listOf (" -p" , executeBenchmarkPath, " connectedAndroidTest" )
58+
59+ try {
60+ println (" Running command: $gradlewPath ${args.joinToString(" " )} " )
61+
62+ val process = ProcessBuilder (gradlewPath, * args.toTypedArray())
63+ .redirectOutput(ProcessBuilder .Redirect .PIPE )
64+ .redirectError(ProcessBuilder .Redirect .PIPE )
65+ .start()
66+
67+ val outputGobbler = StreamGobbler (process.inputStream) { println (it) }
68+ val errorGobbler = StreamGobbler (process.errorStream) { System .err.println (it) }
69+
70+ outputGobbler.start()
71+ errorGobbler.start()
72+
73+ val exitCode = process.waitFor(10 , TimeUnit .MINUTES )
74+ if (! exitCode || process.exitValue() != 0 ) {
75+ println (" Android benchmark task failed with exit code ${process.exitValue()} " )
76+ } else {
77+ println (" Benchmark for Android target finished." )
78+ }
79+ } catch (e: Exception ) {
80+ e.printStackTrace()
81+ throw GradleException (" Failed to execute benchmark task" , e)
82+ }
83+ }
84+
85+ class StreamGobbler (private val inputStream : InputStream , private val consumer : (String ) -> Unit ) : Thread() {
86+ override fun run () {
87+ inputStream.bufferedReader().lines().forEach(consumer)
88+ }
4289}
0 commit comments