## December 13, 2013

### Planet Mozilla — Presence on Firefox OS

Note

The topic is still in flux, this blog post represents my own thoughts, not Mozilla's.

Since a couple of months, we've been thinking about presence in my team at Mozilla, trying to think about what it means and if we need to build something in this area for the future of the web.

The discussion was initiated with this simple question: if you are not currently running social application Foo on your phone, how hard would it be for your friends to know if you're available and to send you an instant notification to reach you ?

### A few definitions

Before going any further, we need to define a few words - because I realized through all the dicussions I had that everyone has its own definitions of words like presence.

The word presence as we use it is how XMPP defines it. To summarize, it's a flag that will let you know if someone is online or offline. This flag is updated by the user itself and made available to others by different ways.

By device we define any piece of hardware that may update the user presence. It's most of the time a phone, but by extension it can also be the desktop browser. Maybe one day we will extend this to the whole operating system on desktop, but right now it's easier to stay in our realm: the Firefox desktop browser and the Firefox OS.

We also make the distinction between app-level presence and device-level presence. The first one is basically the ability for an online app to keep track of who's currently connected to its service. The latter, device-level presence, is the ability to keep track of who's active on a device - even if that user is not active in an application - which can even be turned off.

Being active on a device depends on the kind of device. For the desktop browser, it could simply be the fact that the browser is running and the user has toggled an 'online' button. For the phone, there are things like the Idle API that could be used to determine the status. But it's still quite fuzzy what would be the best way to use this.

Last very important point: we're keeping the notion of contacts out of the picture here because we've realized it's a bit of a dream to think that we could embed people's contacts into our service and ask all of the social apps out there to drop their own social graphs in favor of ours. That's another fight. :)

Anyways, I've investigated a bit on what was done on iOS and Android and found out that they both more or less provide ways for apps to reach out their users even when they don't use the app. I am not a mobile expert at all so if I miss something there, let me know!

### Presence on iOS

In iOS >= 7.x, applications that want to provide a presence feature can keep a socket opened in the background even if the application is not running any more in the foreground.

The feature is called setKeepAliveTimeout and will give the app the ability to register a handler that will be called periodically to check on the socket connection.

The handler has a limited time to do it (max 10 seconds) but this is enough to handle presence for the user by interacting with a server

The Apple Push Notification Service is also often used by applications to keep a connection opened on a server to receive push notifications. That's comparable to the Simple Push service Mozilla has added in Firefox OS.

Therefore, building an application with device-level presence on an iOS device is doable but requires the publisher to maintain one or several connections per user opened all the time - which is draining the battery. Apple is mitigating the problem by enforcing that the service spends at most 10 seconds to call back its server, but it seems that they are still keeping some resources per application in the background.

### Presence on Android

Like iOS, Android provides features to run some services in the background, see http://developer.android.com/guide/components/services.html

However, the service can be killed when the memory becomes low, and if TCP/IP is used it can be hard to have a reliable service. That's also what currently happens in Firefox OS, you can't bet that your application will run forever in the background.

Google also provides a "Google Cloud Messaging" (GCM) service. That provides similar features to Simple Push, to push notifications to users.

There's also a new feature called GCM Cloud Connection Server - (CCS) that allows applications to communicate with the device via XMPP and with client side "Intent Services". The app and the devices interact with CCS, which relays the messages back and forth.

There's a full example on their documentation of a Python server interacting with the GCM service to interact with users.

What's interesting is that the device keeps a single connection to a Google service, that relays calls from application servers. So instead of keeping one connection in every application, the phone shares the same pipe.

It's still up to the app to leverage this service to keep track of connected devices to get device-level presence, but the idea of keeping a single service in the background that dispatches messages to apps and eventually wakes them up, is very appealing to optimize the life of the battery.

Plus, XMPP is a widely known protocol. Offering app developers this standard to interact with the devices is pretty neat.

### And Firefox OS ?

If you were to build a chat application today on Firefox OS, you would need to keep your own connection open on your own server. Once your application is sent in the background, you cannot really control what happens when the system decides to shut it down to free some resources.

In other words, you're blacking out and the application service will not really know what's your status on the device. It will soon be able to send a notification via SimplePush to wake up the app - but there's still this grey zone when the app is sent in the background.

The goal of the Presence project is to improve this and provide a better solution for app developers.

At first, we thought about running our own presence service, be it based on ejabberd or whatever XMPP server out there. Since we're hackers, we quickly dived into all the challenges of scaling such a service for Firefox OS users. Making a presence service scaling for millions of users is not a small task - but that's really interesting.

The problem though, is the incentive for an app publisher to use our own presence service. Why whould they do this ? They all already solved presence in their applications, why would they use our own thing ? They would rather want us to provide a better story for background applications - and keep their client-side interacting with their own servers.

But we felt that we could provide a better service for our user experience, something that is less battery draining, and that puts back the user in the center of the picture.

Through the discussions, Ben Bangert came up with a nice proposal that partially answered those questions: Mozilla can keep track of the users' device status (online/offline/available) if they agree, and every user can authorize the applications she uses to fetch these presence updates through the Mozilla service - via a doorhanger page.

This indirection is a bit similar to Android's GCC architecture.

Like GCC, we'd be able to tweak the battery usage if we're in control of the background service that keeps a connection opened to one of our servers. There are several ways to optimize the battery usage for such a service - and we're exploring them.

One extra benefit of having a Mozilla service keep track of the presence flag is that users will be able to stay in control: they can revoke an application's authorization to see their online presence at anytime.

There's also a lot of potential for tweaking how and who see this information. For example, I can decide that BeerChat, my favorite chat app to talk about beer, can see my presence only between 9pm and 11pm.

And of course, like Firefox Sync, the devices could point to a custom Presence service that's not running on a Mozilla server.

### What's next ?

The Presence project is just an experiment right now, but we're trying to reach a point where we can have a solid proposal for Firefox OS.

As usual for any Mozilla project, everything is built in the open, and we trying to have weekly meetings to talk about the project.

The wiki page of the project is here : https://wiki.mozilla.org/CloudServices/Presence

It's a big mess right now, but it should improve over time to something more readable.

We're also trying to have a prototype that's up-to-date at https://github.com/mozilla-services/presence and an end user application demo that uses it, a Chat Room at: https://github.com/mozilla-services/presence-chatroom

There's a screencast at http://vimeo.com/80780042 where you can see the whole flow of a user authorizing an application to see her presence and another user reaching out the first user through a notification.

The desktop prototype is based on the excellent Social API feature, and we're now building the Firefox OS prototype - to see how the whole thing looks from a mobile perspective.

There's a mailing list, if you want to get involved: https://mail.mozilla.org/listinfo/wg-presence

### Planet Mozilla — Community Building Team: Meetup Day One

Day One (Wednesday) of the Mozilla Community Building Team Meetup here in San Francisco started with a bit of an icebreaker game so all 40+ of us could learn a little bit about each other. The exercise consisted of throwing a purple plushie around the room and answering a question.

After the icebreaker we had some introductions by the track leads and organizers who described the format of the rest of the week. We then broke into workgroups (Education, Events, Recognition, Systems & Data and Pathways). The initial work that each workgroup did was to put together some ideas in their focus area for 2014.

Later we came back to the main area we would be working from this week and did some more exercises to produce ideas for increasing participation surrounding various areas of the Mozilla project. My evening wrapped up heading with a group of Mozillians and my cousin down to a local restaurant to unwind and have dinner.

### Planet Mozilla — On John Leaving Mozilla

John has posted his farewell over on his blog.

John’s been managing me now for 6.5 years. I’ve had other friends/mentors/managers before, but it was under John that I became a manager myself.

Everything I’ve learned about people-first, no-nonsense management has come from him. Everything I’ve learned about cross-group co-ordination and asking the right questions has come from him. Everything I’ve learned about Irish whiskey has come from him.

On the technical- and pure getting-shit-done-side, the Google Tech Talk he gave on “Release Engineering as a Force Multiplier” is probably the only resume he’ll ever need, even if he doesn’t actually need it.

Where does John’s departure leave Mozilla, and more specifically, our release engineering team, and even more specifically, me?

I don’t know, but I’m optimistic, mostly because of the imprint left by John on all of us.

### Planet Mozilla — LWR (job scheduling) part v: some thoughts on the jobs and graphs db

```[10:57] <catlee>    so one thing - I think it may be premature to look at db models before looking at APIs
```

I think I agree with that, especially since it looks like LWR may end up looking very different than my initial views of it.

However, as I noted in part 3's preface, I'm going to go ahead and get my thoughts down, with the caveat that this will probably change significantly. Hopefully this will be useful in the high-level sense, at least.

jobs and graphs db

At the bare minimum, this will need graphs and jobs. But right now I'm thinking we may want the following tables (or collections, depending what db solution we end up choosing):

graph sets

Graph sets would tie a set of graphs together. If we wanted to, say, launch b2g builds as a separate graph from the firefox mobile and firefox desktop graphs, we could still tie them together as a graph set. Alternately, we could create a big graph that represents everything. The benefit of keeping the separate graphs is it's easier to reference and retrigger jobs of a type: retrigger all the b2g jobs, retrigger all the Firefox desktop win32 PGO talos runs.

graph templates

I'm still in the brainstorm mode for the templates. Having templates for graphs and jobs would allow us to generate graphs from the web app, allowing for a faster UI without having to farm out a job to the graph generation pool to clone a repo and generate a graph. These would have templatized bits like branch name that we can fill out to create a graph for a specific branch. It would also be one way we could keep track of changes in customized graphs or jobs (by diffing the template against the actual job or graph).

graphs

This would be the actual dependency graphs we use for scheduling, built from the templates or submitted from external requests.

job templates

This would work similar to the graph templates: how jobs would look, if you filled in the branch name and such, that we can easily work with in the webapp to create jobs.

jobs

These would have the definitions of jobs for specific graphs, but not the actual job run information -- that would go in the "job runs" table.

job runs

I thought of "job runs" as separate from "jobs" because I was trying to resolve how we deal with retriggers and retries. Do we embed more and more information inside the job dictionary? What happens if we want to run a new job Y just like completed job X, but as its own entity? Do we know how to scrub the previous history and status of job X, while still keeping the definition the same? (This is what I meant by "volatile" information in jobs). The "job run" table solves this by keeping the "jobs" table all about definitions, and the "job runs" table has the actual runtime history and status. I'm not sure if I'm creating too many tables or just enough here, right now.

If you're wondering what you might run, you might care about the graph sets, and {graph,job} templates tables. If you're wondering what has run, you would look at the graphs and job runs tables. If you're wondering if a specific job or graph were customized, you would compare the graph or job against the appropriate template. And if you're looking at retriggering stuff, you would be cloning bits of the graphs and jobs tables.

(I think Catlee has the job runs in a separate db, as the job queue, to differentiate pending jobs from jobs that are blocked by dependencies. I think they're roughly equivalent in concept, and his model would allow for acting on those pending jobs faster.)

I think the main thing here is not the schema, but my concerns about retries and retriggers, keeping track of customization of jobs+graphs via the webapp, and reducing the turnaround time between creating a graph in LWR and showing it on the webapp. Not all of these things will be as important for all projects, but since we plan on supporting a superset of gecko's needs with LWR, we'll need to support gecko's workflow at some point.

dependency graph repo

This repo isn't a mandatory requirement; I see it as a piece that could speed up and [hopefully] streamline the workflow of LWR. It could allow us to:

• refer to a set of job+graph definitions by a single SHA. That would make it easier to tie graphs- and jobs- templates to the source.
• easily diff, say, mozilla-inbound jobs against mozilla-central. You can do that if the jobs and graphs definitions live in-tree for each, but it's easier to tell if one revision differs from another revision than if one directory tree in a revision differs from that directory tree in another revision. Even in the same repo: it's hard to tell if m-c revision 2's job and graphs have changed from m-c revision 1, without diffing. The job-and-graph repo would [generally] only have a new revision if something has changed.
• pre-populate sets of jobs and graph templates in the db that people can use without re-generating them.

There's no requirement that the jobs+graph definitions live in this repo, but having it would make the webapp graph+job creation a lot easier.

We could create a branch definitions file in-tree (though it could live elsewhere; its location would be defined in LWR's config). The branch definitions could have trychooser-like options to turn parts of the graphs on or off: PGO, nightlies, l10n, etc. These would be referenced by the job and graph definitions: "enable this job if nightlies are enabled in the branch definitions", etc. So in the branch definitions, we could either point to this dependency graph repo+revision, or at a local directory, for the job+graph definitions. In the gecko model, if someone adds a new job type, that would result in a new jobs+graphs repo revision. A patch to point the branch-definitions file at the new revision would land in Try, first, then one of the inbound branches. Then it would get merged to m-c and then out to the other inbound and project branches; then it would ride the trains.

(Of course, in the above model, there's the issue of inbound having different branch definitions than mozilla-central, which is why I was suggesting we have overrides by branch name. I'm not sure of a better solution at the moment.)

The other side of this model: when someone pushes a new jobs+graphs revision, that triggers a "generate new jobs+graphs templates" job. That would enter new jobs+graphs for the new SHA. Then, if you wanted to create a graph or job based on that SHA, the webapp doesn't have to re-build those from scratch; it has them in the db, pre-populated.

retries and retriggers

For retries, we need to track max [auto] retries, as well as job statuses per run. I played with this in my head: do we keep track of runs separately from job definitions? Or clone the jobs, in which case volatile status and customizing jobs become more of an issue? Keeping the job runs separate, and specifying whether they were an auto-retry or a user-generated retrigger, could help in preventing going beyond max-auto-retries.

Retriggers themselves are somewhat problematic if we mark jobs as skipped due to dependencies: if a job that was unsuccessful is retriggered and exits successfully, do we revisit previously skipped jobs? Or do we clone the graph when we retrigger, and keep all downstream jobs pending-blocked-by-dependencies? Does this graph mark the previous graph as a parent graph, or do we mark it as part of the same graph set?

(This is less of a problem currently, since build jobs run sendchanges in that cascading-waterfall type scheduling; any time you retrigger a build, it will retrigger all downstream tests, which is useful if that's what you want. If you don't want the tests, you either waste test machine time or human time in cancelling the tests. Explicitly stating what we want in the graph is a better model imo, but forces us to be more explicit when we retrigger a job and want the downstream jobs.)

Another possibility: I thought that instead of marking downstream jobs as skipped-due-to-dependencies, we could leave them pending-blocked-by-dependencies until they either see a successful run from their upstream dependencies, or hit their TTL (request timeout). This would remove some complexity in retriggering, but would leave a lot of pending jobs hanging around that could slow down the graph processing pool and skew our 15 minute wait time SLA metrics.

I don't think I have the perfect answers to these questions; a lot of my conclusions are based on the scope of the problem that I'm holding in my head. I'm certain that some solutions are better for some workflows and others are better for others. I think, for the moment, I came to the soft conclusion of a hand-wavy retriggering-portions-of-the-graph-via-webapp (or web api call, which does the equivalent).

A random semi-tangential thought: whichever method of pending- or skipped- solution we generate will probably significantly affect our 15 minute wait time SLA metrics, anyway; they may also provide more useful metrics like end-to-end-times. After we move to this model, we may want to revisit our metric of record.

lwr_runner.py

(This doesn't really have anything to do with the db, but I had this thought recently, and didn't want to save it for a part 6.)

While discussing this with the Gaia, A-Team, and perf teams, it became clear that we may need a solution for other projects that want to run simple jobs that aren't ported to mozharness. Catlee was thinking an equivalent process to the buildbot buildslave process: this would handle logging, uploads, status notifications, etc., without requiring a constant connection to the master. Previously I had worked with daemons like this that spawned jobs on the build farm, but then moved to launching scripts via sshd as a lower-maintenance solution.

The downsides of no daemon include having to solve the mach context problem on macs, having to deal with sshd on windows, and needing a remote logging solution in the scripts. The upsides include being able to add machines to the pool without requiring the daemon, avoiding platform-specific issues with writing and maintaining the daemon(s), and script changes are faster to roll out (and more granular) than upgrading a daemon across an entire pool.

if we create a `mozharness/scripts/lwr_runner.py` that takes a set of commands to run against a repo+revision (or set of repos+revisions), with pre-defined metrics for success and failure, then simpler processes don't need their own mozharness script; we could wrap the commands in lwr_runner.py. And we'd get all the logging, error parsing, and retry logic already defined in mozharness.

I don't think we should rule out either approach just yet. With the lwr_runner.py idea, both approaches seem viable at the moment.

In part 1, I covered where we are currently, and what needs to change to scale up.
In part 2, I covered a high level overview of LWR.
In part 3, I covered some hand-wavy LWR specifics, including what we can roll out in phase 1.
In part 4, I drilled down into the dependency graph.
We met with the A-team about this, a couple times, and are planning on working on LWR together!
Now I'm going to take care of some vcs-sync tasks, prep for this next meeting, and start writing some code.

## December 12, 2013

### Internet Explorer blog — Understanding the Real-World Performance of your Web Application Across IE11 and Other Browsers

The Performance Timing Test Drive lets you try out the Timing APIs.

# Performance Timeline

The Performance Timeline specification has been published as a W3C Recommendation and is fully supported in IE11 and Chrome 30. Using this interface, you can get an end to end view of time spent during navigating, fetching resources, and executing scripts running in your application. This specification defines both the minimum attributes all performance metrics need to implement and the interfaces developers can use to retrieve any type of performance metric.

All performance metrics must support the following four attributes:

• name. This attribute stores a unique identifier for the performance metric. For example, for a resource, it will be the resolved URL of the resource.
• entryType. This attribute stores the type of performance metric. For example, a metric for a resource would be stored as “resource.”
• startTime. This attribute stores the first recorded timestamp of the performance metric.
• duration. This attribute stores the end-to-end duration of the event being recorded by the metric.

All of the timing data is recorded in high resolution time using the type `DOMHighResTimeStamps`, defined in the High Resolution Time specification. Unlike `DOMTimeStamps` which measure time values in milliseconds from 01 January, 1970 UTC, the high resolution time value is measured in at least microsecond resolution from the start of navigation of the document. For example, if I check the current time using `performance.now()`, the high resolution time analogous for `Date.now()`, I would get the following interpretation of the current time:

> performance.now();

4038.2319370044793

> Date.now()

1386797626201

This time value also has the benefit of not being impacted by clock skew or adjustments. You can explore the What Time Is It Test Drive to understand the use of high resolution time.

You can use the following interfaces to retrieve a list of the performance metrics recorded at the time of the call. Using the startTime and duration, as well as any other attributes provided by the metric, you can obtain an end-to-end timeline view of your page performance as your customers had experienced.

PerformanceEntryList getEntries();

PerformanceEntryList getEntriesByType(DOMString entryType);

PerformanceEntryList getEntriesByName(DOMString name, optional DOMString entryType);

The getEntries method returns a list of all of the performance metrics on the page, whereas the other methods return specific items based on the name or type. We expect most developers will just use JSON stringify on the entire list of metrics and send the results to their server for analysis rather than on the client.

Let’s take a closer look at each of the different performance metrics: navigation, resource, marks, and measures.

The Navigation Timing interfaces provide accurate timing measurements for each of the phases of navigating to your Web application. The Navigation Timing L1 specification has been published as a W3C Recommendation, with full support since IE9, Chrome 28, and Firefox 23. The Navigation Timing L2 specification is a First Public Working Draft and is supported by IE11.

With Navigation Timing, developers can not only get the accurate end-to-end page load time, including the time it takes to get the page from the server, but also get the breakdown of where that time was spent in each of the networking and DOM processing phases: unload, redirect, app cache, DNS, TCP, request, response, DOM processing, and the load event. The script below uses Navigation Timing L2 to get this detailed information. The entry type for this metric is “navigation,” while the name is “document.” Check out a demo of Navigation Timing on the IE Test Drive site.

<!DOCTYPEhtml>

<html>

<body>

<script>

var navigation = ' Start Time: ' + nt.startTime + 'ms';

navigation += ' Duration: ' + nt.duration + 'ms';

navigation += ' Redirect: ' + (nt.redirectEnd - nt.redirectStart) + 'ms';

navigation += ' App Cache: ' + (nt. domainLookupStart - nt.fetchStart) + 'ms';

navigation += ' DNS: ' + (nt.domainLookupEnd - nt.domainLookupStart) + 'ms';

navigation += ' TCP: ' + (nt.connectEnd - nt.connectStart) + 'ms';

navigation += ' Request: ' + (nt.responseStart - nt.requestStart) + 'ms';

navigation += ' Response: ' + (nt.responseEnd - nt.responseStart) + 'ms';

}

</script>

</body>

</html>

By looking at the detailed time spent in each of the network phases, you can better diagnose and fix your performance issues. For example, you may consider not using a redirection if you find redirect time is high, use a DNS caching service if DNS time is high, use a CDN closer to your users if request time is high, or GZip your content if response time is high. Check out this video for tips and tricks on improving your network performance.

The main difference between the two Navigation Timing specification versions is in how timing data is accessed and in how time is measured. The L1 interface defines these attributes under the `performance.timing` object and in milliseconds since 01 January, 1970. The L2 interface allows the same attributes to be retrieved using the Performance Timeline methods, enables them to be more easily placed in a timeline view, and records them with high resolution timers.

Prior to Navigation Timing, developers would commonly try to measure the page load performance by writing JavaScript in the head of the document, like the below code sample. Check out a demo of this technique on the IE Test Drive site.

<!DOCTYPEhtml>

<html>

<script>

var start = Date.now();

var now = Date.now();

var latency = now - start;

sendAnalytics('Page Load Time: ' + latency);

}

</script>

</body>

</html>

However, this technique does not accurately measure page load performance, because it does not include the time it takes to get the page from the server. Additionally, running JavaScript in the head of the document is generally a poor performance pattern.

# Resource Timing

Resource Timing provides accurate timing information on fetching resources in the page. Similar to Navigation Timing, Resource Timing provides detailed timing information on the redirect, DNS, TCP, request, and response phases of the fetched resources. The Resource Timing specification has been published as a W3C Candidate Recommendation with support since IE10 and Chrome 30.

The following sample code uses the `getEntriesByType` method to obtain all resources initiated by the <img> element. The entry type for resources is “resource,” and the name will be the resolved URL of the resource. Check out a demo of Resource Timing on the IE Test Drive site.

<!DOCTYPEhtml>

<html>

<imgsrc='http://some-server/image1.png'>

<imgsrc='http://some-server/image2.png'>

<script>

function sendResourceTiming()

{

var resourceList = window.performance.getEntriesByType('resource');

for (i = 0; i < resourceList.length; i++)

{

if (resourceList[i].initiatorType == 'img')

{

sendAnalytics('Image Fetch Time: ' + resourceList[i].duration);

}

}

}

</script>

</body>

</html>

For security purposes, cross-origin resources only show their start time and duration; the detailed timing attributes are set to zero. This helps avoid issues of statistical fingerprinting, where someone can try to determine your membership in an organization by confirming whether a resource is in your cache by looking at the detailed network time. The cross origin server can send the `timing-allow-origin` HTTP header if it wants to share timing data with you.

# User Timing

User Timing provides detailed timing information on the execution of scripts in your application, complementing Navigation Timing and Resource Timing which provide detailed network timing information. User Timing allows you to display your script timing information in the same timeline view as your network timing data to get an end to end understanding of your app performance. The User Timing specification has been published as a W3C Recommendation, with support since IE10 and Chrome 30.

The User Timing interface defines two metrics used to measure script timing: marks and measures. A mark represents a high resolution time stamp at a given point in time during your script execution. A measure represents the difference between two marks.

The following methods can be used to create marks and measures:

void mark(DOMString markName);

void measure(DOMString measureName, optional DOMString startMark, optional DOMString endMark);

Once you have added marks and measures to your script, you can retrieve the timing data by using the `getEntry`, `getEntryByType`, or `getEntryByName` methods. The mark entry type is “mark,” and the measure entry type is “measure.”

The following sample code uses the mark and measure methods to measure the amount of time it takes to execute the doTask1() and doTask2() methods. Check out a demo of User Timing on the IE Test Drive site.

<!DOCTYPEhtml>

<html>

<script>

function doWork()

{

sendUserTiming(performance.getEntries());

}

</script>

</body>

</html>

We want to thank everyone in the W3C Web Performance Working Group for helping design these interfaces and browsers vendors for working on implementing this interface with an eye towards interoperability. With these interfaces, Web developers can truly start to measure and understand what they can do to improve the performance of their applications.

Try out the performance measurement interfaces with your Web apps in IE11, and as always, we look forward to your feedback via Connect.

Thanks,

Jatinder Mann, Internet Explorer Program Manager

### Planet Mozilla — Structural arrays in Typed Objects

Dave Herman and I were tossing around ideas the other day for a revision of the typed object specification in which we remove nominal array types. The goal is to address some of the awkwardness that we have encountered in designing the PJS API due to nominal array types. I thought I’d try writing it out. This is to some extent a thought experiment.

### Description by example

I’ve had a hard time trying to identify the best way to present the idea, because it is at once so similar and so unlike what we have today. So I think I’ll begin by working through examples and then try to define a more abstract version.

Let’s begin by defining a new struct type to represent pixels:

``````var Pixel = new StructType({r: uint8, g: uint8,
b: uint8, a: uint8});
``````

Today, if we wanted an array of pixels, we’d have to create a new type to represent that array (`new ArrayType(Pixel)`). Under the new system, each type would instead come “pre-equipped” with a corresponding array type, which can be used to create both single and multidimensional arrays. This type is accessible under the property `Array`. For example, here I create three objects:

``````var pixel = new Pixel();
var row   = new Pixel.Array(1024);
var image = new Pixel.Array([1024, 768]);
``````

The first object, `pixel`, represents just a single pixel. Its type is simply `Pixel`. The second object, `row`, repesents a single dimensional array of 1024 pixels. I denote this using the following notation `[Pixel : 1024]`. The third object, `image`, represents a two-dimensional array of 1024x768 pixels, which I denote as `[Pixel : 1024 x 768]`.

No matter what dimensions they have, all arrays are associated with a single type object. In other words:

``````objectType(row) === objectType(image) === Pixel.Array
``````

This implies that they share the same prototype as well:

``````row.__proto__ === image.__proto__ === Pixel.Array.prototype
``````

Whenever you have an instance of an array, such as `row` or `image`, you can access the elements of the array as you would expect:

``````var a = row[3];           // a has type Pixel
var b = image[1022];      // b has type [Pixel : 768]
var c = b[765];           // c has type Pixel
var d = image[1022][765]; // d has type Pixel
``````

Note that each time you index into an array instance, you remove the “leftmost” (or “outermost”) dimension, until you are left with the core type.

As today, it is always possible to “redimension” an array, so long as the total number of elements are preserved:

``````// flat has type [Pixel : 786432]:
var flat = image.redim(1024*768);

