Market customizations guide

In This Article
  1. Customization Overview
  2. Steps to apply customization
  3. Buildtime Customizations
    1. power/
    2. ringtones/
    3. wallpapers/
    4. browser.json
    5. calendar.json
    6. camera-config.js (Gallery and Camera app image sizes)
    7. contacts.json
    8. device-features.json
    9. eu-roaming.json
    10. homescreens.json
      1. Collections
      2. Vertical homescreen properties
    11. network.json (not in customization folder)
    12. settings.json
      1. Default Rocketbar search provider
    13. Search provider customization
    14. Customize default Homescreen apps
    15. sms-blacklist.json
    16. cellbroadcast
    17. support.json
    18. WAP user agent profile (wapuaprof.json)
    19. apps.list
  4. Other customization options
    1. Browser bookmarks and default search engines
    2. Single variant customization to override list of providers and Rocketbar search provider
    3. Data and messaging settings
    4. Voicemail and cell broadcast settings
    5. WAP user agent profile
    6. Applications
    7. Other single variant customizations
      1. Support contacts
      2. Default contacts
      3. Ringtone
      4. Wallpaper
      5. Keyboard settings
      6. Network Display Indicator
      7. Pre-populate WiFi SSIDs
      8. Data enabled/disabled by default during FTU
      9. Maximum number of SMS to convert to MMS
      10. Pre-populate browser top sites
      11. Bookmarks
      12. Data roaming on/off by default
      13. Power on/off operator animation
      14. NFC enabled/disabled by default
  5. Building Prebundled web apps
    1. To bundle a single web app
    2. Batch process to bundle multiple web apps
    3. Prebundled web app metadata.json
    4. Packaged web app auto-updates: update.webapp format
    5. Pre-bundled web app AppCache format
  6. FAQ
    1. What can be customized?
    2. How and where do you define a customized app grid layout?
    3. Is it possible to define whether an app is removable in the homescreen configuration?
    4. How do you add a preloaded packaged or hosted app to the build?
    5. How do you prepare a preloaded hosted app for initial offline support?
    6. What Marketplace Customizations Are Possible?
    7. How do I package and store per-market customization changes?
    8. How do you build the product with a specific market's configuration?
    9. How to customize power on / off animation?

Market customizations allow you to specify build-time customization instructions (for example, which apps should be included in your build) in separate directories, without modifying the core Gaia repo. You can include your own customizations in distinct directories, or use the preexisting directories that come with the source. These customizations are specified with build options. In this article we look in detail at how to create and use these customizations.

Customization Overview

Requires Firefox OS 1.0.1

Since 1.0.1, Firefox OS has used the same mechanism as Firefox for customization. All features discussed in this article work inside Firefox OS 1.0.1, unless otherwise indicated.

We have created a full-featured Gaia distribution customization sample as part of the Gaia repo: study this to learn first-hand what can be done with build-time customization. It will also be referenced in the article below.

Note: Send a pull request to the above referenced Github repo if you have any suggestions for improving the customization sample, or see something that has been changed in this article but not updated in the code.

Below is the tree structure for the customization sample:

  customize-sample
  ├── power
  │   ├── carrier_power_on.png
  │   └── carrier_power_off.png
  ├── ringtones
  │   ├── list.json
  │   └── ringer_dream_theme.ogg
  ├── wallpapers
  │   ├── customize.png
  │   └── list.json
  ├── browser.json
  ├── calendar.json
  ├── contacts.json
  ├── costcontrol.json
  ├── device-features.json
  ├── eu-roaming.json
  ├── homescreens.json
  ├── network.json
  ├── settings.json
  ├── sms-blacklist.json
  ├── support.json
  ├── wapuaprof.json
  └── apps.list

Note: All files are optional. If you don't provide a file, it will fallback to the system default.

We will discuss all these optional customizations in the sections that follow, but first let's see how to apply the customization to Gaia.

Steps to apply customization

To apply the customization sample to Gaia:

  1. Clone the Gaia source code from https://github.com/mozilla-b2g/gaia.
  2. You can either copy the gaia/customization/ directory to a new directory to contain your own customizations, or make edits in the gaia/customization/ directory itself. The path to this directory is referred to below as <DISTRIBUTION_PATH>; obviously change this to your directory path.
  3. Make your changes as required.
  4. Attach a Firefox OS device to your computer via USB, and check that it is recognised via ADB.
  5. Build Gaia, specifying the location of the customization sample with the GAIA_DISTRIBUTION_DIR environment variable, like this:
    make production GAIA_DISTRIBUTION_DIR=<DISTRIBUTION_PATH>
  6. You should now get a Gaia build on your Firefox OS device with customizations applied.

If you copy the customization sample directory to gaia/distribution/, you can then just run the make command without the extra environment variable:

make production

Note: Some customizations are done by the Gaia build scripts. Check our make options reference for Build Script customizations.

Note: SIM card-specific customizations are included at build time, but applied at runtime during the First Time Usage experience.

Buildtime Customizations

Let's now go through the different options available in the sample.

power/

Custom power on/off animations (or static images) are included here. Files can be MP4 for animations or PNG for static images.

Valid file names are:

  • carrier_power_on.png
  • carrier_power_on.mp4
  • carrier_power_off.png
  • carrier_power_off.mp4

ringtones/

Custom ringtones are included here. list.json should contain the filenames of the ringtones, like this:

  {
    "ringer_classic_courier.opus": "",
    "ringer_dream_theme.ogg": "",
    "ringer_loud_windchimes.opus": "",
    "ringer_bitbounce.opus": ""
  }

Custom ringtones are selectable in the Firefox OS settings app through Sound > Ringer. The default ringtone must be set in settings.json, using a DataURI; you can use the datauri command to create the DataURI, which is available on node/npm:

  1. Install it using the npm install datauri -g command.
  2. Convert the file to a DataURI with datauri <FILE>.

