Capítulo 8

Creación de un Componente XPCOM para

En este capítulo se expone la forma detallada de crear un componente XPCOM para el navegador para dispositivos móviles de llamado Minimo. El desarrollo del capítulo es el desarrollo natural y cronológico del trabajo de investigación para llegar al resultado deseado. Se han obviado multitud de aspectos que conducían a un resultado erróneo que podrían ser de alguna utilidad pero el gran número de ellas hace imposible su enumeración.

8.1 Creación detallada de un componente XPCOM para Minimo

8.1.1 Primera aproximación: Solución dinámica

Con los conocimientos adquiridos para poder desarrollar cualquier mejora o innovación en el mundo de Mozilla, la primera idea para crear el componente sería pensar en XPCOM y, como consecuencia de ello, el objetivo sería el de

61

Capítulo 8. Creación de un Componente XPCOM para Minimo obtener un archivo .dll. De esta forma aprovecharíamos todas las ventajas que nos ofrece la tecnología XPCOM.

Se comenzaría, por lo tanto, con la idea de crear una librería dinámica y de algún archivo más a lo máximo que se colocaría en algún sitio de nuestro árbol de directorios en el terminal móvil y que se registraría de alguna forma con el fin de que el navegador Minimo supiera de la existencia de este componente. Es importante recalcar la idea de que esta opción sería dinámica, es decir, no se tendría que tocar la estructura de Minimo y tan sólo se desarrollaría una librería que se enlazaría de forma dinámica.

Se empezaría a proceder de la misma forma que para crear un componente en Mozilla . A primera vista cuando se instala Minimo en el terminal aparece una carpeta en el directorio de Program Files con el nombre de Minimo . Tras su exploración se puede observar que tiene una estructura similar a la carpeta que se tenía y que ya conocemos de Mozilla Firefox pero un poco más reducida, algo lógico teniendo en cuenta que es un navegador reducido para terminales móviles.

La carpeta en la que se tiene mayor interés es, a priori, la de components ya que en ella es donde se colocan todos los componentes XPCOM del navegador según lo aprendido anteriormente. En efecto, se comprueba que hay algunos archivos .xpt y algo de código JavaScript que pueden corresponder a algún componente XPCOM.

Se arranca Minimo en el terminal y se comprueba que se generan los ficheros compreg.dat y xpti.dat con una estructura muy parecida a la de los ficheros equivalentes en su “hermano mayor” que, según vimos, eran los encargados de tener registrado el componente y de informar al navegador de su existencia. Hasta ahora parece ser todo más o menos correcto y similar a Mozilla Firefox.

Se procede ahora a crear el componente en Microsoft Visual Studio. Para ello lo primero que se debe hacer es cambiar la plataforma del proyecto creado que, si antes era Win32 por tratarse de una aplicación normal para Windows, ahora es alguna de como por ejemplo Windows Mobile 5.0 PC SDK . Es ahora cuando empiezan los problemas. Con mayor o menor fortuna y tras muchas pruebas de enlazado y demás se consigue generar una .dll con la que probar el componente.

A continuación se quiere probar el componente creado por lo que se va a la carpeta components del terminal y se copian los archivos .dll y .xpt creados tal y como aprendió en Mozilla Firefox. Se puede comprobar cuando arrancamos de nuevo Minimo que el archivo xpti.dat sí tiene constancia del componente

62

Proyecto Fin de Carrera pero el compreg.dat no se ve modificado por lo que ya se percibe que algo no va bien. Efectivamente, el componente al probarlo lanza un mensaje typeError: components.classes[cid] has no properties como era de esperar debido a que compreg.dat no ha cambiado.

Se intenta abordar por otra parte y, manualmente (algo que no se debe hacer) se modifica el archivo compreg.dat y se añade la línea que debería aparecer, tal y como lo hace cuando se probó en Mozilla Firefox. Es entonces cuando lanza el mensaje de typeError: obj has no properties lo que hace pensar que el componente está registrado pero mal construido y el navegador no es capaz de interactuar correctamente con él.

