1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
|
---
title: Firefox OS Architektur
slug: Archive/B2G_OS/Platform/Architektur
translation_of: Archive/B2G_OS/Architecture
---
<div class="summary">
<p><span class="seoSummary">Dieser Artikel gibt eine Übersicht über die Architektur der Firefox OS Plattform und beschreibt die grundlegenden Konzepte und wie die einzelnen Komponenten prinzipiell zusammen arbeiten.</span></p>
</div>
<div class="note">
<p><strong>Hinweis:</strong> Bitte denke daran, dass Firefox OS noch nicht veröffentlicht ist. Die hier beschriebene Architektur ist möglicherweise noch nicht endgültig und es können sich noch ein paar Dinge ändern.</p>
</div>
<h2 id="Firefox_OS_Begriffserklärungen">Firefox OS Begriffserklärungen</h2>
<p>Einige Begriffe solltest Du kennen, bevor Du die Dokumentation von Firefox OS liest.</p>
<dl>
<dt>B2G</dt>
<dd>Kurzform von "Boot to Gecko"</dd>
<dt>Boot to Gecko</dt>
<dd>Der interne Code-Name für das Firefox OS Betriebssystem. Du wirst diesen Begriff häufig als Synonym für Firefox OX finden, weil dieser Code-Name schon lange genutzt wurde bevor das Projekt einen offiziellen Namen hatte.</dd>
<dt>Firefox OS</dt>
<dd>Firefox OS stellt im Grunde das Mozilla Branding (und das von OEM Partnern) und verschiedene Support-Programme über der <strong>Boot to Gecko</strong> Ebene bereit, um aus den einzelnen Komponenten ein marktfähiges Produkt zu machen.</dd>
<dt><a href="/en-US/docs/Mozilla/Firefox_OS/Gaia" title="/en-US/docs/Mozilla/Firefox_OS/Gaia">Gaia</a></dt>
<dd>Das ist die Benutzeroberfläche (User Interface) der Firefox OS Plattform. Alles, was nach dem Start von Firefox OS auf dem Bildschirm zu sehen ist wird von der Gaia Schicht erzeugt. Gaia implementiert den Sperrbildschirm, die Startseite und alle Apps, die man von einem modernen Smartphone erwartet. Die Gaia Schicht wurde vollständig in HTML, CSS und JavaScript geschrieben. Gaia kommuniziert mit dem darunter liegenden Betriebssystem ausschließlich über offene Web APIs, die durch Gecko bereit gestellt werden. Anwendungen von Drittanbietern können neben Gaia installiert werden.</dd>
<dt><a href="https://developer.mozilla.org/en-US/docs/Gecko">Gecko</a></dt>
<dd>Gecko ist die Laufzeitumgebung von Firefox OS. Diese Schicht stellt alles zur Verfügung, was für die drei offenen Standards HTML, CSS und JavaScript benötigt wird. Gecko stellt sicher, dass diese APIs auf jedem von Gecko unterstützten Betriebssystem gut funktionieren. Zu diesem Zweck beinhaltet Gecko unter anderem Netzwerk-, Grafik- und Layoutstacks sowie eine Virtuelle Maschine für JavaScript und Schichten für die Portierung.</dd>
<dt><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Firefox_OS/Gonk">Gonk</a></dt>
<dd>Gonk ist eine tiefer liegende Schicht des Firefox OS Betriebsystems, bestehend aus dem Linux Kernel (basierend auf dem <a href="http://source.android.com/">Android Open Source Project</a> (AOSP)) und der Hardware-Abstraktionsschicht (hardware abstraction layer, HAL). Der Linux Kernel und einige der Anwendungs-Bibliotheken sind allgemeine Open Source Projekte: Linux, libusb, bluez und andere. Einige Pakete des HAL sind Gemeinschafts-Projekte mit AOSP: GPS, Kamera und andere. Man könnte sagen, Gonk ist eine sehr einfache Linux Distribution. Gonk ist ein <strong>Port</strong> von Gecko. Das heißt, es gibt einen Port von Gecko zu Gonk, so wie es Ports von Gecko zu Mac OS X, Windows und Android gibt. Seit das Firefox OS Projekt die alleinige Kontrolle über Gonk hat können wir Schnittstellen zu Gecko entwickeln, die auf anderen Betriebssystemen nicht möglich sind. Zum Beispiel hat Gecko auf Gonk direkten Zugriff zur gesamten Telefonie-Einheit und zum Display Frame Buffer. Auf anderen Betriebssystemen ist dies nicht möglich.</dd>
<dt><a name="Jank">Jank</a></dt>
<dd>Dieser im Bereich der mobilen Web Apps häufig genutzte Begriff bezeichnet den Effekt von langsamem und ineffizientem Code in einer App, wodurch die Aktualisierung der Benutzeroberfläche blockiert wird und diese nur noch langsam oder überhaupt nicht mehr reagiert. Unsere Gaia Entwickler nutzen verschiedene Optimierungs-Techniken, um diese Probleme unter allen Umständen zu verhindern.</dd>
</dl>
<h2 id="Overall_architecture">Overall architecture</h2>
<p>The following figure compares architectures between proprietary platforms and Firefox OS.</p>
<p><img alt="on the left is a native mobile architecture stack, on the right is the Firefox OS architecture. they are similarm except that the native stack is all proprietary device functionality, and the Firefox OS stack is all done with open source and web technologies." src="https://mdn.mozillademos.org/files/9487/general-architecture.png" style="display: block; height: 488px; margin: 0px auto; width: 997px;"></p>
<p>Firefox OS eliminates the native API layer between the operating system and application layers. This integrated design reduces platform overhead and simplifies security without sacrificing performance or a rich user smart phone experience.</p>
<ol>
<li><a href="https://developer.mozilla.org/en-US/Firefox_OS/Platform/Gaia">Gaia</a> is the core web apps of the device, and user interface layer, all written in HTML5, CSS and JavaScript, with a number of exposed APIs to allow the UI code to interact with the phone hardware and Gecko functionality.</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Gecko">Gecko</a> is the web engine and presentation layer in Firefox OS that connects hardware to HTML by serving as the interface between web content and the underlying device. Gecko provides an HTML5 parsing and rendering engine, programmatic access to hardware functionality via secure web APIs, a comprehensive security framework, update management, and other core services.</li>
<li><a href="https://developer.mozilla.org/en-US/Firefox_OS/Platform/Gonk">Gonk</a> is the kernel-level component in the Firefox OS stack that serves as the interface between Gecko and the underlying hardware. Gonk controls the underlying hardware and exposes hardware capabilities to Web APIs implemented in Gecko. Gonk can be seen as the “black box” that does all the complex, detailed work behind the scenes to control the mobile device by enacting requests at the hardware level.</li>
<li>The mobile device is the mobile phone hardware running Firefox OS. The OEM (Original Equipment Manifacturer) is responsible for providing the mobile device.</li>
</ol>
<h2 id="Specific_Firefox_OS_architecture">Specific Firefox OS architecture</h2>
<p><img alt="Firefox OS Architecture" src="https://developer.mozilla.org/files/4605/FirefoxOS.png" style="display: block; height: 915px; margin: 0px auto; width: 754px;"></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="display: block; height: 1979px; margin: 0px auto; width: 2112px;"></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; line-numbers language-cpp"><code class="language-cpp">FILE <span class="operator token">*</span>capacityFile <span class="operator token">=</span> <span class="function token">fopen</span><span class="punctuation token">(</span><span class="string token">"/sys/class/power_supply/battery/capacity"</span><span class="punctuation token">,</span> <span class="string token">"r"</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
double capacity <span class="operator token">=</span> dom<span class="punctuation token">:</span><span class="punctuation token">:</span>battery<span class="punctuation token">:</span><span class="punctuation token">:</span>kDefaultLevel <span class="operator token">*</span> <span class="number token">100</span><span class="punctuation token">;</span>
<span class="keyword token">if</span> <span class="punctuation token">(</span>capacityFile<span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="function token">fscanf</span><span class="punctuation token">(</span>capacityFile<span class="punctuation token">,</span> <span class="string token">"%lf"</span><span class="punctuation token">,</span> <span class="operator token">&</span>capacity<span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="function token">fclose</span><span class="punctuation token">(</span>capacityFile<span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span></code></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 class="line-numbers language-html"><code class="language-html">service b2g /system/bin/b2g.sh
class main
onrestart restart media</code></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="https://developer.mozilla.org/files/3849/B2G%20userspace%20architecture.svg"><img alt="Userspace diagram" src="https://developer.mozilla.org/files/3849/B2G%20userspace%20architecture.svg" style="float: right; height: 491px; position: relative; width: 520px;"></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 <a href="#Gecko">Gecko</a> 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="https://developer.mozilla.org/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 class="line-numbers language-html"><code class="language-html">service ril-daemon /system/bin/rild
socket rild stream 660 root radio</code></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="https://developer.mozilla.org/en-US/docs/Gecko" title="/en-US/docs/Gecko">Gecko</a>, as previously mentioned, is the implementation of web standards (<a href="https://developer.mozilla.org/en-US/docs/HTML" title="/en-US/docs/HTML">HTML</a>, <a href="https://developer.mozilla.org/en-US/docs/CSS" title="/en-US/docs/CSS">CSS</a>, and <a href="https://developer.mozilla.org/en-US/docs/JavaScript" title="/en-US/docs/JavaScript">JavaScript</a>) that is used to implement everything the user sees on Firefox OS, and control interactions with the phone hardware. Web apps connect HTML5 to hardware via controlled, secure Web APIs, implemented in Gecko. The Web APIs provide programmatic access to features in the underlying mobile device hardware (such as the battery or vibration), along with data that is stored on, or available to, a device (such as the calendar or contacts). Web content invokes the accessible Web APIs within HTML5.</p>
<p>An app consists of a collection of related HTML5 web content. To build web apps that run on Firefox OS mobile devices, developers simply assemble, package, and distribute this web content. At run time, this web content is interpreted, compiled, and rendered in a web browser. For more information on Apps, see the <a href="https://developer.mozilla.org/en-US/Apps">App Center</a>.</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_architecture_diagram">Gecko architecture diagram</h3>
<p><img alt="" src="https://mdn.mozillademos.org/files/5027/securityframework.png" style="height: 591px; width: 979px;"></p>
<ul>
<li><strong>Security Framework</strong>: contains
<ul>
<li><strong>Permission Manager</strong>: Gateway to accessing functionality in the Web API.</li>
<li><strong>Access Control List</strong>: Matrix of roles and permissions required to access Web API functionality.</li>
<li><strong>Credential Validation</strong>: Authentication of apps/users.</li>
<li><strong>Permissions Store</strong>: Set of privileges required to access Web API functionality.</li>
</ul>
</li>
<li><strong>Web API</strong>: Set of standard APIs that exposes hardware functionality to web content. Provides web apps with secure, programmatic access to features in the underlying mobile device hardware, along with data that is stored on—or available to—a device.</li>
<li><strong>I/O</strong>: Interface to the hardware and data store(s).</li>
<li><strong>Software Updates</strong>: Obtain and install updates to system software and third-party apps.</li>
<li><strong>Content Layout & Rendering</strong>: Engine that parses, interprets, and executes web content and, with formatting information, displays the formatted content to the user.</li>
<li><strong>b2g process</strong>: (Gecko) runs in a highly-privileged system process that has access to hardware features in the mobile phone. Running apps are child processes of b2g.</li>
</ul>
<h3 id="Gecko_files_related_to_Firefox_OS">Gecko files related to Firefox OS</h3>
<h4 id="b2g_2">b2g/</h4>
<p>The b2g folder contains mainly Firefox OS-related functions.</p>
<h5 id="b2gchromecontent">b2g/chrome/content</h5>
<p>Contains Javascript files run above the system app.</p>
<h5 id="b2gchromecontentshell.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 line-numbers language-html"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>script</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>application/javascript;version<span class="punctuation token">=</span>1.8<span class="punctuation token">"</span></span> <span class="attr-name token">src</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>chrome://browser/content/settings.js<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="language-javascript script token"> </span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>script</span><span class="punctuation token">></span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>script</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>application/javascript;version<span class="punctuation token">=</span>1.8<span class="punctuation token">"</span></span> <span class="attr-name token">src</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>chrome://browser/content/shell.js<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="language-javascript script token"> </span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>script</span><span class="punctuation token">></span></span></code></pre>
<p><code>settings.js</code> contains system default setting parameters.</p>
<h5 id="b2gchromecontentshell.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 line-numbers language-js"><code class="language-js"><span class="keyword token">let</span> systemAppFrame <span class="operator token">=</span>
document<span class="punctuation token">.</span><span class="function token">createElementNS</span><span class="punctuation token">(</span><span class="string token">'http://www.w3.org/1999/xhtml'</span><span class="punctuation token">,</span> <span class="string token">'html:iframe'</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">.</span><span class="punctuation token">.</span><span class="punctuation token">.</span>
container<span class="punctuation token">.</span><span class="function token">appendChild</span><span class="punctuation token">(</span>systemAppFrame<span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre>
<h5 id="b2gappb2g.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="domAPI">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="domapps">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="domappsPermissionsTable.jsm">dom/apps/PermissionsTable.jsm</h5>
<p>All permissions are defined in <a href="http://mxr.mozilla.org/mozilla-central/source/dom/apps/PermissionsTable.jsm">PermissionsTable.jsm</a></p>
<h4 id="domwebidl">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="halgonk">hal/gonk</h4>
<p>This directory contains files related to the gonk port layer.</p>
<h4 id="Generated_files">Generated files</h4>
<h5 id="modulelibprefsrcinitall.js">module/libpref/src/init/all.js</h5>
<p>Contains all config files.</p>
<h5 id="systemb2g_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 <a href="https://dxr.mozilla.org/mozilla-central/source/widget/gonk/nsAppShell.cpp" rel="custom">Gonk implementation</a> of <code><a href="/de/docs/XPCOM_Interface_Referenz/nsIAppShell" title="">nsIAppShell</a></code>, 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; line-numbers language-cpp"><code class="language-cpp">void GeckoInputDispatcher<span class="punctuation token">:</span><span class="punctuation token">:</span><span class="function token">notifyKey</span><span class="punctuation token">(</span>nsecs_t eventTime<span class="punctuation token">,</span>
int32_t deviceId<span class="punctuation token">,</span>
int32_t source<span class="punctuation token">,</span>
uint32_t policyFlags<span class="punctuation token">,</span>
int32_t action<span class="punctuation token">,</span>
int32_t flags<span class="punctuation token">,</span>
int32_t keyCode<span class="punctuation token">,</span>
int32_t scanCode<span class="punctuation token">,</span>
int32_t metaState<span class="punctuation token">,</span>
nsecs_t downTime<span class="punctuation token">)</span> <span class="punctuation token">{</span>
UserInputData data<span class="punctuation token">;</span>
data<span class="punctuation token">.</span>timeMs <span class="operator token">=</span> <span class="function token">nanosecsToMillisecs</span><span class="punctuation token">(</span>eventTime<span class="punctuation token">)</span><span class="punctuation token">;</span>
data<span class="punctuation token">.</span>type <span class="operator token">=</span> UserInputData<span class="punctuation token">:</span><span class="punctuation token">:</span>KEY_DATA<span class="punctuation token">;</span>
data<span class="punctuation token">.</span>action <span class="operator token">=</span> action<span class="punctuation token">;</span>
data<span class="punctuation token">.</span>flags <span class="operator token">=</span> flags<span class="punctuation token">;</span>
data<span class="punctuation token">.</span>metaState <span class="operator token">=</span> metaState<span class="punctuation token">;</span>
data<span class="punctuation token">.</span>key<span class="punctuation token">.</span>keyCode <span class="operator token">=</span> keyCode<span class="punctuation token">;</span>
data<span class="punctuation token">.</span>key<span class="punctuation token">.</span>scanCode <span class="operator token">=</span> scanCode<span class="punctuation token">;</span>
<span class="punctuation token">{</span>
MutexAutoLock <span class="function token">lock</span><span class="punctuation token">(</span>mQueueLock<span class="punctuation token">)</span><span class="punctuation token">;</span>
mEventQueue<span class="punctuation token">.</span><span class="function token">push</span><span class="punctuation token">(</span>data<span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span>
gAppShell<span class="operator token">-</span><span class="operator token">></span><span class="function token">NotifyNativeEvent</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span></code></pre>
<p>These events come from the standard Linux <code>input_event</code> system. Firefox OS uses a <a href="https://dxr.mozilla.org/mozilla-central/source/widget/gonk/libui/InputReader.cpp" rel="custom">light abstraction layer</a> 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 <a href="https://dxr.mozilla.org/mozilla-central/source/widget/gonk/libui/EventHub.cpp" rel="custom">widget/gonk/libui/EventHub.cpp</a>.</p>
<p>Once the events are received by Gecko, they're dispatched into the DOM by <code><a href="https://dxr.mozilla.org/mozilla-central/source/widget/gonk/nsAppShell.cpp" rel="custom">nsAppShell</a></code>:</p>
<pre class="brush:cpp; line-numbers language-cpp"><code class="language-cpp">static nsEventStatus <span class="function token">sendKeyEventWithMsg</span><span class="punctuation token">(</span>uint32_t keyCode<span class="punctuation token">,</span>
uint32_t msg<span class="punctuation token">,</span>
uint64_t timeMs<span class="punctuation token">,</span>
uint32_t flags<span class="punctuation token">)</span> <span class="punctuation token">{</span>
nsKeyEvent <span class="function token">event</span><span class="punctuation token">(</span><span class="boolean token">true</span><span class="punctuation token">,</span> msg<span class="punctuation token">,</span> NULL<span class="punctuation token">)</span><span class="punctuation token">;</span>
event<span class="punctuation token">.</span>keyCode <span class="operator token">=</span> keyCode<span class="punctuation token">;</span>
event<span class="punctuation token">.</span>location <span class="operator token">=</span> nsIDOMKeyEvent<span class="punctuation token">:</span><span class="punctuation token">:</span>DOM_KEY_LOCATION_MOBILE<span class="punctuation token">;</span>
event<span class="punctuation token">.</span>time <span class="operator token">=</span> timeMs<span class="punctuation token">;</span>
event<span class="punctuation token">.</span>flags <span class="operator token">|</span><span class="operator token">=</span> flags<span class="punctuation token">;</span>
<span class="keyword token">return</span> nsWindow<span class="punctuation token">:</span><span class="punctuation token">:</span><span class="function token">DispatchInputEvent</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span></code></pre>
<p>After that, the events are either consumed by Gecko itself or are dispatched to Web applications as <a href="https://developer.mozilla.org/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><a href="https://dxr.mozilla.org/mozilla-central/source/widget/gonk/nsWindow.cpp" rel="custom">nsWindow</a></code> by code similar to this:</p>
<pre class="brush:cpp; line-numbers language-cpp"><code class="language-cpp">gNativeWindow <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">android</span><span class="punctuation token">:</span><span class="punctuation token">:</span><span class="function token">FramebufferNativeWindow</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
sGLContext <span class="operator token">=</span> GLContextProvider<span class="punctuation token">:</span><span class="punctuation token">:</span><span class="function token">CreateForWindow</span><span class="punctuation token">(</span>this<span class="punctuation token">)</span><span class="punctuation token">;</span></code></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="https://developer.mozilla.org/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 — this part of the interaction is handled by the Web APIs.</p>
<p>Let's look at the process form a high level. When a user makes a request to use a phone feature (such as dialing a number, accessing a local wifi network, or connecting via Bluetooth), all layers in the Firefox OS technology stack are involved in carrying out the request. Apps and web content in the Gaia layer submits requests to access the underlying device via Web API calls (invoked from within HTML5 functions), which are implemented in Gecko. Gecko in turn submits the request to Gonk. A single request from Gecko can trigger a complex series of operations, initiated and managed by Gonk, in the mobile phone.</p>
<h4 id="How_the_HAL_works">How the HAL works</h4>
<p>Let's consider the <a href="/de/docs/Web/API/Window/navigator/vibrate" title="Die Beschreibung hierüber wurde bisher noch nicht geschrieben; bitte erwäge, mitzuwirken!"><code>Vibration</code></a> API as an example. The Gecko HAL for this API is defined in <a href="https://dxr.mozilla.org/mozilla-central/source/hal/Hal.h" rel="custom">hal/Hal.h</a>. In essence (simplifying the method signature for clarity's sake), you have this function:</p>
<pre class="line-numbers language-html"><code class="language-html">void Vibrate(const nsTArray<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>uint32</span><span class="punctuation token">></span></span> &pattern);</code></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 <a href="https://dxr.mozilla.org/mozilla-central/source/hal/gonk/GonkHal.cpp" rel="custom">hal/gonk/GonkHal.cpp</a>:</p>
<pre class="brush:cpp; line-numbers language-cpp"><code class="language-cpp">void <span class="function token">Vibrate</span><span class="punctuation token">(</span>const nsTArray<span class="operator token"><</span>uint32_t<span class="operator token">></span> <span class="operator token">&</span>pattern<span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="function token">EnsureVibratorThreadInitialized</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
sVibratorRunnable<span class="operator token">-</span><span class="operator token">></span><span class="function token">Vibrate</span><span class="punctuation token">(</span>pattern<span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span></code></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; line-numbers language-cpp"><code class="language-cpp"><span class="keyword token">while</span> <span class="punctuation token">(</span><span class="operator token">!</span>mShuttingDown<span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="keyword token">if</span> <span class="punctuation token">(</span>mIndex <span class="operator token"><</span> mPattern<span class="punctuation token">.</span><span class="function token">Length</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">)</span> <span class="punctuation token">{</span>
uint32_t duration <span class="operator token">=</span> mPattern<span class="punctuation token">[</span>mIndex<span class="punctuation token">]</span><span class="punctuation token">;</span>
<span class="keyword token">if</span> <span class="punctuation token">(</span>mIndex <span class="operator token">%</span> <span class="number token">2</span> <span class="operator token">==</span> <span class="number token">0</span><span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="function token">vibrator_on</span><span class="punctuation token">(</span>duration<span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span>
mIndex<span class="operator token">++</span><span class="punctuation token">;</span>
mMonitor<span class="punctuation token">.</span><span class="function token">Wait</span><span class="punctuation token">(</span><span class="function token">PR_MillisecondsToInterval</span><span class="punctuation token">(</span>duration<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span>
<span class="keyword token">else</span> <span class="punctuation token">{</span>
mMonitor<span class="punctuation token">.</span><span class="function token">Wait</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span>
<span class="punctuation token">}</span></code></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 <a href="https://dxr.mozilla.org/mozilla-central/source/hal/fallback/FallbackVibration.cpp" rel="custom">hal/fallback/FallbackVibration.cpp</a>.</p>
<pre class="brush:cpp; line-numbers language-cpp"><code class="language-cpp">void <span class="function token">Vibrate</span><span class="punctuation token">(</span>const nsTArray<span class="operator token"><</span>uint32_t<span class="operator token">></span> <span class="operator token">&</span>pattern<span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="punctuation token">}</span></code></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 <a href="https://dxr.mozilla.org/mozilla-central/source/hal/sandbox/SandboxHal.cpp" rel="custom">hal/sandbox/SandboxHal.cpp</a>:</p>
<pre class="brush:cpp; line-numbers language-cpp"><code class="language-cpp">void <span class="function token">Vibrate</span><span class="punctuation token">(</span>const nsTArray<span class="operator token"><</span>uint32_t<span class="operator token">></span><span class="operator token">&</span> pattern<span class="punctuation token">,</span> const WindowIdentifier <span class="operator token">&</span>id<span class="punctuation token">)</span> <span class="punctuation token">{</span>
AutoInfallibleTArray<span class="operator token"><</span>uint32_t<span class="punctuation token">,</span> <span class="number token">8</span><span class="operator token">></span> <span class="function token">p</span><span class="punctuation token">(</span>pattern<span class="punctuation token">)</span><span class="punctuation token">;</span>
WindowIdentifier <span class="function token">newID</span><span class="punctuation token">(</span>id<span class="punctuation token">)</span><span class="punctuation token">;</span>
newID<span class="punctuation token">.</span><span class="function token">AppendProcessID</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="function token">Hal</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="operator token">-</span><span class="operator token">></span><span class="function token">SendVibrate</span><span class="punctuation token">(</span>p<span class="punctuation token">,</span> newID<span class="punctuation token">.</span><span class="function token">AsArray</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">,</span> <span class="function token">GetTabChildFrom</span><span class="punctuation token">(</span>newID<span class="punctuation token">.</span><span class="function token">GetWindow</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span></code></pre>
<p>This sends a message defined by the <code>PHal</code> interface, described by IPDL in <a href="https://dxr.mozilla.org/mozilla-central/source/hal/sandbox/PHal.ipdl" rel="custom">hal/sandbox/PHal.ipdl</a>. This method is described more or less as follows:</p>
<pre class="line-numbers language-html"><code class="language-html">Vibrate(uint32_t[] pattern);</code></pre>
<p>The receiver of this message is the <code>HalParent::RecvVibrate()</code> method in <a href="https://dxr.mozilla.org/mozilla-central/source/hal/sandbox/SandboxHal.cpp" rel="custom">hal/sandbox/SandboxHal.cpp</a>, which looks like this:</p>
<pre class="brush:cpp; line-numbers language-cpp"><code class="language-cpp">virtual bool <span class="function token">RecvVibrate</span><span class="punctuation token">(</span>const InfallibleTArray<span class="operator token"><</span>unsigned int<span class="operator token">></span><span class="operator token">&</span> pattern<span class="punctuation token">,</span>
const InfallibleTArray<span class="operator token"><</span>uint64_t<span class="operator token">></span> <span class="operator token">&</span>id<span class="punctuation token">,</span>
PBrowserParent <span class="operator token">*</span>browserParent<span class="punctuation token">)</span> MOZ_OVERRIDE <span class="punctuation token">{</span>
hal<span class="punctuation token">:</span><span class="punctuation token">:</span><span class="function token">Vibrate</span><span class="punctuation token">(</span>pattern<span class="punctuation token">,</span> newID<span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="keyword token">return</span> <span class="boolean token">true</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span></code></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="https://developer.mozilla.org/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="https://developer.mozilla.org/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><a href="https://dxr.mozilla.org/mozilla-central/source/dom/interfaces/base/nsIDOMNavigator.idl" rel="custom">nsIDOMNavigator.idl</a>:</code></p>
<pre class="line-numbers language-html"><code class="language-html">[implicit_jscontext] void mozVibrate(in jsval aPattern);</code></pre>
<p>The <a href="https://developer.mozilla.org/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="https://developer.mozilla.org/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><a href="https://dxr.mozilla.org/mozilla-central/source/dom/base/Navigator.cpp" rel="custom">Navigator.cpp</a></code>.</p>
<pre class="brush:cpp; line-numbers language-cpp"><code class="language-cpp">NS_IMETHODIMP Navigator<span class="punctuation token">:</span><span class="punctuation token">:</span><span class="function token">MozVibrate</span><span class="punctuation token">(</span>const jsval<span class="operator token">&</span> aPattern<span class="punctuation token">,</span> JSContext<span class="operator token">*</span> cx<span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="comment token">// ...</span>
hal<span class="punctuation token">:</span><span class="punctuation token">:</span><span class="function token">Vibrate</span><span class="punctuation token">(</span>pattern<span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="keyword token">return</span> NS_OK<span class="punctuation token">;</span>
<span class="punctuation token">}</span></code></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 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="https://developer.mozilla.org/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 <a href="#The_userspace_process_architecture">The userspace process architecture</a>. 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 <a href="https://dxr.mozilla.org/mozilla-central/source/dom/system/gonk/ril_worker.js" rel="custom">dom/system/gonk/ril_worker.js</a>, which implements a worker thread that talks to <code>rild</code> through <code>rilproxy</code> and implements the radio state machine; and the <code><a href="/de/docs/XPCOM_Interface_Referenz/nsIRadioInterfaceLayer" title="">nsIRadioInterfaceLayer</a></code> interface, which is the main thread's <a href="https://developer.mozilla.org/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 <code><a href="/de/docs/XPCOM_Interface_Referenz/nsIRILContentHelper" title="">nsIRILContentHelper</a></code> interface provides an XPCOM service that lets code implementing parts of the DOM, such as the <a href="https://developer.mozilla.org/en-US/docs/API/WebTelephony" title="/en-US/docs/API/WebTelephony">Telephony</a> and <a href="https://developer.mozilla.org/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_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; line-numbers language-cpp"><code class="language-cpp">ret <span class="operator token">=</span> <span class="function token">read</span><span class="punctuation token">(</span>rilproxy_rw<span class="punctuation token">,</span> data<span class="punctuation token">,</span> <span class="number token">1024</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="keyword token">if</span><span class="punctuation token">(</span>ret <span class="operator token">></span> <span class="number token">0</span><span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="function token">writeToSocket</span><span class="punctuation token">(</span>rild_rw<span class="punctuation token">,</span> data<span class="punctuation token">,</span> ret<span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span></code></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 <a href="https://dxr.mozilla.org/mozilla-central/source/ipc/ril/Ril.cpp" rel="custom">IPC thread</a>:</p>
<pre class="brush:cpp; line-numbers language-cpp"><code class="language-cpp">int ret <span class="operator token">=</span> <span class="function token">read</span><span class="punctuation token">(</span>fd<span class="punctuation token">,</span> mIncoming<span class="operator token">-</span><span class="operator token">></span>Data<span class="punctuation token">,</span> <span class="number token">1024</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="comment token">// ... handle errors ...</span>
mIncoming<span class="operator token">-</span><span class="operator token">></span>mSize <span class="operator token">=</span> ret<span class="punctuation token">;</span>
sConsumer<span class="operator token">-</span><span class="operator token">></span><span class="function token">MessageReceived</span><span class="punctuation token">(</span>mIncoming<span class="punctuation token">.</span><span class="function token">forget</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre>
<p>The consumer of these messages is <a href="https://dxr.mozilla.org/mozilla-central/source/dom/system/gonk/SystemWorkerManager.cpp" rel="custom">SystemWorkerManager</a>, which repackages the messages and dispatches them to the <code><a href="https://dxr.mozilla.org/mozilla-central/source/dom/system/gonk/ril_worker.js" rel="custom">ril_worker.js</a></code> thread that implements the RIL state machine; this is done in the <code>RILReceiver::MessageReceived()</code> method:</p>
<pre class="brush:cpp; line-numbers language-cpp"><code class="language-cpp">virtual void <span class="function token">MessageReceived</span><span class="punctuation token">(</span>RilRawData <span class="operator token">*</span>aMessage<span class="punctuation token">)</span> <span class="punctuation token">{</span>
nsRefPtr<span class="operator token"><</span>DispatchRILEvent<span class="operator token">></span> <span class="function token">dre</span><span class="punctuation token">(</span><span class="keyword token">new</span> <span class="class-name token">DispatchRILEvent</span><span class="punctuation token">(</span>aMessage<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
mDispatcher<span class="operator token">-</span><span class="operator token">></span><span class="function token">PostTask</span><span class="punctuation token">(</span>dre<span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span></code></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="https://developer.mozilla.org/en-US/docs/SpiderMonkey/JSAPI_Reference/JS_CallFunctionName" title="/en-US/docs/SpiderMonkey/JSAPI_Reference/JS_CallFunctionName">JS_CallFunctionName</a>()</code>:</p>
<pre class="line-numbers language-html"><code class="language-html">return JS_CallFunctionName(aCx, obj, "onRILMessage", NS_ARRAY_LENGTH(argv),
argv, argv);</code></pre>
<p><code>onRILMessage()</code> is implemented in <a href="https://dxr.mozilla.org/mozilla-central/source/dom/system/gonk/ril_worker.js" rel="custom">dom/system/gonk/ril_worker.js</a>, 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; line-numbers language-js"><code class="language-js">handleParcel<span class="punctuation token">:</span> <span class="keyword token">function</span> <span class="function token">handleParcel</span><span class="punctuation token">(</span>request_type<span class="punctuation token">,</span> length<span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="keyword token">let</span> method <span class="operator token">=</span> <span class="keyword token">this</span><span class="punctuation token">[</span>request_type<span class="punctuation token">]</span><span class="punctuation token">;</span>
<span class="keyword token">if</span> <span class="punctuation token">(</span><span class="keyword token">typeof</span> method <span class="operator token">==</span> <span class="string token">"function"</span><span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="keyword token">if</span> <span class="punctuation token">(</span>DEBUG<span class="punctuation token">)</span> <span class="function token">debug</span><span class="punctuation token">(</span><span class="string token">"Handling parcel as "</span> <span class="operator token">+</span> method<span class="punctuation token">.</span>name<span class="punctuation token">)</span><span class="punctuation token">;</span>
method<span class="punctuation token">.</span><span class="function token">call</span><span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">,</span> length<span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span>
<span class="punctuation token">}</span></code></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; line-numbers language-js"><code class="language-js">RIL<span class="punctuation token">[</span>UNSOLICITED_RESPONSE_CALL_STATE_CHANGED<span class="punctuation token">]</span> <span class="operator token">=</span> <span class="keyword token">function</span> <span class="function token">UNSOLICITED_RESPONSE_CALL_STATE_CHANGED</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="keyword token">this</span><span class="punctuation token">.</span><span class="function token">getCurrentCalls</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span><span class="punctuation token">;</span></code></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; line-numbers language-js"><code class="language-js">getCurrentCalls<span class="punctuation token">:</span> <span class="keyword token">function</span> <span class="function token">getCurrentCalls</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span>
Buf<span class="punctuation token">.</span><span class="function token">simpleRequest</span><span class="punctuation token">(</span>REQUEST_GET_CURRENT_CALLS<span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span></code></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 <code><a href="/de/docs/XPCOM_Interface_Referenz/nsIRadioInterfaceLayer" title="">nsIRadioInterfaceLayer</a></code> service on the main thread:</p>
<pre class="brush:js; line-numbers language-js"><code class="language-js">_handleChangedCallState<span class="punctuation token">:</span> <span class="keyword token">function</span> <span class="function token">_handleChangedCallState</span><span class="punctuation token">(</span>changedCall<span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="keyword token">let</span> message <span class="operator token">=</span> <span class="punctuation token">{</span>type<span class="punctuation token">:</span> <span class="string token">"callStateChange"</span><span class="punctuation token">,</span>
call<span class="punctuation token">:</span> changedCall<span class="punctuation token">}</span><span class="punctuation token">;</span>
<span class="keyword token">this</span><span class="punctuation token">.</span><span class="function token">sendDOMMessage</span><span class="punctuation token">(</span>message<span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span></code></pre>
<p><code><a href="/de/docs/XPCOM_Interface_Referenz/nsIRadioInterfaceLayer" title="">nsIRadioInterfaceLayer</a></code> is implemented in <a href="https://dxr.mozilla.org/mozilla-central/source/dom/system/gonk/RadioInterfaceLayer.js" rel="custom">dom/system/gonk/RadioInterfaceLayer.js</a>; the message is received by its <code>onmessage()</code> method:</p>
<pre class="brush:js; line-numbers language-js"><code class="language-js">onmessage<span class="punctuation token">:</span> <span class="keyword token">function</span> <span class="function token">onmessage</span><span class="punctuation token">(</span>event<span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="keyword token">let</span> message <span class="operator token">=</span> event<span class="punctuation token">.</span>data<span class="punctuation token">;</span>
<span class="function token">debug</span><span class="punctuation token">(</span><span class="string token">"Received message from worker: "</span> <span class="operator token">+</span> JSON<span class="punctuation token">.</span><span class="function token">stringify</span><span class="punctuation token">(</span>message<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="keyword token">switch</span> <span class="punctuation token">(</span>message<span class="punctuation token">.</span>type<span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="keyword token">case</span> <span class="string token">"callStateChange"</span><span class="punctuation token">:</span>
<span class="comment token">// This one will handle its own notifications.</span>
<span class="keyword token">this</span><span class="punctuation token">.</span><span class="function token">handleCallStateChange</span><span class="punctuation token">(</span>message<span class="punctuation token">.</span>call<span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="keyword token">break</span><span class="punctuation token">;</span>
<span class="punctuation token">.</span><span class="punctuation token">.</span><span class="punctuation token">.</span></code></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; line-numbers language-js"><code class="language-js">handleCallStateChange<span class="punctuation token">:</span> <span class="keyword token">function</span> <span class="function token">handleCallStateChange</span><span class="punctuation token">(</span>call<span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="punctuation token">[</span>some internal state updating<span class="punctuation token">]</span>
ppmm<span class="punctuation token">.</span><span class="function token">sendAsyncMessage</span><span class="punctuation token">(</span><span class="string token">"RIL:CallStateChanged"</span><span class="punctuation token">,</span> call<span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span></code></pre>
<p>In the content process, the message is received by <code>receiveMessage()</code> method in the <code><a href="/de/docs/XPCOM_Interface_Referenz/nsIRILContentHelper" title="">nsIRILContentHelper</a></code> service, from the Child Process Message Manager (CPMM):</p>
<pre class="brush:js; line-numbers language-js"><code class="language-js">receiveMessage<span class="punctuation token">:</span> <span class="keyword token">function</span> <span class="function token">receiveMessage</span><span class="punctuation token">(</span>msg<span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="keyword token">let</span> request<span class="punctuation token">;</span>
<span class="function token">debug</span><span class="punctuation token">(</span><span class="string token">"Received message '"</span> <span class="operator token">+</span> msg<span class="punctuation token">.</span>name <span class="operator token">+</span> <span class="string token">"': "</span> <span class="operator token">+</span> JSON<span class="punctuation token">.</span><span class="function token">stringify</span><span class="punctuation token">(</span>msg<span class="punctuation token">.</span>json<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="keyword token">switch</span> <span class="punctuation token">(</span>msg<span class="punctuation token">.</span>name<span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="keyword token">case</span> <span class="string token">"RIL:CallStateChanged"</span><span class="punctuation token">:</span>
<span class="keyword token">this</span><span class="punctuation token">.</span><span class="function token">_deliverTelephonyCallback</span><span class="punctuation token">(</span><span class="string token">"callStateChanged"</span><span class="punctuation token">,</span>
<span class="punctuation token">[</span>msg<span class="punctuation token">.</span>json<span class="punctuation token">.</span>callIndex<span class="punctuation token">,</span> msg<span class="punctuation token">.</span>json<span class="punctuation token">.</span>state<span class="punctuation token">,</span>
msg<span class="punctuation token">.</span>json<span class="punctuation token">.</span>number<span class="punctuation token">,</span> msg<span class="punctuation token">.</span>json<span class="punctuation token">.</span>isActive<span class="punctuation token">]</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="keyword token">break</span><span class="punctuation token">;</span></code></pre>
<p>This, in turn, calls the <code><a href="https://developer.mozilla.org/de/docs/XPCOM_Interface_Reference/nsIRILTelephonyCallback#callStateChanged()">nsIRILTelephonyCallback.callStateChanged()</a></code> methods on every registered telephony callback object. Every web application that accesses the <a href="/de/docs/Web/API/Window/navigator/mozTelephony" title="Die Beschreibung hierüber wurde bisher noch nicht geschrieben; bitte erwäge, mitzuwirken!"><code>window.navigator.mozTelephony</code></a> 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; line-numbers language-cpp"><code class="language-cpp">NS_IMETHODIMP Telephony<span class="punctuation token">:</span><span class="punctuation token">:</span><span class="function token">CallStateChanged</span><span class="punctuation token">(</span>PRUint32 aCallIndex<span class="punctuation token">,</span> PRUint16 aCallState<span class="punctuation token">,</span>
const nsAString<span class="operator token">&</span> aNumber<span class="punctuation token">,</span> bool aIsActive<span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="punctuation token">[</span><span class="punctuation token">.</span><span class="punctuation token">.</span><span class="punctuation token">.</span><span class="punctuation token">]</span>
<span class="keyword token">if</span> <span class="punctuation token">(</span>modifiedCall<span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="comment token">// Change state.</span>
modifiedCall<span class="operator token">-</span><span class="operator token">></span><span class="function token">ChangeState</span><span class="punctuation token">(</span>aCallState<span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="comment token">// See if this should replace our current active call.</span>
<span class="keyword token">if</span> <span class="punctuation token">(</span>aIsActive<span class="punctuation token">)</span> <span class="punctuation token">{</span>
mActiveCall <span class="operator token">=</span> modifiedCall<span class="punctuation token">;</span>
<span class="punctuation token">}</span>
<span class="keyword token">return</span> NS_OK<span class="punctuation token">;</span>
<span class="punctuation token">}</span>
nsRefPtr<span class="operator token"><</span>TelephonyCall<span class="operator token">></span> call <span class="operator token">=</span>
TelephonyCall<span class="punctuation token">:</span><span class="punctuation token">:</span><span class="function token">Create</span><span class="punctuation token">(</span>this<span class="punctuation token">,</span> aNumber<span class="punctuation token">,</span> aCallState<span class="punctuation token">,</span> aCallIndex<span class="punctuation token">)</span><span class="punctuation token">;</span>
nsRefPtr<span class="operator token"><</span>CallEvent<span class="operator token">></span> event <span class="operator token">=</span> CallEvent<span class="punctuation token">:</span><span class="punctuation token">:</span><span class="function token">Create</span><span class="punctuation token">(</span>call<span class="punctuation token">)</span><span class="punctuation token">;</span>
nsresult rv <span class="operator token">=</span> event<span class="operator token">-</span><span class="operator token">></span><span class="function token">Dispatch</span><span class="punctuation token">(</span><span class="function token">ToIDOMEventTarget</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">,</span> <span class="function token">NS_LITERAL_STRING</span><span class="punctuation token">(</span><span class="string token">"incoming"</span><span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="function token">NS_ENSURE_SUCCESS</span><span class="punctuation token">(</span>rv<span class="punctuation token">,</span> rv<span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="keyword token">return</span> NS_OK<span class="punctuation token">;</span>
<span class="punctuation token">}</span></code></pre>
<p>Applications can receive these events and update their user interface and so forth:</p>
<pre class="brush:js; line-numbers language-js"><code class="language-js">handleEvent<span class="punctuation token">:</span> <span class="keyword token">function</span> <span class="function token">fm_handleEvent</span><span class="punctuation token">(</span>evt<span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="keyword token">switch</span> <span class="punctuation token">(</span>evt<span class="punctuation token">.</span>call<span class="punctuation token">.</span>state<span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="keyword token">case</span> <span class="string token">'connected'</span><span class="punctuation token">:</span>
<span class="keyword token">this</span><span class="punctuation token">.</span><span class="function token">connected</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="keyword token">break</span><span class="punctuation token">;</span>
<span class="keyword token">case</span> <span class="string token">'disconnected'</span><span class="punctuation token">:</span>
<span class="keyword token">this</span><span class="punctuation token">.</span><span class="function token">disconnected</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="keyword token">break</span><span class="punctuation token">;</span>
<span class="keyword token">default</span><span class="punctuation token">:</span>
<span class="keyword token">break</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span>
<span class="punctuation token">}</span></code></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 <a href="https://de.wikipedia.org/wiki/Point-to-Point Protocol" title="Point-to-Point Protocol">Point-to-Point Protocol</a> (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="https://developer.mozilla.org/en-US/docs/API/WebTelephony/Introduction_to_WebTelephony" title="/en-US/docs/API/WebTelephony/Introduction_to_WebTelephony">Telephony API</a></li>
<li><a href="https://developer.mozilla.org/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><a href="https://dxr.mozilla.org/mozilla-central/source/dom/wifi/DOMWifiManager.js" rel="custom">dom/wifi/DOMWifiManager.js</a></dt>
<dd>Implements the API that's exposed to web content, as defined in <code><a href="/de/docs/XPCOM_Interface_Referenz/nsIWifi.idl" title="">nsIWifi.idl</a></code>.</dd>
<dt><a href="https://dxr.mozilla.org/mozilla-central/source/dom/wifi/WifiWorker.js" rel="custom">dom/wifi/WifiWorker.js</a></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="https://developer.mozilla.org/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. Control groups are used to prioritize process and thread execution thus relying on the Linux kernel's completely fair scheduler. Depending on the status of a process we assign it to different control group. We've currently got 6 priority levels corresponding to 5 control groups:</p>
<table class="standard-table">
<caption>Process priority levels</caption>
<thead>
<tr>
<th scope="col">Priority</th>
<th scope="col">Control group</th>
<th scope="col">Used for</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>MASTER</code></td>
<td> </td>
<td>Main b2g process</td>
</tr>
<tr>
<td><code>FOREGROUND_HIGH</code></td>
<td><code>apps/critical</code></td>
<td>Critical applications holding the <code>cpu</code> or <code>highpriority</code> wakelock; this is currently reserved for the clock and communications applications</td>
</tr>
<tr>
</tr>
<tr>
<td><code>FOREGROUND</code></td>
<td><code>apps</code></td>
<td>Foreground applications</td>
</tr>
<tr>
<td><code>FOREGROUND_KEYBOARD</code></td>
<td><code>apps</code></td>
<td>Keyboard application</td>
</tr>
<tr>
<td><code>BACKGROUND_PERCEIVABLE</code></td>
<td><code>apps/bg_perceivable</code></td>
<td>Background applications playing audio or holding the holding the <code>cpu</code> or <code>highpriority</code> wakelock and having at least a system message handler registered</td>
</tr>
<tr>
<td><code>BACKGROUND</code></td>
<td><code>apps/bg_non_interactive</code></td>
<td>All other applications running in the background</td>
</tr>
</tbody>
</table>
<p>Some levels share the same control group, that's because those levels currently differ in the way they're treated by the <a href="https://developer.mozilla.org/en-US/Firefox_OS/Platform/Out_of_memory_management_on_Firefox_OS">out of memory killer</a>. 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>
<p>The following control groups are currently used:</p>
<table class="standard-table">
<caption>Control groups</caption>
<thead>
<tr>
<th scope="col">Path</th>
<th scope="col">CPU allocation</th>
<th scope="col">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td> </td>
<td>50% of total CPU time</td>
<td>Root control group reserved for the main b2g process and system daemons</td>
</tr>
<tr>
<td><code>apps</code></td>
<td>50% of total CPU time</td>
<td>Regular applications</td>
</tr>
<tr>
<td><code>apps/critical</code></td>
<td>95% of <code>apps</code></td>
<td>Critical applications</td>
</tr>
<tr>
<td><code>apps/bg_perceivable</code></td>
<td>10% of <code>apps</code></td>
<td>Perceivable background applications</td>
</tr>
<tr>
<td><code>apps/bg_non_interactive</code></td>
<td>5% of <code>apps</code></td>
<td>Background applications</td>
</tr>
</tbody>
</table>
<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="https://developer.mozilla.org/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. All threads of an application are currently assigned to the same control group. Process priorities are changed whenever a major event happens such as an application being sent into the background or foreground, a new application starting up or an existing application grabbing a CPU wakelock.</p>
<div class="note">
<p><strong>Note:</strong> cgroups support on ICS devices is currently broken due to a kernel bug.</p>
</div>
|