wallpapers/

Custom wallpapers (PNG files) should be included here and listed in list.json, after which they can be selected in the Firefox OS settings app through Display > Wallpaper.

The default wallpaper must be set in settings.json, using the following line:

"wallpaper.image": "image location"

Note: The image can be specified as a file path, or a dataURI.

browser.json

This file allows you to add customizations into the actual Browser app, such as bookmarks and default search engine. See the section Browser bookmarks & default search engine for more details on what to put in this file.

calendar.json

This file allows you to use your own custom calendars in the Firefox OS Calendar app. You'll need to specify your own Google Oauth credentials.  In addition, calendar CalDav API access is needed: To  generate the required API key and secret, you need to apply at Google's creating your client ID page; follow these instructions:

  1. Open the API console.
  2. Create a project and enable Calendar CalDav API in APIs & auth > APIs.
  3. Click on Credentials.
  4. Click on Create new client ID
  5. Set the Application type to Installed application, and Installed application type to Other, then press Create Client ID. This should give you a Client ID and Client secret.
  6. Open the calendar.json file, change the client_id and client_secret to the Client ID and Client secret you got from the Google API console, and save and close.

Note: API usage is limited to 1,000,000 requests/day.

camera-config.js (Gallery and Camera app image sizes)

{
  "maxImagePixelSize": 6000000,
  "maxSnapshotPixelSize": 4000000,
  "requiredEXIFPreviewSize": {
    "width": 1200,
    "height": 1222
  }
}

maxImagePixelSize and maxSnapshotPixelSize are the maximum pixel sizes of an image the Gallery and Camera apps are allowed to view. This defaults to 5 mega pixels (5*220 pixels; 5MP).

Optionally, you can also define variables to specify the minimum EXIF preview size that will be displayed as a full-screen preview by adding requiredEXIFPreviewSize property. If you do not specify this property then EXIF previews will only be used if they are big enough to fill the screen (via either width or height) in both landscape and portrait mode.

contacts.json

Contacts listed here will be included in the phone's contacts database as soon as Gaia is built.

Here's an example contacts.json file:

[
   {
     "name": ["John Doe"],
     "givenName": ["John"],
     "familyName": ["Doe"],
     "nickname": ["Johnny"],
     "category": ["Work", "Racing Team"],
     "email": [
       {
         "type": ["personal"],
         "value": "john.doe@example.org",
         "pref": true
       },
       {
         "type": ["work"],
         "value": "jdoe@example.com"
       }
     ],
     "adr": [
       {
         "type": ["personal"],
         "streetAddress": "123 Foopy St.",
         "locality": "San Francisco",
         "region": "Downtown",
         "postalCode": "94030",
         "countryName": "US"
       }
     ]
   },
   {
     "name": ["CarrierX"],
     "email": [
       {
         "type": ["work"],
         "value": "support@carrierx.com"
       }
     ],
     "url": [
       {
         "type": ["work"],
         "value": "https://www.carrierx.com"
       }
     ]
   }
 ]

Note: See the Contacts API page for details on the layout of Contacts objects.

Note: For SIM-card dependent customizations, see the Browser bookmarks and default search engine section.

device-features.json

Defines the hardware capabilities of the device. By default it contains:

{ 
  "ambientLight": true,
  "vibration": true,
  "usbHotProtocolSwitch": false
}

You can set the value to false if you want to disable device capabilities.

eu-roaming.json

This file lists the operators that should follow the EU roaming regulation and the apn setting for it. The file comprises three parts. The first part, home,  contains the operator codes of operators that should follow the regulation.  The next part, foreign,  contains the operator codes of the foreign operators that the EU roaming notification should be displayed when roaming to. The last part is the content of the EU roaming apn setting. By default the file looks like this:

{
  "home": null,
  "foreign": null,
  "defaultApns": []
}

If you would like to make the OS display the a roaming notification, you would fill in the file something like the following. This example displays the EU roaming notification when a user roams to a foreign network with operator codes "002, 02", with a sim card of codes "001, 01":

{
  "home": {
    "001": {
      "01": true
    }
  },
  "foreign": {
    "002": {
      "02": true
    }
  },
  "defaultApns": [{
    "apn": "eu.apn",
    "types": ["default"]
  }]
}

Note: All apn settings listed in the defaultApns field will also be displayed in the settings app by default.

homescreens.json

homescreens.json defines what apps to show in the Firefox OS dock and homescreen, and in which order. By default the file looks like this:

{"homescreens": [
   [
     ["apps", "communications", "dialer"],
     ["apps", "sms"],
     ["apps", "browser"],
     ["apps", "camera"]
   ]
 ]}

This causes the four described apps to appear in the dock. If we added another array, that set of apps would appear on page 1 of the homescreen, the next set on page 2, etc.

{"homescreens": [
   [ // We're in the dock!
     ["apps", "communications", "dialer"],
     ["apps", "sms"],
     ["apps", "browser"],
     ["apps", "camera"]
   ],
   [ // We're on Page 1 of the homescreen
     ["apps", "email"],
     ["apps", "settings"],
     ["apps", "clock"],
     ["apps", "calendar"]
   ],
   [ // We're on Page 2 of the homescreen
     ["external-apps", "customapp1"],
     ["external-apps", "customapp2"],
     ["external-apps", "customapp3"],
     ["external-apps", "customapp4"]
   ]
 ]}

The first item inside each sub-array is the folder the app appears inside; the second is the app directory name.

Collections

Note: In Firefox 2.0, the collections directory was moved from being inside the homescreen app to being inside their own collections app. Note also that some of the manifest fields also changed (see the funny collection manifest for an example): provider_id changed to categoryId, and apps changed to pinned.

