Category Archives: PlanetFirefox

A little mouse hack

A major theme of the upcoming Firefox 4 release is improving speed and responsiveness, especially in the user interface. It’s easy to see issues where responsiveness is on the order of seconds (like waiting for an update to apply, or the length of time to respond to a modal dialog), but how do you examine and measure UI changes that happen over a period of just milliseconds?

One could instrument the code and get nanosecond-level precision — but it’s difficult to know where to insert probes, and you still may not be measuring what the user is actually seeing. A more direct “ground truth” would be to use a camera to record what’s displayed on the screen, and then examine the resulting video frame-by-frame to obtain data… I dabbled with this briefly last year when working on a Windows CE bug about slow-opening windows and menus. But more recently, Alex Faaborg has started a investigation of the Firefox UI using a significantly refined technique.

A problem Alex quickly ran into, though, is that it’s hard to look at a video and know exactly when the user clicked a mouse button. If only there was some visual indication of the mouse button state… Hmm! That was enough to start the wheels turning in my head, yadda yadda, and one weekend later I had complete a nice little hack that added some LEDs to a mouse so you could see the button states.

Some pictures… (See Flickr for the whole set.)

First, you’ve got to drill a nice hole (*)… I cringe every time I see someone mention doing some hack with a Dremel, because most of the time the result looks like something a drunk monkey with a chainsaw would produce.

Next, tap into the mouse’s microswitches (which are tied to ground) and the USB’s +5V.

Finally, route things nicely. Behold, the four-as… err, two-wired mouse!

This is the business end of the extra wire now attached to the mouse. 2 LEDs (and a couple of resistors) wrapped up in some heat-shrink tubing. When a mouse button is clicked, one of them lights up — red for right, (ye)llow for left.

This is a pretty simple little hack, but it was especially fun it’s not often us software guys get to do hardware stuff. And, hey, it even worked on the first try!

Sadly, there is one little problem… While the hacked mouse worked flawlessly for me, it immediately failed to work for Alex — the OS didn’t see mouse clicks, even though the LEDs lit up. Oh no! Luckily I had made the LED tail detachable (not shown here), as it turns out that if the mouse is plugged into the computer with the LED tail attached, it doesn’t work. But if it’s plugged in without the LED tail, and then the tail is plugged in afterwards, it works fine. I’m guessing that I just need to add some decoupling capacitor where I tapped into the switches, as the mouse’s IC was ok with the short traces to the switches but not the new 4-foot wires hanging off it. Or maybe a pull-up resistor? Both? Dunno exactly what the problem is yet — this is why I’m a software guy. 😉 What say you?

Status update

One of these things I did not actually work on:

  • JavaScript / js-ctypes implementation of WeaveCrypto
  • Migration and replacement of localstore.rdf with a .json backing store
  • Rickrolling Fligtar’s new dashboard
  • Tab-modal dialogs proof-of-concept
  • Fix multiple master-password dialogs with session restore
  • Ported Firefox to ColecoVision.

Weave, crypto, and JavaScript

tl;dr: fa20ae35b8ac53b28dde4fc333aba21f 🙂

Up until now, Mozilla’s Weave add-on has been living with an awkward implementation detail: a binary component. When I wrote Weave’s current cryptographic component back in 2008, in order to use the crypto code that’s already in Mozilla (ie, NSS) there was no choice but to write C++ code. NSS doesn’t export any scriptable interfaces at all, and its partner-in-crime (PSM) exposes only a limited set of high-level functions — none of which was useful for Weave.

The C++ code has been working fine, but has a number of serious drawbacks… A binary component has to be compiled for each supported platform (originally just Windows, Linux, Mac x86 and Mac PowerPC). That results in a bigger download, and makes it a pain to support new platforms (like 64-bit Windows, 64-bit Linux, 64-bit Mac, Maemo, Windows CE/Mobile, Android, etc). It’s also a barrier to new developers — compiling a binary component requires a build environment and XULRunner SDK, whereas hacking on most extensions requires nothing more than a text editor. Luckily the C++ code has been quite stable, so Weave was able to hack around this by including pre-compiled binaries in the Mercurial repository.

