Mike HommeyGit now faster than Mercurial to clone Mozilla Mercurial repos

How is that for clickbait?

With the now released git-cinnabar 0.5.2, the cinnabarclone feature is enabled by default, which means it doesn’t need to be enabled manually anymore.

Cinnabarclone is to git-cinnabar what clonebundles is to Mercurial (to some extent). Clonebundles allow Mercurial to download a pre-generated bundle of a repository, which reduces work on the server side. Similarly, Cinnabarclone allows git-cinnabar to download a pre-generated bundle of the git form of a Mercurial repository.

Thanks to Connor Sheehan, who deployed the necessary extension and configuration on the server side, cinnabarclone is now enabled for mozilla-central and mozilla-unified, making git-cinnabar clone faster than ever for these repositories. In fact, under some conditions (mostly depending on network bandwidth), cloning with git-cinnabar is now faster than cloning with Mercurial:

$ time git clone hg::https://hg.mozilla.org/mozilla-unified mozilla-unified_git
Cloning into 'mozilla-unified_git'...
Fetching cinnabar metadata from https://index.taskcluster.net/v1/task/github.glandium.git-cinnabar.bundle.mozilla-unified/artifacts/public/bundle.git
Receiving objects: 100% (12153616/12153616), 2.67 GiB | 41.41 MiB/s, done.
Resolving deltas: 100% (8393939/8393939), done.
Reading 172 changesets
Reading and importing 170 manifests
Reading and importing 758 revisions of 570 files
Importing 172 changesets
It is recommended that you set "remote.origin.prune" or "fetch.prune" to "true".
git config remote.origin.prune true
or
git config fetch.prune true

Run the following command to update tags:
git fetch --tags hg::tags: tag "*"
Checking out files: 100% (279688/279688), done.

real    4m57.837s
user    9m57.373s
sys     0m41.106s