Ha de decirse que para la generación de la librería dinámica a través de Microsoft Visual Studio se hicieron multitud de pruebas variando muchas de las características de generación como pueden ser utilizar archivos obtenidos de la generación de Minimo como librerías de entrada en la compilación del proyecto. Otro grupo de pruebas fue encaminado a las opciones de compilación que se tienen sobre el proyecto aunque tampoco ninguna de ellas fue satisfactoria.

Se intenta abordar por otra vía y se comprueba que Minimo sí es capaz de reconocer un componente XPCOM pero escrito en JavaScript, no en ++. El procedimiento es el que ya se conoce: colocar la librería, que en este caso un .js, y el archivo de librería de tipos .xpt en el directorio components , borrar compreg.dat y xpti.dat , y arrancar Minimo. El error tiene que estar por tanto en la generación de la librería dll.

Se podría haber construido el componente en JavaScript pero como la construcción del componente es un paso previo para la integración de otro proyecto de mayor envergadura, es imprescindible que el componente sea escrito en C++. Si se hubiera optado por esta opción se debería haber hecho un enorme trabajo sobre código que es para este proyecto inaccesible por lo que esta opción es inviable.

Tras muchas pruebas y consultas con otros desarrolladores de todas partes del mundo, se abandona la idea de realizar el componente para Minimo escrito en C++ de forma dinámica a través de una dll. Es posible que exista alguna forma de generar el componente en este pero en los proyectos también existe la limitación del tiempo, algo tan fundamental que hace que muchos de ellos cambien de rumbo y acaben siendo algo muy diferente de lo que en principio era la idea, por lo que finalmente se optó por seguir por otro camino.

63

Capítulo 8. Creación de un Componente XPCOM para Minimo

8.1.2 Exploración profunda de la composición de Minimo: Solución estática

Una vez tomada la decisión es hora de cambiar la forma de plantear la estrategia a seguir, aunque no se abandonó radicalmente la idea de una solución dinámica. Tanto el cambio de decisión como la solución final fueron propiciadas por la ayuda desinteresada de Aaron Reed, un trabajador estadounidense de IBM que proporcionó información de vital importancia para el desarrollo de este proyecto, por lo que se le agradece el interés tomado en el tema.

Ahora el trabajo se encamina a realizar un estudio completo de los componentes XPCOM con los que ya cuenta Minimo y, aprovechando los conocimientos sobre ello pero en Mozilla Firefox, se trata de trasladarlos a este caso para llegar a crear el tan ansiado componente.

Es ahora cuando surge el concepto de que Minimo es “unsupported” que viene más o menos a decir que es un software que no se encuentra muy bien respaldado y que no se sostiene perfectamente lo que da una idea ya del terreno por el que se mueve la investigación, ya que el propósito es utilizar este browser y si no es algo sólido puede traer muchos problemas en su tratamiento.

La solución que se tendrá que adoptar será estática ya que se creará el componente antes de compilar Minimo y cuando se genere de nuevo completamente el navegador será cuando se vea que ya podemos utilizar el componente creado. Por lo tanto, cualquier cambio en el componente necesitaría una nueva compilación de Minimo. Ya se ve que esto no es lo óptimo ya que no se aprovechan del todo las capacidades que brinda la tecnología XPCOM pero por razones ya comentadas anteriormente de tiempo y demás se seguirá esta línea.

Se recordará ahora todo lo aprendido para generar Minimo. Nos situamos en toda la estructura de directorios que teníamos partiendo del directorio raíz mozilla . Según se aprendió de su hermano mayor Firefox la carpeta donde se sitúan los componentes se llama components . Nos vamos al directorio minimo y vemos que existe uno llamado components . Se exploran los subdirectorios y vemos que recuerdan a los archivos que se necesitaban para generar el componente y además existe un Makefile.in en todos ellos que serán las instrucciones a seguir para compilar el componente.

Pues bien, tras muchas pruebas, se llega a conseguir generar nuestro propio componente siguiendo los pasos que a continuación se detallan.

64

Proyecto Fin de Carrera

8.1.2.1 Paso 1: Creación del componente

Para crear el componente en primer lugar se creará un directorio en la carpeta components que se llamará testsuma . Se escoge este nombre ya que el componente prueba será el mismo que para Mozilla Firefox.

