Mobile/Distribution Files
Like desktop, mobile Firefox supplies a way for partners to repackage a set of customization files into a Firefox build without recompiling. We don't want to make custom binary builds that need to be QA'd extensively. The "distribution files" concept allows a small set of external files to be used to customize a standard Firefox build. Things that can be customized include:
- Default bookmarks
- Preferences
- Lightweight themes
- Search engines
- Add-ons
Overview
There are currently two ways distribution files can be ... distributed:
- A folder of distribution files is repackaged into the Android APK. During the first run, those files are extracted from the APK and stored in the /data/data/org.mozilla.firefox/distribution/* folder.
- A folder of distribution files are shipped with the ROM image in /system/org.mozilla.firefox/distribution/* folder. Shipping in this way ensures the files are not easily overwritten or removed by an application update. Note, files found in the /data/data/org.mozilla.firefox/distribution/* folder will "win" in cases where both locations are used.
Each type of data may have it's own nuances:
- Default bookmarks are read from the APK directly or from the "distribution" folder (if it already exisits) any time a profile is created. These bookmarks are created before we create the Firefox's default bookmarks.
- Preferences are set as "default" preferences on each run, since a "default" preference only lasts for the lifetime of the session. They are created as "default" preferences to allow "user" preferences to override them.
- Lightweight themes are really only preferences too. The data for the theme must live online somewhere. A typical place are the AMO theme or getpersonas.com sites.
- Search engine plugins and add-ons must follow a fixed folder layout.
Bookmarks
Default bookmarks are specified in /distribution/bookmarks.json. This file should contain an array of bookmark JSON objects with the following properties:
- title: (required) string for the bookmark title
- url: (required) string for the bookmark URL
- title.<locale>: (optional) title string for the given locale
- url.<locale>: (optional) URL string for the given locale
- icon: (optional) data URI for the bookmark favicon
- pinned: (optional) boolean for whether or not to pin this bookmark to the about:home top sites
Here is an example bookmarks.json:
[
{
"title": "Queso",
"url": "http://queso.com/",
"title.en_US": "Cheese",
"url.en_US": "http://cheese.com",
"icon": "data:image/png;base64,..."
}
]
Preferences
Preferences are specified in /distribution/preferences.json. This file should contain a JSON object with the following properties:
- Global
- id: (required) a short string unique to this distribution
- version: (required) version of the distribution (not the version of Firefox)
- about: (required) a short descriptive (ui-visible) string for this distribution
- about.<locale>: (optional) descriptive string for the given locale
- Preferences (optional)
- LocalizablePreferences (optional)
- LocalizablePreferences.<locale> (optional)
Here is an example preferences.json:
{
"Global": {
"id": "testpartner",
"version": 1.0,
"about": "Afiliado de Prueba",
"about.en-US": "Test Partner"
},
"Preferences": {
"distribution.test.string": "a string pref",
"distribution.test.boolean": true,
"distribution.test.int": 5
},
"LocalizablePreferences": {
"distribution.test.localizeable": "http://test.org/%LOCALE%/%LOCALE%/",
"distribution.test.localizeable-override": "http://test.org/%LOCALE%/%LOCALE%/"
},
"LocalizablePreferences.en-US": {
"distribution.test.localizeable-override": "http://cheese.com"
}
}
Lightweight Themes
Lightweight themes are specified in the "Preferences" section of /distribution/preferences.json. Here is an example of the lightweight theme preferences needed for this to work:
"Preferences": {
"lightweightThemes.isThemeSelected": true,
"lightweightThemes.persisted.footerURL": false,
"lightweightThemes.persisted.headerURL": false,
"lightweightThemes.usedThemes": "[{\"id\":\"491717\",\"name\":\"colored trees\",\"headerURL\":\"http://getpersonas-cdn.mozilla.net/static/1/7/491717/trees.png?1358076678\",\"footerURL\":\"http://getpersonas-cdn.mozilla.net/static/1/7/491717/trees-base.png?1358076678\",\"textcolor\":\"#1d022b\",\"accentcolor\":\"#000000\",\"iconURL\":\"http://getpersonas-cdn.mozilla.net/static/1/7/491717/preview_small.jpg?1358076678\",\"previewURL\":\"http://getpersonas-cdn.mozilla.net/static/1/7/491717/preview.jpg?1358076678\",\"author\":\"birdyann\",\"description\":\"trees arbres colored colors couleurs\",\"updateURL\":\"https://www.getpersonas.com/en-US/update_check/491717\",\"version\":\"1358076678\",\"updateDate\":1359579038207,\"installDate\":1359579038207}]"
}
Search Plugins
Search plugins do no need to be listed in any file. Instead, create a directory structure like the following, and they will be automatically loaded:
* distribution/
* searchplugins/
* common/
* <plugin.xml>
* <plugin.xml>
* ...
* locale/
* <locale>/
* <plugin.xml>
* <plugin.xml>
* ...
* <locale>/
* <plugin.xml>
* <plugin.xml>
* ...
If a directory for the locale the browser is running in doesn't exist, Firefox will automatically try the 'default' locale, as defined by the distribution.searchplugins.defaultLocale preference.
Add-ons
Add-ons do no need to be listed in any file. Instead, include them in an extensions directory as follows, and they will be automatically loaded:
* distribution/
* extensions/
* someaddon@somedomain.com.xpi
* ...
Be sure to name the add-on XPI with the ID that's specified in the add-on's install.rdf.
Issues
We need to ensure the files are not cleared or overwritten during an update. The Android "Manage Apps" system allows users to "Clear Data" and we need to verify this does not clear the files.Since we extract from the APK during first run, if a user never runs Firefox but does update it, there is a chance the distribution files would never be extracted.
The use of a /system file location for distribution files solves these issues.