diff --git a/.gitlab-ci-files/job-android.yml b/.gitlab-ci-files/job-android.yml index d80a57450..92ebb1a91 100644 --- a/.gitlab-ci-files/job-android.yml +++ b/.gitlab-ci-files/job-android.yml @@ -7,8 +7,8 @@ job-android: before_script: - if ! [ -z ${SCP_PRIVATE_KEY+x} ]; then eval $(ssh-agent -s); fi - if ! [ -z ${SCP_PRIVATE_KEY+x} ]; then echo "$SCP_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null; fi - - if ! [ -z ${ANDROID_SETTINGS_GRADLE+x} ]; then echo "$ANDROID_SETTINGS_GRADLE" > settings.gradle; fi - - git config --global --add safe.directory /builds/BC/public/linphone-android + - if ! [ -z ${ANDROID_SETTINGS_GRADLE+x} ]; then echo "$ANDROID_SETTINGS_GRADLE" > settings.gradle.kts; fi + - git config --global --add safe.directory /builds/BC/private/linphone-android-6.0 script: - ./gradlew app:dependencies | grep org.linphone diff --git a/app/build.gradle b/app/build.gradle deleted file mode 100644 index 2580a3866..000000000 --- a/app/build.gradle +++ /dev/null @@ -1,211 +0,0 @@ -plugins { - id 'com.android.application' - id 'kotlin-android' - id 'kotlin-kapt' - id 'org.jlleitschuh.gradle.ktlint' version '11.3.1' - id 'org.jetbrains.kotlin.android' - id 'com.google.gms.google-services' - id 'androidx.navigation.safeargs.kotlin' - id 'com.google.firebase.crashlytics' -} - -def packageName = "org.linphone" -def useDifferentPackageNameForDebugBuild = false - -def crashlyticsAvailable = new File(projectDir.absolutePath +'/google-services.json').exists() && new File(LinphoneSdkBuildDir + '/libs/').exists() && new File(LinphoneSdkBuildDir + '/libs-debug/').exists() - -configurations { - customImplementation.extendsFrom implementation -} - -def gitBranch = new ByteArrayOutputStream() -def gitVersion = new ByteArrayOutputStream() -task getGitVersion() { - def gitVersionStream = new ByteArrayOutputStream() - def gitCommitsCount = new ByteArrayOutputStream() - def gitCommitHash = new ByteArrayOutputStream() - - try { - exec { - executable "git" args "describe", "--abbrev=0" - standardOutput = gitVersionStream - } - exec { - executable "git" args "rev-list", gitVersionStream.toString().trim() + "..HEAD", "--count" - standardOutput = gitCommitsCount - } - exec { - executable "git" args "rev-parse", "--short", "HEAD" - standardOutput = gitCommitHash - } - exec { - executable "git" args "name-rev", "--name-only", "HEAD" - standardOutput = gitBranch - } - - if (gitCommitsCount.toString().toInteger() == 0) { - gitVersion = gitVersionStream.toString().trim() - } else { - gitVersion = gitVersionStream.toString().trim() + "." + gitCommitsCount.toString().trim() + "+" + gitCommitHash.toString().trim() - } - println("Git version: " + gitVersion) - } catch (ignored) { - println("Git not found [" + ignored + "], using " + gitVersion) - } -} - -tasks.register('linphoneSdkSource') { - doLast { - configurations.customImplementation.getIncoming().each { - it.getResolutionResult().allComponents.each { - if (it.id.getDisplayName().contains("linphone-sdk-android")) { - println 'Linphone SDK used is ' + it.moduleVersion.version + ' from ' + it.properties["repositoryName"] - } - } - } - } -} - -project.tasks.preBuild.dependsOn 'getGitVersion' -project.tasks.preBuild.dependsOn 'linphoneSdkSource' - -android { - namespace 'org.linphone' - compileSdk 34 - - defaultConfig { - applicationId packageName - minSdk 28 - targetSdk 34 - versionCode 60000 - versionName "6.0.0" - } - - applicationVariants.configureEach { variant -> - variant.outputs.configureEach { - outputFileName = "linphone-android-${variant.buildType.name}-${versionName}.apk" - } - } - - buildTypes { - debug { - if (useDifferentPackageNameForDebugBuild) { - applicationIdSuffix ".debug" - } - debuggable true - jniDebuggable true - - if (useDifferentPackageNameForDebugBuild) { - resValue "string", "file_provider", packageName + ".debug.fileprovider" - } else { - resValue "string", "file_provider", packageName + ".fileprovider" - } - resValue "string", "linphone_app_version", gitVersion.toString().trim() - resValue "string", "linphone_app_branch", gitBranch.toString().trim() - - if (crashlyticsAvailable) { - firebaseCrashlytics { - nativeSymbolUploadEnabled true - unstrippedNativeLibsDir file(LinphoneSdkBuildDir + '/libs-debug/').toString() - } - } - } - - release { - minifyEnabled true - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - - resValue "string", "file_provider", packageName + ".fileprovider" - resValue "string", "linphone_app_version", gitVersion.toString().trim() - resValue "string", "linphone_app_branch", gitBranch.toString().trim() - } - } - compileOptions { - sourceCompatibility = 17 - targetCompatibility = 17 - } - kotlinOptions { - jvmTarget = '17' - } - - buildFeatures { - dataBinding true - } - - - namespace 'org.linphone' - lint { - abortOnError false - } -} - -dependencies { - implementation 'androidx.annotation:annotation:1.8.0' - implementation 'androidx.appcompat:appcompat:1.7.0-rc01' - implementation "androidx.constraintlayout:constraintlayout:2.1.4" - implementation "androidx.core:core-ktx:1.13.1" - implementation 'androidx.core:core-splashscreen:1.2.0-alpha01' - implementation "androidx.core:core-telecom:1.0.0-alpha03" - implementation "androidx.media:media:1.7.0" - implementation "androidx.recyclerview:recyclerview:1.3.2" - implementation "androidx.slidingpanelayout:slidingpanelayout:1.2.0" - implementation "androidx.window:window:1.2.0" - implementation 'androidx.gridlayout:gridlayout:1.0.0' - // For VFS - implementation "androidx.security:security-crypto-ktx:1.1.0-alpha06" - - def nav_version = "2.7.7" - implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" - implementation "androidx.navigation:navigation-ui-ktx:$nav_version" - - def emoji_version = "1.4.0" - implementation "androidx.emoji2:emoji2-emojipicker:$emoji_version" - - // https://github.com/google/flexbox-layout/blob/main/LICENSE Apache v2.0 - implementation 'com.google.android.flexbox:flexbox:3.0.0' - - // https://github.com/material-components/material-components-android/blob/master/LICENSE Apache v2.0 - implementation 'com.google.android.material:material:1.11.0' - - // https://github.com/coil-kt/coil/blob/main/LICENSE.txt Apache v2.0 - def coil_version = "2.6.0" - implementation("io.coil-kt:coil:$coil_version") - implementation("io.coil-kt:coil-gif:$coil_version") - implementation("io.coil-kt:coil-svg:$coil_version") - implementation("io.coil-kt:coil-video:$coil_version") - - // https://github.com/tommybuonomo/dotsindicator/blob/master/LICENSE Apache v2.0 - implementation("com.tbuonomo:dotsindicator:5.0") - - // https://github.com/Baseflow/PhotoView/blob/master/LICENSE Apache v2.0 - implementation 'com.github.chrisbanes:PhotoView:2.3.0' - - implementation platform('com.google.firebase:firebase-bom:32.8.1') - implementation 'com.google.firebase:firebase-messaging' - implementation 'com.google.firebase:firebase-crashlytics-ndk' - - // https://github.com/openid/AppAuth-Android/blob/master/LICENSE Apache v2.0 - implementation 'net.openid:appauth:0.11.1' - //noinspection GroovyConstructorNamedArguments - android.defaultConfig.manifestPlaceholders = [appAuthRedirectScheme: 'org.linphone'] - - // To be able to parse native crash tombstone and print them with SDK logs the next time the app will start - implementation "com.google.protobuf:protobuf-javalite:3.22.3" - - //noinspection GradleDynamicVersion - implementation 'org.linphone:linphone-sdk-android:5.4.+' -} - -ktlint { - android = true - ignoreFailures = true -} - -project.tasks.preBuild.dependsOn 'ktlintFormat' - -if (crashlyticsAvailable) { - afterEvaluate { - assembleDebug.finalizedBy(uploadCrashlyticsSymbolFileDebug) - packageDebug.finalizedBy(uploadCrashlyticsSymbolFileDebug) - } -} \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 000000000..d2ca629ef --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,218 @@ +import com.android.build.gradle.internal.tasks.factory.dependsOn +import com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsExtension +import java.io.ByteArrayOutputStream + +plugins { + alias(libs.plugins.androidApplication) + alias(libs.plugins.kapt) + alias(libs.plugins.ktlint) + alias(libs.plugins.jetbrainsKotlinAndroid) + alias(libs.plugins.navigation) + alias(libs.plugins.googleGmsServices) + alias(libs.plugins.crashlytics) +} + +val packageName = "org.linphone" +val useDifferentPackageNameForDebugBuild = false + +val sdkPath = providers.gradleProperty("LinphoneSdkBuildDir").get() +val googleServices = File(projectDir.absolutePath + "/google-services.json") +val linphoneLibs = File("$sdkPath/libs/") +val linphoneDebugLibs = File("$sdkPath/libs-debug/") +val crashlyticsAvailable = googleServices.exists() && linphoneLibs.exists() && linphoneDebugLibs.exists() + +var gitBranch = ByteArrayOutputStream() +var gitVersion = "6.0.0" + +task("getGitVersion") { + val gitVersionStream = ByteArrayOutputStream() + val gitCommitsCount = ByteArrayOutputStream() + val gitCommitHash = ByteArrayOutputStream() + + try { + exec { + commandLine("git", "describe", "--abbrev=0") + standardOutput = gitVersionStream + } + exec { + commandLine( + "git", + "rev-list", + gitVersionStream.toString().trim() + "..HEAD", + "--count" + ) + standardOutput = gitCommitsCount + } + exec { + commandLine("git", "rev-parse", "--short", "HEAD") + standardOutput = gitCommitHash + } + exec { + commandLine("git", "name-rev", "--name-only", "HEAD") + standardOutput = gitBranch + } + + gitVersion = if (gitCommitsCount.toString().trim().toInt() == 0) { + gitVersionStream.toString().trim() + } else { + gitVersionStream.toString().trim() + "." + gitCommitsCount.toString() + .trim() + "+" + gitCommitHash.toString().trim() + } + println("Git version: $gitVersion") + } catch (e: Exception) { + println("Git not found [$e], using $gitVersion") + } +} +project.tasks.preBuild.dependsOn("getGitVersion") + +configurations { + implementation { isCanBeResolved = true } +} +task("linphoneSdkSource") { + doLast { + configurations.implementation.get().incoming.resolutionResult.allComponents.forEach { + if (it.id.displayName.contains("linphone-sdk-android")) { + println("Linphone SDK used is ${it.moduleVersion?.version}") + } + } + } +} +project.tasks.preBuild.dependsOn("linphoneSdkSource") + +android { + namespace = "org.linphone" + compileSdk = 34 + + defaultConfig { + applicationId = packageName + minSdk = 28 + targetSdk = 34 + versionCode = 60000 + versionName = "6.0.0" + + manifestPlaceholders["appAuthRedirectScheme"] = "org.linphone" + } + + applicationVariants.all { + val variant = this + variant.outputs + .map { it as com.android.build.gradle.internal.api.BaseVariantOutputImpl } + .forEach { output -> + output.outputFileName = "linphone-android-${variant.buildType.name}-$versionName.apk" + } + } + + buildTypes { + getByName("debug") { + if (useDifferentPackageNameForDebugBuild) { + applicationIdSuffix = ".debug" + } + isDebuggable = true + isJniDebuggable = true + + if (useDifferentPackageNameForDebugBuild) { + resValue("string", "file_provider", "$packageName.debug.fileprovider") + } else { + resValue("string", "file_provider", "$packageName.fileprovider") + } + resValue("string", "linphone_app_version", gitVersion.trim()) + resValue("string", "linphone_app_branch", gitBranch.toString().trim()) + + if (crashlyticsAvailable) { + configure { + nativeSymbolUploadEnabled = true + unstrippedNativeLibsDir = File("$sdkPath/libs-debug/").toString() + } + } + } + + getByName("release") { + isMinifyEnabled = true + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + + resValue("string", "file_provider", "$packageName.fileprovider") + resValue("string", "linphone_app_version", gitVersion.trim()) + resValue("string", "linphone_app_branch", gitBranch.toString().trim()) + } + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + kotlinOptions { + jvmTarget = "17" + } + + buildFeatures { + dataBinding = true + } + + lint { + abortOnError = false + } +} + +dependencies { + implementation(libs.androidx.annotations) + implementation(libs.androidx.appcompat) + implementation(libs.androidx.constraint.layout) + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.splashscreen) + implementation(libs.androidx.telecom) + implementation(libs.androidx.media) + implementation(libs.androidx.recyclerview) + implementation(libs.androidx.slidingpanelayout) + implementation(libs.androidx.window) + implementation(libs.androidx.gridlayout) + implementation(libs.androidx.security.crypto.ktx) + implementation(libs.androidx.navigation.fragment.ktx) + implementation(libs.androidx.navigation.ui.ktx) + implementation(libs.androidx.emoji2) + + // https://github.com/google/flexbox-layout/blob/main/LICENSE Apache v2.0 + implementation(libs.google.flexbox) + // https://github.com/material-components/material-components-android/blob/master/LICENSE Apache v2.0 + implementation(libs.google.material) + // To be able to parse native crash tombstone and print them with SDK logs the next time the app will start + implementation(libs.google.protobuf) + + implementation(platform(libs.google.firebase.bom)) + implementation(libs.google.firebase.messaging) + implementation(libs.google.firebase.crashlytics) + + // https://github.com/coil-kt/coil/blob/main/LICENSE.txt Apache v2.0 + implementation(libs.coil) + implementation(libs.coil.gif) + implementation(libs.coil.svg) + implementation(libs.coil.video) + // https://github.com/tommybuonomo/dotsindicator/blob/master/LICENSE Apache v2.0 + implementation(libs.dots.indicator) + // https://github.com/Baseflow/PhotoView/blob/master/LICENSE Apache v2.0 + implementation(libs.photoview) + // https://github.com/openid/AppAuth-Android/blob/master/LICENSE Apache v2.0 + implementation(libs.openid.appauth) + + implementation(libs.linphone) +} + +ktlint { + android = true + ignoreFailures = true +} +project.tasks.preBuild.dependsOn("ktlintFormat") + +if (crashlyticsAvailable) { + afterEvaluate { + tasks.getByName("assembleDebug").finalizedBy( + tasks.getByName("uploadCrashlyticsSymbolFileDebug") + ) + tasks.getByName("packageDebug").finalizedBy( + tasks.getByName("uploadCrashlyticsSymbolFileDebug") + ) + } +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 481bb4348..ff59496d8 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1,6 +1,6 @@ # Add project specific ProGuard rules here. # You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. +# proguardFiles setting in build.gradle.kts. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html diff --git a/build.gradle b/build.gradle deleted file mode 100644 index b4e3bf861..000000000 --- a/build.gradle +++ /dev/null @@ -1,22 +0,0 @@ -buildscript { - repositories { - google() - } - dependencies { - def nav_version = "2.7.7" - classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version" - - classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.9' - } -} -// Top-level build file where you can add configuration options common to all sub-projects/modules. -plugins { - id 'com.android.application' version '8.4.0' apply false - id 'com.android.library' version '8.4.0' apply false - id 'org.jetbrains.kotlin.android' version '1.9.23' apply false - id 'com.google.gms.google-services' version '4.4.1' apply false -} - -task clean(type: Delete) { - delete rootProject.buildDir -} diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 000000000..d0757ec85 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,8 @@ +plugins { + alias(libs.plugins.androidApplication) apply false + alias(libs.plugins.jetbrainsKotlinAndroid) apply false + alias(libs.plugins.kapt) apply false + alias(libs.plugins.navigation) apply false + alias(libs.plugins.googleGmsServices) apply false + alias(libs.plugins.crashlytics) apply false +} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 000000000..8c4c417b6 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,73 @@ +[versions] +agp = "8.4.0" +kotlin = "1.9.23" +gmsGoogleServices = "4.4.1" +firebaseCrashlytics = "2.9.9" +firebaseBomVersion = "32.8.1" +ktlint = "11.3.1" + +annotations = "1.8.0" +appcompat = "1.7.0-rc01" +constraintLayout = "2.1.4" +coreKtx = "1.13.1" +splashscreen = "1.2.0-alpha01" +telecom = "1.0.0-alpha03" +media = "1.7.0" +recyclerview = "1.3.2" +slidingpanelayout = "1.2.0" +window = "1.2.0" +gridlayout = "1.0.0" +securityCryptoKtx = "1.1.0-alpha06" +navigation = "2.7.7" +emoji2 = "1.4.0" +flexbox = "3.0.0" +material = "1.11.0" +protobuf = "3.22.3" +coil = "2.6.0" +dotsIndicator = "5.0" +photoview = "2.3.0" +openidAppauth = "0.11.1" +linphone = "5.4.+" + +[libraries] +androidx-annotations = { group = "androidx.annotation", name = "annotation", version.ref = "annotations" } +androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } +androidx-constraint-layout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintLayout" } +androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } +androidx-splashscreen = { group = "androidx.core", name = "core-splashscreen", version.ref = "splashscreen" } +androidx-telecom = { group = "androidx.core", name = "core-telecom", version.ref = "telecom" } +androidx-media = { group = "androidx.media", name = "media", version.ref = "media" } +androidx-recyclerview = { group = "androidx.recyclerview", name = "recyclerview", version.ref = "recyclerview" } +androidx-slidingpanelayout = { group = "androidx.slidingpanelayout", name = "slidingpanelayout", version.ref = "slidingpanelayout" } +androidx-window = { group = "androidx.window", name = "window", version.ref = "window" } +androidx-gridlayout = { group = "androidx.gridlayout", name = "gridlayout", version.ref = "gridlayout" } +androidx-security-crypto-ktx = { group = "androidx.security", name = "security-crypto-ktx", version.ref = "securityCryptoKtx" } +androidx-navigation-fragment-ktx = { group = "androidx.navigation", name = "navigation-fragment-ktx", version.ref = "navigation" } +androidx-navigation-ui-ktx = { group = "androidx.navigation", name = "navigation-ui-ktx", version.ref = "navigation" } +androidx-emoji2 = { group = "androidx.emoji2", name = "emoji2-emojipicker", version.ref = "emoji2" } + +google-firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "firebaseBomVersion" } +google-firebase-messaging = { group = "com.google.firebase", name = "firebase-messaging" } +google-firebase-crashlytics = { group = "com.google.firebase", name = "firebase-crashlytics-ndk" } +google-flexbox = { group = "com.google.android.flexbox", name = "flexbox", version.ref = "flexbox" } +google-material = { group = "com.google.android.material", name = "material", version.ref = "material" } +google-protobuf = { group = "com.google.protobuf", name = "protobuf-javalite", version.ref = "protobuf" } + +coil = { group = "io.coil-kt", name = "coil", version.ref = "coil" } +coil-gif = { group = "io.coil-kt", name = "coil-gif", version.ref = "coil" } +coil-svg = { group = "io.coil-kt", name = "coil-svg", version.ref = "coil" } +coil-video = { group = "io.coil-kt", name = "coil-video", version.ref = "coil" } +dots-indicator = { group = "com.tbuonomo", name = "dotsindicator", version.ref = "dotsIndicator" } +photoview = { group = "com.github.chrisbanes", name = "PhotoView", version.ref = "photoview" } +openid-appauth = { group = "net.openid", name = "appauth", version.ref = "openidAppauth" } + +linphone = { group = "org.linphone", name = "linphone-sdk-android", version.ref = "linphone" } + +[plugins] +androidApplication = { id = "com.android.application", version.ref = "agp" } +jetbrainsKotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" } +navigation = { id = "androidx.navigation.safeargs.kotlin", version.ref = "navigation" } +crashlytics = { id = "com.google.firebase.crashlytics", version.ref = "firebaseCrashlytics" } +googleGmsServices = { id = "com.google.gms.google-services", version.ref = "gmsGoogleServices" } +ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" } \ No newline at end of file diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index d8d5dbba5..000000000 --- a/settings.gradle +++ /dev/null @@ -1,33 +0,0 @@ -pluginManagement { - repositories { - google() - mavenCentral() - gradlePluginPortal() - } -} -dependencyResolutionManagement { - repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) - repositories { - google() - mavenCentral() - maven { url "https://www.jitpack.io" } // for com.github.chrisbanes:PhotoView - - maven { - name "local linphone-sdk maven repository" - url file(LinphoneSdkBuildDir + '/maven_repository/') - content { - includeGroup "org.linphone" - } - } - - maven { - name "linphone.org maven repository" - url "https://linphone.org/maven_repository" - content { - includeGroup "org.linphone" - } - } - } -} -rootProject.name = "Linphone" -include ':app' diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 000000000..d254ab992 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,37 @@ +pluginManagement { + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + maven { // for com.github.chrisbanes:PhotoView + url = uri("https://www.jitpack.io") + } + + maven { + name = "local linphone-sdk maven repository" + url = uri("file://${providers.gradleProperty("LinphoneSdkBuildDir").get()}/maven_repository/") + content { + includeGroup ("org.linphone") + } + } + + maven { + name = "linphone.org maven repository" + url = uri("https://linphone.org/maven_repository") + content { + includeGroup ("org.linphone") + } + } + } +} + +rootProject.name = "Linphone" +include(":app")