From 9a9740bfd349e6b1bef9e0d2d85fda1f2057ee35 Mon Sep 17 00:00:00 2001 From: Grisha Kruglov Date: Fri, 15 Feb 2019 13:19:14 -0800 Subject: [PATCH] Issue #309: Consume Fenix megazord; enable Rust logging --- app/build.gradle | 12 +++++ .../org/mozilla/fenix/FenixApplication.kt | 48 ++++++++++++++++++- build.gradle | 1 + buildSrc/src/main/java/Dependencies.kt | 3 ++ 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index c56432fb1..fd2e6c5d3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,6 +8,17 @@ apply plugin: 'kotlin-android-extensions' apply from: "$project.rootDir/automation/gradle/versionCode.gradle" apply plugin: 'androidx.navigation.safeargs' +apply plugin: 'org.mozilla.appservices' + +appservices { + defaultConfig { + megazord = 'fenix' + // Necessary to allow for local dependency substitutions. + // See https://github.com/mozilla-mobile/reference-browser/pull/356#issuecomment-449190236 + unitTestingEnabled = false + } +} + android { compileSdkVersion 28 defaultConfig { @@ -183,6 +194,7 @@ dependencies { implementation Deps.mozilla_service_glean implementation Deps.mozilla_support_ktx + implementation Deps.mozilla_support_rustlog implementation Deps.mozilla_ui_colors implementation Deps.mozilla_ui_icons diff --git a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt index 22ab8a2cb..1eec80a5b 100644 --- a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt +++ b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt @@ -19,6 +19,7 @@ import mozilla.components.service.glean.Glean import mozilla.components.support.base.log.Log import mozilla.components.support.base.log.logger.Logger import mozilla.components.support.base.log.sink.AndroidLogSink +import mozilla.components.support.rustlog.RustLog import org.mozilla.fenix.components.Components import java.io.File @@ -31,7 +32,8 @@ open class FenixApplication : Application() { override fun onCreate() { super.onCreate() - Log.addSink(AndroidLogSink()) + val megazordEnabled = setupMegazord() + setupLogging(megazordEnabled) setupCrashReporting() if (!isMainProcess(this)) { @@ -55,6 +57,18 @@ open class FenixApplication : Application() { // no-op, LeakCanary is disabled by default } + private fun setupLogging(megazordEnabled: Boolean) { + // We want the log messages of all builds to go to Android logcat + Log.addSink(AndroidLogSink()) + + if (megazordEnabled) { + // We want rust logging to go through the log sinks. + // This has to happen after initializing the megazord, and + // it's only worth doing in the case that we are a megazord. + RustLog.enable() + } + } + private fun setupGlean(context: Context) { Glean.initialize(context) Glean.setUploadEnabled(BuildConfig.TELEMETRY) @@ -91,6 +105,38 @@ open class FenixApplication : Application() { .crashReporter .install(this) } + + /** + * Initiate Megazord sequence! Megazord Battle Mode! + * + * Mozilla Application Services publishes many native (Rust) code libraries that stand alone: each published Android + * ARchive (AAR) contains managed code (classes.jar) and multiple .so library files (one for each supported + * architecture). That means consuming multiple such libraries entails at least two .so libraries, and each of those + * libraries includes the entire Rust standard library as well as (potentially many) duplicated dependencies. To + * save space and allow cross-component native-code Link Time Optimization (LTO, i.e., inlining, dead code + * elimination, etc). + * Application Services also publishes composite libraries -- so called megazord libraries or just megazords -- that + * compose multiple Rust components into a single optimized .so library file. + * + * @return Boolean indicating if we're in a megazord. + */ + private fun setupMegazord(): Boolean { + // mozilla.appservices.FenixMegazord will be missing if we're doing an application-services + // dependency substitution locally. That class is supplied dynamically by the org.mozilla.appservices + // gradle plugin, and that won't happen if we're not megazording. We won't megazord if we're + // locally substituting every module that's part of the megazord's definition, which is what + // happens during a local substitution of application-services. + // As a workaround, use reflections to conditionally initialize the megazord in case it's present. + return try { + val megazordClass = Class.forName("mozilla.appservices.FenixMegazord") + val megazordInitMethod = megazordClass.getDeclaredMethod("init") + megazordInitMethod.invoke(megazordClass) + true + } catch (e: ClassNotFoundException) { + Logger.info("mozilla.appservices.FenixMegazord not found; skipping megazord init.") + false + } + } } /** diff --git a/build.gradle b/build.gradle index 3f5923377..f2700190f 100644 --- a/build.gradle +++ b/build.gradle @@ -8,6 +8,7 @@ buildscript { dependencies { classpath Deps.tools_androidgradle classpath Deps.tools_kotlingradle + classpath Deps.tools_appservicesgradle classpath Deps.androidx_safeargs classpath Deps.allopen diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt index afdbbb042..3500badb8 100644 --- a/buildSrc/src/main/java/Dependencies.kt +++ b/buildSrc/src/main/java/Dependencies.kt @@ -21,6 +21,7 @@ private object Versions { const val androidx_fragment = "1.1.0-alpha04" const val androidx_safeargs = "1.0.0-beta01" + const val appservices_gradle_plugin = "0.3.1" const val mozilla_android_components = "0.45.0-SNAPSHOT" const val test_tools = "1.0.2" @@ -40,6 +41,7 @@ private object Versions { object Deps { const val tools_androidgradle = "com.android.tools.build:gradle:${Versions.android_gradle_plugin}" const val tools_kotlingradle = "org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}" + const val tools_appservicesgradle = "org.mozilla.appservices:gradle-plugin:${Versions.appservices_gradle_plugin}" const val kotlin_stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${Versions.kotlin}" const val allopen = "org.jetbrains.kotlin:kotlin-allopen:${Versions.kotlin}" @@ -97,6 +99,7 @@ object Deps { const val mozilla_support_base = "org.mozilla.components:support-base:${Versions.mozilla_android_components}" const val mozilla_support_ktx = "org.mozilla.components:support-ktx:${Versions.mozilla_android_components}" + const val mozilla_support_rustlog = "org.mozilla.components:support-rustlog:${Versions.mozilla_android_components}" const val sentry = "io.sentry:sentry-android:${Versions.sentry}" const val leakcanary = "com.squareup.leakcanary:leakcanary-android:${Versions.leakcanary}"