En primer lugar, se creará el fichero de interfaces .xpidl al que se le llamará test.idl y que colocaremos dentro del directorio testsuma .

#include "nsISupports.idl"

[scriptable, uuid(90758A97-A6F3-4ea4-8953-16BD2EE3A977)] interface IMyComponent : nsISupports

{

long Add(in long a, in long b);

};

Como vemos, no difiere en nada de lo que ya sabíamos. Es un típico fichero .idl en el que se nos muestra la interfaz de nuestro componente IMyComponent que hereda de nsISupports, con su uuid y que tendrá el método Add .

A continuación se siguen los pasos que ya aprendimos, salvo que ahora solo necesitamos el archivo de cabecera por lo que, en un intérprete de comandos ejecutamos la siguiente instrucción:

{geckosdkdir}\bin\xpidl.exe -m header -I{geckosdkdir}\idl {archivoidl} con lo que obtenemos el fichero de cabecera que nos servirá para crear nuestro .cpp del componente. Ahora utilizaremos menos parte del archivo que para el anterior ejemplo de XPCOM, con lo que crearemos un archivo test.cpp que se detalla a continuación debida su importancia:

#include "test.h"

#include "nsIGenericFactory.h"

/* Header file */ class MyComponent : public IMyComponent

65

Capítulo 8. Creación de un Componente XPCOM para Minimo

{ public:

NS_DECL_ISUPPORTS

NS_DECL_IMYCOMPONENT

MyComponent() {};

virtual ~MyComponent() {};

};

NS_IMPL_ISUPPORTS1(MyComponent, IMyComponent)

/* long Add (in long a, in long b); */

NS_IMETHODIMP

MyComponent::Add(PRInt32 a, PRInt32 b, PRInt32 *_retval)

{

*_retval = a + b;

return NS_OK;

}

//------

// XPCOM REGISTRATION BELOW

//------

#define MY_COMPONENT_CLASSNAME "A Simple XPCOM Sample"

#define MY_COMPONENT_CID { 0x597a60b0, 0x5272, 0x4284, { 0x90, 0xf6, 0xe9, 0x6c, 0x24, 0x2d, 0x74, 0x6 } }

#define MY_COMPONENT_CONTRACTID "@mozilla.org/myComponent/support;1"

66

Proyecto Fin de Carrera

NS_GENERIC_FACTORY_CONSTRUCTOR(MyComponent) static nsModuleComponentInfo components[] =

{

{

MY_COMPONENT_CLASSNAME,

MY_COMPONENT_CID,

MY_COMPONENT_CONTRACTID,

MyComponentConstructor,

nsnull,

nsnull

}

};

NS_IMPL_NSGETMODULE(MyComponentModule, components) donde vemos cómo hemos hecho una mezcla de los dos archivos que teníamos que tener antes (uno de código .cpp donde se implementaba el componente y otro .h de cabecera donde había información de registro del componente, de los métodos y el módulo de factoría explicados anteriormente).

Todo corresponde a los esqueletos típicos de componentes XPCOM, pero los dos ficheros que eran necesarios anteriormente se funden en uno.

Se tienen ahora, por lo tanto, en nuestro directorio testsuma dos archivos: uno correspondiente a la interfaz (.idl) y otro correspondiente al componente (.cpp).

Tal y como se observa en los demás directorios de componentes hace falta un makefile que se encargue de darle las directrices al compilador para compilar nuestro componente. Este fichero lo tendremos que llamar obligatoriamente Makefile.in y lo pondremos en nuestro directorio testsuma . Tendrá esta forma:

DEPTH = ../../.. topsrcdir = @top_srcdir@ srcdir = @srcdir@

67

Capítulo 8. Creación de un Componente XPCOM para Minimo

VPATH = @srcdir@

include $(DEPTH)/config/autoconf.mk

MODULE_NAME = testsuma

MODULE = testsuma

LIBRARY_NAME = testsuma

IS_COMPONENT = 1

EXPORT_LIBRARY = 1

MOZILLA_INTERNAL_API = 1

REQUIRES = \

\

string \

pref \

