mirror of
https://github.com/mollyim/mollyim-android.git
synced 2025-05-12 21:30:39 +01:00
656 lines
27 KiB
Text
656 lines
27 KiB
Text
plugins {
|
|
alias(libs.plugins.android.application)
|
|
alias(libs.plugins.jetbrains.kotlin.android)
|
|
alias(libs.plugins.compose.compiler)
|
|
id("androidx.navigation.safeargs")
|
|
id("kotlin-parcelize")
|
|
id("com.squareup.wire")
|
|
id("molly")
|
|
}
|
|
|
|
val canonicalVersionCode = 1535
|
|
val canonicalVersionName = "7.39.5"
|
|
val currentHotfixVersion = 1
|
|
val maxHotfixVersions = 100
|
|
val mollyRevision = 2
|
|
|
|
// MOLLY: Use default debug keystore generated by Android Studio at $HOME/.android/debug.keystore
|
|
|
|
val selectableVariants = listOf(
|
|
"prodFossWebsiteDebug",
|
|
"prodFossWebsiteRelease",
|
|
"prodFossStoreDebug",
|
|
"prodFossStoreRelease",
|
|
"prodGmsWebsiteDebug",
|
|
"prodGmsWebsiteRelease",
|
|
"prodGmsWebsiteInstrumentation",
|
|
"prodGmsWebsiteSpinner",
|
|
"stagingFossWebsiteDebug",
|
|
"stagingFossWebsiteRelease",
|
|
"stagingGmsWebsiteDebug",
|
|
"stagingGmsWebsiteRelease",
|
|
)
|
|
|
|
val signalBuildToolsVersion: String by rootProject.extra
|
|
val signalCompileSdkVersion: String by rootProject.extra
|
|
val signalTargetSdkVersion: Int by rootProject.extra
|
|
val signalMinSdkVersion: Int by rootProject.extra
|
|
val signalNdkVersion: String by rootProject.extra
|
|
val signalJavaVersion: JavaVersion by rootProject.extra
|
|
val signalKotlinJvmTarget: String by rootProject.extra
|
|
|
|
// Override build config via env vars when project property 'CI' is set
|
|
val ciEnabled = project.hasProperty("CI")
|
|
|
|
val baseAppTitle = getCiEnv("CI_APP_TITLE") ?: properties["baseAppTitle"] as String
|
|
val baseAppFileName = getCiEnv("CI_APP_FILENAME") ?: properties["baseAppFileName"] as String
|
|
val basePackageId = getCiEnv("CI_PACKAGE_ID") ?: properties["basePackageId"] as String
|
|
val buildVariants = getCiEnv("CI_BUILD_VARIANTS") ?: properties["buildVariants"] as String
|
|
val forceInternalUserFlag = getCiEnv("CI_FORCE_INTERNAL_USER_FLAG") ?: properties["forceInternalUserFlag"] as String
|
|
val mapsApiKey = getCiEnv("CI_MAPS_API_KEY") ?: properties["mapsApiKey"] as String
|
|
|
|
fun getCiEnv(name: String) = if (ciEnabled) System.getenv(name).takeUnless { it.isNullOrBlank() } else null
|
|
|
|
wire {
|
|
kotlin {
|
|
javaInterop = true
|
|
}
|
|
|
|
sourcePath {
|
|
srcDir("src/main/protowire")
|
|
}
|
|
|
|
protoPath {
|
|
srcDir("${project.rootDir}/libsignal-service/src/main/protowire")
|
|
}
|
|
}
|
|
|
|
android {
|
|
namespace = "org.thoughtcrime.securesms"
|
|
|
|
buildToolsVersion = signalBuildToolsVersion
|
|
compileSdkVersion = signalCompileSdkVersion
|
|
ndkVersion = signalNdkVersion
|
|
|
|
flavorDimensions += listOf("environment", "license", "distribution")
|
|
testBuildType = "instrumentation"
|
|
|
|
android.bundle.language.enableSplit = false
|
|
|
|
kotlinOptions {
|
|
jvmTarget = signalKotlinJvmTarget
|
|
freeCompilerArgs = listOf("-Xjvm-default=all")
|
|
suppressWarnings = true
|
|
}
|
|
|
|
signingConfigs {
|
|
System.getenv("CI_KEYSTORE_PATH")?.let { path ->
|
|
create("ci") {
|
|
println("Signing release build with keystore: '$path'")
|
|
storeFile = file(path)
|
|
storePassword = System.getenv("CI_KEYSTORE_PASSWORD")
|
|
keyAlias = System.getenv("CI_KEYSTORE_ALIAS")
|
|
keyPassword = System.getenv("CI_KEYSTORE_PASSWORD")
|
|
enableV4Signing = false
|
|
}
|
|
}
|
|
}
|
|
|
|
testOptions {
|
|
execution = "ANDROIDX_TEST_ORCHESTRATOR"
|
|
|
|
unitTests {
|
|
isIncludeAndroidResources = true
|
|
}
|
|
}
|
|
|
|
sourceSets {
|
|
getByName("test") {
|
|
java.srcDir("$projectDir/src/testShared")
|
|
}
|
|
|
|
getByName("androidTest") {
|
|
java.srcDir("$projectDir/src/testShared")
|
|
}
|
|
}
|
|
|
|
compileOptions {
|
|
isCoreLibraryDesugaringEnabled = true
|
|
sourceCompatibility = signalJavaVersion
|
|
targetCompatibility = signalJavaVersion
|
|
}
|
|
|
|
packaging {
|
|
jniLibs {
|
|
excludes += setOf(
|
|
"**/*.dylib",
|
|
"**/*.dll"
|
|
)
|
|
// MOLLY: Compress native libs by default as APK is not split on ABIs
|
|
useLegacyPackaging = true
|
|
}
|
|
resources {
|
|
excludes += setOf(
|
|
"LICENSE.txt",
|
|
"LICENSE",
|
|
"NOTICE",
|
|
"asm-license.txt",
|
|
"META-INF/LICENSE",
|
|
"META-INF/LICENSE.md",
|
|
"META-INF/NOTICE",
|
|
"META-INF/LICENSE-notice.md",
|
|
"META-INF/proguard/androidx-annotations.pro",
|
|
"**/*.dylib",
|
|
"**/*.dll"
|
|
)
|
|
}
|
|
}
|
|
|
|
buildFeatures {
|
|
buildConfig = true
|
|
viewBinding = true
|
|
compose = true
|
|
}
|
|
|
|
composeOptions {
|
|
kotlinCompilerExtensionVersion = "1.5.4"
|
|
}
|
|
|
|
if (mollyRevision < 0 || currentHotfixVersion < 0 || (mollyRevision + currentHotfixVersion) >= maxHotfixVersions) {
|
|
throw GradleException("Molly revision $mollyRevision or Hotfix version $currentHotfixVersion out of range")
|
|
}
|
|
|
|
defaultConfig {
|
|
val sourceVersionNameWithRevision = "${canonicalVersionName}-${mollyRevision}"
|
|
|
|
versionCode = (canonicalVersionCode * maxHotfixVersions) + mollyRevision + currentHotfixVersion
|
|
versionName = if (ciEnabled) getCommitTag() else sourceVersionNameWithRevision
|
|
|
|
minSdk = signalMinSdkVersion
|
|
targetSdk = signalTargetSdkVersion
|
|
|
|
applicationId = basePackageId
|
|
|
|
buildConfigField("String", "SIGNAL_PACKAGE_NAME", "\"org.thoughtcrime.securesms\"")
|
|
buildConfigField("String", "SIGNAL_CANONICAL_VERSION_NAME", "\"$canonicalVersionName\"")
|
|
buildConfigField("int", "SIGNAL_CANONICAL_VERSION_CODE", "$canonicalVersionCode")
|
|
buildConfigField("String", "BACKUP_FILENAME", "\"${baseAppFileName.lowercase()}\"")
|
|
buildConfigField("boolean", "FORCE_INTERNAL_USER_FLAG", forceInternalUserFlag)
|
|
|
|
vectorDrawables.useSupportLibrary = true
|
|
|
|
// MOLLY: BUILD_TIMESTAMP may be zero in debug builds.
|
|
buildConfigField("long", "BUILD_OR_ZERO_TIMESTAMP", getLastCommitTimestamp() + "L")
|
|
buildConfigField("String", "GIT_HASH", "\"${getGitHash()}\"")
|
|
// MOLLY: Ensure to add any new URLs to SignalServiceNetworkAccess.HOSTNAMES list
|
|
buildConfigField("String", "SIGNAL_URL", "\"https://chat.signal.org\"")
|
|
buildConfigField("String", "STORAGE_URL", "\"https://storage.signal.org\"")
|
|
buildConfigField("String", "SIGNAL_CDN_URL", "\"https://cdn.signal.org\"")
|
|
buildConfigField("String", "SIGNAL_CDN2_URL", "\"https://cdn2.signal.org\"")
|
|
buildConfigField("String", "SIGNAL_CDN3_URL", "\"https://cdn3.signal.org\"")
|
|
buildConfigField("String", "SIGNAL_CDSI_URL", "\"https://cdsi.signal.org\"")
|
|
buildConfigField("String", "SIGNAL_SERVICE_STATUS_URL", "\"uptime.signal.org\"")
|
|
buildConfigField("String", "SIGNAL_SVR2_URL", "\"https://svr2.signal.org\"")
|
|
buildConfigField("String", "SIGNAL_SFU_URL", "\"https://sfu.voip.signal.org\"")
|
|
buildConfigField("String", "SIGNAL_STAGING_SFU_URL", "\"https://sfu.staging.voip.signal.org\"")
|
|
buildConfigField("String[]", "SIGNAL_SFU_INTERNAL_NAMES", "new String[]{\"Test\", \"Staging\", \"Development\"}")
|
|
buildConfigField("String[]", "SIGNAL_SFU_INTERNAL_URLS", "new String[]{\"https://sfu.test.voip.signal.org\", \"https://sfu.staging.voip.signal.org\", \"https://sfu.staging.test.voip.signal.org\"}")
|
|
buildConfigField("String", "CONTENT_PROXY_HOST", "\"contentproxy.signal.org\"")
|
|
buildConfigField("int", "CONTENT_PROXY_PORT", "443")
|
|
buildConfigField("String", "SIGNAL_AGENT", "\"OWA\"")
|
|
buildConfigField("String", "SVR2_MRENCLAVE", "\"9314436a9a144992bb3680770ea5fd7934a7ffd29257844a33763a238903d570\"")
|
|
buildConfigField("String", "UNIDENTIFIED_SENDER_TRUST_ROOT", "\"BXu6QIKVz5MA8gstzfOgRQGqyLqOwNKHL6INkv3IHWMF\"")
|
|
buildConfigField("String", "ZKGROUP_SERVER_PUBLIC_PARAMS", "\"AMhf5ywVwITZMsff/eCyudZx9JDmkkkbV6PInzG4p8x3VqVJSFiMvnvlEKWuRob/1eaIetR31IYeAbm0NdOuHH8Qi+Rexi1wLlpzIo1gstHWBfZzy1+qHRV5A4TqPp15YzBPm0WSggW6PbSn+F4lf57VCnHF7p8SvzAA2ZZJPYJURt8X7bbg+H3i+PEjH9DXItNEqs2sNcug37xZQDLm7X36nOoGPs54XsEGzPdEV+itQNGUFEjY6X9Uv+Acuks7NpyGvCoKxGwgKgE5XyJ+nNKlyHHOLb6N1NuHyBrZrgtY/JYJHRooo5CEqYKBqdFnmbTVGEkCvJKxLnjwKWf+fEPoWeQFj5ObDjcKMZf2Jm2Ae69x+ikU5gBXsRmoF94GXTLfN0/vLt98KDPnxwAQL9j5V1jGOY8jQl6MLxEs56cwXN0dqCnImzVH3TZT1cJ8SW1BRX6qIVxEzjsSGx3yxF3suAilPMqGRp4ffyopjMD1JXiKR2RwLKzizUe5e8XyGOy9fplzhw3jVzTRyUZTRSZKkMLWcQ/gv0E4aONNqs4P+NameAZYOD12qRkxosQQP5uux6B2nRyZ7sAV54DgFyLiRcq1FvwKw2EPQdk4HDoePrO/RNUbyNddnM/mMgj4FW65xCoT1LmjrIjsv/Ggdlx46ueczhMgtBunx1/w8k8V+l8LVZ8gAT6wkU5J+DPQalQguMg12Jzug3q4TbdHiGCmD9EunCwOmsLuLJkz6EcSYXtrlDEnAM+hicw7iergYLLlMXpfTdGxJCWJmP4zqUFeTTmsmhsjGBt7NiEB/9pFFEB3pSbf4iiUukw63Eo8Aqnf4iwob6X1QviCWuc8t0LUlT9vALgh/f2DPVOOmR0RW6bgRvc7DSF20V/omg+YBw==\"")
|
|
buildConfigField("String", "GENERIC_SERVER_PUBLIC_PARAMS", "\"AByD873dTilmOSG0TjKrvpeaKEsUmIO8Vx9BeMmftwUs9v7ikPwM8P3OHyT0+X3EUMZrSe9VUp26Wai51Q9I8mdk0hX/yo7CeFGJyzoOqn8e/i4Ygbn5HoAyXJx5eXfIbqpc0bIxzju4H/HOQeOpt6h742qii5u/cbwOhFZCsMIbElZTaeU+BWMBQiZHIGHT5IE0qCordQKZ5iPZom0HeFa8Yq0ShuEyAl0WINBiY6xE3H/9WnvzXBbMuuk//eRxXgzO8ieCeK8FwQNxbfXqZm6Ro1cMhCOF3u7xoX83QhpN\"")
|
|
buildConfigField("String", "BACKUP_SERVER_PUBLIC_PARAMS", "\"AJwNSU55fsFCbgaxGRD11wO1juAs8Yr5GF8FPlGzzvdJJIKH5/4CC7ZJSOe3yL2vturVaRU2Cx0n751Vt8wkj1bozK3CBV1UokxV09GWf+hdVImLGjXGYLLhnI1J2TWEe7iWHyb553EEnRb5oxr9n3lUbNAJuRmFM7hrr0Al0F0wrDD4S8lo2mGaXe0MJCOM166F8oYRQqpFeEHfiLnxA1O8ZLh7vMdv4g9jI5phpRBTsJ5IjiJrWeP0zdIGHEssUeprDZ9OUJ14m0v61eYJMKsf59Bn+mAT2a7YfB+Don9O\"")
|
|
buildConfigField("String[]", "LANGUAGES", "new String[]{ ${languageList().map { "\"$it\"" }.joinToString(separator = ", ")} }")
|
|
buildConfigField("String", "DEFAULT_CURRENCIES", "\"EUR,AUD,GBP,CAD,CNY\"")
|
|
buildConfigField("String", "GIPHY_API_KEY", "\"3o6ZsYH6U6Eri53TXy\"")
|
|
buildConfigField("String", "SIGNAL_CAPTCHA_URL", "\"https://signalcaptchas.org/registration/generate.html\"")
|
|
buildConfigField("String", "RECAPTCHA_PROOF_URL", "\"https://signalcaptchas.org/challenge/generate.html\"")
|
|
buildConfigField("org.signal.libsignal.net.Network.Environment", "LIBSIGNAL_NET_ENV", "org.signal.libsignal.net.Network.Environment.PRODUCTION")
|
|
buildConfigField("int", "LIBSIGNAL_LOG_LEVEL", "org.signal.libsignal.protocol.logging.SignalProtocolLogger.INFO")
|
|
|
|
// MOLLY: Rely on the built-in variables FLAVOR and BUILD_TYPE instead of BUILD_*_TYPE
|
|
buildConfigField("String", "BADGE_STATIC_ROOT", "\"https://updates2.signal.org/static/badges/\"")
|
|
buildConfigField("String", "STRIPE_BASE_URL", "\"https://api.stripe.com/v1\"")
|
|
buildConfigField("String", "STRIPE_PUBLISHABLE_KEY", "\"pk_live_6cmGZopuTsV8novGgJJW9JpC00vLIgtQ1D\"")
|
|
buildConfigField("boolean", "TRACING_ENABLED", "false")
|
|
|
|
ndk {
|
|
//noinspection ChromeOsAbiSupport
|
|
abiFilters += listOf("armeabi-v7a", "arm64-v8a", "x86_64")
|
|
}
|
|
|
|
resourceConfigurations += listOf()
|
|
|
|
testInstrumentationRunner = "org.thoughtcrime.securesms.testing.SignalTestRunner"
|
|
testInstrumentationRunnerArguments["clearPackageData"] = "true"
|
|
}
|
|
|
|
buildTypes {
|
|
getByName("debug") {
|
|
isDefault = true
|
|
isMinifyEnabled = false
|
|
proguardFiles(
|
|
getDefaultProguardFile("proguard-android.txt"),
|
|
"proguard/proguard-firebase-messaging.pro",
|
|
"proguard/proguard-google-play-services.pro",
|
|
"proguard/proguard-jackson.pro",
|
|
"proguard/proguard-sqlite.pro",
|
|
"proguard/proguard-appcompat-v7.pro",
|
|
"proguard/proguard-square-okhttp.pro",
|
|
"proguard/proguard-square-okio.pro",
|
|
"proguard/proguard-rounded-image-view.pro",
|
|
"proguard/proguard-glide.pro",
|
|
"proguard/proguard-shortcutbadger.pro",
|
|
"proguard/proguard-retrofit.pro",
|
|
"proguard/proguard-klinker.pro",
|
|
"proguard/proguard-retrolambda.pro",
|
|
"proguard/proguard-okhttp.pro",
|
|
"proguard/proguard-ez-vcard.pro",
|
|
"proguard/proguard.cfg"
|
|
)
|
|
testProguardFiles(
|
|
"proguard/proguard-automation.pro",
|
|
"proguard/proguard.cfg"
|
|
)
|
|
|
|
buildConfigField("long", "BUILD_OR_ZERO_TIMESTAMP", "0L")
|
|
buildConfigField("String", "GIT_HASH", "\"abc123def456\"")
|
|
}
|
|
|
|
getByName("release") {
|
|
isMinifyEnabled = true
|
|
isShrinkResources = true
|
|
signingConfig = signingConfigs.findByName("ci")
|
|
proguardFiles(*buildTypes["debug"].proguardFiles.toTypedArray())
|
|
}
|
|
|
|
create("instrumentation") {
|
|
initWith(getByName("debug"))
|
|
isDefault = false
|
|
isMinifyEnabled = false
|
|
matchingFallbacks += "debug"
|
|
applicationIdSuffix = ".instrumentation"
|
|
|
|
buildConfigField("String", "STRIPE_BASE_URL", "\"http://127.0.0.1:8080/stripe\"")
|
|
}
|
|
|
|
create("spinner") {
|
|
initWith(getByName("debug"))
|
|
isDefault = false
|
|
isMinifyEnabled = false
|
|
matchingFallbacks += "debug"
|
|
}
|
|
}
|
|
|
|
productFlavors {
|
|
create("store") {
|
|
dimension = "distribution"
|
|
buildConfigField("boolean", "MANAGES_MOLLY_UPDATES", "false")
|
|
}
|
|
|
|
create("website") {
|
|
dimension = "distribution"
|
|
isDefault = true
|
|
buildConfigField("boolean", "MANAGES_MOLLY_UPDATES", "true")
|
|
}
|
|
|
|
create("gms") {
|
|
dimension = "license"
|
|
isDefault = true
|
|
manifestPlaceholders["mapsApiKey"] = mapsApiKey
|
|
buildConfigField("boolean", "USE_PLAY_SERVICES", "true")
|
|
buildConfigField("boolean", "USE_OSM", "false")
|
|
buildConfigField("String", "FDROID_UPDATE_URL", "\"https://molly.im/fdroid/repo\"")
|
|
}
|
|
|
|
create("foss") {
|
|
dimension = "license"
|
|
versionNameSuffix = "-FOSS"
|
|
buildConfigField("boolean", "USE_PLAY_SERVICES", "false")
|
|
buildConfigField("boolean", "USE_OSM", "true")
|
|
buildConfigField("String", "FDROID_UPDATE_URL", "\"https://molly.im/fdroid/foss/repo\"")
|
|
}
|
|
|
|
create("prod") {
|
|
dimension = "environment"
|
|
|
|
isDefault = true
|
|
|
|
buildConfigField("String", "MOBILE_COIN_ENVIRONMENT", "\"mainnet\"")
|
|
}
|
|
|
|
create("staging") {
|
|
dimension = "environment"
|
|
|
|
applicationIdSuffix = ".staging"
|
|
|
|
buildConfigField("String", "SIGNAL_PACKAGE_NAME", "\"org.thoughtcrime.securesms.staging\"")
|
|
|
|
buildConfigField("String", "SIGNAL_URL", "\"https://chat.staging.signal.org\"")
|
|
buildConfigField("String", "STORAGE_URL", "\"https://storage-staging.signal.org\"")
|
|
buildConfigField("String", "SIGNAL_CDN_URL", "\"https://cdn-staging.signal.org\"")
|
|
buildConfigField("String", "SIGNAL_CDN2_URL", "\"https://cdn2-staging.signal.org\"")
|
|
buildConfigField("String", "SIGNAL_CDN3_URL", "\"https://cdn3-staging.signal.org\"")
|
|
buildConfigField("String", "SIGNAL_CDSI_URL", "\"https://cdsi.staging.signal.org\"")
|
|
buildConfigField("String", "SIGNAL_SVR2_URL", "\"https://svr2.staging.signal.org\"")
|
|
buildConfigField("String", "SVR2_MRENCLAVE", "\"38e01eff4fe357dc0b0e8ef7a44b4abc5489fbccba3a78780f3872c277f62bf3\"")
|
|
buildConfigField("String", "UNIDENTIFIED_SENDER_TRUST_ROOT", "\"BbqY1DzohE4NUZoVF+L18oUPrK3kILllLEJh2UnPSsEx\"")
|
|
buildConfigField("String", "ZKGROUP_SERVER_PUBLIC_PARAMS", "\"ABSY21VckQcbSXVNCGRYJcfWHiAMZmpTtTELcDmxgdFbtp/bWsSxZdMKzfCp8rvIs8ocCU3B37fT3r4Mi5qAemeGeR2X+/YmOGR5ofui7tD5mDQfstAI9i+4WpMtIe8KC3wU5w3Inq3uNWVmoGtpKndsNfwJrCg0Hd9zmObhypUnSkfYn2ooMOOnBpfdanRtrvetZUayDMSC5iSRcXKpdlukrpzzsCIvEwjwQlJYVPOQPj4V0F4UXXBdHSLK05uoPBCQG8G9rYIGedYsClJXnbrgGYG3eMTG5hnx4X4ntARBgELuMWWUEEfSK0mjXg+/2lPmWcTZWR9nkqgQQP0tbzuiPm74H2wMO4u1Wafe+UwyIlIT9L7KLS19Aw8r4sPrXZSSsOZ6s7M1+rTJN0bI5CKY2PX29y5Ok3jSWufIKcgKOnWoP67d5b2du2ZVJjpjfibNIHbT/cegy/sBLoFwtHogVYUewANUAXIaMPyCLRArsKhfJ5wBtTminG/PAvuBdJ70Z/bXVPf8TVsR292zQ65xwvWTejROW6AZX6aqucUjlENAErBme1YHmOSpU6tr6doJ66dPzVAWIanmO/5mgjNEDeK7DDqQdB1xd03HT2Qs2TxY3kCK8aAb/0iM0HQiXjxZ9HIgYhbtvGEnDKW5ILSUydqH/KBhW4Pb0jZWnqN/YgbWDKeJxnDbYcUob5ZY5Lt5ZCMKuaGUvCJRrCtuugSMaqjowCGRempsDdJEt+cMaalhZ6gczklJB/IbdwENW9KeVFPoFNFzhxWUIS5ML9riVYhAtE6JE5jX0xiHNVIIPthb458cfA8daR0nYfYAUKogQArm0iBezOO+mPk5vCNWI+wwkyFCqNDXz/qxl1gAntuCJtSfq9OC3NkdhQlgYQ==\"")
|
|
buildConfigField("String", "GENERIC_SERVER_PUBLIC_PARAMS", "\"AHILOIrFPXX9laLbalbA9+L1CXpSbM/bTJXZGZiuyK1JaI6dK5FHHWL6tWxmHKYAZTSYmElmJ5z2A5YcirjO/yfoemE03FItyaf8W1fE4p14hzb5qnrmfXUSiAIVrhaXVwIwSzH6RL/+EO8jFIjJ/YfExfJ8aBl48CKHgu1+A6kWynhttonvWWx6h7924mIzW0Czj2ROuh4LwQyZypex4GuOPW8sgIT21KNZaafgg+KbV7XM1x1tF3XA17B4uGUaDbDw2O+nR1+U5p6qHPzmJ7ggFjSN6Utu+35dS1sS0P9N\"")
|
|
buildConfigField("String", "BACKUP_SERVER_PUBLIC_PARAMS", "\"AHYrGb9IfugAAJiPKp+mdXUx+OL9zBolPYHYQz6GI1gWjpEu5me3zVNSvmYY4zWboZHif+HG1sDHSuvwFd0QszSwuSF4X4kRP3fJREdTZ5MCR0n55zUppTwfHRW2S4sdQ0JGz7YDQIJCufYSKh0pGNEHL6hv79Agrdnr4momr3oXdnkpVBIp3HWAQ6IbXQVSG18X36GaicI1vdT0UFmTwU2KTneluC2eyL9c5ff8PcmiS+YcLzh0OKYQXB5ZfQ06d6DiINvDQLy75zcfUOniLAj0lGJiHxGczin/RXisKSR8\"")
|
|
buildConfigField("String", "MOBILE_COIN_ENVIRONMENT", "\"testnet\"")
|
|
buildConfigField("String", "SIGNAL_CAPTCHA_URL", "\"https://signalcaptchas.org/staging/registration/generate.html\"")
|
|
buildConfigField("String", "RECAPTCHA_PROOF_URL", "\"https://signalcaptchas.org/staging/challenge/generate.html\"")
|
|
buildConfigField("org.signal.libsignal.net.Network.Environment", "LIBSIGNAL_NET_ENV", "org.signal.libsignal.net.Network.Environment.STAGING")
|
|
buildConfigField("int", "LIBSIGNAL_LOG_LEVEL", "org.signal.libsignal.protocol.logging.SignalProtocolLogger.DEBUG")
|
|
|
|
buildConfigField("String", "BUILD_ENVIRONMENT_TYPE", "\"Staging\"")
|
|
buildConfigField("String", "STRIPE_PUBLISHABLE_KEY", "\"pk_test_sngOd8FnXNkpce9nPXawKrJD00kIDngZkD\"")
|
|
}
|
|
}
|
|
|
|
lint {
|
|
abortOnError = true
|
|
baseline = file("lint-baseline.xml")
|
|
ignoreWarnings = true
|
|
quiet = true
|
|
}
|
|
|
|
applicationVariants.all {
|
|
val isStaging = productFlavors.any { it.name == "staging" }
|
|
|
|
resValue("string", "app_name", baseAppTitle + if (isStaging) " Staging" else "")
|
|
resValue("string", "package_name", applicationId)
|
|
|
|
outputs
|
|
.map { it as com.android.build.gradle.internal.api.ApkVariantOutputImpl }
|
|
.forEach { output ->
|
|
val flavors = "-$baseName"
|
|
.replace("-prod", "")
|
|
.replace(Regex("-(foss|gms)"), "")
|
|
.replace("-website", "")
|
|
.replace("-release", "")
|
|
val unsigned = if (isSigningReady) "" else "-unsigned"
|
|
|
|
output.outputFileName = "${baseAppFileName}${flavors}${unsigned}-${versionName}.apk"
|
|
}
|
|
}
|
|
|
|
androidComponents {
|
|
beforeVariants { variant ->
|
|
val selected = variant.name in selectableVariants
|
|
if (!(selected && buildVariants.toRegex().containsMatchIn(variant.name))) {
|
|
variant.enable = false
|
|
}
|
|
}
|
|
onVariants { variant ->
|
|
// Include the test-only library on debug builds.
|
|
if (variant.buildType != "instrumentation") {
|
|
variant.packaging.jniLibs.excludes.add("**/libsignal_jni_testing.so")
|
|
}
|
|
}
|
|
}
|
|
|
|
val releaseDir = "$projectDir/src/release/java"
|
|
val debugDir = "$projectDir/src/debug/java"
|
|
|
|
android.buildTypes.configureEach {
|
|
val path = if (name == "release") releaseDir else debugDir
|
|
sourceSets.named(name) {
|
|
java.srcDir(path)
|
|
}
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
lintChecks(project(":lintchecks"))
|
|
coreLibraryDesugaring(libs.android.tools.desugar)
|
|
|
|
implementation(project(":libsignal-service"))
|
|
implementation(project(":paging"))
|
|
implementation(project(":core-util"))
|
|
implementation(project(":glide-config"))
|
|
implementation(project(":video"))
|
|
implementation(project(":device-transfer"))
|
|
implementation(project(":image-editor"))
|
|
implementation(project(":donations"))
|
|
implementation(project(":contacts"))
|
|
implementation(project(":qr"))
|
|
implementation(project(":sticky-header-grid"))
|
|
implementation(project(":photoview"))
|
|
implementation(project(":core-ui"))
|
|
|
|
implementation(libs.androidx.fragment.ktx)
|
|
implementation(libs.androidx.fragment.compose)
|
|
implementation(libs.androidx.appcompat) {
|
|
version {
|
|
strictly("1.6.1")
|
|
}
|
|
}
|
|
implementation(libs.androidx.window.window)
|
|
implementation(libs.androidx.window.java)
|
|
implementation(libs.androidx.recyclerview)
|
|
implementation(libs.material.material)
|
|
implementation(libs.androidx.legacy.support)
|
|
implementation(libs.androidx.preference)
|
|
implementation(libs.androidx.legacy.preference)
|
|
implementation(libs.androidx.gridlayout)
|
|
implementation(libs.androidx.exifinterface)
|
|
implementation(libs.androidx.compose.rxjava3)
|
|
implementation(libs.androidx.compose.runtime.livedata)
|
|
implementation(libs.androidx.activity.compose)
|
|
implementation(libs.androidx.constraintlayout)
|
|
implementation(libs.androidx.navigation.fragment.ktx)
|
|
implementation(libs.androidx.navigation.ui.ktx)
|
|
implementation(libs.androidx.navigation.compose)
|
|
implementation(libs.androidx.lifecycle.viewmodel.ktx)
|
|
implementation(libs.androidx.lifecycle.livedata.ktx)
|
|
implementation(libs.androidx.lifecycle.process)
|
|
implementation(libs.androidx.lifecycle.viewmodel.savedstate)
|
|
implementation(libs.androidx.lifecycle.common.java8)
|
|
implementation(libs.androidx.lifecycle.reactivestreams.ktx)
|
|
implementation(libs.androidx.lifecycle.runtime.compose)
|
|
implementation(libs.androidx.activity.compose)
|
|
implementation(libs.androidx.camera.core)
|
|
implementation(libs.androidx.camera.camera2)
|
|
implementation(libs.androidx.camera.extensions)
|
|
implementation(libs.androidx.camera.lifecycle)
|
|
implementation(libs.androidx.camera.view)
|
|
implementation(libs.androidx.concurrent.futures)
|
|
implementation(libs.androidx.autofill)
|
|
implementation(libs.androidx.biometric)
|
|
implementation(libs.androidx.sharetarget)
|
|
implementation(libs.androidx.profileinstaller)
|
|
implementation(libs.androidx.asynclayoutinflater)
|
|
implementation(libs.androidx.asynclayoutinflater.appcompat)
|
|
implementation(libs.androidx.emoji2)
|
|
implementation(libs.androidx.splashscreen)
|
|
implementation(libs.androidx.webkit)
|
|
"gmsImplementation"(libs.firebase.messaging) {
|
|
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")
|
|
}
|
|
"gmsImplementation"(libs.google.play.services.maps)
|
|
"gmsImplementation"(libs.google.play.services.auth)
|
|
"fossImplementation"(project(":libfakegms"))
|
|
implementation(libs.bundles.media3)
|
|
implementation(libs.conscrypt.android)
|
|
implementation(libs.signal.aesgcmprovider)
|
|
implementation(libs.libsignal.android)
|
|
implementation(libs.molly.ringrtc)
|
|
implementation(libs.leolin.shortcutbadger)
|
|
implementation(libs.emilsjolander.stickylistheaders)
|
|
implementation(libs.glide.glide)
|
|
implementation(libs.roundedimageview)
|
|
implementation(libs.materialish.progress)
|
|
implementation(libs.greenrobot.eventbus)
|
|
implementation(libs.google.zxing.android.integration)
|
|
implementation(libs.google.zxing.core)
|
|
implementation(libs.google.flexbox)
|
|
implementation(libs.subsampling.scale.image.view) {
|
|
exclude(group = "com.android.support", module = "support-annotations")
|
|
}
|
|
implementation(libs.android.tooltips) {
|
|
exclude(group = "com.android.support", module = "appcompat-v7")
|
|
}
|
|
implementation(libs.stream)
|
|
implementation(libs.lottie)
|
|
implementation(libs.lottie.compose)
|
|
implementation(libs.signal.android.database.sqlcipher)
|
|
implementation(libs.androidx.sqlite)
|
|
testImplementation(libs.androidx.sqlite.framework)
|
|
implementation(libs.google.ez.vcard) {
|
|
exclude(group = "com.fasterxml.jackson.core")
|
|
exclude(group = "org.freemarker")
|
|
}
|
|
implementation(libs.dnsjava)
|
|
implementation(libs.kotlinx.collections.immutable)
|
|
implementation(libs.accompanist.permissions)
|
|
implementation(libs.accompanist.drawablepainter)
|
|
implementation(libs.kotlin.stdlib.jdk8)
|
|
implementation(libs.kotlin.reflect)
|
|
"gmsImplementation"(libs.kotlinx.coroutines.play.services)
|
|
implementation(libs.kotlinx.coroutines.rx3)
|
|
implementation(libs.jackson.module.kotlin)
|
|
implementation(libs.rxjava3.rxandroid)
|
|
implementation(libs.rxjava3.rxkotlin)
|
|
implementation(libs.rxdogtag)
|
|
|
|
implementation(project(":libnetcipher"))
|
|
implementation(libs.molly.argon2) { artifact { type = "aar" } }
|
|
implementation(libs.molly.native.utils)
|
|
implementation(libs.molly.glide.webp.decoder)
|
|
implementation(libs.gosimple.nbvcxz)
|
|
"fossImplementation"(libs.osmdroid.android)
|
|
implementation(libs.unifiedpush.connector) {
|
|
exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib")
|
|
exclude(group = "com.google.protobuf", module = "protobuf-java")
|
|
}
|
|
implementation(libs.unifiedpush.connector.ui) {
|
|
exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib")
|
|
}
|
|
|
|
"gmsImplementation"(project(":billing"))
|
|
|
|
"spinnerImplementation"(project(":spinner"))
|
|
|
|
"instrumentationImplementation"(libs.androidx.fragment.testing) {
|
|
exclude(group = "androidx.test", module = "core")
|
|
}
|
|
|
|
testImplementation(testLibs.junit.junit)
|
|
testImplementation(testLibs.assertk)
|
|
testImplementation(testLibs.androidx.test.core)
|
|
testImplementation(testLibs.robolectric.robolectric) {
|
|
exclude(group = "com.google.protobuf", module = "protobuf-java")
|
|
}
|
|
testImplementation(testLibs.bouncycastle.bcprov.jdk15on) {
|
|
version {
|
|
strictly("1.70")
|
|
}
|
|
}
|
|
testImplementation(testLibs.bouncycastle.bcpkix.jdk15on) {
|
|
version {
|
|
strictly("1.70")
|
|
}
|
|
}
|
|
testImplementation(testLibs.conscrypt.openjdk.uber)
|
|
testImplementation(testLibs.mockk)
|
|
testImplementation(testFixtures(project(":libsignal-service")))
|
|
testImplementation(testLibs.espresso.core)
|
|
testImplementation(testLibs.kotlinx.coroutines.test)
|
|
|
|
androidTestImplementation(platform(libs.androidx.compose.bom))
|
|
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
|
|
androidTestImplementation(testLibs.androidx.test.ext.junit)
|
|
androidTestImplementation(testLibs.espresso.core)
|
|
androidTestImplementation(testLibs.androidx.test.core)
|
|
androidTestImplementation(testLibs.androidx.test.core.ktx)
|
|
androidTestImplementation(testLibs.androidx.test.ext.junit.ktx)
|
|
androidTestImplementation(testLibs.assertk)
|
|
androidTestImplementation(testLibs.mockk.android)
|
|
androidTestImplementation(testLibs.square.okhttp.mockserver)
|
|
androidTestImplementation(testLibs.diff.utils)
|
|
|
|
androidTestUtil(testLibs.androidx.test.orchestrator)
|
|
}
|
|
|
|
fun assertIsGitRepo() {
|
|
if (!project.rootDir.resolve(".git").exists()) {
|
|
throw GradleException("Must be a git repository to guarantee reproducible builds! (git hash is part of APK)")
|
|
}
|
|
}
|
|
|
|
fun getLastCommitTimestamp(): String {
|
|
return try {
|
|
providers.exec {
|
|
commandLine("git", "log", "-1", "--pretty=format:%ct000")
|
|
}.standardOutput.asText.get().trim()
|
|
} catch (e: Throwable) {
|
|
logger.warn("Failed to get Git commit timestamp: ${e.message}. Using mtime of current build script.")
|
|
buildFile.lastModified().toString()
|
|
}
|
|
}
|
|
|
|
fun getGitHash(): String {
|
|
return try {
|
|
providers.exec {
|
|
commandLine("git", "rev-parse", "--short=12", "HEAD")
|
|
}.standardOutput.asText.get().trim()
|
|
} catch (e: Throwable) {
|
|
logger.warn("Failed to get Git commit hash: ${e.message}. Using default value.")
|
|
"abc123def456"
|
|
}
|
|
}
|
|
|
|
fun getCommitTag(): String {
|
|
assertIsGitRepo()
|
|
|
|
val tag = providers.exec {
|
|
commandLine("git", "describe", "--tags", "--exact-match")
|
|
}.standardOutput.asText.get().trim()
|
|
|
|
return tag.takeIf { it.isNotEmpty() } ?: "untagged"
|
|
}
|
|
|
|
fun getCurrentGitTag(): String? {
|
|
assertIsGitRepo()
|
|
|
|
val output = providers.exec {
|
|
commandLine("git", "tag", "--points-at", "HEAD")
|
|
}.standardOutput.asText.get().trim()
|
|
|
|
return if (output.isNotEmpty()) {
|
|
val tags = output.split("\n").toList()
|
|
tags.firstOrNull { it.contains("nightly") } ?: tags[0]
|
|
} else {
|
|
null
|
|
}
|
|
}
|
|
|
|
tasks.withType<Test>().configureEach {
|
|
testLogging {
|
|
events("failed")
|
|
showCauses = true
|
|
showExceptions = true
|
|
showStackTraces = true
|
|
}
|
|
}
|
|
|
|
fun Project.languageList(): List<String> {
|
|
return fileTree("src/main/res") { include("**/strings.xml") }
|
|
.map { stringFile -> stringFile.parentFile.name }
|
|
.map { valuesFolderName -> valuesFolderName.replace("values-", "") }
|
|
.filter { valuesFolderName -> valuesFolderName != "values" }
|
|
.map { languageCode -> languageCode.replace("-r", "_") }
|
|
.distinct()
|
|
.sorted() + "en"
|
|
}
|
|
|
|
fun String.capitalize(): String {
|
|
return this.replaceFirstChar { it.uppercase() }
|
|
}
|