Mobile/Distribution Files: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
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 will have to fit within these bounding boxes for each density:
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:

  1. 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.
  2. 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.
  3. 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.

Quickshare defaults

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.