// three has type [Pixel : 2 x 512 x 768]:
var three = image.redim([2,512,768]);
``````

The variables `flat`, `three`, and `image` all represent pointers into the same underlying data buffer, but with different underlying dimensions.

Sometimes it is useful to embed an array into a struct. For example, imagine a type `Gradient` that embeds two pixel colors:

``````var Gradient = new StructType({from: Pixel, to: Pixel})
``````

Rather than having two fields, it might be convenient to express this type using an array of length 2 instead. In the old system, we would have used a fixed-length array type for this purpose. In the new system, we invoke the method `dim`, which produces a dimensioned type:

``````var Gradient = new StructType({colors: Pixel.dim(2)})
``````

Dimensioned types are very similar to the older fixed-length array types, except that they are not themselves types. They can only be used as the specification for a field type. When a dimensioned field is reference, the result is an instance of the corresponding array:

``````var gradient = new Gradient(); // gradient has type Gradient
var colors = gradient.colors;  // colors has type [Pixel : 2]
var from = colors[0];          // from has type Pixel
``````

### More abstract description

The type `T` of an typed object can be defined using the following grammar:

``````T = S | [S : D]
S = scalar | C
D = N | D x N
``````

Here `S` is what I call a single type. It can either be a scalar type – like `int32`, `float64`, etc. – or a struct, denoted `C` (to represent the fact that struct types are defined nominally).

UPDATE: This section has confused a few people. I meant for `T` to represent the type of an instance, and hence it includes the specific dimensions. There would only be on type object for all arrays, so if we defined a `U` to represent the set of type objects, it would be ```S | [S]```. But when you instantiate an array `[S]` you give it a concrete dimension. I realize that this is a bit of a confused notion of type, where I am intermingling the “static” state (“this is an array type”) and the dynamic portion (“the precise dimensions”). Of course, in this language we’re defining types dynamically, so the analogy is imprecise anyway.

For each struct `C`, there is a struct type definition `R` is defined as follows:

``````R = struct C { (f: T) ... }
``````

Here `C` is the name of the struct, `f` is a field name, and `T` is the (possibly dimensioned) type of the field.

This description is kind of formal-ish, and it may not be obvious how to map it to the examples I gave above. Each time a new `StructType` instance is created, that instance corresponds to a distinct struct name `C`. When a new array instance like `image` is created, its type corresponds to `[Pixel : 1024 x 768]`. This grammar reflects the fact that struct types are nominal, meaning that the type is tied to a specific struct type object, but array types are structural – given the element type and dimensions, we can construct an array type.

### Why make this change?

As time goes by we’ve encountered more and more scenarios where the nominal nature of array types is awkward. The problem is that it seems very natural to be able to create an array type given the type of the elements and some dimensions. But in today’s system, because those array types are distinct objects, creating a new array type is both heavyweight and has significance, since the array type has a new prototype.

There are a number of examples from the PJS APIs. In fact, we already did an extensive redesign to accommodate nominal array types already. But let me give you instead an example of some code that is hard to write in today’s system, and which becomes much easier in the system I described above.

Intel has been developing some examples that employ PJS APIs to do transforms on images taken from the camera. Those APIs define a number of filters that are applied (or not applied) as the user selects. Each filter is just a function that is supplied with some information about the incoming image as well as the window size and so on. For example, the filter for detecting faces looks like this:

``````function face_detect_parallel(frame, len, w, h, ctx) {
var skin = isskin_parallel(frame, len, w, h);
var row_sums = uint32.array(h).buildPar(i => ...);
var col_sums = uint32.array(w).buildPar(i => ...);
...
}
``````

I won’t go into the details of how the filter works. For our purposes, it suffices to say that `isskin_parallel` computes a (two-dimensional) array `skin` that contains, for each pixel, an indicator of whether the pixel represents “skin” or not. The `row_sums` computation then iterates over each row in the image and computes a sum of how many pixels in that row contain skin. `col_sums` is similar except that the value is computed for each column in the image.

Let’s take a closer look at the `row_sums` computation:

``````var row_sums = uint32.array(h).buildPar(i => ...);
//             ^~~~~~~~~~~~~~~
``````

What I am highlighting here is that this computation begins by defining a new array type of length `h`. This is natural because the height of the image can (potentially) change as the user resizes the window. This means that we are defining new array types for every frame.

This is bad for a number of reasons:

1. It’s inefficient. Creating an array type involves some overhead in the engine, and if nothing else it means creating two or three objects.
2. If we wanted to install methods on arrays or something like that, creating new array types all the time is problematic, since each will have a distinct prototype.

This pattern seems to come up a lot. Basically, it’s useful to be able to create arrays when you know the element type and the dimensions, and right now that means creating new array types.

### What do we lose?

Nominal array types can be useful. They allow people to create local types and attach methods. For example, if some library defines a struct type `Pixel`, then (today) some other library could define:

``````var MyPixelArray = new ArrayType(Pixel);
MyPixelArray.prototype.myMethod = function(...) { ... }
``````

I’m not too worried about this though. You can create wrapper types at various levels. Most languages I can think of – virtually all – use a structural approach rather than nominal for arrays (although the situations are not directly analogous). I think there is a reason for that.

### Is there a compromise?

I suppose we could allow array types to be explicitly instantiated but keep the other aspects of this approach. This permits users to define methods and so on. However, it also means that it is not enough to have the element type and dimension to construct an array instance, one must instead pass in the array type and dimension.

### Planet Mozilla — Building Rust Code - Using Make

This series of posts is about building Rust code. In the first post I covered the current issues (and my solutions) around building Rust using external tooling. This post will cover using Make to build Rust projects.

### The Example Crate

For this post, I'm going to use the rust-geom library as an example. It is a simple Rust library used by Servo to handle common geometric tasks like dealing with points, rectangles, and matrices. It is pure Rust code, has no dependencies, and includes some unit tests.

We want to build a dynamic library and the test suite, and the `Makefile` should be able to run the test suite by using `make check`. As much as possible, we'll use the same crate structure that rustpkg uses so that once rustpkg is ready for real use, the transition to it will be painless.

### Makefile Abstractions

Did you know that `Makefile`s can define functions? It's a little clumsy, but it works and you can abstract a bunch of the tedium away. I'd never really noticed them before dealing with the Rust and Servo build systems, which use them heavily.

By using shell commands like `shasum` and `sed`, we can compute crate hashes, and by using Make's `eval` function, we can dynamically define new targets. I've created a `rust.mk` which can be included in a `Makefile` that makes it really easy to build Rust crates.

### Magical Makefiles

Let's look at a `Makefile` for rust-geom which uses `rust.mk`.

``````include rust.mk

RUSTC ?= rustc
RUSTFLAGS ?=

.PHONY : all
all: rust-geom

.PHONY : check
check: check-rust-geom

\$(eval \$(call RUST_CRATE, .))
``````

It includes `rust.mk`, sets up some basic variables that control the compiler and flags, and then defines the top level targets. The magic bit comes the call to `RUST_CRATE` which takes a path to where a crate's `lib.rs` and `test.rs` are located. In this case the path is the current directory, `.`.

`RUST_CRATE` finds the `pkgid` attribute in the crate and uses this to compute the crate's name, hash, and the output filename for the library. It then creates a target with the same name as the crate name, in this case `rust-geom`, and a target for the output file for the library. It uses the Rust compiler's support for dependency information so that it will know exactly when it needs to recompile things.

If the crate contains a `test.rs` file, it will also create a target that compiles the tests for the crates into an executable as well as a target to run the tests. The executable will be named after the crate; for rust-geom it will be named `rust-geom-test`. The check target is also named after the crate, `check-rust-geom`.

The files `lib.rs` and `test.rs` are the files rustpkg itself uses by default. This `Makefile` does not support the `pkg.rs` custom build logic, but if you need custom logic, it is easy enough to modify this example. One benefit of following in rustpkg's footsteps here is that this same crate should be buildable with rustpkg without modification.

### Behind the Scenes

`rust.mk` is a a little ugly, but not too bad. It defines a few helper functions like `RUST_CRATE_PKGID` and `RUST_CRATE_HASH` which are used by the main `RUST_CRATE` function. The syntax is a bit silly because of the use of `eval` and the need to escape `\$`s, but it shouldn't be too hard to follow if you're already familiar with Make syntax.

``````RUST_CRATE_PKGID = \$(shell sed -ne 's/^#[ *pkgid *= *"(.*)" *];\$\$/\1/p' \$(firstword \$(1)))
RUST_CRATE_PATH = \$(shell printf \$(1) | sed -ne 's/^([^#]*)\/.*\$\$/\1/p')
RUST_CRATE_NAME = \$(shell printf \$(1) | sed -ne 's/^([^#]*\/){0,1}([^#]*).*\$\$/\2/p')
RUST_CRATE_VERSION = \$(shell printf \$(1) | sed -ne 's/^[^#]*#(.*)\$\$/\1/p')
RUST_CRATE_HASH = \$(shell printf \$(strip \$(1)) | shasum -a 256 | sed -ne 's/^(.{8}).*\$\$/\1/p')

ifeq (\$(shell uname),Darwin)
RUST_DYLIB_EXT=dylib
else
RUST_DYLIB_EXT=so
endif

define RUST_CRATE

_rust_crate_dir = \$(dir \$(1))
_rust_crate_lib = \$\$(_rust_crate_dir)lib.rs
_rust_crate_test = \$\$(_rust_crate_dir)test.rs

_rust_crate_pkgid = \$\$(call RUST_CRATE_PKGID, \$\$(_rust_crate_lib))
_rust_crate_name = \$\$(call RUST_CRATE_NAME, \$\$(_rust_crate_pkgid))
_rust_crate_version = \$\$(call RUST_CRATE_VERSION, \$\$(_rust_crate_pkgid))
_rust_crate_hash = \$\$(call RUST_CRATE_HASH, \$\$(_rust_crate_pkgid))
_rust_crate_dylib = lib\$\$(_rust_crate_name)-\$\$(_rust_crate_hash)-\$\$(_rust_crate_version).\$(RUST_DYLIB_EXT)

.PHONY : \$\$(_rust_crate_name)
\$\$(_rust_crate_name) : \$\$(_rust_crate_dylib)

\$\$(_rust_crate_dylib) : \$\$(_rust_crate_lib)
\$\$(RUSTC) \$\$(RUSTFLAGS) --dep-info --lib \$\$<

-include \$\$(patsubst %.rs,%.d,\$\$(_rust_crate_lib))

ifneq (\$\$(wildcard \$\$(_rust_crate_test)),"")

.PHONY : check-\$\$(_rust_crate_name)
check-\$\$(_rust_crate_name): \$\$(_rust_crate_name)-test
./\$\$(_rust_crate_name)-test

\$\$(_rust_crate_name)-test : \$\$(_rust_crate_test)
\$\$(RUSTC) \$\$(RUSTFLAGS) --dep-info --test \$\$< -o \$\$@

-include \$\$(patsubst %.rs,%.d,\$\$(_rust_crate_test))

endif

endef
``````

If you wanted, you could add the crate's target and the check target to the `all` and `check` targets within this function, simplifying the main `Makefile`. You could also have it generate an appropriate `clean-rust-geom` target as well.

It's not going to win a beauty contest, but it will get the job done nicely.

### Next Up

In the next post, I plan to show the same example, but using CMake.

### Planet Mozilla — Two Presentations: PAX Dev 2013 and Advanced JS 2013

I have not blogged in a while, because I’m not a good person. Ahem. I’ve also been behind about posting presentations that I’ve done, so I’m catching up on that now.

The first one is a presentation I gave at PAX Dev 2013, about the nuts and bolts involed in bringing a C++ game (or really any app) to the web using Emscripten. The slides are available here, and have the steps involved in going from existing C++ source to getting that running on the web.

The second one is a presentation I gave at Advanced.JS, about how asm.js can be used in traditional JavaScript client-side apps to speed up processing or add new features that would be difficult to rewrite in pure JS. The slides are available here.

### Planet Mozilla — On Leaving Mozilla

tl;dr: On 18nov, I gave my notice to Brendan and Bob that I will be leaving Mozilla, and sent an email internally at Mozilla on 26nov. I’m here until 31dec2013. Thats a lot of notice, yet feels right – its important to me that this is a smooth stable transition.

After they got over the shock, the RelEng team is stepping up wonderfully. Its great to see them all pitching in, sharing out the workload. They will do well. Obviously, at times like this, there are lots of details to transition, so please be patient and understanding with catlee, coop, hwine and bmoss. I have high confidence this transition will continue to go smoothly.

In writing this post, I realized I’ve been here 6.5 years, so thought people might find the following changes interesting:

1) How quickly can Mozilla ship a zero-day security release?
was: 4-6 weeks
now: 11 hours

2) How long to ship a “new feature” release?
was: 12-18 months
now: 12 weeks

3) How many checkins per day?
was: ~15 per day
now: 350-400 per day (peak 443 per day)

4) Mozilla hired more developers
increased number of developers x8
increased number of checkins x21
The point here being that the infrastructure improved faster then Mozilla could hire developers.

was: desktop only
now: desktop + mobile + phoneOS – many of which ship from the *exact* same changeset

6) updated tools
was: cvs
now: hg *and* git (aside, I don’t know any other organization that ships product from two *different* source-code revision systems.)

7) Lifespan of human Release Engineers
was 6-12 months
now: two-losses-in-6-years (3 including me)
This team stability allowed people to focus on larger, longer term, improvements – something new hires generally cant do while learning how to keep the lights on.

This is the best infrastructure and team in the software industry that I know of – if anyone reading this knows of better, please introduce me! (Disclaimer: there’s a big difference between people who update website(s) vs people who ship software that gets installed on desktop or mobile clients… or even entire phoneOS!)

Literally, Release Engineering is a force multiplier for Mozilla – this infrastructure allows us to work with, and compete against, much bigger companies. As a organization, we now have business opportunities that were previously just not possible.

Finally, I want to say thanks:

• I’ve been here longer then a few of my bosses. Thanks to bmoss for his council and support over the last couple of years.
• Thanks to Debbie Cohen for making LEAD happen – causing organizational change is big and scary, I know its impacted many of us here, including me.
• Thanks to John Lilly and Mike Schroepfer (“schrep”) – for allowing me to prove there was another, better, way to ship software. Never mind that it hadn’t been done before. And thanks to aki, armenzg, bhearsum, catlee, coop, hwine, jhopkins, jlund, joey, jwood, kmoir, mgerva, mshal, nthomas, pmoore, rail, sbruno, for building it, even when it sounded crazy or hadn’t been done before.
• Finally, thanks to Brendan Eich, Mitchell Baker, and Mozilla – for making the “people’s browser” a reality… putting humans first. Mozilla ships all 90+ locales, even Khmer, all OS, same code, same fixes… all at the same time… because we believe all humans are equal. It’s a living example of the “we work for mankind, not for the man” mindset here, and is something I remain super proud to have been a part of.

take care
John.

### Planet Mozilla — Zebra tables using nth-child and hidden rows?

Earlier today my colleague Anton Kovalyov who works on the Firefox JavaScript Profiler ran across an interesting problem: if you have a table in the page and you want to colour every odd row differently to make it easier to read (christened as “Zebra Tables” by David F. Miller on Alistapart in 2004) the great thing is that we have support for :nth-child in browsers these days. Without having to resort to JavaScript, you can stripe a table like this.

Now, if you add a class of “hidden” to a row (or set its CSS property of display to none), you visually hide the element, but you don’t remove it from the document. Thus, the striping is broken. Try it out by clicking the “remove row 3” button:

The solution Anton found other people to use is a repeating gradient background instead:

This works to a degree but seems just odd with the fixed size of line-height (what if one table row spans more than one line?).

Jens Grochtdreis offered a pure CSS solution that on the first glance seems to do the job using a mixture of nth-of-type, nth-child and the tilde selector.

