import groovy.json.JsonSlurper apply plugin: 'com.android.library' apply plugin: 'maven-publish' android { compileSdkVersion rootProject.ext.compileSdkVersion defaultConfig { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion } buildTypes { debug { buildConfigField "boolean", "LIBRE_BUILD", "${rootProject.ext.libreBuild}" buildConfigField "boolean", "GOOGLE_SERVICES_ENABLED", "${rootProject.ext.googleServicesEnabled}" } release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' buildConfigField "boolean", "LIBRE_BUILD", "${rootProject.ext.libreBuild}" buildConfigField "boolean", "GOOGLE_SERVICES_ENABLED", "${rootProject.ext.googleServicesEnabled}" } } sourceSets { main { java { if (rootProject.ext.libreBuild) { srcDir "src" exclude "**/AmplitudeModule.java" } exclude "test/" } } } packagingOptions { pickFirst '**/libc++_shared.so' } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.fragment:fragment:1.2.0' //noinspection GradleDynamicVersion api 'com.facebook.react:react-native:+' // Hermes JS engine def hermesPath = "../../node_modules/hermes-engine/android/" debugImplementation files(hermesPath + "hermes-debug.aar") releaseImplementation files(hermesPath + "hermes-release.aar") implementation 'com.dropbox.core:dropbox-core-sdk:3.0.8' implementation 'com.jakewharton.timber:timber:4.7.1' implementation 'com.squareup.duktape:duktape-android:1.3.0' if (!rootProject.ext.libreBuild) { implementation 'com.amplitude:android-sdk:2.14.1' implementation(project(":react-native-google-signin")) { exclude group: 'com.google.android.gms' exclude group: 'androidx' } } implementation project(':react-native-background-timer') implementation project(':react-native-calendar-events') implementation project(':react-native-community-async-storage') implementation project(':react-native-community_netinfo') implementation project(':react-native-default-preference') implementation project(':react-native-immersive') implementation project(':react-native-keep-awake') implementation project(':react-native-linear-gradient') implementation project(':react-native-sound') implementation project(':react-native-svg') implementation project(':react-native-webrtc') implementation project(':react-native-webview') testImplementation 'junit:junit:4.12' } // Here we bundle all assets, resources and React files. We cannot use the // react.gradle file provided by react-native because it's designed to be used // in an application (it taps into applicationVariants, but the SDK is a library // so we need libraryVariants instead). android.libraryVariants.all { def variant -> // Create variant and target names def targetName = variant.name.capitalize() def targetPath = variant.dirName // React js bundle directories def jsBundleDir = file("$buildDir/generated/assets/react/${targetPath}") def resourcesDir = file("$buildDir/generated/res/react/${targetPath}") def jsBundleFile = file("$jsBundleDir/index.android.bundle") def currentBundleTask = tasks.create( name: "bundle${targetName}JsAndAssets", type: Exec) { group = "react" description = "bundle JS and assets for ${targetName}." // Create dirs if they are not there (e.g. the "clean" task just ran) doFirst { jsBundleDir.deleteDir() jsBundleDir.mkdirs() resourcesDir.deleteDir() resourcesDir.mkdirs() } // Set up inputs and outputs so gradle can cache the result def reactRoot = file("${projectDir}/../../") inputs.files fileTree(dir: reactRoot, excludes: ["android/**", "ios/**"]) outputs.dir jsBundleDir outputs.dir resourcesDir // Set up the call to the react-native cli workingDir reactRoot // Set up dev mode def devEnabled = !targetName.toLowerCase().contains("release") // Run the bundler commandLine( "node", "node_modules/react-native/local-cli/cli.js", "bundle", "--platform", "android", "--dev", "${devEnabled}", "--reset-cache", "--entry-file", "index.android.js", "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir) // Disable bundling on dev builds enabled !devEnabled } currentBundleTask.ext.generatedResFolders = files(resourcesDir).builtBy(currentBundleTask) currentBundleTask.ext.generatedAssetsFolders = files(jsBundleDir).builtBy(currentBundleTask) variant.registerGeneratedResFolders(currentBundleTask.generatedResFolders) def mergeAssetsTask = variant.mergeAssetsProvider.get() def mergeResourcesTask = variant.mergeResourcesProvider.get() mergeAssetsTask.dependsOn(currentBundleTask) mergeResourcesTask.dependsOn(currentBundleTask) mergeAssetsTask.doLast { def assetsDir = mergeAssetsTask.outputDir // Bundle sounds // copy { from("${projectDir}/../../sounds/incomingMessage.wav") from("${projectDir}/../../sounds/joined.wav") from("${projectDir}/../../sounds/left.wav") from("${projectDir}/../../sounds/liveStreamingOn.mp3") from("${projectDir}/../../sounds/liveStreamingOff.mp3") from("${projectDir}/../../sounds/outgoingRinging.wav") from("${projectDir}/../../sounds/outgoingStart.wav") from("${projectDir}/../../sounds/recordingOn.mp3") from("${projectDir}/../../sounds/recordingOff.mp3") from("${projectDir}/../../sounds/rejected.wav") into("${assetsDir}/sounds") } // Copy React assets // if (currentBundleTask.enabled) { copy { from(jsBundleFile) into(assetsDir) } } } mergeResourcesTask.doLast { // Copy React resources // if (currentBundleTask.enabled) { copy { from(resourcesDir) into(mergeResourcesTask.outputDir) } } } } publishing { publications { aarArchive(MavenPublication) { groupId 'org.jitsi.react' artifactId 'jitsi-meet-sdk' version System.env.OVERRIDE_SDK_VERSION ?: project.sdkVersion artifact("${project.buildDir}/outputs/aar/${project.name}-release.aar") { extension "aar" } pom.withXml { def pomXml = asNode() pomXml.appendNode('name', 'jitsi-meet-sdk') pomXml.appendNode('description', 'Jitsi Meet SDK for Android') def dependencies = pomXml.appendNode('dependencies') configurations.getByName('releaseCompileClasspath').getResolvedConfiguration().getFirstLevelModuleDependencies().each { // The (third-party) React Native modules that we depend on // are in source code form and do not have groupId. That is // why we have a dedicated groupId for them. But the other // dependencies come through Maven and, consequently, have // groupId. def groupId = it.moduleGroup def artifactId = it.moduleName if (artifactId.startsWith('react-native-') && groupId.equals('jitsi-meet')) { groupId = rootProject.ext.moduleGroupId } def dependency = dependencies.appendNode('dependency') dependency.appendNode('groupId', groupId) dependency.appendNode('artifactId', artifactId) dependency.appendNode('version', it.moduleVersion) } // Add Hermes dependency. def hermesPkg = new File("$rootDir/../node_modules/hermes-engine/package.json") def hermesVersion = new JsonSlurper().parseText(hermesPkg.text).version def hermesDependency = dependencies.appendNode('dependency') hermesDependency.appendNode('groupId', "com.facebook") hermesDependency.appendNode('artifactId', "hermes") hermesDependency.appendNode('version', hermesVersion) } } } repositories { maven { url rootProject.ext.mavenRepo if (!rootProject.ext.mavenRepo.startsWith("file")) { credentials { username rootProject.ext.mavenUser password rootProject.ext.mavenPassword } } } } }