plugins { id 'com.android.application' version '8.11.1' id 'com.google.gms.google-services' version '4.4.1' } repositories { google() mavenCentral() maven { url "https://www.jitpack.io" name 'JitPack Github wrapper' } } android { namespace "org.thoughtcrime.securesms" flavorDimensions "none" compileSdk 34 // Set NDK version to strip native libraries. // Even though we compile our libraries outside Gradle with `scripts/ndk-make.sh`, // without ndkVersion `./gradlew clean` followed by `./gradlew assembleDebug --warning-mode=all` emits the following warning: // > Task :stripFatDebugDebugSymbols // Unable to strip the following libraries, packaging them as they are: libanimation-decoder-gif.so, libnative-utils.so. // See for details. ndkVersion "27.0.12077973" useLibrary 'org.apache.http.legacy' defaultConfig { versionCode 729 versionName "2.10.0" applicationId "com.b44t.messenger" multiDexEnabled true minSdkVersion 21 targetSdkVersion 34 vectorDrawables.useSupportLibrary = true // base name of the generated apk project.ext.set("archivesBaseName", "deltachat"); buildConfigField "boolean", "DEV_BUILD", "false" ndk { abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64" } testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" buildConfigField("String", "TEST_ADDR", buildConfigProperty("TEST_ADDR")) buildConfigField("String", "TEST_MAIL_PW", buildConfigProperty("TEST_MAIL_PW")) buildConfigField("String", "NDK_ARCH", getNdkArch()) } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } packagingOptions { jniLibs { keepDebugSymbols += ['*/mips/*.so', '*/mips64/*.so'] } resources { excludes += ['LICENSE.txt', 'LICENSE', 'NOTICE', 'asm-license.txt', 'META-INF/LICENSE', 'META-INF/NOTICE'] } } signingConfigs { debug { // add `DC_DEBUG_STORE_FILE=/path/to/debug.keystore` to `~/.gradle/gradle.properties` if(project.hasProperty("DC_DEBUG_STORE_FILE" )) { storeFile file(DC_DEBUG_STORE_FILE ) } } release { // can be defined at `~/.gradle/gradle.properties` or at "Build/Generate signed APK" if(project.hasProperty("DC_RELEASE_STORE_FILE")) { storeFile file(DC_RELEASE_STORE_FILE) storePassword DC_RELEASE_STORE_PASSWORD keyAlias DC_RELEASE_KEY_ALIAS keyPassword DC_RELEASE_KEY_PASSWORD } } } buildTypes { debug { minifyEnabled false applicationIdSuffix ".beta" } release { // minification and proguard disabled for now. // // when enabled, it can cut down apk size about 6%, // however this also has the potential to break things. // so exceptions are needed and have to be maintained. // (see git-history and https://github.com/deltachat/deltachat-android/issues/905 ) // // nb: it is highly recommended to use the same settings in debug+release - // otherwise problems might be noticed delayed only minifyEnabled false signingConfig signingConfigs.release } } productFlavors { foss { dimension "none" buildConfigField "boolean", "USE_PLAY_SERVICES", "false" } gplay { dimension "none" applicationId "chat.delta" apply plugin: "com.google.gms.google-services" buildConfigField "boolean", "USE_PLAY_SERVICES", "true" } } android.applicationVariants.all { variant -> variant.outputs.all { outputFileName = outputFileName .replace("deltachat-android", "deltachat") .replace(".apk", "-${variant.versionName}.apk") } } sourceSets { main { jniLibs.srcDirs = ['libs'] } } androidResources { generateLocaleConfig true } lint { abortOnError false } buildFeatures { renderScript true aidl true } } dependencies { implementation 'androidx.sharetarget:sharetarget:1.2.0' implementation 'androidx.webkit:webkit:1.14.0' implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.appcompat:appcompat:1.7.1' implementation 'com.google.android.material:material:1.12.0' implementation 'androidx.legacy:legacy-support-v13:1.0.0' implementation ('androidx.preference:preference:1.2.1') { exclude group: 'androidx.lifecycle', module:'lifecycle-viewmodel' exclude group: 'androidx.lifecycle', module:'lifecycle-viewmodel-ktx' } implementation 'androidx.legacy:legacy-preference-v14:1.0.0' implementation 'androidx.exifinterface:exifinterface:1.4.1' implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' implementation 'androidx.lifecycle:lifecycle-common-java8:2.6.2' implementation 'androidx.lifecycle:lifecycle-viewmodel:2.6.2' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2' implementation 'androidx.work:work-runtime:2.9.1' implementation 'androidx.emoji2:emoji2-emojipicker:1.5.0' implementation 'com.google.guava:guava:31.1-android' implementation 'com.google.android.exoplayer:exoplayer-core:2.19.1' // plays video and audio implementation 'com.google.android.exoplayer:exoplayer-ui:2.19.1' implementation 'androidx.constraintlayout:constraintlayout:2.2.0' implementation 'com.google.zxing:core:3.3.0' // fixed version to support SDK<24 implementation ('com.journeyapps:zxing-android-embedded:4.3.0') { transitive = false } // QR Code scanner implementation 'com.fasterxml.jackson.core:jackson-databind:2.11.1' // used as JSON library implementation 'com.google.code.gson:gson:2.12.1' // used as JSON library. implementation 'com.github.Baseflow:PhotoView:2.3.0' // does the zooming on photos / media implementation 'com.github.penfeizhou.android.animation:awebp:3.0.5' // animated webp support. implementation 'com.caverock:androidsvg-aar:1.4' // SVG support. implementation 'com.github.bumptech.glide:glide:4.16.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0' annotationProcessor 'androidx.annotation:annotation:1.9.1' implementation 'com.makeramen:roundedimageview:2.3.0' // crops the avatars to circles implementation 'com.github.amulyakhare:TextDrawable:558677ea31' // number of unread messages, // the one-letter circle for the contacts (when there is not avatar) and a white background. implementation 'com.googlecode.mp4parser:isoparser:1.0.6' // MP4 recoding; upgrading eg. to 1.1.22 breaks recoding, however, i have not investigated further, just reset to 1.0.6 implementation ('com.davemorrissey.labs:subsampling-scale-image-view:3.10.0') { // for the zooming on photos / media exclude group: 'com.android.support', module: 'support-annotations' } implementation 'com.annimon:stream:1.1.8' // brings future java streams api to SDK Version < 24 // Replacement for ContentResolver // that protects against the Surreptitious Sharing attack. // implementation 'de.cketti.safecontentresolver:safe-content-resolver-v21:1.0.0' gplayImplementation('com.google.firebase:firebase-messaging:25.0.0') { // for PUSH notifications exclude group: 'com.google.firebase', module: 'firebase-core' exclude group: 'com.google.firebase', module: 'firebase-analytics' exclude group: 'com.google.firebase', module: 'firebase-measurement-connector' } testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.27.3' testImplementation 'org.mockito:mockito-core:5.18.0' testImplementation 'org.powermock:powermock-api-mockito:1.7.4' testImplementation 'org.powermock:powermock-module-junit4:2.0.9' testImplementation 'org.powermock:powermock-module-junit4-rule:2.0.9' testImplementation 'org.powermock:powermock-classloading-xstream:2.0.9' androidTestImplementation 'androidx.test:runner:1.7.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.7.0' androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.7.0' androidTestImplementation 'androidx.test:rules:1.7.0' androidTestImplementation 'androidx.test.ext:junit:1.3.0' androidTestImplementation 'com.android.support:support-annotations:28.0.0' androidTestImplementation ('org.assertj:assertj-core:3.27.3') { exclude group: 'org.hamcrest', module: 'hamcrest-core' } } String buildConfigProperty(String name) { return "\"${propertyOrEmpty(name)}\"" } String propertyOrEmpty(String name) { Object p = findProperty(name) if (p == null) return environmentVariable(name) return (String) p } static String environmentVariable(String name) { String env = System.getenv(name) if (env == null) return "" return env } String getNdkArch() { Properties properties = new Properties() def file = project.rootProject.file('ndkArch') if (!file.exists()) return "\"\"" properties.load(file.newDataInputStream()) def arch = properties.getProperty('NDK_ARCH') if (arch == null) return "\"\"" return "\"$arch\"" }