{# Copyright 2016 The Chromium Authors. All rights reserved. #}
{# Use of this source code is governed by a BSD-style license that can be #}
{# found in the LICENSE file. #}
{% macro expand_sourceset(variables, prefix) %}
{% if variables is defined %}
        {{ prefix }} {
{% if variables.android_manifest is defined %}
            manifest.srcFile "{{ variables.android_manifest }}"
{% endif %}
{% if variables.java_dirs is defined %}
            java.srcDirs = [
{% for path in variables.java_dirs %}
                "{{ path }}",
{% endfor %}
            ]
{% endif %}
{% if variables.java_excludes is defined %}
            java.filter.exclude(
{% for path in variables.java_excludes %}
                "{{ path }}",
{% endfor %}
            )
{% endif %}
{% if variables.jni_libs is defined %}
            jniLibs.srcDirs = [
{% for path in variables.jni_libs %}
                "{{ path }}",
{% endfor %}
            ]
{% endif %}
{% if variables.res_dirs is defined %}
            res.srcDirs = [
{% for path in variables.res_dirs %}
                "{{ path }}",
{% endfor %}
            ]
{% endif %}
        }
{% endif %}
{% endmacro %}
// Generated by //build/android/generate_gradle.py

{% if template_type in ('android_library', 'android_junit') %}
apply plugin: "com.android.library"
{% elif template_type == 'android_apk' %}
apply plugin: "com.android.application"
{% endif %}

android {
    compileSdkVersion "{{ compile_sdk_version }}"
    buildToolsVersion "{{ build_tools_version }}"

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    sourceSets {
{% for name in ['main', 'test', 'androidTest', 'debug', 'release'] %}
        {{ name }} {
            aidl.srcDirs = []
            assets.srcDirs = []
            java.srcDirs = []
            jni.srcDirs = []
            renderscript.srcDirs = []
            res.srcDirs = []
            resources.srcDirs = []
        }
{% endfor %}

{{ expand_sourceset(main, 'main') }}
{{ expand_sourceset(test, 'test') }}

{% if android_test is defined %}
{% for t in android_test %}
{{ expand_sourceset(t, 'androidTest') }}
{% endfor %}
    }
{% endif %}

    defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }
}

{% include 'dependencies.jinja' %}

afterEvaluate {
    def tasksToDisable = tasks.findAll {
        return (it.name.equals('generateDebugSources')  // causes unwanted AndroidManifest.java
                || it.name.equals('generateReleaseSources')
                || it.name.endsWith('BuildConfig')  // causes unwanted BuildConfig.java
                || it.name.equals('preDebugAndroidTestBuild')
{% if not use_gradle_process_resources %}
                || it.name.endsWith('Assets')
                || it.name.endsWith('Resources')
                || it.name.endsWith('ResValues')
{% endif %}
                || it.name.endsWith('Aidl')
                || it.name.endsWith('Renderscript')
                || it.name.endsWith('Shaders'))
    }
    tasksToDisable.each { Task task ->
      task.enabled = false
    }
{% if bootclasspath is defined %}
    tasks.withType(JavaCompile) {
      options.bootClasspath = "{{ bootclasspath }}"
    }
{% endif %}
}
