diff --git a/README.md b/README.md index fcbf52d67..e76431cfc 100644 --- a/README.md +++ b/README.md @@ -100,14 +100,19 @@ cp ./extra/wavesdk/build.gradle ./third_party/wavesdk Make certain to set the build flavor to `wavevrDebug` in Android Studio before building the project. -## Using a custom GeckoView +## Local Development -Create a file called `user.properties` in the top-level project directory. Add a variable called `geckoViewLocalArm` and `geckoViewLocalX86` and set it to the location of your locally built AAR: +### Dependency substitutions + +You might be interested in building this project against local versions of some of the dependencies. +This could be done either by using a [local maven repository](https://mozilla-mobile.github.io/android-components/contributing/testing-components-inside-app) (quite cumbersome), or via Gradle's [dependency substitutions](https://docs.gradle.org/current/userguide/customizing_dependency_resolution_behavior.html) (not at all cumbersome!). + +Currently, the substitution flow is streamlined for some of the core dependencies via configuration flags in `local.properties`. You can build against a local checkout of the following dependencies by specifying their local paths: +- [GeckoView](https://hg.mozilla.org/mozilla-central), specifying its path via `dependencySubstitutions.geckoviewTopsrcdir=/path/to/mozilla-central` (and, optionally, `dependencySubstitutions.geckoviewTopobjdir=/path/to/topobjdir`). See [Bug 1533465](https://bugzilla.mozilla.org/show_bug.cgi?id=1533465). + - This assumes that you have built, packaged, and published your local GeckoView -- but don't worry, the dependency substitution script has the latest instructions for doing that. + +Do not forget to run a Gradle sync in Android Studio after changing `local.properties`. If you specified any substitutions, they will be reflected in the modules list, and you'll be able to modify them from a single Android Studio window. -```ini -geckoViewLocalArm=/path/to/your/build/geckoview-nightly-armeabi-v7a-64.0.20180924100359.aar -geckoViewLocalX86=/path/to/your/build/geckoview-nightly-x86-64.0.20180924100359.aar -``` ## Install dev and production builds on device simultaneously @@ -142,16 +147,6 @@ npm run compress Enable [USB Remote Debugging](https://github.com/MozillaReality/FirefoxReality/wiki/Developer-Info#remote-debugging) on the device. -### `Could not get unknown property 'geckoViewLocal' for build 'FirefoxReality'[...]` - -```bash -./mach build -./mach package -./mach android archive-geckoview -find $objdir -name *.aar -echo "geckoViewLocalArm=$objdir/gradle/build/mobile/android/geckoview/outputs/aar/geckoview-official-withGeckoBinaries-noMinApi-release.aar" > $FirefoxReality/user.properties -``` - ### **`Firefox > Web Developer > WebIDE > Performance`** gets stuck with greyed out "stop and show profile" Restart FxR and close and re-open the WebIDE page. diff --git a/app/build.gradle b/app/build.gradle index c167ad0ac..212411d7b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -12,22 +12,22 @@ def getGitHash = { -> } def getCrashRestartDisabled = { -> - if (gradle.hasProperty("disableCrashRestart")) { - return gradle.disableCrashRestart + if (gradle.hasProperty("userProperties.disableCrashRestart")) { + return gradle."userProperties.disableCrashRestart" } return "false" } def getDevApplicationIdSuffix = { -> - if (gradle.hasProperty("simultaneousDevProduction")) { - return gradle.simultaneousDevProduction == "true" ? ".dev" : "" + if (gradle.hasProperty("userProperties.simultaneousDevProduction")) { + return gradle."userProperties.simultaneousDevProduction" == "true" ? ".dev" : "" } return "" } def getUseDebugSigningOnRelease = { -> - if (gradle.hasProperty("useDebugSigningOnRelease")) { - return gradle.useDebugSigningOnRelease == "true" + if (gradle.hasProperty("userProperties.useDebugSigningOnRelease")) { + return gradle."userProperties.useDebugSigningOnRelease" == "true" } return false } @@ -59,7 +59,7 @@ android { } } - if (gradle.hasProperty('taskclusterBuild')) { + if (gradle.hasProperty('userProperties.taskclusterBuild')) { project.archivesBaseName = "FirefoxReality-$defaultConfig.versionName-$generatedVersionCode" defaultConfig.versionCode = generatedVersionCode } else { @@ -476,21 +476,25 @@ if (findProject(':wavesdk')) { } } -if (findProject(':geckoview-local')) { - dependencies { - implementation project(':geckoview-local') - implementation deps.snakeyaml - } -} else { - dependencies { - // To see what the latest geckoview-nightly version is go here: - // https://maven.mozilla.org/?prefix=maven2/org/mozilla/geckoview/geckoview-nightly-armeabi-v7a/ - armImplementation deps.gecko_view.nightly_armv7a - arm64Implementation deps.gecko_view.nightly_arm64 - x86_64Implementation deps.gecko_view.nightly_x86_64 - } +dependencies { + // To see what the latest geckoview-nightly version is go here: + // https://maven.mozilla.org/?prefix=maven2/org/mozilla/geckoview/geckoview-nightly-armeabi-v7a/ + armImplementation deps.gecko_view.nightly_armv7a + arm64Implementation deps.gecko_view.nightly_arm64 + x86_64Implementation deps.gecko_view.nightly_x86_64 } +if (gradle.hasProperty('geckoViewLocalArm') || gradle.hasProperty('geckoViewLocalX86')) { + throw new GradleException("geckoViewLocal{Arm,X86} are deprecated: use geckoViewLocalTopsrcdir and geckoViewLocalTopobjdir") +} + +if (gradle.hasProperty('localProperties.dependencySubstitutions.geckoviewTopsrcdir')) { + if (gradle.hasProperty('localProperties.dependencySubstitutions.geckoviewTopobjdir')) { + ext.topobjdir = gradle."localProperties.dependencySubstitutions.geckoviewTopobjdir" + } + ext.topsrcdir = gradle."localProperties.dependencySubstitutions.geckoviewTopsrcdir" + apply from: "${topsrcdir}/substitute-local-geckoview.gradle" +} // ------------------------------------------------------------------------------------------------- // Dynamically set versionCode (See tools/build/versionCode.gradle @@ -498,7 +502,7 @@ if (findProject(':geckoview-local')) { android.applicationVariants.all { variant -> def buildType = variant.buildType.name - if (gradle.hasProperty('taskclusterBuild')) { + if (gradle.hasProperty('userProperties.taskclusterBuild')) { def versionCode = generatedVersionCode // The Google Play Store does not allow multiple APKs for the same app that all have the diff --git a/geckoview-local/build.gradle b/geckoview-local/build.gradle deleted file mode 100644 index 241e18bfe..000000000 --- a/geckoview-local/build.gradle +++ /dev/null @@ -1,45 +0,0 @@ -import java.util.regex.Matcher -import java.util.regex.Pattern - -configurations.maybeCreate('default') - -def getCurrentFlavor() { - Gradle gradle = getGradle() - String taskReqStr = gradle.getStartParameter().getTaskRequests().toString() - Pattern pattern - if (taskReqStr.contains("assemble")) { - pattern = Pattern.compile("assemble(\\w+)(Release|Debug)") - } else { - pattern = Pattern.compile("generate(\\w+)(Release|Debug)") - } - Matcher matcher = pattern.matcher(taskReqStr) - if (matcher.find()) { - String flavor = matcher.group(1) - // This makes first character to lowercase. - char[] c = flavor.toCharArray() - c[0] = Character.toLowerCase(c[0]) - flavor = new String(c) - println "getCurrentFlavor:" + flavor - return flavor - } else { - println "getCurrentFlavor:cannot_find_current_flavor" - return "" - } -} - -def addArtifact(path) { - def aar = new File(path) - if (aar.exists()) { - artifacts.add('default', aar) - } else { - throw new GradleException('Failed to find GeckoView AAR at: ' + path) - } -} - -def flavor = getCurrentFlavor() -if (flavor.contains("Arm") && gradle.hasProperty('geckoViewLocalArm')) { - addArtifact(gradle.geckoViewLocalArm) - -} else if (flavor.contains("X86") && gradle.hasProperty('geckoViewLocalX86')) { - addArtifact(gradle.geckoViewLocalX86) -} diff --git a/servo/build.gradle b/servo/build.gradle index 3ce8da0d0..da480bf71 100644 --- a/servo/build.gradle +++ b/servo/build.gradle @@ -24,14 +24,8 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') } -if (findProject(':geckoview-local')) { - dependencies { - compileOnly project(':geckoview-local') - } -} else { - dependencies { - compileOnly deps.gecko_view.nightly_armv7a - } +dependencies { + compileOnly deps.gecko_view.nightly_armv7a } if (gradle.hasProperty('servoViewLocal')) { diff --git a/settings.gradle b/settings.gradle index 1b677d637..7b80625ac 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,26 +7,38 @@ if (wavebuild.exists()) { project(':wavesdk').projectDir = new File('third_party/wavesdk/') } -def userPropertiesFile = new File('user.properties') -if (userPropertiesFile.exists()) { - println("Loading user.properties") - def props = new Properties() - userPropertiesFile.withInputStream { - props.load(it) - } - props.each { prop -> - println(prop.key + " = " + prop.value) - gradle.ext.set(prop.key, prop.value) - } - if (gradle.hasProperty('geckoViewLocalArm') || gradle.hasProperty('geckoViewLocalX86')) { - println("Using local build of geckoview") - include ':geckoview-local' - project(':geckoview-local').projectDir = new File('geckoview-local') +Properties userProperties = null; +if (file('user.properties').canRead()) { + userProperties = new Properties() + userProperties.load(file('user.properties').newDataInputStream()) + logger.lifecycle('Local configuration: loaded user.properties') +} else { + logger.lifecycle('Local configuration: absent user.properties; proceeding as normal.') +} + +if (userProperties != null) { + userProperties.each { prop -> + gradle.ext.set("userProperties.${prop.key}", prop.value) + logger.lifecycle("\tuserProperties.${prop.key}" + '=' + prop.value) } - if (gradle.hasProperty('enableServo')) { - println("Including :servo") + if (gradle.hasProperty('userProperties.enableServo')) { + logger.lifecycle('Including Servo.') include ':servo' } +} + +Properties localProperties = null; +if (file('local.properties').canRead()) { + localProperties = new Properties() + localProperties.load(file('local.properties').newDataInputStream()) + logger.lifecycle('Local configuration: loaded local.properties') } else { - println("FILE DOESN'T EXIST") + logger.lifecycle('Local configuration: absent local.properties; proceeding as normal.') +} + +if (localProperties != null) { + localProperties.each { prop -> + gradle.ext.set("localProperties.${prop.key}", prop.value) + logger.lifecycle("\tlocalProperties.${prop.key}" + '=' + prop.value) + } }