This works, until you remove more than one row. Try it by clicking the button again. :(

In essence, the issue we are facing here is that hiding something doesn’t remove it from the DOM which can mess with many things – assistive technology, search engines and, yes, CSS counters.

The solution to the problem is not to hide the parts you want to get rid of but really, physically remove them from the document, thus forcing the browser to re-stripe the table. Stuart Langridge offered a clever solution to simply move the table rows you want to hide to the end of the table using appendChild() and hide them by storing their index (for later retrieval) in an expando:

[…]rows[i].dataset.idx=i;table.appendChild(rows[i]) and [data-idx] { display:none }

That way the original even/odd pairs will get reshuffled. My solution is similar, except I remove the rows completely and store them in a cache object instead:

This solution also takes advantage of the fact that the result of querySelectorAll is not a live list and thus can be used as a copy of the original table.

As with everything on the web, there are many solutions to the same problem and it is fun to try out different ways. I am sure there is a pure CSS solution. It would also be interesting to see how the different ways perform differently. With a huge dataset like the JS Profiler I’d be tempted to guess that using a full table instead of a table scrolling in a viewport with recycling of table rows might actually be a bottleneck. Time will tell.

## December 11, 2013

### Planet Mozilla — Eliminate Application Attackers before Exploitation - Podcast OWASP AppSensor

Podcast recorded at OWASP AppSecUSA on the AppSensor project.

-Michael Coates - @_mwc

### Planet Mozilla — insist: Better assertions for nodejs

insist: Better assertions for nodejs:

There’s plenty of assertion libraries out there that give you all brand-new APIs with all sorts of assertion testing. I don’t need that. I actually like just using the `assert` module. Except one thing. The standard message for `assert(false)` is useless.

I saw `better-assert`, got excited, and then realized it only provided one method. All I wanted was the `assert` module, with a better message.

So I made `insist`. You can truly just drop it instead of `assert`, and pretend it’s `assert`. Also, unlike a few libraries who try to do this, `insist` plays well with multi-line assertions.

``````var assert = require('insist');
var someArr = [15, 20, 5, 30];
assert(someArr.every(function(val) {
return val > 10;
}));
// output: AssertionError: assert(someArr.every(function(val) {
//   return val > 10;
// }));
``````

I insist.

### Planet Mozilla — Multi-line flexbox support in Nightly and Aurora 28

A few days ago, I checked in support for multi-line flex containers (also known as "multi-line flexbox") in Firefox Nightly. This functionality will be included in the Aurora 28 release that comes out later this week. If all goes well, it will be available in an official release as of Firefox 28, which ships in March.

In prior Firefox versions, we support single-line flex containers, which let authors group elements into a row or a column, which can then grow, shrink, and/or align the elements depending on the available space.

But with multi-line flexbox support, authors can use the flex-wrap CSS property (or the flex-flow shorthand) to permit a flex container's children to wrap into several lines (i.e. rows or columns), with each line able to independently flex and align its children.

This lets authors easily create flexbox-based toolbars whose buttons automatically wrap when they run out of space:
Similarly, it allows authors to create homescreen layouts with app icons and flexible widgets that wrap to fill the screen:
(Note that the flexible blue widget, labeled "wide", changes its size depending on the available space in its line.)

Furthermore, authors can use the align-content property to control how extra space is distributed around the lines. (I don't have a compelling demo for that, but the flexbox spec has a good diagram of how that looks at the bottom of its align-content section.)

The above screenshots are taken from a simple interactive demo page that I whipped up. Follow the link if you want to try it out.

The work here was primarily done in bug 702508, bug 939896, bug 939901, and bug 939905. Thanks to David Baron, Cameron McCormack, and Mats Palmgren for reviewing the patches.

### Planet Mozilla — Mobile Startups Toronto, and Firefox OS as an opportunity

The year is not yet done that I’m starting to pack my speaking agenda for the next one. In January, I’ll be in Toronto to talk about Firefox OS at the Mobile Startups TO user group.

On January 8, join me, and the most dynamic folks in the startups’ ecosystem of Toronto to learn more about Firefox OS, and the opportunity for startups at the Mozilla office. It’s nearly free as the 5\$ you’ll pay will go into food, and drinks, so you won’t have to worry about grabbing something quick from the office to the event. Here is the description of my presentation

As a startup, looking forward to growing the reach, and to improve the sustainability of your product is one key to success. What’s better as a platform than the web itself?  In this talk, Frédéric Harper, Senior Technical Evangelist at Mozilla, will show you how you can use HTML5, CSS3, and JavaScript to build amazing mobile applications as to brush up what you previously published. Learn about the open web technologies, including WebAPIs, and Web Activities, which enhance the developers’ toolbox. Let’s not forget the tools designed to get you started developing HTML apps for Firefox OS, and the web.

As usual, I’m counting on you to make this more of a discussion, than a presentation. So friends of Toronto who likes HTML5, CSS3, JavaScript, and the open web (or just wants to learn more about those), reserve your spot right away as we have a limited number of seats! See you in 2014 Toronto friends!

--
Mobile Startups Toronto, and Firefox OS as an opportunity is a post on Out of Comfort Zone from Frédéric Harper

### Planet Mozilla — <input type=number> coming to Mozilla

The support for <input type=number> that I've been working on for Mozilla is now turned on for Aurora 28 and Nightly builds. If you're interested in using <input type=number> here are a few things you should know:

• The current support should first ship in Firefox 28 (scheduled to release in March), barring any issues that would cause us to disable it.
• As of yet, locale specific user input is not supported. In other words user input that contains non-ASCII digits or a decimal separator other than the decimal point (for example, the comma) will not be accepted. If this turns out to be unacceptable then we may have to turn off support for Firefox 28, or else add a hack to at least accept comma. Ehsan has just finished battling to get ICU integrated into gecko's libXUL, so I should be able to fix this properly for Firefox 29.
• Unprivileged content is not currently allowed to access the CSS pseudo-elements that would let it style the different internal parts of the element (the text field, spinner and spin buttons). The only direct control content has over the styling of the internals is that it can remove the spinner by setting `-moz-appearance:textfield;` on the input. (The logic and behavior that defines <input type=number> will still apply, just without those buttons.)

If you test the new support and find any bugs please report them, being sure to add ":jwatt" to the CC field and "<input type=number>" to the Summary field of the report.

### Planet Mozilla — Building Rust Code - Current Issues

As rustpkg is still in its infancy, most Rust code tends to be built with make, other tools, or by hand. I've been working on updating Servo's build system to something a bit more reliable and fast, and so I've been giving a lot of thought to build tooling with regards to Rust.

In this post, I want to cover what the current issues are with building Rust code, especially with regards to external tooling. I'll also describe some recent work I did to address these issues. In the future, I want to cover specific ways to integrate Rust with a few different build tools.

### Current Issues

Building Rust with existing build tools is a little difficult at the moment. The main issues are related to Rust's attempt to be a better systems language than the existing options.

For example, Rust uses a larger compilation unit than C and C++ compilers, and existing build tools are designed around single file compilation. Rust libraries are output with unpredictable names. And dependency information must be done manually.

#### Compilation Unit

Many programming languages compile one source file to one output file and then collect the results into some final product. In C, you compile `.c` files to `.o` files, then archive or link them into `.lib`, `.a`, `.dylib`, and so on depending on the platform and whether you are building an executable, static library, or shared library. Even Java compiles `.java` inputs to one or more `.class` outputs, which are then normally packaged into a `.jar`.

In Rust, the unit of compilation is the crate, which is a collection of modules and items. A crate may consist of a single source file or an arbitrary number of them in some directory hierarchy, but its output is a single executable or library.

Using crates as the compilation unit makes sense from a compiler point of view, as it has more knowledge during compilation to work from. It also makes sense from a versioning point of view as all of the crate's contents goes together. Using crates as the compilation unit allows for cyclic dependencies between modules in the same crates, which is useful to express some things. It also means that separate declaration and implementation pieces are not needed, such as the header files in C and C++.

Most build tools assume a model similar to that of a typical C compiler. For example, make has pattern rules that can take and input to and output based on on filename transformations. These work great if one input produces one output, but they don't work well in other cases.

Rust still has a main input file, the one you pass to the compiler, so this difference doesn't have a lot of ramifications when using existing build tools.

#### Output Names

Compilers generally have an option for what to name their output files, or else they derive the output name with some simple formula. C compilers use the `-o` option to name the output; Java just names the files after the classes they contain. Rust also has a `-o` option, which works like you expect, except in the case of libraries where it is ignored.

Libraries in Rust are special in order to avoid naming collisions. Since libraries often end up stored centrally, only one library can have a given name. If I create a library called libgeom it will conflict with someone else's libgeom. Operating systems and distributions end up resolving these conflicts by changing the names slightly, but it's a huge annoyance. To avoid collisions, Rust includes a unique identifier called the crate hash in the name. Now my Rust library libgeom-f32ab99 doesn't conflict with libgeom-00a9edc.

Unfortunately, the current Rust compiler computes the crate hash by hashing the link metadata, such as name and version, along with the link metadata of its dependencies. This results in a crate hash that only the Rust compiler is realistically able to compute, making it seem pseudo-random. This causes a huge problem for build tooling as the output filename for libraries in unknown.

To work around this problem when using make, the Rust and Servo build systems use a dummy target called `libfoo.dummy` for a library called foo, and after running `rustc` to build the library, it creates the `libfoo.dummy` file so that make has some well known output to reason about. This workaround is a bit messy and pollutes the build files.

Here's an example of what a `Makefile` looks like with this `.dummy` workaround:

``````RUSTC ?= rustc

SOURCES = \$(find . -name '*.rs')

all: librust-geom.dummy

librust-geom.dummy: lib.rs \$(SOURCES)
@\$(RUSTC) --lib \$<
@touch \$@

clean:
@rm -f *.dummy *.so *.dylib *.dll
``````

While this works, it also has some drawbacks. For example, if you edit a file during a long compile, the `libfoo.dummy` will get updated after the compile is finished, and rerunning the build won't detect any changes. The timestamp of the input file will be older than the final output file that the build tool is checking. If the build system knew the real output file name, it could compare the correct timestamps, but that information has been locked inside the Rust compiler.

#### Dependency Information

Build systems need to be reliable. When you edit a file, it should trigger the correct things to get rebuilt. If nothing changes, nothing should get rebuilt. It's extremely frustrating if you edit a file, rebuild the library, and find that your code changes aren't reflected in the new output for some reason or that the library is not rebuilt at all. Reliable builds need accurate dependency information in order to accomplish this.

There's currently no way for external build tools to get dependency information about Rust crates. This means that developers tend to list dependencies by hand which is pretty fragile.

One quick way to approximate dependency info is just to recursively find every `*.rs` in the crate's source directory. This can be wrong for multiple reasons; perhaps the `include!` or `include_str!` macros are used to pull in files that aren't named `*.rs` or conditional compilation may omit several files.

This is similar to dealing with header dependencies by hand when working with C and C++ code. C compilers have options to generate dependency info to deal with this, which used by tools like CMake.

The price of inaccurate or missing dependency info is an unreliable build and a frustrated developer. If you find yourself reaching for `make clean`, you're probably suffering from this.

### Making It Better

It's possible to solve these problems without sacrificing the things we want and falling back to doing exactly what C compilers do. By making the output file knowable and handling dependencies automatically we make make build tool integration easy and the resulting builds reliable. This is exactly what I've been working on the last few weeks.

#### Stable and Computable Hashes

The first thing we need is to make the crate hash stable and easily computable by external tools. Internally, the Rust compiler uses SipHash to compute the crate hash, and takes into account arbitrary link metadata as well as the link metadata of its dependencies. SipHash is not something easily computed from a `Makefile` and the link metadata is not so easy to slurp and normalize from some dependency graph.

I've just landed a pull request that replaces the link metadata with a package identifier, which is a crate level attribute called `pkgid`. You declare it like `#[pkgid="github.com/mozilla-servo/rust-geom#0.1"];` at the top of your `lib.rs`. The first part, `github.com/mozilla-servo`, is a path, which serves as both a namespace for your crate and a location hint as to where it can be obtained (for use by rustpkg for example). Then comes the crate's name, `rust-geom`. Following that is the version identifier `0.1`. If no `pkgid` attribute is provided, one is inferred with an empty path, a 0.0 version, and a name based on the name of the input file.

To generate a crate hash, we take the SHA256 digest of the `pkgid` attribute. SHA256 is readily available in most languages or on the command line, and the `pkgid` attribute is very easy to find by running a regular expression over the main input file. The first eight digits of this hash are used for the filename, but the full hash is stored in the crate metadata and used as part of the symbol hashes.

Since the crate hash no longer depends on the crate's dependencies, it is stable so long as the `pkgid` attribute doesn't change. This should happen very infrequently, for instance when the library changes versions.

This makes the crate hash computable by pretty much any build tool you can find, and means rustc generates predictable output filenames for libraries.

#### Dependency Management

I've also got a pull request, which should land soon, to enable rustc to output make-compatible dependency information similar to the `-MMD` flag of gcc. To use it, you give rustc the `--dep-info` option and for an input file of `lib.rs` it will create a `lib.d` which can be used by make or other tools to learn the true dependencies.

The `lib.d` file will look something like this:

``````librust-geom-da91df73-0.0.dylib: lib.rs matrix.rs matrix2d.rs point.rs rect.rs side_offsets.rs size.rs
``````

Note that this list of dependencies will include code pulled in via the `include!` and `include_str!` macros as well.

Here's an example of a handwritten `Makefile` using dependency info. Note that this uses a hard-coded output file name, which works because crate hash is stable unless the `pkgid` attribute is changed:

``````RUSTC ?= rustc

all: librust-geom-851fed20-0.1.dylib

librust-geom-851fed20-0.1.dylib: lib.rs
@\$(RUSTC) --dep-info --lib \$<

-include lib.d
``````

Now it will notice when you change any of the `.rs` files without needed to explicitly list them, and this will get updated as your code changes automatically. A little `Makefile` abstraction on top of this can make it quite nice and portable.

### Next Up

In the next few posts, I'll show examples of integrating the improved Rust compiler with some existing build systems like make, CMake, and tup.

(Update: the next post covers building Rust with Make.)

### Planet WebKit — WebKitGTK+ hackfest 5.0 (2013)!

For the fifth year in a row the fearless WebKitGTK+ hackers have gathered in A Coruña to bring GNOME and the web closer. Igalia has organized and hosted it as usual, welcoming a record 30 people to its office. The GNOME foundation has sponsored my trip allowing me to fly the cool 18 seats propeller airplane from Lisbon to A Coruña, which is a nice adventure, and have pulpo a feira for dinner, which I simply love! That in addition to enjoying the company of so many great hackers.

Web with wider tabs and the new prefs dialog

The goals for the hackfest have been ambitious, as usual, but we made good headway on them. Web the browser (AKA Epiphany) has seen a ton of little improvements, with Carlos splitting the shell search provider to a separate binary, which allowed us to remove some hacks from the session management code from the browser. It also makes testing changes to Web more convenient again. Jon McCan has been pounding at Web’s UI making it more sleek, with tabs that expand to make better use of available horizontal space in the tab bar, new dialogs for preferences, cookies and password handling. I have made my tiny contribution by making it not keep tabs that were created just for what turned out to be a download around. For this last day of hackfest I plan to also fix an issue with text encoding detection and help track down a hang that happens upon page load.

Martin Robinson and Dan Winship hack

Martin Robinson and myself have as usual dived into the more disgusting and wide-reaching maintainership tasks that we have lots of trouble pushing forward on our day-to-day lives. Porting our build system to CMake has been one of these long-term goals, not because we love CMake (we don’t) or because we hate autotools (we do), but because it should make people’s lives easier when adding new files to the build, and should also make our build less hacky and quicker – it is sad to see how slow our build can be when compared to something like Chromium, and we think a big part of the problem lies on how complex and dumb autotools and make can be. We have picked up a few of our old branches, brought them up-to-date and landed, which now lets us build the main WebKit2GTK+ library through cmake in trunk. This is an important first step, but there’s plenty to do.

Hackers take advantage of the icecream network for faster builds

Under the hood, Dan Winship has been pushing HTTP2 support for libsoup forward, with a dead-tree version of the spec by his side. He is refactoring libsoup internals to accomodate the new code paths. Still on the HTTP front, I have been updating soup’s MIME type sniffing support to match the newest living specification, which includes specification for several new types and a new security feature introduced by Internet Explorer and later adopted by other browsers. The huge task of preparing the ground for a one process per tab (or other kinds of process separation, this will still be topic for discussion for a while) has been pushed forward by several hackers, with Carlos Garcia and Andy Wingo leading the charge.

Jon and Guillaume battling code

Other than that I have been putting in some more work on improving the integration of the new Web Inspector with WebKitGTK+. Carlos has reviewed the patch to allow attaching the inspector to the right side of the window, but we have decided to split it in two, one providing the functionality and one the API that will allow browsers to customize how that is done. There’s a lot of work to be done here, I plan to land at least this first patch durign the hackfest. I have also fought one more battle in the never-ending User-Agent sniffing war, in which we cannot win, it looks like.

Hackers chillin’ at A Coruña

I am very happy to be here for the fifth year in a row, and I hope we will be meeting here for many more years to come! Thanks a lot to Igalia for sponsoring and hosting the hackfest, and to the GNOME foundation for making it possible for me to attend! See you in 2014!

### Planet Mozilla — You are receiving this mail because you are mentoring this bug

Good news! As of today, Bugzilla now sends out emails containing both an X-Bugzilla-Mentors header and a “You are mentoring this bug” message. This means that it’s now possible to highlight activity in your mentored bugs in your favourite email client! I use Gmail, so I’ve created a filter that searches for “You are mentoring this bug” and stars it; you might consider the same, or giving it a label so it’s easy to see at a glance if there’s something you should prioritize. For mail header filters, you’ll want to search for X-Bugzilla-Mentors containing your bugzilla email address.

Note: this only works if searching for the mentor tag in the whiteboard yields a unique result. If the tag reads mentor=ashish and there’s an another account with :ashish_d, the result will not be unique so no relevant header value or footer will be applied to any messages sent to Ashish.

Please make use of this! There is no longer a good excuse for questions in mentored bugs to go unanswered or overlooked; let’s make sure we’re providing the best possible mentoring experience to new contributors that we can.

## Microsoft Security Bulletin MS13-097 - Critical

This security update resolves seven privately reported vulnerabilities in Internet Explorer. The most severe vulnerabilities could allow remote code execution if a user views a specially crafted Web page using Internet Explorer. An attacker who successfully exploited the most severe of these vulnerabilities could gain the same user rights as the current user. Users whose accounts are configured to have fewer user rights on the system could be less impacted than users who operate with administrative user rights.

This security update is rated Critical for Internet Explorer 6, Internet Explorer 7, Internet Explorer 8, Internet Explorer 9, Internet Explorer 10 and Internet Explorer 11 on Windows clients and Important for Internet Explorer 6, Internet Explorer 7, Internet Explorer 8, Internet Explorer 9, Internet Explorer 10, and Internet Explorer 11 on Windows servers. For more information, see the full bulletin.

Recommendation. Most customers have automatic updating enabled and will not need to take any action because this security update will be downloaded and installed automatically. Customers who have not enabled automatic updating need to check for updates and install this update manually. For information about specific configuration options in automatic updating, see Microsoft Knowledge Base Article 294871.

For administrators and enterprise installations, or end users who want to install this security update manually, Microsoft recommends that customers apply the update immediately using update management software, or by checking for updates using the Microsoft Update service.

## Security Update for Flash Player (2907997)

On December 10th, a security update for Adobe Flash Player in Internet Explorer 10 and 11 on supported editions of Windows 8, Windows 8.1 and Windows Server 2012 and Windows Server 2012 R2 is also available. The details of the vulnerabilities are documented in Adobe security bulletin APSB13-28. This update addresses the vulnerabilities in Adobe Flash Player by updating the affected Adobe Flash binaries contained within Internet Explorer 10 and Internet Explorer 11. For more information, see the advisory

Most customers have automatic updating enabled and will not need to take any action because this update will be downloaded and installed automatically. Customers who have not enabled automatic updating need to check for updates and install this update manually. For information about specific configuration options in automatic updating, see Microsoft Knowledge Base Article 294871.

— Wilson Guo, Program Manager, Internet Explorer

### Planet Mozilla — The Secret of Fast Programming: Stop Thinking

When I talk to developers about code complexity, they often say that they want to write simple code, but deadline pressure or underlying issues mean that they just don’t have the time or knowledge necessary to both complete the task and refine it to simplicity.

Well, it’s certainly true that putting time pressure on developers tends to lead to them writing complex code. However, deadlines don’t have to lead to complexity. Instead of saying “This deadline prevents me from writing simple code,” one could equally say, “I am not a fast-enough programmer to make this simple.” That is, the faster you are as a programmer, the less your code quality has to be affected by deadlines.

Now, that’s nice to say, but how does one actually become faster? Is it a magic skill that people are both with? Do you become fast by being somehow “smarter” than other people?

No, it’s not magic or in-born at all. In fact, there is just one simple rule that, if followed, will eventually solve the problem entirely:

Any time you find yourself stopping to think, something is wrong.

Perhaps that sounds incredible, but it works remarkably well. Think about it—when you’re sitting in front of your editor but not coding very quickly, is it because you’re a slow typer? I doubt it—”having to type too much” is rarely a developer’s productivity problem. Instead, the pauses where you’re not typing are what make it slow. And what are developers usually doing during those pauses? Stopping to think—perhaps about the problem, perhaps about the tools, perhaps about email, whatever. But any time this happens, it indicates a problem.

The thinking is not the problem itself—it is a sign of some other problem. It could be one of many different issues:

### Understanding

The most common reason developers stop to think is that they did not fully understand some word or symbol.

This happened to me just the other day. It was taking me hours to write what should have been a really simple service. I kept stopping to think about it, trying to work out how it should behave. Finally, I realized that I didn’t understand one of the input variables to the primary function. I knew the name of its type, but I had never gone and read the definition of the type—I didn’t really understand what that variable (a word or symbol) meant. As soon as I looked up the type’s code and docs, everything became clear and I wrote that service like a demon (pun partially intended).

This can happen in almost infinite ways. Many people dive into a programming language without learning what (, ), [, ], {, }, +, *, and % really mean in that language. Some developers don’t understand how the computer really works. Remember when I wrote The Singular Secret of the Rockstar Programmer? This is why! Because when you truly understand, you don’t have to stop to think. It’s also a major motivation behind my book—understanding that there are unshakable laws to software design can eliminate a lot of the “stopping to think” moments.

So if you find that you are stopping to think, don’t try to solve the problem in your mind—search outside of yourself for what you didn’t understand. Then go look at something that will help you understand it. This even applies to questions like “Will a user ever read this text?” You might not have a User Experience Research Department to really answer that question, but you can at least make a drawing, show it to somebody, and ask their opinion. Don’t just sit there and think—do something. Only action leads to understanding.

### Drawing

Sometimes developers stop to think because they can’t hold enough concepts in their mind at once—lots of things are relating to each other in a complex way and they have to think through it. In this case, it’s almost always more efficient to write or draw something than it is to think about it. What you want is something you can look at, or somehow perceive outside of yourself. This is a form of understanding, but it’s special enough that I wanted to call it out on its own.

### Starting

Sometimes the problem is “I have no idea what code to start writing.” The simplest solution here is to just start writing whatever code you know that you can write right now. Pick the part of the problem that you understand completely, and write the solution for that—even if it’s just one function, or an unimportant class.

Often, the simplest piece of code to start with is the “core” of the application. For example, if I was going to write a YouTube app, I would start with the video player. Think of it as an exercise in continuous delivery—write the code that would actually make a product first, no matter how silly or small that product is. A video player without any other UI is a product that does something useful (play video), even if it’s not a complete product yet.

If you’re not sure how to write even that core code yet, then just start with the code you are sure about. Generally I find that once a piece of the problem becomes solved, it’s much easier to solve the rest of it. Sometimes the problem unfolds in steps—you solve one part, which makes the solution of the next part obvious, and so forth. Whichever part doesn’t require much thinking to create, write that part now.

### Skipping a Step

Another specialized understanding problem is when you’ve skipped some step in the proper sequence of development. For example, let’s say our Bike object depends on the Wheels, Pedals, and Frame objects. If you try to write the whole Bike object without writing the Wheels, Pedals, or Frame objects, you’re going to have to think a lot about those non-existent classes. On the other hand, if you write the Wheels class when there is no Bike class at all, you might have to think a lot about how the Wheels class is going to be used by the Bike class.

The right solution there would be to implement enough of the Bike class to get to the point where you need Wheels. Then write enough of the Wheels class to satisfy your immediate need in the Bike class. Then go back to the Bike class, and work on that until the next time you need one of the underlying pieces. Just like the “Starting” section, find the part of the problem that you can solve without thinking, and solve that immediately.

Don’t jump over steps in the development of your system and expect that you’ll be productive.

### Physical Problems

If I haven’t eaten enough, I tend to get distracted and start to think because I’m hungry. It might not be thoughts about my stomach, but I wouldn’t be thinking if I were full—I’d be focused. This can also happen with sleep, illness, or any sort of body problem. It’s not as common as the “understanding” problem from above, so first always look for something you didn’t fully understand. If you’re really sure you understood everything, then physical problems could be a candidate.

### Distractions

When a developer becomes distracted by something external, such as noise, it can take some thinking to remember where they were in their solution. The answer here is relatively simple—before you start to develop, make sure that you are in an environment that will not distract you, or make it impossible for distractions to interrupt you. Some people close the door to their office, some people put on headphones, some people put up a “do not disturb” sign—whatever it takes. You might have to work together with your manager or co-workers to create a truly distraction-free environment for development.

### Self-doubt

Sometimes a developer sits and thinks because they feel unsure about themselves or their decisions. The solution to this is similar to the solution in the “Understanding” section—whatever you are uncertain about, learn more about it until you become certain enough to write code. If you just feel generally uncertain as a programmer, it might be that there are many things to learn more about, such as the fundamentals listed in Why Programmers Suck. Go through each piece you need to learn until you really understand it, then move on to the next piece, and so on. There will always be learning involved in the process of programming, but as you know more and more about it, you will become faster and faster and have to think less and less.

### False Ideas

Many people have been told that thinking is what smart people do, thus, they stop to think in order to make intelligent decisions. However, this is a false idea. If thinking alone made you a genius, then everybody would be Einstein. Truly smart people learn, observe, decide, and act. They gain knowledge and then use that knowledge to address the problems in front of them. If you really want to be smart, use your intelligence to cause action in the physical universe—don’t use it just to think great thoughts to yourself.

### Caveat

All of the above is the secret to being a fast programmer when you are sitting and writing code. If you are caught up all day in reading email and going to meetings, then no programming happens whatsoever—that’s a different problem. Some aspects of it are similar (it’s a bit like the organization “stopping to think,”) but it’s not the same.

Still, there are some analogous solutions you could try. Perhaps the organization does not fully understand you or your role, which is why they’re sending you so much email and putting you in so many meetings. Perhaps there’s something about the organization that you don’t fully understand, such as how to go to fewer meetings and get less email. Maybe even some organizational difficulties can be resolved by adapting the solutions in this post to groups of people instead of individuals.

-Max

### Planet Mozilla — Firefox for Android in 2013

Since our big rewrite last year, we’ve released new features of all sizes and shapes in Firefox for Android—as well as tons of bug fixes, of course. The feedback has been amazingly positive.

This was a year of consolidation for us, and I think we’ve succeeded in getting Firefox for Android in a much better place in the mobile browser space. We’ve gone from an (embarrassing) 3.5 average rating on Google Play to a solid 4.4 in just over a year (!). And we’re wrapping up 2013 as a pre-installed browser in a few devices—hopefully the first of many!

We’ve just released Firefox for Android 26 today, our last release this year. This is my favourite release by a mile. Besides bringing a much better UX, the new Home screen lays the ground for some of the most exciting stuff we’ll be releasing next year.

A lot of what we do in Firefox for Android is so incremental that it’s sometimes hard to see how all the releases add up. If you haven’t tried Firefox for Android yet, here is my personal list of things that I believe sets it apart from the crowd.

### All your stuff, one tap

The new Home in Firefox for Android 26 gives you instant access to all your data (history, bookmarks, reading list, top sites) through a fluid set of swipable pages. They are easily accessible at any time—when the app starts, when you create a new tab, or when you tap on the location bar.

You can always search your browsing data by tapping on the location bar. As an extra help, we also show search suggestions from your default search engine as well as auto-completing domains you’ve visited before. You’ll usually find what you’re looking for by just typing a couple of letters.

Top Sites, History, and Search.

Firefox for Android does a couple of special things for readers. Every time you access a page with long-form content—such as a news article or an essay—we offer you an option to switch to Reader Mode.

Reader Mode removes all the visual clutter from the original page and presents the content in a distraction-free UI—where you can set your own text size and color scheme for comfortable reading. This is especially useful on mobile browsers as there are still many websites that don’t provide a mobile-friendly layout.

Reader Mode in Firefox for Android

Secondly, we bundle nice default fonts for web content. This makes a subtle yet noticeable difference on a lot of websites.

Last but not least, we make it very easy to save content to read later—either by adding pages to Firefox’s reading list or by using our quickshare feature to save it to your favourite app, such as Pocket or Evernote.

### Make it yours

Add-ons are big in desktop Firefox. And we want Firefox for Android to be no different. We provide several JavaScript APIs that allow developers to extend the browser with new features. As a user, you can benefit from add-ons like Adblock Plus and Lastpass.

If you’re into blingy UIs, you can install some lightweight themes. Furthermore, you can install and use any web search engine of your choice.

Lightweight theme, Add-ons, and Search Engines

### Smooth panning and zooming

An all-new panning and zooming framework was built as part of the big native rewrite last year. The main focus areas were performance and reliability. The (mobile) graphics team has released major improvements since then and some of this framework is going to be shared across most (if not all) platforms soon.

From a user perspective, this means you get consistently smooth panning and zooming in Firefox for Android.

### Fast-paced development

We develop Firefox for Android through a series of fast-paced 6-week development cycles. In each cycle, we try to keep a balance between general housekeeping (bug fixes and polishing) and new features. This means you get a better browser every 6 weeks.

### Open and transparent

Firefox for Android is the only truly open-source mobile browser. There, I said it. We’re a community of paid staff and volunteers. We’re always mentoring new contributors. Our roadmap is public. Everything we’re working on is being proposed, reviewed, and discussed in Bugzilla and our mailing list. Let us know if you’d like to get involved by the way :-)

That’s it. I hope this post got you curious enough to try Firefox for Android today. Do we still have work to do? Hell yeah. While 2013 was a year of consolidation, I expect 2014 to be the year of excitement and expansion for Firefox on Android. This means we’ll have to set an even higher bar in terms of quality and, at the same time, make sure we’re always working on features our users actually care about.

2014 will be awesome. Can’t wait! In the meantime, install Firefox for Android and let us know what you think!

### Planet Mozilla — comment tagging deployed to bmo

i’ve been working on a bugzilla enhancement which allows you to tag individual comments with arbitrary strings, which was deployed today.

comment tagging features:

the bugzilla administrator can configure a list of comment tags which will result in those comments being collapsed by default when a bug is loaded.

this allows obsolete or irrelevant comments to be hidden from the information stream.

bugzilla shows a list of all comment tags in use on the bug, and clicking on a tag will expand those comments while collapsing all others.

this allows for simple threading of comments without diverging significantly from the current bugzilla user interface, api, and schema. you’ll be able to tag all comments relating to the same topic, and remove comments no longer relevant to that thread by removing the tag.

on bugs with a lot of information, it can be time consuming for people not directly involved in the bug to find the relevant comments.  applying comment tags to the right comments assists this, and may negate the need for information to be gathered outside of bugzilla.

for example:

• tagging a comment with “STR” (steps to reproduce) will help the qa team quickly find the information they need to verify the fix
• writing a comment summarising a new feature and tagging it with “docs” will help the generation of documentation for mdn or similar

implementation notes

• the “add tag” input field has an auto-complete drop-down, drawing from existing tags weighted by usage count
• by default editbugs membership is required to add tags to comments
• comment tags are not displayed unless you are logged in to bugzilla
• tags are added and removed via xhr, changes are immediately visible to the changer without refreshing the page
• tagging comments will not trigger bugmail, nor alter a bug’s last-modified date
• tags added by other users (or on other tabs) will generally not be visible without a page refresh

Filed under: bmo, mozilla

### Planet Mozilla — Firefox 17 ESR EOL Today

Firefox 24 ESR should be officially released today which means Firefox 17 ESR users will be automatically upgraded to Firefox 24 ESR. I want to take this opportunity to remind everyone of a major change that happened in Firefox 21 that will impact everyone upgrading to Firefox 24 ESR.

The location of a number of important files that are used to customize Firefox has changed. Here’s the list:

• defaults/preferences -> browser/defaults/preferences
• defaults/profile -> browser/defaults/profile
• extensions -> browser/extensions
• searchplugins -> browser/searchplugins
• plugins -> browser/plugins
• override.ini -> browser/override.ini

If you find that anything you’ve customized is not working anymore, these changes are probably the reason.

### Planet Mozilla — Clarifying Coding

With the upcoming Hour of Code, there’s been a lot of confusion as to the definition of what “coding” is and why it’s useful, and I thought I’d contribute my thoughts.

Rather than talking about “coding”, I prefer to think of “communicating with computers”. Coding, depending on its definition, is one of many ways that a human can communicate with a computer; but I feel that the word “communicating” is more powerful than “coding” because it gets to the heart of why we use computers in the first place.

We communicate with computers for many different reasons: to express ourselves, to create solutions to problems, to reuse solutions that others have created. At a minimum, this requires basic explorational literacy: knowing how to use a mouse and keyboard, using them to navigate an operating system and the Web, and so forth. Nouns in this language of interaction include terms like application, browser tab and URL; verbs include click, search, and paste.

These sorts of activities aren’t purely consumptive: we express ourselves every time we write a Facebook post, use a word processor, or take a photo and upload it to Instagram. Just because someone’s literacies are limited to this baseline doesn’t mean they can’t do incredibly creative things with them.

And yet communicating with computers at this level may still prevent us from doing what we want. Many of our nouns, like application, are difficult to create or modify using the baseline literacies alone. Sometimes we need to learn the more advanced skills that were used to create the kinds of things that we want to build or modify.

This is usually how coders learn how to code: they see the digital world around them and ask, “how was that made?” Repeatedly asking this question of everything one sees eventually leads to something one might call “coding”.

This is, however, a situation where the journey may be more important than the destination: taking something you really care about and asking how it’s made–or conversely, taking something imaginary you’d like to build and asking how it might be built–is both more useful and edifying than learning “coding” in the abstract. Indeed, learning “coding” without a context could easily make it the next Algebra II, which is a terrifying prospect.

So, my recommendation: don’t embark on a journey to “learn to code”. Just ask “how was that made?” of things that interest you, and ask “how might one build that?” of things you’d like to create. You may or may not end up learning how to code; you might actually end up learning how to knit. Or cook. Or use Popcorn Maker. Regardless of where your interests lead you, you’ll have a better understanding of the world around you, and you’ll be better able to express yourself in ways that matter.

### Opera Desktop Team — Plenty in twenty

Hi!

Been a while since I made a blog post, so I have something special for you today. Opera 20 goes to developer stream today. As you may know, the developer stream is where we try things out; some of them don’t make it to the Opera Next stream, others do, depending on their stability and general bugginess, so thanks in advance for trying them out and for your bug reports.

Opera 20 developer is available for Windows and Mac.

Highlights

• Drag tabs onto the bookmarks bar (DNA-12485)
• Confirm exit when using Command–Q (DNA-12338) (Mac only)
• Improved stash screenshots (DNA-13588). No more  blurry scaled snapshots, hopefully (NB: we haven’t tested every URL on the Web)
• Improved drag and drop between Speed Dial and Bookmarks Bar (DNA-12723)
• Settings | Advanced: Use smaller speed dial thumbnails (DNA-12781)
• Settings | Power-user: Width and Height of speed dial thumbnails (DNA-12781)

### Planet Mozilla — happy bmo push day!

the following changes have been pushed to bugzilla.mozilla.org:

• [941104] Default secure group for Mozilla Communities should not be “core-security”
• [843457] PROJECT environment variable is not honored when mod_perl is enabled
• [938161] sql_date_format() method for SQLite has an incorrect default format
• [928057] When custom fields are added, a DBA bug should be created to update metrics permissions
• [945501] create “Firefox :: Developer Tools: User Stories” component and enable the User Story extension on this component
• [853509] Bugzilla version not displayed on the index page
• [929321] create a script to delete all bugs from the database, and generate two dumps (with and without bugs)
• [781672] checksetup.pl fails to check the version of the latest Apache2::SizeLimit release (it throws “Invalid version format (non-numeric data)”)
• [938300] vers_cmp() incorrectly compares module versions
• [922226] redirect when attachments contain reviewboard URLs
• [943636] SQL error in quicksearch API when providing just a bug ID
• [945799] I cannot change a review from me to someone else
• [937020] consider hosting mozilla skin fonts on bmo
• [942029] review suggestions only shows the first mentor
• [869989] Add X-Bugzilla-Mentors field to bugmail headers and an indication to mentors in bugmail body
• [905384] Project Kickoff Form: Change Drop Down Options for When do the items need to be ordered by? and Currency Request for Total Cost in Finance Questions

discuss these changes on mozilla.tools.bmo.

Filed under: bmo, mozilla

### Planet Mozilla — Best Web Browser: Firefox

It was great to see that Mozilla Firefox was picked by Linux Journal Reader’s for a second year in a row as the best web browser and with a 2% gain in popularity. Additionally, Firefox OS  did pretty good and ranked in the Top 5 for mobile operating systems and I expect next year Firefox OS will take 1st or 2nd place.

Tomorrow, Mozilla Firefox should see a release of Firefox 26.0 to stable and I can tell you this release comes baked with all the goodness you all have come to expect from Firefox. Going back to the Linux Journal Reader’ Choice Awards I really think this continues to be a strong indicator that Linux Users across all distros really enjoy using Firefox and that Firefox remaining a default on many distros is a win for Linux Users considering the popularity of the browser.

If you are a Linux User I highly encourage you to get involved in testing the Nightly and Aurora builds of Firefox. I would also invite you to check out Firefox OS and the app development community (with a newly refreshed MDN!) that is filling the Firefox Marketplace with great apps.

## December 09, 2013

### Planet Mozilla — The bonuses of really short videos

One of the nice things about using YouTube for videos on support.mozilla.org is that we get audience retention stats. Here’s what they look like for a minute-long video I made about two years ago.
This video answers the “How do I set my home page?” question at about 23 seconds in. After that the audience really starts to drop off as the video goes into supplementary topics.

The newer videos I’ve made focus mainly on one thing. This video is only 21 seconds long so it gets right to the point. In this case the average viewer watches the entire thing. Pretty cool!

So shorter is better in this case. Tell me something I don’t already know. Well, my point is that a minute long video is generally considered pretty short. Turns out you might want to think about making videos WAY shorter.

And here’s another bonus for super short videos. They’re much easier to localize. I made this 29 second Firefox OS video as an experiment. After creating an English version, I was able to re-shoot it with the interface in Spanish and drop in localized narration (recorded while I re-shot the video) in about an hour. That’s so awesome. I want to do much more of that next year.

### Planet Mozilla — A brand-new MDN design to make making the Web better better

Today we launched the new design for the Mozilla Developer Network Web site. We’ve been working on this for a long time, with discussions starting as much as a year ago, and actual coding starting this past summer. It was a huge effort involving a ton of brilliant people, and I’m thrilled with the results! Not only is the new design more attractive, but it has a number of entirely new features that will help you find what you want—and read it—more easily, and in more places, than ever before.

The new home page has a completely revamped organization, with a large search box front and center. Below that are links to key areas of the MDN Web site, including much of our most-used documentation, such as the JavaScript, CSS, and HTML docs, content about Firefox OS and developer tools, and the brand-new Mozilla Developer Program, whose goal is to help Web developers learn more and more quickly.

### Zoning in

You may notice the new concept we call “zones” in the screenshot above. A “zone” is a new concept we’ve added, wherein we can construct a special topic area that can accumulate documentation and samples from across MDN to cover that topic. For example, the Firefox OS zone provides documentation about Firefox OS, which involves not only Firefox OS-specific content, but information about HTML, CSS, and so forth.

Here you see our new zone navigation bar along the left side of the screen, promotional boxes for specific content, and lists of key articles.

### Search and ye shall find

Search has been significantly improved; we now have an on-site search powered by Elastic Search rather than using Google, which lets us customize the search in useful ways. One particularly helpful feature is the addition of search filters. Once you’ve done a search, you can narrow the search further by using these filters. For example, here’s a search for “window element”:

Well. 5186 results is a lot. You can use our new search filters, though, to narrow those results down a bit. You can choose to restrict your search to one or more topic areas, types of document, and/or skill level. Let’s look for articles specifically about the DOM:

It’s worth noting here that these filters rely on content being tagged properly, and much of our content is still in the process of being tagged (especially regarding skill level). This is something we can always use help with, so please drop into #mdn on IRC if you’re interested in helping with this quick and easy way to help improve our search quality!

### Responsive design

An area in which MDN was sorely lacking in the past was responsive design. This is the concept of designing content to adapt to the device on which it’s being used. The new MDN design makes key adjustments to its layout based on the size of your screen.

 Here’s the Firefox zone’s landing page in standard “desktop” mode. This is what you’ll see browsing to it in a typical desktop browser environment. Here’s what the same page looks like in “small desktop” mode. This is what the page looks like when your browser window is smaller, such as when viewing on a netbook. And here’s the same page in “mobile” view. The page’s layout is adjusted to be friendlier on a mobile device.

Each view mode rearranges the layout, and in some cases removes less important page elements, to improve the page’s utility in that environment.

The last new feature I’ll point out (although not the last improvement by a long shot!) is the new quicklink feature. We now have the ability to add a collection of quicklinks to pages; this can be done manually by building the list while editing the page, or by using macros.

Here’s a screenshot of the quicklinks area on the page for the CSS background property:

The quicklinks in the CSS reference provide fast access to related properties; when looking at a background-related property, as seen above, you get quick access to all of the background-related properties at once.

There’s also an expandable “CSS Reference” section. Clicking it gives you an alphabetical list of all of the CSS reference pages:

As you see, this lets you quickly navigate through the entire CSS reference without having to backtrack to the CSS landing page. I think this will come as an enormous relief to a lot of MDN users!

To top it off, if you want to have more room for content and don’t need the quicklinks, you can hide them by simply clicking the “Hide sidebar” button at the top of the left column; this results in something like the following:

The quicklinks feature is rapidly becoming my favorite feature of this new MDN look-and-feel. Not all of our content is making full use of it yet, but we’re rapidly expanding its use. It makes navigating content so much easier, and is easy to work with as a content creator on MDN, too.

### Next steps

Our development team and the design and UX teams did a fantastic job building this platform, and our community of writers threw in their share as well: between testing the changes to providing feedback, not to mention contributing and updating enormous amounts of documentation to take advantage of new features and to look right in the new design, I’m enormously proud of everyone involved.

There’s plenty left to do. There are new platform features yet to be built, and the content always needs more work. If you’d like to help, drop into #mdn to talk about content or #mdndev to talk about helping with the platform itself. And feel free to file bugs with your suggestions and input.

See you online!

### Planet Mozilla — Tally

Tally:

I had need of a simple counter application on my phone, and I scoured the Play Store for a good one. They all have atrocious UIs, with far too many buttons and features. I found one that was nicely designed, Tap Counter, but the touch target was too small, only directly in the center, making it very easy to miss when counting people and not looking at the screen.

So, over the weekend, I made one.

It’s a simple, beautiful Holo design. It picks from one of the Android Holo colors for the circle up app launch, so it will change up each time you use it. There’s only one button, and it takes up the whole screen. To reset, simply hold down that button, and you’ll get a fun animation.

That’s it. That’s Tally.

### Planet Mozilla — Killing ESR17 and Thunderbird-ESR17

As I raised on dev.planning last week, today we will be disabling ESR17. Read below the post (fixed some small changes):

`Hello all,Next week, we will have our next merge date [1] on Dec. 9th, 2013.As part of that merge day we will be killing the ESR17 [2][3] builds and testson tbpl.mozilla.org as well as Thunderbird-Esr17 [4].This is part of our normal process where two merge days after thecreation of the latest ESR release (e.g. ESR24 [5]) we obsolete the lastone (e.g. ESR17).On an unrelated note to this post, we will be creating updates fromESR17 to ESR24 even after that date, however, we will have no morebuilds and tests on check-in.Please let me know if you have any questions.regards,Armen#############Zambrano Gasparnian, Armen (armenzg)Mozilla Senior Release Engineerhttps://mozillians.org/en-US/u/armenzg/http://armenzg.blogspot.ca[1] https://wiki.mozilla.org/RapidRelease/Calendar[2] https://wiki.mozilla.org/Enterprise/Firefox/ExtendedSupport:Proposal[3] https://tbpl.mozilla.org/?tree=Mozilla-Esr17[4] https://tbpl.mozilla.org/?tree=Thunderbird-Esr17[5] https://tbpl.mozilla.org/?tree=Mozilla-Esr24`

### Planet Mozilla — Now using AWS Spot instances for tests

Release Engineering makes heavy use of Amazon's EC2 infrastucture. The vast majority of our Firefox builds for Linux and Android, as well as our Firefox OS builds happen in EC2. We also do a ton of unit testing inside EC2.

Amazon offers a service inside EC2 called spot instances. This is a way for Amazon to sell off unused capacity by auction. You can place a bid for how much you want to pay by the hour for a particular type of VM, and if your price is more than the current market price, you get a cheap VM! For example, we're able to run tests on machines for \$0.025/hr instead of the regular \$0.12/hr on-demand price. We started experimenting with spot instances back in November.

There are a few downsides to using spot instances however. One is that your VM can be killed at any moment if somebody else bids a higher price than yours. The second is that your instances can't (easily) use extra EBS volumes for persistent storage. Once the VM powers off, the storage is gone.

These issues posed different challenges for us. In the first case, we were worried about the impact that interrupted jobs would have on the tree. We wanted to avoid the case where jobs were run on a spot instance, interrupted because of the market price changing, and then being retried a second time on another spot instance subject to the same termination. This required changes to two systems:

• aws_watch_pending needed to know to start regular on-demand EC2 instances in the case of retried jobs. This has been landed and has been working well, but really needs the next piece to be complete.
• buildbot needed to know to not pick a spot instance to run retried jobs. This work is being tracked in bug 936222. It turns out that we're not seeing too many spot instances being killed off due to market price [1], so this work is less urgent.

The second issue, the VM storage, turned out to be much more complicated to fix. We rely on puppet to make sure that VMs have consistent software packages and configuration files. Puppet requires per-host SSL certificates generated, and at Mozilla, these certificates need to be signed by a central certificate authority. In our previous usage of EC2 we work around this by puppetizing new instances on first boot, and saving the disk image for later use.

With spot instances, we essentially need to re-puppetize every time we create a new VM.

Having fresh storage on boot also impacts the type of jobs we can run. We're starting with running test jobs on spot instances, since there's no state from previous tests that is valuable for the next test.

Builds are more complicated, since we depend on the state of previous builds to have faster incremental builds. In addition, the cost of having to retry a build is much higher than it is for a test. It could be that the spot instances stay up long enough or that we end up clobbering frequently enough that this won't have a major impact on build times. Try builds are always clobbers though, so we'll be running try builds on spot instances shortly.

All this work is being tracked in https://bugzilla.mozilla.org/show_bug.cgi?id=935683

Big props to Rail for getting this done so quickly. With all this great work, we should be able to scale better while reducing our costs.

### Planet Mozilla — LWR (job scheduling) part iv: drilling down into the dependency graph

I already wrote a bit about the dependency graph here, and :catlee wrote about it here. While I was writing part 2, it became clear that

1. I had a lot more ideas about the dependency graph, enough for its own blog post, and
2. since I want to tackle writing the dependency graph first, solidifying my ideas about it beforehand would be beneficial to writing it.

I've been futzing around with graphviz with :hwine's help. Not half as much fun as drawings on napkins, but hopefully they make sense. I'm still thinking things through.

jobs and graphs

A quick look at TBPL was enough to convince me that the dependency graph would be complex enough just describing the relationships between jobs. The job details should be separate. Per-checkin, nightly, and periodic-PGO dependency graphs trigger overlapping sets of jobs, so avoiding duplicate job definitions is a plus.

We'll need to submit both the dependency graph and the associated job definitions to LWR together. More on how I think jobs and graphs could work in the db below in part 5.

For phase 1, I think job definitions will only cover enough to feed into buildbot and have them work.

dummy jobs

• In my initial dependency graph thoughts, I mentioned breakpoint jobs as a throwaway idea, but it's stuck with me.

We could use these at the beginning of graphs that we want to view or edit in the web app before proceeding. Or if we submit an experimental patch to Try and want to verify the results after a specific job or set of jobs before proceeding further. Or if we want to represent QA signoff in a release graph, and allow them to continue the release via the web app.

I imagine we would want a request timeout on this breakpoint, after which it's marked as timed out, and all child jobs are skipped. I imagine we'd also want to set an ACL on at least a subset of these, to limit who can sign off on releases.

Also in releases, we have simple notification jobs that send email when the release has passed certain milestones. We could later potentially support IRC pings and bug comments.

A highly simplified representation of part of a release:

We currently continue the release via manual Release Engineering intervention, after we see an email "go". It would be great to represent it in the dependency graph and give the correct group of people access. Less RelEng bottleneck.
• We could also have timer jobs that pause the graph until either cancelled or the timeout is hit. So if you want this graph to run at 7pm PST, you could schedule the graph with an initial timer job that marks itself successful at 7, triggering the next steps in the graph.
• In buildbot, we currently have a dummy factory that sleeps 5 and exits successfully. We used this back in the dark ages to skip certain jobs in a release, since we could only restart the release from the beginning; by replacing long-running jobs with dummy jobs, we could start at the beginning and still skip the previously successful portions of the release.

We could use dummy jobs to:

1. simplify the relationships between jobs. In the above graph, we avoided a many-to-many relationship by inserting a notification job in between the linux jobs and the updates.
2. trigger when certain groups of jobs finish (e.g. all linux64 mochitests), so downstream jobs can watch for the dummy job in Pulse rather than having to know how many chunks of mochitests we expect to run, and keep track as each one finishes.
3. quickly test dependency graph processing: instead of waiting for a full build or test, replace it with a dummy job. For instance, we could set all the jobs of a type to "success" except one "timed out; retry" to test max retry limits quickly. This assumes we can set custom exit statuses for each dummy job, as well as potentially pointing at pre-existing artifact manifest URLs for downstream jobs to reference.

Looking at this list, it appears to me that timer and breakpoint jobs are pretty close in functionality, as are notification and dummy (status?) jobs. We might be able to define these in one or two job types. And these jobs seem simple enough that they may be runnable on the graph processing pool, rather than calling out to SlaveAPI/MozPool for a new node to spawn a script on.

statuses

At first glance, it's probably easiest to reuse the set of TBPL statuses: success, warning, failure, exception, retry. But there are also the grey statuses 'pending' and 'running'; the pink status 'cancelled'; and the statuses 'timed out', and 'interrupted' which are subsets of the first five statuses.

Some statuses I've brainstormed:

• inactive (skipped during scheduling)
• request cancelled
• pending blocked by dependencies
• pending blocked by infrastructure limits
• skipped due to coalescing
• skipped due to dependencies
• request timed out
• running
• interrupted due to user request
• interrupted due to network/infrastructure/spot instance interrupt
• interrupted due to max runtime timeout
• interrupted due to idle time timeout (no output for x seconds)
• completed successful
• completed warnings
• completed failure
• retried (auto)
• retried (user request)

The "completed warnings" and "completed failure" statuses could be split further into "with crash", "with memory leak", "with compilation error", etc., which could be useful to specify, but are job-type-specific.

If we continue as we have been, some of these statuses are only detectable by log parsing. Differentiating these statuses allows us to act on them in a programmatic fashion. We do have to strike a balance, however. Adding more statuses to the list later might force us to revisit all of our job dependencies to ensure the right behavior with each new status. Specifying non-useful statuses at the outset can lead to unneeded complexity and cruft. Perhaps 'state' could be separated from 'status', where 'state' is in the set ('inactive', 'pending', 'running', 'interrupted', 'completed'); we could also separate 'reasons' and 'comments' from 'status'.

Timeouts are split into request timeouts or runtime timeouts (idle timeouts, max job runtime timeouts). If we hit a request timeout, I imagine the job would be marked as 'skipped'. I also imagine we could mark it as 'skipped successful' or 'skipped failure' depending on configuration: the former would work for timer jobs, especially if the request timeout could be specified by absolute clock time in addition to relative seconds elapsed. I also think both graphs and jobs could have request timeouts.

I'm not entirely sure how to coalesce jobs in LWR, or if we want to. Maybe we leave that to graph and job prioritization, combined with request timeouts. If we did coalesce jobs, that would probably happen in the graph processing pool.

For retries, we need to track max [auto] retries, as well as job statuses per run. I'm going to go deeper into this below in part 5.

relationships

For the most part, I think relationships between jobs can be shown by the following flowchart:

If we mark job 2 as skipped-due-to-dependencies, we need to deal with that somehow if we retrigger job 1. I'm not sure if that means we mark job 2 as "pending-blocked-by-dependencies" if we retrigger job 1, or if the graph processing pool revisits skipped-due-to-dependencies jobs after retriggered jobs finish. I'm going to explore this more in part 5, though I'm not sure I'll have a definitive answer there either.

It should be possible, at some point, to block the next job until we see a specific job status:

• don't run until this dependency is finished/cancelled/timed out
• don't run unless the dependency is finished and marked as failure
• don't run unless the dependency is finished and there's a memory leak or crash

For the most part, we should be able to define all of our dependencies with this type of relationship: block this job on (job X1 status Y1, job X2 status Y2, ...). A request timeout with a predefined behavior-on-expiration would be the final piece.

I could potentially see more powerful commands, like "cancel the rest of the [downstream?] jobs in this graph", or "retrigger this other job in the graph", or "increase the request timeout for this other job", being potentially useful. Perhaps we could add those to dummy status jobs. I could also see them significantly increasing the complexity of graphs, including the potential for infinite recursion in some constructs.

I think I should mark any ideas that potentially introduce too much complexity as out of scope for phase 1.

branch specific definitions

Since job and graph definitions will be in-tree, riding the trains, we need some branch-specific definitions. Is this a PGO branch? Are nightlies enabled on this branch? Are all products and platforms enabled on this branch?

This branch definition config file could also point at a revision in a separate, standalone repo for its dependency graph + job definitions, so we can easily refer to different sets of graph and job definitions by SHA. I'm going to explore that further in part 5.

I worry about branch merges overwriting branch-specific configs. The inbound and project branches have different branch configs than mozilla-central, so it's definitely possible. I think the solution here is a generic branch-level config, and an optional branch-named file. If that branch-named file doesn't exist, use the generic default. (e.g. generic.json, mozilla-inbound.json) I know others disagree with me here, but I feel pretty strongly that human decisions need to be reduced or removed at merge time.

graphs of graphs

I think we need to support graphs-of-graphs. B2G jobs are completely separate from Firefox desktop or Fennec jobs; they only start with a common trigger. Similarly, win32 desktop jobs have no real dependencies on macosx desktop jobs. However, it's useful to refer to them as a single set of jobs, so if graphs can include other graphs, we could create a superset graph that includes the appropriate product- and platform- specific graphs, and trigger that.

If we have PGO jobs defined in their own graph, we could potentially include it in the per-checkin graph with a branch config check. On a per-checkin-PGO branch, the PGO graph would be included and enabled in the per-checkin graph. Otherwise, the PGO graph would be included, but marked as inactive; we could then trigger those jobs as needed via the web app. (On a periodic-PGO branch, a periodic scheduler could submit an enabled PGO graph, separate from the per-checkin graph.)

It's not immediately clear to me if we'll be able to depend on a specific job in a subgraph, or if we'll only be able to depend on the entire subgraph finishing. (For example: can an external graph depend on the linux32 mochitest-2 job finishing, or would it need to wait until all linux32 jobs finish?) Maybe named dummy status jobs will help here: `graph1.start`, `graph1.end`, `graph1.builds_finished`, etc. Maybe I'm overthinking things again.

We need a balancing act between ease of reading and ease of writing; ease of use and ease of maintenance. We've seen the mess a strong imbalance can cause, in our own buildbot configs. The fact that we're planning on making the final graph easily viewable and testable without any infrastructure dependencies helps, in this regard.

graphbuilder.py

I think `graphbuilder.py`, our [to be written] dependency graph generator, may need to cover several use cases:

• Create a graph in an api-submittable format. This may be all we do in phase 1, but the others are tempting...
• Combine graphs as needed, with branch-specific definitions, and user customizations (think TryChooser and per-product builds).
• Verify that this is a well-formed graph.
• Run other graph unit tests, as needed.
• Potentially output graphviz files for user-friendly local graph visualization?
• It's unclear if we want it to also do the graph+job submitting to the api.

I think the per-checkin graph would be good to build first; the nightly and PGO graphs, as well as the branch-specific defines, might also be nice to have in phase 1.

I have 4 more sections I wrote skeletons for. Since those sections are more db-oriented, I'm going to move those into a part 5.

In part 1, I covered where we are currently, and what needs to change to scale up.
In part 2, I covered a high level overview of LWR.
In part 3, I covered some hand-wavy LWR specifics, including what we can roll out in phase 1.
In part 5, I'm going to cover some dependency graph db specifics.

## December 08, 2013

### Planet Mozilla — Socorro Support Classifiers

Socorro has a new feature: classifiers inside the processors. It is  a programmatic way of tagging a crash. The Support Classifiers are based on the TransformRule system added to the Socorro Processors way back in February of 2012.

Think of the term “Support” as a category for a set of tags.  Another term for “category” in this context is “facet”. Support Classifiers are intended for helping with user support.  For example, let's say we're getting crashes from installations of Firefox for which there are known support articles.  This tagging system will make it simpler to associate the crash with the support article.  Eventually, we could implement a system where the user could be automatically directed to a support article based on how the processor categorized the crash.

Classifications are defined by a list of rules. The first rule to match gets to assign the classification. Rules are in two parts: a predicate and an action:
• predicate: a Python function that implements a test to see if a condition within the raw and/or processed crash is True
• action: a Python function that will attach a tag to the appropriate place within a processed crash
In the initial implementation, there is only one Support Classifier rule. It is called the BitguardClassifier. It tests to see if the list of loaded modules contains “bitguard.dll”. If that module is present, then the classification “bitguard” is assigned to the Support classification. Since that is the only rule defined so far, “bitguard” is the only possible value. We hope to add more as this feature becomes more well known and we move toward engaging our users about crashes.

Support Classifiers are the second implementation of Classifiers within the processor. The first was the experimental SkunkClassfiers. We can add as many Classifiers as we wish. While both Support and Skunk classifiers define a single facet with a single value, more complex rules could add multiple classifications. Sets of rules can work together in many ways: apply all rules, apply rules until one fails, apply rules until one succeeds, etc.

Support Classifiers are pretty simple since it can only assign one value to the facet “support”. Each rule is tried one at a time and the first one to succeed gets to assign the value. The Skunk Classifiers work the same way. Future Signature Classifiers could include alternate or experimental signature generation algorithms.

Do you have a Classifier that you'd like to see applied to crashes? There are two ways that you can get your idea implemented in the processor.

1. decide if your classifier is one for Support or some other categorization.
2. define, in plain English, what you want your predicate and action to be. For example:
• predicate: if the the user put a comment in the crash submission AND they specified an email address and the crash has the signature “EnterBaseline”
3. Enter a bug in Bugzilla with the topic New Classifier with your classification category as well as the predicate and action.  Make sure that you CC :lars so I can vet your work.
4. pending approval, your classifier will be implemented by someone on the Socorro team and pushed to production with the next release.
How do I search in the UI for crashes with a certain classification?
At the moment, the UI for Socorro does not support searching for classifiers. See Bug 947723 for the current status of adding classifications to the UI.

Classifier functions are implemented as methods _predicate and _action in a class derived from the base class SupportClassifierBase.

The predicate is a function that accepts references to the raw and processed crashes as well as a reference to a Socorro Processor object itself. It returns a boolean value. The purpose is to determine if the rule is eligible to be applied. For example, the rule could test to see if the crash is a specific product and version. If the test is true, the predicate returns true and execution passes to the action function. If the test returns False, then the action is skipped and we move on to the next rule.

The action is a function that also accepts a copy of the raw and processed crashes as well as a reference to the Socorro Processor object. The action is generally to just add the classification to the processed crash.

All together, a support classifier should look like this:

`from socorro.processor.support_classifiers import SupportClassificationRuleclass WriteToThisPersonSupportClassifier(SupportClassificationRule):    def version(self):        return '1.0'    def _predicate(self, raw_crash, processed_crash, processor):        # implement the predicate as a boolean expression to be         # returned by this method         return (            raw_crash.UserComment is not None             and raw_crash.EmailAddress is not None             and processed_crash.signature == 'EnterBaseline'        )    def _action(self, raw_crash, processed_crash, processor):        self._add_classification(             # add the support classification to the processed_crash             processed_crash,            # choose the value of your classification on the next line            'contact about EnterBaseline',            # any extra data about the classification (if any)            None,             # the place to log that a classification has been assigned            processor.config.logger,         )`

What's inside the raw_crash and processed_crash that my classifier can access?

The raw_crash and the processed_crash are represented in persistent storage the form of a json compatible mapping.  When passed to a classifier, they are in the form of a DotDict, a DOM-like structure accessed with '.' notation.  There are no "out of bounds" fields with in the crash.  The classifier code is running a privileged environment, so all classifiers must be fully vetted before they can be put into production.

`    raw_crash.UserComment    raw_crash.ProductName    raw_crash.BuildID    processed_crash.json_dump.system_info.OS    processed_crash.json_dump.crash_info.crash_address    processed_crash.json_dump.threads[thread_number][frame_number].function    processed_crash.upload_file_minidump_flash1.json_dump.modules[1].filename`

Here's the form of a raw_crash.  This is what Socorro receives from crashing instances of Firefox.

`{   "AdapterDeviceID" : "0x104a",   "AdapterVendorID" : "0x10de",   "Add-ons" : "%7B972ce4c6-7e08-4474-a285-3208198ce6fd%7D:25.0.1",   "BuildID" : "20131112160018",   "CrashTime" : "1386534180",   "EMCheckCompatibility" : "true",   "EmailAddress": "...@..."   "FlashProcessDump" : "Sandbox",   "id" : "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}",   "InstallTime" : "1384605839",   "legacy_processing" : 0,   "Notes" : "AdapterVendorID: ... ",   "PluginContentURL" : "http://www.j...",   "PluginFilename" : "NPSWF32_11_7_700_169.dll",   "PluginName" : "Shockwave Flash",   "PluginVersion" : "11.7.700.169",   "ProcessType" : "plugin",   "ProductID" : "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}",   "ProductName" : "Firefox",   "ReleaseChannel" : "release",   "StartupTime" : "1386531556",   "submitted_timestamp" : "2013-12-08T20:23:08.450870+00:00",   "Theme" : "classic/1.0",   "throttle_rate" : 10,   "timestamp" : 1386534188.45089,   "Vendor" : "Mozilla",   "Version" : "25.0.1",   "URL" : "http://...",   "UserComment" : "Horrors!",   "Winsock_LSP" : "MSAFD Tcpip ... "}`

Here's the form of the processed_crash:

`{   "additional_minidumps" : [      "upload_file_minidump_flash2",      "upload_file_minidump_browser",      "upload_file_minidump_flash1"   ],   "addons" : [      [         "testpilot@labs.mozilla.com",         "1.2.3"      ],      ...  more addons ...   ],   "addons_checked" : true,   "address" : "0x77a1015d",   "app_notes" : "AdapterVendorID: 0x8086, ...",   "build" : "20131202182626",   "classifications" : {      "support" : {         "classification_version" : "1.0",         "classification_data" : null,         "classification" : "contact about EnterBaseline"      },      "skunk_works" : {         "classification_version" : "0.1",         "classification_data" : null,         "classification" : "not classified"      },      ... additional classifiers ...   },   "client_crash_date" : "2013-12-05 23:59:13.000000",   "completeddatetime" : "2013-12-05 23:59:56.119158",   "cpu_info" : "GenuineIntel family 6 model 42 stepping 7 | 4",   "cpu_name" : "x86",   "crashedThread" : 0,   "crash_time" : 1386287953,   "date_processed" : "2013-12-05 23:59:38.160492",   "distributor" : null,   "distributor_version" : null,   "dump" : "OS|Windows NT|6.1.7601 Service Pack 1\n... PIPE DUMP ...,   "email" : null,   "exploitability" : "none",   "flash_version" : "11.9.900.152",   "hangid" : "fake-e167ea3d-8732-4bae-a403-352e32131205",   "hang_type" : -1,   "install_age" : 680,   "json_dump" : {      "system_info" : {         "os_ver" : "6.1.7601 Service Pack 1",         "cpu_count" : 4,         "cpu_info" : "GenuineIntel family 6 model 42 stepping 7",         "cpu_arch" : "x86",         "os" : "Windows NT"      },      "crashing_thread" : {         "threads_index" : 0,         "total_frames" : 55,         "frames" : [            {               "function_offset" : "0x15",               "function" : "NtWaitForMultipleObjects",               "trust" : "context",               "frame" : 0,               "offset" : "0x77a1015d",               "normalized" : "NtWaitForMultipleObjects",               "module" : "ntdll.dll",               "module_offset" : "0x2015d"            },            ... more frames ...         ]      },      "thread_count" : 10,      "status" : "OK",      "threads" : [         {            "frame_count" : 55,            "frames" : [               {                  "function_offset" : "0x15",                  "function" : "NtWaitForMultipleObjects",                  "trust" : "context",                  "frame" : 0,                  "module" : "ntdll.dll",                  "offset" : "0x77a1015d",                  "module_offset" : "0x2015d"               },               ...  more frames ...            ]         },         ...  more threads ...      ],      "modules" : [         {            "end_addr" : "0x12e6000",            "filename" : "plugin-container.exe",            "version" : "26.0.0.5084",            "debug_id" : "8385BD80FD534F6E80CF65811735A7472",            "debug_file" : "plugin-container.pdb",            "base_addr" : "0x12e0000"         },         ... more modules ...      ],      "sensitive" : {         "exploitability" : "none"      },      "crash_info" : {         "crashing_thread" : 0,         "address" : "0x77a1015d",         "type" : "EXCEPTION_BREAKPOINT"      },      "main_module" : 0   },   "java_stack_trace" : null,   "last_crash" : null,   "os_name" : "Windows NT",   "os_version" : "6.1.7601 Service Pack 1",   "PluginFilename" : "NPSWF32_11_9_900_152.dll",   "pluginFilename" : null,   "pluginName" : null,   "PluginName" : "Shockwave Flash",   "PluginVersion" : "11.9.900.152",   "processor_notes" : "processor03_mozilla_com.89:2012; HybridCrashProcessor",   "process_type" : "plugin",   "product" : "Firefox",   "productid" : "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}",   "reason" : "EXCEPTION_BREAKPOINT",   "release_channel" : "beta",   "ReleaseChannel" : "beta",   "signature" : "hang | F_1152915508___________________________________",   "startedDateTime" : "2013-12-05 23:59:49.142604",   "success" : true,   "topmost_filenames" : "F_388496358________________________________________",   "truncated" : false,   "uptime" : 668,   "url" : "https://...",   "user_comments" : null,   "user_id" : "",   "uuid" : "e167ea3d-8732-4bae-a403-352e32131205",   "version" : "26.0",   "Winsock_LSP" : "...",      ... the next entries are additional crash dumps included in this crash ...      "upload_file_minidump_browser" : {      "address" : null,      "cpu_info" : "GenuineIntel family 6 model 42 stepping 7 | 4",      "cpu_name" : "x86",      "crashedThread" : null,      "dump" : "... same form as "dump" key above ... ",      "exploitability" : "ERROR: something went wrong"      "flash_version" : "11.9.900.152",      "json_dump" : { ... same form as "json_dump" key above ... }      "os_name" : "Windows NT",      "os_version" : "6.1.7601 Service Pack 1",      "reason" : "No crash",      "success" : true,      "truncated" : false,      "topmost_filenames" : [         ... same form as "topmost_filenames" above ...      ],      "signature" : "hang | whatever",   },      "upload_file_minidump_flash1" : {      ... same form as "upload_file_minidump_browser" above ...   },      "upload_file_minidump_flash2" : {      ... same form as "upload_file_minidump_browser" above ...   },}`

### Planet Mozilla — On Stage With A Legend

A few weeks ago I had the incredible fortune to be on stage with Mike Watt, punk rock legend, founding member of bands such as Minutemen, Dos and fIREHOSE, bassist for the Stooges (Iggy Pop's band). You get the idea – the man is a true legend.

My dear friends at CASH Music, a non-profit which builds tools which allow musicians to represent themselves on the web, organized one of their amazing Summits; this one was in LA and it had me on stage with Mike talking about punk rock, open source and everything in-between. It was epic. Here's the video:

### Planet Mozilla — An open talk proposal – Accidental Arrchivism

People who have seen me speak at one of the dozens of conferences I covered in the last year know that I am passionate about presenting and that I love covering topic from a different angle instead of doing a sales pitch or go through the motions of delivering a packaged talk over and over again.

For a few months now I have been pondering a quite different talk than the topics I normally cover – the open web, JavaScript and development – and I’d love to pitch this talk to the unknown here to find a conference it might fit. If you are organising a conference around digital distribution, tech journalism or publishing, I’d love to come around to deliver it. Probably a perfect setting would be a TEDx or Wired-like event. Without further ado, here is the pitch:

### Accidental arrchivism

The subject of media and software piracy is covered in mainstream media with a lot of talk about greedy, unpleasant people who use their knowledge to steal information and make money with it. The image of the arrogant computer nerd as perfectly displayed in Jurassic Park. There is also no shortage of poster children that fit this bill and it is easy to bring up numbers that show how piracy is hurting a whole industry.

This kind of piracy, however, is just the tip of the iceberg when it comes to the whole subject matter. If you dig deeper you will find a complex structure of hierarchies, rules, quality control mechanisms and distribution formats in the piracy scene. These are in many cases superior to those of legal distributors and much more technologically and socially advanced.

In this talk Chris Heilmann will show the results of his research into the matter and show a more faceted view of piracy – one that publishers and distributors could learn from. He will also show positive – if accidental – results of piracy and explain which needs yet unfilled by legal release channels are covered and result in the success of the pirates – not all of them being about things becoming “free”. You can not kill piracy by making it illegal and applying scare tactics – its decentralised structure and its very nature of already being illegal makes that impossible. A lot of piracy happens based on convenience of access. If legal channels embraced and understood some of the ways pirates work and the history of piracy and offered a similar service, a lot of it would be rendered unnecessary.

If you are a conference organiser who’d be interested, my normal presentation rules apply:

• I want this to be a keynote, or closing keynote, not a talk in a side track in front of 20 people
• I want a good quality recording to be published after the event. So far I was most impressed with what Baconconf delivered on that front with the recording of my “Helping or Hurting” presentation.
• I’d like to get my travel expenses back. If your event is in London, Stockholm or the valley, this could be zero as I keep staying in these places

If you are a fan of what I do right now and you’d be interested in seeing this talk, spread this pitch far and wide and give it to conference organisers. Thanks.

## December 07, 2013

### Planet Mozilla — An Hour of Code spawns hours of coding

One of the topics my daughters and two of their friends asked me to do this year in our home school is programming.  They call it Code Club, and we have been learning HTML, JavaScript, CSS together.  We’ve been using Thimble to make things like this visualization of Castles around the world.  It’s been a lot of fun.

This past week I introduced them to the Processing programming language using this great new interactive tutorial.  It was made for Computer Science Education Week and the Hour of Code, in which many organizations (including Mozilla Webmaker, who is also participating) have put together tutorials and learning materials for new programmers.

One of the things I love about the Processing Hour of Code tutorial is that it was made using two projects I worked on for Mozilla, namely Processing.js and Popcorn.js, and does something I always wanted to see people do with them: build in-browser, interactive, rich media, web programming curriculum.  Everything you need to learn and code is all in one page, with nothing to install.

I decided to use the Processing tutorial for Code Club this past week, and let the girls try it out.  I was a bit worried it would be too hard for them, but they loved it, and were able to have a great time with it, and understand how things worked.  Here’s the owl two of the girls made:

The other girls made a one-eyed Minion from Despicable Me.  As they were preparing to show one another their creations, disaster struck, and the code for the Minion was lost.  Some tears were shed, and we agreed to work on making it again.

Today we decided to see if we could fix the issue that caused us to lose our work in the first place.  The Processing Hour of Code was designed to inspire new programmers to try their hand at programming, and what better way than to write some real code that will help other people and improve the tutorial?

What follows is a log I wrote as the girls worked on the problem.  Without giving them all the answers, I gave them tips, explained things they didn’t understand, and let them have an organic experience of debugging and fixing a real bug.  All three of us loved it, and these are the steps my daughters took along the way:

1) Go to http://hello.processing.org, click on “Click Here To Begin” and go to the Introduction.

2) Try to make the bug happen again.  We tried many things to see if we could make the bug happen again, and lose our work.  After experimenting for a while, we discovered that you could make the bug happen by doing the following:

