Skip to content

Working on unreleased application services code in android components or reference browser

Vlad Filippov edited this page Dec 18, 2018 · 2 revisions

OLD DOC:

This is a companion to the equivalent instructions for the android-components repository.

Modern Gradle supports composite builds, which allows to substitute on-disk projects for binary publications. Composite builds transparently accomplish what is usually a frustrating loop of:

  1. change library
  2. publishing library snapshot to the local Maven repository
  3. consume library snapshot in application

Preparation

Let's assume that the (two or) three projects are siblings, like:

git clone https://github.com/mozilla/application-services
git clone https://github.com/mozilla-mobile/android-components
git clone https://github.com/mozilla-mobile/reference-browser

Substituting projects

In android-components/settings.gradle:

includeBuild('../application-services') {
    dependencySubstitution {
        // As required.
        substitute module('org.mozilla.fxaclient:fxaclient') with project(':fxa-client-library')
        substitute module('org.mozilla.sync15:logins') with project(':logins-library')
        substitute module('org.mozilla.places:places') with project(':places-library')
    }
}

In reference-browser/settings.gradle:

includeBuild('../android-components') {
    dependencySubstitution {
        // As required.
        substitute module('org.mozilla.components:service-firefox-accounts') with project(':service-firefox-accounts')
    }
}

Caveat

There's a big gotcha with library substitutions: the Gradle build computes lazily, and AARs don't include their transitive dependencies' JNI libraries. This means that in android-components, ./gradlew :service-sync-logins:assembleDebug does not invoke :logins-library:cargoBuild, even though :service-sync-logins depends on the substitution for :logins-library and even if the inputs to Cargo have changed! It's the final consumer of the :service-sync-logins project (or publication) that will incorporate the JNI libraries.

In practice that means you should always be targeting something that produces an APK: a test, a sample module, or the Reference Browser itself. Then you should find that the cargoBuild tasks are invoked as you expect.

Notes

  1. Transitive substitutions (as shown above) work but require newer Gradle versions (4.10+).
  2. Android Studio happily imports substitutions (and transitive substitutions). However, the project list gets very large.