Graphene On Gecko Without B2G

Recently, I’ve been experimenting with a reimplementation of Graphene on Gecko that doesn’t require B2G. Graphene is a desktop runtime for HTML apps, and Browser.html uses it to run on Servo. There’s a Gecko implementation of Graphene that is based on B2G, but it isn’t maintained and appears to have bitrotted. It also entrains all of B2G, although Browser.html doesn’t use many B2G features.

My reimplementation is minimal. All it does is load a URL in a native window and expose a few basic APIs (including <iframe mozbrowser>). But that’s enough to run Browser.html. And since Browser.html is a web app, it can be loaded from a web server (with this change that exposes <iframe mozbrowser> to https: URLs).

I forked browserhtml/browserhtml to mykmelez/browserhtml, built it locally, and then pushed the build to my GitHub Pages website at mykmelez.github.io/browserhtml. Then I forked mozilla/gecko-dev to mykmelez/graphene-gecko and reimplemented Graphene in it. I put the implementation into embedding/graphene/, but I could have put it anywhere, including in a separate repo, per A Mozilla App Outside Central.

To try it out, clone, build, and run it:

git clone https://github.com/mykmelez/graphene-gecko
cd graphene-gecko
./mach build && ./mach run https://mykmelez.github.io/browserhtml/

You’ll get a native window with Browser.html running in Graphene:

Graphene on Gecko

 

Myk Melez

Myk is a Principal Software Architect and in-house entrepreneur at Mozilla. A Mozillian since 1999, he's contributed to the Web App Developer Initiative, PluotSorbet, Open Web Apps, Firefox OS Simulator, Jetpack, Raindrop, Snowl, Personas, Firefox, Thunderbird, and Bugzilla. He's just a cook. He's all out of bubblegum.

 

8 thoughts on “Graphene On Gecko Without B2G

    1. I don’t think it’s possible to install this implementation of Graphene on a tablet running B2G, but it might be possible to package Browser.html as a B2G app that runs on that tablet, since the original implementation of Graphene was built with B2G. You would need to include a B2G app manifest that requests the browser permission and then distribute it from a website that your installation of B2G trusts (or sideload it in a way that bypasses that security mechanism). You might try asking in B2G or Browser.html discussion forums.

  1. Hi Alex, I didn’t see your blog post, although I know a little about the project, since you showed it to me in person back in June! 😉

    Note that my blog post was actually two months and two days later than yours, since you blogged on June 28, and this post came out on August 30.

    In any case, I left a comment on your post, and I really like the Browser UI project, especially because it demonstrates a potential way to reimplement the Firefox UI incrementally (and test the changes with users), without having to rebuild the entire browser from scratch.

    A similarity between Graphene and Browser UI is that they both enable a browser developer to serve the browser’s interface from a remote web server. Both of them are also capable of exposing system integration APIs.

    The principal difference, from my perspective, is that Graphene focuses on the alternative browser use case, while Browser UI focuses on the alternative interface for Firefox use case. That can have both practical and theoretical implications.

    Practically, there may be differences in how you can extend/modify the backend in Graphene vs. Browser UI (f.e. to add a Web API or a service like the User Agent service) by recompiling the runtime versus adding a WebExtension.

    Theoretically, there may be differences in the sorts of developers who are attracted to a project that enables them to extend Firefox vs. building an alternative browser.

    In any case, this project is just an experiment, not a concrete effort to produce a platform for future browser development. I’d be interested to hear your thoughts on the particular use cases that Browser UI is intended to satisfy and any plans you have to continue to develop it!

  2. Justs a warning, allowing

    <

    iframe mozbrowser> for any page loaded over HTTPS is really bad idea. Because mozbrowser iframes ignore X-Frame-Options headers and overwrites the window.top property, this will allow any website served over HTTPS to launch a clickjacking attack on any other website. Also the browser API does a lot of very privileged things, for example being able to take screenshots. So any website would be able to frame my online banking website, track my browsing history and all my clicks and take screenshots of my activity.

    I wish that the security model was this simple because if it was we could have standardised as a new HTML tag years ago.

    Building browser UI using HTML is a great idea, but for now the Browser API is only safe to expose to chrome privileged content. There is currently no security model for the web fit for the purpose of exposing the Browser API to the web.

    1. Indeed, but note that the DOM hack I’m using for this experiment doesn’t allow just any page loaded over HTTPS to use <mozbrowser>. It only exposes that API to the page that the runtime loads in the native window’s top-level docshell. In other words: the page that the developer specifically requests to load as the application chrome (which, for a packaged and distributed app, will be the page that the app specifies in its configuration).

      So it’s not quite as dangerous as giving all HTTPS sites access to <mozbrowser>. Nevertheless, the current iteration also gives the top-level docshell the system principal, and I’m not happy with that approach, since it’s a footgun: if a developer accidentally specifies the wrong page to load as the application chrome, or an attacker somehow figures out how to load another page in the top-level docshell, then the runtime will escalate its privileges.

      Ok, that’s unlikely to happen to a packaged, distributed app, whose application chrome URL will be specified by configuration, not by the user on the command line. Still, I’d rather make the runtime safe by default.

      Over in https://bugzilla.mozilla.org/show_bug.cgi?id=1290272, I’ve been discussing the issue with bz and jryans. And in https://github.com/mozilla/positron/pull/111 I have a work-in-progress that implements a better approach for Positron. It enables <mozbrowser for the specific origin of the URL specified as the application chrome, without giving the top-level docshell the system principal. So the application chrome page gets <mozbrowser>, but it doesn’t get any other privileges, and no other origin gets <mozbrowser>.

      (We should also restrict the API to pages at that origin that are loaded over HTTPS. And perhaps disable <mozbrowser for HTTPS by default, enabling it only for local files, so developers have to set another pref to confirm that they really want to give a remote page access to that API.)

      Does that seem reasonable?

      1. As a developer tool, maybe, but not as a product you’d ship. We had DEBUG builds of Gaia that you could load in a special build of Firefox using a local web server and it meant you could just hit F5 to reload the system UI after making a change without needing to re-build. It was great for front end developer productivity (when it worked).

        A mozbrowser iframe isn’t a web standard HTML tag and there’s currently no prospect of it becoming one. My conclusion after five years is that we shouldn’t pretend that it’s the web. There’s chrome and there’s web content. Use HTML to build browser chrome and package that HTML in an application like Electron does, sure. But don’t put web pages on the web that only work in one browser engine and under very specific circumstances.

        I’m all for creating a chrome-only tag in Gecko/Servo, but let’s not pollute the web with it.

        1. Ben, I think I mostly agree. The primary use case for this feature is to load (and reload) application chrome dynamically during development. That was the initial use case for the feature in Positron (where we needed to load Tofino from a file: URL while testing/developing it), and it’d presumably be the primary use case for the feature in Graphene (to load Browser.html from a file: or http://localhost/ URL).

          I do think there’s a use case for downloading (and updating) the chrome of a desktop application from a secure, remote server (using a Service Worker to ensure that the app works offline and updates seamlessly). It isn’t about pretending that the chrome is a regular web app and will work outside its shell. Rather, it’s about adopting the web update model in a desktop app, to reduce the developer burden of updating the app via a desktop app distribution channel.

          Nevertheless, I still wouldn’t prioritize that use case too much, at least without learning more about its value (relative to the traditional desktop distribution model).

Leave a Reply

Your email address will not be published.