summaryrefslogtreecommitdiffstats
path: root/mobile/android/app/build.gradle
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/android/app/build.gradle')
-rw-r--r--mobile/android/app/build.gradle406
1 files changed, 406 insertions, 0 deletions
diff --git a/mobile/android/app/build.gradle b/mobile/android/app/build.gradle
new file mode 100644
index 000000000..18586cadb
--- /dev/null
+++ b/mobile/android/app/build.gradle
@@ -0,0 +1,406 @@
+buildDir "${topobjdir}/gradle/build/mobile/android/app"
+
+apply plugin: 'android-sdk-manager' // Must come before 'com.android.*'.
+apply plugin: 'com.android.application'
+apply plugin: 'checkstyle'
+
+android {
+ compileSdkVersion 23
+ buildToolsVersion mozconfig.substs.ANDROID_BUILD_TOOLS_VERSION
+
+ defaultConfig {
+ targetSdkVersion 23
+ minSdkVersion 15
+ applicationId mozconfig.substs.ANDROID_PACKAGE_NAME
+ testApplicationId 'org.mozilla.roboexample.test'
+ testInstrumentationRunner 'org.mozilla.gecko.FennecInstrumentationTestRunner'
+ manifestPlaceholders = [
+ ANDROID_PACKAGE_NAME: mozconfig.substs.ANDROID_PACKAGE_NAME,
+ MOZ_ANDROID_MIN_SDK_VERSION: mozconfig.substs.MOZ_ANDROID_MIN_SDK_VERSION,
+ MOZ_ANDROID_SHARED_ID: "${mozconfig.substs.ANDROID_PACKAGE_NAME}.sharedID",
+ ]
+ // 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"
+ }
+
+ lintOptions {
+ abortOnError true
+ }
+
+ buildTypes {
+ release {
+ shrinkResources true
+ minifyEnabled true
+ proguardFile "${topsrcdir}/mobile/android/config/proguard/proguard.cfg"
+ }
+ }
+
+ productFlavors {
+ // For API 21+ - with multi dex, this will be faster for local development.
+ local {
+ // For multi dex, 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
+ // We only call `MultiDex.install()` for the automation build flavor
+ // so this may not work. However, I don't think the multidex support
+ // library is necessary for 21+, so I expect that it will work.
+ multiDexEnabled true
+ }
+ }
+ // For API < 21 - does not support multi dex because local development
+ // is slow in that case. Most builds will not require multi dex so this
+ // should not be an issue.
+ localOld {
+ }
+ // Automation builds.
+ automation {
+ dexOptions {
+ // As of FF48 on beta, the "test", "lint", etc. treeherder jobs fail because they
+ // exceed the method limit. Beta includes Adjust and its GPS dependencies, which
+ // increase the method count & explain the failures. Furthermore, this error only
+ // occurs on debug builds because we don't proguard.
+ //
+ // We enable multidex as an easy, quick-fix with minimal side effects but before we
+ // move to gradle for our production builds, we should re-evaluate this decision
+ // (bug 1286677).
+ multiDexEnabled true
+ }
+ }
+ }
+
+ sourceSets {
+ main {
+ manifest.srcFile "${project.buildDir}/generated/source/preprocessed_manifest/AndroidManifest.xml"
+
+ aidl {
+ srcDir "${topsrcdir}/mobile/android/base/aidl"
+ }
+
+ java {
+ srcDir "${topsrcdir}/mobile/android/base/java"
+ srcDir "${topsrcdir}/mobile/android/search/java"
+ srcDir "${topsrcdir}/mobile/android/javaaddons/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_WEBRTC) {
+ srcDir "${topsrcdir}/media/webrtc/trunk/webrtc/modules/audio_device/android/java/src"
+ srcDir "${topsrcdir}/media/webrtc/trunk/webrtc/modules/video_capture/android/java/src"
+ srcDir "${topsrcdir}/media/webrtc/trunk/webrtc/modules/video_render/android/java/src"
+ }
+
+ 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_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/base/resources"
+ 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 && !mozconfig.substs.MOZ_ANDROID_PACKAGE_INSTALL_BOUNCER) {
+ // If we are packaging the bouncer, it will have the distribution, so don't put
+ // it in the main APK as well.
+ srcDir "${mozconfig.substs.MOZ_ANDROID_DISTRIBUTION_DIRECTORY}/assets"
+ }
+ srcDir "${topsrcdir}/mobile/android/app/assets"
+ }
+ }
+
+ test {
+ java {
+ srcDir "${topsrcdir}/mobile/android/tests/background/junit4/src"
+
+ if (!mozconfig.substs.MOZ_ANDROID_GCM) {
+ exclude 'org/mozilla/gecko/gcm/**/*.java'
+ exclude 'org/mozilla/gecko/push/**/*.java'
+ }
+ }
+ resources {
+ srcDir "${topsrcdir}/mobile/android/tests/background/junit4/resources"
+ }
+ }
+
+ androidTest {
+ java {
+ srcDir "${topsrcdir}/mobile/android/tests/browser/robocop/src"
+ srcDir "${topsrcdir}/mobile/android/tests/background/junit3/src"
+ srcDir "${topsrcdir}/mobile/android/tests/browser/junit3/src"
+ srcDir "${topsrcdir}/mobile/android/tests/javaddons/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:multidex:1.0.0'
+
+ 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}"
+ compile "com.android.support:palette-v7:${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-ads:${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-multidex) 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'
+ automationCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta1'
+ testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta1'
+
+ compile project(':geckoview')
+ compile project(':thirdparty')
+
+ 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/'
+ // 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") {
+ // All other preprocessed code is included in the geckoview project.
+ include '**/AdjustConstants.java'
+ }
+}
+
+// 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
+
+ // Automation builds don't include Gecko binaries, since those binaries are
+ // not produced until after build time (at package time). 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 productFlavor = 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 (!productFlavor.equals('automation')) {
+ configureVariantWithGeckoBinaries(variant)
+ }
+}
+
+apply plugin: 'spoon'
+
+spoon {
+ // For now, let's be verbose.
+ debug = true
+ // It's not helpful to pass when we don't have a device connected.
+ failIfNoDeviceConnected = true
+
+ def spoonPackageName
+ if (gradle.startParameter.taskNames.contains('runBrowserTests')) {
+ spoonPackageName = 'org.mozilla.tests.browser.junit3'
+ }
+ if (gradle.startParameter.taskNames.contains('runBackgroundTests')) {
+ spoonPackageName = 'org.mozilla.gecko.background'
+ }
+ if (project.hasProperty('spoonPackageName')) {
+ // Command line overrides everything.
+ spoonPackageName = project.spoonPackageName
+ }
+ if (spoonPackageName) {
+ instrumentationArgs = ['-e', "package=${spoonPackageName}".toString()]
+ }
+}
+
+// See discussion at https://github.com/stanfy/spoon-gradle-plugin/issues/9.
+afterEvaluate {
+ tasks["spoonLocal${android.testBuildType.capitalize()}AndroidTest"].outputs.upToDateWhen { false }
+
+ // This is an awkward way to define different sets of instrumentation tests.
+ // The task name itself is fished at runtime and the package name configured
+ // in the spoon configuration.
+ task runBrowserTests {
+ dependsOn tasks["spoonLocalOldDebugAndroidTest"]
+ }
+ task runBackgroundTests {
+ dependsOn tasks["spoonLocalOldDebugAndroidTest"]
+ }
+}
+
+// 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:lintAutomationDebug':
+ def url = "${artifactRootUrl}/public/android/lint/lint-results-automationDebug.html"
+ println "TEST-UNEXPECTED-FAIL | android-lint | Lint found errors in the project; aborting build. See the report at: $url"
+ break
+
+ case ':app:testAutomationDebugUnitTest':
+ def url = "${artifactRootUrl}/public/android/unittest/automationDebug/index.html"
+ println "TEST-UNEXPECTED-FAIL | android-test | There were failing tests. 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))
+}