$ time hg clone https://hg.mozilla.org/mozilla-unified
destination directory: mozilla-unified
applying clone bundle from https://hg.cdn.mozilla.net/mozilla-unified/5ebb4441aa24eb6cbe8dad58d232004a3ea11b28.zstd-max.hg
adding changesets
adding manifests
adding file changes
added 537259 changesets with 3275908 changes to 523698 files (+13 heads)
finished applying clone bundle
searching for changes
adding changesets
adding manifests
adding file changes
added 172 changesets with 758 changes to 570 files (-1 heads)
new changesets 8b3c35badb46:468e240bf668
537259 local changesets published
updating to branch default
(warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor")
279688 files updated, 0 files merged, 0 files removed, 0 files unresolved

real    21m9.662s
user    21m30.851s
sys     1m31.153s

To be fair, the Mozilla Mercurial repos also have a faster “streaming” clonebundle that they only prioritize automatically if the client is on AWS currently, because they are much larger, and could take longer to download. But you can opt-in with the --stream command line argument:

$ time hg clone --stream https://hg.mozilla.org/mozilla-unified mozilla-unified_hg
destination directory: mozilla-unified_hg
applying clone bundle from https://hg.cdn.mozilla.net/mozilla-unified/5ebb4441aa24eb6cbe8dad58d232004a3ea11b28.packed1.hg
525514 files to transfer, 2.95 GB of data
transferred 2.95 GB in 51.5 seconds (58.7 MB/sec)
finished applying clone bundle
searching for changes
adding changesets
adding manifests
adding file changes
added 172 changesets with 758 changes to 570 files (-1 heads)
new changesets 8b3c35badb46:468e240bf668
updating to branch default
(warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor")
279688 files updated, 0 files merged, 0 files removed, 0 files unresolved

real    1m49.388s
user    2m52.943s
sys     0m43.779s

If you’re using Mercurial and can download 3GB in less than 20 minutes (in other words, if you can download faster than 2.5MB/s), you’re probably better off with the streaming clone.

Bonus fact: the Git clone is smaller than the Mercurial clone

The Mercurial streaming clone bundle contains data in a form close to what Mercurial puts on disk in the .hg directory, meaning the size of .hg is close to that of the clone bundle. The Cinnabarclone bundle contains a git pack, meaning the size of .git is close to that of the bundle, plus some more for the pack index file that unbundling creates.

The amazing fact is that, to my own surprise, the git pack, containing the repository contents along with all git-cinnabar needs to recreate Mercurial changesets, manifests and files from the contents, takes less space than the Mercurial streaming clone bundle.

And that translates in local repository size:

$ du -h -s --apparent-size mozilla-unified_hg/.hg
3.3G    mozilla-unified_hg/.hg
$ du -h -s --apparent-size mozilla-unified_git/.git
3.1G    mozilla-unified_git/.git

And because Mercurial creates so many files (essentially, two per file that ever was in the repository), there is a larger difference in block size used on disk:

$ du -h -s mozilla-unified_hg/.hg
4.7G    mozilla-unified_hg/.hg
$ du -h -s mozilla-unified_git/.git
3.1G    mozilla-unified_git/.git

It’s even more mind blowing when you consider that Mercurial happily creates delta chains of several thousand revisions, when the git pack’s longest delta chain is 250 (set arbitrarily at pack creation, by which I mean I didn’t pick a larger value because it didn’t make a significant difference). For the casual readers, Git and Mercurial try to store object revisions as a diff/delta from a previous object revision because that takes less space. You get a delta chain when that previous object revision itself is stored as a diff/delta from another object revision itself stored as a diff/delta … etc.

My guess is that the difference is mainly caused by the use of line-based deltas in Mercurial, but some Mercurial developer should probably take a deeper look. The fact that Mercurial cannot delta across file renames is another candidate.

Mozilla Security BlogFixing Antivirus Errors

After the release of Firefox 65 in December, we detected a significant increase in a certain type of TLS error that is often triggered by the interaction of antivirus software with the browser. Today, we are announcing the results of our work to eliminate most of these issues, and explaining how we have done so without compromising security.

On Windows, about 60% of Firefox users run antivirus software and most of them have HTTPS scanning features enabled by default. Moreover, CloudFlare publishes statistics showing that a significant portion of TLS browser traffic is intercepted. In order to inspect the contents of encrypted HTTPS connections to websites, the antivirus software intercepts the data before it reaches the browser. TLS is designed to prevent this through the use of certificates issued by trusted Certificate Authorities (CAs). Because of this, Firefox will display an error when TLS connections are intercepted unless the antivirus software anticipates this problem.

Firefox is different than a number of other browsers in that we maintain our own list of trusted CAs, called a root store. In the past we’ve explained how this improves Firefox security. Other browsers often choose to rely on the root store provided by the operating system (OS) (e.g. Windows). This means that antivirus software has to properly reconfigure Firefox in addition to the OS, and if that fails for some reason, Firefox won’t be able to connect to any websites over HTTPS, even when other browsers on the same computer can.

The interception of TLS connections has historically been referred to as a “man-in-the-middle”, or MITM. We’ve developed a mechanism to detect when a Firefox error is caused by a MITM. We also have a mechanism in place that often fixes the problems. The “enterprise roots” preference, when enabled, causes Firefox to import any root CAs that have been added to the OS by the user, an administrator, or a program that has been installed on the computer. This option is available on Windows and MacOS.

We considered adding a “Fix it” button to MITM error pages (see example below) that would allow users to easily enable the “enterprise roots” preference when the error is displayed. However, we realized that this was something we want users to do rather than an “override” button that allows a user to bypass an error at their own risk.

Example of a MitM Error Page in Firefox

Beginning with Firefox 68, whenever a MITM error is detected, Firefox will automatically turn on the “enterprise roots” preference and retry the connection. If it fixes the problem, then the “enterprise roots” preference will remain enabled (unless the user manually sets the “security.enterprise_roots.enabled” preference to false). We’ve tested this change to ensure that it doesn’t create new problems. We are also recommending as a best practice that antivirus vendors enable this preference (by modifying prefs.js) instead of adding their root CA to the Firefox root store. We believe that these actions combined will greatly reduce the issues encountered by Firefox users.

In addition, in Firefox ESR 68, the “enterprise roots” preference will be enabled by default. Because extended support releases are often used in enterprise settings where there is a need for Firefox to recognize the organization’s own internal CA, this change will streamline the process of deploying Firefox for administrators.

Finally, we’ve added an indicator that allows the user to determine when a website is relying on an imported root CA certificate. This notification is on the site information panel accessed by clicking the lock icon in the URL bar.

It might cause some concern for Firefox to automatically trust CAs that haven’t been audited and gone through the rigorous Mozilla process. However, any user or program that has the ability to add a CA to the OS almost certainly also has the ability to add that same CA directly to the Firefox root store. Also, because we only import CAs that are not included with the OS, Mozilla maintains our ability to set and enforce the highest standards in the industry on publicly-trusted CAs that Firefox supports by default. In short, the changes we’re making meet the goal of making Firefox easier to use without sacrificing security.

The post Fixing Antivirus Errors appeared first on Mozilla Security Blog.

Mike HommeyAnnouncing git-cinnabar 0.5.2

Git-cinnabar is a git remote helper to interact with mercurial repositories. It allows to clone, pull and push from/to mercurial remote repositories, using git.

Get it on github.

These release notes are also available on the git-cinnabar wiki.

What’s new since 0.5.1?

  • Updated git to 2.22.0 for the helper.
  • cinnabarclone support is now enabled by default. See details in README.md and mercurial/cinnabarclone.py.
  • cinnabarclone now supports grafted repositories.
  • git cinnabar fsck now does incremental checks against last known good state.
  • Avoid git cinnabar sometimes thinking the helper is not up-to-date when it is.
  • Removing bookmarks on a Mercurial server is now working properly.

Cameron KaiserAnd now for something completely different: NetBSD on the last G4 Mac mini (and making the kernel power failure proof)

(First, as a public service message, if you're running Linux on a G5 you may wish to update the kernel.)

I'm a big fan of NetBSD. I've run it since 2000 on a Mac IIci (of course it's still running it) and I ran it for several years on a Power Mac 7300 with a G3 card which was the second incarnation of the Floodgap gopher server. Today I also still run it on a MIPS-based Cobalt RaQ 2 and an HP Jornada 690. I think NetBSD is a better match for smaller or underpowered systems than current-day Linux, and is fairly easy to harden and keep secure even though none of these systems are exposed to the outside world.

Recently I had a need to set up a bridge system that would be fast enough to connect two networks and I happened to have two of the "secret" last-of-the-line 1.5GHz G4 Mac minis sitting on the shelf doing nothing. Yes, they're probably outclassed by later Raspberry Pi models, but I don't have to buy anything and I like putting old hardware to good use. So here it is, doing serious business, with the total outlay being the cost of one weekend afternoon:

NetBSD/macppc is a fairly mature port, but that doesn't mean it doesn't have bugs. And oddly there do seem to still be some in the install process, at least of the 8.1 release I used, on this last and mightiest of the PowerPC miniatures. Still, once it got set up it's been working great since, so here's a few pointers on getting the 1.5 mini (and current Power Macs generally) running as little NetBSD servers. As most of my readers are Power Mac users and likely to have multiple Power Macs that can aid this process, I will orient this guide to them with some sidebar notes for people trying to pull the mini up all by itself. This machine is configured with 1GB of RAM, the standard 2.5" PATA spinning disk and optical drive, USB 2.0, FireWire 400, Bluetooth and WiFi, using the onboard Radeon 9200 GPU as the console.

The working configuration, hit upon by Sevan Janiyan, is to have an HFS+ partition with the bootloader (called ofwboot.xcf) and the kernel, and then a separate partition for NetBSD's root volume. For some reason the mini goes berserk when trying to boot from a kernel on a NetBSD native partition, but works fine from an HFS+ one. Unfortunately, since the NetBSD installer cannot actually initialize an HFS+ volume, you'll need to do some of the partitioning work in Mac OS X, copy the files there, and then finish the rest. There's a couple ways of skinning that cat, but for many of you this means you'll need not only the NetBSD installer CD, but also a bootable copy of Mac OS X either on disc (i.e., an installer) or a bootable external drive, and some means of copying files.

And that brings us to our first pro tip: the G4 Mac minis had absolutely crap optical drives that would fail if you looked at them crossways. This drive was no exception; it would read commercially pressed CDs but only certain media types of burned CDs and wouldn't read any DVD at all. That means it wouldn't boot from my usual OS X Tiger 10.4.6 install DVD, and the last generation of G4 minis require 10.4, so none of my previous OS X CDs would work.

As it happens, the minimum requirement for the G4/1.5 minis is not actually 10.4.2, yet another Apple lie; it's actually 10.4.0 (though note that some devices like Bluetooth may not work properly). This is fortunate because 10.4.0 was available in CD format and I was able to boot Disk Utility off that Tiger CD instead. Your other option is to bring up the mini in Target Disk Mode (connect over FireWire; hold T down as you turn the mini on until you see a yellow logo on a blue background) from another Power Mac and do the formatting there. In fact, we'll be using Target Disk Mode in a minute, but here I just booted from the CD instead.

In Disk Utility (whether you're doing this on the machine from the Tiger installer or on another machine over FireWire), wipe the mini's current partition scheme and create two new partitions. The first is your HFS+ volume for booting. This particular machine will only run NetBSD, so I made it 512MB to have enough room for multiple kernels and for other files I might need, but if you want a dual-boot system you can make this larger. The second partition will be for NetBSD; I allocated everything else and created it as a UFS ("UNIX File System") partition, though we will divvy it up later. The formatting scheme should look more or less like these screenshots. Shut down the mini when you're done.

Now we boot the NetBSD installer. Bring up the machine in OpenFirmware mode -- all New World Macs use OpenFirmware 3 -- by holding down Command-Option-O-F while powering it on (I advise doing this from a directly-attached USB keyboard). This will bring up the OpenFirmware interface. When you are commanded to do so, release the keys and you will drop to the famous ok prompt. If you're lucky and the evil spirits in your optical drive have been placated by an offering of peanut M&Ms and a young maiden at midnight, you can simply insert the NetBSD install disc and type

boot cd:,\ofwboot.xcf netbsd.macppc

Note the backslash, not a forward slash! If this works properly, then the screen will go black (you don't go back) and enter the Installer proper.

If you get weird errors or OpenFirmware complains the disc is not readable, the optical drive is probably whacked. My drive wouldn't read burned Fujifilm CD-R media (that everything else did), but would read burned Maxell media. If you can't even control for that, you may be able to connect a FireWire CD/DVD reader and boot from it instead. The command would be "something like"

boot fw/node/sbp-2/disk:,\ofwboot.xcf netbsd.macppc

If this didn't work, you may need to snoop around the OpenFirmware device tree to figure out where the device is actually attached, though this should basically work for the G4 mini's single port. Alternatively, you could also try a USB CD-ROM drive, or dding the install image to a USB drive on another computer and booting the mini from that, but the boot string will vary based on which port you connect it to (use dev usb0 and ls to show everything under that port, then dev usb1, etc.). Make sure it is directly connected to the mini. Once you find a device that shows a disk, then "something like" this will work (let's say it was found under usb1):

boot usb1/disk:,\ofwboot.xcf netbsd.macppc

If even that won't work, there are some other ways like netbooting, but this is rather more complicated and I won't talk about it here. Or you could actually fix the drive, I guess ...

When the Installer starts up, choose the option to drop to the shell when it is offered. We will now finish the partitioning from the NetBSD side; we do not use the Installer's built-in partition tool as it will run out of memory. At the shell prompt, type

pdisk /dev/wd0c

When it asks you for a command, type a capital letter P and press RETURN. This will print out the current partition map, which if your mini is similar to mine, should show 4 partitions: the Apple partition map itself, followed by the HFS+ partition, and then by a tiny Apple_Boot partition that is made whenever a UFS volume appears to be the boot volume. (Silly Mac OS X.) You can remove it if you want, but this seemed like more trouble than it was worth for a measly 8.5 megabytes. After that is the space for NetBSD. On my G4 mini, this was partition number 4. Delete this partition by typing a lower-case d, press RETURN, and type 4. Be sure of this number! I will use it in the examples below.

First we will formally create the swap. This is done with the capital letter C command (as shown in the screenshot). Indicate the first block is 4p (i.e., starting at partition 4), for 4194304 blocks (2GB), type Apple_UNIX_SVR2 (don't forget the underscores!), and slice b.

Next is the actual NetBSD root: capital letter C, then saying the first block was 5p (i.e., starting at partition 5, the unallocated section), soaking up the rest of the blocks (however many you see listed under Apple_Free), type Apple_UNIX_SVR2 (don't forget the underscores!), and slice a.

If you did all this right, your screen should look more or less like this:

Verify the partition map one more time with the capital letter P command, then write it out with lower-case w, answering y(es), and then quit with lower-case q. At the shell prompt, return to the installer by typing sysinst and when asked, indicate you will "Use existing partition sizes." The installer will then install the appropriate packages and you can do the initial setup for your clock, the root password, etc. When this is all done, reboot your mini with the left mouse button held down; it will eject the CD (and fail to find a boot volume if you do not have an OS X installation). Shut down the mini.

Before the mini will boot NetBSD, we must copy the kernel and the bootloader to the HFS+ partition. This is where Target Disk Mode comes in handy, because you can just copy directly. Here is my iBook G4 copying a custom kernel (more in a moment):

On the iBook G4, I put in the NetBSD install CD and copied off ofwboot.xcf and netbsd-GENERIC.gz, or you can download them from here and here. They should be copied to the root of the mini's HFS+ volume for the command below to work. For good measure I also uncompressed the gzipped kernel as a failsafe and put a copy of the installation kernel there too, though this isn't necessary. Once the files are copied, eject the mini's drive on the FireWire machine, unplug the FireWire and power the mini off.

If you don't have another Mac around that can talk to the mini over FireWire, you can do this from NetBSD itself, but it's a bit more involved.

Either way, re-enter OpenFirmware with Cmd-Opt-O-F while powering it back up. It's time to boot your new NetBSD machine.

You can see from the screenshot here that the HFS+ volume is considered partition 2, as we left it in pdisk. That means your boot string is

boot hd:,\ofwboot.xcf hd:2/netbsd-GENERIC.gz

Yes, the path to ofwboot still has a backslash, but the argument to ofwboot actually needs a forward slash. NetBSD will start immediately.

There are several minor and one rather obnoxious bug with NetBSD's current support. You will notice a few strange messages on startup as part of the huge mass of text:

oea_startup: failed to allocate DEAD ZONE: error=12
pmu0: power-mgt not configured
pmu0: pmu-pwm-fans not configured
WARNING: 3 errors while detecting hardware; check system log.
bwi0: firmware_open failed on v3/ucode5.fw

I don't know what the first three are, but they appear to be harmless, and appear in many otherwise working dmesg archives (see also this report). The summary WARNING thus can also be politely ignored.

However, the last message is rather obnoxious. Per Sevan the built-in Broadcom WiFi in the Mac mini (detected as bwi0) doesn't work right in NetBSD with more than 512MB of memory, which I refuse to downgrade to, and NetBSD doesn't come with the firmware anyway. Even if you copy it off some other system that does, you won't be able to bring the interface up in the configuration here (you'll just see weird errors about wrong firmware version, etc.).

Since this machine is a bridge and sometimes needs to connect to a test WiFi, I went with a USB WiFi dongle instead (I also use a USB dongle when bridging Ethernet to Ethernet, but pretty much any Ethernet-USB dongle will work too). The one I had on the shelf that I'd bought for something else and then forgot about was a Belkin Wireless G. They sell a number of chipsets under this name, but the model F5D7050 I have here is based on a Ralink RT2501USB chipset that NetBSD sees as rum0, and works fine with wpa_supplicant.

Last but not least was making it "failsafe," with a solid power supply and making it autostarting. Although the G4 mini came with an 85W power supply, I stole the 110W from my 2007 Intel mini and used that so it wouldn't run anywhere near the PSU's capacity and hopefully lengthen its lifetime. As it turns out, this may not have been a problem anyway; most of the time this system is using just 21W on the Kill-A-Watt, maybe 40ish when it's booting.

To autostart NetBSD, ordinarily you would go into OpenFirmware and set boot-device to the bootloader and boot-file to the kernel, as the picture below shows.

However, you'll end up with a black screen or at minimum no console at all on an OpenFirmware 3 system if that's all you do. The magic sauce is to emit some text to the screen before loading the bootloader. Thus, the OpenFirmware settings are (each setenv command is one line):

setenv auto-boot? true
setenv boot-device hd:,\ofwboot.xcf
setenv boot-file hd:2/netbsd-GENERIC.gz (note that I used a different kernel in the screenshot: more in a second)
setenv boot-command ." hi there" cr " screen" output boot
reset-all

The boot-command spacing is especially critical. There is a space after the ." and the quote mark before screen" and after cr is also separated by spaces. The reset-all just tells OpenFirmware to write those settings to NVRAM. If you zap the mini's PRAM with Command-Option-P-R later, you may need to re-enter these.

In this configuration your mini will now start NetBSD automatically when it's turned on (just hold down Command-Option-O-F when starting it up to abort to OpenFirmware). However, this won't bring the machine up automatically after a power failure. While FreeBSD allows starting up after a power failure, this code apparently never made it over to NetBSD. Happily, supporting it merely requires a relatively simple kernel hack. Based on the FreeBSD pmu(4) driver, I created a patch that will automatically reboot any PMU-based NetBSD Power Mac after a power failure.

You should be comfortable with compiling your own kernels in NetBSD; not only is it just good to do for auditing purposes, but you can slim the kernel down substantially or enable other less common features. It's especially easy for NetBSD because all the tools to build it come with a standard installation. All you need to do is download the source and run the build process.

To use this patch, download the source to your home directory on the NetBSD box (you want syssrc.tgz) and download the patch and have it in your home directory as pmu.diff. If you don't have a working curl on your install yet (pkg_add curl, pkg_add mozilla-rootcerts, mozilla-rootcerts install), you may want to download it somewhere else and use scp, sftp or ftp to retrieve it. Then, adjusting as necessary for username and path,

cd /
tar zxf ~/syssrc.tgz
cd /usr/src/sys/arch/macppc/dev
patch -p0 < ~/pmu.diff

Then follow the instructions to make the kernel. I have a pre-built one of 8.1-GENERIC (I call it POWERON) on the gopher server, but you should really roll your own so that you get security fixes, since I may only maintain that kernel intermittently. That build is the one I'm using on the machine currently and on the screenshot above. With this custom kernel installed, when the power is abruptly cut while the machine is powered up it will automatically reboot when power is reapplied, just as the analogous option does in Mac OS X. Copy it to the HFS+ partition and remember to change boot-file to point to it once you've confirmed it works.

Overall, I think the G4 mini makes a fine little server. I wouldn't use it as a client except in Mac OS X itself, and I am forced to admit that even that is becoming less practical these days. But as a little machine to do important back-office tasks and do so reliably, I think NetBSD on the mini is a good choice. Once all the kinks with the installation got ironed out, so far it's been solid and performant especially considering this machine is about 13 years old (though I'm happy with its performance even on thirty-year-old machines). Rather than buying something new, if your needs are small it's probable you've got some old machine around that could do those tasks instead of oozing toxins from its circuit board into a waste dump in Rwanda. And since I had two on the shelf, it has an instant spare. I'll probably be usefully running it for as long as I've run my other NetBSD systems, and that's the highest compliment I think I can pay it.

Firefox UXiPad Sketching with GoodNotes 5

I’m always making notes and sketching on my iPad and people often ask me what app I’m using. So I thought I’d make a video of how I use GoodNotes 5 in my design practice.

Links:
This video on YouTube
GoodNotes
Templates: blank, storyboard, crazy 8s, iPhone X

Transcript:
Hi, I’m Michael Verdi, and I’m a product designer for Firefox. Today, I wanna talk about how I use sketching on my iPad in my design practice. So, first, sketching on a iPad, what I really like about it is that these apps on the iPad allow me to collect all my stuff in one place. So, I’ve got photos and screenshots, I’ve got handwritten notes, typed up notes, whatever, it’s all together. And I can organize it, and I can search through it and find what I need.

There’s really two basic kind of apps that you can use for this. There’s drawing and sketching apps, and then there’s note-taking apps. Personally, I prefer the note-taking apps because they usually have better search tools and organization. The thing that I like that I’m gonna talk about today is GoodNotes 5.

I’ve got all kinds of stuff in here. I’ve got handwritten notes with photographs, I’ve got some typewritten notes, screenshots, other things that I’ve saved, photographs, again. Yeah, I really like using this. I can do storyboards in here, right, or I can draw things, copy and paste them so that I can iterate quickly, make multiple variations over and over again. I can stick in screenshots and then draw on top of them or annotate them. Right, so, let me do a quick demo of using this to draw.

So, one of the things that I’ll do is actually, maybe I’ve drawn some stuff before, and I’ll save that drawing as an image in my photo library. And then I’ll come stick it in here, and I’ll draw on top of it. So, I work on search, so here’s Firefox with no search box. So, I’m gonna draw one. Let’s use some straight lines to draw one. I’m gonna draw a big search box, but I’m doing it here in the middle because I’m gonna place it a little better in a second. And we have the selection tool, and I’m gonna make the, the selection is not selecting images, right? So, I can come over here and just grab my box, and then I can move my box around on top. Okay, so, I still have this gray line. I can’t erase that because it’s an image. So, I’m gonna come over here, and I’m gonna get some white, and I’m gonna just draw over it. Right, okay. Let’s go back and get my gray color. I can zoom in when I need to, and I’m gonna copy this, and I’m gonna pate it a bunch of times. Then I can annotate this. Right, so, there we go.

Another thing that I really like about GoodNotes is the ability to search through stuff that you’ve done. So, I’m gonna search here, and I’m gonna search for spaces. So, this was a thing that we mocked up with a storyboard. This is it right here. And it recognized my, it read my handwriting, which is really cool. So, I can find this thing in a notebook of a jillion pages. But there’s also another way to find things. So, you have this view here, this is called the outline view. These are sorta like named bookmarks. There’s also a thumbnail view, right? Here’s all the pages in this notebook. But if I go to the outlines, so, here, I did some notes about a critique format, and I can jump right to them. But let’s say this new drawing, well, where did I do it? This new drawing, I wanna be able to get to this all the time, right? So, I can come up here, and I can say Add This Page to the Outline, and now I can give it a name. And I don’t know what I’m gonna call this, so I’m just callin’ it sample for right now. And so, now it is in the outline. Oh, I guess I had already done this as a demo. But there it is. And that’s how I can get to it now. That’s super, super cool.

Okay, and then one last thing I wanna show you about this is templates. So, I actually made this template to better fit my setup here. I’ve got no status bar at the top. And then these are just PDFs. And you can import your own. And I can change the template for this page, and I’ve made a storyboard template. And I can apply that here. And now I’ve got a thing so I can draw a storyboard. Or maybe I don’t wanna do a storyboard, but what else do I have? Oh, I wanna do a crazy eights exercise. So, now I’ve got one ready for a crazy eight exercise. I love these templates, they’re super handy. I’ll include those in the post with this, a link to some of these things.

So, that’s sketching on the iPad with GoodNotes 5. Thanks for watching.

 

Hacks.Mozilla.OrgGeckoView in 2019

Logo of GeckoViewLast September we wrote about using GeckoView to bring Firefox’s rendering engine to Android as a reusable library. By decoupling the Gecko engine from the Firefox application, we’ve created a newer, faster, and more maintainable way to create Android applications. This approach leverages Gecko’s excellent performance, privacy, and support for cutting-edge web standards.

With today’s release of our GeckoView-powered Firefox Preview, we’d like to share an update on what we’ve accomplished and where GeckoView is going in 2019.

Introducing Firefox Preview

Wordmark of Firefox PreviewWe’re excited to announce today’s initial release of Firefox Preview (GitHub), an entire browser built from the ground up with GeckoView and Mozilla Android Components at its core. Though still an early preview, this is our first end-user product built completely with these new technologies.

Two screenshots of Firefox Preview showing the home screen and a page loaded with the main menu open

Firefox Preview is our platform for building, testing, and delivering unique features. We’ll use it to explore new concepts for how mobile browsers should look and feel. We encourage you to give it a try!

Other Projects using GeckoView

But that is not all — Mozilla is using GeckoView in many other products as well:

Firefox Focus

Logo of Firefox FocusTo date, Firefox Focus has been our most prominent consumer of GeckoView. Focus’s simplicity lends itself to experimentation. Currently we’re using Focus to split test between GeckoView and Android’s built-in WebView. This helps us ensure that GeckoView’s performance and stability meet or exceed expectations set by Android’s platform libraries.

While Focus is great at what it does, it is not a general purpose browser. By design, Focus does not keep track of history or bookmarks, nor does it support APIs like WebRTC. Yet we need a place to test those features to ensure that GeckoView is sufficiently robust and capable of building fully-featured browsers. That’s where Reference Browser comes in.

Reference Browser

Logo of Reference BrowserLike Firefox Preview, Reference Browser is a full browser built with GeckoView and Mozilla Android Components, but crucially, it is not an end-user product. Its intended audience is browser developers. Indeed, Reference Browser is a proving ground where we validate that GeckoView and the Components fit together and work as expected. We gain the ability to develop our core libraries without the constraints of an in-market product.

Firefox Reality

Logo of Firefox RealityGeckoView also powers Firefox Reality, a browser designed for standalone virtual reality headsets. In addition to leveraging Gecko’s excellent support for immersive web technologies, Firefox Reality demonstrates GeckoView’s versatility. The same library that’s at the heart of “traditional” browsers like Focus and Firefox Preview can also power experiences in an entirely different medium.

Firefox for Android

Logo of FirefoxLastly, while Firefox for Android (“Fennec”) does not use GeckoView for normal browsing, it does use it to support Progressive Web Apps and Custom Tabs. Moreover, because GeckoView and Fennec are both based on Gecko, they jointly benefit from improvements to that common infrastructure.

GeckoView is the foundation of Mozilla’s next generation of mobile products. To better support that future, we’ve halted new feature development on Focus while we concentrate on refining GeckoView and prepare for the launch of Firefox Preview. If you’re interested in supporting Focus in the future, please help by filling out this survey.

Internals

Aside from product development, the past six months have seen many improvements to GeckoView’s internals, especially around compiler-level optimizations and support for additional CPU architectures. Highlights include:

  • Profile-Guided Optimization (PGO) on Android is now enabled, which allows the compiler to generate more efficient code by considering data gathered by actually running and observing GeckoView.
  • The IonMonkey JavaScript JIT compiler is now enabled for 64-bit ARM builds of GeckoView.
  • We’re now producing builds of GeckoView for the x86_64 architecture.

In addition to meeting Google’s upcoming requirements for listing in the Play Store, supporting 64-bit architectures further improves GeckoView’s stability (fewer out-of-memory crashes) and security.

For upcoming releases, we’re working on support for web push and “add to home screen,” among other things.

Get involved

GeckoView isn’t just for Mozilla, we want it to be useful to you.

Thanks to Emily Toop for new work on the GeckoView Documentation website. It’s easier than ever to get started, either as an app developer using GeckoView or as a GeckoView contributor. If you spot something that could be better documented, pull requests are always welcome.

Logos of all GeckoView-powered projects

We’d also love to help you directly. If you need assistance with anything GeckoView-related, you can find us:

Please do reach out with any questions or comments.

The post GeckoView in 2019 appeared first on Mozilla Hacks - the Web developer blog.

Mozilla Future Releases BlogReinventing Firefox for Android: a Preview

At Firefox, we’re passionate about providing solutions for people who care about safety, privacy and independence. For several months, we’ve been working on a new strategy for our Android products to serve you even better. Today we’re very happy to announce a pilot of our new browser for Android devices that is available to early adopters for testing as of now. We’ll have a feature-rich, polished version of this flagship application available for this fall.

Firefox Preview — our new mobile pilot app for Android

Always-on, always private: a new and improved mobile Firefox

Unlike Big Tech, which only recently started to put more emphasis on privacy, we launched Firefox Focus about two and a half years ago, a mobile browser for iOS and Android that allows you to discover the web without being followed around by trackers. While continuously improving Firefox Focus over time, we realized that users demanded a full-fledged mobile browsing experience, but more private and secure than any existing app. So we decided to make Firefox more like Focus, but with all the ease and amenities of a full-featured mobile browser. The result is an early version of what we currently call Firefox Preview.

Bringing Firefox Quantum performance to mobile, with GeckoView

With Firefox Preview, we’re combining the best of what our lightweight Focus application and our current mobile browsers have to offer to create a best in class mobile experience. The new application is powered by Firefox’s own mobile browser engine — GeckoView — the same high-performance, feature enabling motor that fuels our Focus app.

You might remember how we revamped the engine behind the Firefox desktop browser in 2017 enabling us to significantly improve the desktop user experience. As a result, today’s Firefox Quantum is much faster, more efficient, equipped with a modern user interface and clearly the next-gen Firefox. Quite similarly, implementing GeckoView paves the way for a complete makeover of the mobile Firefox experience. While all other major Android browsers today are based on Blink and therefore reflective of Google’s decisions about mobile, Firefox’s GeckoView engine ensures us and our users independence. Building Firefox for Android on GeckoView also results in greater flexibility in terms of the types of privacy and security features we can offer our mobile users. With GeckoView we have the ability to develop faster, more secure and more user friendly browsers that deliver unprecedented performance.

To speak more specifically about features, here are some new functions Firefox Preview will offer, partially enabled by GeckoView:

        • Faster than ever: Firefox Preview is up to 2x faster than previous versions of Firefox for Android.
        • Fast by design: with a minimalist start screen and bottom navigation bar, Preview helps you get more done on the go.
        • Stay organized: Make sense of the web with Collections, a new feature that helps you save, organize, and share collections of sites. Quickly save and return to tasks like your morning routine, shopping lists, travel planning and more.
        • Tracking Protection on by default: Everyone deserves freedom from invasive advertising trackers and other bad actors so Firefox Preview blocks trackers by default. The result is faster browsing and fewer annoyances.

 

 

With Firefox Preview you’re browsing the mobile web faster, more efficiently and more privately

 

For more information about how we’re planning to use GeckoView in our product portfolio, check out this blog post on Mozilla Hacks.

Be among the first to test

Before we release products to the world, we run many different experiments and tests which we learn from and help us make our products better for real consumption. For example, our Firefox Quantum desktop browser has a beta release, a separate channel aimed at developers or early tech adopters to test upcoming features before they’re released to all consumers.

Likewise, what we’re releasing today is an early version for our experimental browser for Android users based on GeckoView. Firefox Preview is a separate mobile application primarily aimed at developers and early adopters who want to help us improve Firefox on Android. The user experience of this early version will differ significantly from the final product, planned for release later this year. We’re counting on our passionate users to try it now and provide the kind of feedback (via email or on Github) that will enable us to release the best mobile Firefox possible and continuously improve GeckoView.

How our new mobile strategy affects existing products

For the rest of 2019, we’re going to direct our efforts into optimizing the entire Firefox experience on all Android devices. In order to have a strong foundation for the next generation of mobile Firefox browsers and put all our efforts and resources in GeckoView, work on Firefox Focus will currently be on hold. Don’t worry though, you can still keep using our privacy browser, Focus, as well as our current Firefox for Android.

Stay tuned for more!

We hope this update from the Firefox Mobile Team sparks excitement for the new mobile strategy we’re rolling out in 2019. We plan to take mobile browsing to a whole new level. No matter where, when or on which device, we at Firefox believe that you always deserve the best possible user experience. And we’ll do our best to bring it to your screens.

Try the preview of our new Firefox for Android, let us know what you think about this GeckoView-based mobile app and stay tuned!

The post Reinventing Firefox for Android: a Preview appeared first on Future Releases.

Chris PearceFirefox's Gecko Media Plugin & EME Architecture

For rendering audio and video Firefox typically uses either the operating system's audio/video codecs or bundled software codec libraries, but for DRM video playback (like Netflix, Amazon Prime Video, and the like) and WebRTC video calls using baseline H.264 video, Firefox relies on Gecko Media Plugins, or GMPs for short.

This blog post describes the architecture of the Gecko Media Plugin system in Firefox, and the major class/objects involved, as it looked in June 2019.

For DRM video Firefox relies upon Google's Widevine Content Decryption Module, a dynamic shared library downloaded at runtime. Although this plugin doesn't conform to the GMP ABI, we provide an adapter to allow it to be run through the GMP system. We use the same Widevine CDM plugin that Chrome uses.

For decode and encode of H.264 streams for WebRTC, Firefox uses OpenH264, which is provided by Cisco. This plugin implements the GMP ABI.

These two plugins are downloaded at runtime from Google's and Cisco's servers, and installed in the user's Firefox profile directory.

We also ship a ClearKey CDM, which is the baseline decryption scheme required by the Encrypted Media Extensions specification. This mimics interface which the Widevine CDM implements, and is used in our EME regression tests. It's bundled with the rest of Firefox, and lives in the Firefox install directory.

The objects involved in running GMPs are spread over three processes; the main (AKA parent) process, the sandboxed content process where we run JavaScript and load web pages, and the sandboxed GMP process, which only runs GMPs.




The main facade to the GMP system is the GeckoMediaPluginService. Clients use the GeckoMediaPluginService to instantiate IPDL actors connecting their client to the GMP process, and to configure the service. In general, most operations which involve IPC to the GMPs/CDMs should happen on the GMP thread, as the GMP related protocols are processed on that thread.

mozIGeckoMediaPluginService can be used on the main thread by JavaScript, but the main-thread accessible methods proxy their work to the GMP thread.

How GMPs are downloaded and installed

The Firefox front end code which manages GMPs is the GMPProvider. This is a JavaScript object, running in the front end code in the main process. On startup if any existing GMPs are already downloaded and installed, this calls mozIGeckoMediaPluginService.addPluginDir() with the path to the GMP's location on disk. Gecko's C++ code then knows about the GMP. The GeckoMediaPluginService then parses the metadata file in that GMP's directory, and creates and stores a GMPParent for that plugin. At this stage the GMPParent is like a template, which stores the metadata describing how to start a plugin of this type. When we come to instantiate a plugin, we'll clone the template GMPParent into a new instance, and load a child process to run the plugin using the cloned GMPParent.

Shortly after the browser starts up (usually within 60 seconds), the GMPProvider will decide whether it should check for new GMP updates. The GMPProvider will check for updates if either it has not checked in the past 24 hours, or if the browser has been updated since last time it checked. If the GMPProvider decides to check for updates, it will poll Mozilla's Addons Update Server. This will return an update.xml file which lists the current GMPs for that particular Firefox version/platform, and the URLs from which to download those plugins. The plugins are hosted by third parties (Cisco and Google), not on Mozilla's servers. Mozilla only hosts the manifest describing where to download them from.

If the GMPs in the update.xml file are different to what is installed, Firefox will update its GMPs to match the update.xml file from AUS. Firefox will download and verify the new GMP, uninstall the old GMP, install the new GMP, and then add the new GMP's path to the mozIGeckoMediaPluginService. The objects that do this are the GMPDownloader and the GMPInstallManager, which are JavaScript modules in the front end code as well.

Note Firefox will take action to ensure its installed GMPs matches whatever is specified in the update.xml file. So if a version of a GMP which is older than what is installed is specified in the update.xml file, Firefox will uninstall the newer version, and download and install the older version. This is to allow a GMP update to be rolled back if a problem is detected with the newer GMP version.

If the AUS server can't be contacted, and no GMPs are installed, Firefox has the URLs of GMPs baked in, and will use those URLs to download the GMPs.

On startup, the GMPProvider also calls mozIGeckoMediaPluginService.addPluginDir() for the ClearKey CDM, passing in its path in the Firefox install directory.

How EME plugins are started in Firefox

The lifecycle for Widevine and ClearKey CDM begins in the content process with content JavaScript calling Navigator.requestMediaKeySystemAccess(). Script passes in a set of MediaKeySystemConfig, and these are passed forward to the MediaKeySystemAccessManager. The MediaKeySystemAccessManager figures out a supported configuration, and if it finds one, returns a MediaKeySystemAccess from which content JavaScript can instantiate a MediaKeys object. 

Once script calls MediaKeySystemAccess.createMediaKeys(), we begin the process of instantiating the plugin. We create a MediaKeys object and a ChromiumCDMProxy object, and call Init() on the proxy. The initialization is asynchronous, so we return a promise to content JavaScript and on success we'll resolve the promise with the MediaKeys instance which can talk to the CDM in the GMP process.

To create a new CDM, ChromiumCDMProxy::Init() calls GeckoMediaPluginService::GetCDM(). This runs in the content process, but since the content process is sandboxed, we can't create a new child process to run the CDM there and then. As we're in the content process, the GeckoMediaPluginService instance we're talking to is a GeckoMediaPluginServiceChild. This calls over to the parent process to retrieve a GMPContentParent bridge. GMPContentParent acts like the GMPParent in the content process. GeckoMediaPluginServiceChild::GetContentParent() retrieves the bridge, and sends a LaunchGMPForNodeId() message to instantiate the plugin in the parent process.

In the non multi-process Firefox case, we still call GeckoMediaPluginService::GetContentParent(), but we end up running GeckoMediaPluginServiceParent::GetContentParent(), which can just instantiate the plugin directly.

When the parent process receives a LaunchGMPForNodeId() message, the GMPServiceParent runs through its list of GMPParents to see if there's one matching the parameters passed over. We check to see if there's an instance from the same NodeId, and if so use that. The NodeId is a hash of the origin requesting the plugin, combined with the top level browsing origin, plus salt. This ensures GMPs from different origins always end up running in different processes, and GMPs running in the same origin run in the same process.

If we don't find an active GMPParent running the requested NodeId, we'll make a copy of a GMPParent matching the parameters, and call LoadProcess() on the new instance. This creates a GMPProcessParent object, which in turn uses GeckoChildProcessHost to run a command line to start the child GMP process. The command line passed to the newly spawned child process causes the GMPProcessChild to run, which creates and initializes the GMPChild, setting up the IPC connection between GMP and Main processes.

The GMPChild delegates most of the business of loading the GMP to the GMPLoader. The GMPLoader opens the plugin library from disk, and starts the Sandbox using the SandboxStarter, which has a different implementation for every platform. Once the sandbox is started, the GMPLoader uses a GMPAdapter parameter to adapt whatever binary interface the plugin exports (the Widevine C API for example) to the match the GMP API. We use the adapter to call into the plugin to instantiate an instance of the CDM. For OpenH264 we simply use a PassThroughAdapter, since the plugin implements the GMP API.

If all that succeeded, we'll send a message reporting success to the parent process, which in turn reports success to the content process, which resolves the JavaScript promise returned by MediaKeySystemAccess.createMediaKeys() with the MediaKeys object, which is now setup to talk to a CDM instance.

Once content JavaScript has a MediaKeys object, it can set it on an HTMLMediaElement using HTMLMediaElement.setMediaKeys().

The MediaKeys object encapsulates the ChromiumCDMProxy, which proxies commands sent to the CDM into calls to ChromiumCDMParent on the GMP thread.

How EME playback works

There are two main cases that we care about here; encrypted content being encountered before a MediaKeys is set on the HTMLMediaElement, or after. Note that the CDM is only usable to the media pipeline once it's been associated with a media element by script calling HTMLMediaElement.setMediaKeys().

If we detect encrypted media streams in the MediaFormatReader's pipeline, and we don't have a CDMProxy, the pipeline will move into a "waiting for keys" state, and not resume playback until content JS has set a MediaKeys on the HTMLMediaElement. Setting a MediaKeys on the HTMLMediaElement causes the encapsulated ChromiumCDMProxy to bubble down past MediaDecoder, through the layers until it ends up on the MediaFormatReader, and the EMEDecoderModule.

Once we've got a CDMProxy pushed down to the MediaFormatReader level, we can use the PDMFactory to create a decoder which can process encrypted samples. The PDMFactory will use the EMEDecoderModule to create the EME MediaDataDecoders, which process the encrypted samples.

The EME MediaDataDecoders talk directly to the ChromiumCDMParent, which they get from the ChromiumCDMProxy on initialization. The ChromiumCDMParent is the IPDL parent actor for communicating with CDMs.

All calls to the ChromiumCDMParent should be made on the GMP thread. Indeed, one of the primary jobs of the ChromiumCDMProxy is to proxy calls made by the MediaKeys on the main thread to the GMP thread so that commands can be sent to the CDM via off main thread IPC.

Any callbacks from the CDM in the GMP process are made onto the ChromiumCDMChild object, and they're sent via PChromiumCDM IPC over to ChromiumCDMParent in the content process. If they're bound for the main thread (i.e. the MediaKeys or MediaKeySession objects), the ChromiumCDMCallbackProxy ensures they're proxied to the main thread.

Before the EME MediaDataDecoders submit samples to the CDM, they first ensure that the samples have a key with which to decrypt the samples. This is achieved by a SamplesWaitingForKey object. We keep a copy in the content process of what keyIds the CDM has reported are usable in the CDMCaps object. The information stored in the CDMCaps about which keys are usable is mirrored in the JavaScript exposed MediaKeySystemStatusMap object.

The MediaDataDecoder's decode operation is asynchronous, and the SamplesWaitingForKey object delays decode operations until the CDM has reported that the keys that the sample requires for decryption are usable. Before sending a sample to the CDM, the EME MediaDataDecoders check with the SamplesWaitingForKey, which looks up in the CDMCaps whether the CDM has reported that the sample's keyId is usable. If not, the SamplesWaitingForKey registers with the CDMCaps for a callback once the key becomes usable. This stalls the decode pipeline until content JavaScript has negotiated a license for the media.

Content JavaScript negotiates licenses by receiving messages from the CDM on the MediaKeySession object, and forwarding those messages on to the license server, and forwarding the response from the license server back to the CDM via the MediaKeySession.update() function. These messages are in turn proxied by the ChromiumCDMProxy to the GMP thread, and result in a call to ChromiumCDMParent and thus an IPC message to the GMP process, and a function call into the CDM there. If the license server sends a valid license, the CDM will report the keyId as usable via a key statuses changed callback.

Once the key becomes usable, the SamplesWaitingForKey gets a callback, and the EME MediaDataDecoder will submit the sample for processing by the CDM and the pipeline unblocks. 

EME on Android

EME on Android is similar in terms of the EME DOM binding and integration with the MediaFormatReader and friends, but it uses a MediaDrmCDMProxy instead of a ChromiumCDMProxy. The MediaDrmCDMProxy doesn't talk to the GMP subsystem, and instead uses the Android platform's inbuilt Widevine APIs to process encrypted samples.

How WebRTC uses OpenH264

WebRTC uses OpenH264 for encode and decode of baseline H.264 streams. It doesn't need all the DRM stuff, so it talks to the OpenH264 GMP via the PGMPVideoDecoder and PGMPVideoEncoder protocols.

The child actors GMPVideoDecoderChild and GMPVideoEncoderChild talk to OpenH264, which conforms to the GMP API.

OpenH264 is not used by Firefox for playback of H264 content inside regular <video>, though there is still a GMPVideoDecoder MediaDataDecoder in the tree should this ever be desired.

How GMP shutdown works

Shutdown is confusing, because there are three processes involved. When the destructor of the MediaKeys object in the content process is run (possibly because it's been cycle or garbage collected), it calls CDMProxy::Shutdown(), which calls through to ChromiumCDMParent::Shutdown(), which cancels pending decrypt/decode operations, and sends a Destroy message to the ChromiumCDMChild.

In the GMP process, ChromiumCDMChild::RecvDestroy() shuts down and deletes the CDM instance, and sends a __delete__ message back to the ChromiumCDMParent in the content process.

In the content process, ChromiumCDMParent::Recv__delete__() calls GMPContentParent::ChromiumCDMDestroyed(), which calls CloseIfUnused(). The GMPContentParent tracks the living protocol actors for this plugin instance in this content process, and CloseIfUnused() checks if they're all shutdown. If so, we unlink the GMPContentParent from the GeckoMediaPluginServiceChild (which is PGMPContent protocol's manager), and close the GMPContentParent instance. This shuts down the bridge between the content and GMP processes.

This causes the GMPContentChild in the GMP process to be removed from the GMPChild in GMPChild::GMPContentChildActorDestroy(). This sends a GMPContentChildDestroyed message to GMPParent in the main process.

In the main process, GMPParent::RecvPGMPContentChildDestroyed() checks if all actors on its side are destroyed (i.e. if all content processes' bridges to this GMP process are shutdown), and will shutdown the child process if so. Otherwise we'll check again the next time one of the GMPContentParents shuts down. 

Note there are a few places where we use GMPContentParent::CloseBlocker. This stops us from shutting down the child process when there are no active actors, but we still need the process alive. This is useful for keeping the child alive in the time between operations, for example after we've retrieved the GMPContentParent, but before we've created the ChromiumCDM (or some other) protocol actor.

How crash reporting works for EME CDMs

Crash handling for EME CDMs is confusing for the same reason as shutdown; because there are three processes involved. It's tricky because the crash is first reported in the parent process, but we need state from the content process in order to identify which tabs need to show the crash reporter notification box.

We receive a GMPParent::ActorDestroy() callback in the main process with aWhy==AbnormalShutdown. We get the crash dump ID, and dispatch a task to run GMPNotifyObservers() on the main thread. This collects some details, including the pluginID, and dispatches an observer service notification "gmp-plugin-crash".  A JavaScript module ContentCrashHandlers.jsm observes this notification, and rebroadcasts it to the content processes.

JavaScript in every content process observes the rebroadcast, and calls mozIGeckoMediaPluginService::RunPluginCrashCallbacks(), passing in the plugin ID. Each content process' GeckoMediaPluginService then goes through its list of GMPCrashHelpers, and finds those which match the pluginID. We then dispatch a PluginCrashed event at the window that the GMPCrashHelper reports as the current window owning the plugin. This is then handled by PluginChild.jsm, which sends a message to cause the crash reporter notification bar to show.

GMP crash reporting for WebRTC

Unfortunately, the code paths for WebRTC handling crashes is slightly different, due to their window being owned by PeerConnection. They don't use GMPCrashHelpers, they have PeerConnection help find the target window to dispatch PluginCrashed to.

Hacks.Mozilla.OrgHow accessibility trees inform assistive tech

The web is accessible by default. It was designed with features to make accessibility possible, and these have been part of the platform pretty much from the beginning. In recent times, inspectable accessibility trees have made it easier to see how things work in practice. In this post we’ll look at how “good” client-side code (HTML, CSS and JavaScript) improves the experience of users of assistive technologies, and how we can use accessibility trees to help verify our work on the user experience.

People browse differently

Assistive Technology (AT) is the umbrella term for tools that help people operate a computer in the way that suits them. Braille displays, for instance, let blind users understand what’s on their screen by conveying that information in braille format in real time. VoiceOver, a utility for Mac and iOS, converts text into speech, so that people can listen to an interface. Dragon NaturallySpeaking is a tool that lets people operate an interface by talking into a microphone.

hand on purple braille terminal with laptop on topA refreshable Braille display (Photo: Sebastien.delorme)

The idea that people can use the web in the way that works best for them is a fundamental design principle of the platform. When the web was invented to let scientists exchange documents, those scientists already had a wide variety of systems. Now, in 2019, systems vary even more.  We use browsers on everything from watches to phones, tablets to TVs. There is a perennial need for web pages that are resilient and allow for user choice. These values of resilience and flexibility have always been core to our work.

AT draws on these fundamentals. Most assistive technologies need to know what happens on a user’s screen. They all must understand the user interface, so that they can convey it to the user in a way that makes sense. Many years ago, assistive technologies relied on OCR (optical character recognition) techniques to figure what was on the screen. Later they consumed markup directly from the browser. On modern operating systems the software is more advanced: accessibility APIs that are built into the platform provide guidance.

How front-end code helps

Platform-specific Accessibility APIs are slightly different depending on the platform. Generally, they know about the things that are platform-specific: the Start Menu in Windows, the Dock on the Mac, the Favorites menu in Firefox… even the address bar in Firefox. But when we use the address bar to access a website, the screen displays information that it probably has never displayed before, let alone for AT users. How can Accessibility APIs tell AT about information on websites? Well, this is where the right client-side HTML, CSS and JavaScript can help.

Whether we write plain HTML, JSX or Jinja, when someone accesses our site, the browser ultimately receives markup as the start for any interface. It turns that markup into an internal representation, called the DOM tree. The DOM tree contains objects for everything we had in our markup. In some cases, browsers also create an accessibility tree, based on the DOM tree, as a tool to better understand the needs and experiences of assistive technology users. The accessibility tree informs platform-specific Accessibility APIs, which then inform Assistive Technologies. So ultimately, our client-side code impacts the experience of assistive technology users.

flow chart, starts at your markup, point at DOM tree, points at accessibility tree, points at platform apis, points at AT, which lists text to speech, screen magnifiers and alternate pointing devices

A flow chart: your markup results in a DOM tree, which impacts the accessibility tree, which informs the Platform APIs, which ultimately impact AT users.

HTML

With HTML, we can be specific about what things are in the page. We can define what’s what, or, in technical terms, provide semantics. For example, we can define something as a:

  • checkbox or a radio button
  • table of structured data
  • list, ordered or unordered, or a list of definitions
  • navigation or a footer area

CSS

Stylesheets can also impact the accessibility tree: layout and visibility of elements are sometimes taken into account. Elements that are set to display: none or visibility: hidden are taken out of the accessibility tree completely. Setting display to table/table-cell can also impact semantics, as Adrian Roselli explains in Tables, CSS display properties and ARIA.

If your site dynamically changes generated content in CSS (::before and ::after), this can also appear or disappear in accessibility trees.

And then, there are properties that can make visual layout differ from DOM order, for example order in grid and flex items, and auto-flow: dense in Grid Layout. When visual order is different from DOM order, it is likely also going to be different from accessibility tree order. This may confuse AT users. The Flexbox spec is quite clear: the CSS order property is “for visual, not logical reordering”.

JavaScript

JavaScript lets us change the state of our components. This is often relevant for accessibility, for instance, we can determine:

  • Is the menu expanded or collapsed?
  • Was the checkbox checked or not?
  • Is the email address field valid or invalid?

Note that accessibility tree implementations can vary, creating discrepancies between browsers.  For instance, missing values are computed to null in some browsers, '' (empty string) in others. Differing implementations are one of many reasons plans to develop a standard are in the works.

What’s in an accessibility tree?

Accessibility trees contain accessibility-related meta information for most of our HTML elements. The elements involved determine what that means, so we’ll look at some examples.

Generally, there are four things in an accessibility tree object:

  • name: how can we refer to this thing? For instance, a link with the text ‘Read more’ will have ‘Read more’ as its name (more on how names are computed in the Accessible Name and Description Computation spec)
  • description: how do we describe this element, if we want to add anything to the name? The description of a table could explain what kind of info that table offers.
  • role: what kind of thing is it? For example, is it a button, a nav bar or a list of items?
  • state: if any, does it have state? Think checked/unchecked for checkboxes, or collapsed/expanded for the `<summary>` element

Additionally, the accessibility tree often contains information on what can be done with an element: a link can be followed, a text input can be typed into, that kind of thing.

Inspecting the accessibility tree in Firefox

All major browsers provide ways to inspect the accessibility tree, so that we can figure out what an element’s name has computed to, or what role it has, according to the browser. For some context on how this works in Firefox, see Introducing the Accessibility Inspector in the Firefox Developer Tools by Marco Zehe.

Here’s how it works in Firefox:

  • In Settings, under Default Developer Tools, ensure that the checkbox “Accessibility” is checked
  • You should now see the Accessibility tab
  • In the Accessibility tab, you’ll find the accessibility tree with all its objectsanimated; shows go to settings, check accessibility, accessibility tab appears

Other browsers

In Chrome, the Accessibility Tree information lives together with the DOM inspector and can be found under the ‘Accessibility’ tab. In Safari, it is in the Node tab in the panel next to the DOM tree, together with DOM properties.

An example

Let’s say we have a form where people can pick their favourite fruit:

<form action="">
  <fieldset>
    <legend>Pick a fruit </legend>
    <label><input type="radio" name="fruit"> Apple</label>
    <label><input type="radio" name="fruit"> Orange</label>
    <label><input type="radio"  name="fruit"> Banana</label>
  </fieldset>
</form>

pick a fruit: radio buttons, all unchecked, apple orange banana

In Firefox, this creates a number of objects, including:

    • An object with a role of grouping, named Pick a fruit
    • Three objects with roles of label, named Apple, Orange and Banana, with action Click, and these states: selectable text, opaque, enabled, sensitive
    • An object with role of radiobutton, named Apple, with action of Select and these states: focusable, checkable, opaque, enabled, sensitive

And so on. When we select ‘Apple’, checked is added to its list of states.

Note that each thing expressed in the markup gets reflected in a useful way. Because we added a legend to the group of radio buttons, it is exposed with a name of ‘Pick a fruit’.  Because we used inputs with a type of radio, they are exposed as such and have relevant states.

As mentioned earlier, we don’t just influence this through markup. CSS and JavaScript can also affect it.

With the following CSS, we would effectively take the name out of the accessibility tree, leaving the fieldset unnamed:

legend { display: none; /* removes item from accessibility tree */ }

This is true in at least some browsers. When I tried it in Firefox, its heuristics still managed to compute the name to ‘Pick a fruit’, in Chrome and Safari it was left out completely. What this means, in terms of real humans: they would have no information as to what to do with Apple, Orange and Banana.

As mentioned earlier, we can also influence the accessibility tree with JavaScript. Here is one example:

const inputApple = document.querySelector(‘input[radio]’);
inputApple.checked = true; // alters state of this input, also in accessibility tree

Anything you do to manipulate DOM elements, directly through DOM scripting or with your framework of choice, will update the accessibility tree.

Conclusion

To provide a great experience to users, assistive technologies present our web pages differently from how we may have intended them. Yet, what they present is based directly on the content and semantic structure that we provide. As designers and developers, we can ensure that assistive technologies understand our pages well writing good HTML, CSS and JavaScript. Inspectable accessibility trees help us verify directly in the browser if our names, roles and state make sense.

The post How accessibility trees inform assistive tech appeared first on Mozilla Hacks - the Web developer blog.

QMOFirefox 68 Beta 10 Testday Results

Hello Mozillians!

As you may already know,  Friday June 14th – we held a new Testday event, for Firefox 68 Beta 10.

Thank you all for helping us make Mozilla a better place: Fernando, noelonassis !

Result: Several test cases were executed for: Sync & Firefox Account and Browser notifications & prompts.

Thanks for another awesome testday, we appreciate your contribution! 🙂

We hope to see you all in our next events, keep an eye on QMO.
We will make announcements as soon as something shows up!

The Firefox FrontierHey advertisers, track THIS

If it feels like the ads chasing you across the internet know you a little too well, it’s because they do (unless you’re an avid user of ad blockers, in … Read more

The post Hey advertisers, track THIS appeared first on The Firefox Frontier.

This Week In RustThis Week in Rust 292

Hello and welcome to another issue of This Week in Rust! Rust is a systems language pursuing the trifecta: safety, concurrency, and speed. This is a weekly summary of its progress and community. Want something mentioned? Tweet us at @ThisWeekInRust or send us a pull request. Want to get involved? We love contributions.

This Week in Rust is openly developed on GitHub. If you find any errors in this week's issue, please submit a PR.

Updates from Rust Community

News & Blog Posts

Crate of the Week

This week's crate is winit, a pure-rust cross-platform window initialization library. Thanks to Osspial for the suggestion!

Submit your suggestions and votes for next week!

Call for Participation

Always wanted to contribute to open-source projects but didn't know where to start? Every week we highlight some tasks from the Rust community for you to pick and get started!

Some of these tasks may also have mentors available, visit the task page for more information.

If you are a Rust project owner and are looking for contributors, please submit tasks here.

Updates from Rust Core

172 pull requests were merged in the last week

Approved RFCs

Changes to Rust follow the Rust RFC (request for comments) process. These are the RFCs that were approved for implementation this week:

No RFCs were approved this week.

Final Comment Period

Every week the team announces the 'final comment period' for RFCs and key PRs which are reaching a decision. Express your opinions now.

RFCs
Tracking Issues & PRs

New RFCs

Upcoming Events

Africa
Asia Pacific
Europe
North America

If you are running a Rust event please add it to the calendar to get it mentioned here. Please remember to add a link to the event too. Email the Rust Community Team for access.

Rust Jobs

Tweet us at @ThisWeekInRust to get your job offers listed here!

Quote of the Week

why doesn't 'static, the largest lifetime, not simply eat all the others

@mountain_ghosts on twitter

@mountain_ghosts 'static is biggest but actually,, weakest of lifetimes, becuase it is subtype of every lifetime

'static is big soft friend

pls love and protect it

@gankro on twitter

Thanks to Christopher Durham for the suggestion!

Please submit quotes and vote for next week!

This Week in Rust is edited by: nasa42, llogiq, and Flavsditz.

Discuss on r/rust.

Emily DunhamMore on Mentorship

More on Mentorship

Last year, I wrote about some of the aspirations which motivated my move from Mozilla Research to the CloudOps team. At the recent Mozilla All Hands in Whistler, I had the “how’s the new team going?” conversation with many old and new friends, and that repetition helped me reify some ideas about what I really meant by “I’d like better mentorship”.

To generalize about how mentors’ careers affect what they can mentor me on, I’ve sketched up a quick figure in order to name some possible situations that people can be in relative to one another:

../../../_images/places-to-find-mentors.png

The first couple cases of mentorship are easy to describe, because I’ve experienced and thought about them for many years already:

Mentorship across industries

Mentors from outside my own industry are valuable for high level perspectives, and for advice on general life and human topics that aren’t specialized to a single field. Additionally, specialists in other industries often represent the consumers of my own industry’s products. Wise and thoughtful people who share little to none of my domain knowledge can provide constructive feedback on why my industry’s work gets particular reactions from the people it affects – just as someone who’s never read a particular book before is likely to catch more spelling errors than its own author, who’s been poring over the same manuscript for many hours a day for several years.

However, for more concrete problems within my particular career (“this program is running slower than expected”, or even “how should I describe that role on my resume?”), observers from outside of it can rarely offer a well tested recommendation of a path forward.

Mentorship across companies within an industry

Similarly, mentors from other companies within my own industry are my go-to source of insight on general trends and technologies. A colleague in a distant corner of my field can tell me about the frustrations they encountered when using a piece of technology that I’m considering, and I can use that advice to make better-informed choices in my daily work.

But advice on a particular company’s peculiarities rarely translates well across organizations. A certain frequency of reorganization might be perfectly ordinary at my company, but a re-org might indicate major problems at another. This type of education, while difficult to get from someone at a different company, is perfectly feasible to pick up from anyone on another team within one’s own organization.

Mentorship across teams within a company

When I switched roles, I had trial-and-errored my way into the observation that there’s a large class of problems with which mentors from different teams within the same company cannot effectively help. I’d tentatively call these “junior engineer problems”, as having overcome their general cases seems to correlate strongly to seniority. In my own expeience, honing the improvement of code-adjacent skills such as the intuition for what problems should be effectively solvable from the docs versus when and whom to ask for help, how deeply to explore a prospective course of action before committing to it, and when to write off an experiment as “effectively impossible”, are all questions whose answers one derives from experience and observing expert peers rather than from just asking them with words.

Mentorship across projects or specialties within a team

I had assumed that simply being on the same team as people capable of imparting that highly specialized variant of common sense would suffice to expose me to it. However, my first few projects on my new team have clearly shown, in both the positive and the negative cases, that working on the same project as an expert is far more useful to my own growth than simply chancing to be bureaucracied into the same group.

The negative case was my first pair of projects: The migration of 2 small, simple services from my team’s AWS infrastructure to GCP. Although I was on the same team as experts in this process, the particular projects were essentially mine alone, and it was up to me to determine how far to proceed on each problem by myself before escalating it to interrupt a busy senior engineer. My heuristics for that process weren’t great, and I knew that at the outset, but my bias toward asking for help later than was optimal slowed the process of improving my ability to draw that line – how can one enhance one’s discrimination between “too soon”, “just right”, and “too late” when all the data points one gathers are in the same one of those categories?

Mentorship within a project

Finally, however, I’m in the midst of a project that demonstrates a positive case for the type of mentorship I switched teams to seek. I’m in the case labeled A on the diagram up above – I’m working with a more-experienced teammate on a project which also includes close collaboration with members of another team within our organization. In examining why this is working so much better for me than my prior tasks, I’ve noticed some differences: First, I’m getting constant feedback on my own expectations for my work. This is no serious nor bureaucratic process, but simply a series of tiny interactions – expressions of surprise when I complete a task effectively, or recommendations to move on to a different approach when something seems to take too long. Similarly, code review from someone immersed in the same problem that I’m working on is indescribably more constructive than review from someone who’s less familiar with the nuances of whatever objective my code is trying to achieve.

Another reason that I suspect I’m improving more quickly than before in this particular task is the opportunity to observe my teammate modeling the skills that I’m learning in his interactions with our colleagues from another team (those in position C on that chart). There’s always a particular trick to asking a question in a way that elicits the category of answer one actually wanted, and watching this trick done frequently in circumstances where I’m up to date on all the nuances and details is a great way to learn.

The FOSS loophole

I suspect I may have been slower to notice these differences than I otherwise might have been, because the start of my career included a lot of fantastic, same-project mentorship from individuals on other teams, at other companies, and even in other industries. This is because my earliest work was on free and open source software and infrastructure. In FOSS, anyone who can pay with their time and computer usage buys access to a cross-company, often cross-industry web of professionals and can derive all the benefits of working directly with mentors on a single project. I was particularly fortunate to draw a wage from the OSU Open Source Lab while doing that work, because the opportunity cost of a hours spent on FOSS by a student who also needs to spend those hours on work is far from free.

Daniel Stenbergopenssl engine code injection in curl

This flaw is known as CVE-2019-5443.

If you downloaded and installed a curl executable for Windows from the curl project before June 21st 2019, go get an updated one. Now.

On Windows, using OpenSSL

The official curl builds for Windows – that the curl project offers – are built cross-compiled on Linux. They’re made to use OpenSSL by default as the TLS backend, the by far most popular TLS backend by curl users.

The curl project has provided official curl builds for Windows on and off through history, but most recently this has been going on since August 2018.

OpenSSL engines

These builds use OpenSSL. OpenSSL has a feature called “engines”. Described by the project itself like this:

“a component to support alternative cryptography implementations, most commonly for interfacing with external crypto devices (eg. accelerator cards). This component is called ENGINE”

More simply put, an “engine” is a plugin for OpenSSL that can be loaded and run dynamically. The particular engine is activated either built-in or by loading a config file that specifies what to do.

curl and OpenSSL engines

When using curl built with OpenSSL, you can specify an “engine” to use, which in turn allows users to use their dedicated hardware when doing TLS related communications with curl.

By default, the curl tool allows OpenSSL to load a config file and figure out what engines to load at run-time but it also provides a build option to make it possible to build curl/libcurl without the ability to load that config file at run time – which some users want, primarily for security reasons.

The mistakes

The primary mistake in the curl build for Windows that we offered, was that the disabling of the config file loading had a typo which actually made it not disable it (because the commit message had it wrong). The feature was therefore still present and would load the config file if present when curl was invoked, contrary to the intention.

The second mistake comes a little more from the OpenSSL side: by default if you build OpenSSL cross-compiled like we do, the default paths where it looks for the above mentioned config file is under the c:\usr\local tree. It is in fact even complicated and impossible to fix this path in the build without a patch.

What the mistakes enable

A non-privileged user or program (the attacker) with access to the host to put a config file in the directory where curl would look for a config file (and create the directory first as it probably didn’t already exist) and the suitable associated engine code.

Then, when an privileged user subsequently executes curl, it will run with more power and run the code, the engine, the attacker had put there. An engine is a piece of compiled code, it can do virtually anything on the machine.

The fix

Already three days ago, on June 21st, a fixed version of the curl executable for Windows was uploaded to the curl web site (“curl 7.65.1_2”). All older versions that had been provided in the past were removed to reduce the risk of someone still using an old lingering download link.

The fix now makes the curl build switch off the loading of the config file, as was already intended. But also, the OpenSSL build that is used for the build is now modified to only load the config file from a privileged path that isn’t world writable (C:/Windows/System32/OpenSSL/).

Widespread mistake

This problem is very widespread among projects on Windows that use OpenSSL. The curl project coordinated this publication with the postgres project and have worked with OpenSSL to make them improve their default paths. We have also found a few other openssl-using projects that already have fixed their builds for this flaw (like stunnel) but I think we have reason to suspect that there are more vulnerable projects out there still not fixed.

If you know of a project that uses OpenSSL and ships binaries for Windows, give them a closer look and make sure they’re not vulnerable to this.

The cat is already out of the bag

When we got this problem reported, we soon realized it had already been publicly discussed and published for other projects even before we got to know about it. Due to this, we took it to publication as quick as possible to minimize user impact as much as we can.

Only on Windows and only with OpenSSL

This flaw only exists on curl for Windows and only if curl was built to use OpenSSL with this bad path and behavior.

Microsoft ships curl as part of Windows 10, but it does not use OpenSSL and is not vulnerable.

Credits

This flaw was reported to us by Rich Mirch.

The build was fixed by Viktor Szakats.

The image on the blog post comes from pixabay.

Cameron KaiserTenFourFox FPR15b1 available

TenFourFox Feature Parity Release 15 beta 1 is now available (downloads, hashes, release notes).

In honour of New Coke's temporary return to the market (by the way, I say it tastes like Pepsi and my father says it tastes like RC), I failed again with this release to get some sort of async/await support off the ground, and we are still plagued by issue 533. The second should be possible to fix, but I don't know exactly what's wrong. The first is not possible to fix without major changes because it reaches up into the browser event loop, but should be still able to get parsing and thus enable at least partial functionality from the sites that depend on it. That part didn't work either. A smaller hack, though, did make it into this release with test changes. Its semantics aren't quite right, but they're good enough for what requires it and does fix some parts of Github and other sites.

However, there are some other feature improvements, including expanded blocking of cryptominers when basic adblock is enabled (from the same list Mozilla uses for enhanced privacy in mainstream Firefox), and updated internationalization support with upgraded timezones and locales such as the new Japanese Reiwa era (for fun, look at Is it Reiwa yet? in FPR14.1 before you download FPR15b1). The usual maintenance and security fixes are (will be) also included (in final). In the meantime, I'm going to take a different pass at the async/await problem for FPR16. If even that doesn't work, we'll have to see where we're at then for parity purposes, since while the majority of websites still work well in TenFourFox's heavily patched-up engine there are an increasing number of major ones that don't. It's hard to maintain a browser engine on your own. :(

Meanwhile, if you'd like the next generation of PowerPC but couldn't afford a Talos II, maybe you can afford a Blackbird. Here's what I thought of it. (See also the followup.)

Karl DubostQuick notes for Mozilla Whistler All Hands 2019

Whistler 2019 Quick Notes

(taken as it comes, without a specific logic, just thoughts here and there. Emotions. To take with a pinch of salt.)

  • Plane trip without a hitch from Japan.
  • Back in Vancouver after 5 years, from the bus windows, I noticed the new high rise condos and I wonder who can afford them when they are so many of them. People living with credits and loans?
  • All the Vietnamese restaurants just make me want to stop to have a Bun Bo Hue.
  • Bus didn’t get a flat tire
  • Two very chatty persons beside me during the full bus trip never stopped talking. A flow of words very difficult to cope with when you are tired with jet lag.
  • Noisy Welcome reception.
  • Happy to see new people, happy to see old friends.
  • Beautiful view, I just want to hop in shoes and hike the trails.
  • Huge North American hotel room with cold Air con and all lights on is a waste.
  • Cafe latte. Wonderful.
  • Uneasy with the Native American dance. Culture out of context.
  • I like Roxy Wen for her direct talk about things.
  • Stan Leong very positive vibe for Mozilla and Taipei office.
  • Less people who seemed to read a script at the Plenary. This is a good thing.
  • Overall good impression of the Plenary on Tuesday.
  • Does Pocket surface blogs which are edited by simple people. What’s happening in there? The promoted content seems to be mainstream editors.
  • Noisy environments do not help to have soft, relaxed discussions.
  • Finding a bug and being in admiration by the explanation of Boris Zbarsky
  • The wonderfully intoxicating smell of cypress in the mornings
  • Early morning and refreshing cold makes me happy.
  • Thanks Brianna for the cafe latte station at the breakfast area.
  • I guess I do not have a very good relationship with marketing. I need to dive into that. Plenary Wednesday.
  • Our perception of privacy is not equally distributed. People have different expectations and habits. People working at Mozilla are privileged compared to the rest of the population.
  • That said, there were comments during the panel by Lindsey Shepard, VP Product Marketing which resonated with me. So maybe, I need to break down my own silos.
  • Performance Workshop. We, the developers, techies are a bourgeoisie (by/through devices) which makes us blind to the reality of common users performances. This tied to the Plenary this morning about knowing the normal people using services online.
  • Congratulations to people who made possible to have a dot release during the All Hands.
  • Little discussions here and there which help you to unpack a of lot of unknown contexts, specifically when you are working remotely. Invaluable.
  • Working. Together.
  • Released a long due version of the code for the webcompat metrics dashboard. Found more bugs. Fixed more bugs. Filed new issues.
  • The demos session made discovered cool projects that I had no idea about. This is useful and cool.
  • Chatting about movies from childhood to now with friends we do not have the opportunities to see each other enough.
  • Laptop… shutting off automatically when the battery reaches 50%, keys 2 and m repeating time to time, and shift key not working 20% of time. This last one is probably the most frustrating. 2 years and this MacBook Pro is not giving good signs of health.
  • Spotted two bears from the gondola on our way to the top of the mountain.
  • Very good feeling about the webcompat metrics discussions after the talk by Mike Taylor. Closer work in between Web Platform Tests and Web Compat sounds like a very good thing. We need to explore and define the small loosely joined hooks that will make it really cool.
  • Firefox Devtools team, you are a bunch of awesome people.
  • Plenaries, for this Whistler All Hands, felt more sincere, more in touch with people with clearer goals for Mozilla (than the last 6 years since I started at Mozilla). So that was cool.
  • Loved the cross-cultural/cross-team vibes.
  • Thanks to the people who are contributing to the projects and give one week of their precious time with their family to work on the projects they care about.
  • Whistler is a very expensive place.
  • Slept through all the ride back from Whistler to Vancouver, avoiding being motion sick.
  • Staying in Vancouver for a couple of days
  • Then heading back to Japan on Wednesday.

Otsukare!

Robert O'CallahanStack Write Traffic In Firefox Binaries

For people who like this sort of thing...

I became interested in how much CPU memory write traffic corresponds to "stack writes". For x86-64 this roughly corresponds to writes that use RSP or RBP as a base register (including implicitly via PUSH/CALL). I thought I had pretty good intuitions about x86 machine code, but the results surprised me.

In a Firefox debug build running a (non-media) DOM test (including browser startup/rendering/shutdown), Linux x86-64, non-optimized (in an rr recording, though that shouldn't matter):

Base registerFraction of written bytes
RAX0.40%
RCX0.32%
RDX0.31%
RBX0.01%
RSP53.48%
RBP44.12%
RSI0.50%
RDI0.58%
R80.01%
R90.00%
R100.00%
R110.00%
R120.00%
R130.00%
R140.00%
R150.00%
RIP0.00%
RDI (MOVS/STOS)0.25%
Other0.00%
RSP/RBP97.59%

Ooof! I expected stack writes to dominate, since non-opt Firefox builds have lots of trivial function calls and local variables live on the stack, but 97.6% is a lot more dominant than I expected.

You would expect optimized builds to be much less stack-dominated because trivial functions have been inlined and local variables should mostly be in registers. So here's a Firefox optimized build:

Base registerFraction of written bytes
RAX1.23%
RCX0.78%
RDX0.36%
RBX2.75%
RSP75.30%
RBP8.34%
RSI0.98%
RDI4.07%
R80.19%
R90.06%
R100.04%
R110.03%
R120.40%
R130.30%
R141.13%
R150.36%
RIP0.14%
RDI (MOVS/STOS)3.51%
Other0.03%
RSP/RBP83.64%

Definitely less stack-dominated than for non-opt builds — but still very stack-dominated! And of course this is not counting indirect writes to the stack, e.g. to out-parameters via pointers held in general-purpose registers. (Note that opt builds could use RBP for non-stack purposes, but Firefox builds with -fno-omit-frame-pointer so only in leaf functions, and even then, probably not.)

It would be interesting to compare the absolute number of written bytes between opt and non-opt builds but I don't have traces running the same test immediately at hand. Non-opt builds certainly do a lot more writes.

Hacks.Mozilla.OrgView Source 5 comes to Amsterdam

Mozilla’s View Source Conference is back for a fifth year, this time in Amsterdam, September 30 – October 1, 2019. Tickets are available now.

What’s new for 2019

This year, we’re trying something new. We’ve shifted our focus to take a deeper look at the web platform and how it is evolving. We’ve planned more interactive sessions, and we’ve partnered with a variety of groups to bring you even more opportunities to engage, learn and participate.

Our goal in 2019 is to offer a unique, two-day, single track conference. With this in mind, we’ll provide ways to engage with engineering and thought leaders from Mozilla, Google, Microsoft, and a variety of individuals and organizations that shape the web today and for the future. These experts will share a perspective on how browser makers, standards bodies, and allies work together to create, support, and implement web standards. Together, we’ll explore what that means for the web platform and the developers and designers who rely on it.

We’ll hear from Google’s Paul Irish and Elizabeth Sweeny on performance, Mozilla’s Selena Deckelman on security and Mike Taylor on web compatibility, along with talks from friends and allies like Henri Helvetica, Hui Jing Chen, Ali Spittel, and Tejas Kumar. Jeremy Keith will close out the event with a new talk, and more speakers will be announced in the coming days and weeks.

Beyond the main stage, we are bringing back “conversation corners.” These breakout sessions create opportunities for attendees to learn from and talk with the people across the industry who are contributing to web standards and building browsers and other tools and technologies.

Come for View Source, stay for Fronteers

To provide a full week’s worth of events, we’ve partnered with Fronteers—Amsterdam’s noted single-track community-driven conference on front-end web development that’s taking place Oct 3-4—to offer combination tickets and shared social events. There’s also a Hack on MDN Web Docs event on Oct 2, where we’ll work on web standards documentation together.

Making sure View Source is representative, inclusive, and accessible is a core goal of the conference. To that end, we’ve set aside 20% of the conference tickets for diversity scholarships. In addition, we will provide live captioning, reserved seating, a lounge for attendees from underrepresented groups, a quiet space, and a focus on a friendly and inclusive environment. We not only have a code of conduct but a strong response and communication plan to ensure that all are welcome, safe, and well-treated.

Tickets & updates

Stay tuned for upcoming announcements. We will put out a CFP for lightning talks and a call for volunteers, as well as information on how to apply for a scholarship in the coming weeks. To keep up with the latest news, including newly announced speakers, please follow @viewsourceconf on Twitter.

View Source 2019 Amsterdam tickets are on sale now. Join us in Amsterdam for a week of amazing events. Want to check out last year’s View Source talks? Our 2018 speaker lineup was spectacular, and we’ll rise to this stellar level again this year.

The post View Source 5 comes to Amsterdam appeared first on Mozilla Hacks - the Web developer blog.

Daniel StenbergGoogle to reimplement curl in libcrurl

Not the entire thing, just “a subset”. It’s not stated very clearly exactly what that subset is but the easy interface is mentioned in the Chrome bug about this project.

What?

The Chromium bug states that they will create a library of their own (named libcrurl) that will offer (parts of) the libcurl API and be implemented using Cronet.

Cronet is the networking stack of Chromium put into a library for use on mobile. The same networking stack that is used in the Chrome browser.

There’s also a mentioned possibility that “if this works”, they might also create “crurl” tool which is then their own version of the curl tool but using their own library. In itself is a pretty strong indication that their API will not be fully compatible, as if it was they could just use the existing curl tool…

Why?

“Implementing libcurl using Cronet would allow developers to take advantage of the utility of the Chrome Network Stack, without having to learn a new interface and its corresponding workflow. This would ideally increase ease of accessibility of Cronet, and overall improve adoption of Cronet by first-party or third-party applications.”

Logically, I suppose they then also hope that 3rd party applications can switch to this library (without having to change to another API or adapt much) and gain something and that new applications can use this library without having to learn a new API. Stick to the old established libcurl API.

How?

By throwing a lot of man power on it. As the primary author and developer of the libcurl API and the libcurl code, I assume that Cronet works quite differently than libcurl so there’s going to be quite a lot of wrestling of data and code flow to make this API work on that code.

The libcurl API is also very versatile and is an API that has developed over a period of almost 20 years so there’s a lot of functionality, a lot of options and a lot of subtle behavior that may or may not be easy or straight forward to mimic.

The initial commit imported the headers and examples from the curl 7.65.1 release.

Will it work?

Getting basic functionality for a small set of use cases should be simple and straight forward. But even if they limit the subset to number of functions and libcurl options, making them work exactly as we have them documented will be hard and time consuming.

I don’t think applications will be able to arbitrarily use either library for a very long time, if ever. libcurl has 80 public functions and curl_easy_setopt alone takes 268 different options!

Given enough time and effort they can certainly make this work to some degree.

Releases?

There’s no word on API/ABI stability or how they intend to ship or version their library. It is all very early still. I suppose we will learn more details as and if this progresses.

Flattered?

I think this move underscores that libcurl has succeeded in becoming an almost defacto standard for network transfers.

<figcaption>A Google office building in New York.</figcaption>

There’s this saying about imitation and flattery but getting competition from a giant like Google is a little intimidating. If they just put two paid engineers on their project they already have more dedicated man power than the original libcurl project does…

How will it affect curl?

First off: this doesn’t seem to actually exist for real yet so it is still very early.

Ideally the team working on this from Google’s end finds and fixes issues in our code and API so curl improves. Ideally this move makes more users aware of libcurl and its API and we make it even easier for users and applications in the world to do safe and solid Internet transfers. If the engineers are magically good, they offer a library that can do things better than libcurl can, using the same API so application authors can just pick the library they find work the best. Let the best library win!

Unfortunately I think introducing half-baked implementations of the API will cause users grief since it will be hard for users to understand what API it is and how they differ.

Since I don’t think “libcrurl” will be able to offer a compatible API without a considerable effort, I think applications will need to be aware of which of the APIs they work with and then we have a “split world” to deal with for the foreseeable future and that will cause problems, documentation problems and users misunderstanding or just getting things wrong.

Their naming will possibly also be reason for confusion since “libcrurl” and “crurl” look so much like typos of the original names.

We are determined to keep libcurl the transfer library for the internet. We support the full API and we offer full backwards compatibility while working the same way on a vast amount of different platforms and architectures. Why use a copy when the original is free, proven and battle-tested since years?

Rights?

Just to put things in perspective: yes they’re perfectly allowed and permitted to do this. Both morally and legally. curl is free and open source and licensed under the MIT license.

Good luck!

I wish the team working on this the best of luck!

Updates after initial post

Discussions: the hacker news discussion, the reddit thread, the lobsters talk.

Rename? it seems the google library might change name to libcurl_on_cronet.

Cameron KaiserStand by for FPR14 SPR1 chemspill

Mozilla has shipped a fix for MFSA2019-18 in Firefox 67.0.3 and 60.7.1. This exploit has been detected in the wild, and while my analysis indicates it would require a PowerPC-specific attack to be exploitable in official TenFourFox builds (the Intel versions may be directly exploited, however), it could probably cause drive-by crashes and we should therefore ship an urgent fix as well. The chemspill is currently undergoing confidence tests and I'm shooting to release builds before the weekend. For builders, the only change in FPR14 SPR1 is the patch for bug 1544386, which I will be pushing to the repo just as soon as I have confirmed the fix causes no regressions.

This chemspill also holds up the FPR15 beta which was actually scheduled for today. Unfortunately, the big JavaScript update I've been trying to make for the last couple cycles also ran aground and will not be in FPR15 either. There is a smaller one and some other improvements, so this is not an empty release, but I'll talk more about that in a few days.

Hacks.Mozilla.OrgCSS Scroll Snap Updated in Firefox 68

When Firefox 68 goes to general release next month, it will ship with an updated CSS Scroll Snap specification. This means that Firefox will support the same version of the specification as Chrome and Safari. Scroll snapping will work in the same way across all browsers that implement it.

In this post, I’ll give you a quick rundown of what scroll snapping is. I will also explain why we had a situation where browsers had different versions of the specification for a time.

What is CSS Scroll Snap?

The CSS Scroll Snap specification gives us a way in CSS to snap between different elements in a page or scrolling component, in a very similar fashion to how native apps work on phones and tablets.

Scroll snapping can happen on the x or y axis. This means that you can swipe in both the inline and the block direction depending on your requirements. In the example below I demonstrate a very simple use of scroll snapping. I have a scrolling box, which has a vertical scrollbar due to overflow-y being specified, and the box being given a height. I have then added the property scroll-snap-type: x mandatory, which gives us mandatory scrolling on the x axis. You can see this example in the CodePen.

.scroller {
  height: 300px;
  overflow-y: scroll;
  scroll-snap-type: x mandatory;
}

View the CodePen example.

Mandatory scrolling means that the browser has to snap to a scroll point, no matter where in the content the user is. The other available keyword is proximity. Proximity causes the browser to only snap to the scroll point when the scroll is near that point. This prevents situations where the user is unable to scroll to a certain point because that point is outside the visible area.

In addition to the scroll-snap-type property on the scroll container, I need to add the scroll-snap-align property to define the point that the scroll will snap to. This property takes a value of start, center, or end, which defines where in the child container the scroll should snap to:

.scroller section {
  scroll-snap-align: start;
}

For many use cases, these key properties will be all that you need to get your scroll snapping to work. However, the specification defines a way to add padding and/or margins to the scroll point. This can help in certain cases where you don’t want the scroll to snap right to the edge of the scrollable area.

For example, below I have used the scroll-padding-top property to leave a gap. This makes space for the fixed element at the top of the container. If I didn’t do this, I would risk content ending up underneath that bar.

h1 {
  position: sticky;
  top: 0;
}

.scroller {
  height: 300px;
  overflow-y: scroll;
  scroll-snap-type: y mandatory;
  scroll-padding-top: 40px;
}

.scroller section {
  scroll-snap-align: start;
}

View this example on CodePen.

On MDN we have pages for the various Scroll Snap properties. A guide to using Scroll Snap offers lots of additional examples. The property pages all show the status of browser support for these properties.

What has changed in Firefox 68?

Firefox 68 implements the version of scroll snap as described above, according to the current version of the specification. This matchs the Chrome implementation. If you have implemented scroll snap to work in Chrome, then you don’t need to do anything — your scroll snapping will now work in Firefox.

If you used the old version of the specification as it was implemented in Firefox in version 39, you should update that code to use the new version. In addition to implementing the new spec, Firefox 68 will remove support for properties from the old version of the spec.

If you have used scroll-snap-type-x and scroll-snap-type-y, then you are using the old spec. These properties are removed in Firefox 68. scroll-snap-type is now used to set the x or y direction along with the type of scroll snapping.

Why were there two versions of scroll snap?

CSS specifications are developed in an iterative way, and browsers begin to implement specifications while they are in the process of being developed. This is an important step. The CSS Working Group needs to know that it is possible to implement the specification in browsers. Test implementations let web developers try out a new spec and file issues against it. Often these implementations happen behind a browser flag. In the past we’ve used vendor-prefixed versions to expose them for testing. Sometimes, however, a specification is in a seemingly good state and therefore implemented, but then changes need to be made. Such is the way of developing new browser features.

In some cases, a change like this means that the old and new properties have to be supported forever. The grid-gap property is a good example. The property has been renamed to gap. Due to significant usage in the wild, the grid-gap property is being maintained as an alias. In the case of Scroll Snap, usage of that old experimental spec was very low, and therefore the scroll-snap-type property has been updated in a non-backwards compatible way. This means that the old version will be removed at this point.

Backwards compatibility and scroll snap

Scroll Snap is one of those specifications that can act as a nice enhancement in many cases. If the browser does not support scroll snapping, then regular scrolling will happen instead. We have information on MDN which can help you to implement the old specification as a fallback for old Firefox versions, if your analytics show this is necessary. For most use cases this is unlikely to be required.

It’s great to see another CSS specification get wide browser implementation. If you have used JavaScript to get a scroll snapping effect in the past, it might be a good time to take a look at the CSS version! You are likely to find that it performs far better than a JavaScript solution.

The post CSS Scroll Snap Updated in Firefox 68 appeared first on Mozilla Hacks - the Web developer blog.

This Week In RustThis Week in Rust 291

Hello and welcome to another issue of This Week in Rust! Rust is a systems language pursuing the trifecta: safety, concurrency, and speed. This is a weekly summary of its progress and community. Want something mentioned? Tweet us at @ThisWeekInRust or send us a pull request. Want to get involved? We love contributions.

This Week in Rust is openly developed on GitHub. If you find any errors in this week's issue, please submit a PR.

Updates from Rust Community

News & Blog Posts

Crate of the Week

This week's crate is safe, a #[safe] attribute for explaining why unsafe { ... } is OK. Thanks to Michael-F-Bryan for the suggestion!

Submit your suggestions and votes for next week!

Call for Participation

Always wanted to contribute to open-source projects but didn't know where to start? Every week we highlight some tasks from the Rust community for you to pick and get started!

Some of these tasks may also have mentors available, visit the task page for more information.

If you are a Rust project owner and are looking for contributors, please submit tasks here.

Updates from Rust Core

205 pull requests were merged in the last week

Approved RFCs

Changes to Rust follow the Rust RFC (request for comments) process. These are the RFCs that were approved for implementation this week:

No RFCs were approved this week.

Final Comment Period

Every week the team announces the 'final comment period' for RFCs and key PRs which are reaching a decision. Express your opinions now.

RFCs

No RFCs are currently in final comment period.

Tracking Issues & PRs

No issues are currently in final comment period.

New RFCs

No new RFCs were proposed this week.

Upcoming Events

Africa
Asia Pacific
Europe
North America

If you are running a Rust event please add it to the calendar to get it mentioned here. Please remember to add a link to the event too. Email the Rust Community Team for access.

Rust Jobs

Tweet us at @ThisWeekInRust to get your job offers listed here!

Quote of the Week

No quote was selected for QotW.

Please submit quotes and vote for next week!

This Week in Rust is edited by: nasa42, llogiq, and Flavsditz.

Discuss on r/rust.

Robert HelmerVectiv and the Browser Monoculture

So, so tired of the "hot take" that having a single browser engine implementation is good, and there is no value to having multiple implementations of a standard. I have a little story to tell about this.

In the late 90s, I worked for a company called Vectiv. There isn't much info on the web (the name has been used by other companies in the meantime), this old press release is one of the few I can find.

Vectiv was a web-based service for commercial real estate departments doing site selection. This was pretty revolutionary at the time, as the state-of-the-art for most of these was to buy a bunch of paper maps and put them up on the walls, using push-pins to keep track of current and possible store locations.

The story of Vectiv is interesting on its own, but the relevant bit to this story is that it was written for and tested exclusively in IE 5.5 for Windows, as was the style at the time. The once-dominant Netscape browser had plummeted to negligible market share, and was struggling to rewrite Netscape 6 to be based on the open-source Mozilla Suite.

Around this time, Apple was starting to have a resurgence. Steve Jobs had returned, and the candy-colored iMac was proving to be successful. Apple was planning to launch official stores, and the head of their real estate department was a board member of Vectiv, so we managed to land our first deal - a pilot project with Apple's nascent real estate department.

We picked up a few iMacs around the office for testing, and immediately hit a snag - Steve had ordered that everyone in the company, real estate dept included, has to use the new Mac OS X. The iMacs that the dept used (and that we tested on) were pretty slow, but serviceable. The real snag was that our product didn't really work on IE for Mac. Like, at all. Pages wouldn't load, and the browser would consistently crash on certain pages.

This was before Safari and its Webkit engine, We started debugging and rewriting bits of the product, and simultaneously talking to Microsoft about our problems. They were responsive, and hopeful the upcoming update would fix some of our problems. Sadly, there were to be no further updates for IE 5 for Mac.

I was something on a Unix fanboy at the time, and had been using early releases of Mozilla Suite on my Solaris workstation, so I knew that our product basically worked with some rough edges (mostly minor things like CSS, with a few less trivial problems around divergent web standards.)

Long story short, our QA manager and myself visited Apple's real estate and test folks, and we settled on using Mozilla 0.6 for the pilot, and corresponding Netscape 6 when it was released (I think we ended up using Netscape 7.1, which I recall being a lot more usable, being based on Mozilla 1.4)

Vectiv had other clients like Dollartree and Quiznos, but getting over that initial pilot hurdle was key to proving that our product worked and had backing from a known brand. Vectiv was VC backed and like many startups caught up in the dot-com crash ran out of runway, although the product was sold and did live on. I did a few consulting gigs setting up local installs for the remaining clients.

Most people reading this probably know the rest of the story - IE stagnated, AOL pulled the plug on Netscape, and Mozilla Suite was reborn as the Firefox browser. With MS moving to Google Chrome's Blink browser engine, Mozilla Firefox's Gecko engine along with Apple Safari's Webkit are the only independent implementations of the various web standards.

(Blink is technically a fork of Webkit, but IE and Netscape were ultimately forks of NCSA Mosaic, I think it's fair to call it independent at this point.)

To be clear: having multiple browser engines didn't ultimately save Vectiv, but Firefox did open the door for Safari and Chrome, as Firefox's Firebug (the predecessor of today's integrated devtools) enticed web developers enough that they made their sites more standards-compliant just so they could have access to nice devtools.

It's easy for me to write a nice narrative of the past, complete with the moral of the story. The future isn't totally certain, but it's clear that the web will continue to play a large role in the world. Let's not (again) back ourselves into a corner and cede all meaningful control over that future.

Mozilla Security BlogUpdated GPG key for signing Firefox Releases

The GPG key used to sign the Firefox release manifests is expiring soon, and so we’re going to be switching over to new key shortly.

The new GPG subkey’s fingerprint is 097B 3130 77AE 62A0 2F84 DA4D F1A6 668F BB7D 572E, and it expires 2021-05-29.

The public key can be fetched from KEY files from Firefox 68 beta releases, or from below. This can be used to validate existing releases signed with the current key, or future releases signed with the new key.

-----BEGIN PGP PUBLIC KEY BLOCK-----

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
=xFcH
-----END PGP PUBLIC KEY BLOCK-----

The post Updated GPG key for signing Firefox Releases appeared first on Mozilla Security Blog.

Chris AtLeeUpdated GPG key for signing Firefox Releases

The GPG key used to sign the Firefox release manifests is expiring soon, and so we're going to be switching over to new key shortly.

The new GPG subkey's fingerprint is 097B 3130 77AE 62A0 2F84 DA4D F1A6 668F BB7D 572E, and it expires 2021-05-29.

The public key can be fetched from KEY files from Firefox 68 beta releases, or from below. This can be used to validate existing releases signed with the current key, or future releases signed with the new key.

-----BEGIN PGP PUBLIC KEY BLOCK-----

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
=xFcH
-----END PGP PUBLIC KEY BLOCK-----

Mozilla Addons BlogExtensions in Firefox 68

In Firefox 68, we are introducing a new API and some enhancements to webRequest and private browsing. We’ve also fixed a few issues in order to improve compatibility and resolve issues developers were having with Firefox.

Captivating Add-ons

At airports and cafés you may have seen Firefox asking you to log in to the network before you can access the internet. In Firefox 68, you can make use of this information in an extension. The new captive portal API will assist you in making sure your add-on works gracefully when locked behind a captive portal.

For example, you could hold off your requests until network access is available again. If you have been using other techniques for detecting captive portals, we encourage you to switch to this API so your extension uses the same logic as Firefox.

Here is an example of how to use this API:

(async function() {
  // The current portal state, one of `unknown`, `not_captive`, `unlocked_portal`, `locked_portal`.
  let state = await browser.captivePortal.getState();

  // Get the duration since the captive portal state was last checked
  let lastChecked = await browser.captivePortal.getLastChecked();

  console.log(`The captive portal has been ${state} since at least ${lastChecked} milliseconds`);

  browser.captivePortal.onStateChanged.addListener((details) => {
    console.log("Captive portal state is: " + details.state);
  });

  browser.captivePortal.onConnectivityAvailable.addListener((status) => {
    // status can be "captive" in an (unlocked) captive portal, or "clear" if we are in the open
    console.log("Internet connectivity is available: " + status);
  });
})();

Note: if you use this API, be sure to add the captivePortal permission to your manifest.

Private and contained

We’ve made a few additions to the webRequest API to better support private browsing mode. You can now limit your webRequests to only include requests from private browsing mode. If instead you are interested in both types of requests it is now possible to differentiate them in the webRequest listener.

To improve the integration of containers, we’ve also added the container ID (cookieStoreId) to the webRequest listener.

Proxy new and proxy old

The two additional fields mentioned in the previous section are also available in the details object passed to the proxy.onRequest listener.

At the same time, we’d like to make you aware that we are deprecating the proxy.register, proxy.unregister and proxy.onProxyError APIs. As an alternative, you can use the proxy.onRequest API to determine how requests will be handled, and proxy.onError to handle failures. If your extension is using these APIs you will see a warning in the console. These APIs will ultimately be removed in Firefox 71, to be released on December 10th, 2019.

Timing is everything

We’ve changed the timing of tabs.duplicate for better compatibility with Chrome. The promise is now resolved immediately, before the duplicated tab finished loading. If you have been relying on this promise for a completed duplicated tab in Firefox, please adjust your code and make use of the tabs.onUpdated listener.

Miscellaneous

    • Since extensions cannot add bookmarks to the root folder, we’ve improved the error message you get when you try.
    • If you’ve been trying to remove indexedDB data via browser.browsingData.remove({}, { indexedDB: true }); and it failed in some cases, we’ve fixed this on our end now.
    • Removing cookies for IPv6 addresses has been fixed.
    • Fixes an issue when setting cookies with an IP address in the domain field, along with the url field being set.
    • Hard-to-debug performance issues using webRequest.onBeforeRequest with requestBody during large uploads have been solved.
    • An issue with identity.launchWebAuthFlow hanging after authentication has been resolved.
    • storage.onChanged is now fired when values are removed.

Thank You

We’ve had a great amount of support from the community. I’d like to thank everyone who has taken part, but especially our volunteer contributors Jan Henning, Myeongjun Go, Oriol Brufau, Mélanie Chauvel, violet.bugreport and Piro. If you are interested in contributing to the WebExtensions ecosystem, please take a look at our wiki.

The post Extensions in Firefox 68 appeared first on Mozilla Add-ons Blog.

Will Kahn-GreeneSocorro: May 2019 happenings

Summary

Socorro is the crash ingestion pipeline for Mozilla's products like Firefox. When Firefox crashes, the crash reporter collects data about the crash, generates a crash report, and submits that report to Socorro. Socorro saves the crash report, processes it, and provides an interface for aggregating, searching, and looking at crash reports.

This blog post summarizes Socorro activities in May.

Read more… (5 min remaining to read)

Mozilla Open Innovation TeamA Firefox browser extension promoting quality online content?

We are excited to announce the launch of the “What’s your idea for a Firefox extension for promoting credible content?”, a competition sponsored by Mozilla and posted to MindSumo, the world’s largest crowdsourcing community of Millennial and GenZ solvers. The goal of the competition is to create an extension (or other browser technology solution) to help internet users identify credible voices and credible sources of information online.

The Problems Plaguing the Internet of Today

Imagine the internet that is a place where meaningful and credible content is easily found. A place where everyone feels safe, empowered, and accurately informed.

Is this the internet we’re having today? Unfortunately, not. Today’s internet is unsavory mix of intrusive advertising, misinformation, and toxic social media full of offensive language, harassment, and harmful content. The problems plaguing the web are magnified by the economy that benefits from engagement of the most extreme and attention-grabbing material. Instead of improving a civil, informed online discourse, the internet of today is degrading it.

Solutions to the internet problems exist. Interestingly enough, they are owned by the large tech companies that allowed the problems grow and fester. However, the tech giants are reluctant to implement these solutions because doing so may negatively affect their bottom lines.

Mozilla is a recognized leader in the field of online Privacy & Security. Our commitment to the open and human internet anchored in the Mozilla Manifesto is solidified by our unwavering desire to put people before profits. This commitment was on display again recently with Mozilla’s launch of Enhanced Tracking Protection that blocks third-party tracking cookies by default.

Removing “Bad” Content or Promoting a Quality One?

Ensuring safe internet browsing is only part of Mozilla’s efforts to protect its users; equally important is fighting online harassment. Two general approaches can be considered here. The first is to design online tools to remove or filter “bad” content. However, serious doubts have been expressed whether this approach is technically feasible at all. Besides, this approach is also threatening free expression and the open internet ecosystem.

Instead of asking how we can filter hateful and misleading content, we’re asking: How can browser technology amplify credible and quality content and conversations?

As part of this new paradigm, we’ve launched a crowdsourcing challenge to identify approaches to using Firefox extensions or other browser technology solutions to find and promote credible sources of information online. (For a primer to technological approaches to access credibility online, see this report.)

How to Participate

The challenge was posted to the MindSumo platform, the world’s largest crowdsourcing community of Millennial and GenZ solvers. The competition will run until July 7 and the submitted proposals will be evaluated by the members of Mozilla’s Privacy & Security and Product Management teams. Up to $1,600 in prizes will be awarded to the best proposals.

The challenge is open to everyone (except for Mozilla employees and their families), and we especially encourage members of Mozilla’s communities to take part in it.


A Firefox browser extension promoting quality online content? was originally published in Mozilla Open Innovation on Medium, where people are continuing the conversation by highlighting and responding to this story.

Mozilla Open Design BlogFirefox: The Evolution Of A Brand

Consider the fox. It’s known for being quick, clever, and untamed — attributes easily applied to its mythical cousin, the “Firefox” of browser fame. Well, Firefox has another trait not found in earthly foxes: stretchiness. (Just look how it circumnavigates the globe.) That fabled flexibility now enables Firefox to adapt once again to a changing environment.

The “Firefox” you’ve always known as a browser is stretching to cover a family of products and services united by putting you and your privacy first. Firefox is a browser AND an encrypted service to send huge files. It’s an easy way to protect your passwords on every device AND an early warning if your email has been part of a data breach. Safe, private, eye-opening. That’s just the beginning of the new Firefox family.

Now Firefox has a new look to support its evolving product line. Today we’re introducing the Firefox parent brand — an icon representing the entire family of products. When you see it, it’s your invitation to join Firefox and gain access to everything we have to offer. That includes the famous Firefox Browser icon  for desktop and mobile, and even that icon is getting an update to be rolled out this fall.

Here’s a peek behind the curtain of how the new brand look was born:

Design beyond identity.

This update is about more than logos. The Firefox design system includes everything we need to make product and web experiences today and long into the future.

  • A new color palette that expands the range of possibilities and makes distinctive gradients possible.

  • A new shape system derived from the geometry of the product logos that makes beautiful background patterns, spot illustrations, motion graphics and pictograms.

  • A modern typeface for product marks with a rounded feel that echoes our icons.

  • An emphasis on accessible color and type standards to make the brand open to everyone. Button colors signal common actions within products and web experiences.

Meaning beyond design.

Privacy is woven into every Firefox brand experience. With each release, our products will continue to add features that protect you and alert you to risks. Unlike Big Tech companies that claim to offer privacy but still use you and your data, with us you know where you stand. Everything Firefox is backed by our Personal Data Promise: Take Less, Keep It Safe, No Secrets.

The brand system is built on four pillars, present in everything we make and do:

Radical. It’s a radical act to be optimistic about the future of the internet. It’s a radical act to serve others before ourselves. We disrupt the status quo because it’s the right thing to do.

Kind. We want what’s best for the internet and for the world. So we lead by example. Build better products. Start conversations, Partner, collaborate, educate and inform. Our empathy extends to everybody.

Open. Open-minded. Open-hearted. Open source. An open book. We make transparency and a global perspective integral to our brand, speaking many languages and striving to reflect all vantage points.

Opinionated. Our products prove that we are driven by strong convictions. Now we’re giving voice to our point of view. While others can speak only to settings, we ground everything in our ethos.

The end of the beginning

The Firefox brand exploration began more than 18 months ago, and along the way we tapped into many talents. Michael Johnson of Johnson Banks provided early inspiration while working on the Mozilla brand identity. Jon Hicks, the designer behind the original Firefox browser logo, was full of breathtaking design and wise advice. Michael Chu of Ramotion was the driving force behind the new parent brand and system icons.

We worked across internal brand, marketing, and product teams to reach a consistent brand system for our users. Three members of our cross-org team have since moved on to new adventures: Madhava Enros, Yuliya Gorlovetsky, and Vince Joy. Along with Mozilla team members Liza Ruzer, Stephen Horlander, Natalie Linden, and Sean Martell, they formed the core working team.

Finally, we’re grateful to everyone who has commented on this blog with your passionate opinions, critiques, words of encouragement, and unique points of view.

Tell us. We can take it.

As a living brand, Firefox will never be done. It will continue to evolve as we change and the world changes around us. We have to stretch our brand guidelines even further in the months ahead, so we’re interested in hearing your reaction to what we’ve done so far. Feel free to let us know in the comments below. Thanks for being with us on this journey, and please stay tuned for more.

The post Firefox: The Evolution Of A Brand appeared first on Mozilla Open Design.

Adrian Gaudebertreact-content-marker Released – Marking Content with React

Last year, in a React side-project, I had to replace some content in a string with HTML markup. That is not a trivial thing to do with React, as you can't just put HTML as string in your content, unless you want to use dangerouslySetInnerHtml — which I don't. So, I hacked a little code to smartly split my string into an array of sub-strings and DOM elements.

More recently, while working on Translate.Next — the rewrite of Pontoon's translate page to React — I stumbled upon the same problem. After looking around the Web for a tool that would solve it, and coming up short handed, I decided to write my own and make it a library.

Introducing react-content-marker v1.0

react-content-marker is a library for React to mark content in a string based on rules. These rules can be simple strings or regular expressions. Let's look at an example.

Say you have a blob of text, and you want to make the numbers in that text more visible, for example by making them bold.

const content = 'The fellowship had 4 Hobbits but only 1 Dwarf.';

Matching numbers can be done with a simple regex: /(\d+)/. If we turn that into a parser:

const parser = {
    rule: /(\d+)/,
    tag: x => <strong>{ x }</strong>,
};

We can now use that parser to create a content marker, and use it to enhance our content:

import createMarker from 'react-content-marker';
const Marker = createMarker([parser]);
render(<Marker>{ content }</Marker>);

This will show:

The fellowship had 4 Hobbits but only 1 Dwarf.

Hurray!

Advanced usage

Passing parsers

The first thing to note is that you can pass any number of parsers to the createMarker function, and they will all be called in turn. The order of the parsers is very important though, because content that has already been marked will not be parsed again. Let's look at another example.

Say you have a rule that matches content between brackets: /({.*})/, and a rule that matches content between brackets that contain only capital letters: /({[A-W]+})/. Now let's say you are marking this content: I have {CATCOUNT} cats. Whichever rule you passed first will match the content between brackets, and the second rule will not apply. You thus need to make sure that your rules are ordered so that the most important ones come first. Generally, that means you want to have the more specific rules first.

The reason why this happens is that, behind the scene, the matched content is turned into a DOM element, and parsers ignore non-string content. With the previous example, the initial string, I have {CATCOUNT} cats, would be turned into ['I have ', &lt;mark>{CATCOUNT}&lt;/mark>, ' cats'] after the first parser is called. The second one then only looks at 'I have ' and ' cats', which do not match.

Using regex

The second important thing to know relates to regex. You might have noticed that I put parentheses in my examples above: they are required for the algorithm to capture content. But that also gives you more flexibility: you can use a regex that matches some content that you do not want to mark. Let's say you want to match only the name of someone who's being greeted, with this rule: /hello (\w+)/i. Applying it to Hello Adrian will only mark the Adrian part of that content.

Sometimes, however, you need to use more complex regex that include several groups of parentheses. When that's the case, by default react-content-marker will mark the content of the last non-null capturing group. In such cases, you can add a matchIndex number to your parser: that index will be used to select the capture group to mark.

Here's a simple example:

const parser = {
    rule: /(hello (world|folks))/i,
    tag: x => <b>{ x }</b>,
};

Applying this rule to Hello World will show: Hello World. If we want to, instead, make the whole match bold, we'll have to use matchIndex:

const parser = {
    rule: /(hello (world|folks))/i,
    matchIndex: 0,
    tag: x => <b>{ x }</b>,
};

Now our entire string will correctly be made bold: Hello World.

Advanced example

If you're interested in looking at an advanced usage example of this library, I recommend you check out how we use in Pontoon, Mozilla's localization platform. We have a long list of parsers there, and they have a lot of edge-cases.

Installation and stuff

react-content-marker is available on npm, so you can easily install it with your favorite javascript package manager:

npm install -D react-content-marker
# or
yarn add react-content-marker

The code is released under the BSD 3-Clause License, and is available on github. If you hit any problems with it, or have a use case that is not covered, please file an issue. And of course, you are always welcome to contribute a patch!

I hope this is useful to someone out there. It has been for me at least, on Pontoon and on several React-based side-projects. I like how flexible it is, and I believe it does more than any other similar tools I could find around the Web.

QMOFirefox 68 Beta 10 Testday, June 14th

Hello Mozillians,

We are happy to let you know that Friday, June 14th we are organizing Firefox 68 Beta 10 Testday. We’ll be focusing our testing on: Sync & Firefox Account and Browser notifications & prompts.

Check out the detailed instructions via this etherpad.

No previous testing experience is required, so feel free to join us on #qa IRC channel where our moderators will offer you guidance and answer your questions.

Join us and help us make Firefox better!

See you on Friday! 🙂

Mozilla Privacy BlogIt’s time for the US Senate to Save the Net

On the one year anniversary of the Federal Communications Commission’s repeal of net neutrality, Mozilla is joining millions of people across the internet to once again stand up to protect the open internet.

When the FCC gutted net neutrality protections last year, we filed our lawsuit because we believed that repeal was unlawful. We also believed taking on the FCC was the right thing to do for the future of the internet and everyone who uses it.

Until the Senate listens to the American people and protects the open Internet, Mozilla v. FCC continues to be net neutrality’s best hope.

But it’s time our Senators do what they were elected to do – represent their constituents, and pass net neutrality legislation that has overwhelming support and protects Americans. With a victory in the courts, or bipartisan legislation, we can ensure that people – and not big cable and telephone companies – get to choose what they see and do online.

 

The post It’s time for the US Senate to Save the Net appeared first on Open Policy & Advocacy.

This Week In RustThis Week in Rust 290

Hello and welcome to another issue of This Week in Rust! Rust is a systems language pursuing the trifecta: safety, concurrency, and speed. This is a weekly summary of its progress and community. Want something mentioned? Tweet us at @ThisWeekInRust or send us a pull request. Want to get involved? We love contributions.

This Week in Rust is openly developed on GitHub. If you find any errors in this week's issue, please submit a PR.

Updates from Rust Community

News & Blog Posts

Crate of the Week

This week's crate is uom, Units of measurement is a crate that does automatic type-safe zero-cost dimensional analysis. Thanks to ehsanmok for the suggestion!

Submit your suggestions and votes for next week!

Call for Participation

Always wanted to contribute to open-source projects but didn't know where to start? Every week we highlight some tasks from the Rust community for you to pick and get started!

Some of these tasks may also have mentors available, visit the task page for more information.

If you are a Rust project owner and are looking for contributors, please submit tasks here.

Updates from Rust Core

242 pull requests were merged in the last week

Approved RFCs

Changes to Rust follow the Rust RFC (request for comments) process. These are the RFCs that were approved for implementation this week:

No RFCs were approved this week.

Final Comment Period

Every week the team announces the 'final comment period' for RFCs and key PRs which are reaching a decision. Express your opinions now.

RFCs
Tracking Issues & PRs

New RFCs

Upcoming Events

Asia Pacific
Europe
North America

If you are running a Rust event please add it to the calendar to get it mentioned here. Please remember to add a link to the event too. Email the Rust Community Team for access.

Rust Jobs

Tweet us at @ThisWeekInRust to get your job offers listed here!

Quote of the Week

No quote was selected for QotW.

Please submit quotes and vote for next week!

This Week in Rust is edited by: nasa42, llogiq, and Flavsditz.

Discuss on r/rust.

Firefox NightlyThese Weeks in Firefox: Issue 59

Highlights

  • Integrated add-on abuse reporting landed in Firefox 68
    • You need to enable the HTML-based about:addons by setting extensions.htmlaboutaddons.enabled to true in about:config
    • The abuse reporting UI can be enabled by setting extensions.abuseReport.enabled to true in about:config
  • Work on the new login manager UI is progressing well
    • To see it go to about:config and set signon.management.page.enabled to true
    • Then load about:logins (will need to set the pref before loading the page)
    • Initial password generation code has also landed
      • WIP UI that only works on autocomplete=”new-password” fields
        • This is very early in the project so there is no additional attempt to save the generated password.
        • www.facebook.com is a good test page.
      • Enable both prefs to test the feature:
        • signon.generation.enabled is the user pref to enable/disable the feature from about:preferences (UI not implemented yet).
        • signon.generation.available controls whether the feature is available for users (e.g. if the about:preferences UI should show in the future).
  • The DevTools Inspector color picker widget just got a bit of a re-design. Thanks Maliha Islam [:maliha] for pushing this over the edge!
    • The new color-picker in the Inspector Panel!

      The new color-picker in the Inspector Panel!

Friends of the Firefox team

Introductions/Shout-Outs

  • New interns!
    • Mandy Cheang (@mcheang, mandy__)
      • Working on improving start-up performance
    • Abdoulaye Ly (@Abdoulaye O. Ly, abdoulaye)
      • Working on Fission

Resolved bugs (excluding employees)

Fixed more than one bug
  • Florens Verschelde :fvsch
  • Ian Moody [:Kwan]
  • jaril
  • Kestrel
  • Monika Maheshwari [:MonikaMaheshwari]
  • Tim Nguyen :ntim
New contributors (🌟 = first patch)

 

 

Project Updates

Activity Stream

  • The new Pocket Newtab is on track for 68 with performance parity
    • Slight regression with our usage of -webkit-line-clamp (thanks heycam for platform implementation!) and fixing with requestAnimationFrame (thanks performance best practices doc)
  • We’ve made some progress on migrating our build process into Firefox / making it easier to develop on Activity Stream features
  • Introducing our new intern: Emily (:emcminn)!

Add-ons / Web Extensions

Applications

Lockwise
  • Work on the Lockwise addon is complete
    • Final release waiting on localizers to translate strings
  • Future Lockwise work will happen in tree as part of the Firefox Password Manager
  • Removing this Lockwise item after this meeting

Developer Tools

Layout Tools
  • Inactive CSS landed! It’s currently only ON by default in nightly (since 68) but will ship to everyone with Firefox 69. Bug 1306054. We will be adding a larger collection of warnings very soon too, to warn users about more tricky CSS cases.
    • A tooltip in the CSS property inspector explains that a justify-content property doesn't apply to a non-flex element.

      This tooltip shows a CSS property that has no effect on the current element in the Inspector, and explains why.

  • Expandable CSS warnings also landed (shipping with 68). This allows jumping directly from a CSS warning displayed in the console to a node in the inspector when the warning occurred inside a CSS rule. Bug 1093953.
    • CSS warnings in the web console, with one of them being expanded, and revealing a list of DOM nodes that the warning applies to.

      Now errors can expand and collapse, and link directly to any nodes they’re associated with.

  • CSS Grid level 2 (subgrid) is close to shipping in Firefox. We’re getting the tooling for it ready in Firefox 69 so it’s easy to see the relationship between a grid and a subgrid.
  • We’re continuing to prototype on WebCompat awareness tools. Our latest prototype is an addon that displays CSS compatibility information about a page from the Firefox toolbar. It now allows to jump from a warning into the Style Editor, and to open other browsers where issues occur. GitHub repo for the addon
    • GIF demonstrating the doorhanger menu added by this extension, which contains the list of CSS compatibility problems detected on the page.

      This WebExtension helps bring attention to any detected web compatibility issues on the page. Handy!

  • We’re also focusing on fixing the last few remaining issues preventing to support the <meta viewport> tag in RDM, and therefore simulate mobile devices better.
Console
  • We now have borders between messages to make them easier to read. Bug 1519904. Thanks Florens Verschelde :fvsch for your keen eye for details.
    • Screenshot of the Web Console in Firefox 68 with borders between each console log message.

      Better visual separation and readability? Yes, please!

  • It is possible to resend network requests that were logged in the console. Bug 1530138. Thank you Christoph Walcher.
    • Screenshot of the context menu in the Web Console, showing the new "Resend request" feature for network requests.

      Want to resend that network request from the console? Now you can!

Debugger
  • Column breakpoints are stable now and we’re super happy with it.
  • Event breakpoints making good progress. The UI is ready and we’ll be landing the feature very soon. Follow along in this bug.
    • A preview of the nascent event breakpoints panel in the Debugger, allowing you to set breakpoints on all event types.

      When this lands, developers will be able to set breakpoints on events, as well as lines of code.

  • Workers are now displayed in the source tree along all the other sources.
  • The new logpoint feature is now even better with dedicated icons in the web console.
    • This shows the new "Add log" menu item in the debugger context menu, allowing you to log an expression when a certain line of code is executed.

      Log log log!

Remote Debugging
  • The new about:debugging page will ride the trains with Firefox 69. A final QA testing phase will happen in beta 69 in a few weeks. The main implementation phase is over and the final few fixes have happened:
    • Stay on the same page when reloading about:debugging (reconnects to remote runtimes automatically) (bug)
    • Remember last temporary addon install directory (bug)
    • Disable temporary addon installation if xpinstall.enabled is false (bug)
    • Updated error message colors and borders
    • New “Remote Debugging” menu item in the Web Developer menu
    • Update for Fenix/Firefox Preview (name, icon and version) (bug)
      • The new logo and header in about:debugging if an instance of Firefox Preview is connected.

        Coming soon to a phone near you!

Fission

  • Abdoulaye has an initial version of the <select> dropdown working with Fission
  • Neil has a version of drag and drop working with Fission! \o/
  • mconley has a patch that makes PermitUnload work with Fission, but is blocked on some DOM work
  • mconley is starting efforts to make the context menu work with Fission

Lint

Password Manager

Performance

Performance tools

  • Properly updating the URL state after publishing now.
  • Improved algorithm to find idle threads at load time.
  • Firefox Profiler now supports SimplePerf output format.
  • Added more relevant information to window title to improve the searchability of tabs. Thanks to our GSoC student Raj!
    • A tooltip for Firefox Profile showing the Firefox version, OS version, as well as collection date and time.

      This should make it easier for developers to tell various profiles apart when opened in multiple tabs.

  • Transforms are usable inside stack chart via context menu now.
    • The transfomation utilities are now available in the stack chart panel of the Firefox Profiler.

      Stack chart getting some love!

Picture-in-Picture

  • Dave Justice is about to get a patch landed that decorates the tab that a Picture-in-Picture video is coming from
  • Keyboard access and RTL support for Picture-in-Picture is still underway
  • The tentative plan is to let this ship to Firefox 69 Beta / Dev Edition and get feedback from our users and web developers

Policy Engine

  • ExtensionSettings policy finally landed (bug 1522823)
  • Added a number of preferences to the new Preferences policy (bug 1545539)
  • Download related policies (bug 1546973)
  • Activity Stream policies (bug 1548080)
  • Legacy Browser Support
    • EXE built
    • Able to test extension
    • Working on IE BHO
  • Investigating multiple intermittents on policy that have been around a while

Privacy/Security

Search and Navigation

Search
Quantum Bar
  • Bugs and cleanup work
  • Active in Beta, no critical regressions reported so far
  • Nightly XUL/HTML experiment didn’t show any fallout
  • Adding core support for the WebExtension APIs that will be driving our future experiments

Chris H-CData Science is Hard: Validating Data for Glean

Glean is a new library for collecting data in Mozilla products. It’s been shipping in Firefox Preview for a little while and I’d like to take a minute to talk about how I validated that it sends what we think it’s sending.

Validating new data collections in an existing system like Firefox Desktop Telemetry is a game of comparing against things we already know. We know that some percentage of data we receive is just garbage: bad dates, malformed records, attempts at buffer overflows and SQL injection. If the amount of garbage in the new collection is within the same overall amount of garbage we see normally, we count it as “good enough” and move on.

With new data collection from a new system like Glean coming from new endpoints like the reference browser and Firefox Preview, we’re given an opportunity to compare against the ideal. Maybe the correct number of failures is 0?

But what is a failure? What is acceptable behaviour?

We have an “events” ping in Glean: can the amount of time covered by the events’ timestamps ever exceed the amount of time covered by the ping? I didn’t think so, but apparently it’s an expected outcome when the events were restored from a previous session.

So how do you validate something that has unknown error states?

I started with a list of things any client-based network-transmitted data collection system had to have:

  • How many pings (data transmissions) are there?
  • How many measurements are in those pings?
  • How many clients are sending these pings?
  • How often?
  • How long do they take to get to our servers?
  • How many poorly-structured pings are sent? By how many clients? How often?
  • How many pings with bad values are sent? By how many clients? How often?

From there we can dive into validating specifics about the data collections:

  • Do the events in the “events” ping have timestamps with reasonable separations? (What does reasonable mean here? Well, it could be anything, but if the span between two timestamps is measured in years, and the app has only been available for some number of weeks, it’s probably broken.)
  • Are the GUIDs in the pings actually globally unique? Are we seeing duplicates? (We are, but not many)
  • Are there other ping fields that should be unique, but aren’t? (For Glean no client should ever send the same ping type with the same sequence number. But that kind of duplicate appears, too)

Once we can establish confidence in the overall health of the data reporting mechanism we can start using it to report errors about itself:

  • Ping transmission should be quick (because they’re small). Assuming the ping transmission time is 0, how far away are the clients’ clocks from the server’s clock? (AKA “Clock skew”. Turns out that mobile clients’ clocks are more reliable than desktop clients’ clocks (at least in the prerelease population. We’ll see what happens when we start measuring non-beta users))
  • How many errors are reported by internal error-reporting metrics? How many send failures? How many times did the app try to record a string that was too long?
  • What measurements are in the ping? Are they only the ones we expect to see? Are they showing in reasonable proportions relative to each other and the number of clients and pings reporting them?

All these attempts to determine what is reasonable and what is correct depend on a strong foundation of documentation. I can read the code that collects the data and sends the pings… but that tells me what is correct relative to what is implemented, not what is correct relative to what is intended.

By validating to the documentation, to what is intended, we can not only find bugs in the code, we can find bugs in the docs. And a data collection system lives and dies on its documentation: it is in many ways a more important part of the “product” than the code.

At this point, aside from the “metrics” ping which is awaiting validation after some fixes reach saturation in the population, Glean has passed all of these criteria acceptably. It still has a bit of a duplicate ping problem, but its clock skew and latency are much lower than Firefox Desktop’s. There are some outrageous clients sending dozens of pings over a period that they should be sending a handful, but that might just be a test client whose values will disappear into the noise when the user population grows.

:chutten

Support.Mozilla.OrgSUMO Platform Roadmap

Our support platform went through numerous changes and transitions during the last couple of years. With the SUMO team joining efforts with the Open Innovation group last year, we have started thinking about different approaches to our support platform strategy. Our support platform is complex and there are a lot of legacy items that need to be taken care of. Besides this we need to get ready for all the new things that are coming our way.

We want to ensure we’re providing a stable platform that will support Mozilla in the years to come as well as manage all the new products and changes expected in the following years.

During this first half of the year we have worked on setting up a roadmap that prioritizes the work and helps us be more intentional about the changes we want to make in order to provide the best support platform for our users. With this we have also worked on new processes that will hopefully simplify the way we work with the platform as well as the overall development process.

What’s new

Our current efforts are focused almost 100% on the integration of Firefox Accounts. In parallel we’ve also been working with the IT team to complete a migration of the infrastructure to a new instance of AWS (this has been completed on June 5th). Firefox Accounts implementation will follow shortly. After these major pieces of work are done our next big priorities are: Elastic search upgrades, ongoing UX experiments and a Responsive Design implementation that has become even more important as Google now indexes our site as mobile-first..

There will be more discussions about H2 and how we’re going to manage platform priorities in the second half of the year in July.

You can consult the current platform roadmap here.

This is a high-level overview on each project we’re working on and the expected timeline for completion. We’re going to review the roadmap items at the beginning of each month.

All the development work is being tracked in sprints and you can follow our current sprint here.

As mentioned before, the SUMO platform is a large complex platform with a lot of legacy issues that need to be dealt with. Currently we have around 700 bugs filed, many of them being more than 5 years old. As we don’t have enough resources to deal with this huge backlog we’ll need to change a few processes. We have designed a new triage and roadmap review process that you can read about here . Bugs that are not critical to the stability of the platform and are older than 6 months will be closed – this is a one time only event and we expect this to take care of most outdated bugs that will never be fixed. Feel free to open a new bug if you feel the issue is urgent or should be prioritized nonetheless.

Please note

We’re currently focusing on: Firefox Accounts implementation, the IT migration as well as any critical issues that break the site or block releases. Any other items are currently on hold. We can prioritize other issues as needed as per the process described in the document shared above.

SUMO staff team

Mozilla VR BlogCheck out Hubs on Oculus Quest!

Check out Hubs on Oculus Quest!

We’re excited to share that Hubs is now available on Quest, the new standalone VR headset from Oculus. Because Hubs is web-based, there are no applications to install or limits on cross-platform compatibility. Simply invite people to join your rooms in VR, on a desktop, or with a phone at any time. Launch a browser on the Quest and go to hubs.mozilla.com to create a room, then invite people to join you by sending them the invite link or room code!

Standalone headsets like the Oculus Quest represent exciting new advancements in the systems that we have available for consumer VR technology. Untethered devices with tracking capabilities built into the headset allow for more freedom of movement around a space and more natural interactions within an environment.

At Mozilla, we're committed to supporting a rich, open ecosystem of online content that can be accessed by any device. This is one of the reasons that the immersive web is so powerful - like traditional websites, applications like Hubs can be accessed through browsers with a single URL on new devices without being limited to store requirements. By developing Hubs for the web, we’re able to iterate and deploy changes quickly, which allows us to get new features and bug fixes out quickly and often. It also means our users can be together in the same room on the Quest, PC, and smartphones as well.

Check out Hubs on Oculus Quest!

We're excited by the opportunities that are enabled by an immersive, creative web where anyone can launch mixed reality experiences. For virtual reality to succeed, applications and experiences need to be designed for everyone in mind, and not separate communities based on their hardware preferences. We think it’s important that Hubs exists as a social VR platform that works across the different device families that you use to communicate, regardless of the platform.

Check out Hubs on Oculus Quest!

There are a lot of misconceptions about what the immersive web is capable of, but it does a lot of important things really well. It keeps control of the experiences in the users’ hands and prioritizes accessibility over platform-exclusive features. It gives developers the ability to deliver their experiences across devices without the restrictions that come from publishing to app stores, and it’s born from a decades old community built around standards and openness, which we think is critical to the success of mixed reality.

If you’re a creator or developer interested in learning more about how we’re building virtual reality experiences for the web, join the Hubs Community meetup on Fridays at 11:30am PDT (UTC -7) to hear more from the team about the foundations of how (and why) we’re committed to bringing social VR to the browser. Jump into our Hubs discord server and keep an eye on the #meetup channel to participate!

Hubs is an open-source project by Mozilla to explore how social virtual worlds can be used for collaboration and communication. You can explore Hubs today at hubs.mozilla.com or view the source code at github.com/mozilla/hubs.

Chris PearceQuick start: Profiling local builds of Firefox for Android and GeckoView_example

Getting building and profiling Firefox for Android or GeckoView_example is relatively easy if you know how, so here's my quickstart guide.

See also, the official GeckoView documentation.

First, ensure you run ./mach boostrap, and select "4. GeckoView/Firefox for Android".

Here's the mozconfig I'm using (Ubuntu 18.04):
ac_add_options --enable-optimize
ac_add_options --disable-debug
ac_add_options --enable-release
ac_add_options --disable-tests
mk_add_options AUTOCLOBBER=1
ac_add_options --enable-debug-symbols
# With the following compiler toolchain:
CC="/home/chris/.mozbuild/clang/bin/clang"
CXX="/home/chris/.mozbuild/clang/bin/clang++"
export CC="/home/chris/.mozbuild/clang/bin/clang -fcolor-diagnostics"
export CXX="/home/chris/.mozbuild/clang/bin/clang++ -fcolor-diagnostics"
ac_add_options --with-ccache=/usr/bin/ccache
mk_add_options 'export RUSTC_WRAPPER=sccache'
# Build GeckoView/Firefox for Android:
ac_add_options --enable-application=mobile/android
# Work around issues with mozbuild not finding the exact JDK that works.
# See also https://bugzilla.mozilla.org/show_bug.cgi?id=1451447#c7
ac_add_options --with-java-bin-path=/usr/lib/jvm/java-8-openjdk-amd64/bin
# With the following Android NDK:
ac_add_options --with-android-ndk="/home/chris/.mozbuild/android-ndk-r17b"
ac_add_options --with-android-min-sdk=16
ac_add_options --target=arm-linux-androideabi
A noteworthy item in there is "--with-java-bin-path". I've had trouble on Ubuntu with the system default Java not being the right version. This helps.

Note that if you're profiling, you really want to be doing a release build. The behaviour of release is different from an optimized build.

If you're debuging, you probably need --enable-debug. For details of how to debug, see GeckoView Debugging Native Code in Android Studio.

To build, package, and install Firefox for Android (Fennec) on your Android device, run:
./mach build && ./mach package && ./mach install 
Note that you need to do the package step after every build. Once you've installed, you can start Firefox on a given URL with:
./mach run --url https://www.youtube.com/watch?v=dQw4w9WgXcQ
For testing and profiling GeckoView, the easiest option is to run the GeckoView_example app. To build and install this, run:
./mach build && ./mach package && ./mach android build-geckoview_example && ./mach android install-geckoview_example
To run GeckoView_example, opening a URL:
adb shell am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -n org.mozilla.geckoview_example/org.mozilla.geckoview_example.GeckoViewActivity -d 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
If you want to set environment variables, for example to turn on MOZ_LOGs, run like so:
adb shell am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -n org.mozilla.geckoview_example/org.mozilla.geckoview_example.GeckoViewActivity -d 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' --es env0 MOZ_LOG=MediaSource:5
Note if you want to create more than one environment variable, each one needs to be numberd, i.e. `--es env0 FOO=BAR env1 BAZ=FUZ`, and so on. Also note that you do not put quotes around environment variables here. That is, use `--es env0 FOO=BAR`, do not use `--es env0 FOO="BAR"`.

MOZ_LOGs go to adb logcat. To setup an output stream that reads specific MOZ_LOGs:
adb logcat | grep MediaSource
This stays open, printing logs until you terminate with CTRL+C. If you want to exit at the end of the logs buffered, pass -d. i.e.:
adb logcat -d > log_file.txt
Apparently you can pass a logtag filterspec to `adb logcat` to have it filter for you, but I never figured the syntax out.

To clear logcat's buffered logs:
adb logcat --clear
This is useful if you're prinf-debugging something via logcat, and want to clear the decks before each run.

Other useful commands...

To terminate a running GeckoView_example:
adb shell am force-stop org.mozilla.geckoview_example
To list all packages on your device related to Mozilla:
adb shell pm list packages mozilla
To uninstall a GeckoView_example:
adb uninstall org.mozilla.geckoview_example && adb uninstall org.mozilla.geckoview_example.test
Note that this also uninstalls the GeckoView test app. Sometimes you may find you need to uninstall both apps before you can re-install. I think this is related to different versions of adb interacting.

To get the Android version on your device:
adb shell getprop ro.build.version.release
To simulate typing text:
adb shell input text "your text"
To profile a GeckoView_example session, you need to download the latest Firefox Desktop Nightly build, and install the Firefox Profiler add-on. Note that the Firefox Profiler Documentation is pretty good, so I'll only cover the highlights.

Once you've got Firefox Desktop Nightly and the Firefox Profiler add-on installed, start up your GeckoView_example app and URL you want to profile, and in Firefox Nightly Desktop open about:debugging. Click "Connect" to attach to the device you want to profile on, and then click "Profile Performance".

If you're profiling media playback, you want to add "Media" to the custom thread names under the "Threads" settings.

Since you're profiling a local build, you want to open the "Local build" settings, and ensure you add the path to your object directory.

Once you're configured, press "Start recording", do the thing in GeckoView_example you're profiling, and then hit "Stop and grab the recording".

The profile will open in a new tab in the browser. Sometimes I've noticed that the profiler hangs at "Waiting for symbol tables for library libxul.so". Just reloading the page seems to resovle this normally.

I find the Firefox Profiler very straightforward to use. The Flame Graph view can be particularly enlightening to see where threads are spending time.

Unfortunately the Firefox profiler can't symbollocate Java call stacks. Java calls usually show up as hex addresses, sometimes on the far side of an AndroidBridge C++ call.

On Android >= P you can use Simpleperf to capture profiles with both native and JIT'd Java call stacks. Andrew Creskey has instructions on how to use Simpleperf with GeckoView_example.

Mozilla Security BlogNext steps in privacy-preserving Telemetry with Prio

In late 2018 Mozilla conducted an experiment to collect browser Telemetry data with Prio, a privacy-preserving data collection system developed by Stanford Professor Dan Boneh and PhD candidate Henry Corrigan-Gibbs. That experiment was a success: it allowed us to validate that our Prio data collections were correct, efficient, and integrated well with our analysis pipeline. Today, we want to let you know about our next steps in testing data collection with Prio.

As part of Content Blocking, Firefox will soon include default protections against tracking. Our protections are built on top of a blocklist of known trackers. We expect trackers to react to our protections, and in some cases attempt to work around them. We can monitor how our blocklists are applied in Firefox to detect these workarounds.

However, directly monitoring how our blocklists are applied would require data that we feel is too sensitive to collect from release versions of Firefox. That’s why Prio is so important: it allows us to understand how our blocklists are applied across a large number of users, without giving us the ability to determine how they are applied in any individual user’s browser or on any individual page visit.

To support this we’ve developed Firefox Origin Telemetry, which is built on top of Prio. We will use Firefox Origin Telemetry to collect counts of the number of sites on which each blocklist rule was active, as well as counts of the number of sites on which the rules were inactive due to one of our compatibility exemptions. By monitoring these statistics over time, we can determine how trackers react to our new protections and discover abuse.

In the next phase of testing we need validate that Firefox Origin Telemetry works at scale. To provide effective privacy, Prio requires that two independent parties each process a separate portion of the data — a requirement that we will not satisfy during this test. As in our initial test, we will run both data collection servers ourselves to complete end-to-end testing prior to involving a second party. That’s why we are running this test only in our pre-release channels, which we know are used by a smaller audience that has chosen to help us test development versions of Firefox. We’ve ensured that the data we’re collecting falls within our data collection policies for pre-release versions of Firefox, and we’ve chosen to limit the collection to 1% of Firefox Nightly users, as this is all that’s necessary to validate the API.

We expect to start this test during our Nightly 69 development cycle. Collecting this data in a production environment will require an independent third party to run one of the servers. We will provide further updates once we have such a partner in place.

The post Next steps in privacy-preserving Telemetry with Prio appeared first on Mozilla Security Blog.

Hacks.Mozilla.OrgCSS Grid Level 2 – subgrid is coming to Firefox

The subgrid feature of the CSS Grid Specification is not yet shipping in any browser, but is now available for testing in Firefox Nightly. This is a feature that, if you have used CSS Grid for a layout of any complexity, you are likely to be pretty excited about. In this article I’m going to introduce the feature and some of the use cases it solves.

So what is subgrid exactly? In terms of syntax, it is a new keyword value for the grid-template-columns and grid-template-rows properties. These properties normally accept a track listing, or to put it another way, a listing of sizes of the tracks you want in your grid. For example, the following CSS would create a three column track grid with a 200px column, a column sized as max-content, and a final 1fr column.

grid-template-columns: 200px max-content 1fr;

You can find out more about track sizing in general, and the basics of grid layout via the MDN Guide Basic concepts of Grid Layout.

If we define a track as a subgrid, however, we replace the track listing with the keyword subgrid.

grid-template-columns: subgrid;

This instructs the grid-template-columns property to use the tracks defined on the parent as the track sizing and number used by this nested grid.

In the example below I have an element which is a grid container. It contains three child elements — two <div> elements and a <ul>.

<div class="wrapper">
  <div class="box1">A</div>
  <div class="box2">B</div>
  <ul class="box3">
    <li>List item 1</li>
    <li>List item 2</li>
    <li>List item 3</li>
  </ul>
</div>

I create a grid on .wrapper, and the direct children are laid out on the grid I have created, but the list items go back to displaying as list items.

.wrapper {
  display: grid;
  grid-template-columns: 2.5fr 1fr 0.5fr;
  gap: 20px;
}

.box1 {
  grid-column: 1;
  grid-row: 1;
}

.box2 {
  grid-column: 2 / 4;
  grid-row: 1;
}

.box3 {
  grid-column: 1 / -1;
  grid-row: 2;
}
A layout of boxes, with list items displayed one below the other

The list items do not participate in grid layout.

If we make the <ul> with a class of box3 a grid, and set grid-template-columns to subgrid, the <ul> is now a three-column track grid. The list items are laid out using the tracks of the parent.

.box3 {
  grid-column: 1 / -1;
  grid-row: 2;
  display: grid;
  grid-template-columns: subgrid;
}
A layout of boxes with aligned elements.

The list items use the grid of the parent of the list.

CodePen (needs Firefox Nightly)

There are some additional nice features that make subgrid useful for patterns you might need to build. The *-gap properties are inherited by default into subgrids, however you can override this behavior by setting a gap, row-gap, or column-gap value on the subgrid itself.

The lines in your subgrid will inherit the line names set on the parent grid. This means that you can position items in the subgrid with the line names on your main grid. You can however also add line names just for the subgrid and these will be added to any inherited names.

Take a look at the guide to subgrid on MDN to read about all of these features and see example code.

What will subgrid be useful for?

In terms of new syntax, and new things to learn, this is a very small change for web developers who have learned grid layout. A grid defined as a subgrid is pretty much the same as a regular nested grid, albeit with its own track listings. However it makes a number of previously difficult patterns possible.

For example, if you have a card layout, and the cards have headers and footers with uneven amounts of content, you might want the card headers and footers to align across the rows. However, with a standard nested grid this isn’t possible. The grid on each card is independent, therefore the track sizing in card A can’t respond to change of height inside card B.

A grid of cards with headers and footers which do not align

The card internal elements do not line up

If we cause each card to span across three rows however, we can then change the value of grid-template-rows to subgrid.

.card {
  grid-row: auto / span 3;
  display: grid;
  grid-template-rows: subgrid;
}

The card still spans three row tracks, but those rows are defined on the parent and therefore each footer is in the same row. If one footer gets taller, it makes the whole row taller.

CodePen example.

A grid of cards with aligned headers and footers.

The card internal elements now line up.

You might want to work to a standard 12-column layout. Without subgrid, components that are not direct children of the grid container can’t be laid out on that parent grid. Instead, you need to be careful with track sizing in the nested components in order to get the layout to work. With subgrid we can opt nested grids into that parent grid as far into the structure as is required.

This means that in the below wireframe example, all elements are using the tracks defined on the main element — even things that are nested inside two grids such as the links inside a list inside a <nav> element. The screenshot below has the lines of that parent grid displayed using the Firefox Grid Inspector.

A layout with grid lines overlaid

The twelve column grid highlighted by the Grid Inspector

CodePen example.

A less obvious use case for subgrid is to help in the situation where you have an unknown amount of repeated content in your layout, and want to be able to place an item from the start to the end of the grid.

We can target the end of an explicit grid with -1, so an item placed with grid-row: 1 / -1 will stretch from the first to the last row line. The below grid has two row tracks defined. The block on the left stretches over both as it is spanning from column line 1 to column line -1.

A grid of boxes with the Firefox Grid Inspector showing the lines

The explicit grid highlighted with the Grid Inspector

CodePen example.

However, if you are creating implicit row tracks, because you don’t know how many items there will be you can’t target the end of the implicit grid with -1. As we do not have explicit tracks after the first track (a grid always has one explicit track in each dimension) the blue item can’t span to the end line after all of the auto-placed items have been laid out.

A arrangement of boxes, one blue box is top left.

Without an explicit grid the item cannot stretch to the end line

CodePen example.

If you make the repeating section a subgrid for columns, with implicit rows, all of those rows fit into the same grid area of the parent, rather than creating more rows on the parent. This means that you can have a fully explicit parent grid and know exactly where the end line is no matter how many items are added in the subgridded part.

The only compromise would be the addition of an extra wrapper if your markup didn’t have a container for these repeating elements, however a single wrapping <div> is not going to cause any problems and enables this pattern.

An arrangement of boxes with a full height box on the left

The sidebar stretches to the height of the content

CodePen example.

Firefox DevTools and subgrid

The DevTools team have been working on adding features to DevTools that will make it easier to work with multiple grids, including subgrid.

You can now highlight multiple grids with DevTools. This can be helpful to see how the grid lines up with each other. You can see this in action by highlighting multiple grids in the cards example above, letting you see how the lines of the rows on our cards align with the parent rows.

A grid of cards with two grids of lines displayed overlaid

Two grids are highlighted here, one on the parent and one on a child

In the Grid Inspector subgrids have a little subgrid badge, and appear nested inside their parent. These things should help you to identify them better when working with complex arrangements of grids.

The Firefox DevTools open to show the different ways that subgrids are highlighted.

DevTools makes it easy to see your subgrids.

The team are still working on features, including the ability to highlight a parent when a subgrid is selected.

Status of the subgrid feature

Subgrid is now available in Firefox Nightly, so you can test it out, and we would love you to do so. Firefox will have the first implementation of the specification, so feedback from web developers is vital both for the Firefox implementation, the DevTools, and for the CSS specification itself.

More resources can be found in the MDN guide, and I have started to build some more examples at Grid by Example — my website of CSS Grid examples. In addition, read CSS Grid Level 2: Here Comes Subgrid — an article I wrote about the specification before we had any implementations.

The post CSS Grid Level 2 – subgrid is coming to Firefox appeared first on Mozilla Hacks - the Web developer blog.

Daniel Stenberg7.65.1 patched up and ready to go

(download it from curl.haxx.se of course!)

Whatever we do and whatever we try, no matter how hard we try to test, debug, review and do CI builds it does not change the eternal truth:

Nothing gets tested properly until released.

We worked hard on fixing bugs in the weeks before we shipped curl 7.65.0. We really did. Yet, several annoying glitches managed to creep in, remain unnoticed and cause problems to users when they first eagerly tried out the new release. Those were glitches that none in the development team had experienced or discovered but only took a few hours for users to detect and report.

The initial bad sign was that it didn’t even take a full hour from the release announcement until the first bug on 7.65.0 was reported. And it didn’t stop with that issue. We obviously had a whole handful of small bugs that caused friction to users who just wanted to get the latest curl to play with. The bugs were significant and notable enough that I quickly decided we should patch them up and release an update that has them fixed: 7.65.1. So here it is!

This patch release even got delayed. Just the day before the release we started seeing weird crashes in one of the CI builds on macOS and they still remained on the morning of the release. That made me take the unusual call to postpone the release until we better understood what was going on. That’s the reason why this comes 14 days after 7.65.0 instead of a mere 7 days.

Numbers

the 182nd release
0 changes
14 days (total: 7,747)

35 bug fixes (total: 5,183)
61 commits (total: 24,387)
0 new public libcurl function (total: 80)
0 new curl_easy_setopt() option (total: 267)

0 new curl command line option (total: 221)
27 contributors, 12 new (total: 1,965)
16 authors, 6 new (total: 687)
0 security fixes (total: 89)
0 USD paid in Bug Bounties

Bug-fixes

Let me highlight some of the fixes that went this during this very brief release cycle.

build correctly with OpenSSL without MD4

This was the initial bug report, reported within an hour from the release announcement of 7.65.0. If you built and installed OpenSSL with MD4 support disabled, building curl with that library failed. This was a regression since curl already supported this and due to us not having this build combination in our CI builds we missed it… Now it should work again!

CURLOPT_LOW_SPEED_* repaired

In my work that introduces more ways to disable specific features in curl so that tiny-curl would be as small as possible, I accidentally broke this feature (two libcurl options that allow a user to stop a transfer that goes below a certain transfer speed threshold during a given time). I had added a way to disable the internal progress meter functionality, but obviously not done a good enough job!

The breakage proved we don’t have proper tests for this functionality. I reverted the commit immediately to bring back the feature, and when now I go back to fix this and land a better fix soon, I now also know that I need to add tests to verify.

multi: track users of a socket better

Not too long ago I found and fixed a pretty serious flaw in curl’s HTTP/2 code which made it deal with multiplexed transfers over the same single connection in a manner that was far from ideal. When fixed, it made curl do HTTP/2 better in some circumstances.

This improvement ended up proving itself to have a few flaws. Especially when the connection is closed when multiple streams are done over it. This bug-fix now makes curl closing down such transfers in a better and cleaner way with fewer “loose ends”.

parse_proxy: use the IPv6 zone id if given

One more zone id fix that I didn’t get around to land in 7.65.0 has now landed: specifying a proxy with a URL that includes an IPv6 numerical address and a zone id – now works.

connection “bundles” on same host but different ports

Internally, libcurl collects connections to a host + port combination in a “bundle” (that’s just a term used for this concept internally). It does this to count number of connections to this combination and enforce limits etc. It is only used a bit for controlling when multiplexing can be done or not on this host.

Due to a regression, probably added already back in 7.62.0, this logic always used the default port for the protocol instead of the actual port number used in the given URL! An application that for example did parallel HTTP transfers to the hostname “example.org” on both port 80 and port 81, and used HTTP/1 on one of the ports and HTTP/2 on the other would be totally mixed up by curl and cause transfer failures.

But not anymore!

Coming up

This patch release was not planned. We will give this release a few days to stew and evaluate the situation. If we keep getting small or big bugs reported, we might not open the feature window at all in this release cycle and instead just fix bugs.

Ideally however, we’ve now fixed the most pressing ones and we can now move on and follow our regular development process. Even if we have, the feature window for next release will be open during a shorter period than normal.

Mozilla Reps CommunityNew Council members – 2019 Spring elections

We are very happy to announce that our 5 new Council members are are fully on-boarded and already working moving the Mozilla Reps program forward.

In more detail here are the subjects that they will work on:

Of course we would like to thank our outgoing Reps council members Daniele, Manel and Oarabile for all their contributions during their last year in the program.

The Mozilla Reps Council is the governing body of the Mozilla Reps Program. It provides the general vision of the program and oversees day-to-day operations globally. Currently, 7 volunteers and 2 paid staff sit on the council. Find out more on the Reps wiki.

 

Daniel Stenbergcurl user survey 2019 analysis

The annual curl user survey 2019 ran for 14 days and ended a while ago. I’ve spent a good deal of time summing up the data, making graphs, tables and creating a document out of what I’ve learned.

Some quick insights:

  • HTTPS is now the most used protocol
  • Linux is the most used platform
  • Most of the users (who answered) are in Europe
  • Windows 10 grows as the dominant Windows version used for curl
  • 55% of users use HTTP/2 while 4.1% of users use HTTP/0.9

For all this and much much more. See the full report.

Hacks.Mozilla.OrgIndicating focus to improve accessibility

It’s a common, but fairly easy-to-fix accessibility issue: lack of indicating focus. In this post I will explain what we mean by focus and show you how focus outlines make your site easier to use.

What is focus?

Focus indicators make the difference between day and night for people who rely on them. Let’s first look at what they are, and which people find them useful.

Focus is something that happens between the interactive elements on a page. That’s the first thing you should know. (See the focusable elements compatibility table for a more detailed and nuanced definition.) Interactive elements are elements like links, buttons and form fields: things that users can interact with.
menu links; one is outlined, the outline moves between the links

On a page, at any given time, there is one element that has focus. If you’ve just loaded a page, it is probably the document, but once you start to click or tab, it will be one of the aforementioned interactive elements. The currently focused element can be found with document.activeElement.

By default, browsers convey which element currently has focus by drawing an outline around that element. The defaults vary between browsers and platform. With CSS, you can override these defaults, which we’ll get to in a bit.

Who benefits

Focus outlines help users figure out where they are on a page. They show which form field is currently filled in, or which button is about to be pressed. People who use a mouse, might use their cursor for this, but not everyone uses a mouse. For instance, there are many keyboard users: a person with a baby on one arm, people with chronic diseases that prevent the use of a mouse, and of course… developers and other power users. Beyond keyboards, there are other tools and input devices that rely on clearly indicated focus, like switches.

It is not just keyboard users that benefit, though. Focus indication also helps people who have limited attention spans or issues with short term memory, for example if they are filling out a lengthy form.

If the idea of indicating the current element in a website seems weird, consider TV interfaces. Most people use them with a remote control or game controller, and therefore rely on the interface to convey what’s currently selected.

Never remove them

Not everyone likes how focus outlines look, some find them ugly. But then that’s the case with street lights, too. They are unlikely to win design awards, but if you have to walk home in the dark, you are glad they help you see where you are.

Removing focus styles, as some websites do, is as detrimental for keyboard users as removing the mouse cursor would be for mouse users.

Nobody would override the browser’s default cursor, effectively removing the cursor altogether:

body {
cursor: none; /* you wouldn't do this */
}

So we shouldn’t do this either, which removes the browser’s default outline:

:focus {
outline: none; /* so, please don't do this */
}

Or, as Laura Carvajal put it at Fronteers 2018:

Laura Carvajal with slide: You wouldn’t steal their cursor

Even if you provide an alternative with something like box-shadow, best set outline to solid transparent, because box-shadow does not play well with high contrast modes.

Good focus indicators

One way to indicate focus is to rely on browser defaults. It works, but I would recommend designing your own focus outlines. This gives you maximum control over how easy they are to see, and lets you integrate them with brand colours or the style of your site. Usually, thicker outlines (from 2px onwards) are better, as they are simply easier to see.

The :focus pseudo class takes CSS rules like any other selector, so you could style it however you like. In some cases a background color or underline could indicate that something is active.

Examples

Below are focus outlines as seen on Schiphol.nl and the City of The Hague websites. They make it easy to distinguish in a list of links which one is currently active.

two sets of links, on the left one link is outlined with thick purple outline, on the right a thin outline and yellow background

Transitions

Focus outlines do not have to be boring. The outline property can be transitioned with CSS, so why not add a subtle animation? Make it pop!

Contrast

In WCAG 2.1, focus indicators are bound to the same contrast rules as other parts of the content, as per 1.4.11: Non-text contrast. This means a contrast of 3:1 between the outlines and their background is required.

On websites that have both light and dark parts, it is quite common to have a dark and a light focus style. For example, if your focus outline is blue for parts with a white background (for instance, the main content area), you could make it white for parts with a black background (for instance, the footer).

Special cases

Focusing non-interactive elements

As mentioned earlier, focus works on interactive elements. In special cases, it makes sense to focus a non-interactive element, like a &lt;div&gt;, if that element is a piece of expanded content or a modal overlay that was just opened.

Any element can be added to focus order with the tabindex attribute in HTML. Best use it with 0 or -1:

  • tabindex="0": element can be focused with keyboard and through JavaScript
  • tabindex="-1": element can be focused through JavaScript, but cannot be tabbed to

A tabindex with a number larger than 0 is best avoided, as this sets a preference of where the element goes in the tab order. If you set it for one element, you will have to set and maintain (!) a tabindex value on all interactive elements on the page. See also: It rarely pays to be positive by Scott O’Hara.

Only for keyboard users

If you are a developer and the design team is unwilling to apply bold focus styles, you could propose to show them to users who need them, for instance only to keyboard users.

There are two caveats to this notion of “users who need them”:

  • Not all people who rely on focus styles use a keyboard. We mentioned switches earlier, but that’s only one use case. As a general rule, keep in mind that you can’t predict all the ways your visitors choose to browse the web.
  • Making focus styles keyboard-only takes away an affordance for mouse users too, as focus also indicates that something is interactive.

For these reasons, we should be careful making decisions about when and how to show focus styles. Luckily, there is a CSS property invented to help us out here: focus-visible. According to the spec, it lets us:

provide clearly identifiable focus styles which are visible when a user is likely to need to understand where focus is, and not visible in other cases

In other words: it aims to let you indicate focus only for people that need it. This is supported in Firefox (with prefix), but not yet in Chromium (they intend to implement), so it would be best to use the official focus-visible polyfill. It is preferable to avoid such heuristics and convey focus rings to everybody, but if you have to, focus-visible is ideal. Especially if the alternative is nothing at all.

Focus styles as keyboard accessibility

A focused element that isn’t highlighted has a big impact on usability for keyboard users. You could make keyboard checks part of your development workflow to ensure that you don’t forget focus indicators. For instance, you could include “Can be used with a keyboard” in your definition of done. This is a check that most people in the team should be able to do before a new feature goes live. As we’ve seen above, focus styles don’t just benefit keyboard users, but keyboard operability is a good way to test them.

When testing, you might find that not all browsers and platforms let you tab through interactive elements by default. Here are some of the most common settings across platforms and browsers:

  • macOS: under System Preferences > Keyboard > Shortcuts set ‘Full keyboard access’ to ‘All controls’
  • Safari, macOS: in `Safari > Preferences`, under ‘Advanced’, check ‘Press Tab to highlight each item on a webpage’
  • Chrome: in chrome://settings, under ‘Web content’, check ‘Pressing Tab on a webpage highlights links, as well as form fields’

Summing up

Hopefully this post inspires you to try out your (client’s) site with just a keyboard. Maybe it is a pleasure to use already. If not, perhaps this post convinces you or your team to address the problem and design some on-brand focus indicators. Together we make the web more friendly to users of keyboards, sticks and switches. Together we make the web work for everyone.

Focus outlines are one of many ways to design for accessibility. For more tips on design with accessibility in mind, see Accessibility Information for UI designers on MDN and Tips for designing with accessibility at the W3C.

The post Indicating focus to improve accessibility appeared first on Mozilla Hacks - the Web developer blog.

The Mozilla BlogThe web the world needs can be ours again, if we want it

People everywhere are demanding basic consumer protections. We want our food to be healthy to eat, our water to be clean to drink, and our air to be safe to breathe.

This year people have started to demand more of the internet as well, however, there persists an expectation that on the internet people are responsible for protecting themselves.

You should not have to worry about trading privacy and control in order to enjoy the technology you love. Tech companies have put the onus on people to read through their opaque terms and conditions tied to your data and privacy to use their services. The average privacy policy from a tech company is thousands of words and written at a level that often requires legal training to interpret. As such the vast majority of people don’t bother to read, and just click through these agreements trusting that the companies have their interests at heart.

This isn’t right, and it’s not where we stand. We aspire to put people back in control of their connected lives. To better equip people to navigate the internet today, we’ve built the latest version of our flagship Firefox browser with Enhanced Tracking Protection on by default. These protections work in the background, blocking third-parties from tracking your online activity while increasing the speed of the browser.

We’re offering privacy protections by default as you navigate the web because the business model of the web is broken, with more and more intrusive personal surveillance becoming the norm. While we hope that people’s digital rights and freedoms will ultimately be guaranteed, we’re here to help in the interim.

In a world where tech companies expect you to cobble together different tools to protect your privacy putting the burden on you, we are providing an easy-to-use solution with just one Firefox login to get the full benefit of all of the protections and capabilities we’ve built into our products and services.

By creating a Firefox account you can increase convenience while decreasing your exposure to some harmful parts of the web. An account unlocks the full potential of tools like Lockwise, which securely manages passwords, and Monitor, a service that notifies you when your email has been part of a known data breach.

We’re deepening our relationship with you because we know you can’t go it alone anymore. With Firefox you have a partner who knows the ins and outs of the tech industry, but who is beholden to serving you, not shareholders. We’re optimistic that together we can take back power over our online lives.

We choose to lead, not follow. Join us.  

You know what we stand for and what we’ve been about for over a decade thanks to our Manifesto and our Data Privacy Principles. Today we’re making it even more clear what you get when you sign up with us by announcing the Firefox Personal Data Promise — our commitment to handle your personal information with integrity and decency — and best practices for others to follow when it comes to protecting consumers privacy and rights online.

We’re taking these steps and we’re offering new tools to increase your protection and control, but it’s only the first step in our new relationship with you. We will continue to push back against collect-it-all business models that are set up to monetize people in seemingly every possible way. In addition to the tools and services we offer, we champion efforts like the fight for net neutrality, combat surveillance tactics and push for standards and practices that promote privacy and competition.

I hope you can see we’re different, and that we work hard every day to earn your trust. I believe that the internet can be a tool to make the world a better place where everyone is welcome. And safe. And respected. It can be a place that enables a free exchange of ideas. I know it can be because it once was.

The web the world needs can be ours again, if we want it. Please join me and millions of Firefox users in choosing a safer, more connected world.

The post The web the world needs can be ours again, if we want it appeared first on The Mozilla Blog.

The Mozilla BlogWhen it comes to privacy, default settings matter!

What if I told you that on nearly every single website you visit, data about you was transmitted to dozens or even hundreds of companies, all so that the website could earn an additional $0.00008 per ad! This is a key finding from a new study on behaviorally targeted advertisements from Carnegie Mellon University and it should be a wake-up call to all of us. The status quo of pervasive data collection in service of ad targeting is untenable. That is why we’re announcing some key changes to Firefox.

Today marks an important milestone in the history of Firefox and the web. As of today, for new users who download and install Firefox for the first time, Enhanced Tracking Protection will automatically be set on by default, protecting our users from the pervasive tracking and collection of personal data by ad networks and tech companies.

It seems that each week a new tech company decides to decree that privacy is a human right. They tout how their products provide people with “choices” to change the settings if they wish to opt into a greater level of privacy protection to exemplify how they are putting privacy first. That begs the question — do people really want more complex settings to understand and fiddle with or do they simply want products that respect their privacy and align with their expectations to begin with?

Privacy shouldn’t be relegated to optional settings

When thinking about consumer privacy online, I’m reminded of the behavioral economics studies which led to 401K plans (US retirement savings plans) moving from voluntary enrollment to auto-enrollment. Not too long ago most defined contribution retirement savings plans in the US required employees to sign-up and volunteer to start participating. Participation rates were very low. Why was that? Was it because people didn’t care about saving for retirement? Not at all! There were simply too many barriers to aligning with people’s expectations and desires and the benefits of saving for retirement aren’t felt immediately.

We are in a similar position with respect to software privacy settings. Pervasive tracking is too opaque and potential privacy harms are never felt immediately. The general argument from tech companies is that consumers can always decide to dive into their browser settings and modify the defaults. The reality is that most people will never do that. Yet, we know that people are broadly opposed to the status quo of pervasive cross-site tracking and data collection, particularly when they learn the details on how tracking actually works.

We also know that traditional privacy features such as Chrome’s Incognito mode are failing to live up to consumer expectations. The feature might keep your spouse from knowing what you’re thinking about getting them for your anniversary by erasing your history, but it does not prevent third-party tracking. Our research shows that Firefox users are seeking out privacy protection, particularly through the use of Firefox’s Private Browsing mode. In fact, nearly 25% of web page loads in Firefox take place in a Private Browsing window. The good news for these users is that Firefox’s Private Browsing mode has long put users first by blocking tracking. The bad news is that this generally isn’t true for many popular browsers, which allow tracking even in private browsing/incognito mode. A recent study found that users don’t understand this and think their data is being protected, when it is actually not.

As was the case with retirement savings plans, what this shows us is that the burden needs to shift from the consumers to the companies whereby the complexity of privacy settings shouldn’t be placed on users to figure out. The product defaults should simply align with consumer expectations. That is the approach we are taking in Firefox.

Enhanced Tracking Protection by Default

As stated above, new Firefox users will have strong privacy protection from the moment they install. We also expect to deliver the same functionality to existing users over the coming months. Because we are modifying the fundamental way in which cookies and browser storage operate, we’ve been very rigorous in our testing and roll-out plans to ensure our users are not experiencing unforeseen usability issues. If you’re already using Firefox and can’t wait, you can turn this feature on by clicking on the menu icon marked by three horizontal lines at the top right of your browser, then Content Blocking. Go to your privacy preferences and click on the Custom option on the right side. Mark the Cookies checkbox and make sure that “Third-party trackers” is selected. To learn more about our privacy and security settings and get more detail on what each section — Standard, Strict, and Custom — includes, visit here.

For existing users, go to your privacy preferences and click on the Custom option, ark the Cookies checkbox

If you are new to Firefox, we’d love for you to give it a try. Download the latest version here.

When it comes to privacy, default settings matter! We hope that the actions we are taking can ultimately compel change in the industry. Afterall, consumers deserve better.

 

The post When it comes to privacy, default settings matter! appeared first on The Mozilla Blog.

The Firefox FrontierFive ways joining Firefox can keep you safer and smarter online

The word “privacy” gets thrown around a lot these days, but every tech company defines privacy differently. Respecting your privacy has been at our core from day one, with the … Read more

The post Five ways joining Firefox can keep you safer and smarter online appeared first on The Firefox Frontier.

The Mozilla BlogFirefox Now Available with Enhanced Tracking Protection by Default Plus Updates to Facebook Container, Firefox Monitor and Lockwise

It’s been several weeks since I was promoted to Senior Vice President of Firefox, responsible for overall Firefox product and web platform development. As a long-time employee with 10+ years, I’ve seen a lot of things within the tech industry from data breaches, net neutrality and the rise and fall of tech companies. I believe that Firefox has and will continue to make a big impact in building the necessary protections to keep people safe online.

This past year, we’ve seen tech companies talk a big game about privacy as they’re realizing that, after several global scandals, people feel increasingly vulnerable. It’s unfortunate that this shift had to happen in order for tech companies to take notice. At Firefox, we’re doing more than that. We believe that in order to truly protect people, we need to establish a new standard that puts people’s privacy first. At Firefox, we have been working on setting this standard by offering privacy-related features, like Tracking Protection in Private Browsing, long before these issues were brought to light. With this new, increased awareness for privacy, we feel that the time is right for the next step in stronger online protections for everyone.

Last year, we announced our new approach to anti-tracking, and our commitment to help people stay safe whenever they used Firefox. One of those initiatives outlined was to block cookies from known third party trackers in Firefox. Today, Firefox will be rolling out this feature, Enhanced Tracking Protection, to all new users on by default, to make it harder for over a thousand companies to track their every move. Additionally, we’re updating our privacy-focused features including an upgraded Facebook Container extension, a Firefox desktop extension for Lockwise, a way to keep their passwords safe across all platforms, and Firefox Monitor’s new dashboard to manage multiple email addresses.

Enhanced Tracking Protection blocks sites from tracking you

For new users who install and download Firefox for the first time, Enhanced Tracking Protection will automatically be set on by default as part of the ‘Standard’ setting in the browser and will block known “third-party tracking cookies” according to the Disconnect list. We talk more about tracking cookies here. Enhanced Tracking Protection will be practically invisible to you and you’ll only notice that it’s operating when you visit a site and see a shield icon in the address bar next to the URL address and the small “i” icon. When you see the shield icon, you should feel safe that Firefox is blocking thousands of companies from your online activity.

For those who want to see which companies we block, you can click on the shield icon, go to the Content Blocking section, then Cookies. It should read Blocking Tracking Cookies. Then, click on the arrow on the right hand side, and you’ll see the companies listed as third party cookies and trackers that Firefox has blocked. If you want to turn off blocking for a specific site, click on the Turn off Blocking for this Site button.

For existing users, we’ll be rolling out Enhanced Tracking Protection by default in the coming months without you having to change a thing. If you can’t wait, you can turn this feature on by clicking on the menu icon marked by three horizontal lines at the top right of your browser, then under Content Blocking. Go to your privacy preferences and click on the Custom gear on the right side. Mark the Cookies checkbox and make sure that “Third-party trackers” is selected. To learn more about our privacy and security settings and get more detail on what each section – Standard, Strict, and Custom – includes, visit here.

For existing users, go to your privacy preferences, click on the Custom gear and mark the Cookies checkbox

Latest Facebook Container blocks tracking from other sites

Earlier this year, Mozilla was honored as one of the World’s Most Innovative Companies by Fast Company. Notably our Facebook Container extension played a big role in getting us selected. With more than two million downloads since it launched, our Facebook Container is an add-on/web extension that helps you take control and isolate your web activity from Facebook (i.e. following and tracking you across the web). Today, we’re releasing the latest update for Facebook Container which prevents Facebook from tracking you on other sites that have embedded Facebook capabilities such as the Share and Like buttons on their site.

For example, when you are on a news site and reading an article, you often see Facebook Like and Share buttons. Our Facebook Container will block these buttons and all connections to Facebook’s servers, so that Facebook isn’t able to track your visits to these sites. This blocking makes it much harder for Facebook to build shadow profiles of non-Facebook users. You will know the blocking is in effect when you see the Facebook Container purple fence badge.

Facebook Container will block these buttons and all connections to Facebook’s servers

To add the latest Facebook Container Add-On, visit here.

Meet Firefox Lockwise: Manage Your Passwords Safely and Take them Everywhere

Last Summer, we brought you Firefox Lockbox for iOS, and in March of this year we announced both Firefox Lockbox for Android and an iPad-optimized version to expand the ecosystem. One of the top most requested features from users was to find a way to manage their passwords. Today, we are rolling out a Firefox desktop extension that offers this feature and completes this product family we are now calling Firefox Lockwise.

As part of the Firefox Lockwise product suite, formerly known as Firefox Lockbox, the desktop extension will give you more control over your stored passwords with shared access from every device. With the new desktop extension, Firefox Lockwise will provide an additional touchpoint to store, edit and access your passwords. The extension provides an enhanced experience for your saved logins, which will allow you to more easily manage and interact with your stored passwords in Firefox. You will notice a seamless integrated experience in Firefox when you move from desktop to mobile, with a similar layout of key features for easy navigation and access, and easy access to your logins and passwords.

The new Firefox Lockwise desktop extension includes:

  • Manage your saved list of passwords – The new dashboard interface makes it simple to update and manage your saved list. If you’re no longer frequenting a site, you can easily delete your saved password. And for the sites you access frequently, you can quickly reference and edit what is being stored, thus giving you an easy way to take control of your online privacy.
  • Access your passwords anywhere – Whether you’re shopping for shoes on your desktop or purchasing them on-the-go from your favorite site, Firefox Lockwise has you covered. Both the mobile app and desktop extension can help you quickly retrieve your password to access your site account, no matter which device you’re on to take advantage of member discounts or free shipping.

Whether you are a loyal user or you are ready to take control of your passwords, try Firefox Lockwise, available on iOS, Android, and now a Firefox add-on for Desktop.

Firefox Monitor adds dashboard to manage multiple email addresses

Since the launch of Firefox Monitor, a free service that notifies you when your email has been part of a data breach, more than 635,000 people have signed up for alerts. Users have been checking multiple personal email addresses on Monitor since launch, and the ability to easily manage multiple accounts has been a top, frequently requested feature. Today we’re launching a central dashboard to help you track and manage multiple email addresses, whether it’s your personal email accounts or ones for professional use.

Through the breach dashboard, you’ll receive a quick summary of updates for all registered email accounts. You’ll be able to easily identify which emails are being monitored, how many known data breaches may have exposed your information, and specifically, if any passwords have been leaked across those breaches. Adding a new email address to your existing Firefox Monitor account is simple, and whether you’re managing one – or multiple – new email accounts, you will be able to select a primary email address to serve as the hub for all notifications and alerts. We added a safety measure to ensure that all email addresses are verified by email before they are activated.

Identify which emails are being monitored, how many known data breaches may have exposed your information, and if any passwords have been leaked across those breaches

Being part of a data breach is not fun, but keeping track of and knowing where your private information may have been made public is one of the first steps in taking control of your online privacy.

We invite you to check out the new breach dashboard on Firefox Monitor!

 

The post Firefox Now Available with Enhanced Tracking Protection by Default Plus Updates to Facebook Container, Firefox Monitor and Lockwise appeared first on The Mozilla Blog.

The Firefox FrontierTechnology with respect and honesty. Here’s how we do it.

Tech companies are using the word “privacy” a lot these days. What do they mean when they say it? To one company, privacy means keeping your information between you and … Read more

The post Technology with respect and honesty. Here’s how we do it. appeared first on The Firefox Frontier.

QMOFirefox 68 Beta 6 Testday Results

 

Hello Mozillians!

As you may already know, last Friday May 31st – we held a new Testday event, for Firefox 68 Beta 6.

Thank you all for helping us make Mozilla a better place: Rockstarprem007, Mohamed Bawas, Aishwarya Narasimhan and Aishu, noelonassis!

Result: Several test cases were executed for: Activity Stream and  Pin Firefox shortcut to taskbar for Windows 10.

Thanks for another awesome testday, we appreciate your contribution! 🙂

We hope to see you all in our next events, keep an eye on QMO.
We will make announcements as soon as something shows up!

Cameron KaiserMake Cheese Grating Great Again

The Mac Pro, like New Coke, is back. In a miniature cheese grater you could make a mean quesadilla with. A million Power Mac G5s and O.G. Mac Pros are singing out, "we told you so! We told you so!"

But if you're going to buy one of these things (starting at $6000), you don't get to complain how much a Talos II costs.

This Week In RustThis Week in Rust 289

Hello and welcome to another issue of This Week in Rust! Rust is a systems language pursuing the trifecta: safety, concurrency, and speed. This is a weekly summary of its progress and community. Want something mentioned? Tweet us at @ThisWeekInRust or send us a pull request. Want to get involved? We love contributions.

This Week in Rust is openly developed on GitHub. If you find any errors in this week's issue, please submit a PR.

Updates from Rust Community

News & Blog Posts

Crate of the Week

This week's crate is emu, a Rust-based language for programming GPUs. Thanks to Caleb Winston for the suggestion!

Submit your suggestions and votes for next week!

Call for Participation

Always wanted to contribute to open-source projects but didn't know where to start? Every week we highlight some tasks from the Rust community for you to pick and get started!

Some of these tasks may also have mentors available, visit the task page for more information.

If you are a Rust project owner and are looking for contributors, please submit tasks here.

Updates from Rust Core

283 pull requests were merged in the last week

Approved RFCs

Changes to Rust follow the Rust RFC (request for comments) process. These are the RFCs that were approved for implementation this week:

Final Comment Period

Every week the team announces the 'final comment period' for RFCs and key PRs which are reaching a decision. Express your opinions now.

RFCs

No RFCs are currently in final comment period.

Tracking Issues & PRs

New RFCs

Upcoming Events

Asia Pacific
Europe
North America

If you are running a Rust event please add it to the calendar to get it mentioned here. Please remember to add a link to the event too. Email the Rust Community Team for access.

Rust Jobs

Tweet us at @ThisWeekInRust to get your job offers listed here!

Quote of the Week

apparently I wrote Building Git to explain a complex problem to rust devs who could then help me build it in rust

/dev/horse @ jsconf eu (mountain_ghosts) on twitter

Thanks to Dos Moonen for the suggestion!

Please submit quotes and vote for next week!

This Week in Rust is edited by: nasa42, llogiq, and Flavsditz.

Discuss on r/rust.

Mozilla VR BlogPathfinder: a first look at the best fonts and vector graphics on VR/AR

Pathfinder: a first look at the best fonts and vector graphics on VR/AR

Second only to watching video, most of the time people spend on computing devices today involves reading text and looking at vector graphics in the toolbars and user interfaces of programs. Over the last 20 years, a great deal of focus has gone into improving the quality of those fonts and graphics: subpixel anti-aliasing, cached font maps, etc.

Unfortunately, as you can see in the left image below, that work results in grainy and jagged text in modern AR headsets. Ideally, we would render text smoothly at all angles, as shown in the image on the right.

Pathfinder: a first look at the best fonts and vector graphics on VR/AR Document in built-in browser
Pathfinder: a first look at the best fonts and vector graphics on VR/AR Document in Pathfinder

The key limitation today is that most vector graphics or font rendering libraries assume that the images are viewed head on at a fixed resolution, rather than having a user walk around the content viewing it from many different angles and distances. Fortunately, Pathfinder fundamentally reimagines this rasterization process, and can render complex images and documents in real time.

The following movie provides a demonstration of both Pathfinder's font and vector graphics rendering.

Pathfinder running on the Magic Leap augmented reality headset

The main innovation in Pathfinder is to move rendering of curved shapes from the CPU to the GPU, and to support the transforms required for viewing from any angle. Since many modern devices have very powerful GPUs compared to their CPU, this results in a massive performance gain in 3D rendering, allowing graphics and text to be rendered on every frame, rather than rendered once at a fixed resolution. This is done by breaking down complex images into much smaller tiles, many of which are just flat colour, and writing GPU shader code to handle the tiles that are more complicated. (For more details, see A Look at Pathfinder by Nicolas Silva.)

Pathfinder: a first look at the best fonts and vector graphics on VR/ARPathfinder: a first look at the best fonts and vector graphics on VR/AR
How Pathfinder renders the GhostScript Tiger (from A Look at Pathfinder)

Today, we are providing demos of the technology, available for daydream VR and Magic Leap here! These are provided to give an early glimpse of what Pathfinder is capable of, and not for deploying in production yet! We are working to enable Pathfinder inside of WebRender, which will allow it to be used directly in our new browsers for AR headsets based on Servo and potentially in all Firefox Gecko-based browsers in the future. And we'd like to make it available for use in Unity projects and as a WASM package, which will not have full integration with the operating system but still provide a dramatic improvement in rasterization quality. Please drop by the Github repository to check it out for your own projects and contribute to ensure that our new computing platforms have the best possible readability.

The Servo BlogThis Week In Servo 130

In the past month, we merged 208 PRs in the Servo organization’s repositories.

Windows nightlies are temporarily broken.

Planning and Status

Our roadmap is available online, including the team’s plans for 2019.

This week’s status updates are here.

Exciting works in progress

<figcaption>An early success rendering a website in the HoloLens emulator.</figcaption>

Notable Additions

  • Manish added foundations of automated testing of WebXR.
  • Eijebong implemented type-safe DOM APIs that interact with JS Promises.
  • jdm and paulrouget upgraded glutin to 0.21.
  • maharsh312 implemented most of the missing OffscreenCanvas APIs.
  • ferjm added support for simultaneous playback of audio and video streams.
  • Darkspirit updated various network security data files (HSTS, PSL, CAs).
  • jdm added support for running Servo on Windows via ANGLE.
  • Manishearth made receiving streams through WebRTC possible.
  • pylbrecht implemented resource timing for synchronous network requests.
  • jdm fixed a problem preventing transitioning into Daydream VR.
  • jdm improved the ergonomics of testing Magic Leap builds.
  • codehag implemented support for using a remote web console from Firefox with Servo’s content.
  • PurpleHairEngineer implemented the StereoPannerNode WebAudio API.
  • jdm upgraded the JavaScript engine.
  • tdelacour improved the type-safety of text input code that switches between UTF-8 and UTF-16 strings.
  • ceyusa created an API for providing hardware-accelerated GL video playback.
  • mmatyas implemented support for compressed textures in WebGL.
  • jdm upgraded the NDK in use for Android builds.

New Contributors

Interested in helping build a web browser? Take a look at our curated list of issues that are good for new contributors!

The Rust Programming Language BlogThe Governance WG is going public

Hey all! Today we're happy to announce the Governance Working Group is going public. We've been spending the last couple weeks finding our bearings and structuring the working group.

You can find our charter outlining our main goals and priorities in our work repository. We are using the Github issues, milestones and projects to organise and track our progress. The readme in the repository explains our working process a bit more in detail. It also states how you can talk to us (hint, via discord) and get involved.

If you're interested in the governance working group, you may also be interested in the Lang Team Meta WG, which is exploring solutions specific to the lang team.

Mozilla B-Teamhappy bmo push day: now with added contrast

happy bmo push day: now with added contrast

release tag

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

  • [1225902] Show only flags with requestee in the “Flags You Have Requested” section
  • [1552720] Linkify bug summaries on My Dashboard query table
  • [1542554] Add bug type icons to dependency trees
  • [1514000] Suppress duplicated changes in bug history made at the same time mainly due to mid-air collisions
  • [1523536] New bug’s…

View On WordPress

Mozilla B-Teamhappy bmo push day (May 16th)

happy bmo push day (May 16th)

release tag

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

  • [1546502] Miscellaneous tweaks and fixes for 2019 week 16
  • [1345750] “Depends on” and “Blocks” bug lists should still show list of bug links in edit mode
  • [1544059] Cloning a bug as a blocker doesn’t copy the ‘component’ field
  • [1543741] Blocklist requests getting filed as ‘defect’ instead of ‘task’ because of custom form
  • [1…

View On WordPress

Tantek ÇelikThe @W3C Needs You: Please Vote For Change In The @W3CAB Election

(as is customary for W3C), is the deadline for voting.

Please Vote in the 2019 W3C Advisory Board Election (W3C Member-only link, only Advisory Committee members can vote).

My fellow Advisory Board (AB) candidates and additional members of the W3C Community have shared their thoughts on the AB election, some on their blogs, and some on W3C Member only list(s).

It is very important that you explicitly rank candidates according to what is most important to you due to the way the current W3C STV mechanism is interpreted and implemented by the W3C Team. Past STV elections have shown that a Ranked 1 vote is crucial to candidates, Ranked 2 may have some impact, and the likelihood of effect drops off precipitously from there (though you should still rank at least a few more, ideally all candidates, just in case).

I’ve previously stated why I think W3C is facing several existential crises, how I will do my best to help W3C during this crucial time of transition, and thus ask for your Ranked 1 vote:

The AB has seven open spots in this election, so I will recommend six others for your consideration of a Ranked 1 vote.

Each of these candidates has many strengths, I am highlighting just one or two, depending on what may be most important to help steer the W3C in the next two years. Each of these candidates has many more strengths. Ordered by those with their own posts/blogs first (then by full name).

If web developer perspective is most important to you, choose Aaron Gustafson as Ranked 1

Aaron has worked as a profession web developer, written several well regarded books on web development, and spoken with & taught numerous web developers. Of all candidates he brings the most modern and most aware perspective of what matters to web developers today on the web, and what standards the W3C must prioritize in order to better serve today and tomorrow’s web development community, the community that builds the web you and I depend on day-to-day. Read his blog post for more

If experience is most important to you, choose Chris Wilson as Ranked 1

Chris Wilson has been working on the web for over 25 years, more than any other candidate. He has written code in web browsers, written specifications, chaired working groups, and served for five years on the Advisory Board. He has more experience, and a broader perspective, across more companies essential to the evolution of the web, than any other canidate. See his post for more

If bold directness & standing up to W3C Management is most important to you, choose Elika Etemad as Ranked 1

I have had the good fortune of working with Elika (AKA fantasai) for numerous years in the CSS Working Group, have seen her contribute to invited W3C Advisory Board discussions, and Advisory Committee meetings as well. She always brings a well considered, often bold, and always direct perspective. She brings a strength of commitment that is inspiring and I believe necessary to represent the needs of the web community especially when such needs require standing up to W3C Management. This will be an essential skill during W3C’s upcoming transitions. Read her blog post for more

If accessibility is most important to you, choose Léonie Watson as Ranked 1

I have had the good fortune to work with Léonie Watson during my past tenure on the Advisory Board. She has consistently brought a diverse and inclusive perspective in all our matters, especially making sure the AB was aware of accessibility implications of any number of policy decisions. Read her blog for more

If consensus building is most important to you, choose Alan Stearns as Ranked 1

I have also had the good fortune of working with Alan Stearns for many years. He has been an extremely effective chair of the CSS Working Group, a very large and diverse set of individuals with a variety of backgrounds, interests, and priorities, that is also extremely prolific. He has demonstrated time & time again that when there is conflict, he is able to mediate a dialog to find common ground, find fair ways to resolve differences, or often get parties to defer when progress can be made regardless.

If Chinese standards efforts representation is most important to you, choose Judy (Hongru) Zhu as Ranked 1

While I was on the Advisory Board, I got to know Judy and very much appreciate her participation. She brought key insights with regards to the interactions of global standards efforts, especially with standards efforts in China. I believe these insights have helped the governance of W3C, and W3C’s goals of producing truly global standards.

Thank you Natasha and Mike

Huge thanks to Advisory Board incumbents Natasha and Mike for their service. I am glad I got a chance to work with Natasha and Mike on the AB. Natasha provided a refreshing perspective and I hope she considers running for the AB in the future. Mike has served on the AB for a very long time, and demonstrated the ability to actively evolve the AB, the W3C, and forge a productive relationship with the WHATWG (as noted in the recenty announced MoU). Both Mike and Natasha set good examples for whoever is next elected to the AB.

Please vote!

Go Vote in the 2019 W3C Advisory Board Election (W3C Member-only link, only Advisory Committee members can vote).

If you have already voted, thank you for voting. If you have not, please take the few minutes to do so. In either case please consider the above candidates for their strengths and consider (re)ranking accordingly. Thank you for your consideration.

Daniel Stenbergcurl: 3K forks

It’s just another meaningless number, but today there are 3,000 forks done of the curl GitHub repository.

This pops up just a little over three years since we reached our first 1,000 forks. Also, 10,000 stars no too long ago.

Why fork?

A typical reason why people fork a project on GitHub, is so that they can make a change in their own copy of the source code and then suggest that change to the project in the form of a pull-request.

The curl project has almost 700 individual commit authors, which makes at least 2,300 forks done who still haven’t had their pull-requests accepted! Of course those are 700 contributors who actually managed to work all the way through to inclusion. We can imagine that there is a huge number of people who only ever thought about doing a change, some who only ever just started to do it, many who ditched the idea before it was completed, some who didn’t actually manage to implement it properly, some who got their idea and suggestion shut down by the project and of course, lots of people still have their half-finished change sitting there waiting for inspiration.

Then there are people who just never had the intention of sending any change back. Maybe they just wanted to tinker with the code and have fun. Some want to do private changes they don’t want to offer or perhaps they already know the upstream project won’t accept.

We just can’t tell.

Many?

Is 3,000 forks a lot or a little? Both. It is certainly more forks than we’ve ever had before in this project. But compared to some of the most popular projects on GitHub, even comparing to some other C projects (on GitHub the most popular projects are never written in C) our numbers are dwarfed by the really popular ones. You can probably guess which ones they are.

In the end, this number is next to totally meaningless as it doesn’t say anything about the project nor about what contributions we get or will get in the future. It tells us we have (or had) the attention of a lot of users and that’s about it.

I will continue to try to make sure we’re worth the attention, both now and going forward!

(Picture from pixabay.)

Honza BambasFixing adb device unauthorized in VirtualBox hosted linux

Getting either no devices listed or just unauthorized from adb devices when running adb in a virtual machine? My setup is VirtualBox running Ubuntu 18.04 LTS hosted in Windows 10 machine. Connecting one of my Android devices with Lineage 16 and running adb in the VM doesn’t make the device ask for debugging authorization. When connecting with adb from the host machine, it does.

The solution is inspired by this stackoverflow post, with few modifications.

Prerequisites:

On both the host and the virtual machine make sure the version of adb is exactly the same. Otherwise the client will ask the server to restart and unexpectedly fail, when using the below provided solution.

For instance, Firefox for Android build uses internally adb version 1.0.41. But the system wide adb (up to date) in Ubuntu is 1.0.39. To download platform-tools for Windows, in my case, with that version you have to hack the URL bar a bit as there are no download links on the android site for older versions. Trial and error got me this link to get the tools with adb version 1.0.39 for Windows.

On the host machine:

  • Connect the device with USB debugging enabled, as usually
  • Don’t connect it in the running VirtualBox VM
  • Run adb devices to check the host machine sees the devices, check the server has started on port 5037

On the virtual machine:

  • Make sure the adb server is not running with adb kill-server
  • Check nothing listens on the 5037 port with netstat -nao | grep :5037
  • Run socat tcp-listen:5037,fork tcp:10.0.2.2:5037 where 10.0.2.2 should be the host address as seen from the VirtualBox VM
  • Run adb devices
  • You should see the same result as on the host machine and be able to work with the device now

The trick is to simply forward the TCP traffic between the two machines and pretend a server in the VM. It can work well the other way around with any kind of direct TCP relay in Windows, any kind of port and any IP address of choice.

I wrote this more for myself to not forget till next time, but maybe it will help someone.

The post Fixing adb device unauthorized in VirtualBox hosted linux appeared first on mayhemer's blog.

The Mozilla Blog“We believe the internet can be better,” Mozilla to the International Grand Committee

Alan Davidson, Vice President of Global Policy, Trust and Security testified today on behalf of Mozilla before the International Grand Committee on Big Data, Privacy and Democracy. The International Grand Committee, composed of representatives from numerous governments around the world, has gathered in Ottawa, Canada for its second meeting, hosted by the House of Commons of Canada.

“We believe the internet can be better. And to build an internet that is both innovative and worthy of people’s trust, we will need better technology and better policy,” said Alan. In his testimony Alan focused on the need for better product design to protect privacy; getting privacy policy and regulation right; and the complexities of content policy issues. Against the backdrop of tech’s numerous missteps over the last year, our mission-driven work is a clear alternative to much of what is wrong with the web today.

For more, check out the replay of the hearing or read Alan’s prepared statement for the Committee.

 

The post “We believe the internet can be better,” Mozilla to the International Grand Committee appeared first on The Mozilla Blog.

Hacks.Mozilla.OrgJavaScript and evidence-based language design

Author’s note: Hi, I’m an engineer at Mozilla working on the Firefox DevTools server. I’m also a TC39 representative. This post focuses on some of the experiments I am trying out at the TC39, the standards body that manages the JavaScript specification. A follow up post will follow…


In what ways can empirical evidence be used in the design of a language like JavaScript? What kind of impact would a more direct connection to developers give us? As stewards of the JavaScript specification, how do we answer questions about the design of JavaScript and help make it accessible to the thousands of new coders who join the industry each year? To answer this we need to experiment, and I need your help.

Enter stage left: a survey

I know, it isn’t so exciting. It’s a survey. We are testing whether or not the methods used in this survey provide useful information about specific parts of a proposal. In other words, we are testing how we can identify different factors related to code: Cognitive load, error proneness, readability, and learn-ability.

The goal is to see what we can learn from the data you share. Whether it will be useful remains to be seen. This is the first attempt to do this, so it will not be perfect.

This is also why I need everyone’s help. Whatever your background, your responses will be very much appreciated. You might be learning JavaScript as your first language, coming to JavaScript from another language, or working in the language professionally.

Well, I hope I have gotten everyone excited to take a survey. I am certainly excited. It is estimated to be 15 minutes, I hope it is enjoyable!

Here is the survey link again.

The post JavaScript and evidence-based language design appeared first on Mozilla Hacks - the Web developer blog.

Tantek ÇelikI Am Running For The @W3C Advisory Board (@W3CAB)

I am running for the W3C Advisory Board (AB). If you work on or care about open web standards, I am asking you, and in particular your W3C Advisory Committee representative, to vote me for as their #1 vote (due to the way the current W3C STV mechanism is interpreted and implemented by the W3C Team).

The web community depends on W3C as a key venue for open web standards development. We are in a period of transition and existential risks for W3C (detailed in my official Advisory Board nomination statement). I bring both the experience (served on the AB for five years, 20+ years of first-hand standards work at W3C), and the boldness (created and drove numerous open reforms) necessary to work with an Advisory Board committed to modernizing W3C into a form that continues to support pragmatic & responsive open standards development.

There are many highly qualified candidates running for the W3C Advisory Board in this election, with a variety of strengths and abilities.

I believe the most important issue for this election is the active modernization of W3C to both avoid its existential risks and hopefully refocus on its best qualities, providing an even better venue for modern open web standards development.

Now more than ever we need an active Advisory Board composed of individuals who have demonstrated that they are bold web-doers that can actively drive change at the W3C. This means they must both have experience with editing & shipping broadly applicable specifications at W3C (ideally also experience with W3C processes), and have shown the initiative to teach themselves to pragmatically first-hand use the technologies of the web itself to express their work, i.e. using their own websites.

There are (currently) four additional AB candidates that have such experience and actively use the web itself to do their work. I encourage you to read their blog posts (or blogs in general) and vote for them as well:

  1. Chris Wilson (Google)
  2. Aaron Gustafson (Microsoft)
  3. Elika Etemad (AKA fantasai, W3C Invited Expert)
  4. Léonie Watson (TetraLogical)

The deadline for votes is .

Please Vote in the 2019 W3C Advisory Board Election (W3C Member-only link, only Advisory Committee members can vote) for myself (preferably as "Ranked 1"), and at least the other abovementioned candidates (Ranked 2 through Ranked 5) in an order according to who you think has the experience, capabilities, and will to actively collaborate and drive positive changes at the W3C. Thank you for your consideration.

Cameron KaiserFinally, a bit of love for Intel Tiger

Again, a polite reminder that Intel Macs aren't supported, but that doesn't mean people don't want to run TenFourFox on them. Thanks to new builder Hayley, Tiger-compatible versions of FPR14 and the MP4 Enabler are available for Intel. Previous versions have had issues on Tiger due to issue 209, so watch for that if you choose to run these, but initial testing at least looks very promising.

I've also given Ken direct access to that folder so that he can coordinate and upload Intel builds on a semi-regular basis without me as the rate limiting step. Remember, the Intel build is unsupported and issues posted to Tenderapp about it will be closed. There are no guarantees that it works, and there are no guarantees that builds will continue.

Meanwhile, I'm working on what may be a fruitless effort to add async/await support and am about halfway done with the merge. It will probably build but no guarantees that it will work, and there's probably some additional fixes needed to get it up to reasonable standards compliance. I'm trying to keep it all in one easily managed commit which is why there hasn't been much activity on Github for FPR15; this may be the only major new feature in order to reduce regression risk. More later.

Mozilla Open Design BlogA glimpse of what’s to come.

Today we’re presenting new brand marks for Firefox Monitor and Firefox Lockwise. Lockwise? Yes, that’s the official name for the service we’d nicknamed “Lockbox” during its product development phase. The new icons are meant to signal the functions these apps perform. Firefox Monitor, which helps you discover if your email address has been part of a data breach and can alert you about further breaches, is represented by a magnifying glass. Firefox Lockwise, which provides an easy way to store your Firefox passwords and protect your data, suggests both a lock and a profile. The marks reinforce that all of our Firefox products and services help you keep your personal life private.

 

If you’ve been wondering whatever happened to the Firefox brand identity work we shared in this space last year, and whether System 1 or System 2 prevailed, these new icons offer a clue.  They are not the whole story. We’ll be unveiling an evolved Firefox brand the week of June 10th, so please stay tuned. We look forward to hearing what you think.

The post A glimpse of what’s to come. appeared first on Mozilla Open Design.

Mozilla Addons BlogFriend of Add-ons: Martin Giger

Our newest Friend of Add-ons is Martin Giger! Martin is a leader and member of the Mozilla Switzerland community, an extension developer, and a frequent contributor to Mozilla’s community forums, where he helps people find answers to their questions about extension development. If you have ever visited our forums or joined one of our channels on IRC, there’s a good chance you’ve seen Martin kindly and patiently helping people resolve their issues. (He has also written a great blog post about how to effectively ask for help when you get stuck on a problem.)

Martin began contributing to Mozilla in the early 2010s when he began localizing a Thunderbird extension into German and building his first Firefox extension. He also became involved with the Nightingle Media Player project, an open-source audio player and web browser based on the Mozilla XULRunner.

Since then, Martin has contributed to a number of add-on projects, including the Add-on SDK, the add-ons linter, the site addons.mozilla.org, and the WebExtensions API. Always interested in finding creative technical solutions to solve problems he encounters in everyday life, he has recently been tinkering with Mozilla’s Web of Things platform, rewriting a Twitter tool used by the Mozilla Switzerland community, and managing web-related activities for the concert band he plays in.

In addition to spending time with Mozillians online, Martin also enjoys socializing in person with members of his local community. “Doing things with local contributors is meaningful,” he remarks. “No matter what they contributed to, meeting up with people and talking about things you’re passionate about makes Mozilla something you can grasp (and not just something you spend time in front of a computer on).”

Martin, the entire add-ons team extends their gratitude and appreciation to you for your kindness, willingness to help others, and sound judgement. Thank you for all of your contributions to our ecosystem!

If you are interested in getting involved with the add-ons community, please take a look at our wiki for some opportunities to contribute to the project.

The post Friend of Add-ons: Martin Giger appeared first on Mozilla Add-ons Blog.

This Week In RustThis Week in Rust 288

Hello and welcome to another issue of This Week in Rust! Rust is a systems language pursuing the trifecta: safety, concurrency, and speed. This is a weekly summary of its progress and community. Want something mentioned? Tweet us at @ThisWeekInRust or send us a pull request. Want to get involved? We love contributions.

This Week in Rust is openly developed on GitHub. If you find any errors in this week's issue, please submit a PR.

Updates from Rust Community

News & Blog Posts

Crate of the Week

This week's crate is mockiato, a strict yet friendly mocking library for Rust 2018. Thanks to Ruben Schmidmeister for the suggestion!

Submit your suggestions and votes for next week!

Call for Participation

Always wanted to contribute to open-source projects but didn't know where to start? Every week we highlight some tasks from the Rust community for you to pick and get started!

Some of these tasks may also have mentors available, visit the task page for more information.

No issues were proposed for CfP.

If you are a Rust project owner and are looking for contributors, please submit tasks here.

Updates from Rust Core

286 pull requests were merged in the last week

Approved RFCs

Changes to Rust follow the Rust RFC (request for comments) process. These are the RFCs that were approved for implementation this week:

No RFCs were approved this week.

Final Comment Period

Every week the team announces the 'final comment period' for RFCs and key PRs which are reaching a decision. Express your opinions now.

RFCs

No RFCs are currently in final comment period.

Tracking Issues & PRs

New RFCs

Upcoming Events

Africa
Asia Pacific
Europe
North America
South America

If you are running a Rust event please add it to the calendar to get it mentioned here. Please remember to add a link to the event too. Email the Rust Community Team for access.

Rust Jobs

Tweet us at @ThisWeekInRust to get your job offers listed here!

Quote of the Week

I used to think of programs as execution flowing and think about what the CPU is doing. As I moved to rust I started thinking a lot more about memory: how the data was laid out in memory, and how ownership of different parts of memory is given to different parts of the program at run time.

Oliver Gould on "The Open Source Show: All About Rust

Thanks to infogulch for the suggestion!

Please submit quotes and vote for next week!

This Week in Rust is edited by: nasa42, llogiq, and Flavsditz.

Discuss on r/rust.

QMOFirefox 68 Beta 6 Testday, May 31st

Hello Mozillians,

We are happy to let you know that Friday, May 31st  we are organizing Firefox 68 Beta 6 Testday. We’ll be focusing our testing on: Activity Stream and Pin Firefox shortcut to taskbar for Windows 10.

Check out the detailed instructions via this etherpad.

No previous testing experience is required, so feel free to join us on #qa IRC channel where our moderators will offer you guidance and answer your questions.

Join us and help us make Firefox better!

See you on Friday! 🙂

Karl DubostThe illusions of privacy (What about intimacy?)

We have read in the news that big platforms are willing to tackle head on privacy. The word "privacy" became an act of marketing, a way to sell a brand, to grow market shares, to renew or increase trust. This became an object of commerce. We even see debates on who could provide the best solution for a privacy oriented platform or that privacy is a hype.

For a long time, we know that the amount of data collections by any platforms is humongous.

In the same time, another topic of concerns has increased, security with different angles:

  • being safe online for individual people
  • stopping massive data hacking
  • protecting knowledge and speech with regards to the surge of fake news

All of these mostly resonate around the one-to-many/many-to-one issues.

But one thing is certain. The big platforms will redefine the word "privacy". It will be a space where you communicate with your friends protected from the mass. Privacy will be redefined as small group communications. Don't be fooled. There is still one entity which will be recording everything, studying patterns of communications, making money on understanding your behavorial patterns.

Worse… with the illusion of privacy given by this smaller spaces of communications, the people using them will feel more secure, comfortable, more at home. They will stop thinking twice about sharing something, while the entity is still listening.

Intimacy is something we share with others in small groups indeed. It has a lot of variations, levels of opacity, adjusted for contexts. Big platforms will never be able to provide a true space of privacy or intimacy, while their core business is about listening on what we express. Smaller communication groups are indeed sometimes the solution, but they need to exist outside of any listening/recording apparatus created by a third party. Communications are a contract in between the people who choose to have them. Any third party listening, recording, analyzing to sell the value extracted from these communications challenges right away the notion of privacy. The forest is not dark, when someone is listening.

Otsukare!

Hacks.Mozilla.OrgFirefox brings you smooth video playback with the world’s fastest AV1 decoder

Tuesday’s release of Firefox 67 brought a number of performance enhancing features that make this our fastest browser ever.  Among these is the high performance, royalty free AV1 video decoder dav1d, now enabled by default on all desktop platforms (Windows, OSX and Linux) for both 32-bit and 64-bit systems.

With files more than 30% smaller than today’s most popular web codec VP9 [1], and nearly 50% smaller than its widely deployed predecessor H.264 [2], AV1 allows high-quality video experiences with a lot less network usage, and has the potential to transform how and where we watch video on the Internet. However, because AV1 is brand new and more sophisticated, some experts had predicted that market adoption would wait until 2020 when high-performance hardware decoders are expected.  Dav1d in the browser upends these predictions.

Sponsored by the Alliance for Open Media, dav1d is a joint effort between the French non-profit VideoLAN and the greater FFmpeg open source audio/video community.  Some of the leading minds in open source multimedia joined forces to release the first version of dav1d last fall, already 2x to 5x faster than libaom, the reference decoder published by AOMedia as part of the AV1 standards effort.

Since then the dav1d developers have squeezed out even more performance by profiling and rewriting critical sections in highly-parallelized SIMD assembly. And this shows in the benchmarks:

Higher performance and greater efficiency means smooth playback of AV1 video in the browser with significantly less CPU utilization.

AV1 already seeing adoption on the web

Landing dav1d in Firefox could not have happened at a better time.  In just the past few months we’ve seen remarkable growth in the use of AV1, with our latest figures showing that 11.8% of video playback in Firefox Beta used AV1, up from 3% in March and 0.85% in February.

Now that desktop Firefox contains dav1d, we expect even more websites will take advantage of this next-generation, royalty-free video codec AV1.

Mozilla investing in the AV1 future

State-of-the-art decoders like dav1d are great for video playback, but best-in-class, free and open source software encoders are equally important to a healthy AV1 community.  The AOMedia reference encoder was developed with the goal of creating the AV1 standard, not a production encoder.  Thus, Mozilla and Xiph.Org are jointly developing a clean-room encoder named rav1e (the Rust AV1 Encoder) to increase encoding gains over the reference encoder and allow software encoding fast enough for real-time applications like WebRTC.

Good encoders make heavy use of psychovisual models to allocate bits for what humans perceive as good visual quality (not PSNR).  With rav1e we are applying the perceptual analysis expertise from our earlier Daala and Theora codec development efforts to add activity masking, better color balancing, improved rate control and perceptual distortion metrics like CDEF that bring new, improved quality to AV1 encoding.

We’re also investing considerable research to improve encoder speed, optimizing new techniques that appear for the first time in AV1.  It’s not enough to rewrite existing code from the initial reference encoder in SIMD assembly and make it four times faster. Rav1e is developing ways to make AV1 encoding tools 1000x faster by finding new algorithms rather than simply optimizing existing code.

Rav1e is getting better all the time.  Active development continues at a rapid pace, landing major new improvements weekly.

Join the conversation

Do you find video compression and related technologies fascinating?  Then join us in New York on June 26 for the Big Apple Video 2019 conference co-hosted by Mozilla and Vimeo.  This full day event focuses on cutting edge video technologies and the user experiences they enable.  With speakers from Twitch, Cisco, NGCodec, Intel, Wikimedia and other well known companies, this conference is designed for video technology enthusiasts like you!

We’d love to have you with us in New York, but if not you can register to attend remotely and watch our on-line video stream.  What else would you expect from a conference on video and related technologies?

References

  1. AV1 beats x264 and libvpx-vp9 in practical use case – https://code.fb.com/
  2. MSU Codec Comparison 2018 – http://www.compression.ru/

The post Firefox brings you smooth video playback with the world’s fastest AV1 decoder appeared first on Mozilla Hacks - the Web developer blog.

Firefox UXThe 11 Secrets of Iterative and Incremental Product Development – A lightining talk

Something I really like about the Firefox UX team is how we are all open to learning from each other.
So, when one of my colleagues shared this specific image in our Slack channel, I knew it was OK to raise the question of why this picture is incorrect.

How to buld a minimum viable product image. The image is divided in two section "Not like this" and "like this" in the not like this section we see one wheel, two wheel, the shape of car and a full car at the end. And sad face is shown for all the examples, but not for the car. In the second section "Like this" you find a skate, a scooter, a bike, a motorbike and a car. And happy face is always shown.

From the discussion that followed, an idea for a lightning talk* on the topic of Iterative and Incremental Product Development emerged – for the benefit of our own team and whoever else will watch this video.

*The title is supposed to be funny. However, when I realized it’s not, it was – well – too late.

The talk

Acknowledgment

I’d like to thank Micheal Verdi for the recording and the editings. Markus Jaritz, for pushing me to share this talk, and Michelle Heubusch for her feedback.

Learn more

Books

Agile Experience Design, Lindsay Ratcliffe & Marc McNeil
Lean UX, Jeff Gothelf & Josh Seiden
Impact Mapping, Gojko Adzic
User Story Mapping, Jeff Patton

Online articles

Making sense of MVP (Minimum Viable Product) – and why I prefer Earliest Testable/Usable/Lovable by Henrik Kniberg
Is User Experience Relevant Where You Work? by Jeff Patton
Don’t Know What I Want, But I Know How to Get It by Jeff Patton
The waterfall trap for “agile” projects By Gojko Adzic
Products over Projects by Sriram Narayan

Transcript

Hello everyone. Thank you for being here for this small talk that I made for the Firefox UX team. The Firefox UX team is based all over the world. Mostly in North America and in Europe, but we have our colleagues from the Taipei team as well. This talk is born from a funny conversation that happened on Slack, where one of my colleagues shared the very popular image, the one with the skateboard and everything, and we started this conversation around iterative and incremental product development. And since I’m a big process nerd, I said, “You know what, I know some stuff about that. Do you want me to share it with you?” And they said, “Yeah, why you don’t share it with the whole group?” So that’s the reason why we are here today to share this presentation about “The 11 Secrets of Iterative and Incremental Product Development.” My name is Emanuela Damiani, and I’m a UX Designer for the Firefox UX team based in Berlin. I’m also part of the Ladies That UX community in Berlin, and the Codemotion community. I just love sharing my knowledge with the rest of the world and to create a larger conversation around design. So let’s get started.

Number one, Agile matters, deal with it. Agile and UX have a lot in common. In February 2001, a group of 17 people working in software got together in Snowbird, to create a manifesto to help others find better ways of developing software by doing it. By doing it means producing it and that, I think, is really interesting because even with your job as a designer, as a researcher, as a content strategist, as a PM, you’re still developing software even if you don’t write code. We’re all working here in the software industry. For us in particular, in Firefox, we’re building the browser which is how people enter the internet, which is all of software. And why does Agile matter? It matters because it really focuses on finding better ways to work together. And it’s where different processes are coming from as well, even if sometimes people forget that the main goal of Agile was to put individuals and interactions over processes and tools. And other principles like working software—so the idea that pushing, having software that works is more important than documenting it. And customer collaboration—so seeking feedback from your end user. And being able to respond to change when your end user gives feedback. And if this feedback is kind of giving you a big hint that what you’re doing maybe is not completely right, is not completely serving your customer or your user, you need to be able to respond to that. So that’s why I feel that Agile and UX have a lot in common and, especially for this presentation, we need to acknowledge that.

Number two, begin with the end in mind. So this is a famous quote from The 7 Habits of Highly Effective People, the book by Stephen Covey. I have the impression that sometimes we kind of forget about that. We forget about how important it is to have a clear endpoint in mind. And as a designer, we know that this is really important because the endpoint in our work can be the vision of our work product. And our job as a designer is to design this end point, so design the final experience, what actually happens when the user uses our product and experiences the product and the flow that we created for them, according to their needs of course. So somehow it’s not just about designing the end point, but designing the alignment, the alignment between the business and the customer, the alignment between different parts of the Org in order to get that vision that we mentioned before. So, begin with the end in mind is something really important.

Number three, don’t pick your solution too early. And this something that I’m big fan of. Like in this case we have here Batman having a coffee. Never start work before you have your favorite beverage. It can be coffee, it can be tea, it can be just water, but it’s important to take that moment, right? Take that moment before going into it and just start. Why is it important to don’t pick our solution too early? Well, one of the big things is about scope creep. So we are not sure if the solution that we are picking are the right one, and we’re not sure about that because we probably didn’t have enough time to learn and research about the problem. So we are focusing on the solution without really thinking about the problem. And also we’re focusing on the solution without really thinking of the user goals together with the business goal. In my personal opinion, we really need to come to agreement that user goals are business goals, and if your business goals somehow mismatch with your user goals, we probably need to have a larger conversation around that. And another reason why it’s important to not jump to a solution too early is because you may end up designing the wrong solution and focusing on a pet feature. So the first point is actually to focus your workflow on the user goal and not the feature because the feature is just part of the product, it’s not the core of the product. The core of the product is the end experience. And the feature is a way to achieve that end, right, that vision that we had before. And a lot of time it’s easy to just think of the feature that maybe makes you or your peers really happy without thinking of the silent majority of users that are not there communicating with you. And because we didn’t learn enough, we can base our solution on the wrong assumptions. And we can even end up having some added prioritization. So we prioritize what we have to do according to gut feelings, according to, as I said before, pet features or wrong assumptions, and you may end up with your backlog full of stuff that then gets implemented, missing the part that was really important for your end user. How can we avoid that? Well, here is where Lean methodology comes to help us. So in Lean there is this idea of the last responsible moment where you can take a decision. So if we know when this last responsible moment is, we can learn as much as possible before that. We can, instead of focusing on, as I said before, on a solution, we have a dedicated time to focus on the problem, to focus on the needs. And here is where user research, and also competitive analysis, looking at previous behavior, looking at previous research really helps us to focus on a solution at the right time.

Number four, avoid the term MVP. Many people are familiar with the idea of MVP, which stands for minimum viable product. The internet is full of diagrams that show “the right way” to do an MVP and the fact that the MVP needs to cover a bit of everything. It’s not just fully functional but it’s also reliable, usable and includes design. All of those thing are right, but the main issue here is the idea. When you build an MVP, what are you doing? That’s why we hear from developers, content strategists, everyone, including the user, right? “This is not what I have in mind.” Or, “I will never have the opportunity to change it.” “After we ship the MVP, it’s done.” There is nothing more wrong with that. So first of all, let’s try to avoid this term and be more precise. Because when we are more precise: we can be more focused, and we can be sure that it doesn’t take too long to ship the MVP. We can understand what a reasonable timeframe is to have something really focused—so what is the user problem that we are solving with the MVP. And we can be sure that our hypothesis is clear—be sure that we know what we want to learn by launching the MVP. Working in the software industry is actually all a learning experience. We always have a hypothesis that we test in different stages in our process. Then we get feedback from our users by having them use or not use what we’ve built, and from there we can refine our hypothesis. But in the end, we are always kind of investigating.

So what are better terms for MVP? Well, if our goal is to have something just to be tested—maybe we have a big usability test. Maybe instead of calling it MVP, we can call it early testable product. If our goal is to understand if the feature or part of the product that we’re building is usable, let’s call it early usable product. Or if you’re trying to understand if the user loves it, well, you get it, let’s call it earliest lovable product. I believe and other people believe too, that having a precise terminology will help us to reduce the scope creep here, and have better end results.

Number five, this picture, is wrong. Keep it in your mind because we’re going to come back here. And yes, this was the picture that was shared in our Slack channel and started all of this.

Number six, iterative and incremental are separate ideas. The whole goal of this presentation is to talk about iterative and incremental process development. So I think it’s important first to understand what we mean by iterative and what we mean by incremental. Let’s start with incremental. With incremental development, we just develop small pieces, small user stories, one piece after another in an incremental way. We basically, gradually build up functionality and at the end, and just at the end, the product is completed. It means that, let’s say that we have a set of user stories for our product, only when all of those user stories are completed, we’re able to put it in front of the user. So we’re able to say it’s done. And to illustrate this, I would like to use this pretty famous metaphor of the Mona Lisa. Thank you to Jeff Patton for illustrating this, and I think it was John Armitage that introduced this concept in his paper “Are Agile Methods Good for Design?” In this picture we see how incremental development should work in theory. Someone has this idea of painting the Mona Lisa, and they just start to paint one piece under another in a progressive way. Only at the end can we see the full Mona Lisa, and we can actually understand the full vision. Because if we look at step one, we don’t know what the rest is. Maybe she’s holding a little kitten, or maybe she’s playing a guitar. We have no idea. Even with the second step, we still don’t have a clear understanding of what this woman is doing. There can still be something to surprise us. So in terms of product, there can be some feature that we’re not aware of, and maybe that’s the big part of our work product. In step three, we can finally see that, yes, what we wanted was this woman, being there, just holding this pose with this beautiful background, and it’s complete. So this is how it should work in theory but the way that I see, and the way that other people see, incremental development being used is more like this. We have this picture and we know more or less that we have paint a woman, so we know that someone has to draw an eye, we know that another team is working on the hands, and we end up having a mess. We end up not having a real clear idea of what we built and why because it was all in someone’s head and it wasn’t clear and what we wanted to do wasn’t shown to everyone.

Let’s talk about iterative. So when we talk about iterative development, we’re building something that we expect to change. We expect that we’re going to build something and remove it and change it and improve it. We always try to evaluate it. So every time that we build something we ask the question, “Does it bring value?” What if we just stop developing today? Is it still something that has some value to the end user? Is it something that creates expectation, that respects what we had in mind in the beginning? And again, we have this whole idea of changing and improving. So you always have a sort of base. You start with a vision actually. You start with thinking, “Okay, I want to create this painting.” And then you add the first layer. So even if you stop right now, even if you stop at this implementation, you can still understand what the vision behind this is. And then you do a second step, you start adding colors and giving it some more flavor, and you see, “Oh yeah, I can see where I want to go.” And the last step is where you add texture, you add details, and you can really fulfill the initial vision. But be clear, here the initial vision was fuzzy, was fuzzy by definition. So we know what we wanted, but we didn’t know how to do it. And it was the team, or in this case, the artist, who created it and put it together.

So as I promised, let’s jump in our TARDIS, and go back to number five. The reason why that picture is wrong is because the first part is actually right. It’s showing how we can build a car. So we first have the tire, and then we have more tires, and we add some part of the car, all together, and in the end we have a car. Our user is not happy because what purpose is just a tire alone? So until the end, we cannot really understand what we’re building. We don’t see the vision, and most importantly, there is no goal. A car without the engine has no real value for the end user. There is no goal around that. So the first try, which was actually correct in the number five images as well, represents the incremental. This one represent the iterative, and as we see here, the main difference between this image proposed in number five is that the user is not really happy here as well in the beginning. Sure, the skateboard, the scooter, the bike, the motorbike and the car, they all allow you to move around. But maybe if you have a family, the skateboard and the scooter is not really the perfect way to move in the city. Even the bike, right? I saw a guy biking with a lot of kittens and it was really cute, but it’s probably not super safe to just bike with an infant during the rainy season. And the motorbike can accomplish more of that goal of going around the city with your family, but probably it’s only the car, that can really fulfill this need. So the reason why the picture from number five is wrong is because this is just one way to produce. But we also need to understand that here, because it is iterative, we’re building with this idea of generating some value, to learn more, but we’re also taking in consideration that we need to try some stuff. I mean the scooter, it may be great, but it’s not helping us with our vision, as well as the bike. So we build the bike, we learn from the bike as much as possible, and then we move on to the next thing. And this can still be valuable, right? There are a lot of successful companies that work like this, but it’s not really what we want to discuss here today because we would like to discuss the combination.

So number eight, iterative and incremental, what is this all about? We’re doing all these steps, and we still haven’t talked about it. If we take the metaphor before, if we take the metaphor of the car, we can say that iterative and incremental development together, is kind of the best of the two worlds. So we still start with the end in mind, we still have a clear vision, and we try to deliver that as soon as possible. So in this case we see the main difference is that we make the engine our core. Or if we talk about product development, we may even think of it as the main feature. That’s the implementation way to solve the problem. So we need to have a robust engine, and we need to cover our user, otherwise they’re going to get wet when they travel with their family and it’s raining. So we build that, and then we increment on top. And yes, there are some stuff that we’re going to “waste,” we’re going to trash it, that’s why re-factoring, not just for coding but for UX is important. But the more we learn, the more we can work on this idea and make it better to fulfill our user needs. And if we want to look at the metaphor of the Mona Lisa again, we can see that we still start with this vision. So we have a sort of first implementation of more or less everything. We have kind of a hint of the things that we want to do, and then we build, sometimes a part at a time, and sometimes we just go a level deeper on another part until we have the full picture—until our vision is fulfilled. And what is really critical to make this process work is to keep it short. We need to keep our iteration short, in terms of time, in terms of work, and also in terms of goals. We need to have a clear idea of what we’re going to achieve, and we need to be okay with the idea that if for some reason we’re going to stop working on it, while we still won’t fulfill our full promise, we’re still getting something. So everything that we have in that moment is all learning. And it’s not shown in those examples, but what is really good about this process is that by keeping these iterations short and having a clear vision in mind, we’re still able to do variations—to seek new ideas and try new things. So maybe if we have another team working in parallel, we may try a version with the Mona Lisa wearing a red dress. How does it feel? Maybe we can try a blond Mona Lisa? Does it help us to fulfill our goal better? And what is the one that really fills the need? We can kind of go into this process of variation, selection, and suitability, so that only the strongest iteration survives and goes to the next step and gets shipped to the whole population. And that’s kind of great. It’s interesting because before we get feedback from the real user by using the real product, the more we can grow and learn.

The next step is about starting small. It doesn’t mean that you can’t think big. Again it’s about this idea of vision. The infamous picture from number five, so the example of the scooter versus the car, all comes from the consulting company that helped Spotify to be the music streaming leading company that it is today. And what is interesting is that even if the first implementation, the first testable product, the first product they were able to give, not even to the whole public but just to their friends, was really simple and kind of to the point, they had that vision. They knew where we wanted to go, they knew what the main goal was, what the promise was. And the good thing is that even with this implementation, it was really slow—the latency between when you selected a song and the song was playing was not as expected, they were still able to communicate that vision. So they started small, but by thinking big, they’re now able to be big.

And I understand that it can be harder with projects because projects are founded on a case-by-case basis and they’re evaluated by being shipped or ended on time and on budget. And projects are made by a group of people that are being moved from different teams. So you get people from a pool of talent, and you just change them. And the main goal of the project team is to build or enhance the product and then move on, move to the next thing. So it’s kind of hard to retain this vision, to retain this idea of what we’re building and why we’re building it if you always have to shuffle between projects. But there are solutions to that. We can have a great product manager that embraces the product vision. We can have a lot of cross-communication in the company. So let’s say in our case, talking about designers, you have a great way to communicate what the vision of all the different product lines are so that when one of us gets informed or gets moved with a specific goal—so maybe to just enhance part of the product or to just build a new feature for that specific product—we’re still able to share this understanding.

And number 11 is just don’t give up. I know that sometimes all of these things can be confusing, and our natural reaction as human beings is to be like, “I don’t want to do it, I just want to do it the way that I know because I know it works, and yes, maybe it’s not perfect, but at least it’s successful, and I can deliver.” Seek collaboration with others, seek collaboration with your team members, and seek new ways of working because it’s just by evolving that we’re able to understand what the best way of working together is and the way to, in the end, give value to our end user.

Thank you.

Mozilla GFXWebRender newsletter #45

Hi there! I first published this newsletter episode on May 21st and hitting the publish button at the same time as Jessie who wrote an excellent announcement post about WebRender on the stable channel. We decided to unpublish the newsletter for a couple of days to avoid shadowing the other post.

WebRender is a GPU based 2D rendering engine for web written in Rust, currently powering Mozilla’s research web browser servo and on its way to becoming Firefox‘s rendering engine.

🎉 WebRender enabled by default for a subset of users on stable 🎉

Firefox users on the stable channel are starting to use WebRender without opting into it manually.
This is a huge milestone for everyone involved! The initial target configuration is Windows 10 with nvidia desktop GPUs and recent enough drivers. A very specific and small set of users for sure, and this is so that we can progressively roll out this massive change to Firefox’s graphics engine and appropriately react to the bugs that went unnoticed during all these months of testing and polish (and I am sure there will be). On the nightly channel, we’ve already started enabling WebRender by default on some AMD and Intel configurations on Windows and Linux.

Congratulations and big thanks to everyone who helped pushing WebRender forward, mozilla staff and volunteers alike. In particular, I would like to highlight the tremendous amount help provided by volunteer contributors Darkspirit and Alice0775 White in filing, reproducing and triaging bugs.

Bug triage is an often underapreciated, yet absolutely vital part of the process of making Firefox. Without it developers would not know about important bugs that need fixing. It is crucial to our ability to see and react to problems in the wild and impacts priorities and other decision making. Bug Triage is time consuming and requires a lot of knowledge about the project. So once again, many thanks to Alice0775 White, Darkspirit and many other volunteers who’s help and impact on the project is really appreciated.

What’s new in WebRender

  • Glenn landed a number of changes towards generating separate batches per dirty region. The goal is to improve the performance of incremental updates.
  • Glenn fixed external scroll offsets for perspective elements.
  • Kvark fixed a backfrace-visibility issue.
  • Kvark fixed a texture cache reallocation crash.
  • Kvark fixed a transform flattening bug.
  • Kvark added support for using the KHR_blend_equation_advanced GL extension for mix-blend modes.
  • Kats added support for WebRender’s builtin debugging and profiling features on Android.
  • Doug fixed a number of document splitting bugs.
  • Nical finished turning the render task tree into a more powerful render task graph, and integrated the debug visualization into frame captures.
  • On top of this Nical started implementing render graph optimizations for items with many shadows.
  • Nical increased the amount of blob tiles that are rendered asynchronously.
  • Gankro landed the refactoring to how we represent webrender display items, reducing the size of lots of items, eliminating lots of meaningless states, and making it easier to read webrender captures.
  • Gankro got cbindgen to work with rust 2018 extern crate idioms, unlocking the ability for us to bump webrender and other gecko crates to Rust 2018.
  • Andrew improved pixel snapping.
  • Andrew fixed a crash caused by primitives with empty clips in some situations.
  • Jamie is improving glyph zooming on Android.
  • Jamie fixed a border rendering bug.
  • Jeff fixed a number of bugs with “clipped drawtargets”, a way to better represent the work for tiled blob images and deduplicate work.
  • Jeff and Nical reduced memory allocation overhead in during blob image rasterization.
  • Sotaro landed a lot of improvements to the texture sharing code.
  • Sotaro enabled the shader cache on android.
  • Lee reduced lock contention when rendering text on Windows.
  • Lee improved dual-source blending.
  • Miko landed many improvements to displaylist building performance.

Enabling WebRender manually

In about:config, enable the pref gfx.webrender.all and restart the browser.

Reporting bugs

The best place to report bugs related to WebRender in Firefox is the Graphics :: WebRender component in bugzilla.

Note that it is possible to log in with a github account.

Using WebRender in a Rust project

WebRender is available as a standalone crate on crates.io (documentation)

Mozilla Localization (L10N)L10n report: May edition

Please note some of the information provided in this report may be subject to change as we are sometimes sharing information about projects that are still in early stages and are not final yet.

Welcome!

New localizers

Are you a locale leader and want us to include new members in our upcoming reports? Contact us!

New community/locales added

  • Bashkirs (ba), a Turkic language mostly spoken in Russia

New content and projects

What’s new or coming up in Firefox desktop

Firefox 68 has officially entered Beta. The deadline to ship localization updates into this version is June 25. It’s important to remember that 68 is going to be an ESR version too: if your localization is incomplete on Jun 26, or contains errors, it won’t be possible to fix them later on for ESR.

A lot of content has landed in Firefox 68 towards the end of the cycle. In particular, make sure to test the new stub installer in the coming weeks, and the redesigned about:welcome experience. Detailed instructions are available in this thread on dev-l10n. You should also check out this post on how to localize the new “Join Firefox” message.

Partially related to Firefox Desktop: Facebook Container is quickly approaching version 2.0, adding several informative panels to the initial bare UI.

What’s new or coming up in mobile

As promised, more new and exciting things are happening in mobile land since our last report.

In fact, we have recently enabled two new projects in Pontoon, since we are opening up localization of a new password management product for both Android and iOS: Lockwise for Android (strings are located inside the locale folders, with a path starting by mozilla-mobile/lockwise-android/) and Lockwise for iOS – both formerly known as “Lockbox”. Ideal deadline for localizing and testing these projects is May 27th. As for previously enabled mobile projects, we are only exposing these strings to a subset of locales for now. We’ll add more locales as we get a handle on this first batch.

For Fenix and android-components strings, the current deadline for localizing and testing is still June 13th.

What’s new or coming up in web projects

Version 2 of the Firefox Monitor website is launching in the coming days. It’s a complete redesign, that will allow users to sign up with their Firefox Account, and monitor multiple emails easily.

Firefox Accounts: many strings were added in the recent feature updates. Please check Pontoon for the deadline. There might be more strings to be added before the weekend. The team will push codes more regularly to include as much localized content as possible on production before the launch of the new feature.

Mozilla.org added and updated four files in the past week: firefox/accounts-2019.lang, firefox/new/trailhead.lang, firefox/whatsnew_67.0.5.lang, and mozorg/newsletters.lang. Follow the deadline and prioritize against other requests.

Events

  • The Thai community meetup took place in Bangkok on 18-19 of May. This was the first localization meetup of the year led by the l10n-drivers. Community manager Vee summarized well through this blog.
  • Want to showcase an event coming up that your community is participating in? Reach out to any l10n-driver and we’ll include that (see links to emails at the bottom of this report)

Friends of the Lion

Image by Elio Qoshi

Know someone in your l10n community who’s been doing a great job and should appear here? Contact on of the l10n-drivers and we’ll make sure they get a shout-out (see list at the bottom)!

Useful Links

Questions? Want to get involved?

Did you enjoy reading this report? Let us know how we can improve by reaching out to any one of the l10n-drivers listed above.

The Rust Programming Language BlogAnnouncing Rust 1.35.0

The Rust team is happy to announce a new version of Rust, 1.35.0. Rust is a programming language that is empowering everyone to build reliable and efficient software.

If you have a previous version of Rust installed via rustup, getting Rust 1.35.0 is as easy as:

$ rustup update stable

If you don't have it already, you can get rustup from the appropriate page on our website, and check out the detailed release notes for 1.35.0 on GitHub.

What's in 1.35.0 stable

The highlight of this release is the implementation of the FnOnce, FnMut, and Fn closure traits for Box<dyn FnOnce>, Box<dyn FnMut>, and Box<dyn Fn> respectively. Additionally, closures may now be coerced to unsafe function pointers. The dbg! macro introduced in Rust 1.32.0 can now also be called without arguments. Moreover, there were a number of standard library stabilizations. Read on for a few highlights, or see the detailed release notes for additional information.

Fn* closure traits implemented for Box<dyn Fn*>

In Rust 1.35.0, the FnOnce, FnMut, and the Fn traits are now implemented for Box<dyn FnOnce>, Box<dyn FnMut>, and Box<dyn Fn> respectively.

Previously, if you wanted to call the function stored in a boxed closure, you had to use FnBox. This was because instances of Box<dyn FnOnce> and friends did not implement the respective Fn* traits. This also meant that it was not possible to pass boxed functions to code expecting an implementor of a Fn trait, and you had to create temporary closures to pass them down.

This was ultimately due to a limitation in the compiler's ability to reason about such implementations, which has since been fixed with the introduction of unsized locals.

With this release, you can now use boxed functions in places that expect items implementing a function trait.

The following code now works:

fn foo(x: Box<dyn Fn(u8) -> u8>) -> Vec<u8> {
    vec![1, 2, 3, 4].into_iter().map(x).collect()
}

Furthermore, you can now directly call Box<dyn FnOnce> objects:

fn foo(x: Box<dyn FnOnce()>) {
    x()
}

Coercing closures to unsafe fn pointers

Since Rust 1.19.0, it has been possible to coerce closures that do not capture from their environment into function pointers. For example, you may write:

fn twice(x: u8, f: fn(u8) -> u8) -> u8 {
    f(f(x))
}

fn main() {
    assert_eq!(42, twice(0, |x| x + 21));
}

This has however not extended to unsafe function pointers. With this release of Rust, you may now do so. For example:

/// The safety invariants are those of the `unsafe fn` pointer passed.
unsafe fn call_unsafe_fn_ptr(f: unsafe fn()) {
    f()
}

fn main() {
    // SAFETY: There are no invariants.
    // The closure is statically prevented from doing unsafe things.
    unsafe {
        call_unsafe_fn_ptr(|| {
            dbg!();
        });
    }
}

Calling dbg!() with no argument

For the benefit of all the occasional and frequent "print debuggers" out there, Rust 1.32.0 saw the release of the dbg! macro. To recap, the macro allows you to quickly inspect the value of some expression with context. For example, when running:

fn main() {
    let mut x = 0;

    if dbg!(x == 1) {
        x += 1;
    }

    dbg!(x);
}

...you would see:

[src/main.rs:4] x == 1 = false
[src/main.rs:8] x = 0

As seen in the previous section, where the higher order function call_unsafe_fn_ptr is called, you may now also call dbg! without passing any arguments. This is useful when tracing what branches your application takes. For example, with:

fn main() {
    let condition = true;

    if condition {
        dbg!();
    }
}

...you would see:

[src/main.rs:5]

Library stabilizations

In 1.35.0, a number of APIs have become stable.

In addition, some implementations were added and other changes occured as well. See the detailed release notes for more details.

Copy the sign of a floating point number onto another

With this release, new methods copysign have been added to the floating point primitive types f32 and f64:

As the name suggests, you can use these to copy the sign of one number onto another. For example:

fn main() {
    assert_eq!(3.5_f32.copysign(-0.42), -3.5);
}
Check whether a Range contains a value

Rust 1.35.0 contains a few freshly minted methods on the Range types:

With these, you can easily check whether a given value exists in a range. For example, you may write:

fn main() {
    if (0..=10).contains(&5) {
        println!("Five is included in zero to ten.");
    }
}
Map and split a borrowed RefCell value in two

With Rust 1.35.0, you can now map and split the borrowed value of a RefCell into multiple borrows for different components of the borrowed data:

Replace the value of a RefCell through a closure

This release introduces a convenience method replace_with on RefCell:

With it, you can more ergonomically map and replace the current value of the cell and get back the old value as a result.

Hash a pointer or reference by address, not value

In this release, we have introduced:

This function takes a raw pointer and hashes it. Using ptr::hash, you can avoid hashing the pointed-to value of a reference and instead hash the address.

Copy the contents of an Option<&T>

From the very beginning with Rust 1.0.0, the methods Option::cloned for Option<&T> and Option<&mut T> have allowed you to clone the contents in case of Some(_). However, cloning can sometimes be an expensive operation and the methods opt.cloned() provided no hints to that effect.

With this release of Rust, we introduced:

The functionality of opt.copied() is the same as for opt.cloned(). However, calling the method requires that T: Copy. Using this method, you can make sure that code stops compiling should T no longer implements Copy.

Changes in Clippy

In this release of Rust, Clippy (a collection of lints to catch common mistakes and improve your Rust code) added a new lint drop_bounds. This lint triggers when you add a bound T: Drop to a generic function. For example:

fn foo<T: Drop>(x: T) {}

Having a bound T: Drop is almost always a mistake as it excludes types, such as u8, which have trivial drop-glues. Moreover, T: Drop does not account for types like String not having interesting destructor behavior directly but rather as a result of embedding types, such as Vec<u8>, that do.

In addition to drop_bounds, this release of Clippy split the lintredundant_closure into redundant_closure and redundant_closure_for_method_calls.

See the detailed release notes for Clippy for more details.

Changes in Cargo

See the detailed release notes for Cargo for more details.

Contributors to 1.35.0

Many people came together to create Rust 1.35.0. We couldn't have done it without all of you. Thanks!