Firefox Android: Add-ons in a Native World

One of the first things I yelled about when we were debating switching to a native Android UI for Firefox was add-on support. Using a XUL-based UI meant add-ons were free. The Mozilla platform has support for add-ons baked right in. Moving to a native UI would surely kill our ability to support add-ons, right? Wrong!

Add-ons are an important part of the Firefox story. Native UI builds of Firefox support add-ons. There are some things an add-on developer needs to be aware:

  • The add-ons system is the same one used in other Mozilla applications. We did not invent a new add-on system.
  • Native UI builds are considered a new application and are not add-on compatible with the XUL versions. The application ID for native UI builds is: {aa3c5121-dab2-40e2-81ca-7ea25febc110}
  • There is no visible XUL in the UI, so using overlays to try to add or change UI is useless.
  • There is a simple NativeWindow object that allows you to manipulate parts of the native Android UI.
  • Services like nsIPromptService and nsIAlertsService are implemented to use native Android UI.
  • Since overlays are useless for UI and JavaScript APIs are available for native UI, you should seriously consider just making a restartless add-on.

NativeWindow

We wanted to give add-on developers some APIs to manipulate the native Android UI, so we create a helper object called NativeWindow. The API is still young, but it gives you access to: Android Menu, Doorhanger Notifications, Context Menus (in web content) and Android popup toast alerts. The object is currently part of the main browser window, but we are considering moving it to a JS module. The basic API is here:


/*
 label: menu label
 icon: file:// or data: URI for an icon
 callback: JS function called when menu is tapped
 returns a menu ID that can be used to remove the menu
*/
menuID = NativeWindow.menu.add(label, icon, callback);
NativeWindow.menu.remove(menuID);

/*
 message: displayed text
 value: string based tag
 buttons: array of JS objects used to create buttons in the notification
 tabID: tab associated with this notification
 options: JS object that has 'persistence' and 'timeout' options
*/
NativeWindow.doorhanger.show(message, value, buttons, tabID, options);
NativeWindow.doorhanger.hide(value, tabID);

/*
 label: menu label
 selector: JS object that has a 'matches(element)' function. Used to show the menu.
 callback: JS function called when menu is tapped
 returns a menu ID that can be used to remove the menu
*/
menuID = NativeWindow.contextmenu.add(label, selector, callback);
NativeWindow.contextmenu.add(menuID);

/*
 message: displayed text
 duration: "short" or "long"; Used for alert timeout
*/
NativeWindow.toast.show(message, duration);

Some examples of what the API can do:

Doorhanger Notification


Menu Item


Context Menu Item


Toast Popup Alert


The NativeWindow API will continue to grow and mature, but I think even now it shows that add-ons can have first-class interactions with the native UI of Firefox. I am looking forward to developers trying it out and helping us push the API forward.

7 Replies to “Firefox Android: Add-ons in a Native World”

  1. you might want to make NativeWindow really good, and have desktop firefox work like nativeUI on android.

    native UI + threaded geckos, fast startup and UI that never freezes. Fixes 90% of users complains on desktop?

  2. It’ll definitely be interesting to see where this goes. I trust you guys to do well for the average user, but I still have two significant concerns:

    1. Whether the Native UI or the NativeWindow API will provide me with a suitable replacement for the home button I currently get from an extension. (placed next to the new tab button in the sidebar and shows a short menu-style list of especially commonly-used sites)

    2. Whether I’ll be stuck on pre-Native builds for x86_64 Linux.

    (I’m a Canadian University student with Stallman-like leanings. I can’t afford a cellphone and wouldn’t want one in their current state of freedom but I can’t stand how slow the Android emulator is as a means of testing my creations to the point of being able to hand them off to friends with genuine phones for less intensive but more accurate testing.)

  3. This seems a bit bikesheddy, but these things are very hard to change once established, so: are you sure your API names are generic enough? “Native” is a distinguishing mark at the moment, but will it still make sense to call the thing “NativeWindow” 5 years from now? Similar with “doorhanger” – as well as being an Americanism, what happens if these notifications get implemented another way in a different UI paradigm? “Toast” has the same problems.

    Have you consulted with the Jetpack team on your API design and naming? I’m sure they’d have great input…

    Gerv

  4. @Gervase – It would be best if you didn’t consider NativeWindow a frozen API. Like any code in Firefox available to add-on developers, this can and will change, especially as it evolves. Jetpack is an API that has compatibility guarantees. NativeWindow could be wrapped by Jetpack to implement it’s API.

Comments are closed.