But enough is enough.

The next (trunk) version of Firefox includes JS-CTypes, a feature that allows JavaScript to interface with native code. Think of it as dlopen/dlsym for JS. By porting the WeaveCrypto component over to JavaScript + JS-CTypes, Weave is now able to talk with NSS directly, without any C++ code. It basically Just Works — adding support for Mossop’s Palm Pre port of Firefox was literally a 1-line change. Adding support for Android was a 4-line change (only because they’re tricky and put in a sub-directory).

I should also mention that unit tests were a HUGE help in getting the new code completed. I wrote extensive tests for the C++ version of WeaveCrypto, and once the JS-CTypes version was working with those tests I was able to make a full-up Weave sync work with the new code on the first try. Easy-peasy!

If you’re interested in seeing what this new code does, take a look at the bug and the code in the Mercurial repository. Note that the XPCOM interfaces are fairly specific to what Weave wants to do — it’s not a general-purpose JS crypto API. But it’s a huge step towards making it easier to do crypto code in JS extensions — and perhaps in the future we’ll look at making a real general-purpose crypto API for extensions; it’s certainly an interesting problem! If folks are interested in helping out with such a project, let me know.

Status and stuff

A bit of stuff I’ve been up to lately:

  • CSS Transitions for videocontrols. Finally got around to landing this. There’s really no visible change, but it replaces and simplifies a whole bunch of Javascript-driven animation code. CSS Transitions are really nice to work with.
  • Use Services.jsm in Login Manager. Gavin added Services.jsm to trunk not that long ago, and it’s one of those things that’s so slick to use we should have done it years ago. There’s been a small flurry of patches to convert various code over to using Services.jsm; it’s trivial work but is really good for code hygiene.
  • A 3rd round of crashed-plugin UI tweaks. Hopefully we’ve got it nailed this time! Also fixed the last of the significant crashed-plugin UI bugs, and started a cleanup of the trunk code in preparation for future work.
  • Reviews of 2 Form History patches for “good first bug” bugs — I need to start tagging more of these! With these fixes, we now avoid saving credit card numbers, and there’s a new option (off by default) to suppress saving data on SSL pages. I’ve also been finishing up patches for helping Weave to sync form data.
  • Finished reviews, tests, and landing for automatic proxy authentication. BenB’s patch is now in the tree, though it’s currently preffed off. If you use a proxy with authentication, enable “signon.autologin.proxy” and give it spin.
  • Finished porting of the C++ WeaveCrypto module to JS-CTypes, and was able to successfully sync between profiles using it.
  • Thunzilla!

Coming up soon:

  • Finish up last quarter’s E10S scoping, and get this quarter’s E10S goal underway.
  • Final polish on the JS-CTypes WeaveCrypto, get it out for review.
  • Doing a little 1 or 2 day sprint with zpao to port most of the remaining C++ form history code to Javascript.
  • Death to (almost) all superfluous Master Password prompts.
  • Other random awesomeness.

Not quite smooth as buttah…

So, I finally got around to watching this video which has been been making the rounds as of late (not a Rickroll, I swear to god! WHY DOES NO ONE TRUST ME?! :-). I fired it up the 1080p version in fullscreen mode, and was slightly disappointed to find that while the video was playing back rather well, it wasn’t quite perfect. As the beer commercials say, “rich, but not smooth.”

So I next loaded it up in Safari, to see how it compared. Previous versions of Firefox have had some jerky-video problems (due to running garbage collection at bad times or doing too much main-thread disk IO for session restore), so I was fully prepared to file a bug on the problem — smooth playback in another browser would be a strong indication that something in our code was causing the poor performance.

However, what I found was that playback in Safari was much much worse that on the trunk Firefox build I was using. While Firefox yielded good playback with an occasional glitch, Safari gave a consistently poor playback of around 3 fps.

There’s one clear, inescapable conclusion here: Flash sucks. 🙂 But seriously, folks, I’m happy to see that trunk builds perform well. I should still file a bug to investigate if we’re responsible for the occasional stutter in playback (or if that’s just Flash), and if results on Windows are similar to OS X or not. But I’m still pleased to see that this arbitrary trunk nightly — not even beta quality — is doing a good job.

