aboutsummaryrefslogtreecommitdiffstats
path: root/android/app/build.gradle
blob: 381e2775276375296c98db30a7f5b3d117a171e5 (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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
apply plugin: 'com.android.application'

def keystoreProps = new Properties()
def keystoreFile = rootProject.file('keystore.properties')
if (keystoreFile.exists()) keystoreProps.load(new FileInputStream(keystoreFile))
// COINOS_UNSIGNED=1 builds without the keystore even when it is present —
// the reproducible-build check compares two unsigned builds byte for byte,
// and F-Droid builds unsigned and compares against our signed release.
def signRelease = keystoreFile.exists() && System.getenv('COINOS_UNSIGNED') == null

// The bundled shell carries the built web app as assets. It is copied from
// ../dist, which the web build produces first: COINOS_NO_SW=1 bun run build
// (the service worker is left out — inside the WebView the app is served
// from these assets, and a worker would fetch the live site over it).
tasks.register('copyWeb', Copy) {
  def dist = rootProject.file('../dist') // the repo root's dist, not the module's
  doFirst {
    if (!new File(dist, 'index.html').exists())
      throw new GradleException('build the web app first: COINOS_NO_SW=1 bun run build (in the repo root)')
  }
  from(dist) { exclude '*.apk', 'standalone.html', 'sw.js', 'zmq-watcher.js' }
  into layout.buildDirectory.dir('www')
}

android {
  namespace 'io.coinos.app'
  compileSdk 35
  defaultConfig {
    applicationId 'io.coinos.app'
    minSdk 24
    targetSdk 35
    versionCode 14
    versionName '1.13'
  }
  // Two builds of the same wallet.
  //
  //  twa      — Chrome renders the site (the better browser, and the one
  //             people already have installed). Its storage is Chrome's, so
  //             nothing outside Chrome can wake the wallet, and on a phone
  //             without Google Play Services nothing inside it can either.
  //  webview  — the wallet runs in the app, so a UnifiedPush message can
  //             start it off-screen and let it answer. A separate app id,
  //             because it is a separate wallet: its storage is its own.
  //  fdroid   — the webview shell with the web app BUNDLED as assets: what
  //             runs is what was built from this source tree, reproducibly,
  //             which is what F-Droid publishes. No service worker, no
  //             remote code; the live site is only reached for its APIs.
  // Google's dependency-metadata block (a Play-only extra in the APK
  // signing block, encrypted to Google) is refused by F-Droid's scanner.
  dependenciesInfo {
    includeInApk = false
    includeInBundle = false
  }
  flavorDimensions += 'shell'
  buildFeatures { buildConfig true }
  productFlavors {
    twa {
      dimension 'shell'
      isDefault = true
      buildConfigField 'boolean', 'BUNDLED', 'false'
    }
    webview {
      dimension 'shell'
      applicationId 'io.coinos.webview'
      versionNameSuffix '-webview'
      resValue 'string', 'app_name', 'Coinos (UnifiedPush)'
      buildConfigField 'boolean', 'BUNDLED', 'false'
    }
    fdroid {
      dimension 'shell'
      applicationId 'io.coinos.fdroid'
      resValue 'string', 'app_name', 'Coinos'
      buildConfigField 'boolean', 'BUNDLED', 'true'
    }
  }
  sourceSets {
    // the same shell as webview, plus the bundled web app
    fdroid {
      java.srcDirs = ['src/webview/java']
      res.srcDirs = ['src/webview/res']
      manifest.srcFile 'src/webview/AndroidManifest.xml'
      assets.srcDirs += layout.buildDirectory.dir('www').get().asFile
    }
  }
  signingConfigs {
    release {
      if (signRelease) {
        storeFile rootProject.file(keystoreProps['storeFile'])
        storePassword keystoreProps['storePassword']
        keyAlias keystoreProps['keyAlias']
        keyPassword keystoreProps['keyPassword']
      }
    }
  }
  buildTypes {
    release {
      minifyEnabled false
      if (signRelease) signingConfig signingConfigs.release
    }
  }
}
dependencies {
  // only the TWA shell needs Chrome's helper; the WebView build carries none
  twaImplementation 'com.google.androidbrowserhelper:androidbrowserhelper:2.5.0'
}

preBuild.dependsOn copyWeb