$(NULL)

CPPSRCS = test.cpp

XPIDLSRCS = test.idl

EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS)

ifdef WINCE

OS_LIBS += $(call EXPAND_LIBNAME, aygshell cellcore) endif include $(topsrcdir)/config/rules.mk

68

Proyecto Fin de Carrera

Es una copia de los que ya disponemos en el que le indicamos al compilador los nombres de nuestro módulo, librería, etc. Recalcamos las dos líneas donde le indicamos los ficheros correspondientes al código fuente y a la interfaz:

CPPSRCS = test.cpp

XPIDLSRCS = test.idl

Por lo demás es algo que se nos proporciona.

8.1.2.2 Paso 2: Incorporación de nuestro componente a la estructura de Minimo

Ya tenemos el código del componente listo para compilarse, ahora lo que tenemos que hacer es decirle a Minimo que compile este nuevo componente. Para ello se realizan tres cambios:

- Modificamos minimo/components/Makefile.in , el Makefile correspondiente a todos los componentes, y añadimos a la línea DIRS el nuevo directorio testsuma con lo que le estamos diciendo que hemos creado un nuevo directorio con un nuevo componente.

- Modificamos minimo/base/wince/minimo-link-comps y añadimos una línea con el nuevo directorio testsuma . Este es otro archivo que le indicará que existe un nuevo directorio para compilar.

- Modificamos minimo/base/wince/minimo-link-names y añadimos una línea con el nombre del nuevo componente MyComponentModule . Ahora es cuando le estamos indicando explícitamente el nombre de nuestro nuevo componente.

8.1.2.3 Paso 3: Volver a generar Minimo

Ya estamos preparados para incrustar de forma estática el componente XPCOM en la estructura de Minimo. Para ello volvemos a compilar Minimo situándonos en el directorio raíz mozilla y ejecutando en cualquier intérprete de comandos: make -f client.mk build_all

Es importante que la opción sea build_all ya que necesitamos que se genere de nuevo y bien toda la estructura entera de directorios.

Tras el tiempo ya conocido de generación del Minimo y si no ha habido ningún error podemos observar algunos detalles en nuestro directorio de resultados.

69

Capítulo 8. Creación de un Componente XPCOM para Minimo

Por ejemplo, en \obj-dir-minimo-8-opt\minimo\components\testsuma tenemos ya nuestra librería compilada. Ya se va viendo que el componente creado se encuentra presente en la estructura del navegador.

Continuamos y ahora desde el directorio mozilla/obj-dir-minimo-8- opt/minimo/base ejecutamos los siguientes comandos: make package make installer

Con el primero tendremos el paquete de Minimo y con el segundo crearemos el instalador listo para instalarse en cualquier terminal.

8.1.2.4 Paso 4: Testeo

Estamos ya en condiciones de probar nuestro componente y lo vamos a hacer sobre el emulador que hemos utilizado ya previamente.

En primer lugar tenemos que arrancar el emulador que nos proporciona Visual Studio y que estamos utilizando para nuestras pruebas. Emularemos Windows Mobile 5.0 Pocket PC como anteriormente explicamos.

A continuación instalaremos el Minimo con el ejecutable que hemos generado siguiendo los pasos que conocemos ya.

Una vez instalado, arrancamos el navegador de la forma habitual.

Ahora pasamos la página web que teníamos de prueba al terminal. Puesto que estamos usando el emulador, tan sólo tenemos que copiar el archivo en el dispositivo móvil que nos aparece en Windows (tal y como si fuera una memoria usb típica) y ActiveSync ya se encarga de convertir el archivo para poder manejarlo en el terminal. Preferentemente se copiará el archivo a un directorio “manejable” del dispositivo como puede ser My Documents para evitar imprevistos.

Abrimos la página pulsando el último botón de la barra de botones con puntos suspensivos como icono y pulsando File Open :

70

Proyecto Fin de Carrera

Figura 8.1: Ejecutando la prueba.

71

Capítulo 8. Creación de un Componente XPCOM para Minimo

Una vez abierta la página obtendremos el mismo resultado que antes.

Figura 8.2: Resultado de la prueba en Minimo.

72