import android.support.checkapi.ApiXmlConversionTask
import android.support.checkapi.CheckApiTask
import android.support.checkapi.UpdateApiTask
import android.support.doclava.DoclavaMultilineJavadocOptionFileOption
import android.support.doclava.DoclavaTask
import android.support.jdiff.JDiffTask

import com.android.build.gradle.internal.coverage.JacocoPlugin
import com.android.build.gradle.internal.coverage.JacocoReportTask
import com.android.build.gradle.internal.tasks.DeviceProviderInstrumentTestTask
import org.gradle.internal.os.OperatingSystem

import com.google.common.base.Charsets
import com.google.common.hash.HashCode
import com.google.common.hash.HashFunction
import com.google.common.hash.Hashing
import com.google.common.io.Files

import groovy.io.FileType

buildscript {
    apply from: 'buildSrc/dependencies.gradle'

    repositories {
        maven { url '../../prebuilts/gradle-plugin' }
        maven { url '../../prebuilts/tools/common/m2/repository' }
        maven { url '../../prebuilts/tools/common/m2/internal' }
        maven { url '../../prebuilts/maven_repo/android' }
    }
    dependencies {
        classpath libs.gradle
    }
}

apply from: 'buildSrc/dependencies.gradle'

repositories {
    maven { url '../../prebuilts/tools/common/m2/repository' }
}

configurations {
    doclava
    jdiff
}

dependencies {
    doclava project(':doclava')
    jdiff project(':jdiff')
    jdiff libs.xml_parser_apis
    jdiff libs.xerces_impl
}

// Version code components.
ext.supportVersion = "26.0.0-SNAPSHOT"

// This number gets incremented for each public release.
ext.extraVersion = 41

// Enforce the use of prebuilt dependencies in all sub-projects. This is
// required for the doclava dependency.
ext.usePrebuilts = "true"

final String platform = OperatingSystem.current().isMacOsX() ? 'darwin' : 'linux'
System.setProperty('android.dir', "${rootDir}/../../")
final String fullSdkPath = "${rootDir}/../../prebuilts/fullsdk-${platform}"
if (file(fullSdkPath).exists()) {
    gradle.ext.currentSdk = 26
    ext.buildToolsVersion = '26.0.0'
    project.ext.androidJar = files("${fullSdkPath}/platforms/android-${gradle.ext.currentSdk}/android.jar")
    System.setProperty('android.home', "${rootDir}/../../prebuilts/fullsdk-${platform}")
    File props = file("local.properties")
    props.write "sdk.dir=${fullSdkPath}"
} else {
    gradle.ext.currentSdk = 'current'
    ext.buildToolsVersion = '24.0.1'
    project.ext.androidJar = files("${project.rootDir}/../../prebuilts/sdk/current/android.jar")
    File props = file("local.properties")
    props.write "android.dir=../../"
}

ext.supportRepoOut = ''
ext.buildNumber = Integer.toString(ext.extraVersion)

/*
 * With the build server you are given two env variables.
 * The OUT_DIR is a temporary directory you can use to put things during the build.
 * The DIST_DIR is where you want to save things from the build.
 *
 * The build server will copy the contents of DIST_DIR to somewhere and make it available.
 */
if (System.env.DIST_DIR != null && System.env.OUT_DIR != null) {
    buildDir = new File(System.env.OUT_DIR + '/gradle/frameworks/support/build').getCanonicalFile()
    project.ext.distDir = new File(System.env.DIST_DIR).getCanonicalFile()

    // the build server does not pass the build number so we infer it from the last folder of the dist path.
    ext.buildNumber = project.ext.distDir.getName()
} else {
    buildDir = file("${project.rootDir}/../../out/host/gradle/frameworks/support/build")
    project.ext.distDir = file("${project.rootDir}/../../out/dist")
}

subprojects {
    // Change buildDir first so that all plugins pick up the new value.
    project.buildDir = project.file("$project.parent.buildDir/../$project.name/build")
}

ext.docsDir = new File(buildDir, 'javadoc')
ext.supportRepoOut = new File(buildDir, 'support_repo')
ext.testApkDistOut = ext.distDir

// Main task called by the build server.
task(createArchive)

// upload anchor for subprojects to upload their artifacts
// to the local repo.
task(mainUpload)

// repository creation task
task createRepository(type: Zip, dependsOn: mainUpload) {
    from project.ext.supportRepoOut
    destinationDir project.ext.distDir
    into 'm2repository'
    baseName = String.format("sdk-repo-linux-m2repository-%s", project.ext.buildNumber)
}
createArchive.dependsOn createRepository

