mise.toml, the comments in app/build.gradle (corrected where they no longer described the build: the car build is signed by build-car, and the updater reads the version from build-car's file name), OTA.md's message table (now the updater's current English messages), the Turkish messages quoted in CHANGELOG.md and OTA.md (glossed in English), two test assertion messages, an icon comment, and the ignition-state comment in EVHardware.kt. The vendored EVHardware library still has about 120 half-French comment lines; noted in SPECS.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
149 lines
6.1 KiB
Groovy
149 lines
6.1 KiB
Groovy
plugins {
|
|
alias(libs.plugins.android.application)
|
|
}
|
|
|
|
android {
|
|
namespace 'com.evsuite.abrp'
|
|
compileSdk {
|
|
version = release(36) {
|
|
minorApiLevel = 1
|
|
}
|
|
}
|
|
|
|
// APK signing — nothing to do with the user's ABRP credentials. These values are ONLY for
|
|
// the build: they prove the APK comes from us and never enter the app. The ABRP API key and
|
|
// token are entered in the app and stored encrypted on the device (see SecurePrefs).
|
|
// The car build is signed by build-car (flake.nix) with the AOSP platform key instead.
|
|
//
|
|
// A keystore holds several keys: SIGNING_STORE_PASSWORD opens the container,
|
|
// SIGNING_KEY_ALIAS picks the key, SIGNING_KEY_PASSWORD opens that key.
|
|
// Read from the environment (CI) or a local gradle.properties — NEVER committed.
|
|
def keystorePath = System.getenv("SIGNING_KEYSTORE") ?: project.findProperty("signing.keystore")
|
|
signingConfigs {
|
|
if (keystorePath != null && file(keystorePath).exists()) {
|
|
platform {
|
|
storeFile file(keystorePath)
|
|
storePassword System.getenv("SIGNING_STORE_PASSWORD") ?: project.findProperty("signing.store.password")
|
|
keyAlias System.getenv("SIGNING_KEY_ALIAS") ?: project.findProperty("signing.key.alias") ?: "platform"
|
|
keyPassword System.getenv("SIGNING_KEY_PASSWORD") ?: project.findProperty("signing.key.password")
|
|
}
|
|
}
|
|
}
|
|
|
|
defaultConfig {
|
|
applicationId "com.stinnesbeck.nilsmg4"
|
|
minSdk 27
|
|
targetSdk 36
|
|
versionCode 81
|
|
versionName "2.14.3"
|
|
|
|
// Nothing about the server ships in the APK: its URL and ingest token are entered in
|
|
// the app's Server tab (ServerConfig), and the database is only reachable by the server.
|
|
|
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
|
}
|
|
|
|
// null when no keystore is configured: the build still works on a machine without
|
|
// secrets (unsigned APK) instead of failing.
|
|
def platformSigning = signingConfigs.findByName("platform")
|
|
|
|
// Two distribution channels:
|
|
// - stable: no self-update at all. The user installs it; nothing in the app fetches an
|
|
// APK (the updater is not even in this APK).
|
|
// - unstable: the car build (system UID, platform-signed), with the OTA updater, so the
|
|
// car can update itself from published pre-releases. Installs next to stable.
|
|
flavorDimensions += "channel"
|
|
productFlavors {
|
|
stable {
|
|
dimension "channel"
|
|
buildConfigField "boolean", "OTA_ENABLED", "false"
|
|
}
|
|
unstable {
|
|
dimension "channel"
|
|
applicationIdSuffix ".unstable"
|
|
// Three-part versions, the same as defaultConfig ("2.8.1-unstable"). Upstream added
|
|
// a fourth part for its CI build number; there is no CI here and the OTA updater is
|
|
// off. The version code keeps upstream's x100000 so it never drops below codes
|
|
// already installed on the car (2.8.0.0 was 6600000): a lower code is a downgrade,
|
|
// which the installer refuses.
|
|
versionCode defaultConfig.versionCode * 100000
|
|
versionName defaultConfig.versionName
|
|
versionNameSuffix "-unstable"
|
|
buildConfigField "boolean", "OTA_ENABLED", "true"
|
|
}
|
|
}
|
|
|
|
buildTypes {
|
|
debug {
|
|
if (platformSigning != null) signingConfig platformSigning
|
|
}
|
|
release {
|
|
// [T-918] R8 enabled. CarPropertyAdapter reaches the car purely by
|
|
// reflection, so proguard-rules.pro must keep those targets; a release build
|
|
// needs an on-vehicle check of the car reads before it ships.
|
|
minifyEnabled true
|
|
if (platformSigning != null) signingConfig platformSigning
|
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
|
}
|
|
}
|
|
// BuildConfig.DEBUG gates the debug-only logging (T-912).
|
|
buildFeatures {
|
|
buildConfig true
|
|
}
|
|
|
|
lint {
|
|
abortOnError true
|
|
checkReleaseBuilds true
|
|
warningsAsErrors false
|
|
}
|
|
|
|
compileOptions {
|
|
sourceCompatibility JavaVersion.VERSION_11
|
|
targetCompatibility JavaVersion.VERSION_11
|
|
}
|
|
}
|
|
|
|
// The version build-car puts in the APK's file name ("NilsMG4-unstable-2.8.1.apk"), which
|
|
// is also the name the OTA updater reads a release's version from.
|
|
tasks.register('printUnstableVersion') {
|
|
doLast {
|
|
println android.defaultConfig.versionName
|
|
}
|
|
}
|
|
|
|
// Names the APKs by channel so the build outputs are readable.
|
|
androidComponents {
|
|
onVariants(selector().all()) { variant ->
|
|
variant.outputs.each { output ->
|
|
if (variant.buildType == "release") {
|
|
// A fixed name for the unstable release output. What is published for the car
|
|
// comes from build-car, named NilsMG4-unstable-<version>.apk: that file name is
|
|
// where the updater reads a release's version from.
|
|
output.outputFileName.set(variant.flavorName == "unstable"
|
|
? "NilsMG4-unstable.apk"
|
|
: "NilsMG4-${variant.flavorName}-${output.versionName.get()}.apk")
|
|
} else {
|
|
// Debug builds: NilsMG4-stable-debug.apk, NilsMG4-unstable-debug.apk.
|
|
output.outputFileName.set("NilsMG4-${variant.flavorName}-${variant.buildType}.apk")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
implementation project(':evhardware')
|
|
implementation libs.appcompat
|
|
implementation libs.material
|
|
implementation libs.activity
|
|
implementation libs.constraintlayout
|
|
implementation libs.viewpager2
|
|
implementation libs.security.crypto
|
|
implementation 'com.google.zxing:core:3.5.3'
|
|
// android.jar's org.json is a stub in unit tests; the real implementation lets the
|
|
// telemetry payload tests parse what the app actually builds.
|
|
testImplementation libs.junit
|
|
testImplementation libs.json
|
|
androidTestImplementation libs.ext.junit
|
|
androidTestImplementation libs.espresso.core
|
|
}
|