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