1buildscript { 2 repositories { 3 google() 4 mavenCentral() 5 } 6 dependencies { 7 classpath libraries.android_tools 8 } 9} 10 11description = 'Conscrypt: Android Benchmarks' 12 13ext { 14 androidHome = "$System.env.ANDROID_HOME" 15 androidSdkInstalled = file("$androidHome").exists() 16 androidVersionCode = 1 17 androidVersionName = "$version" 18 androidMinSdkVersion = 26 19 androidTargetSdkVersion = 26 20} 21 22if (androidSdkInstalled) { 23 apply plugin: 'com.android.library' 24 25 android { 26 namespace "org.conscrypt" 27 compileSdkVersion androidTargetSdkVersion 28 29 defaultConfig { 30 minSdkVersion androidMinSdkVersion 31 targetSdkVersion androidTargetSdkVersion 32 versionCode androidVersionCode 33 versionName androidVersionName 34 } 35 lintOptions { 36 // Some Caliper classes reference packages that don't exist on Android 37 disable 'InvalidPackage' 38 } 39 sourceSets.main { 40 java { 41 srcDirs = [ 42 "src/main/java" 43 ] 44 } 45 } 46 } 47 48 configurations { 49 // For the depsJar task, we need to create a config we can pull libraries from to 50 // make the complete JAR. Some we do not want the transitive dependencies because 51 // they are already included on the Android system. 52 depsJarApi 53 depsJarApi.transitive = true 54 55 depsJarImplementation 56 depsJarImplementation.transitive = false 57 58 implementation.extendsFrom(depsJarApi) 59 implementation.extendsFrom(depsJarImplementation) 60 } 61 62 dependencies { 63 depsJarApi project(path: ':conscrypt-android'), 64 libraries.bouncycastle_provider, 65 libraries.bouncycastle_apis 66 67 depsJarImplementation project(':conscrypt-benchmark-base'), 68 project(path: ":conscrypt-testing", configuration: "shadow"), 69 project(':conscrypt-libcore-stub') 70 71 implementation 'com.google.caliper:caliper:1.0-beta-2' 72 } 73 74 // This task bundles up everything we're going to send to the device into a single jar. 75 // We need to include all the Conscrypt code plus the Bouncy Castle jar because the platform 76 // version of Bouncy Castle is jarjared. 77 // 78 // Since we're examining the contents of the archive files, we need to prevent evaluation of 79 // the .aar and .jar contents before the actual archives are built. To do this we create a 80 // configure task where the "from" contents is set inside a doLast stanza to ensure it is run 81 // after the execution phase of the "assemble" task. 82 def configureDepsJar = tasks.register("configureDepsJar") { 83 dependsOn assemble, \ 84 configurations.depsJarApi.artifacts, \ 85 configurations.depsJarImplementation.artifacts 86 doLast { 87 depsJar.from { 88 [ 89 configurations.depsJarApi, 90 configurations.depsJarImplementation, 91 configurations.archives.artifacts.file 92 ].collect { config -> 93 config.findResults { archive -> 94 // For Android library archives (.aar), we need to expand the classes.jar 95 // inside as well as including all the jni libraries. 96 if (archive.name.endsWith(".aar")) { 97 [ 98 zipTree(archive).matching { 99 include 'classes.jar' 100 }.collect { file -> 101 zipTree(file) 102 }, 103 zipTree(archive).matching { 104 include '**/*.so' 105 } 106 ] 107 } else if (archive.name.endsWith(".jar")) { 108 // Bouncy Castle signs their jar, which causes our combined jar to fail 109 // to verify. Just strip out the signature files. 110 zipTree(archive).matching { 111 exclude 'META-INF/*.SF' 112 exclude 'META-INF/*.DSA' 113 exclude 'META-INF/*.EC' 114 exclude 'META-INF/*.RSA' 115 } 116 } 117 } 118 } 119 } 120 } 121 } 122 123 def depsJar = tasks.register("depsJar", Jar) { 124 dependsOn configureDepsJar 125 archiveName = 'bundled-deps.jar' 126 } 127 128 def getAndroidDeviceAbi = tasks.register("getAndroidDeviceAbi") { 129 doLast { 130 new ByteArrayOutputStream().withStream { os -> 131 def result = exec { 132 executable android.adbExecutable 133 args 'shell', 'getprop', 'ro.product.cpu.abi' 134 standardOutput = os 135 } 136 project.ext.androidDeviceAbi = os.toString().trim() 137 project.ext.androidDevice64Bit = androidDeviceAbi.contains('64') 138 } 139 } 140 } 141 142 def configureExtractNativeLib = tasks.register("configureExtractNativeLib") { 143 dependsOn getAndroidDeviceAbi, depsJar 144 doLast { 145 extractNativeLib.from { 146 zipTree(depsJar.archivePath).matching { 147 include "jni/${androidDeviceAbi}/*.so" 148 }.collect { 149 // Using collect flattens out the directory. 150 it 151 } 152 } 153 } 154 } 155 156 def extractNativeLib = tasks.register("extractNativeLib", Copy) { 157 dependsOn configureExtractNativeLib 158 into "$buildDir/extracted-native-libs" 159 } 160 161 def configurePushNativeLibrary = tasks.register("configurePushNativeLibrary") { 162 dependsOn extractNativeLib 163 doLast { 164 project.ext.nativeLibPath = "/system/lib${androidDevice64Bit ? '64' : ''}/libconscrypt_jni.so" 165 pushNativeLibrary.args 'push', "${extractNativeLib.destinationDir}/libconscrypt_jni.so", nativeLibPath 166 } 167 } 168 169 def pushNativeLibrary = tasks.register("pushNativeLibrary", Exec) { 170 dependsOn configurePushNativeLibrary 171 pushNativeLibrary.executable android.adbExecutable 172 } 173 174 def runBenchmarks = tasks.register("runBenchmarks") { 175 dependsOn depsJar, pushNativeLibrary 176 doLast { 177 // Execute the benchmarks 178 exec { 179 workingDir "${rootDir}" 180 environment PATH: "${android.sdkDirectory}/build-tools/${android.buildToolsVersion}:$System.env.PATH" 181 environment JACK_JAR: "${android.sdkDirectory}/build-tools/${android.buildToolsVersion}/jack.jar" 182 183 executable 'java' 184 args '-cp', 'benchmark-android/vogar.jar', 'vogar.Vogar' 185 args '--classpath', depsJar.archivePath 186 args '--benchmark' 187 args '--language=JN' 188 args '--mode=app_process' 189 args 'org.conscrypt.CaliperAlpnBenchmark' 190 args 'org.conscrypt.CaliperClientSocketBenchmark' 191 args 'org.conscrypt.CaliperEngineHandshakeBenchmark' 192 args 'org.conscrypt.CaliperEngineWrapBenchmark' 193 } 194 // Clean up the native library 195 exec { 196 executable android.adbExecutable 197 args 'shell', 'rm', '-f', nativeLibPath 198 } 199 } 200 } 201} else { 202 logger.warn('Android SDK has not been detected. The Android Benchmark module will not be built.') 203 204 // Disable all tasks 205 tasks.configureEach { 206 it.enabled = false 207 } 208} 209