Written on Jul 24, 2018
The Mozilla Gigabit Community Fund provides grant funding in select U.S. communities to support pilot tests of gigabit technologies such as virtual reality, 4K video, artificial intelligence, and their related curricula. In so doing, our goal is to increase participation in technology innovation in support of a healthy Internet where all people are empowered, safe, and independent online.
I have managed to get the pipeline for the code generator to work for one simple service scriptloader
. I now need to look into more services, and see how I can implement the complicated ones. The one I am currently looking at is io
. In services.jsm
there is
a following code
XPCOMUtils.defineLazyGetter(Services, "io", () => {
return Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService)
.QueryInterface(Ci.nsISpeculativeConnect);
});
So when we call Services.io
we will get the object that is returned by the above lambda function.
According to this MDN article,
Components.classes
is a read-only object whose properties implement thensIJSCID
interface. Each object represents one of the classes of XPCOM components that can be constructed or accessed as an XPCOM service.
Let’s recall QueryInterface
function. From reading this MDN article
The function
QueryInterface(...)
is a function provided by all components which can be used to get a specific interface of that component. This function takes one parameter, the interface that you want to get.
and from reading Creating Applications with Mozilla book,
QueryInterface
A method used to match an interface with a desired implementation. The implementation can be in C, C++, JavaScript, Python, and other languages for which appropriate bindings are created. You can have multiple implementations for an interface. Through
QueryInterface
, you can ask for and assign the desired interface to its implementation. Each XPCOM object needs to implementQueryInterface
in order to return an instance of that object’s class.
And also, tangentially related, I learned more about Components
object. According to the above book,
In XPConnect, XPCOM interfaces,
classIDs
, andprogIDs
are stored as global JavaScript objects and properties that can be manipulated directly through a top-level object calledComponents
. This object accesses any component that is declared “scriptable” in an XPCOM IDL interface. Through the Components object, you can access and use the services that these interfaces provide. The Component object’s top-level properties and methods include:QueryInterface
,interfaces
and more! You might have guessed it but here is what exactly interfaces
are:
interfaces
A read-only object array containing all the interfaces declared scriptable in the IDL file. The object name has the same name as the interface it represents.
I have been reading a lot about XPCOM and I am forgetting the difference between components, classes, services.
Some of the functionality that the browser provides needs to be used by both consumers in core browser written in C++ and by the front-end of the browser which is written in JavaScript. XPCOM provides us with a way to implement such functionality in one language and expose it to a different language. There are clearly defined interfaces, which are language agnostic and they are specified using IDL
, and they attempt to outline different functionality that a browser can provide. A component is a reusable piece of code that implements such an interface (one or more of such interfaces). Some of the components need to be instantiated every time they are used and they are called classes, and others exist as singleton instances and don’t need to be invoked every time they are used and they are called services.
So now we see that in the above code example, Services.io
needs to return a nsIIOService
service that also has an interface nsISpeculativeConnect
. Let’s check if we can find a class that implements both such things, to see if I understood correctly everything I just read.
Indeed, nsIOService implements both. Now, I need to think about how I will make sure that the correct class will be returned when the getter is called. I’m going to look at the implementation of QueryInterface
.
My mentor pointed me towards this code so I will be doing something like this
if (IS_WN_REFLECTOR(obj))
auto tearOff = XPCWrappedNative::Get(obj)->FindTearOff(*iid);
to get a tear off object which will allow us to access both interfaces.
I kept trying to include xpcprivate.h
but the compiler kept giving me an error
... Services.cpp:31:10: fatal error: 'XPCWrappedNative.cpp' file not found
Then I realized I need to modify xpcom/build/moz.build
so that it will include the appropriate files in the build.