// prepare repository with older versions
task unzipRepo(type: Copy) {
    from "${project.rootDir}/../../prebuilts/maven_repo/android"
    into project.ext.supportRepoOut
}

unzipRepo.doFirst {
    project.ext.supportRepoOut.deleteDir()
    project.ext.supportRepoOut.mkdirs()
}

// anchor for prepare repo. This is post unzip + sourceProp.
task(prepareRepo)

// lint every library
task(lint)

task(createXml).doLast({
    def repoArchive = createRepository.archivePath
    def repoArchiveName = createRepository.archiveName
    def size = repoArchive.length()
    def sha1 = getSha1(repoArchive)

    def xml =
"<sdk:sdk-addon xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:sdk=\"http://schemas.android.com/sdk/android/addon/6\">\n\
  <sdk:extra>\n\
    <sdk:revision>\n\
      <sdk:major>${project.ext.extraVersion}</sdk:major>\n\
    </sdk:revision>\n\
    <sdk:vendor-display>Android</sdk:vendor-display>\n\
    <sdk:vendor-id>android</sdk:vendor-id>\n\
    <sdk:name-display>Local Maven repository for Support Libraries</sdk:name-display>\n\
    <sdk:path>m2repository</sdk:path>\n\
    <sdk:archives>\n\
      <sdk:archive>\n\
       <sdk:size>${size}</sdk:size>\n\
       <sdk:checksum type=\"sha1\">${sha1}</sdk:checksum>\n\
       <sdk:url>${repoArchiveName}</sdk:url>\n\
      </sdk:archive>\n\
    </sdk:archives>\n\
  </sdk:extra>\n\
</sdk:sdk-addon>"

    Files.write(xml, new File(project.ext.distDir, 'repo-extras.xml'), Charsets.UTF_8)
})
createArchive.dependsOn createXml
createXml.dependsOn createRepository

task(createSourceProp).doLast({
    def sourceProp =
"Extra.VendorDisplay=Android\n\
Extra.Path=m2repository\n\
Archive.Arch=ANY\n\
Extra.NameDisplay=Android Support Repository\n\
Archive.Os=ANY\n\
Pkg.Desc=Local Maven repository for Support Libraries\n\
Pkg.Revision=${project.ext.extraVersion}.0.0\n\
Extra.VendorId=android"

    Files.write(sourceProp, new File(project.ext.supportRepoOut, 'source.properties'), Charsets.UTF_8)
})
createSourceProp.dependsOn unzipRepo
prepareRepo.dependsOn createSourceProp

import java.nio.charset.Charset

/**
 * Generates SHA1 hash for the specified file's absolute path.
 *
 * @param inputFile file to hash
 * @return SHA1 hash
 */
String getSha1(File inputFile) {
    HashFunction hashFunction = Hashing.sha1()
    HashCode hashCode = hashFunction.hashString(inputFile.getAbsolutePath(), Charset.forName("UTF-8"))
    return hashCode.toString()
}

void registerForDocsTask(Task task, Project subProject, releaseVariant) {
    task.dependsOn releaseVariant.javaCompile
    task.source {
        def buildConfig = fileTree(releaseVariant.getGenerateBuildConfig().sourceOutputDir)
        return releaseVariant.javaCompile.source.minus(buildConfig) +
            fileTree(releaseVariant.aidlCompile.sourceOutputDir) +
            fileTree(releaseVariant.outputs[0].processResources.sourceOutputDir)
    }
    task.classpath += files(releaseVariant.javaCompile.classpath) +
            files(releaseVariant.javaCompile.destinationDir)
}

// Generates online docs.
task generateDocs(type: DoclavaTask, dependsOn: configurations.doclava) {
    docletpath = configurations.doclava.resolve()
    destinationDir = new File(project.docsDir, "online")

    // Base classpath is Android SDK, sub-projects add their own.
    classpath = project.ext.androidJar

    def hdfOption = new DoclavaMultilineJavadocOptionFileOption('hdf')
    hdfOption.add(
            ['android.whichdoc', 'online'],
            ['android.hasSamples', 'true']);

    // Default hidden errors + hidden superclass (111) and
    // deprecation mismatch (113) to match framework docs.
    final def hidden = [105, 107, 111, 112, 113, 115, 116, 121]

    doclavaErrors = (101..122) - hidden
    doclavaWarnings = []
    doclavaHidden += hidden

    options {
        addStringOption "templatedir",
                "${project.rootDir}/../../build/tools/droiddoc/templates-sdk"
        addStringOption "federate Android", "http://developer.android.com"
        addStringOption "stubpackages", "android.support.*"
        addStringOption "samplesdir", "${project.rootDir}/samples"
        addOption hdfOption
    }

    exclude '**/BuildConfig.java'
}

