mozilla

Revision 651751 of Architecture de Firefox OS

  • リビジョンの URL スラグ: Mozilla/Firefox_OS/Platform/Architecture
  • リビジョンのタイトル: Firefox OS architecture
  • リビジョンの ID: 651751
  • 作成日:
  • 作成者: yvesd
  • 現行リビジョン いいえ
  • コメント beginning translation

このリビジョンの内容

Cet article est une vue d'ensemble de l'architecture de la plateforme Firefox OS, présentant les concepts-clés et expliquant sommairement comment les composants intérragissent.

Note: Gardez à l'esprit que Firefox OS est toujours un produit non finalisé ("Pre-release"). L'architecture décrite ici n'est pas forcément finalisée, et des chanagements  peuvent survenir.

Terminologie Firefox OS

Voici quelques termes à connaître avant de lire la suite de notre documentation de Firefox OS.

B2G
Accronyme de Boot to Gecko.
Boot to Gecko
Le nom de code du système d'exploitation Firefox OS lors de sa conception. Vous trouverez souvent ce terme en référence à Firefos OS, car il a été utilisé longtemps avant que le projet n'ait de nom officiel.
Firefox OS
Firefox OS correspond aux services de support et de branding de Mozilla (et ceux de ses partenaires OEM) ajoutés au-dessus de Boot to Gecko, pour créer un produit fini.
Gaia
L'interface utilisateur de la plateforme Firefox OS. Tout ce qui est affiché à l'écran une fois que Firefox OS est lancé, est produit par la couche Gaia. Gaia implements the lock screen, home screen, and all the standard applications you expect on a modern smartphone. Gaia is implemented entirely using HTML, CSS, and JavaScript. Its only interfaces to the underlying operating system are through open Web APIs, which are implemented by the Gecko layer. Third party applications can be installed alongside the Gaia layer.
Gecko
This is the Firefox OS application runtime; that is, the layer that provides all of the support for the trifecta of open standards: HTML, CSS, and JavaScript. It makes sure those APIs work well on every operating system Gecko supports. This means that Gecko includes, among other things, a networking stack, graphics stack, layout engine, a JavaScript virtual machine, and porting layers.
Gonk
Gonk is the lower level operating system of the Firefox OS platform, consisting of a Linux kernel (based on the Android Open Source Project (AOSP)) and userspace hardware abstraction layer (HAL). The kernel and several of the user space libraries are common open-source projects: Linux, libusb, bluez, and so forth. Some of the other parts of the HAL are shared with the AOSP: GPS, camera, and others. You could say that Gonk is a very simple Linux distribution. Gonk is a porting target of Gecko; that is, there's a port of Gecko to Gonk, just like there's a port of Gecko to OS X, Windows, and Android. Since the Firefox OS project has full control over Gonk, we can expose interfaces to Gecko that can't be exposed on other operating systems. For example, Gecko has direct access to the full telephony stack and display frame buffer on Gonk, but doesn't have this access on any other operating system.
Jank
This term, often used in the mobile apps space, refers to the effect of slow/inefficient code operations in an app, which block updating of the UI and cause it to become laggy or unresponsive. Our Gaia engineers use various optimization techniques to try to avoid this at all costs.

Architecture diagram

Firefox OS Architecture

Firefox OS bootup procedure

This section describes the process by which Firefox OS devices boot, what parts are involved, and where. As a quick reference, the general system bootup flow goes from bootloaders in the Kernel space, to init in the native code, to B2G and then Gecko in the user space, and then finally to the system app, window manager, then homescreen app inside Gecko. This is what all other apps are executed on top of.

The bootstrapping process

When a Firefox OS device is first turned on, execution begins in the primary bootloader. From there, the process of loading the main operating system proceeds in the typical way; a succession of increasingly higher-level bootloaders bootstrap the next loader in the chain. At the end of the process, execution is handed off to the Linux kernel.

There are a few points worth noting about the boot process:

  • The bootloaders usually display the first splash screen seen by the user during device startup; this is typically a vendor logo.
  • The bootloaders implement flashing an image to the device. Different devices use different protocols; most phones use the fastboot protocol, but the Samsung Galaxy S II uses the odin protocol.
  • By the end of the bootstrapping process, the modem image is usually loaded and running on the modem processor. How this happens is highly device-specific and may be proprietary.

The Linux kernel

The Linux kernel(s) used by Gonk is very similar to the upstream Linux from which it's derived (based on the Android Open Source Project). There are a few changes made by the AOSP that have not yet been upstreamed. In addition, vendors sometimes modify the kernel and upstream those changes on their own schedule. In general, though, the Linux kernel is close to stock.

The startup process for Linux is well-documented elsewhere on the Internet, so this article won't cover that.

The Linux Kernel will bring up devices and run essential processes. It will execute processes defined in init.rc and the successor init.b2g.rc to boot essential process such as b2g (FirefoxOS basic process, containing Gecko) and rild (telephony related process that might proprietary by different chipsets) — see below for more details. At the end of the process, a userspace init process is launched, as it is in most UNIX-like operating systems.

Once the init process is launched, the Linux kernel handles system calls from userspace, and interrupts and the like from hardware devices. Many hardware features are exposed to userspace through sysfs. For example, here's a code snippet that reads the battery state in Gecko:

FILE *capacityFile = fopen("/sys/class/power_supply/battery/capacity", "r");
double capacity = dom::battery::kDefaultLevel * 100;
if (capacityFile) {
  fscanf(capacityFile, "%lf", &capacity);
  fclose(capacityFile);
}

More on the init process

The init process in Gonk handles mounting the required file systems and spawns system services. After that, it stays around to serve as a process manager. This is quite similar to init on other UNIX-like operating systems. It interprets scripts (that is, the init*.rc files) that consist of commands describing what should be done to start various services. The Firefox OS init.rc is typically the stock Android init.rc for that device patched to include the things required to kick-start Firefox OS, and varies from device to device.

One key task the init process handles is starting up the b2g process; this is the core of the Firefox OS operating system.

The code in init.rc that starts this up looks like this:

service b2g /system/bin/b2g.sh
    class main
    onrestart restart media

Note: Exactly how much init.rc differs from the Android version varies from device to device; sometimes, init.b2g.rc is simply appended, and sometimes the patches are more significant.

The userspace process architecture

Now it's useful to take a high-level look at how the various components of Firefox OS fit together and interact with one another. This diagram shows the primary userspace processes in Firefox OS.

Userspace diagram

Note: Keep in mind that since Firefox OS is under active development, this diagram is subject to change, and may not be entirely accurate.

The b2g process is the primary system process. It runs with high privileges; it has access to most hardware devices. b2g communicates with the modem, draws to the display framebuffer, and talks to GPS, cameras, and other hardware features. Internally, b2g runs the Gecko layer (implemented by libxul.so). See {{anch("Gecko")}} for details on how the Gecko layer works, and how b2g communicates with it.

b2g

The b2g process may, in turn, spawn a number of low-rights content processes. These processes are where web applications and other web content are loaded. These processes communicate with the main Gecko server process through IPDL, a message-passing system.

The b2g process runs libxul, which references b2g/app/b2g.js to get default preferences. From the preferences it will open the described HTML file b2g/chrome/content/shell.html, which is compiled within the omni.ja file. shell.html includes b2g/chrome/content/shell.js file, which triggers the Gaia system app.

rild

The rild process is the interface to the modem processor. rild is the daemon that implements the Radio Interface Layer (RIL). It's a proprietary piece of code that's implemented by the hardware vendor to talk to their modem hardware. rild makes it possible for client code to connect to a UNIX-domain socket to which it binds. It's started up by code like this in the init script:

service ril-daemon /system/bin/rild
    socket rild stream 660 root radio

rilproxy

In Firefox OS, the rild client is the rilproxy process. This acts as a dumb forwarding proxy between rild and b2g. This proxy is needed as an implementation detail; suffice it to say, it is indeed necessary. The rilproxy code can be found on GitHub.

mediaserver

The mediaserver process controls audio and video playback. Gecko talks to it through an Android Remote Procedure Call (RPC) mechanism. Some of the media that Gecko can play (OGG Vorbis audio, OGG Theora video, and WebM video) are decoded by Gecko and sent directly to the mediaserver process. Other media files are decoded by libstagefright, which is capable of accessing proprietary codecs and hardware encoders.

Note: The mediaserver process is a "temporary" component of Firefox OS; it's there to aid in our initial development work, but is expected to go away eventually. This will most likely not happen until Firefox OS 2.0 at the earliest, however.

netd

The netd process is used to configure network interfaces.

wpa_supplicant

The wpa_supplicant process is the standard UNIX-style daemon that handles connectivity with WiFi access points.

dbus-daemon

The dbus-daemon implements D-Bus, a message bus system that Firefox OS uses for Bluetooth communication.

Gecko

Gecko, as previously mentioned, is the implementation of web standards (HTML, CSS, and JavaScript) that is used to implement everything the user sees on Firefox OS.

Note: To search the Gecko codebase, you could use http://dxr.mozilla.org. It’s more fancy and provides good reference features, but with limited repositories. Or you could try the traditional http://mxr.mozilla.org, which contains more Mozilla projects.

b2g/

The b2g folder contains mainly Firefox OS-related functions.

b2g/chrome/content

Contains Javascript files run above the system app.

b2g/chrome/content/shell.html

The entry point into Gaia — the HTML for the system app. shell.html pulls in settings.js and shell.js:

<script type="application/javascript;version=1.8" src="chrome://browser/content/settings.js"> </script>
<script type="application/javascript;version=1.8" src="chrome://browser/content/shell.js"> </script>

settings.js contains system default setting parameters.

b2g/chrome/content/shell.js

shell.js is the first script to load in the Gaia system app.

shell.js imports all required modules, registers key listeners, defines sendCustomEvent and sendChromeEvent to communicate with Gaia, and provides webapp install helpers: indexedDB quota, RemoteDebugger, keyboard helper, and screenshot tool.

But the most important function of shell.js is to launch the Gaia system app, then hand over the overall systems related management work to the Gaia system app.