Collections are groups of apps that have their own icon that appears on the homescreen. When this icon is tapped, a new screen appears containing all the icons for the apps in the collection. Have a look at the collections directory in the source code to see what collections are available by default:

  • funny: Enjoy the latest funny apps.
  • games: Play games online.
  • local: What's happening around you?
  • music: Listen to favorite songs.
  • news: Keep updated with your world news sources.
  • shopping: Follow shopping trends.
  • showbiz: Discover entertainment apps.
  • social: Follow you social networks in everywhere.
  • sports: The best apps about sports.
  • tv: Apps related to media.

In each of these directories you will find different resolution icon files, plus a manifest file that defines metadata about the scollection such as name, role, and paths to its icons.

Note: There are additional collections available on the E.me server, a total of 19 (the 10 above plus 9 additional ones.) These can be seen when you long tap the homescreen and choose the Add Smart Collections option.

In homescreens.json it's possible to define what collections to load, what pages they should appear on and in what order. For example, if we wanted to specify the shopping, social, sports and tv collections to appear, we would write this:

{"homescreens": [
   [
     ["apps/collection/collections", "shopping"],
     ["apps/collection/collections", "social"],
     ["apps/collection/collections", "sports"],
     ["apps/collection/collections", "tv"]
   ], [
     ["apps", "communications", "dialer"],
     ["apps", "sms"],
     ["apps", "browser"],
     ["apps", "camera"]
   ]
 ]}

Each top level array position refers to a page of the homescreen. Here, the collections would appear in the dock, and the individual apps would appear on page 1 of the homescreen.

Note: By default, four Collections are prefilled on the first page of the Gaia homescreen: Social, Games, Music, and Entertainment.

Note: Collection names are written in lowercase.

What collections contain

Collections are composed of two types of app.

Local apps are defined at build time by manifest files located at /apps/collection/collections/<collectionName>/manifest.collection. The local apps contained within each collection are defined in the manifest file. For example, the social collection (contains dialer, sms, contacts and email apps) manifest looks like so:

{
  "name": "Social",
  "role": "collection",
  "provider_id": "289", // adaptive search identifier
  "apps": [
    ["apps", "communications", "dialer"],
    ["apps", "sms"],
    ["apps", "communications", "contacts"],
    ["apps", "email"]
  ],
  "default_locale": "en-US",
  "icons": {
    "60": "/collections/social/icon.png",
    "90": "/collections/social/icon@1.5x.png",
    "120": "/collections/social/icon@2x.png"
  }
 }

Remote apps are supplied by the adaptive search provider at runtime, when the device is online.

How to translate collections

Collection translations have to be defined in locale files in within the homescreen app, in the apps/collection/locales/ directory. Each different locale file has a name structure looking like collections.<langCode>.properties — where <langCode> is for example fr for French — and contains simple lines containing the default English string and translated version. An example from the French locale file follows:

# Add bookmark to homescreen
add-to-home-screen=Ajouter à l’écran d’accueil
add-to-home-screen-header=Ajouter un lien
website-name=Nom du site web
address=Adresse
added-to-home-screen=Ajouté à l’écran d’accueil
Custom collections

Requires Firefox OS 1.3

As of Firefox OS 1.3, you can define your own custom collections. You simply create them inside the collections directory, and point to them inside collections.json, as shown above.

Vertical homescreen properties

In Firefox 2.0 and above, you can choose a vertical homescreen display instead of the default horizontal display. The vertical homescreen properties are set in default-homescreens.json, including what apps and collections should appear, how many columns the homescreen should have, and what bookmarks should appear. This can be overridden by a file called homescreens.json in the GAIA_DISTRIBUTION_DIR directory.

network.json (not in customization folder)

Requires Firefox OS 1.4 or below

Important: This is no longer supported, as of Firefox OS 1.4+.

In Firefox OS < 1.4, this file can be created in gaia/apps/settings/resources, and it allows you to set the network types supported by the device. Firefox OS supports the following types:

  • 'wcdma/gsm' (WCDMA preferred)
  • 'gsm'
  • 'wcdma'
  • 'wcdma/gsm-auto' (GSM preferred)
  • 'cdma/evdo' (CDMA preferred)
  • 'cdma'
  • 'evdo'
  • 'wcdma/gsm/cdma/evdo' (Automatic)

An example is as follows:

{
  "types":  [
    "cdma/evdo",
    "cdma", "evdo"
  ]
}

settings.json

  • Settings general: Requires Firefox OS 1.0.1
  • Default Rocketbar search provider: Requires Firefox OS 2.0

This file allows you to set default wallpaper/ringtones, lockscreen enabled/disabled status, bluetooth on/off status, etc. You can consult build/config/common-settings.json to find out what settings can be set;  for example you can set "wifi.enabled": false to disable wifi by default.

You put your custom settings in customization/settings.json.

Default Rocketbar search provider

In Firefox OS 2.0 and above, you can set the following additional settings inside settings.json, to set the default Rocketbar search provider:

"search.urlTemplate": "https://www.google.com/search?q={searchTerms}",
"search.suggestionsUrlTemplate": "https://www.google.com/complete/search?client=firefox&q={searchTerms}",
"search.iconUrl": "data:image/x-icon;base64,AAABAAIAEBAAAAAAAAB9AQAAJ [TRUNCATED FOR BREVITY]

Search provider customization

Requires Firefox OS 2.0

In Firefox 2.0+, there is a default list of search providers and icon files in apps/settings/resources/search/providers.json. You can configure these at build time by modifying customization/search/providers.json and adding the appropriate icon files into the same directory. The contents of this directory will overwrite app/settings/resources/search if it is found to exist at build time, and if you've built with make production GAIA_DISTRIBUTION_DIR=customization.

