The Settings app allows users to configure device settings and also responds to incoming activities that allow app developers to display specific settings views from apps (e.g. show the wifi settings panel if no data connection is available). This article explains how it works.
mozSettings API and Data binding
Technically speaking, the Settings app is the UI that provides users with access to the certified window.navigator.mozSettings API.
The Settings app automatically handles basic settings operations such as binding data fields and mozSettings values — all basic operations such as toggling a setting or changing an input value will also result in the relevant mozSettings value being changed.
The window.navigator.mozSettings
API accesses the settings data from Gecko. The usage looks something like this:
navigator.mozSettings.createLock().set(values);
For set data.
Note: We need to use createLock()
to lock the settings before reading or writing any mozSettings
values.
To retrieve data, we could use get and set a callback function to start some operation upon the data:
var reqTimerGoBack = window.navigator.mozSettings.createLock().get('icc.goBackTimeout'); reqTimerGoBack.onsuccess = function icc_getTimerGoBackSuccess() { goBackTimer.timeout = reqTimerGoBack.result['icc.goBackTimeout']; ... };
The data is stored in an instance.result
dict.
From Firefox OS 2.0, a single mozSettings
instance can be reused via js/modules/settings_cache.js:
var SettingsCache = require('modules/settings_cache'); SettingsCache.getSettings(function(result){ var onlineSupportTitle = result['support.onlinesupport.title']; ... });
Navigation
When users open the Settings app, they see several panels listed on the overview page, which are functional independent pages. SettingsService.navigate
(js/module/settings_service.js) controls navigation between those pages.
Note: For legacy panels (which are not yet ported to the new structure), settings.currentPanel is used instead of SettingsService.navigate to navigate
between panels.
Since Firefox OS will support tablet devices as well as mobiles, the Settings app has two different types of navigation model implemented:
- One column (for mobile)
- Two column (for tablet)
While called, SettingsService.navigate
determines what navigation model to use via the following code:
if (_isTabletAndLandscape()) { PageTransitions.twoColumn(oldPanel, newPanel, callback); } else { PageTransitions.oneColumn(oldPanel, newPanel, callback); }
Panels
From Firefox OS 2.0 onwards, the basic panel structure is defined in js/modules/panel.js. It defines six lifecycle stats:
init
beforeShow
show
hide
beforeHide
uninit
All new settings panels are inherited from SettingsPanel
, which extends Panel
’s functionalities. The code is contained in js/modules/settings_panel.js:
onInit: function(panel, initOptions) { ... PanelUtils.activate(panel); }, onBeforeShow: function(panel, beforeShowOptions) { // Preset the panel every time when it is presented. PanelUtils.preset(panel); _addListeners(panel); ... },
PanelUtils.activate
— defined in js/modules/panel_utils.js — is used to parse all links in the panel and adds corresponding handlers in onInit
stat, and PanelUtils.preset
is used to preset elements with the settings values in the onBeforeShow
stat.
All new settings panels are defined in the js/panels folder.
AMD module and Build time optimization
From Firefox OS 2.0 onwards, the Settings app uses the AMD modules pattern to implement each panel. The AMD modules are loaded via Alemeda (a lighter version of RequireJS) and built/optimized using r.js
(the RequireJS optimizer). The Settings app still had dependencies on files (shared/js) which aren’t AMD modules. For those it uses the shim
options defined in settings/js/config/require.js.
See also
The Settings app has a build-in README which is useful to read for a further information on Settings (Mainly written by Arthur Chen and Fred Lin).