gecko-dev/mobile/android/app/build.gradle
Nevin Chen 32c2be0d45 Bug 1420886 - Replace -ads with -analytics. r=maliu
Looking at latest Adjust SDK [1]
compile 'com.google.android.gms:play-services-analytics:10.2.1'
should be enough. And it doesn't have DoubleClick in it (testing with dexdump)	.
Even Adjust has change from -ads to -analytics [2]

I just build/test with below options.

export MOZ_INSTALL_TRACKING=1
ac_add_options --with-adjust-sdk-keyfile=.....

export MOZILLA_OFFICIAL=1
export MOZ_TELEMETRY_REPORTING=1

export MOZ_ANDROID_MMA=1
ac_add_options --with-leanplum-sdk-keyfile=.....

and it works for below places where we have have com.google.android.gms.ads.identifier.AdvertisingIdClient  : Leanplum[3] and Adjust[4]

[1] https://github.com/adjust/android_sdk

[2] https://github.com/adjust/android_sdk/issues/143

[3] https://searchfox.org/mozilla-central/rev/9f3bd430c2b132c86c46126a0548661de876799a/mobile/android/thirdparty/com/leanplum/internal/Util.java#204

[4] https://searchfox.org/mozilla-central/rev/9f3bd430c2b132c86c46126a0548661de876799a/mobile/android/thirdparty/com/adjust/sdk/Reflection.java#97

MozReview-Commit-ID: 6YdQ6NJm4hM

--HG--
extra : rebase_source : 6a26cfd135c72738f086f305c60905a920abace8
2017-11-29 15:53:01 +08:00

577 lines
26 KiB
Groovy

