aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-android/app/build.gradle.kts
blob: b26acf38a63421d43b5cb4bc63a489eb218e2823 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import groovy.json.JsonSlurper

plugins { id("com.android.application") }

// One version for every package (CLAUDE.md): read from the desktop client's
// package.json rather than written a second time here.
val packageVersion = (JsonSlurper().parse(rootDir.resolve("../meshbay-client/package.json"))
    as Map<*, *>)["version"] as String
val versionParts = packageVersion.split(".").map { it.toInt() }

android {
    namespace = "org.meshbay.client"
    compileSdk = 37
    defaultConfig {
        applicationId = "org.meshbay.client"
        minSdk = 26
        targetSdk = 36
        versionName = packageVersion
        versionCode = versionParts[0] * 10000 + versionParts[1] * 100 + versionParts[2]
    }
    buildTypes {
        getByName("release") { isMinifyEnabled = false }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
    buildFeatures { buildConfig = true }
    testOptions { unitTests.isReturnDefaultValues = false }
}

dependencies {
    implementation("androidx.webkit:webkit:1.17.1")
    implementation("com.squareup.okhttp3:okhttp:5.5.0")
    // Ed25519, X25519, HKDF and Argon2id, identical on the JVM and every
    // Android version: the platform has no Argon2 and its Ed25519 is recent.
    implementation("org.bouncycastle:bcprov-jdk18on:1.86")
    // Casting: discovery through MediaRouter, control through the cast sender
    // SDK and the default media receiver. Needs the vendor's play services at
    // run time; where they are absent the page is offered no cast at all.
    implementation("com.google.android.gms:play-services-cast-framework:22.3.1")
    implementation("androidx.mediarouter:mediarouter:1.8.1")
    testImplementation("junit:junit:4.13.2")
    // Android's org.json is a stub on the JVM; the unit tests need the real one.
    testImplementation("org.json:json:20260814")
}

/**
 * The interface, copied from its single source at build time (§8.3).
 *
 * `meshbay-hub/src/meshbay_hub/static/` is the interface for the web, the
 * desktop application and this one. The copy lands in build/ and is never
 * committed, so it cannot fork. The page itself is the desktop application's
 * `scripts/index.html` — the hub builds its own with a /a/<hash>/ prefix that
 * would point back at the hub — so an application loading from its package
 * has one page, not two.
 */
abstract class SyncUi : DefaultTask() {
    @get:InputDirectory abstract val staticDir: DirectoryProperty
    @get:InputFile abstract val indexHtml: RegularFileProperty
    @get:OutputDirectory abstract val outputDir: DirectoryProperty

    @TaskAction
    fun copy() {
        val ui = outputDir.get().asFile.resolve("ui")
        outputDir.get().asFile.deleteRecursively()
        staticDir.get().asFile.copyRecursively(ui)
        indexHtml.get().asFile.copyTo(ui.resolve("index.html"), overwrite = true)
    }
}

val syncUi = tasks.register<SyncUi>("syncUi") {
    staticDir.set(rootDir.resolve("../meshbay-hub/src/meshbay_hub/static"))
    indexHtml.set(rootDir.resolve("../meshbay-client/scripts/index.html"))
    outputDir.set(layout.buildDirectory.dir("generated/ui-assets"))
}

androidComponents {
    onVariants { variant ->
        variant.sources.assets?.addGeneratedSourceDirectory(syncUi, SyncUi::outputDir)
    }
}