JDiffTask createApiDiffsTask(String taskName, File oldApiXml, File newApiXml, File outDir,
                             Configuration jdiff, Task... dependencies) {
    return tasks.create(name: taskName, type: JDiffTask.class) {
        dependsOn jdiff
        dependsOn dependencies

        docletpath = jdiff.resolve()

        oldApiXmlFile oldApiXml
        newApiXmlFile newApiXml
        destinationDir = outDir

        // This prefix is based on the assumption that the output diffs will
        // ultimately land in frameworks/base/docs/html/sdk/support_api_diff/.
        newJavadocPrefix = "../reference/"
    }
}

// Generates API files.
task generateApi(type: DoclavaTask, dependsOn: configurations.doclava) {
    docletpath = configurations.doclava.resolve()
    destinationDir = project.docsDir

    // Base classpath is Android SDK, sub-projects add their own.
    classpath = project.ext.androidJar

    apiFile = new File(project.docsDir, 'release/current.txt')
    removedApiFile = new File(project.docsDir, 'release/removed.txt')
    generateDocs = false

    options {
        addStringOption "templatedir",
                "${project.rootDir}/../../build/tools/droiddoc/templates-sdk"
        addStringOption "federate Android", "http://developer.android.com"
        addStringOption "stubpackages", "android.support.*"
    }
    exclude '**/BuildConfig.java'
    exclude '**/R.java'
}

// Copies generated API files to current version.
task updateApi(type: UpdateApiTask, dependsOn: generateApi) {
    newApiFile = new File(project.docsDir, 'release/current.txt')
    oldApiFile = new File(project.rootDir, 'api/current.txt')
    newRemovedApiFile = new File(project.docsDir, 'release/removed.txt')
    oldRemovedApiFile = new File(project.rootDir, 'api/removed.txt')
}

// Checks generated API files against current version.
task checkApi(type: CheckApiTask, dependsOn: generateApi) {
    doclavaClasspath = generateApi.docletpath

    checkApiTaskPath = name
    updateApiTaskPath = updateApi.name

    // Check that the API we're building hasn't changed from the development
    // version. These typed of changes require an explicit API file update.
    checkApiErrors = (2..30)-[22]
    checkApiWarnings = []
    checkApiHidden = [22]

    newApiFile = new File(project.docsDir, 'release/current.txt')
    oldApiFile = new File(project.rootDir, 'api/current.txt')
    newRemovedApiFile = new File(project.docsDir, 'release/removed.txt')
    oldRemovedApiFile = new File(project.rootDir, 'api/removed.txt')
}
createArchive.dependsOn checkApi

// Checks generated API files against current version.
task checkApiStable(type: CheckApiTask, dependsOn: generateApi) {
    doclavaClasspath = generateApi.docletpath

    checkApiTaskPath = name
    updateApiTaskPath = updateApi.name

    // Check that the API we're building hasn't broken the last-released
    // library version. These types of changes are forbidden.
    checkApiErrors = (7..18)
    checkApiWarnings = [23, 24]
    checkApiHidden = (2..6) + (19..22) + (25..30)

    newApiFile = new File(project.docsDir, 'release/current.txt')
    oldApiFile = getReleasedApiFile()
    newRemovedApiFile = new File(project.docsDir, 'release/removed.txt')
    oldRemovedApiFile = new File(project.rootDir, 'api/removed.txt')
}
checkApi.dependsOn checkApiStable

/**
 * Converts the <code>toApi</code>.txt file (or current.txt if not explicitly
 * defined using -PtoAPi=<file>) to XML format for use by JDiff.
 */
task newApiXml(type: ApiXmlConversionTask, dependsOn: configurations.doclava) {
    classpath configurations.doclava.resolve()

    if (project.hasProperty("toApi")) {
        // Use an explicit API file.
        inputApiFile = new File(project.rootDir, "api/${toApi}.txt")
    } else {
        // Use the current API file (e.g. current.txt).
        inputApiFile = generateApi.apiFile
        dependsOn generateApi
    }

    int lastDot = inputApiFile.name.lastIndexOf('.')
    outputApiXmlFile = new File(project.docsDir,
            "release/" + inputApiFile.name.substring(0, lastDot) + ".xml")
}