let systemAppFrame =
  document.createElementNS('http://www.w3.org/1999/xhtml', 'html:iframe');
    ...
  container.appendChild(systemAppFrame);
b2g/app/b2g.js

This script contains predefined settings, like about:config in browser, and the same as Gaia's pref.js. These settings can be changed from the Settings app, and can be overwritten with Gaia’s user.js in the Gaia build script.

dom/{API}

New API implementations (post-b2g) will be located in dom/. Older APIs will be located in dom/base, for example Navigator.cpp.

dom/apps

.jsm will be loaded — .js API implementations such as webapp.js install, getSelf, etc.

dom/apps/src/

All permissions are defined in PermissionsTable.jsm

dom/webidl

WebIDL is the language used to define web APIs. For supported attributes, read WebIDL_bindings.

hal/gonk

This directory contains files related to the gonk port layer.

Generated files

module/libpref/src/init/all.js

Contains all config files.

/system/b2g/ omni.ja and omni.js

Contains the pack of styles for resources in the device.

Processing input events

Most action inside Gecko is triggered by user actions. These actions are represented by input events (such as button presses, touches to a touch screen device, and so forth). These events enter Gecko through the {{source("widget/gonk/nsAppShell.cpp", "Gonk implementation")}} of {{interface("nsIAppShell")}}, a Gecko interface that is used to represent the primary entrance points for a Gecko application; that is, the input device driver calls methods on the nsAppShell object that represents the Gecko subsystem in order to send events to the user interface.

For example:

void GeckoInputDispatcher::notifyKey(nsecs_t eventTime,
                                     int32_t deviceId,
                                     int32_t source,
                                     uint32_t policyFlags,
                                     int32_t action,
                                     int32_t flags,
                                     int32_t keyCode,
                                     int32_t scanCode,
                                     int32_t metaState,
                                     nsecs_t downTime) {
  UserInputData data;
  data.timeMs = nanosecsToMillisecs(eventTime);
  data.type = UserInputData::KEY_DATA;
  data.action = action;
  data.flags = flags;
  data.metaState = metaState;
  data.key.keyCode = keyCode;
  data.key.scanCode = scanCode;
  {
    MutexAutoLock lock(mQueueLock);
    mEventQueue.push(data);
  }
  gAppShell->NotifyNativeEvent();
}

These events come from the standard Linux input_event system. Firefox OS uses a {{source("widget/gonk/libui/InputReader.cpp", "light abstraction layer")}} over that; this provides some nice features like event filtering. You can see the code that creates input events in the EventHub::getEvents() method in {{source2("widget/gonk/libui/EventHub.cpp")}}.

Once the events are received by Gecko, they're dispatched into the DOM by {{source("widget/gonk/nsAppShell.cpp", "nsAppShell")}}:

static nsEventStatus sendKeyEventWithMsg(uint32_t keyCode,
                                         uint32_t msg,
                                         uint64_t timeMs,
                                         uint32_t flags) {
    nsKeyEvent event(true, msg, NULL);
    event.keyCode = keyCode;
    event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_MOBILE;
    event.time = timeMs;
    event.flags |= flags;
    return nsWindow::DispatchInputEvent(event);
}

After that, the events are either consumed by Gecko itself or are dispatched to Web applications as DOM events for further processing.

Graphics

At the very lowest level, Gecko uses OpenGL ES 2.0 to draw to a GL context that wraps the hardware frame buffers. This is done in the Gonk implementation of {{source("widget/gonk/nsWindow.cpp", "nsWindow")}} by code similar to this:

gNativeWindow = new android::FramebufferNativeWindow();
sGLContext = GLContextProvider::CreateForWindow(this);

The FramebufferNativeWindow class is brought in directly from Android; see FramebufferNativeWindow.cpp. This uses the gralloc API to access the graphics driver in order to map buffers from the framebuffer device into memory.

Gecko uses its Layers system to composite drawn content to the screen. In summary, what happens is this:

  1. Gecko draws separate regions of pages into memory buffers. Sometimes these buffers are in system memory; other times, they're textures mapped into Gecko's address space, which means that Gecko is drawing directly into video memory. This is typically done in the method BasicThebesLayer::PaintThebes().
  2. Gecko then composites all of these textures to the screen using OpenGL commands. This composition occurs in ThebesLayerOGL::RenderTo().

The details of how Gecko handles the rendering of web content is outside the scope of this document.

Hardware Abstraction Layer (HAL)

The Gecko hardware abstraction layer is one of the porting layers of Gecko. It handles low-level access to system interfaces across multiple platforms using a C++ API that's accessible to the higher levels of Gecko. These APIs are implemented on a per-platform basis inside the Gecko HAL itself. This hardware abstraction layer is not exposed directly to JavaScript code in Gecko.

How the HAL works

Let's consider the {{domxref("window.navigator.vibrate", "Vibration")}} API as an example. The Gecko HAL for this API is defined in {{source2("hal/Hal.h")}}. In essence (simplifying the method signature for clarity's sake), you have this function:

void Vibrate(const nsTArray<uint32> &pattern);

This is the function called by Gecko code to turn on vibration of the device according to the specified pattern; a corresponding function exists to cancel any ongoing vibration. The Gonk implementation of this method is in {{source2("hal/gonk/GonkHal.cpp")}}:

void Vibrate(const nsTArray<uint32_t> &pattern) {
  EnsureVibratorThreadInitialized();
  sVibratorRunnable->Vibrate(pattern);
}

This code sends the request to start vibrating the device to another thread, which is implemented in VibratorRunnable::Run(). This thread's main loop looks like this:

while (!mShuttingDown) {
  if (mIndex < mPattern.Length()) {
    uint32_t duration = mPattern[mIndex];
    if (mIndex % 2 == 0) {
      vibrator_on(duration);
    }
    mIndex++;
    mMonitor.Wait(PR_MillisecondsToInterval(duration));
  }
  else {
    mMonitor.Wait();
  }
}

vibrator_on() is the Gonk HAL API that turns on the vibrator motor. Internally, this method sends a message to the kernel driver by writing a value to a kernel object using sysfs.

Fallback HAL API implementations

The Gecko HAL APIs are supported across all platforms. When Gecko is built for a platform that doesn't expose an interface to vibration motors (such as a desktop computer), then a fallback implementation of the HAL API is used. For vibration, this is implemented in {{source2("hal/fallback/FallbackVibration.cpp")}}.

void Vibrate(const nsTArray<uint32_t> &pattern) {
}

Sandbox implementations

Because most web content runs in content processes with low privileges, we can't assume those processes have the privileges needed to be able to (for example), turn on and off the vibration motor. In addition, we want to have a central location for handling potential race conditions. In the Gecko HAL, this is done through a "sandbox" implementation of the HAL. This sandbox implementation simply proxies requests made by content processes and forwards them to the "Gecko server" process. The proxy requests are sent using IPDL.

For vibration, this is handled by the Vibrate() function implemented in {{source2("hal/sandbox/SandboxHal.cpp")}}:

void Vibrate(const nsTArray<uint32_t>& pattern, const WindowIdentifier &id) {
  AutoInfallibleTArray<uint32_t, 8> p(pattern);

  WindowIdentifier newID(id);
  newID.AppendProcessID();
  Hal()->SendVibrate(p, newID.AsArray(), GetTabChildFrom(newID.GetWindow()));
}

This sends a message defined by the PHal interface, described by IPDL in {{source2("hal/sandbox/PHal.ipdl")}}. This method is described more or less as follows:

Vibrate(uint32_t[] pattern);

The receiver of this message is the HalParent::RecvVibrate() method in {{source2("hal/sandbox/SandboxHal.cpp")}}, which looks like this:

virtual bool RecvVibrate(const InfallibleTArray<unsigned int>& pattern,
            const InfallibleTArray<uint64_t> &id,
            PBrowserParent *browserParent) MOZ_OVERRIDE {

  hal::Vibrate(pattern, newID);
  return true;
}

This omits some details that aren't relevant to this discussion; however, it shows how the message progresses from a content process through Gecko to Gonk, then to the Gonk HAL implementation of Vibrate(), and eventually to the Vibration driver.

DOM APIs

DOM interfaces are, in essence, how web content communicates with Gecko. There's more involved than that, and if you're interested in added details, you can read about the DOM. DOM interfaces are defined using IDL, which comprises both a foreign function interface (FFI) and object model (OM) between JavaScript and C++.

The vibration API is exposed to web content through an IDL interface, which is provided in {{source("dom/interfaces/base/nsIDOMNavigator.idl", "nsIDOMNavigator.idl")}}:

[implicit_jscontext] void mozVibrate(in jsval aPattern);

The jsval argument indicates that mozVibrate() (which is our vendor-prefixed implementation of this non-finalized vibration specification) accepts as input any JavaScript value. The IDL compiler, xpidl, generates a C++ interface that's then implemented by the Navigator class in {{source("dom/base/Navigator.cpp", "Navigator.cpp")}}.

NS_IMETHODIMP Navigator::MozVibrate(const jsval& aPattern, JSContext* cx) {
  // ...
  hal::Vibrate(pattern);
  return NS_OK;
}

There's a lot more code in this method than what you see here, but it's not important for the purposes of this discussion. The point is that the call to hal::Vibrate() transfers control from the DOM to the Gecko HAL. From there, we enter the HAL implementation discussed in the previous section and work our way down toward the graphics driver. On top of that, the DOM implementation doesn't care at all what platform it's running on (Gonk, Windows, OS X, or anything else). It also doesn't care whether the code is running in a content process or in the Gecko server process. Those details are all left to lower levels of the system to deal with.

The vibration API is a very simple API, which makes it a good example. The SMS API is an example of a more complex API which uses its own "remoting" layer connecting content processes to the server.

Radio Interface Layer (RIL)

The RIL was mentioned in the section {{anch("The userspace process architecture")}}. This section will examine how the various pieces of this layer interact in a bit more detail.

The main components involved in the RIL are:

rild
The daemon that talks to the proprietary modem firmware.
rilproxy
The daemon that proxies messages between rild and Gecko (which is implemented in the b2g process). This overcomes the permission problem that arises when trying to talk to rild directly, since rild can only be communicated with from within the radio group.
b2g
This process, also known as the chrome process, implements Gecko. The portions of it that relate to the Radio Interface Layer are {{source2("dom/system/gonk/ril_worker.js")}} (which implements a worker thread that talks to rild through rilproxy and implements the radio state machine; and the {{interface("nsIRadioInterfaceLayer")}} interface, which is the main thread's XPCOM service that acts primarily as a message exchange between the ril_worker.js thread and various other Gecko components, including the Gecko content process.
Gecko's content process
Within Gecko's content process, the {{interface("nsIRILContentHelper")}} interface provides an XPCOM service that lets code implementing parts of the DOM, such as the Telephony and SMS APIs talk to the radio interface, which is in the chrome process.

Example: Communicating from rild to the DOM

Let's take a look at an example of how the lower level parts of the system communicate with DOM code. When the modem receives an incoming call, it notifies rild using a proprietary mechanism. rild then prepares a message for its client according to the "open" protocol, which is described in ril.h. In the case of an incoming call, a RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED message is generated and sent by rild to rilproxy.

rilproxy, implemented in rilproxy.c, receives this message in its main loop, which polls its connection to rild using code like this:

ret = read(rilproxy_rw, data, 1024);

if(ret > 0) {
  writeToSocket(rild_rw, data, ret);
}

Once the message is received from rild, it's then forwarded along to Gecko on the socket that connects rilproxy to Gecko. Gecko receives the forwarded message on its {{source("ipc/ril/Ril.cpp", "IPC thread")}}:

int ret = read(fd, mIncoming->Data, 1024);
// ... handle errors ...
mIncoming->mSize = ret;
sConsumer->MessageReceived(mIncoming.forget());

The consumer of these messages is {{source("dom/system/gonk/SystemWorkerManager.cpp", "SystemWorkerManager")}}, which repackages the messages and dispatches them to the {{source("dom/system/gonk/ril_worker.js", "ril_worker.js")}} thread that implements the RIL state machine; this is done in the RILReceiver::MessageReceived() method:

virtual void MessageReceived(RilRawData *aMessage) {
  nsRefPtr<DispatchRILEvent> dre(new DispatchRILEvent(aMessage));
  mDispatcher->PostTask(dre);
}

The task posted to that thread in turn calls the onRILMessage() function, which is implemented in JavaScript. This is done using the JavaScript API function JS_CallFunctionName():

return JS_CallFunctionName(aCx, obj, "onRILMessage", NS_ARRAY_LENGTH(argv),
                           argv, argv);

onRILMessage() is implemented in {{source2("dom/system/gonk/ril_worker.js")}}, which processes the message bytes and chops them into parcels. Each complete parcel is then dispatched to individual handler methods as appropriate:

handleParcel: function handleParcel(request_type, length) {
  let method = this[request_type];
  if (typeof method == "function") {
    if (DEBUG) debug("Handling parcel as " + method.name);
    method.call(this, length);
  }
}

This code works by getting the request type from the object, making sure it's defined as a function in the JavaScript code, then calling the method. Since ril_worker.js implements each request type in a method given the same name as the request type, this is very simple.

In our example, RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, the following handler is called:

RIL[UNSOLICITED_RESPONSE_CALL_STATE_CHANGED] = function UNSOLICITED_RESPONSE_CALL_STATE_CHANGED() {
  this.getCurrentCalls();
};

As you see in the code above, when notification is received that the call state has changed, the state machine simply fetches the current call state by calling the getCurrentCall() method:

getCurrentCalls: function getCurrentCalls() {
  Buf.simpleRequest(REQUEST_GET_CURRENT_CALLS);
}

This sends a request back to rild to request the state of all currently active calls. The request flows back along a similar path the RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED message followed, but in the opposite direction (that is, from ril_worker.js to SystemWorkerManager to Ril.cpp, then rilproxy and finally to the rild socket). rild then responds in kind, back along the same path, eventually arriving in ril_worker.js's handler for the REQUEST_GET_CURRENT_CALLS message. And thus bidirectional communication occurs.

The call state is then processed and compared to the previous state; if there's a change of state, ril_worker.js notifies the {{interface("nsIRadioInterfaceLayer")}} service on the main thread:

_handleChangedCallState: function _handleChangedCallState(changedCall) {
  let message = {type: "callStateChange",
                 call: changedCall};
  this.sendDOMMessage(message);
}

{{interface("nsIRadioInterfaceLayer")}} is implemented in {{source2("dom/system/gonk/RadioInterfaceLayer.js")}}; the message is received by its onmessage() method:

 onmessage: function onmessage(event) {
   let message = event.data;
   debug("Received message from worker: " + JSON.stringify(message));
   switch (message.type) {
     case "callStateChange":
       // This one will handle its own notifications.
       this.handleCallStateChange(message.call);
       break;
   ...

All this really does is dispatch the message to the content process using the Parent Process Message Manager (PPMM):

handleCallStateChange: function handleCallStateChange(call) {
  [some internal state updating]
  ppmm.sendAsyncMessage("RIL:CallStateChanged", call);
}

In the content process, the message is received by receiveMessage() method in the {{interface("nsIRILContentHelper")}} service, from the Child Process Message Manager (CPMM):

receiveMessage: function receiveMessage(msg) {
  let request;
  debug("Received message '" + msg.name + "': " + JSON.stringify(msg.json));
  switch (msg.name) {
    case "RIL:CallStateChanged":
      this._deliverTelephonyCallback("callStateChanged",
                                     [msg.json.callIndex, msg.json.state,
                                     msg.json.number, msg.json.isActive]);
      break;

This, in turn, calls the {{ifmethod("nsIRILTelephonyCallback", "callStateChanged")}} methods on every registered telephony callback object. Every web application that accesses the {{domxref("window.navigator.mozTelephony")}} API has registered one such callback object that dispatches events to the JavaScript code in the web application, either as a state change of an existing call object or a new incoming call event.

NS_IMETHODIMP Telephony::CallStateChanged(PRUint32 aCallIndex, PRUint16 aCallState,
                                          const nsAString& aNumber, bool aIsActive) {
  [...]

  if (modifiedCall) {
    // Change state.
    modifiedCall->ChangeState(aCallState);

    // See if this should replace our current active call.
    if (aIsActive) {
      mActiveCall = modifiedCall;
    }

    return NS_OK;
  }

  nsRefPtr<TelephonyCall> call =
          TelephonyCall::Create(this, aNumber, aCallState, aCallIndex);
  nsRefPtr<CallEvent> event = CallEvent::Create(call);
  nsresult rv = event->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("incoming"));
  NS_ENSURE_SUCCESS(rv, rv);
  return NS_OK;
}

Applications can receive these events and update their user interface and so forth:

handleEvent: function fm_handleEvent(evt) {
  switch (evt.call.state) {
    case 'connected':
      this.connected();
      break;
    case 'disconnected':
      this.disconnected();
      break;
    default:
      break;
  }
}

Take a look at the implementation of handleEvent() in the Dialer application as an extended example.

3G data

There is a RIL message that initiates a "data call" to the cellular service; this enables data transfer mode in the modem. This data call ends up creating and activating a {{interwiki("wikipedia", "Point-to-Point Protocol")}} (PPP) interface device in the Linux kernel that can be configured using the usual interfaces.

Note: This section needs to be written.

This section lists DOM APIs that are related to RIL communications:

WiFi

The WiFi backend for Firefox OS simply uses wpa_supplicant to do most of the work. That means that the backend's primary job is to simply manage the supplicant, and to do some auxiliary tasks such as loading the WiFi driver and enabling or disabling the network interface. In essence, this means that the backend is a state machine, with the states following the state of the supplicant.

Note: Much of the interesting stuff that happens in WiFi depends deeply on possible state changes in the wpa_supplicant process.

The implementation of the WiFi component is broken up into two files:

{{source2("dom/wifi/DOMWifiManager.js")}}
Implements the API that's exposed to web content, as defined in {{interface("nsIWifi.idl")}}.
{{source2("dom/wifi/WifiWorker.js")}}
Implements the state machine and the code that drives the supplicant.

These two files communicate with one another using the message manager. The backend listens for messages requesting certain actions, such as "associate", and responds with a message when the requested action has been completed.

The DOM side listens for the response methods as well as several event messages that indicate state changes and information updates.

Note: Any synchromous DOM APIs are implemented by caching data on that side of the pipe. Synchronous messages are avoided whenever possible.

WifiWorker.js

This file implements the main logic behind the WiFi interface. It runs in the chrome process (in multi-process builds) and is instantiated by the SystemWorkerManager. The file is generally broken into two sections: a giant anonymous function and WifiWorker (and its prototype). The anonymous function ends up being the WifiManager by providing a local API, including notifications for events such as connection to the supplicant and scan results being available. In general, it contains little logic and lets its sole consumer control its actions while it simply responds with the requested information and controls the details of the connection with the supplicant.

The WifiWorker object sits between the WifiManager and the DOM. It reacts to events and forwards them to the DOM; in turn, it receives requests from the DOM and performs the appropriate actions on the supplicant. It also maintains state information about the supplicant and what it needs to do next.

DOMWifiManager.js

This implements the DOM API, transmitting messages back and forth between callers and the actual WiFi worker. There's very little logic involved.

Note: In order to avoid synchronous messages to the chrome process, the WiFi Manager does need to cache the state based on the received event.

There's a single synchronous message, which is sent at the time the DOM API is instantiated, in order to get the current state of the supplicant.

DHCP

DHCP and DNS are handled by dhcpcd, the standard Linux DHCP client. However, it's not able to react when the network connection is lost. Because of this, Firefox OS kills and restarts dhcpcd each time it connects to a given wireless network.

dhcpcd is also responsible for setting the default route; we call into the network manager to tell the kernel about DNS servers.

Network Manager

The Network Manager configures network interfaces opened by the 3G data and WiFi components.

Note: This needs to be written.

Processes and threads

Firefox OS uses POSIX threads to implement all application threads, this includes the main thread of each application as well as Web workers and helper threads. Nice values are used prioritize process and thread execution thus relying on the standard Linux kernel scheduler. Depending on the status of a process we assign it a different nice level. We've currently got 7 levels:

Process priority levels
Priority Nice Used for
MASTER 0 main b2g process
FOREGROUND_HIGH 0 applications holding a CPU wakelock
FOREGROUND 1 foreground applications
FOREGROUND_KEYBOARD 1 keyboard application
BACKGROUND_PERCEIVABLE 7 background applications playing audio
BACKGROUND_HOMESCREEN 18 homescreen application
BACKGROUND 18 all other applications running in the background

Some levels share the same nice values, that's because those levels currently differ in the way they're treated by the out of memory killer. All priorities can be adjusted at build time via preferences; the relevant entries can be found in the b2g/app/b2g.js file.

Note: for more information on the out-of-memory killer, and how Firefox OS manages low memory situations, read Out of memory management on Firefox OS.

Within a process the main thread inherits the nice value of the process whilst web worker threads are given a nice value that is one point higher than the main thread thus running at lower priority. This is done in order to prevent CPU-intensive workers from excessively slowing down the main thread. Processes priorities are changed whenever a major event happens such as an application is sent into the background or foreground, a new application is started up or an existing application grabs a CPU wakelock. Whenever a process priority is adjusted all its threads' priorities will also be adjusted accordingly.

Note: cgroups are not currently used for resource management as they've proven unreliable on certain devices and kernels.

 

このリビジョンのソースコード

<div class="summary">
 <p><span class="seoSummary">Cet article est une vue d'ensemble de l'architecture de la plateforme Firefox OS, présentant les concepts-clés et expliquant sommairement comment les composants intérragissent.</span></p>
</div>
<div class="note">
 <p><strong>Note:</strong> Gardez à l'esprit que Firefox OS est toujours un produit non finalisé ("Pre-release"). L'architecture décrite ici n'est pas forcément finalisée, et des chanagements&nbsp; peuvent survenir.</p>
</div>
<h2 id="Firefox_OS_terminology">Terminologie Firefox OS</h2>
<p>Voici quelques termes à connaître avant de lire la suite de notre documentation de Firefox OS.</p>
<dl>
 <dt>
  B2G</dt>
 <dd>
  Accronyme de Boot to Gecko.</dd>
 <dt>
  Boot to Gecko</dt>
 <dd>
  Le nom de code du système d'exploitation Firefox OS lors de sa conception. Vous trouverez souvent ce terme en référence à Firefos OS, car il a été utilisé longtemps avant que le projet n'ait de nom officiel.</dd>
 <dt>
  Firefox OS</dt>
 <dd>
  Firefox OS correspond aux services de support et de branding de Mozilla (et ceux de ses partenaires OEM) ajoutés au-dessus de <strong>Boot to Gecko</strong>, pour créer un produit fini.</dd>
 <dt>
  <a href="/en-US/docs/Mozilla/Firefox_OS/Gaia" title="/en-US/docs/Mozilla/Firefox_OS/Gaia">Gaia</a></dt>
 <dd>
  L'interface utilisateur de la plateforme Firefox OS. Tout ce qui est affiché à l'écran une fois que Firefox OS est lancé, est produit par la couche Gaia. Gaia implements the lock screen, home screen, and all the standard applications you expect on a modern smartphone. Gaia is implemented entirely using HTML, CSS, and JavaScript. Its only interfaces to the underlying operating system are through open Web APIs, which are implemented by the Gecko layer. Third party applications can be installed alongside the Gaia layer.</dd>
 <dt>
  <a href="/en-US/docs/Gecko" title="/en-US/docs/Accessibility/AT-APIs/Gecko">Gecko</a></dt>
 <dd>
  This is the Firefox OS application runtime; that is, the layer that provides all of the support for the trifecta of open standards: HTML, CSS, and JavaScript. It makes sure those APIs work well on every operating system Gecko supports. This means that Gecko includes, among other things, a networking stack, graphics stack, layout engine, a JavaScript virtual machine, and porting layers.</dd>
 <dt>
  <a href="/en-US/docs/Mozilla/Firefox_OS/Gonk" title="/en-US/docs/Mozilla/Firefox_OS/Gonk">Gonk</a></dt>
 <dd>
  Gonk is the lower level operating system of the Firefox OS platform, consisting of a Linux kernel (based on the <a href="http://source.android.com/">Android Open Source Project</a> (AOSP)) and userspace hardware abstraction layer (HAL). The kernel and several of the user space libraries are common open-source projects: Linux, libusb, bluez, and so forth. Some of the other parts of the HAL are shared with the AOSP: GPS, camera, and others. You could say that Gonk is a very simple Linux distribution. Gonk is a <strong>porting target</strong> of Gecko; that is, there's a port of Gecko to Gonk, just like there's a port of Gecko to OS X, Windows, and Android. Since the Firefox OS project has full control over Gonk, we can expose interfaces to Gecko that can't be exposed on other operating systems. For example, Gecko has direct access to the full telephony stack and display frame buffer on Gonk, but doesn't have this access on any other operating system.</dd>
 <dt>
  <a name="Jank">Jank</a></dt>
 <dd>
  This term, often used in the mobile apps space, refers to the effect of slow/inefficient code operations in an app, which block updating of the UI and cause it to become laggy or unresponsive. Our Gaia engineers use various optimization techniques to try to avoid this at all costs.</dd>
</dl>
<h2 id="Architecture_diagram">Architecture diagram</h2>
<p><img alt="Firefox OS Architecture" src="/files/4605/FirefoxOS.png" style="width: 754px; height: 915px; margin: 0px auto; display: block;" /></p>
<h2 id="Firefox_OS_bootup_procedure">Firefox OS bootup procedure</h2>
<p>This section describes the process by which Firefox OS devices boot, what parts are involved, and where. As a quick reference, the general system bootup flow goes from bootloaders in the Kernel space, to init in the native code, to B2G and then Gecko in the user space, and then finally to the system app, window manager, then homescreen app inside Gecko. This is what all other apps are executed on top of.</p>
<p><img alt="" src="https://mdn.mozillademos.org/files/7491/bootup.png" style="width: 2112px; height: 1979px; display: block; margin: 0px auto;" /></p>
<h3 id="The_bootstrapping_process">The bootstrapping process</h3>
<p>When a Firefox OS device is first turned on, execution begins in the primary bootloader. From there, the process of loading the main operating system proceeds in the typical way; a succession of increasingly higher-level bootloaders bootstrap the next loader in the chain. At the end of the process, execution is handed off to the Linux kernel.</p>
<p>There are a few points worth noting about the boot process:</p>
<ul>
 <li>The bootloaders usually display the first splash screen seen by the user during device startup; this is typically a vendor logo.</li>
 <li>The bootloaders implement flashing an image to the device. Different devices use different protocols; most phones use the <a href="http://android-dls.com/wiki/index.php?title=Fastboot" title="http://android-dls.com/wiki/index.php?title=Fastboot">fastboot protocol</a>, but the Samsung Galaxy S II uses the odin protocol.</li>
 <li>By the end of the bootstrapping process, the modem image is usually loaded and running on the modem processor. How this happens is highly device-specific and may be proprietary.</li>
</ul>
<h3 id="The_Linux_kernel">The Linux kernel</h3>
<p>The Linux kernel(s) used by Gonk is very similar to the upstream Linux from which it's derived (based on the <a href="http://source.android.com/" title="http://source.android.com/">Android Open Source Project</a>). There are a few changes made by the AOSP that have not yet been upstreamed. In addition, vendors sometimes modify the kernel and upstream those changes on their own schedule. In general, though, the Linux kernel is close to stock.</p>
<p>The <a href="http://en.wikipedia.org/wiki/Linux_startup_process" title="http://en.wikipedia.org/wiki/Linux_startup_process">startup process for Linux</a> is well-documented elsewhere on the Internet, so this article won't cover that.</p>
<p>The Linux Kernel will bring up devices and run essential processes. It will execute processes defined in <code>init.rc</code> and the successor <a href="https://github.com/mozilla-b2g/gonk-misc/blob/master/init.b2g.rc">init.b2g.rc</a> to boot essential process such as <code>b2g</code> (FirefoxOS basic process, containing Gecko) and <code>rild</code> (telephony related process that might proprietary by different chipsets) — see below for more details. At the end of the process, a userspace <code>init</code> process is launched, as it is in most UNIX-like operating systems.</p>
<p>Once the <code>init</code> process is launched, the Linux kernel handles system calls from userspace, and interrupts and the like from hardware devices. Many hardware features are exposed to userspace through <a href="http://en.wikipedia.org/wiki/Sysfs" title="http://en.wikipedia.org/wiki/Sysfs"><code>sysfs</code></a>. For example, here's a <a href="https://github.com/cgjones/mozilla-central/blob/master/hal/gonk/GonkHal.cpp#L277" title="https://github.com/cgjones/mozilla-central/blob/master/hal/gonk/GonkHal.cpp#L277">code snippet</a> that reads the battery state in Gecko:</p>
<pre class="brush:cpp;">
FILE *capacityFile = fopen("/sys/class/power_supply/battery/capacity", "r");
double capacity = dom::battery::kDefaultLevel * 100;
if (capacityFile) {
  fscanf(capacityFile, "%lf", &amp;capacity);
  fclose(capacityFile);
}</pre>
<h3 id="More_on_the_init_process">More on the init process</h3>
<p>The <code>init</code> process in Gonk handles mounting the required file systems and spawns system services. After that, it stays around to serve as a process manager. This is quite similar to init on other UNIX-like operating systems. It interprets scripts (that is, the <code>init*.rc</code> files) that consist of commands describing what should be done to start various services. The Firefox OS <code>init.rc</code> is typically the stock Android <code>init.rc</code> for that device patched to include the things required to kick-start Firefox OS, and varies from device to device.</p>
<p>One key task the <code>init</code> process handles is starting up the <code>b2g</code> process; this is the core of the Firefox OS operating system.</p>
<p>The code in <code>init.rc</code> that starts this up looks like this:</p>
<pre>
service b2g /system/bin/b2g.sh
&nbsp;&nbsp;&nbsp; class main
&nbsp;&nbsp;&nbsp; onrestart restart media</pre>
<div class="note">
 <p><strong>Note:</strong> Exactly how much <code>init.rc</code> differs from the Android version varies from device to device; sometimes, <code>init.b2g.rc</code> is simply appended, and sometimes the patches are more significant.</p>
</div>
<h2 id="The_userspace_process_architecture">The userspace process architecture</h2>
<p>Now it's useful to take a high-level look at how the various components of Firefox OS fit together and interact with one another. This diagram shows the primary userspace processes in Firefox OS.</p>
<p><a href="/files/3849/B2G userspace architecture.svg"><img alt="Userspace diagram" src="/files/3849/B2G%20userspace%20architecture.svg" style="width: 520px; height: 491px; float: right; position: relative; z-index: 12; " /></a></p>
<div class="note">
 <p><strong>Note:</strong> Keep in mind that since Firefox OS is under active development, this diagram is subject to change, and may not be entirely accurate.</p>
</div>
<p>The <code>b2g</code> process is the primary system process. It runs with high privileges; it has access to most hardware devices. <code>b2g</code> communicates with the modem, draws to the display framebuffer, and talks to GPS, cameras, and other hardware features. Internally, <code>b2g</code> runs the Gecko layer (implemented by <code>libxul.so</code>). See {{anch("Gecko")}} for details on how the Gecko layer works, and how <code>b2g</code> communicates with it.</p>
<h3 id="b2g">b2g</h3>
<p>The <code>b2g</code> process may, in turn, spawn a number of low-rights <strong>content processes</strong>. These processes are where web applications and other web content are loaded. These processes communicate with the main Gecko server process through <a href="/en-US/docs/IPDL" title="/en-US/docs/IPDL">IPDL</a>, a message-passing system.</p>
<p>The <code>b2g</code> process runs libxul, which references <code>b2g/app/b2g.js</code> to get default preferences. From the preferences it will open the described HTML file <code>b2g/chrome/content/shell.html</code>, which is compiled within the <code>omni.ja</code> file. <code>shell.html</code> includes <code>b2g/chrome/content/shell.js</code> file, which triggers the Gaia <code>system</code> app.</p>
<h3 id="rild">rild</h3>
<p>The <code>rild</code> process is the interface to the modem processor. <code>rild</code> is the daemon that implements the <strong>Radio Interface Layer</strong> (RIL). It's a proprietary piece of code that's implemented by the hardware vendor to talk to their modem hardware. <code>rild</code> makes it possible for client code to connect to a UNIX-domain socket to which it binds. It's started up by code like this in the <code>init</code> script:</p>
<pre>
service ril-daemon /system/bin/rild
&nbsp;&nbsp;&nbsp; socket rild stream 660 root radio</pre>
<h3 id="rilproxy">rilproxy</h3>
<p>In Firefox OS, the <code>rild</code> client is the <code>rilproxy</code> process. This acts as a dumb forwarding proxy between <code>rild</code> and <code>b2g</code>. This proxy is needed as an implementation detail; suffice it to say, it is indeed necessary. The <a href="https://github.com/mozilla-b2g/rilproxy" title="https://github.com/mozilla-b2g/rilproxy"><code>rilproxy</code> code can be found on GitHub</a>.</p>
<h3 id="mediaserver">mediaserver</h3>
<p>The <a href="https://github.com/android/platform_frameworks_base/tree/ics-mr0-release/media/libmediaplayerservice" title="https://github.com/android/platform_frameworks_base/tree/ics-mr0-release/media/libmediaplayerservice"><code>mediaserver</code> process</a> controls audio and video playback. Gecko talks to it through an Android Remote Procedure Call (RPC) mechanism. Some of the media that Gecko can play (OGG Vorbis audio, OGG Theora video, and <a href="http://www.webmproject.org/about/" title="http://www.webmproject.org/about/">WebM</a> video) are decoded by Gecko and sent directly to the <code>mediaserver</code> process. Other media files are decoded by <code>libstagefright</code>, which is capable of accessing proprietary codecs and hardware encoders.</p>
<div class="note">
 <p><strong>Note:</strong> The <code>mediaserver</code> process is a "temporary" component of Firefox OS; it's there to aid in our initial development work, but is expected to go away eventually. This will most likely not happen until Firefox OS 2.0 at the earliest, however.</p>
</div>
<h3 id="netd">netd</h3>
<p>The <code>netd</code> process is used to configure network interfaces.</p>
<h3 id="wpa_supplicant">wpa_supplicant</h3>
<p>The <code>wpa_supplicant</code> process is the standard UNIX-style daemon that handles connectivity with WiFi access points.</p>
<h3 id="dbus-daemon">dbus-daemon</h3>
<p>The dbus-daemon implements <a href="http://www.freedesktop.org/wiki/Software/dbus" title="http://www.freedesktop.org/wiki/Software/dbus">D-Bus</a>, a message bus system that Firefox OS uses for Bluetooth communication.</p>
<h2 id="Gecko">Gecko</h2>
<p><a href="/en-US/docs/Gecko" title="/en-US/docs/Gecko">Gecko</a>, as previously mentioned, is the implementation of web standards (<a href="/en-US/docs/HTML" title="/en-US/docs/HTML">HTML</a>, <a href="/en-US/docs/CSS" title="/en-US/docs/CSS">CSS</a>, and <a href="/en-US/docs/JavaScript" title="/en-US/docs/JavaScript">JavaScript</a>) that is used to implement everything the user sees on Firefox OS.</p>
<div class="note">
 <p><strong>Note</strong>: To search the Gecko codebase, you could use <a href="http://dxr.mozilla.org">http://dxr.mozilla.org</a>. It’s more fancy and provides good reference features, but with limited repositories. Or you could try the traditional <a href="http://mxr.mozilla.org">http://mxr.mozilla.org</a>, which contains more Mozilla projects.</p>
</div>
<h3 id="Gecko_files_related_to_Firefox_OS">Gecko files related to Firefox OS</h3>
<h4 id="b2g.2F">b2g/</h4>
<p>The b2g folder contains mainly Firefox OS-related functions.</p>
<h5 id="b2g.2Fchrome.2Fcontent">b2g/chrome/content</h5>
<p>Contains Javascript files run above the system app.</p>
<h5 id="b2g.2Fchrome.2Fcontent.2Fshell.html">b2g/chrome/content/shell.html</h5>
<p>The entry point into Gaia — the HTML for the system app. <code>shell.html</code> pulls in <code>settings.js</code> and <code>shell.js</code>:</p>
<pre class="brush: html">
&lt;script type="application/javascript;version=1.8" src="chrome://browser/content/settings.js"&gt; &lt;/script&gt;
&lt;script type="application/javascript;version=1.8" src="chrome://browser/content/shell.js"&gt; &lt;/script&gt;</pre>
<p><code>settings.js</code> contains system default setting parameters.</p>
<h5 id="b2g.2Fchrome.2Fcontent.2Fshell.js">b2g/chrome/content/shell.js</h5>
<p><code>shell.js</code> is the first script to load in the Gaia <code>system</code> app.</p>
<p><code>shell.js</code> imports all required modules, registers key listeners, defines <code>sendCustomEvent</code> and <code>sendChromeEvent</code> to communicate with Gaia, and provides webapp install helpers: indexedDB quota, RemoteDebugger, keyboard helper, and screenshot tool.</p>
<p>But the most important function of <code>shell.js</code> is to launch the Gaia <code>system</code> app, then hand over the overall systems related management work to the Gaia <code>system</code> app.</p>
<pre class="brush: js">
let systemAppFrame =
  document.createElementNS('http://www.w3.org/1999/xhtml', 'html:iframe');
    ...
  container.appendChild(systemAppFrame);</pre>
<h5 id="b2g.2Fapp.2Fb2g.js">b2g/app/b2g.js</h5>
<p>This script contains predefined settings, like about:config in browser, and the same as Gaia's pref.js. These settings can be changed from the Settings app, and can be overwritten with Gaia’s user.js in the Gaia build script.</p>
<h4 id="dom.2F.7BAPI.7D">dom/{API}</h4>
<p>New API implementations (post-b2g) will be located in <code>dom/</code>. Older APIs will be located in <code>dom/base</code>, for example <code>Navigator.cpp</code>.</p>
<h5 id="dom.2Fapps">dom/apps</h5>
<p><code>.jsm</code> will be loaded — <code>.js</code> API implementations such as <code>webapp.js</code> install, <code>getSelf</code>, etc.</p>
<h5 id="dom.2Fapps.2Fsrc.2F">dom/apps/src/</h5>
<p>All permissions are defined in <a href="http://mxr.mozilla.org/mozilla-central/source/dom/apps/src/PermissionsTable.jsm">PermissionsTable.jsm</a></p>
<h4 id="dom.2Fwebidl">dom/webidl</h4>
<p>WebIDL is the language used to define web APIs. For supported attributes, read <a href="https://developer.mozilla.org/en-US/docs/Mozilla/WebIDL_bindings">WebIDL_bindings</a>.</p>
<h4 id="hal.2Fgonk">hal/gonk</h4>
<p>This directory contains files related to the gonk port layer.</p>
<h4 id="Generated_files">Generated files</h4>
<h5 id="module.2Flibpref.2Fsrc.2Finit.2Fall.js">module/libpref/src/init/all.js</h5>
<p>Contains all config files.</p>
<h5 id=".2Fsystem.2Fb2g.2F_omni.ja_and_omni.js">/system/b2g/ omni.ja and omni.js</h5>
<p>Contains the pack of styles for resources in the device.</p>
<h3 id="Processing_input_events">Processing input events</h3>
<p>Most action inside Gecko is triggered by user actions. These actions are represented by input events (such as button presses, touches to a touch screen device, and so forth). These events enter Gecko through the {{source("widget/gonk/nsAppShell.cpp", "Gonk implementation")}} of {{interface("nsIAppShell")}}, a Gecko interface that is used to represent the primary entrance points for a Gecko application; that is, the input device driver calls methods on the <code>nsAppShell</code> object that represents the Gecko subsystem in order to send events to the user interface.</p>
<p>For example:</p>
<pre class="brush:cpp;">
void GeckoInputDispatcher::notifyKey(nsecs_t eventTime,
                                     int32_t deviceId,
                                     int32_t source,
                                     uint32_t policyFlags,
                                     int32_t action,
                                     int32_t flags,
                                     int32_t keyCode,
                                     int32_t scanCode,
                                     int32_t metaState,
                                     nsecs_t downTime) {
  UserInputData data;
  data.timeMs = nanosecsToMillisecs(eventTime);
  data.type = UserInputData::KEY_DATA;
  data.action = action;
  data.flags = flags;
  data.metaState = metaState;
  data.key.keyCode = keyCode;
  data.key.scanCode = scanCode;
  {
    MutexAutoLock lock(mQueueLock);
    mEventQueue.push(data);
  }
  gAppShell-&gt;NotifyNativeEvent();
}</pre>
<p>These events come from the standard Linux <code>input_event</code> system. Firefox OS uses a {{source("widget/gonk/libui/InputReader.cpp", "light abstraction layer")}} over that; this provides some nice features like event filtering. You can see the code that creates input events in the <code>EventHub::getEvents()</code> method in {{source2("widget/gonk/libui/EventHub.cpp")}}.</p>
<p>Once the events are received by Gecko, they're dispatched into the DOM by <code>{{source("widget/gonk/nsAppShell.cpp", "nsAppShell")}}</code>:</p>
<pre class="brush:cpp;">
static nsEventStatus sendKeyEventWithMsg(uint32_t keyCode,
                                         uint32_t msg,
                                         uint64_t timeMs,
                                         uint32_t flags) {
    nsKeyEvent event(true, msg, NULL);
    event.keyCode = keyCode;
    event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_MOBILE;
    event.time = timeMs;
    event.flags |= flags;
    return nsWindow::DispatchInputEvent(event);
}
</pre>
<p>After that, the events are either consumed by Gecko itself or are dispatched to Web applications as <a href="/en-US/docs/DOM_Client_Object_Cross-Reference/DOM_Events" title="/en-US/docs/DOM_Client_Object_Cross-Reference/DOM_Events">DOM events</a> for further processing.</p>
<h3 id="Graphics">Graphics</h3>
<p>At the very lowest level, Gecko uses <a href="http://www.khronos.org/opengles/2_X/" title="http://www.khronos.org/opengles/2_X/">OpenGL ES 2.0</a> to draw to a GL context that wraps the hardware frame buffers. This is done in the Gonk implementation of <code>{{source("widget/gonk/nsWindow.cpp", "nsWindow")}}</code> by code similar to this:</p>
<pre class="brush:cpp;">
gNativeWindow = new android::FramebufferNativeWindow();
sGLContext = GLContextProvider::CreateForWindow(this);</pre>
<p>The <code>FramebufferNativeWindow</code> class is brought in directly from Android; see <a href="https://github.com/android/platform_frameworks_base/blob/ics-mr1-release/libs/ui/FramebufferNativeWindow.cpp" title="https://github.com/android/platform_frameworks_base/blob/ics-mr1-release/libs/ui/FramebufferNativeWindow.cpp"><code>FramebufferNativeWindow.cpp</code></a>. This uses the <strong>gralloc</strong> API to access the graphics driver in order to map buffers from the framebuffer device into memory.</p>
<p>Gecko uses its <a href="/en-US/docs/Gecko/Layers" title="/en-US/docs/Gecko/Layers">Layers</a> system to composite drawn content to the screen. In summary, what happens is this:</p>
<ol>
 <li>Gecko draws separate regions of pages into memory buffers. Sometimes these buffers are in system memory; other times, they're textures mapped into Gecko's address space, which means that Gecko is drawing directly into video memory. This is typically done in the method <a href="http://mxr.mozilla.org/mozilla-central/source/gfx/layers/basic/BasicThebesLayer.cpp#83" title="http://mxr.mozilla.org/mozilla-central/source/gfx/layers/basic/BasicThebesLayer.cpp#201"><code>BasicThebesLayer::PaintThebes()</code></a>.</li>
 <li>Gecko then composites all of these textures to the screen using OpenGL commands. This composition occurs in <a href="http://mxr.mozilla.org/mozilla-central/source/gfx/layers/opengl/ThebesLayerOGL.cpp#124" title="http://mxr.mozilla.org/mozilla-central/source/gfx/layers/basic/BasicThebesLayer.cpp#201"><code>ThebesLayerOGL::RenderTo()</code></a>.</li>
</ol>
<p>The details of how Gecko handles the rendering of web content is outside the scope of this document.</p>
<h3 id="Hardware_Abstraction_Layer_(HAL)">Hardware Abstraction Layer (HAL)</h3>
<p>The Gecko hardware abstraction layer is one of the porting layers of Gecko. It handles low-level access to system interfaces across multiple platforms using a C++ API that's accessible to the higher levels of Gecko. These APIs are implemented on a per-platform basis inside the Gecko HAL itself. This hardware abstraction layer is not exposed directly to JavaScript code in Gecko.</p>
<h4 id="How_the_HAL_works">How the HAL works</h4>
<p>Let's consider the {{domxref("window.navigator.vibrate", "Vibration")}} API as an example. The Gecko HAL for this API is defined in {{source2("hal/Hal.h")}}. In essence (simplifying the method signature for clarity's sake), you have this function:</p>
<pre>
void Vibrate(const nsTArray&lt;uint32&gt; &amp;pattern);</pre>
<p>This is the function called by Gecko code to turn on vibration of the device according to the specified pattern; a corresponding function exists to cancel any ongoing vibration. The Gonk implementation of this method is in {{source2("hal/gonk/GonkHal.cpp")}}:</p>
<pre class="brush:cpp;">
void Vibrate(const nsTArray&lt;uint32_t&gt; &amp;pattern) {
  EnsureVibratorThreadInitialized();
  sVibratorRunnable-&gt;Vibrate(pattern);
}
</pre>
<p>This code sends the request to start vibrating the device to another thread, which is implemented in <code>VibratorRunnable::Run()</code>. This thread's main loop looks like this:</p>
<pre class="brush:cpp;">
while (!mShuttingDown) {
  if (mIndex &lt; mPattern.Length()) {
    uint32_t duration = mPattern[mIndex];
    if (mIndex % 2 == 0) {
      vibrator_on(duration);
    }
    mIndex++;
    mMonitor.Wait(PR_MillisecondsToInterval(duration));
  }
  else {
    mMonitor.Wait();
  }
}
</pre>
<p><code>vibrator_on()</code> is the Gonk HAL API that turns on the vibrator motor. Internally, this method sends a message to the kernel driver by writing a value to a kernel object using <code>sysfs</code>.</p>
<h4 id="Fallback_HAL_API_implementations">Fallback HAL API implementations</h4>
<p>The Gecko HAL APIs are supported across all platforms. When Gecko is built for a platform that doesn't expose an interface to vibration motors (such as a desktop computer), then a fallback implementation of the HAL API is used. For vibration, this is implemented in {{source2("hal/fallback/FallbackVibration.cpp")}}.</p>
<pre class="brush:cpp;">
void Vibrate(const nsTArray&lt;uint32_t&gt; &amp;pattern) {
}</pre>
<h4 id="Sandbox_implementations">Sandbox implementations</h4>
<p>Because most web content runs in content processes with low privileges, we can't assume those processes have the privileges needed to be able to (for example), turn on and off the vibration motor. In addition, we want to have a central location for handling potential race conditions. In the Gecko HAL, this is done through a "sandbox" implementation of the HAL. This sandbox implementation simply proxies requests made by content processes and forwards them to the "Gecko server" process. The proxy requests are sent using IPDL.</p>
<p>For vibration, this is handled by the <code>Vibrate()</code> function implemented in {{source2("hal/sandbox/SandboxHal.cpp")}}:</p>
<pre class="brush:cpp;">
void Vibrate(const nsTArray&lt;uint32_t&gt;&amp; pattern, const WindowIdentifier &amp;id) {
  AutoInfallibleTArray&lt;uint32_t, 8&gt; p(pattern);

  WindowIdentifier newID(id);
  newID.AppendProcessID();
  Hal()-&gt;SendVibrate(p, newID.AsArray(), GetTabChildFrom(newID.GetWindow()));
}</pre>
<p>This sends a message defined by the <code>PHal</code> interface, described by IPDL in {{source2("hal/sandbox/PHal.ipdl")}}. This method is described more or less as follows:</p>
<pre>
Vibrate(uint32_t[] pattern);</pre>
<p>The receiver of this message is the <code>HalParent::RecvVibrate()</code> method in {{source2("hal/sandbox/SandboxHal.cpp")}}, which looks like this:</p>
<pre class="brush:cpp;">
virtual bool RecvVibrate(const InfallibleTArray&lt;unsigned int&gt;&amp; pattern,
            const InfallibleTArray&lt;uint64_t&gt; &amp;id,
            PBrowserParent *browserParent) MOZ_OVERRIDE {

  hal::Vibrate(pattern, newID);
  return true;
}</pre>
<p>This omits some details that aren't relevant to this discussion; however, it shows how the message progresses from a content process through Gecko to Gonk, then to the Gonk HAL implementation of <code>Vibrate()</code>, and eventually to the Vibration driver.</p>
<h3 id="DOM_APIs">DOM APIs</h3>
<p><strong>DOM interfaces</strong> are, in essence, how web content communicates with Gecko. There's more involved than that, and if you're interested in added details, you can read <a href="/en-US/docs/DOM/About_the_Document_Object_Model" title="/en-US/docs/DOM/About_the_Document_Object_Model">about the DOM</a>. DOM interfaces are defined using <a href="/en-US/docs/XPIDL" title="/en-US/docs/XPIDL">IDL</a>, which comprises both a foreign function interface (FFI) and object model (OM) between JavaScript and C++.</p>
<p>The vibration API is exposed to web content through an IDL interface, which is provided in <code>{{source("dom/interfaces/base/nsIDOMNavigator.idl", "nsIDOMNavigator.idl")}}:</code></p>
<pre>
[implicit_jscontext] void mozVibrate(in jsval aPattern);</pre>
<p>The <a href="/en-US/docs/SpiderMonkey/JSAPI_Reference/Jsval" title="/en-US/docs/SpiderMonkey/JSAPI_Reference/JSVAL_IS_OBJECT"><code>jsval</code></a> argument indicates that <code>mozVibrate()</code> (which is our vendor-prefixed implementation of this non-finalized vibration specification) accepts as input any JavaScript value. The IDL compiler, <a href="/en-US/docs/XPIDL/xpidl" title="/en-US/docs/XPIDL/xpidl"><code>xpidl</code></a>, generates a C++ interface that's then implemented by the <code>Navigator</code> class in <code>{{source("dom/base/Navigator.cpp", "Navigator.cpp")}}</code>.</p>
<pre class="brush:cpp;">
NS_IMETHODIMP Navigator::MozVibrate(const jsval&amp; aPattern, JSContext* cx) {
  // ...
  hal::Vibrate(pattern);
  return NS_OK;
}</pre>
<p>There's a lot more code in this method than what you see here, but it's not important for the purposes of this discussion. The point is that the call to <code>hal::Vibrate()</code> transfers control from the DOM to the Gecko HAL. From there, we enter the HAL implementation discussed in the previous section and work our way down toward the graphics driver. On top of that, the DOM implementation doesn't care at all what platform it's running on (Gonk, Windows, OS X, or anything else). It also doesn't care whether the code is running in a content process or in the Gecko server process. Those details are all left to lower levels of the system to deal with.</p>
<p>The vibration API is a very simple API, which makes it a good example. The <a href="/en-US/docs/API/WebSMS" title="/en-US/docs/API/WebSMS">SMS API</a> is an example of a more complex API which uses its own "remoting" layer connecting content processes to the server.</p>
<h2 id="Radio_Interface_Layer_(RIL)">Radio Interface Layer (RIL)</h2>
<p>The RIL was mentioned in the section {{anch("The userspace process architecture")}}. This section will examine how the various pieces of this layer interact in a bit more detail.</p>
<p>The main components involved in the RIL are:</p>
<dl>
 <dt>
  <code>rild</code></dt>
 <dd>
  The daemon that talks to the proprietary modem firmware.</dd>
 <dt>
  <code>rilproxy</code></dt>
 <dd>
  The daemon that proxies messages between <code>rild</code> and Gecko (which is implemented in the <code>b2g</code> process). This overcomes the permission problem that arises when trying to talk to <code>rild</code> directly, since <code>rild</code> can only be communicated with from within the <code>radio</code> group.</dd>
 <dt>
  <code>b2g</code></dt>
 <dd>
  This process, also known as the <strong>chrome process</strong>, implements Gecko. The portions of it that relate to the Radio Interface Layer are {{source2("dom/system/gonk/ril_worker.js")}} (which implements a worker thread that talks to <code>rild</code> through <code>rilproxy</code> and implements the radio state machine; and the {{interface("nsIRadioInterfaceLayer")}} interface, which is the main thread's <a href="/en-US/docs/XPCOM" title="/en-US/docs/XPCOM">XPCOM</a> service that acts primarily as a message exchange between the <code>ril_worker.js</code> thread and various other Gecko components, including the Gecko content process.</dd>
 <dt>
  Gecko's content process</dt>
 <dd>
  Within Gecko's content process, the {{interface("nsIRILContentHelper")}} interface provides an XPCOM service that lets code implementing parts of the DOM, such as the <a href="/en-US/docs/API/WebTelephony" title="/en-US/docs/API/WebTelephony">Telephony</a> and <a href="/en-US/docs/API/WebSMS" title="/en-US/docs/API/WebSMS">SMS</a> APIs talk to the radio interface, which is in the chrome process.</dd>
</dl>
<h3 id="Example.3A_Communicating_from_rild_to_the_DOM">Example: Communicating from rild to the DOM</h3>
<p>Let's take a look at an example of how the lower level parts of the system communicate with DOM code. When the modem receives an incoming call, it notifies <code>rild</code> using a proprietary mechanism. <code>rild</code> then prepares a message for its client according to the "open" protocol, which is described in <a href="https://github.com/mozilla-b2g/android-hardware-ril/blob/master/include/telephony/ril.h" title="https://github.com/mozilla-b2g/android-hardware-ril/blob/master/include/telephony/ril.h"><code>ril.h</code></a>. In the case of an incoming call, a <code>RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED</code> message is generated and sent by <code>rild</code> to <code>rilproxy</code>.</p>
<p><code>rilproxy</code>, implemented in <a href="https://github.com/mozilla-b2g/rilproxy/blob/master/src/rilproxy.c" title="https://github.com/mozilla-b2g/rilproxy/blob/master/src/rilproxy.c"><code>rilproxy.c</code></a>, receives this message in its main loop, which polls its connection to <code>rild</code> using code like this:</p>
<pre class="brush:cpp;">
ret = read(rilproxy_rw, data, 1024);

if(ret &gt; 0) {
  writeToSocket(rild_rw, data, ret);
}</pre>
<p>Once the message is received from <code>rild</code>, it's then forwarded along to Gecko on the socket that connects <code>rilproxy</code> to Gecko. Gecko receives the forwarded message on its {{source("ipc/ril/Ril.cpp", "IPC thread")}}:</p>
<pre class="brush:cpp;">
int ret = read(fd, mIncoming-&gt;Data, 1024);
// ... handle errors ...
mIncoming-&gt;mSize = ret;
sConsumer-&gt;MessageReceived(mIncoming.forget());
</pre>
<p>The consumer of these messages is {{source("dom/system/gonk/SystemWorkerManager.cpp", "SystemWorkerManager")}}, which repackages the messages and dispatches them to the <code>{{source("dom/system/gonk/ril_worker.js", "ril_worker.js")}}</code> thread that implements the RIL state machine; this is done in the <code>RILReceiver::MessageReceived()</code> method:</p>
<pre class="brush:cpp;">
virtual void MessageReceived(RilRawData *aMessage) {
  nsRefPtr&lt;DispatchRILEvent&gt; dre(new DispatchRILEvent(aMessage));
  mDispatcher-&gt;PostTask(dre);
}</pre>
<p>The task posted to that thread in turn calls the <code>onRILMessage()</code> function, which is implemented in JavaScript. This is done using the JavaScript API function <code><a href="/en-US/docs/SpiderMonkey/JSAPI_Reference/JS_CallFunctionName" title="/en-US/docs/SpiderMonkey/JSAPI_Reference/JS_CallFunctionName">JS_CallFunctionName</a>()</code>:</p>
<pre>
return JS_CallFunctionName(aCx, obj, "onRILMessage", NS_ARRAY_LENGTH(argv),
                           argv, argv);</pre>
<p><code>onRILMessage()</code> is implemented in {{source2("dom/system/gonk/ril_worker.js")}}, which processes the message bytes and chops them into parcels. Each complete parcel is then dispatched to individual handler methods as appropriate:</p>
<pre class="brush:js;">
handleParcel: function handleParcel(request_type, length) {
  let method = this[request_type];
  if (typeof method == "function") {
    if (DEBUG) debug("Handling parcel as " + method.name);
    method.call(this, length);
  }
}
</pre>
<p>This code works by getting the request type from the object, making sure it's defined as a function in the JavaScript code, then calling the method. Since ril_worker.js implements each request type in a method given the same name as the request type, this is very simple.</p>
<p>In our example, <code>RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED</code>, the following handler is called:</p>
<pre class="brush:js;">
RIL[UNSOLICITED_RESPONSE_CALL_STATE_CHANGED] = function UNSOLICITED_RESPONSE_CALL_STATE_CHANGED() {
  this.getCurrentCalls();
};</pre>
<p>As you see in the code above, when notification is received that the call state has changed, the state machine simply fetches the current call state by calling the <code>getCurrentCall()</code> method:</p>
<pre class="brush:js;">
getCurrentCalls: function getCurrentCalls() {
  Buf.simpleRequest(REQUEST_GET_CURRENT_CALLS);
}</pre>
<p>This sends a request back to <code>rild</code> to request the state of all currently active calls. The request flows back along a similar path the <code>RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED</code> message followed, but in the opposite direction (that is, from <code>ril_worker.js</code> to <code>SystemWorkerManager</code> to <code>Ril.cpp</code>, then <code>rilproxy</code> and finally to the <code>rild</code> socket). <code>rild</code> then responds in kind, back along the same path, eventually arriving in <code>ril_worker.js</code>'s handler for the <code>REQUEST_GET_CURRENT_CALLS</code> message. And thus bidirectional communication occurs.</p>
<p>The call state is then processed and compared to the previous state; if there's a change of state, ril_worker.js notifies the {{interface("nsIRadioInterfaceLayer")}} service on the main thread:</p>
<pre class="brush:js;">
_handleChangedCallState: function _handleChangedCallState(changedCall) {
  let message = {type: "callStateChange",
                 call: changedCall};
  this.sendDOMMessage(message);
}</pre>
<p>{{interface("nsIRadioInterfaceLayer")}} is implemented in {{source2("dom/system/gonk/RadioInterfaceLayer.js")}}; the message is received by its <code>onmessage()</code> method:</p>
<pre class="brush:js;">
 onmessage: function onmessage(event) {
   let message = event.data;
   debug("Received message from worker: " + JSON.stringify(message));
   switch (message.type) {
     case "callStateChange":
       // This one will handle its own notifications.
       this.handleCallStateChange(message.call);
       break;
   ...
</pre>
<p>All this really does is dispatch the message to the content process using the Parent Process Message Manager (PPMM):</p>
<pre class="brush:js;">
handleCallStateChange: function handleCallStateChange(call) {
  [some internal state updating]
  ppmm.sendAsyncMessage("RIL:CallStateChanged", call);
}</pre>
<p>In the content process, the message is received by <code>receiveMessage()</code> method in the {{interface("nsIRILContentHelper")}} service, from the Child Process Message Manager (CPMM):</p>
<pre class="brush:js;">
receiveMessage: function receiveMessage(msg) {
  let request;
  debug("Received message '" + msg.name + "': " + JSON.stringify(msg.json));
  switch (msg.name) {
    case "RIL:CallStateChanged":
      this._deliverTelephonyCallback("callStateChanged",
                                     [msg.json.callIndex, msg.json.state,
                                     msg.json.number, msg.json.isActive]);
      break;</pre>
<p>This, in turn, calls the {{ifmethod("nsIRILTelephonyCallback", "callStateChanged")}} methods on every registered telephony callback object. Every web application that accesses the {{domxref("window.navigator.mozTelephony")}} API has registered one such callback object that dispatches events to the JavaScript code in the web application, either as a state change of an existing call object or a new <code>incoming</code> call event.</p>
<pre class="brush:cpp;">
NS_IMETHODIMP Telephony::CallStateChanged(PRUint32 aCallIndex, PRUint16 aCallState,
                                          const nsAString&amp; aNumber, bool aIsActive) {
  [...]

  if (modifiedCall) {
    // Change state.
    modifiedCall-&gt;ChangeState(aCallState);

    // See if this should replace our current active call.
    if (aIsActive) {
      mActiveCall = modifiedCall;
    }

    return NS_OK;
  }

  nsRefPtr&lt;TelephonyCall&gt; call =
          TelephonyCall::Create(this, aNumber, aCallState, aCallIndex);
  nsRefPtr&lt;CallEvent&gt; event = CallEvent::Create(call);
  nsresult rv = event-&gt;Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("incoming"));
  NS_ENSURE_SUCCESS(rv, rv);
  return NS_OK;
}</pre>
<p>Applications can receive these events and update their user interface and so forth:</p>
<pre class="brush:js;">
handleEvent: function fm_handleEvent(evt) {
  switch (evt.call.state) {
    case 'connected':
      this.connected();
      break;
    case 'disconnected':
      this.disconnected();
      break;
    default:
      break;
  }
}</pre>
<p>Take a look at the implementation of <a href="https://github.com/mozilla-b2g/gaia/blob/master/apps/communications/dialer/js/dialer.js" title="https://github.com/mozilla-b2g/gaia/blob/master/apps/communications/dialer/js/dialer.js"><code>handleEvent()</code> in the Dialer application</a> as an extended example.</p>
<h3 id="3G_data">3G data</h3>
<p>There is a RIL message that initiates a "data call" to the cellular service; this enables data transfer mode in the modem. This data call ends up creating and activating a {{interwiki("wikipedia", "Point-to-Point Protocol")}} (PPP) interface device in the Linux kernel that can be configured using the usual interfaces.</p>
<div class="note">
 <p><strong>Note:</strong> This section needs to be written.</p>
</div>
<h3 id="Related_DOM_APIs">Related DOM APIs</h3>
<p>This section lists DOM APIs that are related to RIL communications:</p>
<ul>
 <li><a href="/en-US/docs/API/WebTelephony/Introduction_to_WebTelephony" title="/en-US/docs/API/WebTelephony/Introduction_to_WebTelephony">Telephony API</a></li>
 <li><a href="/en-US/docs/API/WebSMS/Introduction_to_WebSMS" title="/en-US/docs/API/WebSMS/Introduction_to_WebSMS">SMS API</a></li>
 <li>Mobile Connection API</li>
</ul>
<h2 id="WiFi">WiFi</h2>
<p>The WiFi backend for Firefox OS simply uses <code>wpa_supplicant</code> to do most of the work. That means that the backend's primary job is to simply manage the supplicant, and to do some auxiliary tasks such as loading the WiFi driver and enabling or disabling the network interface. In essence, this means that the backend is a state machine, with the states following the state of the supplicant.</p>
<div class="note">
 <p><strong>Note:</strong> Much of the interesting stuff that happens in WiFi depends deeply on possible state changes in the <code>wpa_supplicant</code> process.</p>
</div>
<p>The implementation of the WiFi component is broken up into two files:</p>
<dl>
 <dt>
  {{source2("dom/wifi/DOMWifiManager.js")}}</dt>
 <dd>
  Implements the API that's exposed to web content, as defined in {{interface("nsIWifi.idl")}}.</dd>
 <dt>
  {{source2("dom/wifi/WifiWorker.js")}}</dt>
 <dd>
  Implements the state machine and the code that drives the supplicant.</dd>
</dl>
<p>These two files communicate with one another using the <a href="/en-US/docs/The_message_manager" title="/en-US/docs/The_message_manager">message manager</a>. The backend listens for messages requesting certain actions, such as "associate", and responds with a message when the requested action has been completed.</p>
<p>The DOM side listens for the response methods as well as several event messages that indicate state changes and information updates.</p>
<div class="note">
 <p><strong>Note:</strong> Any synchromous DOM APIs are implemented by caching data on that side of the pipe. Synchronous messages are avoided whenever possible.</p>
</div>
<h3 id="WifiWorker.js">WifiWorker.js</h3>
<p>This file implements the main logic behind the WiFi interface. It runs in the chrome process (in multi-process builds) and is instantiated by the SystemWorkerManager. The file is generally broken into two sections: a giant anonymous function and <code>WifiWorker</code> (and its prototype). The anonymous function ends up being the <code>WifiManager</code> by providing a local API, including notifications for events such as connection to the supplicant and scan results being available. In general, it contains little logic and lets its sole consumer control its actions while it simply responds with the requested information and controls the details of the connection with the supplicant.</p>
<p>The <code>WifiWorker</code> object sits between the <code>WifiManager</code> and the DOM. It reacts to events and forwards them to the DOM; in turn, it receives requests from the DOM and performs the appropriate actions on the supplicant. It also maintains state information about the supplicant and what it needs to do next.</p>
<h3 id="DOMWifiManager.js">DOMWifiManager.js</h3>
<p>This implements the DOM API, transmitting messages back and forth between callers and the actual WiFi worker. There's very little logic involved.</p>
<div class="note">
 <p><strong>Note:</strong> In order to avoid synchronous messages to the chrome process, the WiFi Manager does need to cache the state based on the received event.</p>
</div>
<p>There's a single synchronous message, which is sent at the time the DOM API is instantiated, in order to get the current state of the supplicant.</p>
<h3 id="DHCP">DHCP</h3>
<p>DHCP and DNS are handled by <code>dhcpcd</code>, the standard Linux DHCP client. However, it's not able to react when the network connection is lost. Because of this, Firefox OS kills and restarts <code>dhcpcd</code> each time it connects to a given wireless network.</p>
<p><code>dhcpcd</code> is also responsible for setting the default route; we call into the network manager to tell the kernel about DNS servers.</p>
<h2 id="Network_Manager">Network Manager</h2>
<p>The Network Manager configures network interfaces opened by the 3G data and WiFi components.</p>
<div class="note">
 <p><strong>Note:</strong> This needs to be written.</p>
</div>
<h2 id="Processes_and_threads">Processes and threads</h2>
<p>Firefox OS uses POSIX threads to implement all application threads, this includes the main thread of each application as well as Web workers and helper threads. Nice values are used prioritize process and thread execution thus relying on the standard Linux kernel scheduler. Depending on the status of a process we assign it a different nice level. We've currently got 7 levels:</p>
<table class="standard-table" summary="Process priority levels">
 <caption>
  Process priority levels</caption>
 <thead>
  <tr>
   <th scope="col">Priority</th>
   <th scope="col">Nice</th>
   <th scope="col">Used for</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td><code>MASTER</code></td>
   <td>0</td>
   <td>main b2g process</td>
  </tr>
  <tr>
   <td><code>FOREGROUND_HIGH</code></td>
   <td>0</td>
   <td>applications holding a CPU wakelock</td>
  </tr>
  <tr>
  </tr>
  <tr>
   <td><code>FOREGROUND</code></td>
   <td>1</td>
   <td>foreground applications</td>
  </tr>
  <tr>
   <td><code>FOREGROUND_KEYBOARD</code></td>
   <td>1</td>
   <td>keyboard application</td>
  </tr>
  <tr>
   <td><code>BACKGROUND_PERCEIVABLE</code></td>
   <td>7</td>
   <td>background applications playing audio</td>
  </tr>
  <tr>
   <td><code>BACKGROUND_HOMESCREEN</code></td>
   <td>18</td>
   <td>homescreen application</td>
  </tr>
  <tr>
   <td><code>BACKGROUND</code></td>
   <td>18</td>
   <td>all other applications running in the background</td>
  </tr>
 </tbody>
</table>
<p>Some levels share the same nice values, that's because those levels currently differ in the way they're treated by the out of memory killer. All priorities can be adjusted at build time via preferences; the relevant entries can be found in the <a href="http://hg.mozilla.org/mozilla-central/file/54e8c6492dc4/b2g/app/b2g.js#l610"><code>b2g/app/b2g.js</code></a> file.</p>
<div class="note">
 <p><strong>Note</strong>: for more information on the out-of-memory killer, and how Firefox OS manages low memory situations, read <a href="/en-US/Firefox_OS/Platform/Out_of_memory_management_on_Firefox_OS">Out of memory management on Firefox OS</a>.</p>
</div>
<p>Within a process the main thread inherits the nice value of the process whilst web worker threads are given a nice value that is one point higher than the main thread thus running at lower priority. This is done in order to prevent CPU-intensive workers from excessively slowing down the main thread. Processes priorities are changed whenever a major event happens such as an application is sent into the background or foreground, a new application is started up or an existing application grabs a CPU wakelock. Whenever a process priority is adjusted all its threads' priorities will also be adjusted accordingly.</p>
<div class="note">
 <p><strong>Note:</strong> cgroups are not currently used for resource management as they've proven unreliable on certain devices and kernels.</p>
</div>
<p>&nbsp;</p>
このリビジョンへ戻す