• Go to the “Color” section
• Change the code in the code editor.
• Click on the blue outside the code editor
• Press the Delete/Backspace key
• The web page goes back to the beginning, and now we’ve lost our code

3) Find a way to stop this from happening.  We went to Google and tried to research some solutions.  Here are some of the searches we tried, and what we found:

• “How do you make a web page not go back?”
• “How to keep the delete key from triggering the back button?”
• “How to stop a web page from losing my work hitting backspace”
• “what is the code to stop a web page from losing my work hitting backspace”

Most of these searches gave us the wrong info.  Either we found ways to stop a web browser from doing Back when you press Delete, or else we found complicated code for ignoring the Delete key.  We tried another search:

• “stop the page from closing”

This brought us to a question on a site called Stack Overflow, with an answer that looked interesting.  It talked about using some code called `window.onbeforeunload`.  We had never heard of this, so we did another search for it:

Many pages came back with details on how to use it, and one of them was Mozilla’s page, which we read.  In it we found a short example of how to use it, which we copied into our clipboard:

```window.onbeforeunload = function(e) {
return 'Dialog text here.';
};```

We tried pasting this into the Processing code editor, but that didn’t work.  Instead we needed to change the code for the hello.processing.org web page itself.  Our dad showed us one way to do it.

4) We used the Developer Tools to modify the code for the hello.procesing.org web page by pasting the code from Mozilla’s example into the Web Console (Tools > Web Developer > Web Console)

