📄 build.gradle

jabjab / build.gradle
10.0 kB Raw History
1buildscript {
2 repositories {
3 google()
4 mavenCentral()
5 }
6 dependencies {
7 classpath 'com.android.tools.build:gradle:9.2.1'
8 classpath 'com.diffplug.spotless:spotless-plugin-gradle:8.10.2'
9 }
10}
11
12apply plugin: 'com.android.application'
13apply plugin: 'com.diffplug.spotless'
14
15repositories {
16 google()
17 mavenCentral()
18 maven { url = 'https://jitpack.io' }
19}
20
21spotless {
22 ratchetFrom '2.17.4'
23 java {
24 target '**/*.java'
25 googleJavaFormat().aosp().reflowLongStrings()
26 }
27}
28
29def abiCodes = ['armeabi-v7a': 1, 'x86': 2, 'x86_64': 3, 'arm64-v8a': 4]
30
31configurations.named('implementation') {
32 exclude group: 'org.jetbrains', module: 'annotations'
33}
34
35configurations {
36 freeImplementation {}
37 conversationsPlaystoreImplementation {}
38 quicksyImplementation {}
39 quicksyPlaystoreImplementation {}
40}
41
42dependencies {
43 coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'
44
45 annotationProcessor 'org.immutables:value:2.12.2'
46 implementation 'org.immutables:value-annotations:2.12.2'
47 annotationProcessor project(':libs:annotation-processor')
48 implementation project(':libs:annotation')
49 implementation 'androidx.appcompat:appcompat:1.8.0'
50 implementation 'androidx.cardview:cardview:1.0.0'
51 implementation 'androidx.concurrent:concurrent-futures:1.3.0'
52 implementation 'androidx.documentfile:documentfile:1.1.0'
53 implementation 'androidx.emoji2:emoji2:1.6.0'
54 freeImplementation 'androidx.emoji2:emoji2-bundled:1.6.0'
55 implementation 'androidx.emoji2:emoji2-emojipicker:1.6.0'
56 implementation 'androidx.exifinterface:exifinterface:1.4.2'
57 implementation 'androidx.heifwriter:heifwriter:1.1.0'
58 implementation 'androidx.preference:preference:1.2.1'
59 implementation 'androidx.biometric:biometric:1.1.0'
60 implementation 'androidx.sharetarget:sharetarget:1.2.0'
61 implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.2.0'
62 implementation 'androidx.viewpager:viewpager:1.1.0'
63 implementation 'androidx.work:work-runtime:2.11.2'
64 implementation 'com.github.open-keychain.open-keychain:openpgp-api:v5.7.1'
65 implementation 'com.google.android.material:material:1.14.0'
66 implementation 'com.google.guava:guava:33.7.1-android'
67 implementation 'com.google.zxing:core:3.5.4'
68 implementation 'com.leinardi.android:speed-dial:3.3.0'
69 implementation 'com.squareup.okhttp3:okhttp:5.5.0'
70 implementation 'com.squareup.retrofit2:converter-gson:3.0.0'
71 implementation 'com.squareup.retrofit2:retrofit:3.0.0'
72 implementation 'com.vanniktech:android-image-cropper:4.7.0'
73 implementation 'im.conversations.webrtc:webrtc-android:149.0.0'
74 implementation 'io.deepmedia.community:transcoder-android:0.11.2'
75 implementation 'me.leolin:ShortcutBadger:1.1.22@aar'
76 //noinspection NewerVersionAvailable
77 implementation 'net.fellbaum:jemoji:1.7.6' //1.7.6 is the latest with Java 8 support
78 implementation 'org.bouncycastle:bcmail-jdk18on:1.86'
79 implementation 'org.conscrypt:conscrypt-android:2.7.0'
80 implementation 'org.hsluv:hsluv:1.0.2'
81 implementation 'org.jxmpp:jxmpp-jid:1.1.0'
82 implementation 'org.jxmpp:jxmpp-stringprep-libidn:1.1.0'
83 implementation 'org.minidns:minidns-client:1.1.1'
84 implementation 'org.minidns:minidns-dnssec:1.1.1'
85 implementation 'org.osmdroid:osmdroid-android:6.1.20'
86 //noinspection NewerVersionAvailable
87 implementation 'org.whispersystems:signal-protocol-java:2.6.2'
88 conversationsPlaystoreImplementation 'com.android.installreferrer:installreferrer:2.2'
89 quicksyImplementation 'io.michaelrocks:libphonenumber-android:9.0.38'
90 quicksyPlaystoreImplementation 'com.google.android.gms:play-services-auth-api-phone:18.3.1'
91
92 testImplementation 'junit:junit:4.13.2'
93 testImplementation 'org.robolectric:robolectric:4.17'
94 androidTestImplementation 'androidx.test.ext:junit:1.3.0'
95}
96
97// Load local.properties so GIPHY_API_KEY etc. don't need to be passed on the command line
98def localProps = new Properties()
99def localPropsFile = rootProject.file('local.properties')
100if (localPropsFile.exists()) localProps.load(new FileInputStream(localPropsFile))
101
102android {
103 namespace = 'tel.xmpp.jabjab'
104 compileSdk = 37
105
106 defaultConfig {
107 minSdk = 23
108 versionCode = 42316
109 versionName = '1.0.8'
110 applicationId = 'tel.xmpp.jabjab'
111 resValue('string', 'applicationId', applicationId)
112 def appName = "JabJab"
113 resValue('string', 'app_name', appName)
114 buildConfigField('String', 'APP_NAME', "\"${appName}\"")
115 // Giphy GIF search — override with GIPHY_API_KEY gradle property
116 def giphyKey = localProps.getProperty('GIPHY_API_KEY') ?: project.findProperty('GIPHY_API_KEY') ?: ""
117 buildConfigField('String', 'GIPHY_API_KEY', "\"${giphyKey}\"")
118 def updateUrl = project.findProperty('UPDATE_SERVER_URL') ?: ""
119 buildConfigField('String', 'UPDATE_SERVER_URL', "\"${updateUrl}\"")
120 // Conversations upstream version — read from conversations.doap at build time
121 def conversationsVersion = "unknown"
122 def doapFile = file("conversations.doap")
123 if (doapFile.exists()) {
124 def m = doapFile.text =~ /<revision>([^<]+)<\/revision>/
125 if (m.find()) conversationsVersion = m.group(1).trim()
126 }
127 buildConfigField('String', 'CONVERSATIONS_BASE_VERSION', "\"${conversationsVersion}\"")
128 base {
129 archivesName = "jabjab-${android.defaultConfig.versionName}-${android.defaultConfig.versionCode}"
130 }
131 }
132
133 splits {
134 abi {
135 universalApk = true
136 enable = true
137 reset()
138 //noinspection ChromeOsAbiSupport
139 include(abiCodes.keySet() as String[])
140 }
141 }
142
143 compileOptions {
144 coreLibraryDesugaringEnabled = true
145 sourceCompatibility = JavaVersion.VERSION_21
146 targetCompatibility = JavaVersion.VERSION_21
147 }
148
149 flavorDimensions += 'mode'
150 flavorDimensions += 'distribution'
151
152 productFlavors {
153 quicksy {
154 dimension = 'mode'
155 applicationId = 'im.quicksy.client'
156 resValue('string', 'applicationId', applicationId)
157 def appName = "Quicksy"
158 resValue('string', 'app_name', appName)
159 buildConfigField('String', 'APP_NAME', "\"${appName}\"")
160 buildConfigField('String', 'PRIVACY_POLICY', '"https://quicksy.im/privacy.htm"')
161
162 def propsFile = rootProject.file('quicksy-auth-secret.properties')
163 def key = null
164 if (propsFile.exists()) {
165 def props = new Properties()
166 propsFile.withInputStream { props.load(it) }
167 key = props.getProperty('QUICKSY_AUTHENTICATION_SECRET')
168 }
169 buildConfigField('String', 'QUICKSY_AUTHENTICATION_SECRET', key != null ? "\"${key}\"" : 'null')
170 }
171
172 conversations {
173 dimension = 'mode'
174 buildConfigField('String', 'PRIVACY_POLICY', '"https://conversations.im/privacy.html"')
175 }
176
177 playstore {
178 dimension = 'distribution'
179 }
180 free {
181 dimension = 'distribution'
182 }
183 }
184
185 sourceSets {
186 quicksyFree {
187 java.srcDir('src/quicksyFree/java')
188 }
189 quicksyPlaystore {
190 java.srcDir('src/quicksyPlaystore/java')
191 res.srcDir('src/quicksyPlaystore/res')
192 }
193 conversationsFree {
194 java.srcDir('src/conversationsFree/java')
195 }
196 conversationsPlaystore {
197 java.srcDir('src/conversationsPlaystore/java')
198 res.srcDir('src/conversationsPlaystore/res')
199 }
200 }
201
202 def signingPropsFile = ["signing.properties",
203 "${System.getProperty('user.home')}/.keys/android/jabjab/signing.properties"]
204 .collect { new File(it) }
205 .find { it.exists() }
206
207 if (signingPropsFile != null) {
208 Properties props = new Properties()
209 props.load(new FileInputStream(signingPropsFile))
210
211 // Password is never stored in signing.properties — read from env var set by build-release.sh
212 def ksPassword = props['keystore.password'] ?: ""
213
214 signingConfigs {
215 release {
216 storeFile = file(props['keystore'])
217 storePassword = ksPassword
218 keyAlias = props['keystore.alias']
219 keyPassword = ksPassword
220 }
221 }
222 }
223
224 buildTypes {
225 release {
226 shrinkResources = true
227 minifyEnabled = true
228 proguardFiles(getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro')
229 if (signingPropsFile != null) {
230 signingConfig = signingConfigs.getByName('release')
231 }
232 }
233 debug {
234 if (signingPropsFile != null) {
235 signingConfig = signingConfigs.getByName('release')
236 }
237 }
238 }
239
240 packaging {
241 resources {
242 excludes += ['META-INF/BCKEY.DSA', 'META-INF/BCKEY.SF', 'META-INF/LICENSE.md',
243 'META-INF/versions/9/OSGI-INF/MANIFEST.MF']
244 }
245 }
246
247 lint {
248 disable += ['MissingTranslation', 'InvalidPackage', 'AppCompatResource']
249 }
250
251 buildFeatures {
252 buildConfig = true
253 resValues = true
254 dataBinding = true
255 aidl = true
256 }
257
258 dependenciesInfo {
259 includeInApk = false
260 includeInBundle = false
261 }
262}
263
264subprojects {
265 plugins.withId('com.android.library') {
266 android {
267 lint {
268 disable += ['AndroidGradlePluginVersion', 'MissingTranslation']
269 }
270 }
271 }
272 plugins.withId('com.android.application') {
273 android {
274 lint {
275 disable += ['AndroidGradlePluginVersion', 'MissingTranslation']
276 }
277 }
278 }
279}

Built with passion for open-source software, XMPP, privacy, and security —
the belief that people deserve communication tools that serve them, not surveil them.

Dedicated to every brave man and woman who stands up against tyranny and oppression across the world.
And in memory of those who were silenced before they could speak freely.