/**
 * Converts the <code>fromApi</code>.txt file (or the most recently released
 * X.Y.Z.txt if not explicitly defined using -PfromAPi=<file>) to XML format
 * for use by JDiff.
 */
task oldApiXml(type: ApiXmlConversionTask, dependsOn: configurations.doclava) {
    classpath configurations.doclava.resolve()

    if (project.hasProperty("fromApi")) {
        // Use an explicit API file.
        inputApiFile = new File(project.rootDir, "api/${fromApi}.txt")
    } else if (project.hasProperty("toApi") && toApi.matches(~/(\d+\.){2}\d+/)) {
        // If toApi matches released API (X.Y.Z) format, use the most recently
        // released API file prior to toApi.
        inputApiFile = getReleasedApiFile(toApi)
    } else {
        // Use the most recently released API file.
        inputApiFile = getReleasedApiFile();
    }

    int lastDot = inputApiFile.name.lastIndexOf('.')
    outputApiXmlFile = new File(project.docsDir,
            "release/" + inputApiFile.name.substring(0, lastDot) + ".xml")
}

/**
 * Generates API diffs.
 * <p>
 * By default, diffs are generated for the delta between current.txt and the
 * next most recent X.Y.Z.txt API file. Behavior may be changed by specifying
 * one or both of -PtoApi and -PfromApi.
 * <p>
 * If both fromApi and toApi are specified, diffs will be generated for
 * fromApi -> toApi. For example, 25.0.0 -> 26.0.0 diffs could be generated by
 * using:
 * <br><code>
 *   ./gradlew generateDiffs -PfromApi=25.0.0 -PtoApi=26.0.0
 * </code>
 * <p>
 * If only toApi is specified, it MUST be specified as X.Y.Z and diffs will be
 * generated for (release before toApi) -> toApi. For example, 24.2.0 -> 25.0.0
 * diffs could be generated by using:
 * <br><code>
 *   ./gradlew generateDiffs -PtoApi=25.0.0
 * </code>
 * <p>
 * If only fromApi is specified, diffs will be generated for fromApi -> current.
 * For example, lastApiReview -> current diffs could be generated by using:
 * <br><code>
 *   ./gradlew generateDiffs -PfromApi=lastApiReview
 * </code>
 * <p>
 */
task generateDiffs(type: JDiffTask, dependsOn: [configurations.jdiff, configurations.doclava,
                                                oldApiXml, newApiXml, generateDocs]) {
    // Base classpath is Android SDK, sub-projects add their own.
    classpath = project.ext.androidJar

    // JDiff properties.
    oldApiXmlFile = oldApiXml.outputApiXmlFile
    newApiXmlFile = newApiXml.outputApiXmlFile
    newJavadocPrefix = "../../../../reference/"

    String newApi = newApiXmlFile.name
    int lastDot = newApi.lastIndexOf('.')
    newApi = newApi.substring(0, lastDot)

    // Javadoc properties.
    docletpath = configurations.jdiff.resolve()
    destinationDir = new File(project.docsDir, "online/sdk/support_api_diff/$newApi")
    title = "Support&nbsp;Library&nbsp;API&nbsp;Differences&nbsp;Report"

    exclude '**/BuildConfig.java'
    exclude '**/R.java'
}

/**
 * Returns the most recently released API, optionally restricting to APIs
 * before <code>beforeApi</code>.
 *
 * @param beforeApi the API to find an API file before, ex. 25.0.0
 * @return the most recently released API file
 */
File getReleasedApiFile(String beforeApi = null) {
    String beforeApiFileName = beforeApi != null ? beforeApi + ".txt" : null
    File lastReleasedApiFile = null
    File apiDir = new File(project.rootDir, 'api')

    apiDir.eachFileMatch FileType.FILES, ~/(\d+\.){3}txt/, { File apiFile ->
        // Is the current API file newer than the last one we saw?
        if (lastReleasedApiFile == null || apiFile.name > lastReleasedApiFile.name) {
            // Is the current API file older than the "before" API?
            if (beforeApiFileName == null || apiFile.name < beforeApiFileName) {
                lastReleasedApiFile = apiFile
            }
        }
    }

    return lastReleasedApiFile
}