Crashed Plugin UI

Yesterday I landed bug 538910, which introduces some new UI for when a plugin crashes. This builds on top of the fantastic Out Of Process Plugins (OOPPs) work from the Electrolysis team, which allows the browser to keep running even after a plugin dies. So, now that crashes from plugins like Flash, Java, Silverlight, and Quicktime don’t take down Firefox, we need to show the user something to indicate when a plugin has a problem and how to deal with it.

A picture is worth a kiloword, so let’s start with that:

When a plugin crashes, we now show a placeholder (as in the pic above) to indicate that the page is missing some expected content. The browser runs a single plugin process (per plugin type), which is shared across all tabs and windows, so any page using a plugin when it crashes will have it replaced with this UI. But if the plugin on the page is sized too small to show the UI (text and icon), we’ll instead show a notification bar.

Recovering from a plugin crash is easy — simply reload the page. It would be nice to restart just the plugin without reloading the whole page, but scripts on the page won’t be expecting the crash, and can break or misbehave. It would be an interesting future experiment (addon?) to allow attempting to do this anyway, but for now reloading the page is a simple, conservatative approach that we know will always work.

You might have noticed that at the bottom of the placeholder UI there’s a message saying “A crash report was submitted.” Mozilla has an existing system for collecting Firefox crash reports, which are hugely useful for helping us detect and fix problems that users encounter. Plugin crashes are also able to generate these reports, and we can notify plugin vendors of their bugs. Crashes are annoying enough, so we decided that then was the wrong time to have annoying popups or checkboxes which require the user to make a decision about submitting a report. Instead, submission is controlled by a preference (exposed as a checkbox in the usual browser preferences window), and the browser will automatically submit the crash report when it’s enabled. The preference is shared with the existing Crash Reporter, so if you’ve previously told it to not submit crashes, that choice will continue to be honored (and, now you can disable submission without having to wait for a crash to happen — but we hope you won’t do this because these reports are so helpful for improving Firefox’s stability).

The visual style of this UI is also being used for what’s shown when a plugin is missing, disabled, or blocked. We’ve always had UI for those cases, but it was a bit barebones and ugly. Now it looks better, and further refinements are coming (see bug 545070).

If you’d like to check out this new UI, you’ll need to be running a current Windows or Linux trunk nightly. Sorry OS X, no OOPP for you yet. You can wait for a plugin to crash, or just kill it off from the OS’s task manager (look for a “mozilla-runtime” process).

Finally, here’s a particularly nice screenshot of how nice this UI can look in content. Thanks to Stephen Horlander for the beautiful visual design, and to Alexes Limi and Faaborg for UX. I think this will be the best crashed plugin experience you’ve ever had. (Oh, and don’t miss Sean Martell’s epic alternate version!)

Handy trick

If you’re involved with developing on Mozilla, odds are you’ve got at least one or two (dozen? 🙂 profiles for testing. Some used regularly, some created-and-forgotten for one-off testing, some you’ve forgotten what they’re for. And you probably jump through gymnastics with the Profile Manager to create, select, and delete said profiles.

Once upon a time I used to do the same thing, until someone pointed out that there’s a different way to create and select profiles.

Old And Busted:

1) run firefox -P
2) Create new profile
3) Click, click, typeity, click
4) Select new profile
5) Swear, run firefox -P again because you didn’t mean to set that as your default
6) What was I doing again?
7) Oh yeah, test that thing. Quit.
8) run firefox -P
9) Delete profile
10) Lather, rinse, repeat for repeating testing with a clean new profile.

New Hotness:

1) mkdir /tmp/blah (or ~/profiles/blah for more permanence)
2) firefox -profile /tmp/blah
3) rm -rf /tmp/blah

At least for my workflow, I haven’t used the Profile Manager since. (This trick doesn’t depend on Profile Manager at all, so even it was removed at some point this would still work.) Some folks might prefer the Profile Manger for their needs, but this works great for me.