import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile /** * Gearslip: a phone-side Android Auto client built against the reverse-engineered AA wire * protocol, so a non-Google app can authenticate to and project onto a real car head unit * with no gearhead in the path. No third-party dependencies: the X.509 certificate is * generated by hand (see `SelfSignedCert`) so there is no BouncyCastle version to track and * no second crypto provider to collide with Conscrypt. */ plugins { alias(libs.plugins.android.application) alias(libs.plugins.kotlin.compose) } android { namespace = "app.seb3thehacker.gearslip" compileSdk = 37 defaultConfig { applicationId = "app.seb3thehacker.gearslip" minSdk = 35 targetSdk = 37 versionCode = 1 versionName = "0.1" } // Keeps build output out of the module folder: /build/gearslip/... instead of // /gearslip/build/..., so everything this project produces lands under one // root-level build/ directory. layout.buildDirectory.set(rootProject.layout.buildDirectory.dir("gearslip")) compileOptions { sourceCompatibility = JavaVersion.VERSION_21 targetCompatibility = JavaVersion.VERSION_21 } testOptions { // GearslipLog calls android.util.Log, which is a stub on the local JVM. unitTests.isReturnDefaultValues = true } } // Renames the produced APK and moves it to the root build/ folder (/build/Gearslip-debug.apk) // after the fact rather than fighting AGP's variant-output API across versions - simpler and // doesn't break when that API moves again. tasks.register("renameApk") { doLast { val rootBuildDir = rootProject.layout.buildDirectory.get().asFile layout.buildDirectory.dir("outputs/apk").get().asFile.walkTopDown() .filter { it.extension == "apk" } .toList() .forEach { apk -> val renamed = File(rootBuildDir, "Gearslip-${apk.parentFile.name}.apk") apk.copyTo(renamed, overwrite = true) apk.delete() } } } tasks.matching { it.name.startsWith("assemble") }.configureEach { finalizedBy("renameApk") } dependencies { // Only for the XML window theme (Theme.Material3.DynamicColors); every screen is Compose. implementation(libs.google.material) implementation(platform(libs.androidx.compose.bom)) implementation(libs.androidx.compose.ui) implementation(libs.androidx.compose.material3) implementation(libs.androidx.compose.material.icons.core) implementation(libs.androidx.activity.compose) implementation(libs.androidx.lifecycle.runtime.compose) // Used from the host side, not the app side: Gearslip renders other apps' templates rather // than publishing its own, so this is here for the AIDL interfaces and the model classes // their Bundleables deserialize into. implementation(libs.androidx.car.app) implementation(libs.androidx.car.app.projected) testImplementation(libs.junit) } tasks.withType().configureEach { compilerOptions { jvmTarget.set(JvmTarget.JVM_21) } }