Now we tried again to trigger our bug, and it asked us if we wanted to leave or stay on the page.  We fixed it!!!

We opened another tab and loaded hello.processing.org again, and we see that this version still has the old bug.  We now need to make this fix for all versions.

5) We want to fix the actual code for the site.  “Dad, how do we fix it?  Doesn’t he have have to fix it? How can we fix it for the whole world from here?”  Great questions!  First we have to find the code so we can make our change.  We look at the site’s About page, and see the names of the people who made this web page listed under Credits.  We do a search for their names and “Hello Processing”:

• “daniel shiffman scott garner scott murray hello processing”

In the results, we find a site where they were talking about the project, and Dan Shiffman was announcing it.  In his announcement he says, “We would love as many folks as possible to test out the tutorial and find bugs.” He goes on to say: “You can file bug reports here: https://github.com/scottgarner/Processing-Hour-Of-Code/issues?state=open We are glad to read that he wants people to test it and tell him if they hit bugs.  Now we know where to tell them about our bug.

6) At https://github.com/scottgarner/Processing-Hour-Of-Code we find the list of open issues (there were 5), and none of them mentioned our problem–maybe they don’t know about it.  We also see all of the code for their site, and there is a lot of it.

7) We create a new account on Github so that we can tell them about the issue, and also fix their code.  We then fork their project, and get our own version at https://github.com/threeamigos/Processing-Hour-Of-Code

8 ) Now we have to figure out where to put our code.  It’s overwhelming just looking at it.  Our dad suggests that we put the code in the page that caused our error, which was http://hello.processing.org/editor/index.html.  On github, we see that editor/index.html is an HTML file https://github.com/threeamigos/Processing-Hour-Of-Code/blob/gh-pages/editor/index.html.

9) Next we have to find the right place in this HTML file to paste our code.  Our dad tells us we need to find a `<script>...</script>` block, and we quickly locate a bunch of them.  We don’t understand how all of them work, but notice there is one at the bottom of the file, and decide to put our code there.

10) We clicked “Edit” on the file in the Github web page, and made the following change:

https://github.com/threeamigos/Processing-Hour-Of-Code/commit/1cf2be198f7a1db12c35e45b8bc1e0edd73f8e6c#diff-d05c1452bfe9809c27d44ee7c8df31d1

10) Finally, we made a Pull Request from our code to the original.  We told them about the bug, and how it happens, and also that we’d fixed it, and that they could use our code.  We’re excited to see their reply, and we hope they will use our code, and that it will help other new programmers too.

### Planet Mozilla — Mozilla Taiwan Localization Sprint

Last week I traveled to Taipei for localization sprint with Mozilla Taiwan community. The community translates various Mozilla projects into Chinese (Traditional)(zh-TW). The goal of a localization sprint is to bring together new and experienced translators under one roof. Such events help promote knowledge sharing through peer learning and mentor-ship. Special thanks to Michael Hung, Estela Liu and Natasha Ma for making the Mozilla space available and inviting by providing Pizzas.

The event began with a short introduction to localization by Peter Chen, followed by a brief overview of various translation projects such as translating Mozilla Support (SUMO) by Ernest Chiang, translating Webmaker by Peter Chen, translating addons.mozilla.org by Toby, translating Mozilla Developer Network(MDN) articles by Carl, translating Mozilla videos with Amara tool by Irvin and translating Mozilla Links by Chung-Hui Fang. The speakers then organized participants into topic specific working groups, based on each individual's interest.

It was interesting to see how people used various tools such as Narro, Pootle, Transifex and even Google Docs for translation. It gave me an opportunity to observe and note some of the potential problems in the translation process. At the end of the day, everyone gathered to share and present their group's work. The also took time to answer question that participants had. All in all it was a very productive and enjoyable event. Mozilla badges were issued to recognize the participants' contributions.

Check out the event photos and etherpad for additional details. The Mozilla Taiwan community will continue to translate during their weekly MozTwLab meetups and a follow-up event is planned for the sprint 2014.

## December 06, 2013

### Planet Mozilla — How EgotisticalGiraffe was fixed

In October, Bruce Schneier reported that the NSA had discovered a way to attack Tor, a system for online anonymity.

The NSA did this not by attacking the Tor system or its encryption, but by attacking the Firefox web browser bundled with Tor. The particular vulnerability, code-named “EgotisticalGiraffe”, was fixed in Firefox 17, but the Tor browser bundle at the time included an older version, Firefox 10, which was vulnerable.

I’m writing about this because I’m a member of Mozilla’s JavaScript team and one of the people responsible for fixing the bug.

I still don’t know exactly what vulnerability EgotisticalGiraffe refers to. According to Mr. Schneier’s article, it was a bug in a feature called E4X. The security hole went away when we disabled E4X in Firefox 17.

You can read a little about this in Mozilla’s bug-tracking database. E4X was disabled in bugs 753542, 752632, 765890, and 778851, and finally removed entirely in bugs 833208 and 788293. Nicholas Nethercote and Ted Shroyer contributed patches. Johnny Stenback, Benjamin Smedberg, Jim Blandy, David Mandelin, and Jeff Walden helped with code reviews and encouragement. As with any team effort, many more people helped indirectly.

Thank you.

Now I will write as an American. I don’t speak for Mozilla on this or any topic. The views expressed here are my own and I’ll keep my political opinions out of it.

The NSA has twin missions: to gather signals intelligence and to defend American information systems.

From the outside, it appears the two functions aren’t balanced very well. This could be a problem, because there’s a conflict of interest. The signals intelligence folks are motivated to weaponize vulnerabilities in Internet systems. The defense folks, and frankly everyone else, would like to see those vulnerabilities fixed instead.

It seems to me that fixing them is better for national security.

In the particular case of this E4X vulnerability, mainly only Tor users were vulnerable. But it has also been reported that the NSA has bought security vulnerabilities “from private malware vendors”.

All I know about this is a line item in a budget (\$25.1 million). I’ve seen speculation that the NSA wants these flaws for offensive use. It’s a plausible conjecture—but I sure hope that’s not the case. Let me try to explain why.

The Internet is used in government. It’s used in banks, hospitals, power plants. It’s used in the military. It’s used to handle classified information. It’s used by Americans around the world. It’s used by our allies. If the NSA is using security flaws in widely-used software offensively (and to repeat, no one says they are), then they are holding in their hands major vulnerabilities in American civilian and military infrastructure, and choosing not to fix them. It would be a dangerous bet: that our enemies are not already aware of those flaws, aren’t already using them against us, and can’t independently buy the same information for the same price. Also that deploying the flaws offensively won’t reveal them.

Never mind the other, purely civilian benefits of a more secure Internet. It just sounds like a bad bet.

Ultimately, the NSA is not responsible for Firefox in particular. That honor and privilege is ours. Yours, too, if you want it.

We have work to do. One key step is content process separation and sandboxing. Internet Explorer and Chrome have had this for years. It’s coming to Firefox. I’d be surprised if a single Firefox remote exploit known to anyone survives this work (assuming there are any to begin with). Firefox contributors from four continents are collaborating on it. You can join them. Or just try it out. It’s rough so far, but advancing.

I’m not doing my job unless life is constantly getting harder for the NSA’s SIGINT mission. That’s not a political statement. That’s just how it is. It’s the same for all of us who work on security and privacy. Not only at Mozilla.

If you know of a security flaw in Firefox, here’s how to reach us.

### Planet Mozilla — Introducing Scroll-Graph

For awhile I’ve been warning people that the FPS counter is very misleading. There’s many case where the FPS might be high but the scroll may still not be smooth. To give a better indicator of the scrolling performance I’ve written Scroll-Graph which can be enabled via layers.scroll-graph. Currently it requires OMTC+OGL but if this is useful we can easily port this to OMTC+D3D. Currently it works best on Desktop, it will need a bit more work for mobile to be compatible with APZC.

To understand how Scroll-Graph works lets look at scrolling from the point of view of a physicist. Scrolling and pan should be smooth. The ideal behavior is for scrolling to behave like you have a page on a low friction surface. Imagine that the page is on a low friction ice arena and that every time you fling the page with your finger or the trackpad you’re applying force to the page. The friction of the ice is applying a small force in the opposite direction. If you plot the velocity graph you’d expect to see something like this roughly:

Expected Velocity Graph

Now if we scroll perfectly then we expect the velocity of a layer to follow a similar curve. The important part is *not* the position of the velocity curve but it’s the smoothness of the velocity graph. Smooth scrolling means the page has a smooth velocity curve.

Now on to the fun part. Here’s some examples of Scroll-Graph in the browser. Here’s I pan a page and get smooth scrolling with 2 minor inperfections (Excuse the low FPS gif, the scrolling was smooth):

Smooth ScrollGraph velocity = Smooth Scrolling

Now here’s an example of a jerky page scrolling. Note the Scroll-Graph is not smooth at all but very ‘spiky’ and it was noticeable to the eye:

Jerky scrolling = Jerky Scroll-Graph

### Planet Mozilla — My presentations are Creative Commons: share them, use them, improve them…

Creative Commons: http://j.mp/1bNjxvC

I want more people to do public speaking. I want more people to share their passion about technology. I want more people to show the awesomeness of the Open Web, and help others be more open. So when someone asks me if he can take one of my presentations, my reaction is: of course!  Of course you can: share it, use it, improve it, change it…

I uploaded all my presentations under a Creative Commons license Attribution 2.5 Generic on my SlideShare account. It’s easy to download the original format, but if you have any trouble, feel free to let me know. To be even clearer about what you can do with my material, I’ll add a Creative Commons logo on all my new presentations. Of course, all the content inside of those presentations, like images, are also under Creative Commons license. I as well encourage you to check on this site as there is probably a recording of the presentation related to the slides you want to use: I started to do this a couple of weeks ago, so you won’t find it for older presentations. It can be a guide to help you understand the slides, the content, and how I delivered it: in no situation, you have to share the information in the same way! Make it yours.

As I said in my presentation about public speaking: if you are starting to be on the stage, and wants some feedbacks on your presentation, materials, and ways of delivering your own story, please let me know, I’ll be more than happy to help. So start now, and share your passion with others…

--
My presentations are Creative Commons: share them, use them, improve them… is a post on Out of Comfort Zone from Frédéric Harper

### Planet Mozilla — reading binary structures with python

Last week, I wanted to parse some Mach-O files with Python.  “Oh sure,” you think, “just use the `struct` module and this will be a breeze.”  I have, however, tried to do that:

```class MyBinaryBlob:
def __init__(self, buf, offset):
self.f1, self.f2 = struct.unpack_from("BB", buf, offset)```

and such an approach involves a great deal of copy-and-pasted code.  And if you have some variable-length fields mixed in with fixed-length fields, using `struct` breaks down very quickly. And if you have to write out the fields to a file, things get even more messy. For this experiment, I wanted to do things in a more declarative style.

The desire was that I could say something like:

```class MyBinaryBlob:
field_names = ["f1", "f2"]
field_kinds = ["uint8_t", "uint8_t"]```

and all the necessary code to parse the appropriate fields out of a binary buffer would spring into existence. (Automagically having the code to write these objects to a buffer would be great, too.) And if a binary object contained something that would be naturally interpreted as a Python list, then I could write a minimal amount of code to do that during initialization of the object as well. I also wanted inheritance to work correctly, so that if I wrote:

```class ExtendedBlob(MyBinaryBlob):
field_names = ["f3", "f4"]
field_kinds = ["int32_t", "int32_t"]```

`ExtendedBlob` should wind up with four fields once it is initialized.

At first, I wrote things like:

```def field_reader(fmt):
size = struct.calcsize(fmt)
return struct.unpack_from(fmt, buf, offset)[0], size

def initialize_slots(obj, buf, offset, slot_names, field_specs):
total = 0
for slot, reader in zip(slot_names, field_specs):
x, size = reader(buf, offset + total)
setattr(obj, slot, x)
total += size

class MyBinaryBlob:
field_names = ["f1", "f2"]
field_specs = [fB, fB]

def __init__(self, buf, offset):
initialize_slots(self, buf, offset, self.field_names, self.field_specs)```

Fields return their size to make it straightforward to add variable-sized fields, not just fixed-width fields that can be parsed by `struct.unpack_from`. This worked out OK, but I was writing out a lot of copy-and-paste constructors, which was undesirable. Inheritance was also a little weird, since the natural implementation looked like:

```class ExtendedBlob(MyBinaryBlob):
field_names = ["f3", "f4"]
field_specs = [fi, fi]

def __init__(self, buf, offset):
super(ExtendedBlob, self).__init__(buf, offset)
initialize_slots(self, buf, offset, self.field_names, self.field_specs)```

but that second `initialize_slots` call needs to start reading at the offset resulting from reading `MyBinaryBlob`‘s fields. I fixed this by storing a `_total_size` member in the objects and modifying `initialize_slots`:

```def initialize_slots(obj, buf, offset, slot_names, field_specs):
total = obj._total_size
for slot, reader in zip(slot_names, field_specs):
x, size = reader(buf, offset + total)
setattr(obj, slot, x)
total += size
obj._total_size = total```

which worked out well enough.

I realized that if I wanted to use this framework for writing binary blobs, I’d need to construct “bare” objects without an existing buffer to read them from. To do this, there had to be some static method on the class for parsing things out of a buffer. `@staticmethod` couldn’t be used in this case, because the code inside the method didn’t know what class it was being invoked on. But `@classmethod`, which received the invoking class as its first argument, seemed to fit the bill.

After some more experimentation, I wound up with a base class, `BinaryObject`:

```class BinaryObject(object):
field_names = []
field_specs = []

def __init__(self):
self._total_size = 0

def initialize_slots(self, buf, offset, slot_names, field_specs):
total = self._total_size
for slot, reader in zip(slot_names, field_specs):
x, size = reader(buf, offset + total)
setattr(self, slot, x)
total += size
self._total_size = total

@classmethod
def from_buf(cls, buf, offset):
# Determine our inheritance path back to BinaryObject
inheritance_chain = []
pos = cls
while pos != BinaryObject:
inheritance_chain.append(pos)
bases = pos.__bases__
assert len(bases) == 1
pos = bases[0]
inheritance_chain.reverse()

# Determine all the field names and specs that we need to read.
all_field_names = itertools.chain(*[c.field_names
for c in inheritance_chain])
all_field_specs = itertools.chain(*[c.field_specs
for c in inheritance_chain])

# Create the actual object and populate its fields.
obj = cls()
obj.initialize_slots(buf, offset, all_field_names, all_field_specs)
return obj```

Inspecting the inheritance hierarchy at runtime makes for some very compact code. (The single-inheritance assertion could probably be relaxed to an assertion that all superclasses except the first do not have `field_names` or `field_specs` class members; such a relaxation would make behavior-modifying mixins work well with this scheme.) Now my classes all looked like:

```class MyBinaryBlob(BinaryObject):
field_names = ["f1", "f2"]
field_specs = [fB, fB]

class ExtendedBlob(MyBinaryBlob):
field_names = ["f3", "f4"]
field_specs = [fi, fi]

blob1 = MyBinaryBlob.from_buf(buf, offset)
blob2 = ExtendedBlob.from_buf(buf, offset)```

with a pleasing lack of code duplication.  Any code for writing can be written once in the `BinaryObject` class using a similar inspection of the inheritance chain.

But how does parsing additional things during construction work? Well, subclasses can define their own `from_buf` methods:

```class ExtendedBlobWithList(BinaryObject):
field_names = ["n_objs"]
field_specs = [fI]

@classmethod
def from_buf(cls, buf, offset):
obj = BinaryObject.from_buf.__func__(cls, buf, offset)
# do extra initialization here
for i in range(obj.n_objs):
...
return obj```

The trick here is that calling `obj = BinaryObject.from_buf(buf, offset)` wouldn’t do the right thing: that would only parse any members that `BinaryObject` had, and return an object of type `BinaryObject` instead of one of type `ExtendedBlobWithList`. Instead, we call `BinaryObject.from_buf.__func__`, which is the original, undecorated function, and pass the `cls` with which we were invoked, which is `ExtendedBlobWithList`, to do basic parsing of the fields. After that’s done, we can do our own specialized parsing, probably with `SomeOtherBlob.from_buf` or similar. (The `_total_size` member also comes in handy here, since you know exactly where to start parsing additional members.) You can even define `from_buf` methods that parse a bit, determine what class they should really be constructing, and construct an object of that type instead:

