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.

Fennec – Handling Add-on Options

The add-on (extension) mechanism built into the Mozilla platform is very powerful. One of the optional features is support for options (preferences) dialogs. As discussed in my last post, Fennec doesn’t like dialogs. In addition, Fennec has a simple, clean preference system. While designing the Fennec Add-ons Manager, we discussed how we would support add-on options. We didn’t want popup dialogs of random and complicated XUL.

After brainstorming a few ideas, we settled on a simple idea. Fennec uses special XUL tags to create it’s list of preferences. Add-ons would be forced to use the same tags. The options would be merged into the Fennec Add-on Manager, not displayed as a popup dialog. Of course, add-ons can support more than one application, so we needed to make sure that the options XUL for Fennec could coexist with the options XUL for other applications. Let’s take a look at how this all works:

Install Manifest

Add-ons use install.rdf to identify the XUL used for displaying the preferences. This is optional.


chrome://myaddon/content/options.xul

This is needed for any add-on that wants to use an options dialog.

Chrome Manifest

Add-ons use the chrome manifest to selectively override XUL, and other resources, between different applications using the application flags


override chrome://myaddon/content/options.xul chrome://myaddon/content/fennec-options.xul application={a23983c0-fd0e-11dc-95ff-0800200c9a66}

This will tell Mozilla to use fennec-options.xul anytime the options.xul resource is requested.

Options XUL

As I said, the XUL allowed for the Fennec options system is limited to a few new tags. Here is an example of a Fennec options dialog:







  
  
    Profiling can affect the performance of the application
  
  
  
  
    

Note that we don’t have any