Mobile/Distribution Files: Difference between revisions
Line 162: | Line 162: | ||
The list of suggested sites from the distribution will be prepended to the default list of suggested sites that ships with Firefox. | The list of suggested sites from the distribution will be prepended to the default list of suggested sites that ships with Firefox. | ||
The suggested site images | The suggested site images are expected to fit within these bounding boxes for each density: | ||
* ''xxhdpi'': 375x195 | * ''xxhdpi'': 375x195 | ||
* ''xhdpi'': 250x130 | * ''xhdpi'': 250x130 |
Revision as of 13:20, 8 August 2014
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
- Quickshare defaults
- Suggested sites
Overview
There are currently three 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/*
directory. - A folder of distribution files are shipped with the ROM image in
/system/org.mozilla.firefox/distribution/*
directory. 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/*
directory will "win" in cases where both locations are used. - A distribution zip file is downloaded over-the-air as a result of a post-install referrer intent. See bug 1013024. This feature should ship with Firefox 33.
Note that distribution files are not loaded for webapp profiles, as of bug 1016611.
Distributions are processed asynchronously during first run. Frontend code can chain post-distribution tasks via Distribution.addOnDistributionReadyCallback
.
Each type of data has its own nuances:
- Default bookmarks are read from the APK directly or from the "distribution" folder (if it already exists) any time a profile is created. These bookmarks are created prior to 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 actually just preferences. The data for the theme must live online somewhere. Typical places are the AMO theme or getpersonas.com sites.
- Search engine plugins and add-ons must follow a fixed folder layout.
- If distribution data is processed after the initial quickshare set is loaded, these options won't take effect until next run (bug 1021176).
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
Include search plugins in 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
Include add-ons 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.
Add a file named history.xml
under distribution/quickshare
. Its contents should be something like:
<historical-records> <historical-record activity="com.android.mms/com.android.mms.ui.ConversationComposer" time="0" weight="1"/> </historical-records>
Suggested sites
Added by bug 1012462 in Firefox 33.
Use a directory tree like the following. Locales are named via a locale code, such as en-US
.
* distribution/ * suggestedsites/ * locales/ * <locale>/ * suggestedsites.json * res/ * hdpi/ * <distro>.png * xxhdpi/ * <distro>.png
The suggestedsites.json file should be a JSON array:
[ { url: "<site-url>", title: "<site-title>", imageurl: "gecko.distribution://<image-dir>/<image-name>", bgcolor: "<color-hex-code>" }, ... ]
Where <image-dir>
is the directory containing the density-specific image directories (mdpi
, hdpi
, etc) and <image-name>
is the filename under the density-specific directories without the file extension. For example, gecko.distribution://suggestedsites/res/distroimage
image URL will be translated to <distribution-root-dir>/suggestedsites/res/xhdpi/distroimage.png
on a XHDPI device.
The list of suggested sites from the distribution will be prepended to the default list of suggested sites that ships with Firefox.
The suggested site images are expected to fit within these bounding boxes for each density:
- xxhdpi: 375x195
- xhdpi: 250x130
- hdpi: 188x98
- mdpi:125x65
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.
Tips
- You can test creating a /system distribution with a rooted phone
- Run 'adb devices' to find the ID for your device
- Run 'mount -o remount,rw <device> /system' as root in adb shell (replace <device> with your device ID)
- Put distribution files at /system/<package>/distribution/* (replace <package> with the ID for the package you want to test, e.g. org.mozilla.fennec)
- To create a distribution build locally, put your distribution folder at objdir/dist/bin/distribution, then package the app as you normally would (./mach build). The distribution files will be copied out to /data/data/org.mozilla.fennec_yourname/distribution, and they will override a system distribution if it is present.
Testing distribution download
A distribution download is triggered when two things are true:
- This is the first run of Firefox (or Clear Data has been used).
- An
INSTALL_REFERRER
intent has been received prior to launch.
The Google Play app takes care of sending that intent. You can also manually send it via adb shell
. Assuming you're testing Nightly:
am broadcast -a com.android.vending.INSTALL_REFERRER \ -n org.mozilla.fennec/org.mozilla.gecko.distribution.ReferrerReceiver \ --es "referrer" "utm_source=mozilla&utm_medium=testmedium&utm_term=testterm&utm_content=testsigned&utm_campaign=distribution"
This will fetch the "testsigned.jar" distribution.
Telemetry will be recorded for the download: FENNEC_DISTRIBUTION_DOWNLOAD_TIME_MS
records the download time in milliseconds, and FENNEC_DISTRIBUTION_CODE_CATEGORY
records the result. The value will be one of these:
- 0
- Unexpected HTTP status.
- 1
- HTTP 1xx. Should not occur.
- 2
- HTTP 2xx. The expected result.
- 3
- HTTP 3xx. Should not occur.
- 4
- HTTP 4xx. Should not occur.
- 5
- HTTP 5xx. Should not occur.
- 6
- The device was offline.
- 7
- Generic fetch exception.
- 8
- Failure during processing of downloaded zip.
- 9
- Security exception: malformed, corrupted, or modified signatures.
- 10
- Malformed distribution file.
- 11
- Fetch: socket error.
- 12
- Fetch: SSL error.
- 13
- Fetch: non-success HTTP response.
- 14
- Fetch: invalid Content-Type header received.
Crafting a distribution referrer
These are the fields exposed in a referrer URL to Play:
utm_content
- The distribution name. Must be unique. Identifies the distribution name.
utm_campaign
- The campaign name. Must be
distribution
. utm_source
- Original referrer. E.g.,
mozilla
. Not used by Firefox. utm_medium
- Campaign medium. E.g.,
email
. Not used by Firefox. utm_term
- Search terms. E.g.,
web+browser
. Not used by Firefox.