Customize default Homescreen apps

homescreen.appName allows you to set specific apps as default Homescreen apps.

{ "homescreen.appName": "homescreen-stingray" }

sms-blacklist.json

This file contains a custom SMS blacklist: numbers specified in this file can't have SMS messages sent to them. This list will overwrite blacklist.json in the SMS app. The numbers are specified in an array, like so:

["11223344", "55667788"]

cellbroadcast

Listening Channels:

  • availability: runtime: Settings — ril.cellbroadcast.searchlist
  • type: string
  • valid format: \d(-\d)?(,\d(-\d))*

Disable event reporting:

  • availability:
    • run time: Settings — ril.cellbroadcast.disabled
    • build time: Preference — ril.cellbroadcast.disabled
  • type: boolean
  • meaning: true to completely shutdown Cell Broadcast reporting.

Note: Default settings are available in operator_variant.xml.

support.json

This file contains support contacts, including online support & telephone support. When included, this file will overwrite support.json in the Settings app. Since these customizations will overwrite the default settings, you should copy those settings from the built-in apps and add your own customization onto them if you want to keep default settings and add extra resources.

Here's an example of what the JSON should look like:

{
   "onlinesupport": {
     "href": "http://support.mozilla.org/",
     "title": "Mozilla Support"
   },
   "callsupport": [
     {
       "href": "tel:12345678",
       "title": "Call Support 1"
     },
     {
       "href": "tel:87654321",
       "title": "Call Support 2"
     }
   ]
 }

WAP user agent profile (wapuaprof.json)

The WAP user agent profile overrides the user agent information when sending WAP packets. If you want to override the default WAP user agent profile based on MCC/MNC, you can use this one to do it  (further explained in runtime customization).

apps.list

This allows you to specify which apps you want to load up at runtime (in a similar manner to variant.json, as explained in the Applications section below.) The applications are specified like so:

