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
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
|
---
title: Arquitectura del Sistema Operativo Firefox OS
slug: Archive/B2G_OS/Architecture
translation_of: Archive/B2G_OS/Architecture
---
<div class="summary">
<p><span class="seoSummary">Este artículo es un panorama de alto nivel de la arquitectura de la plataforma Firefox OS, que introduce conceptos fundamentales y explica cómo sus componentes interactúan a un nivel básico.</span></p>
</div>
<div class="note">
<p><strong>Nota:</strong> recuerda que Firefox OS todavía se encuentra en estado de pre-lanzamiento. La arquitectura descrita aquí no necesariamente es la final y que otros elementos todavía pueden estar sujetos a cambios.</p>
</div>
<h2 id="Terminología_de_Firefox_OS">Terminología de Firefox OS</h2>
<p>Existen algunos términos que debes entender antes de continuar leyendo nuestra documentación sobre Firefox OS.</p>
<dl>
<dt>B2G</dt>
<dd>Sigla de Boot to Gecko.</dd>
<dt>Boot to Gecko</dt>
<dd>El nombre código de ingeniería para el sistema operativo Firefox OS.</dd>
<dt>Firefox OS</dt>
<dd>Es básicamente la marca y servicios de soporte de Mozilla (y sus socios de OEM) aplicados sobre <strong>Boot to Gecko</strong> para crear el producto final de lanzamiento.</dd>
<dt><a href="/en-US/docs/Mozilla/Firefox_OS/Gaia" title="/en-US/docs/Mozilla/Firefox_OS/Gaia">Gaia</a></dt>
<dd>La interfaz de usuario de la plataforma Firefox OS. Cualquier cosa dibujada en la pantalla una vez que Firefox OS ha sido iniciado es un producto de la capa Gaia. La misma implementa la pantalla de seguridad (lock screen), pantalla principal (home screen) y todas las aplicaciones estándares de cualquier teléfono inteligente moderno. Gaia se implementa en su totalidad empleando HTML, CSS y JavaScript. Las interfaces subyacentes al sistema operativo son Web APIs de código abierto, que se implementan por medio de la capa Gecko. Las aplicaciones de terceros se pueden instalar en paralelo con la capa Gaia.</dd>
<dt><a href="/en-US/docs/Gecko" title="/en-US/docs/Accessibility/AT-APIs/Gecko">Gecko</a></dt>
<dd>Este es el <em>runtime</em> de aplicaciones de Firefox OS, es decir, la capa que provee todo el soporte para el trío de estándares de código abierto: HTML, CSS y JavaScript. Es responsable de que esas APIs funcionen bien en cualquier sistema operativo soportado por Gecko. Esto implica que Gecko incluya, además de otras cosas, paquetes de redes y de gráficos, un motor de diagramación, una máquina virtual de JavaScript y capas de adaptación (<em>porting</em>).</dd>
<dt><a href="/en-US/docs/Mozilla/Firefox_OS/Gonk" title="/en-US/docs/Mozilla/Firefox_OS/Gonk">Gonk</a></dt>
<dd>Gonk es el sistema operativo de bajo nivel de la plataforma Firefox OS que consiste un núcleo/kernel Linux (basado sobre el <a href="http://source.android.com/">Android Open Source Project</a> (AOSP)) y una capa de abstracción de hardware de espacio de usuario (HAL por su sigla en inglés). El kernel y varias de las librerías de espacio de usuario son proyectos comunes de código abierto: Linux, libusb, bluez, y sucesivos. Algunas de las otras partes de la HAL se comparten con la AOSP: GPS, cámara y otros. Se podría decir que Gonk es una distribución de Linux muy sencilla. <span style="line-height: 1.5;">Gonk es una capa de adaptación (port) de dispositivos: un adaptador entre el hardware y Gecko. Gonk es una distribución de Linux bastante sencilla que puede ser tratada como un adaptador Gecko empardado con capas de adaptación Gecko —entonces Gonk es un <strong>objetivo</strong> para adaptar <a href="https://developer.mozilla.org/en-US/docs/Gecko">Gecko</a> a Firefox OS así como también hay adaptadores de Gecko para OS X, Windows y Android.</span> Como el Proyecto Firefox OS goza de control total sobre Gonk, podemos exponer interfaces a Gecko que no podrían ser expuestas en otros sistemas operativos. Por ejemplo, Gecko posee a través de Gonk acceso directo al conjunto completo de telefonía y al buffer de pantalla pero no tiene este acceso en otros sistemas operativos.</dd>
<dt><a name="Jank">Jank</a></dt>
<dd>Este término, generalmente empleado en el área de las aplicaciones móviles, se refiere al efecto causado por código lento o ineficiente en una aplicación, que podría bloquear la actualización de la interfaz de usuario y provocar su lentitud o que no responda. Nuestros ingenieros de Gaia se valen de numerosas técnicas de optimización para evitar esto lo mejor posible.</dd>
</dl>
<h2 id="Diagrama_estructural">Diagrama estructural</h2>
<p><img alt="Firefox OS Architecture" src="/files/4605/FirefoxOS.png" style="display: block; height: 915px; margin: 0px auto; width: 754px;"></p>
<h2 id="Procedimiento_de_arranque_de_Firefox_OS">Procedimiento de arranque de Firefox OS</h2>
<p>Esta sección describe el proceso por el que los dipositivos con Firefox OS arrancan (<em>butean</em>), cuáles partes están involucradas en el proceso y dónde. A modo de referencia rápida, el flujo del arranque general del sistema va desde los cargadores de arranque (<em>bootloaders</em>) en el espacio del núcleo/<em>kernel </em>al <em>init</em> en el código nati<em>vo</em>, a B2G y después a Geko en el espacio de usuario y después finalmente a la aplicación de sistema, gestor de ventanas y posteriormente a la pantalla de inicio de la aplicación en Gecko. Sobre ese conjunto se ejecutan todas las otras aplicaciones.</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="El_proceso_de_arranque_encadenado_(bootstrapping)">El proceso de arranque encadenado (<em>bootstrapping</em>)</h3>
<p>Cuando un dispositivo con FirefoxOS se enciende, la ejecución se inicia en el cargador del arranque primario (<em>bootloader</em>). Desde allí, el proceso de la carga del SO principal procede normalmene; una sucesión de arranques de jerarquías crecientes inicia el siguiennte arranque en la cadena. Al final del proceso, se delega la ejecución al núcleo/kernel Linux.</p>
<p>Hay algunos puntos destcables sobre el proceso de arranque:</p>
<ul>
<li>Los arrancadores generalmente muestran la primera pantalla de sistema que ve el usuario durante el inicio; generalmente es un logo del fabricante/vendedor.</li>
<li>Los arrancadores cargan por <em>flash</em> una imagen [virtual] en el dispositivo. Diferentes dispositivos emplean difierentes protocolos; la mayoría de los teléfonos emplean el <em><a href="http://android-dls.com/wiki/index.php?title=Fastboot" title="http://android-dls.com/wiki/index.php?title=Fastboot">fastboot protocol</a></em> (protocolo de carga rápida), pero el Samsung Galaxy S II usa el protocolo Odin.</li>
<li>Hacia el final del proceso de arranque encadenado, suele cargarse la imagen virtual del módem y se ejecuta en el procesador del módem. Cómo ocurre esto es específico de cada dispositivo y puede tambien serlo del fabricante.</li>
</ul>
<h3 id="El_kernel_Linux">El <em>kernel</em> Linux</h3>
<p>El núcleo Linux empleado por Gonk es muy similar a la versión de Linux difundida (<em>upstreamed</em>) de la que deriva (basada sobre el <em><a href="http://source.android.com/" title="http://source.android.com/">Android Open Source Project</a></em>). Existen cambios hehos por el AOSP que todavía no han sido difundidos. Además, los fabricantes y vendedores a veces modifican el núcleo y cargan esos cambios a la versión de difusión de acuerdo con su intinerario. En términos generales, el núcleo Linux es muy parecido al original.</p>
<p>El <a href="http://en.wikipedia.org/wiki/Linux_startup_process" title="http://en.wikipedia.org/wiki/Linux_startup_process">proceso de arranque de Linux</a> se encuentra bien documentado en la internet por lo tanto este artículo no lo cubrirá.</p>
<p>El núcleo Linux activará dispositivos y ejecutará procesos esenciales definidos en <code>init.rc</code> y su sucesor <a href="https://github.com/mozilla-b2g/gonk-misc/blob/master/init.b2g.rc"><code>init.b2g</code>.<code>rc</code></a> para arrancar procesos esenciales como <code>b2g</code> [procesos básicos de Firefox OS, contenedores de Gecko] y <code>rild</code> [un proceso relacionado con la telefonía que puede ser específico de cada chip] —vaya más abajo para ver más detalles. Al final del proceso, un proceso <code>init</code> de espacio de usuario (<em>userspace</em>) se lanza, como ocurre en la mayoría de los sistemas operativos del tipo UNIX.</p>
<p>Una vez que el proceso <code>init</code> se ha lanzado, el núcleo Linux administra las llamadas del sistema desde el espacio de usuario, las interrupciones y semejantes desde los dispositivos de hardware. Algunas de las características de hardware se exponen al espacio de usuario a través de <a href="http://en.wikipedia.org/wiki/Sysfs" title="http://en.wikipedia.org/wiki/Sysfs"><code>sysfs</code></a>. Por ejemplo, aquí hay un <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">fragmento de código</a> que lee el estado de la batería en 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", &capacity);
fclose(capacityFile);
}</pre>
<h3 id="Más_sobre_el_proceso_init">Más sobre el proceso <code>init</code></h3>
<p>El proceso <code>init</code> en Gonk gestiona el montaje de los archivos de sistema requeridos y activa los procesos de systema. Después de eso, se mantiene activo como gestor de procesos. Esto es muy similar al init en otros sistemas operativos similares a UNIX. Interpreta <em>scripts</em> [los archivos <code>init.rc</code>] que consisten de comandos que describen lo que debería ser hecho para iniciar servicios varios. El <code>init.rc</code> de FirefoxOS suele ser el <code>init.rc original </code>de Android para ese dispositivo, parchado para incluir los requisitos de arranque de FirefoxOS, y varía de dispositivo a dispositivo.</p>
<p>Una de las tareas fundamentales que maneja el proceso <code>init</code> es el inicio del proceso <code>b2g</code>; éste es el núcleo del sistema operativo FirefoxOS.</p>
<p>El código para tal <code>init.rc</code> es el siguiente:</p>
<pre>service b2g /system/bin/b2g.sh
class main
onrestart restart media</pre>
<div class="note">
<p><strong>Nota:</strong> las variaciones de<code> init.rc </code>dependerán de dispositivo a dispositivo; a veces <code>init.b2g.rc</code> sólo es anexadoo, y a veces los parches son más significativos.</p>
</div>
<h2 id="Arquitectura_de_los_procesos_del_espacio_de_usuario_(userspace)">Arquitectura de los procesos del espacio de usuario (userspace)</h2>
<p>Resulta muy útil echar un vistazo de alto nivel a cómo varios componentes del Firefox OS se articulan e interactúan entre sí. Este diagrama muestra los procesos primarios de espacio de usuario en Firefox OS.</p>
<p><a href="/files/3849/B2G userspace architecture.svg"><img alt="Userspace diagram" src="/files/3849/B2G%20userspace%20architecture.svg" style="float: right; height: 491px; position: relative; width: 520px;"></a></p>
<div class="note">
<p><strong>Nota:</strong> recuerda que como Firefox OS se encuentra en desarrollo activo, este diagrama puede estar sujeto a cambios y puede ser impreciso parcialmente.</p>
</div>
<p>El proceso b2g es el proceso primario de sistema. Se ejecuta con privilegios altos; tiene acceso a la mayoría del hardware. b2g se comunica con el módem, almacena en el buffer de pantalla e interactúa con el GPS, cámaras y otros dispositivos. Internamemte, se ejecuta con una capa de Gecko<span style="line-height: 1.5;"> (implementada por </span><code style="font-style: normal; line-height: 1.5;">libxul.so</code><span style="line-height: 1.5;">). Ver <a href="#Gecko">Gecko</a> para más detalles sobre cómo funciona la capa Gecko y cómo b2g se comunica con ella.</span></p>
<h3 id="b2g">b2g</h3>
<p>El proceso <code>b2g</code> puede dar lugar a un número de procesos de contenido de privilegios limitados. Estos procesos albergan la carga de aplicaciones web y otros contenidos. Estos procesos se comunican con el proceso principal del servidor Gecko a través de <a href="/en-US/docs/IPDL" title="/en-US/docs/IPDL">IPDL</a>, un sistema de envio de mensajes.</p>
<p>El proceso <code>b2g</code> ejecuta lixbul, el cual referencia a <code>b2g/app/b2g.js</code> para obtener las preferencias de fábrica. De las preferencias se abrirá el archivo HTML descriptor <code>b2g/chrome/content/shell.html</code>, que es compilado en un archivo <code>omni.ja.</code> El <code>shell.html</code> incluye el archivo <code>b2g/chrome/content/shell.js</code> , que dispara la aplicación <code>system</code> de Gaia.</p>
<h3 id="rild">rild</h3>
<p>El proceso <code>rild</code> es la interfaz del proceso del módem. <code>rild</code> es el daemon que implementa <strong>La capa de Interfaz de la Radio</strong> [<strong>Radio Interface Layer</strong> (RIL)]. Es un componente de codigo cerrado implementado por el fabricante/vendedor de hardware para comunicarse con el hardware del módem. <code>rild</code> hace posible que el código cliente se comunique con un empalme de dominio-UNIX al que se enlaza. Se inicia con un código como este en el <code>init</code> script:</p>
<pre>service ril-daemon /system/bin/rild
socket rild stream 660 root radio</pre>
<h3 id="rilproxy">rilproxy</h3>
<p>En Firefox OS, el cliente <code>rild</code> client es el proceso <code>rilproxy</code>. Este actúa como un proxy de reenvio mudo (dumb proxy) entre <code>rild</code> y <code>b2g</code>. Este proxy es necesario como un detalle de implementación; es de hecho necesario. El<code> </code><a href="https://github.com/mozilla-b2g/rilproxy" title="https://github.com/mozilla-b2g/rilproxy">código de rilproxy se encuentra en GitHub</a>.</p>
<h3 id="mediaserver">mediaserver</h3>
<p>El <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">proceso<code> mediaserver</code></a> controla la reproducción de audio y video. Gecko se comunica con él a través de un mecanismo de Llamada de Procedimiento Remota de Android [Android Remote Procedure Call (RPC)]. Algunos de los contenidos multimedia que Gecko puede reproducir (OGG Vorbis audio, OGG Theora video, y <a href="http://www.webmproject.org/about/" title="http://www.webmproject.org/about/">WebM</a> video) son decodificados por Gecko y enviados directamente al proceso <code>mediaserver</code>. Otros archivos multimedia son decodificados por <code>libstagefright</code>, que puede acceder códecs del fabricante y codificadores del hardware.</p>
<div class="note">
<p><strong>Nota:</strong> El proceso <code>mediaserver</code> es un componente "provisional" de Firefox OS; existe sólo para ayudar en el trabajo de desarrollo inicial pero se espera que se descarte con el tiempo; lo que seguramente no ocurrirá antes de la version 2.0 de Firefox OS.</p>
</div>
<h3 id="netd">netd</h3>
<p>El proceso <code>netd</code> se usa para configurar interfaces de red.</p>
<h3 id="wpa_supplicant">wpa_supplicant</h3>
<p>El proceso <code>wpa_supplicant</code> process es el daemon estándar tipo UNIX que maneja la conectividad con los puntos de acceso WiFi.</p>
<h3 id="dbus-daemon">dbus-daemon</h3>
<p>El dbus-daemon implementa el <a href="http://www.freedesktop.org/wiki/Software/dbus" title="http://www.freedesktop.org/wiki/Software/dbus">D-Bus</a>, un sistema de mensajes de bus que Firefox OS emplea para las comunicaciones por Bluetooth.</p>
<h2 id="Gecko">Gecko</h2>
<p><a href="/en-US/docs/Gecko" title="/en-US/docs/Gecko">Gecko</a>, como se lo mencionó previamente, es la implementación de estándares web (<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>, y <a href="/en-US/docs/JavaScript" title="/en-US/docs/JavaScript">JavaScript</a>) que se usa para implementar todos lo que el usuario ve en Firefox OS, y controlar las interacciones con el hardware del telefono.</p>
<p>Las aplicaciones Web conectan HTML5 con el hardware de forma controlada a traves de API's web seguras, implementadas en Gecko. Las API's Web proveen de acceso programado a las caracteristicas implicitas en el hardware del dispositivo (como la bateria, o la vibracion), a medida que los datos son guardados, o estan disponibles, en el dispositivo. El contenido web invoca a las API's web accesibles con HTML5.</p>
<p>Una app consiste en una coleccion de codigos web HTML5 relacionados. Para construir aplicaciones web que funcionen en dispositivos Firefox OS, los desarrolladores simplemento ensamblan, empaquetan y distribuyen este contenido web. En tiempo de ejecucion, este contenido web es interpretado, compilado y renderizado en una navegador web. Para mas informacion sobre Apps, puedes consultar el <a href="https://developer.mozilla.org/en-US/Apps">App Center</a></p>
<div class="note">
<p><strong>Note</strong>: Para buscar en la base de código de Gecko, se puede usar <a href="http://dxr.mozilla.org">http://dxr.mozilla.org</a>. Es más elegante y ofrece buenas características de referemcias. pero con repositorios limitados. También podría usar el tradicional <a href="http://mxr.mozilla.org">http://mxr.mozilla.org</a>, que contiene más proyectos de Mozilla.</p>
</div>
<h3 id="Diagrama_de_arquitectura_de_Gecko">Diagrama de arquitectura de Gecko</h3>
<h3 id="sect1"><img alt="" src="https://mdn.mozillademos.org/files/5027/securityframework.png" style="height: 591px; width: 979px;"></h3>
<h3 id="sect2"> </h3>
<ul>
<li><strong>Framework de seguridad: </strong>formado por
<ul>
<li>Gestor de Permisos: Da acceso a las funcionalidades de la API Web</li>
<li>Lista de Control de Acceso: Matriz de roles y permisos requeridos para acceder a las funcionalidades de la API Web.</li>
<li>Validador de Credenciales: Autentificacion de apps y usuarios</li>
<li>Conjunto de Permisos: Conjunto de privilegios requeridos para acceder a las funcionalidades de la API Web</li>
</ul>
</li>
<li><strong>API Web: </strong>Conjunto de APIs estandar que exponen las funcionalidades del hardware al contenido web.<br>
Proveen aplicaciones web con seguridad, acceso programado a las caracteristicas implicitas del hardware del dispositivo movil, mientran el dato este almacenado -o accesible- al dispositivo.</li>
<li><strong>I/O: </strong>Interfaz al hardware y almacenamiento de datos.</li>
<li><strong>Actualizaciones de Software: </strong>Obtienen e instalan las actualizaciones del software del sistema y aplicaciones de terceros.</li>
<li><strong>Diseñador de contenidos y renderizado: </strong>Motor que analiza sintacticamente, interpreta y ejecuta el contenido web y. con la informacion de formato, muestra el contenido formateado al usuario</li>
<li><strong>Proceso b2g: </strong>(Gecko) corre con alto nivel de privilegios los procesos del sistema que tienen acceso a las caracteristicas del telefono movil.<br>
Las aplicaciones en ejecucion son procesos hijo de b2g.</li>
</ul>
<p> </p>
<h3 id="Archivos_de_Gecko_relacionados_con_Firefox_OS">Archivos de Gecko relacionados con Firefox OS</h3>
<h4 id="b2g_2">b2g/</h4>
<p>La carpeta b2g contiene es su mayoría funciones relacionadas con Firefox OS.</p>
<h5 id="b2gchromecontent">b2g/chrome/content</h5>
<p>Contiene archivos de Javascript ejecutados sobre la aplicación de sistema.</p>
<h5 id="b2gchromecontentshell.html">b2g/chrome/content/shell.html</h5>
<p>El punto de entrada a Gaia — el HTML para la aplicación de sistema. <code>shell.html</code> toma de <code>settings.js</code> and <code>shell.js</code>:</p>
<pre class="brush: html"> </pre>
<p><code>settings.js</code> contiene parámetros de configuración básicos (default) de sistema.</p>
<h5 id="b2gchromecontentshell.js">b2g/chrome/content/shell.js</h5>
<p><code>shell.js</code> es el primer script que se carga en la aplicación de sistema de Gaia.</p>
<p><code>shell.js</code> importa todos los módulos requeridos, registra los detectores de clave (key listeners), define <code>sendCustomEvent</code> y <code>sendChromeEvent</code> para que se cominiquen con Gaia, y provee ayudantes de instalación de aplicaciones web: indexedDB quota, RemoteDebugger, ayudante de teclado, y la herramienta para captura de pantalla.</p>
<p>Pero la función más importante de <code>shell.js</code> es lanzar la aplicación de <code>sistema</code> de Gaia, después entregarle todo el trabajo general de administración del sistema.</p>
<pre class="brush: js">let systemAppFrame =
document.createElementNS('http://www.w3.org/1999/xhtml', 'html:iframe');
...
container.appendChild(systemAppFrame);</pre>
<h5 id="b2gappb2g.js">b2g/app/b2g.js</h5>
<p>Este script contiene configuraciones predefinidas, como about:config en el navegador, y la misma que Gaia's pref.js. Estas configuraciones se pueden cambiar desde la aplicación de congifuraciones y se pueden sobreescribir con user.js en el script de construcción Gaia.</p>
<h4 id="domAPI">dom/{API}</h4>
<p>Nuevas implementaciones de la API (post-b2g) se localizarán en <code>dom/</code>. Las APIs anteiores se localizarán en <code>dom/base</code>, for example <code>Navigator.cpp</code>.</p>
<h5 id="domapps">dom/apps</h5>
<p><code>.jsm</code> se cargarán implementaciones de API — <code>.js</code> API tales como <code>webapp.js</code> install, <code>getSelf</code>, etc.</p>
<h5 id="domappsPermissionsTable.jsm">dom/apps/PermissionsTable.jsm</h5>
<p>Se definen todos los permisos en <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 es el lenguaje empleado para definir web APIs. La información sobre los atributos soportados se encuentra en <a href="https://developer.mozilla.org/en-US/docs/Mozilla/WebIDL_bindings">WebIDL_bindings</a>.</p>
<h4 id="halgonk">hal/gonk</h4>
<p>Este directorio contiene archivos sobre la capa de adaptación gonk..</p>
<h4 id="Archivos_generados">Archivos generados</h4>
<h5 id="modulelibprefsrcinitall.js">module/libpref/src/init/all.js</h5>
<p>Contiene todos los archivos de configuración.</p>
<h5 id="systemb2g_omni.ja_and_omni.js">/system/b2g/ omni.ja and omni.js</h5>
<p>Contiene el paquete de estilos para los recursos en el dispositivo.</p>
<h3 id="Proceso_de_eventos_de_ingreso">Proceso de eventos de ingreso</h3>
<p>La mayor parte de las acciones en Gecko se activan por acciones de usuario. Estas acciones son representadas por eventos de emtrada (tales como presionar botones, tocar la pantalla y similar). Estos eventos entran a Gecko a través de <a href="https://dxr.mozilla.org/mozilla-central/source/widget/gonk/nsAppShell.cpp" rel="custom">Gonk implementation</a> perteneciente a <code><a href="/es/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIAppShell" title="">nsIAppShell</a></code>, que es una interfaz de Gecko empleada para representar los puntos de entrada primaria de una aplicación de Gecko, es decir, el controlador del dispositivo de ingreso llama métodos en el objeto <code>nsAppShell</code> que representa el subsistema de Gecko para así enviar eventos a la interfaz de usuario.</p>
<p> </p>
<p>Por ejemplo:</p>
<p> </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->NotifyNativeEvent();
}</pre>
<p>Estos eventos provienen del sistema estándar Linux <code>input_event</code>. Firefox OS emplea <a href="https://dxr.mozilla.org/mozilla-central/source/widget/gonk/libui/InputReader.cpp" rel="custom">light abstraction layer</a> sobre eso; lo que provee algunas características útiles como filtrar los eventos. Se puede ver el código que crea eventos de ingreso en el método <code>EventHub::getEvents()</code> que se encuentra en <a href="https://dxr.mozilla.org/mozilla-central/source/widget/gonk/libui/EventHub.cpp" rel="custom">widget/gonk/libui/EventHub.cpp</a>.</p>
<p>Un vez que Gecko recivió los eventos, se envían a DOM por <code><a href="https://dxr.mozilla.org/mozilla-central/source/widget/gonk/nsAppShell.cpp" rel="custom">nsAppShell</a></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>Después de lo anterior, los eventos son consumidos por el propio Gecko o despachados a aplicaciones web como <a href="/en-US/docs/DOM_Client_Object_Cross-Reference/DOM_Events" title="/en-US/docs/DOM_Client_Object_Cross-Reference/DOM_Events">Eventos DOM</a> para ser procesados posteriormente.</p>
<h3 id="Graficos">Graficos</h3>
<p>En si nivel más inferior, Gecko emplea <a href="http://www.khronos.org/opengles/2_X/" title="http://www.khronos.org/opengles/2_X/">OpenGL ES 2.0</a> para establecer un contexto GL que envuelva los <em>buffers</em> del <em>hardware</em>. Esto es realizado en la implementación de Gonk en <code><a href="https://dxr.mozilla.org/mozilla-central/source/widget/gonk/nsWindow.cpp" rel="custom">nsWindow</a></code> por medio de un código similar a este:</p>
<pre class="brush:cpp;">gNativeWindow = new android::FramebufferNativeWindow();
sGLContext = GLContextProvider::CreateForWindow(this);</pre>
<p>La clase <code>FramebufferNativeWindow</code> es obtenida directamente desde Android; ver <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>. Este emplea la API de <strong>gralloc</strong> para acceder al controlador de gráficos con el fin de mapear los <em>buffers</em> del dispositivo <em>framebuffer</em> a la memoria del dispositivo.</p>
<p>Gecko emplea su sistema (de) <a href="/en-US/docs/Gecko/Layers" title="/en-US/docs/Gecko/Layers">Layers</a> para componer contenido dibujado en la pantalla. En resumen, ocurre lo siguiente:</p>
<ol>
<li>Gecko dibuja regiones distintas de las páginas en los <em>buffers</em> de memoria, A veces, estos <em>buffers</em> están en la memoria del sistema; otras veces, son texturas mapeadas en el espacio de direcciones de Gecko, lo que siginifica que Gecko está dibujando directamente en la memoria de video. Esto se realiza generalmente en el método <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>Entonces, Gecko, compone todas estas texturas en la pantalla empleando comandos OpenGL. Esta composición tiene lugar en <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>Los detalles de cómo Gecko maneja el muestreo (<em>rendenring</em>) de contenido web se encuentra fuera del alcance de este documento.</p>
<h3 id="Capa_de_Abstracción_de_Hardware_(HAL)">Capa de Abstracción de Hardware (HAL)</h3>
<p><br>
La capa de abstracción de hardware de Gecko es una de sus capas de adaptación (porting). Gestiona los accesos de bajo nivel a las interfaces del sistema a lo largo de múltiples plataformas usando una API de C++ accesible desde los niveles superiores de Gecko. Estas APIs son implementadas plataforma a plataforma dentro de la HAL de Gecko. Esta capa de abstracción de hardware no es expuesta directamente a código JavaScript dentro de Gecko.</p>
<h4 id="Cómo_funciona_HAL">Cómo funciona HAL</h4>
<p>Vamos a considerar la API <a href="/es/docs/Web/API/Window/navigator/vibrate" title="La documentación acerca de este tema no ha sido escrita todavía . ¡Por favor considera contribuir !"><code>Vibration</code></a> como ejemplo. la HAL para esta API se define en <a href="https://dxr.mozilla.org/mozilla-central/source/hal/Hal.h" rel="custom">hal/Hal.h</a>. Resumiendo (simplificando el método de firma para hacerlo más claro), tienes esta función:</p>
<pre>void Vibrate(const nsTArray &pattern);</pre>
<p>Esta es la función que el código de Gecko llama par activar la vibración del dispositivo de acuerdo con un patrón específico; una función correspondiente existe para cancelar la vibración activa. La implementación de GONK para este método está en <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;">void Vibrate(const nsTArray &pattern) {
EnsureVibratorThreadInitialized();
sVibratorRunnable->Vibrate(pattern);
}
</pre>
<p>Este código envía la petición para el inicio de la vibración a otro conjunto de procesos, que se implementa en <code>VibratorRunnable::Run()</code>. El bucle principal de este hilo seria parecido a esto:</p>
<pre class="brush:cpp;">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();
}
}
</pre>
<p><code>vibrator_on()</code> es la API HAL de GONK que enciende el motor de vibración. Internamente, este método envía un mensaje al controlador de núcleo (kernel driver) al escribir un valor en un objeto de kernel empleando <code>sysfs</code>.</p>
<h4 id="Implementaciones_de_la_Fallback_HAL_API">Implementaciones de la <em>Fallback HAL API</em></h4>
<p><br>
Las APIs HAL de Gecko tienen soporte en todas las plataformas. Cuando se construye Gecko para una plataforma que no expone una interfaz a los motores de vibración (como una computadora de escritorio) entonces se vale de una implemenación de <em>fallback</em> de la API de HAL. Para la vibración, este esta implementado en <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;">void Vibrate(const nsTArray &pattern) {
}</pre>
<h4 id="Implementaciones_de_Sandbox_(entorno_cerrado)">Implementaciones de <em>Sandbox</em> (entorno cerrado)</h4>
<p>Debido a que la mayoría del contenido de la red se ejecuta en procesos de contenido con privilegios bajos, no podemos suponer que esos procesos tienen los privilegios necesarios para poder (por ejemplo) activar o desactivar el motor de vibración. Además, queremos tener una ubicación central para controlar las posibles condiciones de carrera (<em>race conditions</em>). En la HAL de Gecko, esto es realizado por medio de la implementación de una sandbox de la HAL. Esta sandbox simplemente funciona como un proxy para la peticiones realizadas por los procesos de contenido y las reenvía al proceso del "servidor Gecko". Las peticiones de proxy se envían empleando IPDL.</p>
<p>Para la vibración, la función<code> Vibrate()</code> se encarga de la gestión y se la implementa en <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;">void Vibrate(const nsTArray& pattern, const WindowIdentifier &id) {
AutoInfallibleTArray p(pattern);
WindowIdentifier newID(id);
newID.AppendProcessID();
Hal()->SendVibrate(p, newID.AsArray(), GetTabChildFrom(newID.GetWindow()));
}</pre>
<p>Esto envía un mensaje definido por la interfaz PHal, descrita por IPDL en <a href="https://dxr.mozilla.org/mozilla-central/source/hal/sandbox/PHal.ipdl" rel="custom">hal/sandbox/PHal.ipdl</a>. El método se describe aproximadamente de la siguiente manera:</p>
<pre>Vibrate(uint32_t[] pattern);</pre>
<p>El receptor de este mensaje es la <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>, el cual seria algo parecido a esto:</p>
<pre class="brush:cpp;">virtual bool RecvVibrate(const InfallibleTArray& pattern,
const InfallibleTArray &id,
PBrowserParent *browserParent) MOZ_OVERRIDE {
hal::Vibrate(pattern, newID);
return true;
}</pre>
<p>Este omite algunos detalles que no son relevantes a este punto pero, en cualquier caso, demuestra cómo el mensaje progresa desde un proceso de contenido a través de Gecko hasta Gonk, luego a la implementación de la HAL de Gonk <code>Vibrate()</code>, y finalmente al controlador de vibración.</p>
<h3 id="APIs_DOM">APIs DOM</h3>
<p><strong>Las interfaces DOM</strong> son, esencialmente, la forma en la que el contenido web se comunica con Gecko. Hay más información al respecto y, si estás interesado en detalles extras, puedes leer <a href="/en-US/docs/DOM/About_the_Document_Object_Model" title="/en-US/docs/DOM/About_the_Document_Object_Model">sobre el DOM</a>. Las interfaces DOM se definen empleando <a href="/en-US/docs/XPIDL" title="/en-US/docs/XPIDL">IDL</a>, que compone una interfaz de función foránea (foreign function interface, FFI) y un objeto modelo (OM) entre JavaScript y C++.</p>
<p>La API de vibración se expone al contenido web por medio de una interfaz IDL, que se la provee en <code><a href="https://dxr.mozilla.org/mozilla-central/source/dom/interfaces/base/nsIDOMNavigator.idl" rel="custom">nsIDOMNavigator.idl</a>:</code></p>
<pre>[implicit_jscontext] void mozVibrate(in jsval aPattern);</pre>
<p>El argumento <a href="/en-US/docs/SpiderMonkey/JSAPI_Reference/Jsval" title="/en-US/docs/SpiderMonkey/JSAPI_Reference/JSVAL_IS_OBJECT"><code>jsval</code></a> indica que <code>mozVibrate()</code> (que es nuestra implementación vendedor-prefijada de esta especificación no finalazida de vibración) acepta como ingreso cualquier valor de JavaScript. El compilador IDL, <a href="/en-US/docs/XPIDL/xpidl" title="/en-US/docs/XPIDL/xpidl"><code>xpidl</code></a>, genera una interfaz C++ que entonces se implementa por la clase <code>Navigator</code> en <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;">NS_IMETHODIMP Navigator::MozVibrate(const jsval& aPattern, JSContext* cx) {
// ...
hal::Vibrate(pattern);
return NS_OK;
}</pre>
<p>Hay mucho más código en este método de lo que ves aquí, pero no es importante para el proposito que estamos tratando. El hecho es que la llamada a <code>hal::Vibrate()</code> transfiere el control de DOM a la HAL Gecko. Desde allí, entramos a la implementación de HAL tratada en la sección previa y continuamos hacia el controlador. Además, la implementación DOM no se preocupa por la plataforma en la que está corriendo (Gonk, Windows, OS X, o cualquier otra). Tampoco le interesa si el código está corriendo en un proceso de contenido o en un proceso del servidor Gecko. Esos detalles se dejan de lado para que los gestionen los procesos de nivel bajo del sistema.</p>
<p>La API de vibración es muy simple, lo que la convierte un ejemplo excelente. La<a href="/en-US/docs/API/WebSMS" title="/en-US/docs/API/WebSMS"> API de SMS</a> es más compleja porque emplea su propia capa de envío remoto que conecta los procesos de contenido con el servidor.</p>
<h2 id="Capa_de_Interfaz_de_Radio_(CIRRIL)">Capa de Interfaz de Radio (CIR/RIL)</h2>
<p>La RIL (Radio Interface Lyer) ya se mencionó en la sección <a href="#The_userspace_process_architecture">The userspace process architecture</a>. Esta sección examinará con más detalle cómo las diferentes partes de esta capa interactúan.</p>
<p>Los componentes principales involucrados en la RIL son los siguientes:</p>
<dl>
<dt><code>rild</code></dt>
<dd>El daemon que habla al firmware del módem de fábrica.</dd>
<dt><code>rilproxy</code></dt>
<dd>El daemon que referencia mensajes (proxy) entre <code>rild</code> y Gecko (que está implementado en el proceso <code>b2g</code>). Esto soluciona el problema de permisos que surje cuando se trata de comunicar con<code> rild</code> directamente ya que sólo se puede comunicar con <code>rild desde el grupo </code><code>radio</code>.</dd>
<dt><code>b2g</code></dt>
<dd>Este proceso, también conocido como el <em><strong>proceso chrome</strong></em>, implementa Gecko. Las partes de el que se relacionan con la Capa de Interfaz de Radio son <a href="https://dxr.mozilla.org/mozilla-central/source/dom/system/gonk/ril_worker.js" rel="custom">dom/system/gonk/ril_worker.js</a>, las cuales implementan una cadena de procesos de trabajo (<em>worker thread</em>) que se comunica con <code>rild</code> a través de <code>rilproxy</code> es implementa el estadio radial (<em>radio state machine</em>) y la interfaz <code><a href="/es/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIRadioInterfaceLayer" title="">nsIRadioInterfaceLayer</a></code>, que es el servicio <a href="/en-US/docs/XPCOM" title="/en-US/docs/XPCOM">XPCOM</a> de la cadena de procesos principal, que actúa principalmente como un intercambio de mensajes entre la cadena <code>ril_worker.js</code> y otros numerosos componentes de Gecko, incluidos el proceso de contenido de Gecko.</dd>
<dt>Proceso de contenido de Gecko (<em>Gecko's content process</em>)</dt>
<dd>Dentro del proceso de contenido de Gecko, la interfaz <code><a href="/es/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIRILContentHelper" title="">nsIRILContentHelper</a></code> provee un servicio XPCOM que permite a algunas partes de código implementado de DOM, tales como las APIs<a href="/en-US/docs/API/WebTelephony" title="/en-US/docs/API/WebTelephony"> Telephony</a> y <a href="/en-US/docs/API/WebSMS" title="/en-US/docs/API/WebSMS">SMS</a>, comunicarse con la interfaz de radio, la cual es un proceso chrome.</dd>
</dl>
<h3 id="Ejemplo_comunicación_desde_rild_a_DOM">Ejemplo: comunicación desde rild a DOM</h3>
<p>Echemos una mirada al ejemplo de cómo las partes del nivel inferior del sistema se comunican con código DOM. Cuando el módem recibe una llamada entrante, la notifica a <code>rild</code> empleando un mecanismo de fábrica. entonces<code> rild</code> prepara un mensaje para su cliente de acuerdo con el protocolo "open", que se describe en <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>. En el caso de una llamada entrante, se genera un mensaje <code>RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED</code> y lo envía <code>rild</code> a <code>rilproxy</code>.</p>
<p><code>rilproxy</code>, implementada en <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>, recibe este mensaje en bucle principal, que envía (<em>poll</em>) la conexión a<code> rild</code> utilizando código como éste:</p>
<pre class="brush:cpp;">ret = read(rilproxy_rw, data, 1024);
if(ret > 0) {
writeToSocket(rild_rw, data, ret);
}</pre>
<p>Una vez que el mensaje es recibido por <code>rild</code>, se lo reenvía a Gecko en el empalme que conecta <code>rilproxy</code> con Gecko. Gecko recibe el mensaje enviado en su <a href="https://dxr.mozilla.org/mozilla-central/source/ipc/ril/Ril.cpp" rel="custom">IPC thread</a>:</p>
<pre class="brush:cpp;">int ret = read(fd, mIncoming->Data, 1024);
// ... handle errors ...
mIncoming->mSize = ret;
sConsumer->MessageReceived(mIncoming.forget());
</pre>
<p>El consumidor de estos mensajes es <a href="https://dxr.mozilla.org/mozilla-central/source/dom/system/gonk/SystemWorkerManager.cpp" rel="custom">SystemWorkerManager</a>, que reempaqueta los mensajer y los envía a la cadena <code><a href="https://dxr.mozilla.org/mozilla-central/source/dom/system/gonk/ril_worker.js" rel="custom">ril_worker.js</a></code> que implementa la máquina de estado RIL; que se realia en the <code>RILReceiver::MessageReceived()</code> method:</p>
<pre class="brush:cpp;">virtual void MessageReceived(RilRawData *aMessage) {
nsRefPtr dre(new DispatchRILEvent(aMessage));
mDispatcher->PostTask(dre);
}</pre>
<p>La tarea postada en esa cadena a su vez llama la función <code>onRILMessage()</code>, que se implemente en JavaScript. Esto se realiza empleando la función <code><a href="/en-US/docs/SpiderMonkey/JSAPI_Reference/JS_CallFunctionName" title="/en-US/docs/SpiderMonkey/JSAPI_Reference/JS_CallFunctionName">JS_CallFunctionName</a>()</code> de la API de JavaScript:</p>
<pre>return JS_CallFunctionName(aCx, obj, "onRILMessage", NS_ARRAY_LENGTH(argv),
argv, argv);</pre>
<p><code>onRILMessage()</code> está implementada en <a href="https://dxr.mozilla.org/mozilla-central/source/dom/system/gonk/ril_worker.js" rel="custom">dom/system/gonk/ril_worker.js</a>, que procesa los bytes del mensaje y los corta en fragmentos. Cada fragmento completo se envía a métodos de gestión (<em>handler</em>) individuales apropiadamente:</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>Este código trabaja por medio del tipo de petición (<em>request</em>) del objeto, asegurándose de que sea definido como una función en código de JavaScript, para después llamar al método. Ya que ril_worker.js implementa cada tipo de petición (<em>request type</em>) en un método con el mismo nombre que el tipo de petición, es muy sencillo.</p>
<p>En nuestro ejemplo <code>RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED</code>, se llama al siguiente <em>handler</em>:</p>
<pre class="brush:js;">RIL[UNSOLICITED_RESPONSE_CALL_STATE_CHANGED] = function UNSOLICITED_RESPONSE_CALL_STATE_CHANGED() {
this.getCurrentCalls();
};</pre>
<p>Como puedes ver en el código de más arriba, cuando se recibe la notificación que el estado de la llamada ha cambiado, la máquina de estado (<em>state machine</em>) simplemente trae para sí el estado actual de la llamafa invocando el método <code>getCurrentCall()</code>:</p>
<pre class="brush:js;">getCurrentCalls: function getCurrentCalls() {
Buf.simpleRequest(REQUEST_GET_CURRENT_CALLS);
}</pre>
<p>Esto envía una petición de vuelta a <code>rild</code> para solicitar el estado de todas las llamadas actuales. La petición regresa por un camino similar al que siguió el mensaje <code>RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED</code> message pero en la dirección opuesta (es decir, desde <code>ril_worker.js</code> a <code>SystemWorkerManager</code> a <code>Ril.cpp</code>, después a <code>rilproxy</code> y finalmente al <code>rild</code> socket). <code>rild</code> responde por el camino inverso y la respuesta llega al handler de <code>ril_worker.js</code>'s handler para el mensaje <code>REQUEST_GET_CURRENT_CALLS</code>. Así es como se da lugar la comunicación bidireccional.</p>
<p>El estado de la llamda se procesay compara con el estado previo; si hay un cambio de estado, ril_worker.js notifica al servicio <code><a href="/es/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIRadioInterfaceLayer" title="">nsIRadioInterfaceLayer</a></code> de la cadena principal:</p>
<pre class="brush:js;">_handleChangedCallState: function _handleChangedCallState(changedCall) {
let message = {type: "callStateChange",
call: changedCall};
this.sendDOMMessage(message);
}</pre>
<p>Se implementa <code><a href="/es/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIRadioInterfaceLayer" title="">nsIRadioInterfaceLayer</a></code> en <a href="https://dxr.mozilla.org/mozilla-central/source/dom/system/gonk/RadioInterfaceLayer.js" rel="custom">dom/system/gonk/RadioInterfaceLayer.js</a>; se recibe el mensaje por su método<code> onmessage()</code>:</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>Lo que todo esto realmente hace es enviar el mensaje al proceso de contenidos empleando el Administrador de Mensajes de Procesos Principales [<em>Parent Process Message Manager</em> (PPMM)]:</p>
<pre class="brush:js;">handleCallStateChange: function handleCallStateChange(call) {
[some internal state updating]
ppmm.sendAsyncMessage("RIL:CallStateChanged", call);
}</pre>
<p>En el proceso de contenidos, el mensaje es recibido por el método <code>receiveMessage()</code> en el servicio <code><a href="/es/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIRILContentHelper" title="">nsIRILContentHelper</a></code>, del Administrador de Mensajes de Procesos Secundarios [<em>Child Process Message Manager</em> (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>Esto, a su vez, llama a los métodos <code><a href="https://developer.mozilla.org/es/docs/XPCOM_Interface_Reference/nsIRILTelephonyCallback#callStateChanged()">nsIRILTelephonyCallback.callStateChanged()</a></code> de cada uno de los objetos registrados de las respuesta de telefonía (<em>registered telephony callback object</em>). Cada aplicación web que accede la API <a href="/es/docs/Web/API/Window/navigator/mozTelephony" title="La documentación acerca de este tema no ha sido escrita todavía . ¡Por favor considera contribuir !"><code>window.navigator.mozTelephony</code></a> API ha registrado uno de ese tipo de objeto que envía los eventos al código JavaScript code en la aplicación web, así sea como un cambio de estado de un objeto de llamada existente o un nuevo evento de llamada <code>incoming</code>.</p>
<pre class="brush:cpp;">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 call =
TelephonyCall::Create(this, aNumber, aCallState, aCallIndex);
nsRefPtr event = CallEvent::Create(call);
nsresult rv = event->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("incoming"));
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}</pre>
<p>Las aplicaciones pueden recibir estos eventos y actualizar su interfaz de usuario:</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>Echa una mirada a la implementación de <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> como un ejemplo más.</p>
<h3 id="Datos_3G">Datos 3G</h3>
<p>Hay un mensaje RIL que inicia una "petición de datos" al servicio móvil; este activa el modo de transferencia de datos en el modem. Esta petición de datos termina creando y activando una interfaz <a href="https://es.wikipedia.org/wiki/Point-to-Point Protocol" title="Point-to-Point Protocol">Point-to-Point Protocol</a> (PPP) en el kernel Linux que pueden ser configuradas usando las interfaces comunes.</p>
<div class="note">
<p><strong>Nota:</strong> Esta sección necesita ser redactada</p>
</div>
<h3 id="APIs_relacionadas_con_DOM">APIs relacionadas con DOM</h3>
<p>Esta sección lista las APIs de DOM que estan relacionadas con comunicaciones RIL.</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>El backend de WiFi para Firefox OS simplemente usa wpa_supplicant para hacer la mayor parte del trabajo.<br>
Esto significa que el principal trabajo del backend es simplemente gestionar el <em>supplicant</em>, y hacer algunas tareas auxiliares como cargar el driver del WiFI y activar o desactivar la interfaz de red.<br>
En resumen, esto significa que el backend es una maquina de estados, con los estados que indican el estado del <em>supplicant.</em></p>
<div class="note">
<p><strong>Note:</strong> Muchas cosas interesantes que suceden en WiFi dependen profundamente de posibles cambios de estado en el proceso <code>wpa_supplicant</code>.</p>
</div>
<p>La implementación del componente WiFi esta dividida en dos archivos.</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>Implementa lo que la API muestra al contenido web, tal como esta definido en <code><a href="/es/docs/Mozilla/Tech/XPCOM/Reference/Interface/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>Implementa la máquina de estados y el código que controla el <em>supplicant.</em></dd>
</dl>
<p>Estos dos archivos se comunican con otro usando el <a href="https://developer.mozilla.org/en-US/docs/The_message_manager">gestor de mensajes.</a><br>
El backend escucha los mensajes que requieran una determinada acción, como "asociar" y responde con una mensaje cuando la acción requerida ha sido completada.</p>
<p>El lado del DOM escucha los métodos de respuesta, asi como muchos mensajes de eventos que indican cambios de estado y actualización de información.</p>
<div class="note">
<p><strong>Note:</strong> Algunas API's síncronas de DOM son implementadas leyendo datos en el otro extremo de la tubería. Los mensajes síncronos son evitados siempre que es posible</p>
</div>
<h3 id="WifiWorker.js">WifiWorker.js</h3>
<p>Este archivo implementa la logica principal detras de la interfaz WiFi. Se ejecuta en el proceso chrome (en construcciones multiproceso) y es instanciado por el SystemWorkerManager. El fichero es generalmente dividido en dos secciones: una gigantesca funcion anonima y WifiWorker (y su prototipo). La funcion anonima termina siendo el WifiManager proveyendo una API local, incluyendo notificaciones para eventos como una conexion al supplicant y escaneando los resultados cuando estan disponibles. En general. este contiene la logica simple y manda a su control exclusivo de consumidor sus acciones mientras estas simplemente responden a la informacion requerida y controla los detalles de la conexion con el supplicant.</p>
<p>El objeto WifiWorker se situa entre el WifiManager y el DOM. Este reacciona a eventos y los sigue al DOM; a su vez, este recibe las peticiones del DOM y realiza las acciones apropiadas en el supplicant. Este tambien mantiene informacion sobre el supplicant y lo siguiente que necesita hacer.</p>
<h3 id="DOMWifiManager.js">DOMWifiManager.js</h3>
<p>Este implementa la API de DOM, transmitiendo mensajes hacia atras y llamadas de regreso y el actual WiFi worker. Hay muy poca logica envuelta aqui.</p>
<div class="note">
<p><strong>Nota:</strong> Para poder permitir mensajes sincronos al proceso chrome, el WiFi Manager necesita cachear el estado basado en el envio recibido.</p>
</div>
<p>Hay un solo mensaje sincrono, el cual es enviado en cuanto la API DOM se instancia, para poder obtener el estado actual del supplicant.</p>
<h3 id="DHCP">DHCP</h3>
<p>DHCP y DND van de la mano con dhcpcd, el cliente DHCP estandar en Linux.<br>
Sin embargo, este no permite reaccionar cuando la conexion de red se pierde.<br>
Por eso, Firefox OS mata y reinicia dhcpcd cada vez que se conecta a una red inalambrica dada.</p>
<p><code>dhcpcd</code> es tambien responsable de ajustar la ruta por defecto; nosotros llamamos al gestor de redes para informar al kernel sobre los servidores DNS.</p>
<h2 id="Gestor_de_Redes">Gestor de Redes</h2>
<p>El Gestor de Redes configura las interfaces de red abiertas por los datos 3G y los componentes WiFi</p>
<div class="note">
<p><strong>Nota:</strong> Esto necesita ser redactado.</p>
</div>
<h2 id="Procesos_e_hilos">Procesos e hilos</h2>
<p>Firefox OS usa los hilos de POSIX para implementar todos los hilos de las aplicaciones - esto incluye los hilos principales de cada aplicación asi como los trabajadores web y los hilos de ayuda. Los grupos de control son usados para priorizar procesos e hilos de ejecución que dependen del planificador completamente justo del kernel Linux. Dependiendo del estado del proceso le asignaremos un grupo de control distinto. Actualmente tenemos 6 niveles de prioridad correspondientes a 5 grupos de control</p>
<table class="standard-table">
<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>proceso principal de b2g</td>
</tr>
<tr>
<td><code>FOREGROUND_HIGH</code></td>
<td>0</td>
<td>aplicaciones criticas que sostienen la cpu y el wakelock de alta prioridad.<br>
Este es actualmente reservado para el reloj y las aplicaciones de comunicacion</td>
</tr>
<tr>
</tr>
<tr>
<td><code>FOREGROUND</code></td>
<td>1</td>
<td>aplicaciones en primer plano</td>
</tr>
<tr>
<td><code>FOREGROUND_KEYBOARD</code></td>
<td>1</td>
<td>aplicacion de teclado</td>
</tr>
<tr>
<td><code>BACKGROUND_PERCEIVABLE</code></td>
<td>7</td>
<td>aplicaciones en segundo plano que ejecuten audio o sostengan la CPU o el wakelock de alta prioridad y tengan al menos un controlador de mensajes de sistema registrado</td>
</tr>
<tr>
<td><code>BACKGROUND_HOMESCREEN</code></td>
<td>18</td>
<td>aplicacion de pantalla principal</td>
</tr>
<tr>
<td><code>BACKGROUND</code></td>
<td>18</td>
<td>resto de aplicaciones que se ejecuten en segundo plano</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
</tr>
</tbody>
</table>
<p>Algunos niveles comparten el mismo grupo de control, esto es asi porque dichos niveles actualmente difieren en la manera que son tratados por el liberador de memoria. Todas las prioridades pueden ser ajustadas en tiempo de ejecucion mediante preferencias; las entradas relativas a esto se pueden encontrar en el <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>Actualmente se usan los siguientes grupos de control:</p>
<table class="standard-table">
<caption>Grupos de Control</caption>
<tbody>
<tr>
<td><strong>Ruta</strong></td>
<td><strong>Ocupación de la CPU</strong></td>
<td><strong>Descripción</strong></td>
</tr>
<tr>
<td> </td>
<td>50% del tiempo total de CPU</td>
<td>Grupo de control de Root reservado para el proceso principal de b2g y los servicios del sistema</td>
</tr>
<tr>
<td>apps</td>
<td>50% del tiempo total de CPU</td>
<td>Aplicaciones comunes</td>
</tr>
<tr>
<td>apps/critical</td>
<td>95% de las apps</td>
<td>Aplicaciones criticas</td>
</tr>
<tr>
<td><code>apps/bg_perceivable</code></td>
<td>10% de las apps</td>
<td>Aplicaciones perceptibles en segundo plano</td>
</tr>
<tr>
<td><code>apps/bg_non_interactive</code></td>
<td>5% de las apps</td>
<td>Aplicaciones en segundo plano</td>
</tr>
</tbody>
</table>
<div class="note">
<p><strong>Nota: </strong>para mas informacion sobre el liberador de memoria, y como Firefox OS gestiona las situaciones de memoria baja, lease <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>Sin un proceso, el hilo principal hereda el "valor seguro" del proceso, mientras que los procesos web en curso toman un "valor seguro" que es un punto mas alto que el hilo principal, que corre la prioridad mas baja.<br>
Esto esta hecho para prevenir que los ciclos intensivos en curso de la CPU ralenticen excesivamente el hilo principal. Todos los hilos de una aplicación son actualmente asignados al mismo grupo de control. Las prioridades de los procesos son cambiadas cuando un evento importante sucede, como cuando una aplicación cambia de segundo plano al primer plano, o una nueva aplicación inicia, o una aplicación acapara la CPU.</p>
<div class="note">
<p><strong>Nota: </strong>los cgroups soportados en dispositivos ICS estan actualmente rotos debido a un bug del kernel.</p>
</div>
<p> </p>
|