buildDir "${topobjdir}/gradle/build/mobile/android/app"
apply plugin: 'com.android.application'
apply plugin: 'checkstyle'
apply plugin: 'com.getkeepsafe.dexcount'
apply plugin: 'findbugs'
dexcount {
format = "tree"
}
android {
compileSdkVersion project.ext.compileSdkVersion
buildToolsVersion project.ext.buildToolsVersion
defaultConfig {
targetSdkVersion project.ext.targetSdkVersion
minSdkVersion project.ext.minSdkVersion
manifestPlaceholders = project.ext.manifestPlaceholders
applicationId mozconfig.substs.ANDROID_PACKAGE_NAME
testApplicationId 'org.mozilla.roboexample.test'
testInstrumentationRunner 'org.mozilla.gecko.FennecInstrumentationTestRunner'
// Used by Robolectric based tests; see TestRunner.
buildConfigField 'String', 'BUILD_DIR', "\"${project.buildDir}\""
vectorDrawables.useSupportLibrary = true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
dexOptions {
javaMaxHeapSize "2g"
jumboMode = true
}
lintOptions {
abortOnError true
}
buildTypes {
// We have the following difficult situation. Minification (Proguard) is only available per
// Android-Gradle `buildType`. Instrumentation (Robocop) is only available for exactly one
// `buildType` (see Android-Gradle `testBuildType`, which defaults to "debug"). Local
// developers expect to build and run tests against the "debug" build type. Automation
// needs to produce an instrumentation (Robocop) APK against a Fennec APK that will ship.
// (This is very unusual; usually, instrumentation tests do _not_ run against a shipping
// APK.)
//
// Given these constraints, we should not change `testBuildType` to avoid confusing local
// developers. Also, we should not Proguard any "debug" builds, because we don't want local
// developers to incur the cost of Proguard. However, we still need to find a way to
// Proguard a shipping APK and produce an instrumentation (Robocop APK) against it. To
// achieve this, we make "debug" builds Proguard in automation alone. This does have the
// unfortunate side effect of Proguarding the instrumentation (Robocop) APK, but nothing
// uses runtime inspection or class-loading with that APK, so it shouldn't be a problem.
def configureMinifyClosure = {
// Bug 1229269: we can't yet shrinkResources effectively. Be sure
// to use -stripped.ap_ after enabling this.
// shrinkResources true
minifyEnabled true
proguardFile "${topsrcdir}/mobile/android/config/proguard/proguard.cfg"
}
release configureMinifyClosure
if (mozconfig.substs.MOZILLA_OFFICIAL) {
debug configureMinifyClosure
}
}
// The "audience" flavour dimension distinguishes between _local_ builds (intended for
// development) and _official_ builds (intended for testing in automation and to ship in one of
// the Fennec distribution channels).
//
// The "skin" flavor dimension distinguishes between different user interfaces. We sometimes
// want to develop significant new user interface pieces in-tree that don't ship (even in the
// Nightly channel) while under development. A new "skin" flavour allows us to develop such
// pieces in Gradle without changing the mainline configuration.
flavorDimensions "audience", "skin"
productFlavors {
// For API 21+ - with pre-dexing, this will be faster for local development.
local {
dimension "audience"
// For pre-dexing, setting `minSdkVersion 21` allows the Android gradle plugin to
// pre-DEX each module and produce an APK that can be tested on
// Android Lollipop without time consuming DEX merging processes.
minSdkVersion 21
dexOptions {
preDexLibraries true
}
}
// For API < 21 - does not support pre-dexing because local development
// is slow in that case.
localOld {
dimension "audience"
}
// Automation builds. We use "official" rather than "automation" to drive these builds down
// the list of configurations that Android Studio offers, thereby making it _not_ the
// default. This avoids a common issue with "omni.ja" not being packed into the default APK
// built and deployed by Android Studio.
official {
dimension "audience"
}
// Since Firefox 57, the mobile user interface has followed the Photon design.
// Before Firefox 57, the user interface followed the Australis design.
photon {
dimension "skin"
}
}
sourceSets {
main {
aidl {
srcDir "${topsrcdir}/mobile/android/base/aidl"
}
java {
srcDir "${topsrcdir}/mobile/android/base/java"
srcDir "${topsrcdir}/mobile/android/services/src/main/java"
if (mozconfig.substs.MOZ_ANDROID_MLS_STUMBLER) {
srcDir "${topsrcdir}/mobile/android/stumbler/java"
}
if (!mozconfig.substs.MOZ_CRASHREPORTER) {
exclude 'org/mozilla/gecko/CrashReporter.java'
}
if (!mozconfig.substs.MOZ_NATIVE_DEVICES) {
exclude 'org/mozilla/gecko/ChromeCastDisplay.java'
exclude 'org/mozilla/gecko/ChromeCastPlayer.java'
exclude 'org/mozilla/gecko/GeckoMediaPlayer.java'
exclude 'org/mozilla/gecko/GeckoPresentationDisplay.java'
exclude 'org/mozilla/gecko/MediaPlayerManager.java'
}
if (mozconfig.substs.MOZ_INSTALL_TRACKING) {
exclude 'org/mozilla/gecko/adjust/StubAdjustHelper.java'
} else {
exclude 'org/mozilla/gecko/adjust/AdjustHelper.java'
}
if (mozconfig.substs.MOZ_ANDROID_MMA) {
exclude 'org/mozilla/gecko/mma/MmaStubImp.java'
} else {
exclude 'org/mozilla/gecko/mma/MmaLeanplumImp.java'
}
if (!mozconfig.substs.MOZ_ANDROID_GCM) {
exclude 'org/mozilla/gecko/gcm/**/*.java'
exclude 'org/mozilla/gecko/push/**/*.java'
}
srcDir "${project.buildDir}/generated/source/preprocessed_code" // See syncPreprocessedCode.
}
res {
srcDir "${topsrcdir}/${mozconfig.substs.MOZ_BRANDING_DIRECTORY}/res"
srcDir "${project.buildDir}/generated/source/preprocessed_resources" // See syncPreprocessedResources.
srcDir "${topsrcdir}/mobile/android/services/src/main/res"
if (mozconfig.substs.MOZ_CRASHREPORTER) {
srcDir "${topsrcdir}/mobile/android/base/crashreporter/res"
}
}
assets {
if (mozconfig.substs.MOZ_ANDROID_DISTRIBUTION_DIRECTORY) {
srcDir "${mozconfig.substs.MOZ_ANDROID_DISTRIBUTION_DIRECTORY}/assets"
}
}
}
// Every configuration needs the stub manifest at
// src/main/AndroidManifest.xml and the generated manifest. We can't
// use the main sourceSet without losing the stub, so we cover all the
// configurations by enumerating the buildTypes here.
debug {
manifest.srcFile "${project.buildDir}/generated/source/preprocessed_manifest/AndroidManifest.xml"
}
release {
manifest.srcFile "${project.buildDir}/generated/source/preprocessed_manifest/AndroidManifest.xml"
}
test {
java {
// Bug 1229149 tracks pushing this into a :services Gradle project.
srcDir "${topsrcdir}/mobile/android/services/src/test/java"
if (!mozconfig.substs.MOZ_ANDROID_GCM) {
exclude 'org/mozilla/gecko/gcm/**/*.java'
exclude 'org/mozilla/gecko/push/**/*.java'
}
}
resources {
// Bug 1229149 tracks pushing this into a :services Gradle project.
srcDir "${topsrcdir}/mobile/android/services/src/test/resources"
}
}
androidTest {
java {
srcDir "${topsrcdir}/mobile/android/tests/browser/robocop/src"
// Bug 1229149 tracks pushing this into a :services Gradle project.
srcDir "${topsrcdir}/mobile/android/services/src/androidTest/java"
srcDir "${topsrcdir}/mobile/android/tests/browser/junit3/src"
}
res {
srcDir "${topsrcdir}/mobile/android/tests/browser/robocop/res"
}
assets {
srcDir "${topsrcdir}/mobile/android/tests/browser/robocop/assets"
}
}
}
testOptions {
unitTests.all {
// We'd like to use (Runtime.runtime.availableProcessors()/2), but
// we have tests that start test servers and the bound ports
// collide. We'll fix this soon to have much faster test cycles.
maxParallelForks 1
}
}
}
dependencies {
compile "com.android.support:support-v4:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
compile "com.android.support:appcompat-v7:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
compile "com.android.support:cardview-v7:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
compile "com.android.support:recyclerview-v7:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
compile "com.android.support:design:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
compile "com.android.support:customtabs:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
if (mozconfig.substs.MOZ_NATIVE_DEVICES) {
compile "com.android.support:mediarouter-v7:${mozconfig.substs.ANDROID_SUPPORT_LIBRARY_VERSION}"
compile "com.google.android.gms:play-services-basement:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
compile "com.google.android.gms:play-services-base:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
compile "com.google.android.gms:play-services-cast:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
}
if (mozconfig.substs.MOZ_INSTALL_TRACKING) {
compile "com.google.android.gms:play-services-analytics:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
compile "com.google.android.gms:play-services-basement:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
}
if (mozconfig.substs.MOZ_ANDROID_GCM) {
compile "com.google.android.gms:play-services-basement:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
compile "com.google.android.gms:play-services-base:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
compile "com.google.android.gms:play-services-gcm:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
compile "com.google.android.gms:play-services-measurement:${mozconfig.substs.ANDROID_GOOGLE_PLAY_SERVICES_VERSION}"
}
// Include LeakCanary in most gradle based builds. LeakCanary adds about 5k methods, so we disable
// it for the (non-proguarded, non-predex) localOld builds to allow space for other libraries.
// Gradle based tests include the no-op version. Mach based builds only include the no-op version
// of this library.
// It doesn't seem like there is a non-trivial way to be conditional on 'localOld', so instead we explicitly
// define a version of leakcanary for every flavor:
localCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta1'
localOldCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta1'
officialCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta1'
officialCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta1'
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta1'
// With a simple "compile", Gradle will always build these libraries in their default configuration
// (i.e. release), so we need to explicitly forward our own build configuration here (bug 1385695).
//
// Official builds compile a hacked up app:Official..Debug, but need the
// release versions of the dependencies, in order to not have debugging
// information. It's not yet possible to specify just officialDebug, so we
// hack around it here.
if (mozconfig.substs.MOZILLA_OFFICIAL) {
debugCompile project(path: ':geckoview', configuration: "release")
} else {
debugCompile project(path: ':geckoview', configuration: "debug")
}
releaseCompile project(path: ':geckoview', configuration: "release")
if (mozconfig.substs.MOZILLA_OFFICIAL) {
debugCompile project(path: ':thirdparty', configuration: "release")
} else {
debugCompile project(path: ':thirdparty', configuration: "debug")
}
releaseCompile project(path: ':thirdparty', configuration: "release")
testCompile 'junit:junit:4.12'
testCompile 'org.robolectric:robolectric:3.1.2'
testCompile 'org.simpleframework:simple-http:6.0.1'
testCompile 'org.mockito:mockito-core:1.10.19'
// Including the Robotium JAR directly can cause issues with dexing.
androidTestCompile 'com.jayway.android.robotium:robotium-solo:5.5.4'
}
// TODO: (bug 1261486): This impl is not robust -
// we just wanted to land something.
task checkstyle(type: Checkstyle) {
configFile file("checkstyle.xml")
// TODO: should use sourceSets from project instead of hard-coded str.
source = ['../base/java/','../geckoview/src/main/java/']
// TODO: This ignores our pre-processed resources.
include '**/*.java'
// TODO: classpath should probably be something.
classpath = files()
}
task syncPreprocessedCode(type: Sync, dependsOn: rootProject.generateCodeAndResources) {
into("${project.buildDir}/generated/source/preprocessed_code")
from("${topobjdir}/mobile/android/base/generated/preprocessed")
}
// The localization system uses the moz.build preprocessor to interpolate a .dtd
// file of XML entity definitions into an XML file of elements referencing those
// entities. (Each locale produces its own .dtd file, backstopped by the en-US
// .dtd file in tree.) Android Studio (and IntelliJ) don't handle these inline
// entities smoothly. This filter merely expands the entities in place, making
// them appear properly throughout the IDE. Be aware that this assumes that the
// JVM's file.encoding is utf-8. See comments in
// mobile/android/mach_commands.py.
class ExpandXMLEntitiesFilter extends FilterReader {
ExpandXMLEntitiesFilter(Reader input) {
// Extremely inefficient, but whatever.
super(new StringReader(groovy.xml.XmlUtil.serialize(new XmlParser(false, false, true).parse(input))))
}
}
task syncPreprocessedResources(type: Sync, dependsOn: rootProject.generateCodeAndResources) {
into("${project.buildDir}/generated/source/preprocessed_resources")
from("${topobjdir}/mobile/android/base/res")
filesMatching('**/strings.xml') {
filter(ExpandXMLEntitiesFilter)
}
}
// It's not easy -- see the backout in Bug 1242213 -- to change the <manifest>
// package for Fennec. Gradle has grown a mechanism to achieve what we want for
// Fennec, however, with applicationId. To use the same manifest as moz.build,
// we replace the package with org.mozilla.gecko (the eventual package) here.
task rewriteManifestPackage(type: Copy, dependsOn: rootProject.generateCodeAndResources) {
into("${project.buildDir}/generated/source/preprocessed_manifest")
from("${topobjdir}/mobile/android/base/AndroidManifest.xml")
filter { it.replaceFirst(/package=".*?"/, 'package="org.mozilla.gecko"') }
}
apply from: "${topsrcdir}/mobile/android/gradle/with_gecko_binaries.gradle"
android.applicationVariants.all { variant ->
variant.preBuild.dependsOn rewriteManifestPackage
variant.preBuild.dependsOn syncPreprocessedCode
variant.preBuild.dependsOn syncPreprocessedResources
// Official automation builds don't include Gecko binaries, since those binaries are not
// produced until after build time (at package time). official Therefore, automation builds
// include the Gecko binaries into the APK at package time. The "withGeckoBinaries" variant of
// the :geckoview project also does this. (It does what it says on the tin!) For notes on this
// approach, see mobile/android/gradle/with_gecko_binaries.gradle.
// Like 'local' or 'localOld'.
def audienceDimension = variant.productFlavors[0].name
// :app uses :geckoview:release and handles it's own Gecko binary inclusion,
// even though this would be most naturally done in the :geckoview project.
if (!audienceDimension.equals('official')) {
configureVariantWithGeckoBinaries(variant)
}
}
android.applicationVariants.all { variant ->
configureVariantWithJNIWrappers(variant, "Fennec")
}
// Bug 1299015: Complain to treeherder if checkstyle, lint, or unittest fails. It's not obvious
// how to listen to individual errors in most cases, so we just link to the reports for now.
def makeTaskExecutionListener(artifactRootUrl) {
return new TaskExecutionListener() {
void beforeExecute(Task task) {
// Do nothing.
}
void afterExecute(Task task, TaskState state) {
if (!state.failure) {
return
}
// Link to the failing report. The task path and the report path
// depend on the android-lint task in
// taskcluster/ci/android-stuff/kind.yml. It's not possible to link
// directly, so for now consumers will need to copy-paste the URL.
switch (task.path) {
case ':app:checkstyle':
def url = "${artifactRootUrl}/public/android/checkstyle/checkstyle.xml"
println "TEST-UNEXPECTED-FAIL | android-checkstyle | Checkstyle rule violations were found. See the report at: $url"
break
case ':app:lintOfficialPhotonDebug':
def url = "${artifactRootUrl}/public/android/lint/lint-results-officialPhotonDebug.html"
println "TEST-UNEXPECTED-FAIL | android-lint | Lint found errors in the project; aborting build. See the report at: $url"
break
case ':app:testOfficialPhotonDebugUnitTest':
def url = "${artifactRootUrl}/public/android/unittest/officialPhotonDebug/index.html"
println "TEST-UNEXPECTED-FAIL | android-test | There were failing tests. See the reports at: $url"
break
case ':app:findbugsHtmlOfficialPhotonDebug':
def url = "${artifactRootUrl}/public/android/findbugs/findbugs-officialPhotonDebug-output.html"
println "TEST-UNEXPECTED-FAIL | android-findbugs | Findbugs found issues in the project. See the report at: $url"
break
case ':app:findbugsXmlOfficialPhotonDebug':
def url = "${artifactRootUrl}/public/android/findbugs/findbugs-officialPhotonDebug-output.xml"
println "TEST-UNEXPECTED-FAIL | android-findbugs | Findbugs found issues in the project. See the report at: $url"
break
}
}
}
}
// TASK_ID and RUN_ID are provided by docker-worker; see
// https://docs.taskcluster.net/manual/execution/workers/docker-worker.
if (System.env.TASK_ID && System.env.RUN_ID) {
def artifactRootUrl = "https://queue.taskcluster.net/v1/task/${System.env.TASK_ID}/runs/${System.env.RUN_ID}/artifacts"
gradle.addListener(makeTaskExecutionListener(artifactRootUrl))
}
if (gradle.startParameter.taskNames.any { it.endsWith('UnitTest') }) {
// Approach cribbed from https://github.com/rwinch/jce-checker.
int maxKeyLen = javax.crypto.Cipher.getMaxAllowedKeyLength("AES")
if (maxKeyLen <= 128) {
throw new GradleException(
"Android unit tests require " +
"Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy, see " +
"http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html")
}
}
// Bug 1320035: Gradle configuration for running findbugs. Findbugs only allows
// to generate one report per invocation: https://stackoverflow.com/a/42720235.
// Run two tasks, accepting the cost of duplicate work.
android.applicationVariants.all { variant ->
task("findbugsHtml${variant.name.capitalize()}", type: FindBugs) {
// TODO: figure out how to share the shared configuration.
description "Analyze ${variant.name} code with findbugs (HTML report)"
group "Verification"
ignoreFailures = false // We want builds to fail when running this task and issues are found
effort = "max" // Using more memory and time to find issues is acceptable in automation
reportLevel = "high" // For now we only care about high priority bugs. After we have fixed
// the issues with medium/low priority we can lower the report level here.
classes = files("$project.buildDir/intermediates/classes")
source = variant.javaCompile.source
classpath = variant.javaCompile.classpath
excludeFilter = file("findbugs-exclude.xml")
dependsOn "assemble${variant.name.capitalize()}"
reports {
html.enabled = true // HTML reports for humans.
html.destination = "$project.buildDir/reports/findbugs/findbugs-${variant.name}-output.html"
xml.enabled = false
}
}
task("findbugsXml${variant.name.capitalize()}", type: FindBugs) {
// TODO: figure out how to share the shared configuration.
description "Analyze ${variant.name} code with findbugs (XML report)"
group "Verification"
ignoreFailures = false // We want builds to fail when running this task and issues are found
effort = "max" // Using more memory and time to find issues is acceptable in automation
reportLevel = "high" // For now we only care about high priority bugs. After we have fixed
// the issues with medium/low priority we can lower the report level here.
classes = files("$project.buildDir/intermediates/classes")
source = variant.javaCompile.source
classpath = variant.javaCompile.classpath
excludeFilter = file("findbugs-exclude.xml")
dependsOn "assemble${variant.name.capitalize()}"
reports {
xml.enabled = true // XML reports for machines.
xml.destination = "$project.buildDir/reports/findbugs/findbugs-${variant.name}-output.xml"
html.enabled = false
}
}
}
// Bug 1353055 - Strip 'vars' debugging information to agree with moz.build.
apply from: "${topsrcdir}/mobile/android/gradle/debug_level.gradle"
android.applicationVariants.all configureVariantDebugLevel
// Bug 1320310 - Hack up the manifest produced by Gradle to match that produced
// by moz.build. Per https://bugzilla.mozilla.org/show_bug.cgi?id=1320310#c14,
// this breaks launching in Android Studio; therefore, we only do this for
// official automation builds and not for local developer builds.
import groovy.xml.XmlUtil
android.applicationVariants.all { variant ->
// Like 'local', 'localOld', or 'official'.
def audienceDimension = variant.productFlavors[0].name
if (!audienceDimension.equals('official')) {
return
}
variant.outputs.each { output ->
output.processManifest.doLast {
[output.processManifest.manifestOutputFile,
output.processManifest.instantRunManifestOutputFile,
].each({ File manifestOutFile ->
if (manifestOutFile.exists()) {
def contents = manifestOutFile.getText('UTF-8')
// A non-validating, non-namespace aware XML processor.
def xml = new XmlSlurper(false, false).parseText(contents)
// First, reinstate our <activity-alias android:name=".App">.
xml.depthFirst()
.findAll { it.name() == 'activity-alias' && it.'@android:name' == 'org.mozilla.gecko.App' }
.each { it.'@android:name' = '.App' }
// Second, cull all manifest entries provided by com.google.android.gms.measurement.
xml.depthFirst()
.findAll { it.'@android:name'.text().contains('AppMeasurement') }
.each { it.replaceNode {} }
manifestOutFile.write(XmlUtil.serialize(xml), 'UTF-8')
}
})
}
}
}
android.applicationVariants.all { variant ->
def processResourcesTask = tasks["process${variant.name.capitalize()}Resources"]
def assembleTask = tasks["assemble${variant.name.capitalize()}"]
def dumpTask = task("dump${variant.name.capitalize()}RTxt", type: Copy) {
from "${project.buildDir}/intermediates/symbols"
into "${project.buildDir}/R/symbols-${System.env.AB_CD}"
include "**/R.txt"
includeEmptyDirs = false
// Force task to run.
outputs.upToDateWhen { false }
rename { filename ->
filename.replace 'R.txt', "R-${new Date().format('yyyyMMddHHmmssSSS')}.txt"
}
dependsOn processResourcesTask
}
assembleTask.dependsOn dumpTask
}
// Bug 1415298: make Robolectric find assets. Fix adapted from
// https://github.com/robolectric/robolectric/issues/2647.
android.applicationVariants.all { variant ->
def productFlavor = ""
variant.productFlavors.each {
productFlavor += "${it.name.capitalize()}"
}
def buildType = "${variant.buildType.name.capitalize()}"
tasks["compile${productFlavor}${buildType}UnitTestSources"].dependsOn(tasks["merge${productFlavor}${buildType}Assets"])
}