{"id":313,"date":"2021-07-26T10:18:53","date_gmt":"2021-07-26T10:18:53","guid":{"rendered":"https:\/\/blog.mozilla.org\/data\/?p=313"},"modified":"2021-07-26T10:18:53","modified_gmt":"2021-07-26T10:18:53","slug":"this-week-in-glean-shipping-glean-with-geckoview","status":"publish","type":"post","link":"https:\/\/blog.mozilla.org\/data\/2021\/07\/26\/this-week-in-glean-shipping-glean-with-geckoview\/","title":{"rendered":"This Week in Glean: Shipping Glean with GeckoView"},"content":{"rendered":"<p>(\u201cThis Week in Glean\u201d is a series of blog posts that the Glean Team at Mozilla is using to try to communicate better about our work. They could be release notes, documentation, hopes, dreams, or whatever: so long as it is inspired by Glean.) All \u201cThis Week in Glean\u201d blog posts are listed in the <a href=\"https:\/\/mozilla.github.io\/glean\/book\/appendix\/twig.html\">TWiG index<\/a> (and on the <a href=\"https:\/\/blog.mozilla.org\/data\/category\/glean\/\">Mozilla Data blog<\/a>).<\/p>\n<hr \/>\n<h2 id=\"glean-sdk\">Glean SDK<\/h2>\n<p>The Glean SDK is Mozilla\u2019s telemetry library, used in most mobile products and now for Firefox Desktop as well. By now it has grown to a sizable code base with a lot of functionality beyond just storing some metric data. Since its first release as a Rust crate in 2019 we managed to move more and more logic from the language SDKs (previously also known as \u201clanguage bindings\u201d) into the core Rust crate. This allows us to maintain business logic only once and can easily share that across different implementations and platforms. The Rust core is shipped precompiled for multiple target platforms, with the language SDK distributed through the respective package manager.<\/p>\n<p>I talked about how this all works in more detail <a href=\"https:\/\/www.youtube.com\/watch?v=j5rczOF7pzg\">last year<\/a>, <a href=\"https:\/\/www.youtube.com\/watch?v=j5rczOF7pzg\">this year<\/a> and blogged about it <a href=\"https:\/\/blog.mozilla.org\/data\/2020\/09\/01\/twig-leveraging-rust\/\">in a previous TWiG<\/a>.<\/p>\n<h2 id=\"geckoview\">GeckoView<\/h2>\n<p><a href=\"https:\/\/mozilla.github.io\/geckoview\/\">GeckoView<\/a> is Mozilla\u2019s alternative implementation for WebViews on Android, based on Gecko, the web engine that also powers Firefox Desktop. It is used as the engine behind <a href=\"https:\/\/github.com\/mozilla-mobile\/fenix\/\">Firefox for Android<\/a> (also called Fenix). The visible parts of what makes up Firefox for Android is written in Kotlin, but it all delegates to the underlying Gecko engine, written in a combination of C++, Rust &amp; JavaScript.<\/p>\n<p>The GeckoView code resides in the mozilla-central repository, next to all the other Gecko code. From there releases are pushed to Mozilla\u2019s own <a href=\"https:\/\/maven.mozilla.org\/maven2\/\">Maven repository<\/a>.<\/p>\n<h2 id=\"one-glean-too-many\">One Glean too many<\/h2>\n<p>Initially Firefox for Android was the only user of the Glean SDK. Up until today it consumes Glean through its release as part of <a href=\"https:\/\/github.com\/mozilla-mobile\/android-components\/\">Android Components<\/a>, a collection of libraries to build browser-like applications.<\/p>\n<p>But the Glean SDK is also available outside of Android Components, as its own package. And additionally it\u2019s available for other languages and platforms too, including a <a href=\"https:\/\/crates.io\/crates\/glean\">Rust crate<\/a>. <a href=\"https:\/\/blog.mozilla.org\/data\/2020\/10\/06\/this-week-in-glean-fog-progress-report\/\">Over the past year we\u2019ve been busy<\/a> getting Gecko to use Glean through the Rust crate to build its own telemetry on top.<\/p>\n<p>With the Glean SDK used in all these applications we\u2019re in a difficult position: There\u2019s a Glean in Firefox for Android that\u2019s reporting data. Firefox for Android is using Gecko to render the web. And Gecko is starting to use Glean to report data.<\/p>\n<p>That\u2019s one Glean too many if we want coherent data from the full application.<\/p>\n<h2 id=\"shipping-it-all-together-take-one\">Shipping it all together, take one<\/h2>\n<p>Of course we knew about this scenario for a long time. It\u2019s been one of the goals of Project FOG to transparently collect data from Gecko and the embedding application!<\/p>\n<p>We set out to find a solution so that we can connect both sides and have only one Glean be responsible for the data collection &amp; sending.<\/p>\n<p>We started with more detailed planning all the way back in August of last year and agreed on a design in October. Due to changed priorities &amp; availability of people we didn\u2019t get into the implementation phase until earlier this year.<\/p>\n<p>By February I had a first rough prototype in place. When Gecko was shipped as part of GeckoView it would automatically look up the Glean library that is shipped as a dynamic library with the Android application. All function calls to record data from within Gecko would thus ultimately land in the Glean instance that is controlled by Fenix. Glean and the abstraction layer within Gecko would do the heavy work, but users of the Glean API would notice no difference, except their data would now show up in pings sent from Fenix.<\/p>\n<p>This integration was brittle. It required finding the right dynamic library, looking up symbols at runtime as well as reimplementing all metric types to switch to the FFI API in a GeckoView build. We abandoned this approach and started looking for a better one.<\/p>\n<h2 id=\"shipping-it-all-together-take-two\">Shipping it all together, take two<\/h2>\n<p>After the first failed approach the issue was acknowledged by other teams, including the GeckoView and Android teams.<\/p>\n<p>Glean is not the only Rust project shipped for mobile, the <a href=\"https:\/\/github.com\/mozilla\/application-services\">application-services team<\/a> is also shipping components written in Rust. They bundle all components into a single library, dubbed the <a href=\"https:\/\/github.com\/mozilla\/application-services\/blob\/main\/docs\/design\/megazords.md\">megazord<\/a>. This reduces its size (dependencies &amp; the Rust standard library are only linked once) and simplifies shipping, because there\u2019s only one library to ship. We always talked about pulling in Glean as well into such a megazord, but ultimately didn\u2019t do it (except for <a href=\"https:\/\/github.com\/mozilla\/application-services\/tree\/main\/megazords\/ios\">iOS builds<\/a>).<\/p>\n<p>With that in mind we decided it\u2019s now the time to design a solution, so that eventually we can bundle multiple Rust components in a single build. We came up with the following plan:<\/p>\n<ul>\n<li>The Glean Kotlin SDK will be split into 2 packages: a <code>glean-native<\/code> package, that only exists to ship the compiled Rust library, and a <code>glean<\/code> package, that contains the Kotlin code and has a dependency on <code>glean-native<\/code>.<\/li>\n<li>The GeckoView-provided <code>libxul<\/code> library (that\u2019s \u201cGecko\u201d) will bundle the Glean Rust library and export the C-compatible FFI symbols, that are used by the Glean Kotlin SDK to call into Glean core.<\/li>\n<li>The GeckoView Kotlin package will then use Gradle capabilities to replace the <code>glean-native<\/code> package with itself (this is actually handle by the Glean Gradle plugin).<\/li>\n<\/ul>\n<p>Consumers such as Fenix will depend on both GeckoView and Glean. At build time the Glean Gradle plugin will detect this and will ensure the <code>glean-native<\/code> package, and thus the Glean library, is not part of the build. Instead it assumes <code>libxul<\/code> from GeckoView will take that role.<\/p>\n<p>This has some advantages. First off everything is compiled together into one big library. Rust code gets linked together and even Rust consumers within Gecko can directly use the Glean Rust API. Next up we can ensure that the version of the Glean core library matches the Glean Kotlin package used by the final application. It is important that the code matches, otherwise calling native functions could lead to memory or safety issues.<\/p>\n<p>Glean is running ahead here, paving the way for more components to be shipped the same way. Eventually the experimentation SDK called Nimbus and other application-services components will start using the Rust API of Glean. This will require compiling Glean alongside them and that\u2019s the exact case that is handled in mozilla-central for GeckoView then.<\/p>\n<p>Now the unfortunate truth is: these changes have not landed yet. It\u2019s been implemented for both the Glean SDK and mozilla-central, but also requires changes for the build system of mozilla-central. Initially that looked like simple changes to adopt the new bundling, but it turned into bigger changes across the board. Some of the infrastructure used to build and test Android code from mozilla-central was untouched for years and thus is very outdated and not easy to change. With everything else going on for Firefox it\u2019s been a slow process to update the infrastructure, prepare the remaining changes and finally getting this landed.<\/p>\n<p>But we\u2019re close now!<\/p>\n<p>Big thanks to <a href=\"https:\/\/github.com\/agi\/\">Agi<\/a> for connecting the right people, driving the initial design and helping me with the GeckoView changes. He also took on the challenge of changing the build system. And also thanks to <a href=\"https:\/\/github.com\/chutten\">chutten<\/a> for his reviews and input. He\u2019s driving the FOG work forward and thus really really needs us to ship GeckoView support.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>(\u201cThis Week in Glean\u201d is a series of blog posts that the Glean Team at Mozilla is using to try to communicate better about our work. They could be release &hellip; <a class=\"go\" href=\"https:\/\/blog.mozilla.org\/data\/2021\/07\/26\/this-week-in-glean-shipping-glean-with-geckoview\/\">Read more<\/a><\/p>\n","protected":false},"author":1756,"featured_media":197,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[448297],"tags":[],"coauthors":[],"_links":{"self":[{"href":"https:\/\/blog.mozilla.org\/data\/wp-json\/wp\/v2\/posts\/313"}],"collection":[{"href":"https:\/\/blog.mozilla.org\/data\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mozilla.org\/data\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/data\/wp-json\/wp\/v2\/users\/1756"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/data\/wp-json\/wp\/v2\/comments?post=313"}],"version-history":[{"count":0,"href":"https:\/\/blog.mozilla.org\/data\/wp-json\/wp\/v2\/posts\/313\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/data\/wp-json\/wp\/v2\/media\/197"}],"wp:attachment":[{"href":"https:\/\/blog.mozilla.org\/data\/wp-json\/wp\/v2\/media?parent=313"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mozilla.org\/data\/wp-json\/wp\/v2\/categories?post=313"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mozilla.org\/data\/wp-json\/wp\/v2\/tags?post=313"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mozilla.org\/data\/wp-json\/wp\/v2\/coauthors?post=313"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}