subprojects {
    // Only modify Android projects.
    if (project.name.equals('doclava') || project.name.equals('jdiff')) return;

    // Current SDK is set in studioCompat.gradle.
    project.ext.currentSdk = gradle.ext.currentSdk
    apply plugin: 'maven'

    version = rootProject.ext.supportVersion
    group = 'com.android.support'

    repositories {
        maven { url "${project.parent.projectDir}/../../prebuilts/tools/common/m2/repository" }
        maven { url "${project.parent.projectDir}/../../prebuilts/tools/common/m2/internal" }
        maven { url "${project.parent.projectDir}/../../prebuilts/maven_repo/android" }
    }

    project.plugins.whenPluginAdded { plugin ->
        def isAndroidLibrary = "com.android.build.gradle.LibraryPlugin".equals(plugin.class.name)
        def isAndroidApp = "com.android.build.gradle.AppPlugin".equals(plugin.class.name)
        def isJavaLibrary = "org.gradle.api.plugins.JavaPlugin".equals(plugin.class.name)

        if (isAndroidLibrary || isAndroidApp) {
            project.android.buildToolsVersion = rootProject.buildToolsVersion

            // Enable code coverage for debug builds only if we are not running inside the IDE,
            // since enabling coverage reports breaks the method parameter resolution in the IDE
            // debugger.
            project.android.buildTypes.debug.testCoverageEnabled = !hasProperty('android.injected.invoked.from.ide')

            // Copy the class files in a jar to be later used to generate code coverage report
            project.android.testVariants.all { v ->
                // check if the variant has any source files
                // and test coverage is enabled
                if (v.buildType.testCoverageEnabled
                        && v.sourceSets.any { !it.java.sourceFiles.isEmpty() }) {
                    def jarifyTask = project.tasks.create(
                            name: "package${v.name.capitalize()}ClassFilesForCoverageReport",
                            type: Jar) {
                        from v.testedVariant.javaCompile.destinationDir
                        exclude "**/R.class"
                        exclude "**/R\$*.class"
                        destinationDir file(project.distDir)
                        archiveName "${project.archivesBaseName}-${v.baseName}-allclasses.jar"
                    }
                    def jacocoAntConfig =
                            project.configurations[JacocoPlugin.ANT_CONFIGURATION_NAME]
                    def jacocoAntArtifacts = jacocoAntConfig.resolvedConfiguration.resolvedArtifacts
                    def version = jacocoAntArtifacts.find { "org.jacoco.ant".equals(it.name) }
                            .moduleVersion.id.version
                    def collectJacocoAntPackages = project.tasks.create(
                            name: "collectJacocoAntPackages",
                            type: Jar) {
                        from (jacocoAntArtifacts.collect { zipTree(it.getFile()) }) {
                            // exclude all the signatures the jar might have
                            exclude "META-INF/*.SF"
                            exclude "META-INF/*.DSA"
                            exclude "META-INF/*.RSA"
                        }
                        destinationDir file(project.distDir)
                        archiveName "jacocoant-" + version  + ".jar"
                    }
                    v.assemble.dependsOn jarifyTask, collectJacocoAntPackages
                }
            }

            // Enforce NewApi lint check as fatal.
            project.android.lintOptions.check 'NewApi'
            project.android.lintOptions.fatal 'NewApi'
            project.parent.lint.dependsOn project.lint
        }

        if (isAndroidLibrary || isJavaLibrary) {
            // Add library to the aggregate dependency report.
            task allDeps(type: DependencyReportTask) {}

            // Create release and separate zip task for library.
            task release(type: Upload) {
                configuration = configurations.archives
                repositories {
                    mavenDeployer {
                        repository(url: uri("$rootProject.ext.supportRepoOut"))

                        // Disable unique names for SNAPSHOTS so they can be updated in place.
                        setUniqueVersion(false)
                        doLast {
                            // Remove any invalid maven-metadata.xml files that may have been
                            // created for SNAPSHOT versions that are *not* uniquely versioned.
                            pom*.each { pom ->
                                if (pom.version.endsWith('-SNAPSHOT')) {
                                    final File artifactDir = new File(
                                            rootProject.ext.supportRepoOut,
                                            pom.groupId.replace('.', '/')
                                                    + '/' + pom.artifactId
                                                    + '/' + pom.version)
                                    delete fileTree(dir: artifactDir,
                                            include: 'maven-metadata.xml*')
                                }
                            }
                        }
                    }
                }
            }

            def deployer = release.repositories.mavenDeployer
            deployer.pom*.whenConfigured { pom ->
                pom.dependencies.findAll { dep ->
                    dep.groupId == 'com.android.support' && dep.artifactId != 'support-annotations'
                }*.type = 'aar'
            }

            ext.versionDir = {
                def groupDir = new File(rootProject.ext.supportRepoOut,
                        project.group.replace('.','/'))
                def artifactDir = new File(groupDir, archivesBaseName)
                return new File(artifactDir, version)
            }

            task generateSourceProps(dependsOn: createRepository)
            generateSourceProps.doLast({
                def content = "Maven.GroupId=$deployer.pom.groupId\n" +
                        "Maven.ArtifactId=$deployer.pom.artifactId\n" +
                        "Maven.Version=$deployer.pom.version\n" +
                        "Extra.VendorDisplay=Android\n" +
                        "Extra.VendorId=android\n" +
                        "Pkg.Desc=$project.name\n" +
                        "Pkg.Revision=1\n" +
                        "Maven.Dependencies=" +
                        String.join(",", project.configurations.compile.allDependencies.collect {
                            def p = parent.findProject(it.name)
                            return p ? "$p.group:$p.archivesBaseName:$p.version" : null
                        }.grep()) +
                        "\n"
                Files.write(content, new File(versionDir(), 'source.properties'), Charsets.UTF_8)
            })

            task createSeparateZip(type: Zip, dependsOn: generateSourceProps)  {
                into archivesBaseName
                destinationDir project.parent.ext.distDir
                baseName = project.group
                version = project.parent.ext.buildNumber
            }
            project.parent.createArchive.dependsOn createSeparateZip

            // Before the upload, make sure the repo is ready.
            release.dependsOn rootProject.tasks.prepareRepo

            // Make the mainupload depend on this one.
            mainUpload.dependsOn release
        }
    }

    project.afterEvaluate {
        // The archivesBaseName isn't available intially, so set it now
        def createZipTask = project.tasks.findByName("createSeparateZip")
        if (createZipTask != null) {
            createZipTask.appendix = archivesBaseName
            createZipTask.from versionDir()
        }

        // Copy instrumentation test APK into the dist dir
        def assembleTestTask = project.tasks.findByPath('assembleAndroidTest')
        if (assembleTestTask != null) {
            assembleTestTask.doLast {
                // If the project actually has some instrumentation tests, copy its APK
                if (!project.android.sourceSets.androidTest.java.sourceFiles.isEmpty()) {
                    def pkgTask = project.tasks.findByPath('packageDebugAndroidTest')
                    copy {
                        from(pkgTask.outputFile)
                        into(rootProject.ext.testApkDistOut)
                    }
                }
            }
        }
    }

    project.afterEvaluate { p ->
        // remove dependency on the test so that we still get coverage even if some tests fail
        p.tasks.findAll { it instanceof JacocoReportTask}.each { task ->
            def toBeRemoved = new ArrayList()
            def dependencyList = task.taskDependencies.values
            dependencyList.each { dep ->
                if (dep instanceof String) {
                    def t = tasks.findByName(dep)
                    if (t instanceof DeviceProviderInstrumentTestTask) {
                        toBeRemoved.add(dep)
                        task.mustRunAfter(t)
                    }
                }
            }
            toBeRemoved.each { dep ->
                dependencyList.remove(dep)
            }
        }
    }

    project.afterEvaluate { p ->
        if (p.hasProperty('android')
                && p.android.hasProperty('libraryVariants')
                && !(p.android.hasProperty('noDocs') && p.android.noDocs)) {
            p.android.libraryVariants.all { v ->
                if (v.name == 'release') {
                    registerForDocsTask(rootProject.generateDocs, p, v)
                    registerForDocsTask(rootProject.generateApi, p, v)
                    registerForDocsTask(rootProject.generateDiffs, p, v)
                }
            }
        }
    }

    // Update the version meta-data in each Manifest
    project.afterEvaluate { p ->
        if (p.hasProperty('android')) {
            p.android.defaultConfig.manifestPlaceholders =
                    ["support-version": rootProject.ext.supportVersion]
        }
    }
}

project.gradle.buildFinished { buildResult ->
    if (buildResult.getFailure() != null) {
        println()
        println 'Build failed. Possible causes include:'
        println '    1) Bad codes'
        println '    2) Out of date prebuilts in prebuilts/sdk'
        println '    3) Need to update the compileSdkVersion in a library\'s build.gradle'
        println()
    }
}
