• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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