apps/*
external-apps/*
outoftree_apps/*

You can specify individual apps rather than whole folders of apps, like this:

apps/email
apps/settings

Note: If you want to include custom external apps as part of your Gaia build, you need to build them in a specific way, and then place them into the gaia/external-apps/ folder. Read Building Prebundled web apps to find out how.

Important: Apps that you add as part of a customized Firefox OS build need to be added in agreement with Mozilla's Distribution Agreement.

Other customization options

There are many other customizations that can be made, which we should explore more. Let's look at them now.

Note: The build script used in many of the below sections can be found in gaia/build/applications-data.js. This gets copied into an init.json file in the browser app directory at build time.

Browser bookmarks and default search engines

  • Bookmarks: Requires Firefox OS 1.0.1
  • Default search engines: Requires Firefox OS 1.2

The default bookmarks and default search engine can be customised at build time, with different variants for each country and network in a single build. The customised data is inserted into the browser app the first time it is run, based on the MCC and MNC codes of the SIM card present in the device at the time.

Note: Bookmarks can be customised in Firefox OS 1.0.1+, but the procedure for doing so changed in version 2.1 as explained in Other single variant customizations section; default search engines can be customised in Firefox OS 1.2+.

The example below (browser.json) shows a configuration for Vivo in Brazil (724006, where 724 is Brazil and 006 is Vivo according to the MCC and MNC codes), along with a default fallback (000000) in case a non-matching SIM card or no SIM card is present.

content = {
   '000000': {
     'bookmarks': [
       { 'title': 'Mozilla',
         'uri': 'https://mozilla.org',
         'iconUri':
           'data:image/png;base64,AAABAAIAEBAAAAEAIABo[truncated]'
       },
       { 'title': 'Firefox OS',
         'uri': 'https://mozilla.org/firefoxos',
         'iconUri':
           'data:image/png;base64,AAABAAIAEBAAAAEA[truncated]'
       }
     ],
     'searchEngines' : [
        {
          'title': 'Google',
          'uri': 'https://www.google.com/search?q={searchTerms}',
          'iconUri':
            'data:image/png;base64,AAABAAIAEBAAAAEAIABoBAA[truncated]'
        }
      ],
      'settings' : {
        'defaultSearchEngine': 'https://www.google.com/search?q={searchTerms}'
      }
   },
   '724006': {
     "bookmarks": [
       { "title": "Vivo Busca",
         "uri": "https://www.google.com.br/m/search",
         "iconUri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC[truncated]"
       },
       { "title": "Serviços e Downloads",
         "uri": "http://vds.vivo.com.br",
         "iconUri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACA[truncated]"
       },
       {
         "title": "Site Vivo",
         "uri": "http://www.vivo.com.br/conteudosmartphone",
         "iconUri": "data:image/jpg;base64,/9j/4AAQSkZJRg[truncated]"
       }
     ],
     'searchEngines' : [
        {
          'title': 'Yahoo',
          'uri': 'https://search.yahoo.com/search?q={searchTerms}',
          'iconUri':
            'data:image/png;base64,AAABAAIAEBAAAAEAIABoBAA[truncated]'
        }
      ],
      'settings' : {
        'defaultSearchEngine': 'https://search.yahoo.com/search?q={searchTerms}'
      }
   }
 };

In the example, if a Vivo SIM card from Brazil is entered on first run the user will see Vivo bookmarks, and Yahoo as the default search engine. If another SIM card or no SIM card is entered on first run the user will see Mozilla bookmarks, and Google as the default search engine. There are a few important points to note:

  • The defaultSearchEngine property must match the uri property of the search engine specified. This string acts as a template for the {searchTerms} placeholder, which will get replaced with the user's search query at run time. Other values such as search strings may be appended to the query string in the URL template.
  • The favicon URLs shown are base64-encoded dataURIs of the image data (truncated for brevity) rather than HTTP URLs. This is recommended so that the icons will still appear the first time the browser is run, even if the user has not connected to the Internet yet.
  • Notice that multiple customisations can be applied for different networks and different countries in a single build, with a different 6 digit code representing each variant. The 6 digit code is constructed from the MCC code plus the MNC code, each padded with zeros to ensure it is 3 digits long.
  • When populating the default data the browser will first look for an exact match with the MCC and MNC codes, then if there is no match it will look for MCC+000, and finally if there's still no match it will fall back to 000+000.
  • When upgrading between versions of Gaia, new customisations will only be applied if that type of customisation is a new feature in the new version of Gaia being upgraded to. Previous customisations will not be overwritten.

Note: The browser application will show bookmarks in reverse order, the first bookmark in the json will be shown the last one and so on.

Single variant customization to override list of providers and Rocketbar search provider

Requires Firefox OS 2.0

  1. The default Rocketbar search provider and list of providers can also be customized per MCC/MNC — data added the first time the relevant SIM card is inserted into the phone — by specifying them in JSON files in your distribution directory:
  2. variant.json then defines which .json file is used to specify the settings for each MCC/MNC pair; see lines 47–48 in our sample:
    "search": "mobizilla/mobizilla_search.json",
    "default_search": "mobizilla/mobizilla_default_search.json",
  3. variant.json is placed in the root of your distribution directory.
  4. In order to apply the single variant configuration you have to set the GAIA_DISTRIBUTION_DIR variable to the path of your distribution directory when building Gaia.

Data and messaging settings

Device data and messaging settings are runtime-customizable.

To apply specific settings, change gaia/shared/resources/apn/apns_conf_local.xml, simply adding or editing carrier blocks as required:

 <apn carrier="Test Network"
      mcc="001"
      mnc="01"
      apn="internet"
      user="user"
      password="password"
      proxy="127.0.0.1"
      port="8080"
      mmsc="http://127.0.0.1"
      mmsproxy="127.0.0.1"
      mmsport="8080"
      authtype="0"
      type="default,supl,mms"
  />

Voicemail and cell broadcast settings

To apply specific voicemail and cell broadcast settings, change gaia/shared/resources/apn/operator_variant.xml. Add or edit a carrier block, changing attributes as needed:

   <operator carrier="Test Network with Operator Variant Settings"
       mcc="001"
       mnc="01"
       cellBroadcastSearchList="0,1,2,3"
       voicemail="999999"
   />

WAP user agent profile

The WAP user agent profile is another app that supports runtime customization. It overrides the user agent information when sending WAP packets, based on MCC/MNC. The profile overriding has url and tagname parts, but we only support url in our current implementation.

The WAP user agent profile uses the same coding style for its key as the browser app, although "000000" is used as the default profile. An example follows:

   {
     "000000": {
       "url": "http://example.url/default.xml"
     },
     "123001": {
       "url": "http://example.url/custom123001.xml"
     }
   }

In this example, the url of the default profile is http://example.url/default.xml; for MCC = 123 and MNC = 001, the url is http://example.url/custom123001.xml. If there was another ic card with MCC = 123 and MNC = 100, its url would be http://example.url/default.xml.

If the 000000 is removed from this example, like so:

  {
     "123001": {
       "url": "http://example.url/custom123001.xml"
     }
   }

the UA profile url of the ic card with MCC = 123 and MNC = 001 is now overridden as http://example.url/custom123001.xml. No others will be overridden.

If we have the "000000" as before, but we also have a "123001" case with no url inside it, like so:

   {
     "000000": {
       "url": "http://example.url/default.xml"
     },
     "123001": {}
   }

All UA profile urls will now be overridden as http://example.url/default.xml

Applications

Applications installed in Firefox OS can be customized at runtime, in a number of ways (see also Customizing the build-time apps). Perhaps the most powerful way is to edit the variant.json configuration file, which allows apps to be selectively installed and placed in the desired position in the homescreen, depending on the MCC/MNC. The customized applications will be added to the standard applications list.

The relevant part of the variant.json file typically looks like so.

   {
     "apps": {
       "puzzle":
         {
           "manifestURL": "https://owd.tid.es/store/packages/fe8e4a866c518a42db9d2041568684c1.webapp"
         },
       "store":
         {
           "manifestURL": "https://owd.tid.es/store/manifest.webapp",
           "installOrigin": "https://www.openwebdevice.com"
         }
     },
     "operators": [
       {
         "id": "movistar-co",
         "mcc-mnc": [
           "214-01",
           "214-02"
         ],
         "apps": [
           {
             "id": "store",
             "screen": 0,
             "location": 2
           }
         ]
       },
       {
         "id": "movistar-mx",
         "mcc-mnc": [
           "215-23"
         ],
         "apps": [
           {
             "id": "store",
             "screen": 0,
             "location": 2
           },
           {
             "id": "puzzle"
           }
         ]
       }
     ]
   }
  • The first object of the JSON is called apps, and defines the custom applications to be copied at buildtime. The example uses two applications, one hosted (store) and one packaged (puzzle). Notice that while packaged apps only require the manifestURL, hosted ones also need the installOrigin in order to download them.
  • The second object, called operators, is responsible of the configuration based on MCC/MNC. The object contains an array of objects for each MCC/MNC pair. These objects define the id of the operator, a MCC/MNC list for the configuration and a list of apps objects defining which applications are going to be installed at runtime in each case.
  • Each apps object requires an id property and has two optional arguments to set the position in the homescreen:
    • The screen property sets the screen number.
    • The location property sets the position on that screen.

Other single variant customizations

The same file variant.json file — used to configure applications at runtime depending on the MCC/MNC — also allows you to configure specific resources by adding some attributes under each operator object. Thus, an operator can have the following settings:

   { 
     "apps": {
       ...
     },
     "operators": [
       {
         "id": "movistar-co",
           "mcc-mnc": [
             "214-01",
             "214-02"
           ],
         "apps": [
           {
             "id": "store",
             "screen": 0,
             "location": 2
           }
         ],
         "support_contacts": "resources/support_contacts_movistar.json",
         "default_contacts": "resources/contacts_movistar.json",
         "ringtone": {
           "path": "resources/Movistar_Mid_ABR_128kbps.ogg",
           "name": "Tono Movistar"
         },
         "wallpaper": "resources/customize.jpg",
         "keyboard": "resources/keyboard_movistar.json",
         "network_type": "resources/network_type_movistar.json",
         "known_networks": "resources/known_networks_movistar.json",
         "data_ftu": true,
         "sms": "resources/sms_movistar.json",
         "topsites": "resources/topsites_movistar.json",
         "bookmarks": "resources/bookmarks_movistar.json",
         "data_roaming": true,
         "power": {
           "poweron": {
             "video": "app://operatorresources/resources/power/latam_power_on.mp4"
           },
           "poweroff": {
             "video": "resources/latam_power_off.mp4"
           }
         },
         "nfc": true
       }        
       ...
     ]
   }

And here are the details of the specific resources for each operator.

Support contacts

Requires Firefox OS 1.2

support_contacts specifies a path to a file containing contacts to be shown on the help screen (Settings > Help), offering the same functionality as support.json. The file format is:

   {
     "onlinesupport": {
       "title": "Mozilla Support",
       "href": "http://test.mozilla.org/support"
     },
     "callsupport1": {
       "title": "Call Support (Primary)",
       "href": "tel:14155550001"
     },
     "callsupport2": {
       "title": "Call Support (Secondary)",
       "href": "tel:14155550002"
     }
   }

Default contacts

Requires Firefox OS 1.2

default_contacts contains the path to a file containing contacts that will be preloaded to the Contacts application, depending on the MCC/MNC pair present at run time. The section names are the MCC/MNC pair, and section contents should be an array of contacts following the same format as contacts.json. For example:

    {
        "123123":
        [
            {name: ["John Doe"]},
            // etc
        ],
    }

Ringtone

Requires Firefox OS 1.3

ringtone sets the default ringtone and contains two attributes, both mandatory:

  • path: The path to the ringtone audio file.
  • name: The name to display when the ringtone is shown in settings.

Wallpaper

Requires Firefox OS 1.2

wallpaper contains the path to the image file (PNG) that will be set as the default wallpaper.

Keyboard settings

Requires Firefox OS 1.4

keyboard contains the path to a file containing keyboard settings configuration information. The file format is as follows:

 {
   "keyboard.vibration": true,
   "keyboard.autocorrect": false,
   "keyboard.clicksound": true,
   "keyboard.wordsuggestion": false
 }

Network Display Indicator

Requires Firefox OS 1.4

network_type contains the path to a file that will hold an associated text that will be shown to the user when that network is being used by the device — for each of the network types supported by the device. The text will be shown on the Settings app, status bar, and quick settings.

The status bar and all the occurrences on the Settings app will use the text value indicated in the file. For quick settings the file must contain a data_sprite key that will point to a css sprite holding the icons for all the supported network types.

The data_sprite key must always be a URL pointing to a preinstalled app on the device. A file format example follows:

 {
  "lte": "4G",
  "ehrpd": "4G",
  "hspa+": "H+",
  "hsdpa": "H",
  "hsupa": "H",
  "hspa": "H",
  "evdo0": "E",
  "evdoa": "E",
  "evdob": "E",
  "1xrtt": "1x",
  "umts": "3G",
  "edge": "E",
  "is95a": "2G",
  "is95b": "2G",
  "gprs": "2G",
  "wcdma/gsm": "2G/3G GSM auto",
  "gsm": "2G GSM",
  "wcdma": "3G GSM",
  "wcdma/gsm-auto": "2G GSM Preferred",
  "cdma/evdo": "2G/3G CDMA auto",
  "cdma": "2G CDMA",
  "evdo": "3G CDMA",
  "wcdma/gsm/cdma/evdo": "2G-3G GSM/CDMA auto",
  "data_sprite": "app://operatorresources/resources/quick_settings/images/data-sprite-latam.png"
 }

Pre-populate WiFi SSIDs

Requires Firefox OS 2.0

known_networks contains the path to a file containing descriptions of known wifi networks. Here is a file format example:

 {
  "OPEN": {
    "ssid": "OPEN"
  },
  "WEP-WITHOUTKEY": {
    "ssid": "wifi-WEP-WITHOUTKEY",
    "keyType": "WEP"
  },
  "WEP_KEY": {
    "ssid": "WEP-KEYOK",
    "keyType": "WEP",
    "capabilities": "",
    "password": "constrasenya1"
  },
  "WEP_KEYOK_WPS": {
    "ssid": "WEP-KEYOK-WPS",
    "keyType": "WEP",
    "capabilities":"WPS",
    "password": "constrasenya1"
  },
  "wpa": {
    "ssid": "macaFirefoxHotspot",
    "keyType": "WPA-PSK"
  },
  "WPA-PSK_KEY": {
    "ssid": "WPA-PSK-KEYOK",
    "keyType": "WPA-PSK",
    "capabilities":"",
    "password": "constrasenya1"
  },
  "WPA-PSK_KEY_WPS": {
    "ssid": "WPA-PSK-KEYOK-WPS",
    "keyType": "WPA-PSK",
    "capabilities":"WPS",
    "password": "constrasenya1"
  },
  "WPA-EAP-PSK_WITHOUTEAP": {
    "ssid": "WPA-EAP-WITHOUTKEY",
    "keyType": "WPA-EAP"
  },
  "WPA-EAP_SIM": {
    "ssid": "WPA-EAP-SIM",
    "keyType": "WPA-EAP",
    "eap": "SIM",
    "password": "constrasenya1"
  },
  "WPA-EAP-KEYOK-WPS": {
    "ssid": "WPA-EAP-KEYOK-WPS",
    "keyType": "WPA-EAP",
    "eap": "PEAP",
    "capabilities": "WPS",
    "password": "constrasenya1",
    "identity": "HI\\usr"
  },
  "WPA-EAP-KEYOK-CAPOK-PHASE2-OK": {
    "ssid": "WPA-EAP-KEYOK-CAPOK-PHASE2",
    "keyType": "WPA-EAP",
    "eap": "PEAP",
    "capabilities":"WPS",
    "phase2": "PAP",
    "password": "constrasenya1",
    "identity": "HI\\usr"
  }
 }

Data enabled/disabled by default during FTU

Requires Firefox OS 2.0

The data_ftu attribute defines if the data setting is enabled or disabled by default during FTU. This is a boolean value (true or false).

Maximum number of SMS to convert to MMS

Requires Firefox OS 2.0

sms contains the path to a file holding some customization details for SMS. Currently the only attribute that can be set is the maximum number of SMS messages that can be converted to MMS. A file format example follows:

 {
  "smsMaxConcat": 9
 }

Pre-populate browser top sites

Requires Firefox OS 2.0

topsites contains the path to a file containing an array of topsite objects. A topsite object has three parameters: the title (string), the uri (url) and the iconPath. Here is a file format example:

{
  "topsites": [
    {
      "title": "Movistar",
      "uri": "http://www.movistar.es",
      "iconPath": "resources/movistar.ico"
    }
  ]
}

Bookmarks

Requires Firefox OS 2.1

Note: For information about customizing bookmarks on earlier versions of Firefox OS see the Browser bookmarks and default search engines section.

bookmarks contains the path to a file containing an array of bookmark objects. The bookmark object has three parameters: the title (string), the uri (url) and the iconPath. File format example:

{
  "bookmarks": [
    {
      "title": "Google",
      "uri": "http://www.google.es",
      "iconPath": "resources/google.ico"
    }
  ]
}

Data roaming on/off by default

Requires Firefox OS 2.0

The data_roaming attribute defines if data roaming is enabled by default; its value is a boolean (true or false).

Power on/off operator animation

Requires Firefox OS 2.0

Custom power on/off animations are configured using an object as a value for the power attribute. The object contains two attributes, one for the boot animation when the device is switched on (poweron) and the other one for the animation when the device shuts down. Both attributes are configured with a key value identifying the resource to be loaded — the resource key should be video and the value is a path to the resource. Note that the path can be a local path to the resource in the build machine filesystem (for example resource/afile.png) or a URI to file inside a Gaia application that will be installed in the device (for example app://name.domain/path/to/video.mp4).

Here is an example of the full structure of a power object:

"power": {
  "poweron": {
    "video": "app://operatorresources/resources/power/latam_power_on.mp4"
  },
  "poweroff": {
    "video": "resources/Power_off_test.mp4"
  }
}

NFC enabled/disabled by default

Requires Firefox OS 2.0

The nfc attribute defines if Near Field Communication is enabled by default; its value is a boolean (true or false).

Building Prebundled web apps

Earlier on, we discussed the apps.list file, and how this can be used to add built-in apps to your build. These apps need to be built in a certain way, then added to the gaia/external-apps directory.

To build Prebundled web apps, you can utilize our preload-app-toolkit script, which builds a prebundled webapp from a given .webapp URL. It can accept hosted web app manifests, or packaged app mini-manifests.

To bundle a single web app

Find a .webapp URL that want to bundle, and run the command to bundle it, as follows:

python preload.py http://<webapp url>

This will generate a directory with the same name as the target webapp's name, e.g. accuweather.

Batch process to bundle multiple web apps

You can create a file called list, containing all the app names and .webapp locations you want to bundle all together in a batch. The format is:

myFirstApp,https://www.firstapp.com/manifest.webapp
mySecondApp,https://www.secondapp.com/manifest.webapp
etc.

You need to save this list file in the same directory as our preload.py script, then run the following command:

$ python preload.py

The preload.py script will parse the list file and do the batch conversion for you.

Prebundled web app metadata.json

Every Prebundled webapp should have a metadata.json file contained within its root directory. The Firefox Marketplace counts on this metadata.json file for auto-updating. This file is auto-generated by the preload.py script.

For a hosted webapp, the properties of metadata.json are:

  • origin: The domain name of the webapp url.
  • manifestURL: The location of the web app manifest for a hosted app.
  • installOrigin(hosted): The location the app was installed from in the customization. For customizations, this should always be https://marketplace.firefox.com.
  • etag: This is the webapp manifest etag used for checking for updates. The etag value is retrieved by the parse html header when downloading the .webapp file from the server.
  • external: This is a required field in Firefox OS 2.1+. The value is true for prebundled apps, and false for non-external apps. This is used for checking if fine tuning the file order in the application.zip is necessary (fine tuning will occur if the value is set to true).

For a packaged webapp, the properties of metadata.json are:

  • manifestURL: This should be the location of the mini-manifest. For customizations right now, the manifestURL will always be a mini-manifest from marketplace.firefox.com.
  • installOrigin(hosted): The location the app was installed from in the customization. For customizations, this should always be https://marketplace.firefox.com.
  • etag: This is the webapp manifest etag used for checking for updates. The etag value is retrieved by the parse html header when downloading the .webapp file from the server.
  • external: This is a required field in Firefox OS 2.1+. The value is true for prebundled apps, and false for For non-external apps it should be false. Use for checking if fine tunining file order in the application.zip is needed ( fine tune if the value is true ).
  • packageEtag: This is the app package's etag, retrieved by the parse html header when downloading the package from the server once an update has been detected.

Packaged web app auto-updates: update.webapp format

Packaged webapps have an update.webapp file, which is used for auto-updates. The format is similar to manifest.webapp, but you have to include additional attributes:

  • package_path is the path to the packaged (zip) file.
  • size is the package size, in bytes.
  {
    "name": "Game Pack",
    "icons": {
      "60": "/icon-60.png", 
      "128": "/icon-128.png"
    },
    "version": "1.1.2",
    "package_path": "/application.zip",
    "developer": {
      "url": "http://abc.com", 
      "name": "abc Inc."
    },
    "release_notes": "2nd release",
    "locales": {
      "es": {
        "launch_path": "/index-es.html", 
        "description": "show me customization."
      }
    },
    "size": 5460141
  }

Pre-bundled web app AppCache format

If your web app's manifest.webapp has an appcache_path included in it, the preload.py script will fetch the AppCache file pointed to, and pre-fetch all the resources described in the AppCache file. The Pre-bundled webapp AppCache is a bit different, as Gecko recognizes a different format, but this is auto-generated by the preload.py script.

The translated file structure is:

    <app name>
       ├── manifest.webapp
       ├── metadata.json
       └── cache
             ├── manifest.appcache
             └── <resources>

Note: If a different name is given to the AppCache file in the appcache_path, it needs to be renamed to manifest.appcache and saved in the cache folder.

FAQ

The following is a list of common questions and answers about market customizations.

What can be customized?

  • Brand
    • Start up & Power off animations
    • Network name on Lock screen and in Utility Tray
    • First Run Experience logos
  • Localization
    • Installed locales (shared/locales)
    • Default locale (GAIA_DEFAULT_LOCALE)
    • Default keyboard layouts (Multiple keyboards can be enabled, not tied to locale)
  • Apps
    • Preinstalled third party apps
    • Home grid app placement
    • Licensing
    • In-app payment provider configuration
  • Settings
    • Default screen brightness
    • Device Information — Model (name or #)
    • Device Information — Legal Information link or content
    • Help — Online support link
    • Help — Call support phone number
    • Help — User guide link
    • APN
    • MMS message size limitation
    • MMS message retrieval mode
  • Media preloads
    • Wallpapers
    • Music
    • Videos
    • Gallery
  • Sounds
    • Start up & Power off
    • Ring tone
    • Message tone
  • Everything.me
    • Option to enable or disable the feature
    • Set of default categories and apps
  • Browser
    • Default bookmarks
    • Default search engine

How and where do you define a customized app grid layout?

This is currently defined in gaia/apps/homescreen/js/init.json. customize.py takes care of building this in the correct format.

Is it possible to define whether an app is removable in the homescreen configuration?

No. All apps in /system/b2g are non-removable; those in /data are removable. Since all preloaded apps come from /system, we need to move them to /data if we want them to be removable.

How do you add a preloaded packaged or hosted app to the build?

These should both be added to gaia/external-apps. customize.py will allow entry of the URL to a packaged app or a hosted app manifest, and will download it into the correct place and create metadata.json. This will serve as the "build step".

We have different metadata for packaged and hosted apps to distinguish them.

See Building Prebundled web apps for more details.

How do you prepare a preloaded hosted app for initial offline support?

You need to provide all the files to cache in the directory external-apps/MY_APP/cache, along with the AppCache manifest.

See Building Prebundled web apps for more details.

What Marketplace Customizations Are Possible?

  • On-device
    • The customization on the device regarding payments is limited to populating a whitelist of payment providers. There are a couple prefs for this, documented on Web Payments.
    • For example, Mozilla B2G phones will ship with our implementation of the payment provider in a whitelist so that it is accessible to the Marketplace and third party apps for in-app purchases via navigator.mozPay. Some more info on providers is available at Web Payment Providers.
    • If any carrier wants to implement their own payment processor and whitelist it, they are free to do so. However, the Firefox Marketplace is only configured to enable purchases through Mozilla's payment provider at this time.
  • On-server
    • The merchant app sets a price point for the product and Mozilla's backend payment processor chooses the currency based on the user's network. None of currency, regional taxation, or l10n can be controlled by device configs (yet).
    • Category in the Firefox Marketplace specific to the carrier with your operator logo/name in the region.
    • Featured apps / promotions in the Firefox Marketplace, specified by the Carrier.

There are many other considerations when adding a region or carrier.  See Adding Regions and Carriers for more details.

How do I package and store per-market customization changes?

Store only the files changed; currently these are in various locations in the filesystem. In B2G v2, we are considering consolidating these into a single location, similar to the branding directories we have for Gecko.

How do you build the product with a specific market's configuration?

Copy your changed files into a checkout of Gaia, and build using that modified Gaia. customize.py will provide a UI for setting relevant switches, create the appropriate files in the appropriate places in the gaia checkout, and then build the profile from that Gaia.

How to customize power on / off animation?

  • This animation uses Android's bootanimation.zip/desc.txt format.
  • This lets us create multi-part animation sequences where we can specify things like size, framerate, and number of times an animation sequence loops for each part.
  • There is also an animated PNG transition animation that bridges the gap between this bootanimation.zip sequence and the transition to the lockscreen, which is performed by Gaia.
  • The size on disk of the default animation is 8.2MB (looping) + 3.6MB (frame 18 transition) = 11.8MB total.
  • Currently, the shutdown animation is a custom css animation based on a design specified in bug 809342.

Document Tags and Contributors

 Last updated by: chrisdavidmills,