```R_SCATTERED = 0x80000000

class Relocation(BinaryObject):
field_names = ["_bits1", "_bits2"]
field_specs = [fI, fI];
__slots__ = field_names

@classmethod
def from_buf(cls, buf, offset):
obj = BinaryObject.from_buf.__func__(Relocation, buf, offset)

# OK, now for the decoding of what we just got back.
if obj._bits1 & R_SCATTERED:
return ScatteredRelocationInfo.from_buf(buf, offset)
else:
return RelocationInfo.from_buf(buf, offset)```

This hides any detail about file formats in the parsing code, where it belongs.

Overall, I’m pretty happy with this scheme; it’s a lot more pleasant than bare `struct.unpack_from` calls scattered about.

### Planet Mozilla — A Weird Ritual

I stumbled across the short form creative brief by way of a tweet from @jmspool and I had to share it. It reminds me of something we built at dojo4 when I was CEO there, but it includes a Very Important Addition.

Technology and design work is expensive, far too expensive to do without some anticipated return (unless you work in a sector that allows you to light bricks of technology dollars afire on a hot summer day “just for the ambiance”).

When I was at dojo4, upon signing a contract with a customer, I tried to capture a couple sentences about their anticipated return on a 3″ by 5″ notecard. I pinned the notecard to a corkboard where everyone could see it (and I mean everyone: our employees, our guests, our other customers). We called the notecard the Project Compass.

The project compass was intended to be a guide, an arbiter in times of uncertainty. Whenever a question arose about project scope or direction, we could look at the project compass for clarity. A typical project compass might be “Redesign the website and add a feature allowing customers to create and manage their own profiles.”

Astute readers may notice the above compass doesn’t describe a return on investment at all. That’s quite common, unfortunately. It is HARD to achieve clarity about a project’s anticipated return. Often, a project’s sponsor has already done some initial analysis and design and is giving implementation experts the output of the initial analysis (“Redesign the website”) instead of the input (“Increase signups and improve retention”). Sometimes the sponsor can’t articulate what they hope to achieve. Just as often the implementation team can’t hear it.

At dojo4 we assumed imperfection in our project compass. Every project required a compass to move forward, but we agreed (and said out loud) that the compass might change. We even asked @anthonydimitre to draw us a classy graphic explaining exactly how this process would work:

dojo4′s Project Compass, circa 2011

We usually dove into implementation as soon as a compass was written and pinned to the corkboard. For the minimum-viable-product startups dojo4 worked with, “implementation” was practically synonymous with “changing the compass”. But “implementation” also always meant “charging hard toward maximal features in minimal time”.

The little black “No” in the middle of the illustration above is what we envisioned happening if the project was discovered to be out of alignment with the compass. We’d look at stories and check them against the compass and change one or the other as necessary. But delivering code at breakneck pace to customers with rapidly changing goals was totally orthogonal to thoughtfully reviewing and making adjustments to paper-based project artifacts. So, our project compasses often went stale.

This is common in every kind of project everywhere. Sometimes it is a problem; sometimes not. When a project sponsor and all the project’s implementers have fantastic rapport and constant engagement, they can happily forget whatever they wrote in the brief three months ago. They’re grooving. But sometimes, the project sponsor and the implementers will carry divergent ideas of the project’s purpose all the way to launch day. I know at least a few people who’ve changed careers after pulling a week of all-nighters to deliver something that nobody wants.

That was precisely what the project compass was designed to help us avoid. But a corkboard full of stale project compasses didn’t help anything. Which is why the short form creative brief caught my eye. The document itself resembles the project compass — more verbose, still quite brief. But unlike the compass, the short form creative brief is imbued with longevity through a “weird ritual at the start of every meeting”:

One of the team members, always a different person, would read the exact same document out loud, word for word. The document, about three–quarters of a printed page, contained a tiny creative brief about the design they were working on. Reading it out loud was how they started every design meeting, whether it was a brainstorming meeting or a design review….[then] the project’s leader would turn to the group and ask the same question, “Everyone agree that this is what we’re working on today?”

Many times this exercise has no obvious impact: Everyone simply nods and the meeting moves forward. But occasionally, someone asks for clarification. They ask because they’re new to the project; or they ask because they’ve been assigned a task that doesn’t seem aligned; or they ask because they sponsored the project and no longer agree with something in the brief. When someone asks, the group discusses and updates the brief as needed.

Ritual is the perfect word for this exercise because the magic only happens if you do it religiously. You read the brief every time. You read the brief even when it feels silly to read the brief. Even — no, especially — when the meeting is about something urgent or tense. Because reading the brief puts the project’s critical facts right where they belong: At the forefront of everyone’s mind, in consensus terms freshly aligned with the effort actually underway, for the entire duration of the project.

I suspect the shape of the brief (or compass) is not nearly as important as its frequent review. Of course, it should contain enough information to explain why project participants keep meeting and working together, instead of playing pinball or hoarding shoes or visiting every county in Texas. That could be one terse sentence. The important thing is that the brief continues to explain where the group is headed, even if the group changes direction.

At Mozilla we use etherpad for planning meetings and taking notes during meetings. I have begun adding a “theme” to the top of etherpad agendas as a gentle way to remind people of the big reason we’re having yet another weekly meeting. For example, on Mozillians.org right now, the big reason we’re having yet another weekly meeting is to discuss the Curated Groups feature that we’ve been working on all quarter.

After reading up on the short form creative brief, I think I may take a moment at every meeting to speak our current theme out loud, too. Does everyone agree that this is our focus right now? Are there any questions about what it means?

### Opera Desktop Team — Opera 18 stable update

Hello!

We are continuing to work on Opera Next and Opera Developer in our never ending quest to provide the best web browser.

This of course doesn’t mean we neglect the Opera stable version. Recently you guys reported crashes when enabling notifications in Gmail. Thanks for the feedback and in return here is an update to fix this issue!

What do you have to do to get the update? If you already have Opera installed it may well have already updated itself (or be in the process of updating). You can check this via the ‘About Opera’ entry in the main Opera Menu. Alternatively, if you want you can also manually download Opera here.

### Planet Mozilla — Mozilla Location Service - The What, Why and Privacy

I'm currently working on the Mozilla Location Service and have been doing so for the last quarters. The project was finally announced more broadly over at the Mozilla Cloud Services blog in late October. Since then we've had a steady amount of interest and a number of repeating questions coming in. I'd like to take this opportunity to give more background information on why we are interested in location services and address some questions about the way we do things. This area is extremely complex, so bear with me while I provide a lot of background information.

Note that this is my personal opinion and not an official position of Mozilla.

### What is it?

There's a lot of interest in "the location space" and lots of news, start-ups and competition around location, mobile location, location context, maps and all things related. We aren't investing broadly in "all things location", but are focused on one very concrete aspect: The ability of a device to determine its own position as represented by a latitude and longitude. A device will use a variety of sensors to determine information about its environment and do some calculation to derive a position from those. In most cases a remote service will be queried to provide extra data to aid in the calculation or large parts of the calculation will be done remotely.

As a concrete example a mobile phone might be connected to a cell tower. Using this information it will query a remote service. The remote service has a database of all cell towers mapped to positions and can return the position of the cell tower as an approximation of the device position.

The sensors typically used for this purpose include a satellite based positioning sensor (GPS, Glonass, ...) and data for visible cell towers, WiFi access points and Bluetooth LE beacons. Other sensors like the compass or accelerometer can be used to determine relative position changes. There are even scientific experiments to use light sensors and variations in the magnetic field as sources of location information. If multiple sensors deliver data, these can be combined to provide more precise positions or positions with a smaller error margin or better accuracy. For some sensors additional data like signal strengths, signal noise or time of flight data can be used to narrow down the position.

### What it is not!

The Mozilla Location Service only deals with determining a device position. It doesn't and won't deal with services like maps, points of interest data, transportation or traffic information. For some of these OpenStreetMap is an established open community and it doesn't make sense for us to compete with them. In addition there are also a good number of commercial offerings for these higher level services and both users and developers have a good number of choices here. Different Mozilla products might partner with both communities and companies to provide user value and bundle their services - those questions are outside of our scope here.

Our location service helps with what you might call device initiated positioning. It is up to the device and ultimately the user to decide if a positioning request should be done. Separate from this are network or operator based positioning methods used for mobile phones. As part of being connected to a cell network, the cell network operator maintains a database of which phone is currently connected to which cell tower. This is required to route incoming phone calls or SMS to the right tower and ultimately the phone itself. Depending on the cell standard a phone might maintain connections to multiple cell towers. You can find out more about this on the radiolocation wikipedia page.

These operators based methods don't require additional user consent and work as a side-effect of having a cell connection. The only way to opt-out of these is by not using phones. In many countries operators are required to provide this data to government agencies. There are two common examples of this. One is emergency services (for example E-911) in which the emergency call is directed to the geographically closest response center and the response center gets the exact location of the caller to quickly dispatch emergency help to the right location. Even if the caller is unsure of his or her location or confused or distressed.

The other much more controversial case is data retention in which operators have to store and share metadata about calls and phone positions for a lengthy period of months to years. There are also examples of intelligence services capturing this information on sometimes questionable legal grounds. These operator based methods are completely outside the control and scope of our location service.

### Why do it at all?

There are plenty of examples where users are willing to have their devices determine their location. There always has to be and will be an explicit user choice in this, but most people find some of the use-cases compelling enough to allow this.

Some of the use-cases are obvious and others not so much. One of the earliest examples is being able to pin-point the current location on a map, for example to show points of interest like coffee shops around the current location, or show the transit data for the nearest bus stop. Another popular example is continuous location updates for driving directions or capturing walking or bike trails as part of fitness apps. In the future this will be extended to indoor location and for example being able to get walking directions to a specific shop inside a large shopping center, including hints to take escalators down or up various levels.

Another not quite so obvious use-case is taking photos and automatically recording the position in the photos metadata. Or a service to "find my device" - either when a user lost it or fears it has been stolen. Maybe a user is also willing to share his or her location with a trusted group of people, for example as a parent I might want to be able to tell the location of my kids phones. Or whenever I'm near a friend of mine, I'd like to be alerted so we don't miss each other. These cases certainly aren't for everyone and require strong and explicit user consent or consensus in the family.

Even more recent examples are what's technically called "geo-fencing" and the use of Bluetooth low energy beacons. These allow the user or apps on the users behalf to take some action when the user leaves or arrives at a certain area. A common example is being reminded to call someone or a reminder to go shopping once you leave work. If the user opts-in this might also be used to show interesting offers or ads when the user is near a favorite coffee shop or next to a specific section inside a store, or interact with a museum exhibit once the user gets close to it. A largely unexplored field is various sorts of augmented reality games, where players have to move around in the real world, but the real world is overlaid with game mechanics.

In addition to those user level use-cases there's also at least one technical use-case most people are unaware of. Using a satellite based sensor like the GPS completely on its own provides a rather poor experience, as the chip needs up to 10 minutes to provide the first location. If you owned an older standalone GPS navigation system, you might remember the long waiting times on first use. In order to improve this, all modern sensors use some form of assisted GPS, in which other sensors are used to tell the GPS in which general area it is and based on that what satellites it should see. It also uses a faster data link to download information about the exact orbit of satellites. Currently this support is outside the scope of our location service and provided by partners via the mobile "secure user plane location" standard.

Currently we also don't deal with IP address based location or Geo-IP, which is commonly used to either direct website visitors to a regional part of the website or restrict content if distribution rights aren't available for all countries.

### Why Mozilla?

As the use-cases in the previous section should have shown there is tremendous user interest in this. As a result any platform needs to offer the capability to position users. For us this means we need to support these use-cases for the web platform, independent of whether you are running Firefox on top of another operating system (Windows, Linux, Mac OS, Android, etc.) or directly (Firefox OS). In terms of official developer API's the W3C Geolocation working group has defined a geolocation API and is being re-chartered to add new API's for geo-fencing and indoor location. These are developer visible API's, but they don't define how the underlying browser gets the required data or interacts with device sensors or an operating system.

Furthermore it should have become clear that positioning needs an external service component, even for seemingly standalone sensors like GPS. We currently have to either use the underlying operating system services or use commercial partners to provide these service components. There is little competition in the market and we aren't in a good position to influence terms of service on our users behalf, especially in the area of privacy. In addition cost of entry into this specific market is extremely high, as collecting a global data set and keeping it up-to-date requires a lot of resources. As a result there are few commercial companies trying to gain market entry, service costs are high and no open community project emerged that covers the whole world and combines all of the required data types into one consistent experience. We maintain a list of some of the projects we know about and most are practically constrained to certain regions or data types like only cell or only WiFi data.

When we started out to investigate the problem space, we were aiming to create a public data set and not just a public service. Unfortunately over time we discovered more and more legal and privacy problems and we haven't found a solution for those yet.

### Privacy

Privacy is a serious concern while dealing with location data. As part of our location service we have to deal with the privacy concerns of three different actors. The first is the normal end-user of the service, who uses it to determine his or her position. The second is any user who chooses to contribute back data to the service and improve the underlying database for the benefit of all users. The third is the owner of the equipment used as an information source, like cell towers, WiFi access points or Bluetooth beacons.

For another much shorter take on privacy, you can read Gerv's much shorter blog post from late October.

#### Privacy - WiFi interlude

Especially for owners of WiFi access points we have some interesting challenges. The service uses a unique identifier for each WiFi access point in the form of the BSSID. This is a technical identifier which is most often the MAC address of the underlying network interface, but can also be a randomized number for ad-hoc networks. In addition to this technical id WiFi networks also have a human readable name (SSID). You see the name whenever choosing what WiFi to connect to.

The BSSID is a unique device id and never changes. What's worse is that many modern smart phones not only connect to WiFi networks, but also act as WiFi access points of their own, to share their internet connection with your other devices like a laptop or tablet. Using WiFi access points as part of a location service isn't ideal, both for these privacy concerns and due to technical limitations. The existing protocols where never meant for this use-case and thus have many shortcomings. For instance there is no way to distinguish a phone from a stationary access point, while observing it only once. But WiFi access points are the only wildly deployed type of device that can be used and provides a precise enough position for many of the current use-cases. Changes to wireless networking standards take years to agree upon and many more years to be available in a majority of deployed devices. So workarounds based on current standards are the only viable mid-term option.

### Privacy continued

If you haven't followed tech news closely over the years, you might have missed a couple of the early problems and revelations about location services by other companies. Starting in 2010 a variety of news stories, governmental and data privacy agency actions took place. It's valuable to look a bit more closely at the history here and learn from these lessons.

Two good overviews of all these come from CNET in a roundup article from July 14, 2011 and another article from September 1, 2011. There where four interesting cases.

#### Apple and the large cache

Researchers found that iOS devices stored a year long detailed list of all the places the device had been in a local cache file. The concerns where addressed in the end and Apple provided a detailed Q&A on its location data practices. At the end of the article three concrete actions are detailed: 1. Only maintain a location cache for a short period of time. The cache is useful to improve the experience and allow device local look-ups for frequently visited locations like your home or workplace. Android was found to have a similar cache with a much shorter time period. 2. Don't backup this cache to any external device or cloud service. 3. Delete the cache if the user opts-out of using location services (and never maintain it without user consent in the first place).

#### Google, Microsoft and the single WiFi look-up

In June 2011 a CNET article appeared describing how researchers probed Google's location service and where able to lookup smart phones or personal WiFi routers over time and track them. Later in August 2011 a similar CNET article covered Microsoft and an article in Ars Technica specifically covered Microsoft's response. The immediate result were two new restrictions to the services. On one hand greater care was taken to filter out constantly moving WiFi access points, as these were likely smart phones and useless for determining a users position. On the other hand a "you need to know two" restriction was added. The idea here is to only answer service requests, if you can provide information about two nearby WiFi networks. The assumption is that you can only reasonably get two matching data points if you are indeed near those WiFi access points. This should make it considerably harder to do remote tracking of anyone. If you already know where someone is, potentially confirming this result via the service is much less of a problem than tracking the user in the first place.

#### Google street view cars, wiretapping and opt-out

As part of building up a database of street view imagery, Google also collected additional data while driving around. There's an original Google statement from April 2010 and an update from May 2010 in which Google admitted to collecting not only metadata about WiFi access points like everyone else, but also samples of the network traffic of unencrypted WiFi networks.

There's so far been no regulation or statements which would disallow the metadata collection, but the collection of network traffic has seen various legal actions. In the US the court cases over wiretapping charges are still going on, with some details in a recent Wired article from September 2013. In the European Union cases by various data protection agencies have already been resolved, as for example confirmed by a report by the Dutch DPA from 2012.

While the wiretapping charges are unrelated to our location service, the initial concerns have led to the creation of an opt-out approach for owners of WiFi access points. A Google blog post from November 2011 explains their "_nomap" suffix approach. This approach lets any WiFi access point owner signal his intent to avoid tracking. This is done by changing the user visible WiFi name (SSID) and append a "_nomap" string. Changing a user visible name isn't ideal, but unfortunately it's the only user changeable setting in WiFi standards. This approach is similar to efforts like "do not track", which rely on a combination of a user signal and the industry respecting this signal.

Unfortunately there's so far no industry standard for WiFi tracking. A manual opt-out approach was chosen by Microsoft instead. Other competitors have so far not offered any opt-out approach at all.

For our own location service we have chosen to respect the "_nomap" signal. It has the advantage of only requiring a single user action, instead of each user having to track down all possible location services and dealing with lots of companies. Not to mention having to keep track of any new company entering the field. In addition we are still discussing if and how to implement the manual opt-out approach.

#### Apple and the randomized BSSID

There is one case that isn't documented very well and only mentioned in various support forums. With the release of iOS 5 in late 2011 users reported a variety of problems with WiFi connectivity. Some users suggest that Apple actually made at least one intended change and switched its mobile hotspot from using normal infrastructure mode to ad-hoc mode. In infrastructure mode the WiFi is using the underlying MAC address as the BSSID. In ad-hoc mode it sets two bits of the BSSID to mark it as ad-hoc and than generates a random bit sequence for the rest. The device can than regenerate a randomized id once in a while.

If this were true, at first glance it would give a neat solution to the live-long unique id problem. By using ever changing randomized ids, the tracking potential for phones would be limited a lot and reduced to a much shorter time span. Since the BSSID contains two magic bits to mark it as ad-hoc, it would be easy for any location service to exclude these WiFi networks from its databases. Since they are only set on phones or otherwise ad-hoc and moving WiFi networks, it's in the best interest of any location service to filter them out, since they don't provide any value. Independent of whether this story is true or not, both the code deployed on Google's street view cars and our own clients filter out ad-hoc networks.

According to the forum reports, Apple however had to revert this change to satisfy users. The problem that occurred was that most operating systems remember WiFi networks not only by the clear text name, but also by their BSSID. Laptop users who wanted to use their trusted mobile phone hotspot were suddenly constantly presented with a dialog to re-enter the WiFi password, as the operating system thought these were new and never seen before devices. This user frustration apparently trumped a privacy win at the time.

It's unclear how much of this story is true. But it highlights one possible avenue for improving privacy of mobile phone owners. Either operating systems could be adjusted to keep remembering WiFi networks independent of their BSSID. Or there could be an acceptable trade-off, where the BSSID would only change every couple of days or weeks. Still narrowing down the tracking window from forever to a much shorter time span.

### Privacy - summary

What most of the historical cases have in common is adding protections which only work in a service model, where access to the underlying data can be restricted or data can be removed from the database. At the start of this project we wanted to make the underlying data source publicly available in as much detail as possible. But the protections around Wifi access points that other companies have found and data privacy agencies have agreed upon, don't work for a public database.

So while we currently don't know of any model to share the WiFi data and protecting privacy, you might argue that the same problem doesn't apply to cell data or other types of data. Unfortunately there's a different group of users whose privacy is a concern here. The users deciding to contribute to the service should be protected as well. As long as there is just one or very few users in any geography, those location samples can rather easily be tied back to individual users, even without Mozilla tagging the data with unique user ids. And we made sure to never store the location data samples with a user id in our current system. We keep our optional leader board system completely separate from the location data.

There's research that convincingly shows that once you add user ids, you only need a very small number of data samples to uniquely identify people. Basically most people always travel the same routes and stay at work and home for long periods of time. Once I know both a home and work address, it's easy enough to match this data with other data sources. Now while we don't add user ids, we aren't clear on whether or not any of the data that is sent, is unique enough to still identify users. This starts with having data about the country and mobile carrier and the user cell standard. Combine that with potential device specific patterns in the reported signal strength or other measures, and there might well be a way to find identifying marks. For instance the first LTE user in any area would be easy to identify, or a laptop or tablet user would likely show different signal strength readings. At this stage we don't know enough to decide this. Once we publish the data there is no way of going back and the data is available for all future people to analyze.

### Final words

I hope this sheds some more light on why we are so extremely cautious and don't have any good answers on questions like: "are you going to release the data" or "what license is the data available under". We set out to improve user privacy as one of our main goals. It might be that this goal can only be achieved by keeping the data private and identify a trusted organization or a trusted group of organizations and companies to watch over this data - assuming we can find an acceptable set of terms that indeed do protect users. Other sources of concerns are changing legal requirements, which might get us into trouble for hosting this data. And there is a real problem of brand and trust damage that would hinder our mission, if Mozilla is suddenly a company that allowed someone to track other users and the potential harm that can result from it.

I could go on about the technical difficulties on extracting on processing this data or the challenge of creating a global data set. But I'll leave those for another time.

If you want to correct me on any of the statements in this blog post, please leave a comment. If you want to engage with us, we'd love to hear from you on IRC or our mailing list.

Hanno

### Planet Mozilla — Mentor Community Call December 5th

Yesterday, we had another Webmaker Mentor Community call, and it was a great one. WARNING: this post has too many GIFs. [caption id="attachment_2057" align="aligncenter" width="500"] Atul puts on a hat. Doug's head will never be cold again. Santiago crashes into his couch. Heather and I share fur hoodies. Michelle can't see her monitor. Every one else smiles at how ridiculous we all are.[/caption] As per usual, we kicked things off with some silent ether padding. The first prompt, stolen at the funeral of the Webmaker Community call, was a collection of interesting stuff people have seen on the web lately. Here are a few, check out the pad for more!

### Reflection on 2013

[caption id="" align="alignnone" width="380"] Reflections are great, I'm not sure why cats are always fighting them...[/caption] Next we wrote about what 2013 had brought us, our top experiences, learnings, etc. The biggest joys for many on the call were Training Days, the Teach the Web MOOC and MozFest. Other folks liked trying out some of our activities for the first time, hanging out on HOMAGO and seeing their own coding progress.

### Vision for 2014

[caption id="" align="alignnone" width="245"] Why do all the X-Men have creepy eyes?[/caption] After spending some time reflecting, we silent ether padded and then talked about what we’re excited about coming up in 2014. We talked about the biggest opportunities to teach the web and how each of us wants to grow, personally and as a community. Here are just a few:
• Next year libraries from Stockholm to Thessaloniki to NYC will be bustling
• Women in Asia are going to have the chance to attend Mozilla’s Sweet 16 birthday party
• Youth will become curriculum developers for other youth
• Engineering activities will be documented with Thimble makes
• #Teachtheweb will be coming to the School of Education at an unspecified university in Pittsburg
• Seniors in Vancouver will get creative as amazing mentors reach out to help folks overcome their fears of new technologies
There are more aspirations in the Etherpad, suffice to say – this community is rad.

### Welcome!

[caption id="" align="alignnone" width="480"] I mean, if that pops up on a Giphy search, you have to use it, right?[/caption] During the Vision silent ether padding, we realized that we had forgotten to say hi to the folks on the call that were experiencing it for the first time. So we took a few minutes to say hi to Åke, Heather, and Thomas. Åke is looking to introduce Mozilla to libraries in Sweden and is working on a Teaching Kit to help him do so, Heather is working to teachtheweb to future teachers, and Thomas was looking into helping his daughter, a senior in high school, level up her web skills. So excited you all are here!

### Blocker in 2014

There’s only 1: Fear. Fear from parents, admins, teachers that the Web is dangerous. This one pops up quite frequently when you’re working “out there” in the real world. People don’t understand openness or the Web, that’s why we have to continue to evangelize, #teachtheweb and change hearts and minds – sometimes one at a time.

### Other Ideas

People are hoping that our tutorial feature levels up and that we make even more interactive videos with Popcorn. A couple other folks are hoping that in 2014 we find capacity to make more advanced levels of curriculum (e.g. For more advanced webmakers).

### Webmaker School Club

A longstanding (and amazing) community member, Emma Irwin ran some hack jams during the 2011 Summer of Code. She got great response, but it was really hard to recruit kids. She felt she would have a bigger effect if she worked with schools, so she submitted a proposal and was instantly turned down. But she didn’t give up, she kept pushing for her idea. Now Emma is teaching 28 kids for a short class two days a week. She’s building curriculum, teaching kids about Privacy and Security and making, making, making. Check out this amazing project and follow how her classes are doing.

### Hour of Code

Next week is Computer Science Education Week’s Hour of Code, so we talked about this too. You can read all about how we’ll participate, and get involved here.

### Helsinki Learning Festival

It’s always great to end up at the same events and spread the Mozilla love as a community, so I mentioned that next year, Mozilla will be attending the Helsinki Learning Festival. It’s in April, and I figured the earlier people know about it, the easier it is to plan. If you’re wanting to go, let me know - we can hack on proposals or at least #teachtheweb together!

### Webmaker Working Groups

In the new year, the Webmaker team will be setting up some standing, cross-team working groups whose leadership will help refresh and manage the continued health of key Webmaker features, starting with templates and galleries. Community members who want to contribute will play an essential behind-the-scenes role to help tackle some of Webmaker's most  interesting design challenges. More info, and signup here.

### Mentor Calls and the Future!

We love this call, and we want to make it better for everyone. Take 10 seconds (that’s all it takes, really) and give us a little feedback on the Community Call YOU want. See you on Dec. 19th, and by the way, we’ll likely have these awesome calls more often in the new year.

### Planet Mozilla — Automation Development report – week 47/48 2013

This is again an overview about the highlights of our work in week 47 and 48 this year. Sorry for the delay of a couple of days but some critical work was holding me off from writing this post.

### Highlights

