So... why make Firefox for Android?

Mozilla's mission is to promote openness, innovation and opportunity on the web.

What this means for the mobile web

Firefox 4.0 for Android

Time to take a different approach

Native Android UI

Building a native browser UI

Message passing

Java to JS

Create a GeckoEvent in Java:

GeckoEvent e = GeckoEvent.createBroadcastEvent("my-event", "data");
GeckoAppShell.sendEventToGecko(e);

Add an observer in JS:

Services.obs.addObserver(observer, "my-event", false);
function observer(aSubject, aTopic, aData) {
  // Do some stuff
};

JS to Java

Create a JSON message in JS:

let message = {
  gecko: {
    type: "another-event", ...
  }
};
sendMessageToJava(message);

Register a listener in Java:

GeckoAppShell.registerGeckoEventListener("another-event", listener);
GeckoEventListener listener = new GeckoEventListener() {
  public void handleMessage(String event, JSONObject message) {
    // Do some stuff
  }
}

Let's see how this works in practice

The back button

In Java, use an Android API to listen for a back button press:

@Override
public void onBackPressed() {
  GeckoEvent e = GeckoEvent.createBroadcastEvent("Session:Back", "");
  GeckoAppShell.sendEventToGecko(e);
}

In JS, use a Gecko API to navigate back in session history:

Services.obs.addObserver(handleBackPressed, "Session:Back", false);
function handleBackPressed(aSubject, aTopic, aData) {
  BrowserApp.selectedBrowser.goBack();
};

Updating a tab's title

Listen for DOMTitleChanged events in JS, and pass them along to Java:

Tab.prototype = {
  create: function(...) {
    this.browser.addEventListener("DOMTitleChanged", this, true);
  },
  handleEvent: function(aEvent) {
    let message = {
      gecko: {
        type: "DOMTitleChanged",
        tabID: this.id,
        title: aEvent.target.title }
    }
    sendMessageToJava(message);
  }
}

Update the tab's title in the native Java UI:

GeckoAppShell.registerGeckoEventListener("DOMTitleChanged", listener);

GeckoEventListener listener = new GeckoEventListener() {
  public void handleMessage(String event, JSONObject message) {
    int tabId = message.getInt("tabID");
    Tab tab = Tabs.getInstance().getTab(tabId);

    String title = message.getString("title");
    tab.updateTitle(title);
  }
}

Writing add-ons (totally in JS!)

A basic restartless add-on is two files

Building a simple add-on

An add-on to view the source of a webpage

var menuId;

function loadIntoWindow(window) {
  function viewSource() {
    let url = window.content.location.href;
    window.BrowserApp.addTab("view-source:" + url);
  }
  let [label, icon, cb] = ["View Source", null, viewSource];
  menuId = window.NativeWindow.menu.add(label, icon, cb);
}

function unloadFromWindow(window) {
  window.NativeWindow.menu.remove(menuId);
}

APIs for add-on developers

Ways to get involved

Thanks!

@mleibovic

margaret@mozilla.com

http://margaretleibovic.com/talks/jsconf/firefox-for-android.html