Josh Matthews, Platform Engineer (Mozilla)
Help keep the web open.
Gain practical experience with 10M LOC.
Work on a wide variety of challenging technical problems.
Static analysis | Parallel programming |
Audio/video decoding | Sandboxing and multiprocess |
Network protocols | Garbage collection |
JIT compilation | Multi-language integration |
Distributed synchronization |
More generally, we get to work on:
Evolving web standards | Performance improvements |
Memory usage | Native platform integration |
Privacy improvements | Cross-platform constraints |
Internationalization | Minimizing attack surface |
Backwards compatibility |
There are two main ways to do this:
Find relevant teams based on required skills.
Follow links to instructions for how to join that team.
Find relevant tasks based on areas of interest.
Each task has an associated mentor to help you succeed.
Bugzilla: where tasks are tracked, patches attached, and reviews sought and given (here's an example).
Lots of communication happens on irc.mozilla.org. Newcomers and oldcomers are welcome in #introduction
.
#developers
- high traffic, general Gecko-related development#jsapi
- JavaScript engine development#gfx
- graphics/rendering discussion#content
- DOM implementation#fx-team
- Firefox frontend development#devtools
- Firefox web developer tools team#necko
- Networking stack development#mobile
- Firefox for Android development#b2g
- Firefox OS developmentreview?
flag to the attachment, targetted at your mentor (or someone mentioned a lot in hg log
).review+
(AKA r+), it's ready to be committed.review+
.#introduction
is a very helpful place for these questions.
There's a wiki page that has everything you need.
Bootstrap: | $ wget https://hg.mozilla.org/mozilla-central/raw-file/default/python/mozboot/bin/bootstrap.py && python bootstrap.py |
Clone: | $ hg clone https://hg.mozilla.org/mozilla-central |
Build: | $ ./mach build |
Run: | $ ./mach run |
Full builds take 15 minutes to 1-2 hours depending on hardware.
MXR is your friend, as is DXR (with a guide).
#introduction
We have a lot of tests, and a lot of testing frameworks.
./mach mochitest-plain
: web content tests./mach mochitest-chrome
: web content tests with elevated privileges./mach mochitest-browser
: browser UI tests with elevated privileges./mach mochitest-a11y
: accessibility tests./mach reftest
: rendering/layout comparison tests./mach crashtest
: tests that don't crash./mach xpcshell-test
: JS-only tests that run in a limited environment (no DOM)Ask your mentor to submit your patches to our build farm.
You can also (and should!) request limited commit access to do so yourself.
init
method to the JS mozContacts APImozContacts API defined by WebIDL (Contacts.webidl):
interface mozContact { attribute DOMString? sex; attribute DOMString? genderIdentity; attribute sequence<ContactAddress>? adr; void setMetadata(DOMString id, Date? updated); };
Need to introduce an init method for compatibility reasons:
interface mozContact { ... void setMetadata(DOMString id, Date? updated); void init(optional ContactProperties properties); };
Next we need an implementation:
function Contact() { } Contact.prototype = { setMetadata: function(aId, aUpdated) { ... } };
Add the new method:
Contact.prototype = { setMetadata: function(aId, aUpdated) { }, init: function(aProperties) { Components.utils.reportError("deprecated"); } };
Read the complete patch (it's quite short).
It also demonstrates automated tests for the new method.
Read through bug 951766 to see the full process.
Want to create a module that can improve network preloading.
Needs to see all requests and learn user habits.
It should not be accessible to arbitrary web content.
nsINetworkSeer interface defined by IDL (nsINetworkSeer.idl):
interface nsINetworkSeer : nsISupports { void reset(); void learn(in nsIURI targetURI); };
XPCOM uses interfaces to interact with "components."
eg. nsIChannel
provides common interface for:
nsHttpChannel
(http://)nsFtpChannel
(ftp://)nsFileChannel
(file://)Similarly, nsIGeolocationProvider
provides interface for
NetworkGeolocationProvider
, JS component that initiates an XMLHttpRequest to Google's serviceGonkGPSGeolocationProvider
, C++ component that uses hardware GPSImplemented by C++ (Seer.h/Seer.cpp):
#include "nsINetworkSeer.h" class Seer : public nsINetworkSeer { public: NS_DECL_ISUPPORTS NS_DECL_NSINETWORKSEER nsCOMPtr<nsIThread> mIOThread; };
Implemented by C++ (Seer.h/Seer.cpp):
#include "nsINetworkSeer.h" class Seer : public nsINetworkSeer { public: NS_DECL_ISUPPORTS NS_DECL_NSINETWORKSEER nsCOMPtr<nsIThread> mIOThread; };
Implemented by C++ (Seer.h/Seer.cpp):
#include "nsINetworkSeer.h" class Seer : public nsINetworkSeer { public: NS_DECL_ISUPPORTS NS_DECL_NSINETWORKSEER nsCOMPtr<nsIThread> mIOThread; };
Implemented by C++ (Seer.h/Seer.cpp):
#include "nsINetworkSeer.h" class Seer : public nsINetworkSeer { public: NS_DECL_ISUPPORTS NS_DECL_NSINETWORKSEER nsCOMPtr<nsIThread> mIOThread; };
Implemented by C++ (Seer.h/Seer.cpp):
#include "nsINetworkSeer.h" class Seer : public nsINetworkSeer { public: NS_DECL_ISUPPORTS NS_DECL_NSINETWORKSEER nsCOMPtr<nsIThread> mIOThread; };
Implemented by C++ (Seer.h/Seer.cpp):
NS_IMETHODIMP Seer::Learn(nsIURI* targetURI) { nsRefPtr<SeerLearnEvent> event = new SeerLearnEvent(targetURI); mIOThread->Dispatch(event, NS_DISPATCH_NORMAL); return NS_OK; }
Implemented by C++ (Seer.h/Seer.cpp):
NS_IMETHODIMP Seer::Learn(nsIURI* targetURI) { nsRefPtr<SeerLearnEvent> event = new SeerLearnEvent(targetURI); mIOThread->Dispatch(event, NS_DISPATCH_NORMAL); return NS_OK; }
Implemented by C++ (Seer.h/Seer.cpp):
NS_IMETHODIMP Seer::Learn(nsIURI* targetURI) { nsRefPtr<SeerLearnEvent> event = new SeerLearnEvent(targetURI); mIOThread->Dispatch(event, NS_DISPATCH_NORMAL); return NS_OK; }
Implemented by C++ (Seer.h/Seer.cpp):
NS_IMETHODIMP Seer::Learn(nsIURI* targetURI) { nsRefPtr<SeerLearnEvent> event = new SeerLearnEvent(targetURI); mIOThread->Dispatch(event, NS_DISPATCH_NORMAL); return NS_OK; }
Implemented by C++ (Seer.h/Seer.cpp):
NS_IMETHODIMP Seer::Learn(nsIURI* targetURI) { nsRefPtr<SeerLearnEvent> event = new SeerLearnEvent(targetURI); mIOThread->Dispatch(event, NS_DISPATCH_NORMAL); return NS_OK; }
From C++, we can use Seer. From JS, we use nsINetworkSeer.
try { var seer = Components.classes["@mozilla.org/network/seer;1"] .getService(Components.interfaces.nsINetworkSeer); seer.reset(); } catch (e) { }
From C++, we can use Seer. From JS, we use nsINetworkSeer.
try { var seer = Components.classes["@mozilla.org/network/seer;1"] .getService(Components.interfaces.nsINetworkSeer); seer.reset(); } catch (e) { }
From C++, we can use Seer. From JS, we use nsINetworkSeer.
try { var seer = Components.classes["@mozilla.org/network/seer;1"] .getService(Components.interfaces.nsINetworkSeer); seer.reset(); } catch (e) { }
Report an error instead:
NS_IMETHODIMP Seer::Learn(nsIURI* targetURI) {
if (DatabaseMissing()) {
return NS_ERROR_NOT_AVAILABLE;
}
...
}
What happens when an error is returned from C++?
... try { seer.learn(document.documentURIObject); } catch (e) { Components.utils.reportError("Whoops."); }
Skim the main patch (it's quite long).
It's a good, contained example of implementing a feature.
Read through remaining integration patches to see how the new module is used (they're quite short).
You now know much more than most people who see Mozilla's code for the first time.
Your turn.
Remember: when in doubt, ask someone! The Mozilla community awaits you.
Josh Matthews, Mozilla Engineer and Community Builder
Slides: http://joshmatthews.net/cusec14/