Henrik and Dave were working on a couple of Mozmill-CI updates, which have been pushed to production. The first batch of features and bug fixes landed in week 47. It included the monitoring plugin for Jenkins, which hopefully will help us to figure out the reasons of Java crashes. Also we can finally run project branches via our CI now, even it can only be done manually as of now. It is important for our upcoming tests for the Holly branch (Firefox Nightly without the Australis feature). The second batch landed by last week was intended to upgrade our system to Mozmill 2.0.1. Sadly we failed in it due to a couple of other failures, which we haven’t seen before on our staging server. So we partly reverted back the latest commits for production and we all are working hard on getting those issues fixed.

With the detected failures by upgrading to Mozmill 2.0.1, Henrik has noticed that one of those existed because of an incompatibility of mozbase with Python 2.6. See bug 944361 for details. To solve this we upgraded our OS X 10.6 boxes to Python 2.7.3, so all machines are running the same version of Python now. As a very nice side-effect we noticed a speed improvement by running our Mozmill tests of about 25%!

Henrik pushed a couple of releases to pypi, which include mozprofile 0.17 with a lot of add-on manager related bug fixes, mozdownload 1.10 (see details), and mozmill 2.0.1 (see details)

To be prepared for executing the first Metro tests with Mozmill we had to prepare the mozmill-tests repository for handling multiple applications. Therefore Andreea refactored nearly the whole repository. You can find details on bug 927397.

### Meeting Details

If you are interested in further details and discussions you might also want to have a look at the meeting agenda and notes from the last two Automation Development meetings of week 47 and week 48.

### Planet Mozilla — Firefox OS DevTreff Vienna

Last month, I was contacted within a few days by a local "open mobile devices" enthusiast, a Mozilla events manager and a fellow German-speaking Mozilla Rep, all of them pointing to an event here in Vienna called Firefox OS DevTreff Austria.

While the local just asked me if I'd go there, the Mozilla contacts had been asked by the organizers for a speaker to open up the event. We were trying to get someone more used to talking about Firefox OS, but everyone's busy this time of year, so in the end we settled with me doing this keynote.

Now, I have been giving presentations on different occasions and events in the last years, but I never have actually keynoted anything, so that made me somewhat nervous. The other talks that were lined up for the evening were about app development, to some part about very concrete pieces of it, so I figured I should give that some frame and introduce people to Firefox OS, starting with why we are doing it, moving to what and where it is and giving a bit of glance onto where we want to take it. So I came up with "Firefox OS: Reasons, Status & Plans" as the title (my slides are behind the link).

The audience was supposed to be about 50 people, I guess 30-35 really showed up (the pictures, taken "in style" with Firefox OS on my Peak, only show one part of the room), but those were an awesome bunch. They were really into the topic, asked interesting questions, and the talks following me were showing that we really had capable developers in the room, from those that do JS in their free time to those who earn their bread and butter by doing apps.
We also had two Mozillians, both of which I had not met in person before, even though I spent a lot of time in this city in the last decade!

As the event was going on, I was often the voice in the room who would have answers from the Mozilla side or could explain our point of view and initiatives - and in quite a few cases, I could loop back to something I said in my keynote. It was really great to see how apparently I had touched exactly on the right things there and gave everything else a good base to build on. Interestingly, there was quite a bit of interest in the DeviceStorage API, probably because accessing local files is something people can refer better to than storing items in-app. I was thankful someone did a talk on our Marketplace and in-app payment API/Services as that's one area I'm actually weak in, but it also sparked quite a bit of interest. The permission model did also get a few questions.

We surely had people with Firefox OS app experience in there, but I think more of those people might pick up web app development, esp. if more similar events come around, which would be cool. And maybe someone should tell them how to do simple apps without larger libraries or frameworks, and explain app manifests in more detail. I hope they will organize more of those and the chance for that will come along!

### Planet Mozilla — Why NOT to sync iOS apps to iCloud: Ability to revert updates

When I recently updated to Checkie for Foursquare v2.5 on my iPod 5 Touch, it started crashing on launch. Tried restarting my iPod to no avail. So I reverted it to the previous version by doing the following:

1. delete Checkie App on my iPod (touch-hold Checkie icon, wiggly icons, touch (x) on the Checkie icon, confirm delete dialog box)
2. connect iPod to MacBook Air
3. open iTunes
4. select iPod in left column
5. choose the "Apps" tab
6. scroll to "Checkie for Foursquare" - note it is [ ] unchecked
7. check [x] Checkie for Foursquare
8. click "Apply" in the lower right corner of the iTunes window

Presto, the previous version of the app from the last time I sync'd/backed up to iTunes is back on my iPod Touch.

If I had been auto-syncing my apps with iCloud, then all my devices would have updated to the latest version of Checkie and the previous version would either be lost - or a huge hassle to retrieve from a previous backup (if iTunes even kept more than one backup of it).

If you're syncing directly with iTunes on your laptop, you can revert to the previous version there. You may even be able to revert to even older versions, see this blog post with lots of screenshots for details.

iOS native app developers seem to screw up apps in plenty of ways frequently enough that it's perfectly reasonable to take matters into your own hands as the user and revert such apps when developers screw up.

How do native app developers screw up? Let me count the ways:

1. update crashes on launch
2. removal of a feature essential to usability or you really liked
3. making an existing feature take more steps
4. addition of visual noise (design cheese, 1+1=3, chartjunk etc.)
5. less efficient use of screen space

None of these are theoretical. All of these have happened. The first with Checkie, and unfortunately all of 2-5 have happened with the Foursquare app.

Everybody makes mistakes of course. We're not trying to build the perfect system.

When software screws up, we should empower users with the agency to work around it. #fightfortheusers

### Planet Mozilla — WebRTC And People-Oriented Communications

Tantek had an interesting blog post about making people rather than protocols the organizing principle of communication apps. I like his vision quite a lot. One neat extension of his post would be to introduce WebRTC. With WebRTC it would be relatively easy to have the "Robert O'Callahan" app check if I'm currently logged into the appropriate receiver app, at any WebRTC-capable endpoint, and if I am, establish a voice or voice+video session with me (with peer-to-peer transmission, naturally). If I'm not logged in, WebRTC lets you record a message for later delivery. This would be very cool.

## December 05, 2013

### Planet Mozilla — Decomposition of 2D-transform matrices

−⁡π

Note: some parts of this blog post (especially the Javascript program) may be lost when exported to Planet or other feed aggregators. Please view it on the original page.

I recently took a look at the description of the CSS 2D / SVG transform `matrix(a, b, c, d, e, f)` on MDN and I added a concrete example showing the effect of such a transform on an SVG line, in order to make this clearer for people who are not familiar with affine transformations or matrices.

This also recalled me a small algorithm to decompose an arbitrary SVG transform into a composition of basic transforms (Scale, Rotate, Translate and Skew) that I wrote 5 years ago for the Amaya SVG editor. I translated it into Javascript and I make it available here. Feel free to copy it on MDN or anywhere else. The convention used to represent transforms as 3-by-3 matrices is the one of the SVG specification.

### Live demo

Enter the CSS 2D transform you want to reduce and decompose or pick one example from the list . You can also choose between LU-like or QR-like decomposition: .

CSS

Here is the reduced CSS/SVG matrix as computed by your rendering engine ? and its matrix representation:

After simplification (and modulo rounding errors), an SVG decomposition into simple transformations is ? and it renders like this:

After simplification (and modulo rounding errors), a CSS decomposition into simple transformations is ? and it renders like this:

CSS

A matrix decomposition of the original transform is:

### Mathematical Description

The decomposition algorithm is based on the classical LU and QR decompositions. First remember the SVG specification: the transform `matrix(a,b,c,d,e,f)` is represented by the matrix

$\left(\begin{array}{ccc}a& c& e\\ b& d& f\\ 0& 0& 1\end{array}\right)$

and corresponds to the affine transformation

$\left(\begin{array}{c}x\\ y\end{array}\right)&map\left(\begin{array}{cc}a& c\\ b& d\end{array}\right)\left(\begin{array}{c}x\\ y\end{array}\right)+\left(\begin{array}{c}e\\ f\end{array}\right)$

which shows the classical factorization into a composition of a linear transformation $\left(\begin{array}{cc}a& c\\ b& d\end{array}\right)$ and a translation $\left(\begin{array}{c}e\\ f\end{array}\right)$. Now let's focus on the matrix $\left(\begin{array}{cc}a& c\\ b& d\end{array}\right)$ and denote $\Delta =ad-bc$ its determinant. We first consider the LDU decomposition. If $a\ne 0$, we can use it as a pivot and apply one step of Gaussian's elimination:

$\left(\begin{array}{cc}1& 0\\ -b/a& 1\end{array}\right)\left(\begin{array}{cc}a& c\\ b& d\end{array}\right)=\left(\begin{array}{cc}a& c\\ 0& \Delta /a\end{array}\right)$

and thus the LDU decomposition is

$\left(\begin{array}{cc}a& c\\ b& d\end{array}\right)=\left(\begin{array}{cc}1& 0\\ b/a& 1\end{array}\right)\left(\begin{array}{cc}a& 0\\ 0& \Delta /a\end{array}\right)\left(\begin{array}{cc}1& c/a\\ 0& 1\end{array}\right)$

Hence if $a\ne 0$, the transform `matrix(a,b,c,d,e,f)` can be written `translate(e,f) skewY(atan(b/a)) scale(a, Δ/a) skewX(c/a)`. If $a=0$ and $b\ne 0$ then we have $\Delta =-cb$ and we can write (this is approximately "LU with full pivoting"):

$\left(\begin{array}{cc}0& c\\ b& d\end{array}\right)=\left(\begin{array}{cc}0& -1\\ 1& 0\end{array}\right)\left(\begin{array}{cc}b& d\\ 0& -c\end{array}\right)=\left(\begin{array}{cc}\mathrm{cos}\left(\pi /2\right)& -\mathrm{sin}\left(\pi /2\right)\\ \mathrm{sin}\left(\pi /2\right)& \mathrm{cos}\left(\pi /2\right)\end{array}\right)\left(\begin{array}{cc}b& 0\\ 0& \Delta /b\end{array}\right)\left(\begin{array}{cc}1& d/b\\ 0& 1\end{array}\right)$

and so the transform becomes `translate(e,f) rotate(90°) scale(b, Δ/b) skewX(d/b)`. Finally, if $a=b=0$, then we already have an LU decomposition and we can just write

$\left(\begin{array}{cc}0& c\\ 0& d\end{array}\right)=\left(\begin{array}{cc}c& 0\\ 0& d\end{array}\right)\left(\begin{array}{cc}1& 1\\ 0& 1\end{array}\right)\left(\begin{array}{cc}0& 0\\ 0& 1\end{array}\right)$

and so the transform is `translate(e,f) scale(c, d) skewX(45°) scale(0, 1)`.

As a consequence, we have proved that any transform `matrix(a,b,c,d,e,f)` can be decomposed into a product of simple transforms. However, the decomposition is not always what we want, for example `scale(2) rotate(30°)` will be decomposed into a product that involves `skewX` and `skewY` instead of preserving the nice factors.

We thus consider instead the QR decomposition. If $\Delta \ne 0$, then by applying the Gram–Schmidt process to the columns $\left(\begin{array}{c}a\\ b\end{array}\right),\left(\begin{array}{c}c\\ d\end{array}\right)$ we obtain

$\left(\begin{array}{cc}a& c\\ b& d\end{array}\right)=\left(\begin{array}{cc}a/r& -b/r\\ b/r& a/r\end{array}\right)\left(\begin{array}{cc}r& \left(ac+bd\right)/r\\ 0& \Delta /r\end{array}\right)=\left(\begin{array}{cc}a/r& -b/r\\ b/r& a/r\end{array}\right)\left(\begin{array}{cc}r& 0\\ 0& \Delta /r\end{array}\right)\left(\begin{array}{cc}1& \left(ac+bd\right)/{r}^{2}\\ 0& 1\end{array}\right)$

where $r=\sqrt{{a}^{2}+{b}^{2}}\ne 0$. In that case, the transform becomes ```translate(e,f) rotate(sign(b) * acos(a/r)) scale(r, Δ/r) skewX(atan((a c + b d)/r^2))```. In particular, a similarity transform preserves orthogonality and length ratio and so $ac+bd=\left(\begin{array}{c}a\\ b\end{array}\right)\cdot \left(\begin{array}{c}c\\ d\end{array}\right)=0$ and $\Delta =&DoubleVerticalBar\left(\begin{array}{c}a\\ b\end{array}\right)&DoubleVerticalBar&VerticalBar\left(\begin{array}{c}c\\ d\end{array}\right)&DoubleVerticalBar\mathrm{cos}\left(\pi /2\right)={r}^{2}$. Hence for a similarity transform we get `translate(e,f) rotate(sign(b) * acos(a/r)) scale(r)` as wanted. We also note that it is enough to assume the weaker hypothesis $r\ne 0$ (that is $a\ne 0$ or $b\ne 0$) in the expression above and so the decomposition applies in that case too. Similarly, if we let $s=\sqrt{{c}^{2}+{d}^{2}}$ and instead assume $c\ne 0$ or $d\ne 0$ we get

$\left(\begin{array}{cc}a& c\\ b& d\end{array}\right)=\left(\begin{array}{cc}\mathrm{cos}\left(\pi /2\right)& -\mathrm{sin}\left(\pi /2\right)\\ \mathrm{sin}\left(\pi /2\right)& \mathrm{cos}\left(\pi /2\right)\end{array}\right)\left(\begin{array}{cc}-c/s& d/s\\ -d/s& -c/s\end{array}\right)\left(\begin{array}{cc}\Delta /s& 0\\ 0& s\end{array}\right)\left(\begin{array}{cc}1& 0\\ \left(ac+bd\right)/{s}^{2}& 1\end{array}\right)$

Hence in that case the transform is `translate(e,f) rotate(90° - sign(d) * acos(-c/s)) scale(Delta/s, s) skewY(atan((a c + b d)/s^2))`. Finally if $a=b=c=d=0$, then the transform is just `scale(0,0)`.

The decomposition algorithms are now easy to write. We note that none of them gives the best result in all the cases (compare for example how they factor Rotate2 and Skew1). Also, for completeness we have included the noninvertible transforms in our study (that is $\Delta =0$) but in practice they are not really useful (try NonInvertible).

### Planet Mozilla — Nice site about how different companies onboard users

I saw this tweet last night…

which lead me to this awesome site.

### The full report is available here:http://mzl.la/User_Testing_Report_2013

Executive Summary

The Webmaker.org user experience team conducted user testing at Mozilla Toronto between August 9 and October 1 with 11 users.  The goal: examine the navigation and site architecture, and whether users understood  the concept of remix.  Sessions lasted approximately 1 hour.

Key issues

• The navigation between WebMaker.org and the individual tools is unclear (e.g., no consistent way to return to the homepage)

• The meaning of X-Ray Goggles, Thimble and Popcorn is not intuitive to users

• Publishing and saving is an unclear process for users

• Help is not easily available in Thimble or Popcorn

• Search is confusing for some users.  The filter option on the homepage is sometimes confused for search, and the magnifying glass icon is missed

• Deleting a user account does not result in data being erased from the site (this is being fixed)

### Bugs to review / triage / file as a result of this testing:

Users had problems navigating between the tools and the Webmaker.org homepage.

• Current fix: a logo to link back to Webmaker.org homepage was added to the right side of the interface on Popcorn and Thimble.
• Next step options: Creating a breadcrumb link below the Popcorn/Thimble logos could be more intuitive than having a logo on the far right of the interface.
•   e.g., “Webmaker.org  |  Popcorn “
• Could consider making the Webmaker link dynamic like the Mozilla one it replaces, so that the Webmaker site functions more consistently.

Thimble: Confusion with save/publish
In Thimble the “publish” option appears only after sign in. On Popcorn there is a greyed out save. (Center interface)

• Short term options: Have both Thimble and Popcorn include the “Publish” option (after ‘saving’ in Popcorn, a link is generated and it is effectively published).
• Move the “Publish” options to the same location (center) with consistent greyed out buttons until the user is signed in.
• Long term options: Add a “Save Draft” option to allow users to login to edit their work over multiple sessions before they publish.

Thimble: Lack of help for novice users or those new to the Webmaker.org interface

Options:

• Provide a “tour” option for new users
• Do research on other interface options, such as arrows between code and the rendered website
• Better labelling of makes to direct users to appropriate projects.

Thimble: “Show hints” doesn’t do anything for most users

• Make this more specific (i.e. show HTML tag meanings to produce captions pop-ups on rollover of tags)

Thimble: Lack of colour picker

• Add a colour picker to give users the hex values to type into their code.

• An image uploader in Thimble (similar to in Popcorn) could be useful.
• Creative Commons/Public domain content could be emphasized as an available resource.

Thimble: Lorum ipsum text in starter makes confuses some users

• Avoid using lorum ipsum text in starter makes and edit it out of existing examples

Popcorn: Lack of help for novice users and those new to the interface

• Link to a tutorial or intro video for new users

Popcorn: the “event” tab is not noticed by users (i.e. they can’t easily add text, images or maps)

• Have a layer type selector when users add a layer (i.e., blank, video or text) and dynamically change the tabs on the right of the screen to events if they choose text

Popcorn: Zoom issue.  Sometimes users zoom out too much and can’t find their project anymore.

• Provide a “Fit to timeline” option to automatically scale multimedia for easy editing.

Popcorn: Audio loop issue

• Fix so that audio files can loop not just video

• Allow for a search of Creative Commons licensed materials where available (i.e., Flickr, YouTube)

### Planet Mozilla — Short Update

A short update of a list of things I’ve been doing lately…

### Drones aka multi-rotor copters

I built a tricopter with my Kang’s help (a friend of mine from Mozilla and formerly a teammate on secass). I managed to almost make it fly before I crapped it out. I’m still trying to debug why it likes to flip over instead of fly but, hey, I learned how to assemble a copter from scratch, flash open source firmware on my speed controllers, and find something useful to do with my craptastic soldering skills. It is fun. I also have a hexacopter, which is quite a beast when it flies and the kind of thing that makes you involtunarily take a step back when you turn it on. I’m going to be re-building an old quadcopter when I get the gumption to bother.

### 3D Printers

I’m still working on 3D printers. My Printrbot Jr. has been modified a bit with more to come. For such a cheap little machine, it is a pretty good workhorse. I’ve got at least two other printers (a small Delta style and the foldarap from early this year) partially assembled and waiting to be finished. I don’t really need more than one working printer so the motivation is always a little lacking but I work on them slowly. The process of building printers several times is what finally teached me how the mechanical and electrical parts work. With one of my buddies, Atom, from Ace Monster Toys, there is a plan to do a simple through-hole solder 3D printer controller as an all in one unit but done cheaply for under \$50. That ought to be interesting.

### Bitcoin Mining

While I’ve had friends doing it for a while, on a lark I picked up a couple of ASIC-based bitcoin miners as dedicated hardware a while ago. I managed to get them, along with buying a few bitcoins directly, before the massive recent increase in prices. I look on it as an experiment and one that I don’t take very seriously. “Never gamble money you can’t afford to lose” is a good motto. If I lost everything that I put in, I would call it a lesson learned but so far I’m actually looking to break even on the cost of the gear in about two months (including the costs of power). My main complaint with it so far is that the miners are in my home office because they need decent network connectivity and I also work in there. It is kind of like working next to a pair of hairdryers that you never turn off (on a plus note, I’m not cold). I’ve had to find various places for doing my videoconferencing as the noise can be a bit burdensome. I’m quite interested in where bitcoin may wind up going but I really don’t have any expectations.

### Tabletop Role-Playing Games

The short explanation is always “You remember Dungeons and Dragons? Well, it is like that except we don’t play D&D.” Right now there is a renaissance of independent role-playing games going on (for most of a decade now but really kicked up further by things like kickstarter). I was in an RPG group that met once a month, then twice a month, and now we have a weekly pickup game with people who feel like playing along with two Sundays a month of regular sessions. The weekly games have been used as an opportunity for us to play one or two-off games that are either interesting concept pieces or just intriguing without any kind of commitment to regular play. I and two of the cohort have plotted out an extended scenario/game, using the very simple Lady Blackbird rules as a basis, involving the shift from Pulp Era Heroes (think “The Shadow”) to Golden Age Superheroes (think “Superman”). We’re going to do some design work on this and playtest it with our group before releasing it under some kinf of Creative Commons license.

Beyond all of this, I’m on the board once again of my local hackerspace, the aforementioned Ace Monster Toys, and it continues to thrive. I may also be going to Japan for a week or two in March on matters Buddhist related but nothing has been set in stone as of yet. My work is still focused on being a program manager for security over at Mozilla (though I largely focus on Firefox efforts).

### Planet Mozilla — Book Review – Feedback Control for Computers

If you write code for fun or for a livelihood, I recommend you check out my friend Philipp Janert’s newest book Feedback Control for Computer Systems.

Feedback Control is a topic well known to mechanical engineers, but not so much in our industry. Feedback Control is about making smarter systems that can cope with dynamic environments. Many knobs that we build into configuration can actually be automated with feedback loops.

Examples given early in the book:

• A Cache by tracking hit rate and changing the cache size
• A Server Farm by tracking request latency and changing number of deployed server nodes
• A Queueing System by tracking wait time and changing the number of workers
• A Graphics Library by tracking memory consumption and changing the output resolution

The book is well written. It starts out with practical examples and working code. It later introduces the deep theory and drops some math bombs. Don’t worry, there is Python code for everything and you don’t have to understand the math.
It gives solid advice, like don’t blindly use Feedback Control for optimization; optimization needs a higher level strategy guiding the process.

Lastly, there are references for further reading, if you do want to work through more of the theory.

It also sets realistic expectations. You’ll control one metric by changing one variable. This is no silver bullet.

The term Enterprise is thrown about, don’t let this scare you away This is a valuable book for many types of software problems. A couple I’ve brainstormed of:

• Controlling difficulty of a video game, to react to how skilled a player is
• Controlling aspects of an animation
• Controlling polling of APIs for fresh data
• Driving load testing to find different scaling points (errors, high latency, etc)

I haven’t had much test to put these ideas into practice… so you’re don’t throw too many tomatoes at these wacky ideas.

Update:

• There is also a Blog series on the topic
• Let’s port the Python examples to JavaScript including a JS port of Gnuplot

### Planet Mozilla — Toward A People Focused Mobile Communication Experience

Focus-enhancing note: all in-line hyperlink citations[number] are listed in the References footer of this post. You may procrastinate clicking them until the end for a more in-flow reading experience.

#### Smart and dumber

Remember when phones were dumb and people were smart?

While smart phones become smarter, their push notification interruptions fuel a mobile dopamine[1] addiction[2] that's making us dumber[3].

#### App focus and notification distractions

These devices and their app store interfaces have also trained us to install, organize, and curate ever more mobile "apps" on our home screens. Thanks to designers' obsession over attention, retention, returning eye-balls, and need to compete with all those other apps, they ever more aggressively demand our attention.

Their push notifications insist that they're more important than anything else we could possibly be doing. We miss things right in front of us, or we overreact, overmute, and miss important things. Not things. People.

Virtual notifications distract us from real people.

This is a broader systemic design problem beyond smart phones: Hospitals look to reduce danger of 'alarm fatigue'[4].

Take a moment to recover your focus after skimming or bookmarking those links.

#### App centric interfaces cause dopamine fueled distraction

Right now we have screenfuls of apps to communicate and interact with people online. Screenfuls like:

The problems with this current state of the mobile interface:

1. Person A wants to communicate with person B
2. Person A has to pick (absent B's context!) a communication app
3. Person A launches the specific app
4. The app immediately shows Person A:
• Missed calls from others!
• Unread count of new messages!
• Actual new messages from others!

Every one of those exclamation points (!) is a dopamine squirt (you probably got a little one even just reading about it happening).

Consequence: Person A is distracted by the missed calls, unread counts, new messages beckoning their attention - ooh someone reached out to me! I better check if that's important before I communicate with, who was it I was going to communicate with?

Worse yet: the dopamine reinforces this distraction based behavior, turning it into a habit of reacting and losing our context, rather than acting and keeping our flow.

#### What if we focused on people first?

What if our mobile devices focused on people first and apps second?

Remember when they used to? When you looked up a person first, and decided to txt, call, or email them second?

What if we put people first in our mobile interfaces, before choosing an app to interact?

Could we grow a culture of adding icons of each other to our home screens instead of application intermediaries?

What if we organized screenfuls of icons of people that matter to us rather than apps that distract us?

If we could organize screenfuls of icons of people, what would it look like?

An interface with a bunch of faces[5] certainly feels a lot more human.

#### How do we organize screenfuls of icons of people?

The above is an actual screenshot. The answer, today, is to go to their personal sites, tap the action icon (or choose add bookmark), and then "Add to Home Screen".

Yes, this is why you should make sure your personal site has an icon of you that people can add to their home screen.

<aside>

#### Want a personal site?

Don't have a personal site and want one? Go to the Homebrew Website Club Meeting tonight[6] (in SF or PDX) and ask for help setting one up! Or join #indiewebcamp on Freenode and start asking questions!

</aside>

#### Why would someone want an icon of you on their home screen?

In short, human-focused rather than app-focused communication.

• You want to catch up on someone's site (recent writings, activities) just before meeting up with them in person.
• You miss someone and are wondering what they're up to.
• Communicating with a person - person first, method second:
• callee-preferred comm apps icon UI
• What if you provided icons for each of those yourself as if they were apps, e.g. in a pane on your home page?
• Like a Contact folder that when tapped would open up a row of icons of the ways you could be contacted, maybe even in your order of preference!

Would it be too disruptive to the mobile experience and ecosystem to focus on people rather than apps?

#### User experience flow

How would a person use this?

• Go to someone's domain, e.g. tap their icon from home screen
• See their personal home page which with methods of contact as a list or icons in the order that they prefer to be contacted.
• Go across and down that list until you see something you can (and want) to use to communicate, and tap/click it.
• The browser takes you to a website or "native" app to open the communication channel / new message.

Thus after tapping the person you want to communicate with, just one more tap to open a new IM, email, or audio/video call.

Note that there was no distraction by unread IM/email or new activity counts beckoning your attention away from your desire to communicate with a specific person.

#### UX flow with identification

By identifying yourself to the personal site, the site can provide progressive enhancement of communication options:

• Go to someone's domain, e.g. tap their icon from home screen
• Identify yourself to the site (e.g. with IndieAuth, or perhaps your device/browser automatically detects IndieAuth and identifies you if you've been to the site before)
• Now their personal site provides more (or possibly fewer!) communication options based on who you are.
• Again pick the first method of communication you see that you want to use
• You're again routed to either a website or "native" app to start communicating.

Thus after going to someone's personal site, with one tap you can perhaps SMS Facetime or Skype as well.

#### Context Enabled Presence

Someone's personal site could even do presence detection (some personal sites already show live IM presence status), and show/hide communication options in accordance with their apparent availability. E.g. some combination based on determining if they are:

• Asleep?
• In an area with poor network reception?
• In a meeting (or noisy location)?
• Or otherwise pre-occupied?
• Running or otherwise in motion
• Have IM/Skype client open (for more than 10 minutes)

Then their site could enable/disable various things by either hiding or disabling (dimming or greyscaling) the respective icons for:

• realtime interactive audio/video (AKA "phone" calls)
• IM busy/idle/away/active status

User-friendly privacy: such context-based selection should be seamless enough and yet coarse enough that you cannot necessarily determine from the (un)availability of various methods of communication, what their actual context (asleep, busy, in motion etc.) is.

#### Solving the "Can we talk" problem

Perhaps this is the solution to the "Can we talk?"[7] problem.

Nevermind all this "what should I ..."

Domains (or proxies thereof) work as identity.

Just share domain names when you meet, add their icon to your home screen and you're done.

Or even share Twitter handles (purely as a quicker-easier-to-say discovery mechanism for domain names), add their icon and you're done.

The rest is automatically handled when you tap their icon.

#### How do you make this work on your site?

How do you make this work for when someone taps an icon to your site?

• aim:, mailto:, etc. hyperlinks (add `rel=me` to them)
• platform familiar icons and grid layout (combining elements of adaptive and responsive design)
• IndieAuth support - to allow visitors to identify themselves
• Conditionally show more (or fewer) hyperlinks based on whitelists, i.e. check their identity against a whitelist or two and then provide e.g. sms:, facetime:, skype: (callto:?) links.

Optionally have your site passively (or in response) check your meeting schedule, your Foursquare location, perhaps even native app specific presence (e.g. IM), and cache/show/hide links accordingly.

#### Who has done this?

Nobody so far - this is a user experience brainstorm.

#### Can we do this?

Yes. Some communication protocols are supported in today's mobile operating systems / browsers:

iOS Mobile Safari[8][9]
facetime, mailto, skype, sms, tel
Android[10]
tel
Firefox OS Browser[11]
mailto, sms, tel

I couldn't easily find specific references for protocol support in Android Chrome and Firefox for Android browsers. My guess is that the various mobile browsers likely support more communication protocols than the above (and the reference documents) claim. It's probably worth some testing to expand the above lists.

Even maps.apple.com/?q= links are supported on iOS[8] (and "geo:" links on Android[10]) as a way to launch the native maps app - perhaps a person could for some identified visitors have a geo/maplink that showed exactly (or roughly) where the person was if and when they chose to.

There's a whole wiki page of URL protocols supported on iOS and iOS apps[12] and here's a blog post providing clickable examples of Special links: phone calls, sms, e-mails, iPhone and Android apps,...[13] (ht: Ryan Barrett for both). Both are quite useful, especially for instant messaging / telephony protocols. However keep in mind that it may be better to use mobile web app URLs where possible instead of app-specific protocols, e.g.:

Because the mobile web URL is more robust, platform/device independent, and never mind that the twitter: protocol[12] lacks a way to open messages (or a new message) to a specific person.

In addition, I feel I can better depend on DNS to go to twitter.com as intended, whereas it seems like it could be easier for a malevolent native app to hijack "twitter:" URLs by claiming to handle them.

#### What next?

Next, it's time to try prototyping this on our personal sites and mobile devices to see if we can make it work and how the interaction feels.

If this kind of out-of-the-app-box thinking and personal site focused hackery appeals to you, try it out yourself, and come on by tonight's Homebrew Website Club meeting and show what you got working!

#### Previously

Previous posts and notes related to focus (distraction) and specifically to human interface design and processes to improve (reduce) respectively.

#### References

In order of appearance:

2. <time class="dt-published">2013-08-27</time> Computerworld: Nerd, interrupted: Inside a smartphone addiction treatment center
4. <time class="dt-published">2013-10-23</time> SFGate: Hospitals look to reduce danger of 'alarm fatigue'
5. <time class="dt-published">2013-12-02</time> IndieWebCamp: icon FAQ: Should you use a photo of your face
6. <time class="dt-accessed">2013-12-04</time> Event Homebrew Website Club Meeting
7. <time class="dt-published">2013-11-18</time> WIRED: Can We Talk?
8. <time class="dt-accessed">2013-12-04</time> accessed: Apple: Apple URL Scheme Reference
9. <time class="dt-published">2010-11-18</time> Max Firtman: How to create click-to-call links for mobile browsers
10. <time class="dt-accessed">2013-12-04</time> accessed: Google: Intents List: Invoking Google Applications on Android Devices
11. <time class="dt-accessed">2013-12-04</time> accessed: Mozilla: Bug 805282 - MailtoProtocolHandler.js, SmsProtocolHandler.js and TelProtocolHandler.js in package-manifest.in
12. <time class="dt-accessed">2013-12-05</time> accessed: Akosma Software: wiki page of URL protocols supported on iOS and iOS apps
13. <time class="dt-published">2010-01-15</time> Adrian Ber: Special links: phone calls, sms, e-mails, iPhone and Android apps, …

#### Translations

1. <time class="dt-published">2013-12-06</time> Robert O'Callahan: WebRTC And People-Oriented Communications

### Planet Mozilla — Multiprocess Firefox

Since this January, David Anderson and I have been working on making Firefox use multiple processes. Tom Schuster (evilpie on IRC) joined us as an intern this summer, and Felipe Gomes, Mark Hammond and other have made great contributions. Now we’re interested to hear what people think of the work so far.

Firefox has always used a single process. When Chrome was released, it used one UI process and separate “content” processes to host web content. Other browsers have adopted similar strategies since then. (Correction: Apparently IE 8 used multiple processes 6 months before Chrome was released.) Around that time, Mozilla launched a far-reaching effort, called Electrolysis, to rewrite Firefox and the Gecko engine to use multiple processes. Much of this work bore fruit. Firefox OS relies heavily on the multiprocessing and IPC code introduced during Electrolysis. However, the main effort of porting the desktop Firefox browser to use multiple processes was put on hold in November 2011 so that shorter-term work to increase responsiveness could proceed more quickly. A good summary of that decision is in this thread.

This blog entry covers some of the technical issues involved in multiprocess Firefox. More information is available on the project wiki page, which includes links to tracking bugs and mailing lists. Tom Schuster’s internship talk gives a great overview of his work.

### Why are we doing this?

There are a couple reasons for using multiple processes.

Performance. Most performance work at Mozilla over the last two years has focused on responsiveness of the browser. The goal is to reduce “jank”—those times when the browser seems to briefly freeze when loading a big page, typing in a form, or scrolling. Responsiveness tends to matter a lot more than throughput on the web today. Much of this work has been done as part of the Snappy project. The main focuses have been:

• Moving long-running actions to a separate thread so that the main thread can continue to respond to the user.
• Doing I/O asynchronously or on other threads so that the main thread isn’t blocked waiting for the disk.
• Breaking long-running code into shorter pieces and running the event loop in between. Incremental garbage collection is an example of this.

Much of the low-hanging fruit in these areas has already been picked. The remaining issues are difficult to fix. For example, JavaScript execution and layout happen on the main thread, and they block the event loop. Running these components on a separate thread is difficult because they access data, like the DOM, that are not thread-safe. As an alternative, we’ve considered allowing the event loop to run in the middle of JavaScript execution, but doing so would break a lot of assumptions made by other parts of Firefox (not to mention add-ons).

Running web content in a separate process is a nice alternative to these approaches. Like the threaded approach, Firefox is able to run its event loop while JavaScript and layout are running in a content process. But unlike threading, the UI code has no access to content DOM or or other content data structures, so there is no need for locking or thread-safety. The downside, of course, is that any code in the Firefox UI process that needs to access content data must do so explicitly through message passing.

We feel this tradeoff makes sense for a few reasons:

• It’s not all that common for Firefox code to access content DOM.
• Code that is shared with Firefox OS already uses message passing.
• In the multiprocess model, Firefox code that fails to use message passing to access content will fail in an obvious, consistent way. In the threaded model, code that accesses content without proper locking will fail in subtle ways that are difficult to debug.

The last point is, in my opinion, the most compelling. None of the approaches for improving responsiveness of JavaScript code are easy to implement. The multiprocess approach at least has the advantage that errors are reproducible.

Security. Right now, if someone discovers an exploitable bug in Firefox, they’re able to take over users’ computers. There are a lot of techniques to mitigate this problem, but one of the most powerful is sandboxing. Technically, sandboxing doesn’t require multiple processes. However, a sandbox that covered the current (single) Firefox process wouldn’t be very useful. Sandboxes are only able to prevent processes from performing actions that a well-behaved process would never do. Unfortunately, a well-behaved Firefox process (especially one with add-ons installed) needs access to much of the network and file system. Consequently, a sandbox for single-process Firefox couldn’t restrict much.

In multiprocess Firefox, content processes will be sandboxed. A well-behaved content process won’t access the filesystem directly; it will have to ask the main process to perform the request. At that time, the main process can verify that the request is safe and that it makes sense. Consequently, the sandbox for content processes can be quite restrictive. Our hope is that this arrangement will make it much harder to craft exploitable security holes for Firefox.

Stability. Although Firefox usually doesn’t crash very often, multiple processes will make crashes much less annoying. Rather than killing the entire browser, the crash will only take down the content process that crashed.

### Trying it out

We’ve been doing all of our development on mozilla-central, which means that all of our code is available in Firefox nightlies. You can try out multiprocess Firefox with the following steps:

• Update to a current nightly.
• We strongly recommend you create a new profile!
• Set the browser.tabs.remote preference to true.
• Restart Firefox.

Here’s what Firefox looks like in multiprocess mode. Notice that the title of the tab is underlined. This means that the content for the tab is being rendered in a separate process.

This screenshot shows what happens when a content process crashes. The main Firefox process remains alive, along with any tabs being rendered in other processes.

### What works?

The best way to find out is to try it! All basic browsing functionality should work at this time. In particular: back and forward navigation, the URL bar and search bar, the context menu, bookmarks, tabs, Flash (except on Macs), the findbar, and even Adblock Plus. Some less-used features are still missing: developer tools, printing, and saving pages to disk. Add-on support is pretty spotty—some add-ons work, but most don’t.

To be conservative, we’re using only one content process for all web content. To get all of the performance, security, and stability benefits of multiple processes, we’ll need to use multiple content processes.

### When will it be released?

We simply don’t know. It’s a large project and any predictions at this point would be foolhardy. There are a lot of concerns about compatibility with add-ons and plugins that will need to be settled before we have any sense of a release date.

### How much memory will it use?

Many people who hear about the project are concerned that multiple processes will cause the memory usage of Firefox to balloon. There’s a fairly widespread belief that more processes will require a lot more memory. I don’t believe this will be the case though.

The actual overhead of an empty process is very small. A normal desktop system can easily support thousands of processes. Even when all the code for Firefox is loaded into each process, this memory is shared, so not much more memory is used than in the single-process case.

Using multiple processes does take more memory if data that could be shared between tabs in a single process must be duplicated in a multiprocess browser. There are many different caches and other shared data structures in Firefox where this might be a problem. We have plans to mitigate these issues. For example, it should be possible for processes to store some of this data in read-only shared memory. A process would be able to observe that it is holding local data that is identical to some data already stored in the read-only cache. In that case, it would drop its own copy of the data and use the shared version instead. Periodically, processes could add new data to the cache and mark it read-only. Processes would want to avoid sharing data that might include sensitive information like credit card numbers or bank data. However, it would probably be safe to share image data, JavaScript scripts, and the like.

Admittedly, it will take some time to optimize the memory usage of multiprocess Firefox. We already have `about:memory` working for multiple processes, which should make the work go more quickly. Nevertheless, until we feel that multiprocess Firefox is competitive with the single-process version, we will probably use a single content process to render all tabs. That model brings most of the security benefits and some of the performance and stability advantages we’re seeking. It also takes only a small amount more memory than single-process Firefox. I’ve taken some simple measurements using `about:memory` and Gregor Wagner’s MemBench benchmark. The benchmark opens 50 tabs and then measures memory usage.

 Memory usage Single-process Multiprocess UI process 974 MB 124 MB Content process 860 MB Total 974 MB 984 MB

The total memory usage for multiprocess Firefox is only 10MB greater than single-process Firefox. We should be able to shrink this difference with some effort.

### How will it work?

At a very high level, multiprocess Firefox works as follows. The process that starts up when Firefox launches is called the parent process. Initially, this process works similarly to single-process Firefox: it opens a window displaying `browser.xul`, which contains all the principal UI elements for Firefox. Firefox has a flexible GUI toolkit called XUL that allows GUI elements to be declared and laid out declaratively, similar to web content. Just like web content, the Firefox UI has a `window` object, which has a `document` property, and this document contains all the XML elements from `browser.xul`. All the Firefox menus, toolbars, sidebars, and tabs are XML elements in this document. Each tab element contains a `<browser>` element to display web content.

The first place where multiprocess Firefox diverges from single-process Firefox is that each `<browser>` element has a `remote="true"` attribute. When such a browser element is added to the document, a new content process is started. This process is called a child process. An IPC channel is created that links the parent and child processes. Initially, the child displays `about:blank`, but the parent can send the child a command to navigate elsewhere.

In the remainder of this section, I will discuss the most important aspects of multiprocess Firefox.

Drawing. Somehow, displayed web content needs to get from the child process to the parent and then to the screen. Multiprocess Firefox depends on a new Firefox feature called off main thread compositing (OMTC). In brief, each Firefox window is broken into a series of layers, somewhat similar to layers in Photoshop. Each time Firefox draws, these layers are submitted to a compositor thread that clips and translates the layers and combines them together into a single image that is then drawn.

Layers are structured as a tree. The root layer of the tree is responsible for the entire Firefox window. This layer contains other layers, some of which are responsible for drawing the menus and tabs. One subtree displays all the web content. Web content itself may be broken into multiple layers, but they’re all rooted at a single “content” layer.

In multiprocess Firefox, the content layer subtree is actually a shim. Most of the time, it contains a placeholder node that simply keeps a reference to the IPC link with the child process. The content process retains the actual layer tree for web content. It builds and draws to this layer tree. When it’s done, it sends the structure of its layer tree to the parent process via IPC. Backing buffers are shared with the parent either through shared memory or GPU memory. References to this memory are sent as part of the layer tree. When the parent receives the layer tree, it removes its placeholder content node and replaces it with the actual tree from content. Then it composites and draws as normal. When it’s done, it puts the placeholder back.

The basic architecture of how OMTC works with multiple processes has existed for some time, since it is needed for Firefox OS. However, Matt Woodrow and David Anderson have done a lot of work to get everything working properly on Windows, Mac, and Linux. One of the big challenges for multiprocess Firefox will be getting OMTC enabled on all platforms. Right now, only Macs use it by default.

User input. Events in Firefox work the same way as they do on the web. Namely, there is a DOM tree for the entire window, and events are threaded through this tree in capture and bubbling phases. Imagine that the user clicks on a button on a web page. In single-process Firefox, the root DOM node of the Firefox window gets the first chance to process the event. Then, nodes lower down in the DOM tree get a chance. The event handling proceeds down through to the XUL `<browser>` element. At this point, nodes in the web page’s DOM tree are given a chance to handle the event, all the way down to the button. The bubble phase follows, running in the opposite order, all the way back up to the root node of the Firefox window.

With multiple processes, event handling works the same way until the `<browser>` element is hit. At that point, if the event hasn’t been handled yet, it gets sent to the child process by IPC, where handling starts at the root of the content DOM tree. There are still some problems with how this works. Ideally, the parent process would wait to run its bubbling phase until the content process had finished handling the event. Right now, though, the two happen simultaneously, which can cause problems if the content process called `stopPropagation()` on the event. Bug 862519 covers this problem. The usual manifestation is that hitting a key combination like Cmd-Left on a Mac will go back even if a textbox is in focus.

Inter-process communication. All IPC happens using the Chromium IPC libraries. Each child process has its own separate IPC link with the parent. Children cannot communicate directly with each other. To prevent deadlocks and to ensure responsiveness, the parent process is not allowed to sit around waiting for messages from the child. However, the child is allowed to block on messages from the parent.

Rather than directly sending packets of data over IPC as one might expect, we use code generation to make the process much nicer. The IPC protocol is defined in IPDL, which sort of stands for “inter-* protocol definition language”. A typical IPDL file is `PNecko.ipdl`. It defines a set messages and their parameters. Parameters are serialized and included in the message. To send a message `M`, C++ code just needs to call the method `SendM`. To receive the message, it implements the method `RecvM`.

IPDL is used in all the low-level C++ parts of Gecko where IPC is required. In many cases, IPC is just used to forward actions from the child to the parent. This is a common pattern in Gecko:

```void AddHistoryEntry(param) {
if (XRE_GetProcessType() == GeckoProcessType_Content) {
// If we're in the child, ask the parent to do this for us.
return;
}

// Actually add the history entry...
}

// Got a message from the child. Do the work for it.
return true;
}
```

When `AddHistoryEntry` is called in the child, we detect that we’re inside the child process and send an IPC message to the parent. When the parent receives that message, it calls `AddHistoryEntry` on its side.

For a more realistic illustration, consider the Places database, which stores visited URLs for populating the awesome bar. Whenever the user visits a URL in the content process, we call this code. Notice the content process check followed by the `SendVisitURI` call and an immediate return. The message is received here; this code just calls `VisitURI` in the parent.

The code for IndexedDB, the places database, and HTTP connections all runs in the parent process, and they all use roughly the same proxying mechanism in the child.

Content scripts. IPDL takes care of passing messages in C++, but much of Firefox is actually written in JavaScript. Instead of using IPDL directly, JavaScript code relies on the message manager to communicate between processes. To use the message manager in JS, you need to get hold of a message manager object. There is a global message manager, message managers for each Firefox window, and message managers for each `<browser>` element. A message manager can be used to load JS code into the child process and to exchange messages with it.

As a simple example, imagine that we want to be informed every time a `load` event triggers in web content. We’re not interested in any particular browser or window, so we use the global message manager. The basic process is as follows:

```// Get the global message manager.
let mm = Cc["@mozilla.org/globalmessagemanager;1"].
getService(Ci.nsIMessageListenerManager);

});

// Load code into the child process to listen for the event.
```

For this to work, we also need to have a file `content-script.js`:

```// Listen for the load event.
// Inform the parent process.
let docURL = content.document.documentURI;
}, false);
```

This file is called a content script. When the `loadFrameScript` function call runs, the code for the script is run once for each `<browser>` element. This includes both remote browsers and regular ones. If we had used a per-window message manager, the code would only be run for the browser elements in that window. Any time a new browser element is added, the script is run automatically (this is the purpose of the `true` parameter to `loadFrameScript`). Since the script is run once per browser, it can access the browser’s window object and docshell via the `content` and `docShell` globals.

The great thing about content scripts is that they work in both single-process and multiprocess Firefox. So if you write your code using the message manager now, it will be forward-compatible with multiprocessing. Tim Taubert wrote a more comprehensive look at the message manager in his blog.

Cross-process APIs. There are a lot of APIs in Firefox that cross between the parent and child processes. An example is the `webNavigation` property of XUL `<browser>` elements. The `webNavigation` property is an object that provides methods like `loadURI`, `goBack`, and `goForward`. These methods are called in the parent process, but the actions need to happen in the child. First I’ll cover how these methods work in single-process Firefox, and then I’ll describe how we adapted them for multiple processes.

The `webNavigation` property is defined using the XML Binding Language (XBL). XBL is a declarative language for customizing how XML elements work. Its syntax is a combination of XML and JavaScript. Firefox uses XBL extensively to customize XUL elements like `<browser>` and `<tabbrowser>`. The `<browser>` customizations reside in `browser.xml`. Here is how `browser.webNavigation` is defined:

```<field name="_webNavigation">null</field>

<getter>
<![CDATA[
]]>
</getter>
</property>
```

This code is invoked whenever JavaScript code in Firefox accesses `browser.webNavigation`, where `browser` is some `<browser>` element. It checks if the result has already been cached in the `browser._webNavigation` field. If it hasn’t been cached, then it fetches the navigation object based off the browser’s docshell. The docshell is a Firefox-specific object that encapsulates a lot of functionality for loading new pages, navigating back and forth, and saving page history. In multiprocess Firefox, the docshell lives in the child process. Since the `webNavigation` accessor runs in the parent process, `this.docShell` above will just return null. As a consequence, this code will fail completely.

One way to fix this problem would be to create a fake docshell in C++ that could be returned. It would operate by sending IPDL messages to the real docshell in the child to get work done. We may eventually take this route in the future. We decided to do the message passing in JavaScript instead, since it’s easier and faster to prototype things there. Rather than change every docshell-using accessor to test if we’re using multiprocess browsing, we decided to create a new XBL binding that applies only to remote `<browser>` elements. It is called `remote-browser.xml`, and it extends the existing `browser.xml` binding.

The `remote-browser.xml` binding returns a JavaScript shim object whenever anyone uses `browser.webNavigation` or other similar objects. The shim object is implemented in its own JavaScript module. It uses the message manager to send messages like `"WebNavigation:LoadURI"` to a content script loaded by `remote-browser.xml`. The content script performs the actual action.

The shims we provide emulate their real counterparts imperfectly. They offer enough functionality to make Firefox work, but add-ons that use them may find them insufficient. I’ll discuss strategies for making add-ons work in more detail later.

Cross-process object wrappers. The message manager API does not allow the parent process to call `sendSyncMessage`; that is, the parent is not allowed to wait for a response from the child. It’s detrimental for the parent to wait on the child, since we don’t want the browser UI to be unresponsive because of slow content. However, converting Firefox code to be asynchronous (i.e., to use `sendAsyncMessage` instead) can sometimes be onerous. As an expedient, we’ve introduced a new primitive that allows code in the parent process to access objects in the child process synchronously.

These objects are called cross-process object wrappers—frequently abbreviated CPOWs. They’re created using the message manager. Consider this example content script:

```addEventListener("load", function (e) {
let doc = content.document;
}, false);
```

In this code, we want to be able to send a reference to the document to the parent process. We can’t use the second parameter to `sendAsyncMessage` to do this: that argument is converted to JSON before it is sent up. The optional third parameter allows us to send object references. Each property of this argument becomes accessible in the parent process as a CPOW. Here’s what the parent code might look like:

```let mm = Cc["@mozilla.org/globalmessagemanager;1"].
getService(Ci.nsIMessageListenerManager);

let uri = msg.objects.document.documentURI;
});
```

It’s important to realize that we’re send object references. The `msg.objects.document` object is only a wrapper. The access to its `documentURI` property sends a synchronous message down to the child asking for the value. The dump statement only happens after a reply has come back from the child.

Because every property access sends a message, CPOWs can be slow to use. There is no caching, so 1,000 accesses to the same property will send 1,000 messages.

Another problem with CPOWs is that they violate some assumptions people might have about message ordering. Consider this code:

```mm.addMessageListener("GotLoadEvent", function (msg) {
mm.sendAsyncMessage("ChangeDocumentURI", {newURI: "hello.com"});
let uri = msg.objects.document.documentURI;
});
```

This code sends a message asking the child to change the current document URI. Then it accesses the current document URI via a CPOW. You might expect the value of `uri` to come back as `"hello.com"`. But it might not. In order to avoid deadlocks, CPOW messages can bypass normal messages and be processed first. It’s possible that the request for the `documentURI` property will be processed before the `"ChangeDocumentURI"` message, in which case `uri` will have some other value.

For this reason, it’s best not to mix CPOWs with normal message manager messages. It’s also a bad idea to use CPOWs for anything security-related, since you may not get results that are consistent with surrounding code that might use the message manager.

Despite these problems, we’ve found CPOWs to be useful for converting certain parts of Firefox to be multiprocess-comptabile. It’s best to use them in cases where users are less likely to notice poor responsiveness. As an example, we use CPOWs to implement the context menu that pops up when users right-click on content elements. Whether this code is asynchronous or synchronous, the menu cannot be displayed until content has responded with data about the element that has been clicked. The user is unlikely to notice if, for example, tab animations don’t run while waiting for the menu to pop up. Their only concern is for the menu to come up as quickly as possible, which is entirely gated on the response time of the content process. For this reason, we chose to use CPOWs, since they’re easier than converting the code to be asynchronous.

It’s possible that CPOWs will be phased out in the future. Asynchronous messaging using the message manager gives a user experience that is at least as good as, and often strictly better than, CPOWs. We strongly recommend that people use the message manager over CPOWs when possible. Nevertheless, CPOWs are sometimes useful.

### How will add-ons be affected?

The effect of multiple processes on add-ons is a huge topic. The most important thing I want to emphasize is that we intend to go to great lengths to ensure compatibility with add-ons. We realize that add-ons are extremely important to Firefox users, and we have no intention of abandoning or disrupting add-ons. At the same time, we feel strongly that users will appreciate the security and responsiveness benefits of multiprocess Firefox, so we’re willing to work very hard to get add-ons on board. We’re very interested in working with add-on developers to ensure that their add-ons work well in multiprocess Firefox. I hope to cover this topic in greater depths in future blog posts.

By default, add-on code runs in the parent process. Some add-ons have no need to access content objects, and so they will continue to function without any need for changes. For the remaining add-ons, we have a number of ideas and proposals to ensure compatibility.

The best way to ensure that add-ons are multiprocess-compatible is for them to use the message manager to touch content objects. This is what we’ve been doing for Firefox itself. It’s the most efficient option, and it gives the best user experience. Developers can use the message manager in their code right now; it was added in Firefox 4. We plan to convert the add-on SDK to use the message manager, which should allow most Jetpack add-ons to work with multiple processes without any additional changes. If you’re writing a new add-on, you would be doing Mozilla a great service if you use the message manager or the add-on SDK from the start.

Realistically, though, it will be a long time before all add-ons are converted to use the message manager. Until then, we have two strategies for coping with incompatible add-ons:

• Any time an add-on accesses a content object (like a DOM node), we can give it a CPOW instead. For the most part, CPOWs behave exactly like the objects they’re wrapping. The main difference is that only primitive values can be passed as arguments when calling CPOW methods. This problem usually surfaces when the add-on calls `element.addEventListener("load", function (e) {...})`. This won’t work if `element` is a CPOW because the second argument is a function, which is not a primitive. We have some ideas for mitigating this restriction. Despite the argument problem, CPOWs make it possible for some add-ons to work with multiple processes. It’s possible to use Adblock Plus with multiprocess Firefox right now. As our CPOW techniques become better, we expect that more and more add-ons will be compatible.
• For add-ons that don’t use the message manager or the add-on SDK and that don’t work with CPOWs, we can fall back to single-process Firefox. There are a few difficulties with this approach (what happens to your existing tabs if you install an incompatible add-on?), but we think they’re tractable.

In the future, I’m planning to update some popular add-ons to work with multiprocess Firefox. I’ll blog about difficulties I run into and possible solutions. I hope this material will be useful to people trying to use the message manager in their add-ons.