Daniel Stenbergcurl ootw: –ftp-skip-pasv-ip

(Other command line options of the week.)

--ftp-skip-pasv-ip has no short option and it was added to curl in 7.14.2.

Crash course in FTP

Remember how FTP is this special protocol for which we create two connections? One for the “control” where we send commands and read responses and then a second one for the actual data transfer.

When setting up the second connection, there are two ways to do it: the active way and the passive way. The wording there is basically in the eyes of the FTP server: should the server be active or passive in the creation and that’s the key. The traditional underlying FTP commands to do this is either PORT or PASV.

Due to the prevalence of firewalls and other network “complications” these days, the passive style is dominant for FTP. That’s when the client asks the server to listen on a new port (by issuing the PASV command) and then the client connects to the server with a second connection.

The PASV response

When a server responds to a PASV command that the client sends to it, it sends back an IPv4 address and a port number for the client to connect to – in a rather arcane way that looks like this:

227 Entering Passive Mode (192,168,0,1,156,64)

This says the server listens to the IPv4 address 192.168.0.1 on port 40000 (== 156 x 256 + 64).

However, sometimes the server itself isn’t perfectly aware of what IP address it actually is accessible as “from the outside”. Maybe there’s a NAT involved somewhere, maybe there are even more than one NAT between the client and the server.

We know better

For the cases when the server responds with a crazy address, curl can be told to ignore the address in the response and instead assume that the IP address used for the control connection will in fact work for the data connection as well – this is generally true and has actually become even more certain over time as FTP servers these days typically never return a different IP address for PASV.

Enter the “we know better than you” option --ftp-skip-pasv-ip.

What about IPv6 you might ask

The PASV command, as explained above, is explicitly only working with IPv4 as it talks about numerical IPv4 addresses. FTP was actually first described in the early 1970s, quite a lot time before IPv6 was born.

When FTP got support for IPv6, another command was introduced as a PASV replacement.: the EPSV command. If you run curl with -v (verbose mode) when doing FTP transfers, you will see that curl does indeed first try to use EPSV before it eventually falls back and tries PASV if the previous command doesn’t work.

The response to the EPSV command doesn’t even include an IP address but then it always assumes the same address as the control connection and it only returns back a TCP port number.

Example

Download a file from that server giving you a crazy PASV response:

curl --ftp-skip-pasv-ip ftp://example.com/file.txt

Related options

Change to active FTP mode with --ftp-port, switch off EPSV attempts with --disable-epsv.

Hacks.Mozilla.OrgNew in Firefox 77: DevTool improvements and web platform updates

A new stable Firefox version is rolling out. Version 77 comes with a few new features for web developers.

This blog post provides merely a set of highlights; for all the details, check out the following:

Developer tools improvements

Let’s start by reviewing the most interesting Developer Tools improvements and additions for 77. If you like to see more of the work in progress to give feedback, get Firefox DevEdition for early access.

Faster, leaner JavaScript debugging

Large web apps can provide a challenge for DevTools as bundling, live reloading, and dependencies need to be handled fast and correctly. With 77, Firefox’s Debugger learned a few more tricks, so you can focus on debugging.

After we improved debugging performance over many releases, we did run out of actionable, high-impact bugs. So to find the last remaining bottlenecks, we have been actively reaching out to our community. Thanks to many detailed reports we received, we were able to land performance improvements that not only speed up pausing and stepping but also cut down on memory usage over time.

JavaScript & CSS Source Maps that just work

Source maps were part of this outreach and saw their own share of performance boosts. Some cases of inline source maps improved 10x in load time. More importantly though, we improved reliability for many more source map configurations. We were able to tweak the fallbacks for parsing and mapping, thanks to your reports about specific cases of slightly-incorrect generated source maps. Overall, you should now see projects that just work, that previously failed to load your original CSS and JavaScript/TypeScript/etc code.

Step JavaScript in the selected stack frame

Stepping is a big part of debugging but not intuitive. You can easily lose your way and overstep when moving in and out of functions, and between libraries and your own code.

The debugger will now respect the currently selected stack when stepping. This is useful when you’ve stepped into a function call or paused in a library method further down in the stack. Just select the right function in the Call Stack to jump to its currently paused line and continue stepping from there.

Navigating the call stack and continuing stepping further in that function

We hope that this makes stepping through code execution more intuitive and less likely for you to miss an important line.

Overflow settings for Network and Debugger

To make for a leaner toolbar, Network and Debugger follow Console’s example in combining existing and new checkboxes into a new settings menu. This puts powerful options like “Disable JavaScript” right at your fingertips and gives room for more powerful options in the future.

Overflow settings menus in both Network and Debugger toolbar.

Pause on property read & write

Understanding state changes is a problem that is often investigated by console logging or debugging. Watchpoints, which landed in Firefox 72, can pause execution while a script reads a property or writes it. Right-click a property in the Scopes panel when paused to attach them.

Right-click on object properties in Debugger's Scopes to break on get/set

Contributor Janelle deMent made watchpoints easier to use with a new option that combines get/set, so any script reference will trigger a pause.

Improved Network data preview

Step by step over each release, the Network details panels have been rearchitected. The old interface had event handling bugs that made selecting and copying text too flaky. While we were at it, we also improved performance for larger data entries.

This is part of a larger interface cleanup in the Network panel, which we have been surveying our community about via @FirefoxDevTools Twitter and Mozilla’s Matrix community. Join us there to have your voice heard. More parts of the Network-panel sidebar redesign are also available in Firefox DevEdition for early access.

Web platform updates

Firefox 77 supports a couple of new web platform features.

String#replaceAll

Firefox 67 introduced String#matchAll, a more convenient way to iterate over regex result matches. In Firefox 77 we’re adding more comfort: String#replaceAll helps with replacing all occurrences of a string – an operation that’s probably one of those things you have searched for a thousand times in the past already (thanks StackOverflow for being so helpful!).

Previously, when trying to replace all cats with dogs, you had to use a global regular expression

.replace(/cats/g, 'dogs');

Or, you could use split and join:

.split('cats').join('dogs');

Now, thanks to String#replaceAll, this becomes much more readable:

.replaceAll('cats', 'dogs');

IndexedDB cursor requests

Firefox 77 exposes the request that an IDBCursor originated from as an attribute on that cursor. This is a nice improvement that makes it easier to write things like wrapper functions that “upgrade” database features. Previously, to do such an upgrade on a cursor you’d have to pass in the cursor object and the request object that it originated from, as the former is reliant on the latter. With this change, you now only need to pass in the cursor object, as the request is available on the cursor.

Extensions in Firefox 77: Fewer permission requests and more

Since Firefox 57, users see the permissions an extension wants to access during installation or when any new permissions are added during an update. The frequency of these prompts can be overwhelming, and failure to accept a new permission request during an extension’s update can leave users stranded on an old version. We’re making it easier for extension developers to avoid triggering as many prompts by making more permissions available as optional permissions. Optional permissions don’t trigger a permission request upon installation or when they are added to an extension update, and can also be requested at runtime so users see what permissions are being requested in context.

Visit the Add-ons Blog to see more updates for extensions in Firefox 77!

Summary

These are the highligts of Firefox 77! Check out the new features and have fun playing! As always, feel free to give feedback and ask questions in the comments.

The post New in Firefox 77: DevTool improvements and web platform updates appeared first on Mozilla Hacks - the Web developer blog.

The Mozilla BlogPocket provides fascinating reads from trusted sources in the UK with newest Firefox

It’s a stressful and strange time. Reading the news today can feel overwhelming, repetitive, and draining. We all feel it. We crave new inputs and healthy diversions—stories that can fuel our minds, spark fresh ideas, and leave us feeling recharged, informed, and inspired.

Connecting people with such stories is what we do at Pocket. We surface and recommend exceptional stories from across the web to nearly 40 million Firefox users in the U.S., Canada, and Germany each month. More than 4 million subscribers to our Pocket Hits newsletters (available in English and in German) see our curated recommendations each day in their inboxes.

Today we’re pleased to announce the launch of Pocket’s article recommendations for Firefox users in the United Kingdom. The expansion into the UK was made seamless thanks to our successes with English-language recommendations in the U.S. and Canada.

What does this mean for Firefox users in the UK? Open a new tab every day and see a curated selection of recommended stories from Pocket. People will see thought-provoking essays, hidden gems, and fascinating deep-dives from UK-based publishers both large and small — and other trusted global sources from across the web.

Open a new tab to see a curated selection of recommended stories

Where do these recommendations come from? Pocket readers. Pocket has a diverse, well-read community of users who help us surface some of the best stories on the web. Using our flagship Pocket app and save button (built right into Firefox), our users save millions of articles each day. The data from our most saved, opened, and read articles is  aggregated; our curators then sift through and recommend the very best of these stories with the wider Firefox and Pocket communities.

The result is a unique alternative to the vast array of content feeds out there today. Instead of breaking news, users will see stories that dig deep into a subject, offer a new perspective, and come from outlets that might be outside their normal reading channels. They’ll find engrossing science features, moving first-person narratives, and entertaining cooking and career how-tos. They’ll discover deeply reported business features, informative DIY guides, and eye-opening history pieces. Most of all, they’ll find stories worthy of their time and attention, curated specifically for Firefox users in the United Kingdom. Publishers, too, will benefit from a new stream of readers to their high-quality content.

Pocket delivers these recommendations with the same dedication to privacy that people have come to expect from Firefox and Mozilla. Recommendations are drawn from aggregate data and neither Mozilla nor Pocket receives Firefox browsing history or data, or is able to view the saved items of an individual Pocket account. A Firefox user’s browsing data never leaves their own computer or device. .

We welcome new Pocket readers in the UK — alongside our readers in the U.S., Canada, and Germany — and hope you find your new tab is a breath of fresh air and a stimulating place to refuel and recharge at a time when you may be needing it most.

Download Firefox to get thought-provoking stories from around the web with every new tab. Be sure to enable the recommendations to begin reading.

The post Pocket provides fascinating reads from trusted sources in the UK with newest Firefox appeared first on The Mozilla Blog.

Christopher ArnoldMoney, friction and momentum on the web

Back when I first moved to Silicon Valley in 1998, I tried to understand how capital markets here made the valley such a unique place for inventors and entrepreneurs.  Corporate stocks, real estate, international currency and commodities markets were concepts I was well familiar with from my time working at a financial news service in the nation's capital in the mid 1990's.  However, crowdfunding and angel investing were new concepts to me 20 years ago.  The emergence of crowdfunding platforms (Kiva, Indiegogo, Kickstarter, Appbackr for instance) were more to the advantage of the funding recipient than the balanced two-sided exchanges of the commercial financial system.

When trying to grasp the way angel investors think about entrepreneurship, my friend Willy, a serial entrepreneur and investor, said: “If you want to see something succeed, throw money at it!”  The idea behind the "angel" is that they are the riskiest of risk-capital.  Angel investors seldom get payoffs from the companies they sponsor.  They are the lenders of first-resort because they tend to be more generous, more flexible and more forgiving than other kinds of lenders.  Angel investors contribute to the cause in spite of the the uncertain outcome of the specific initiative they're funding. 

During the Augmented World Expo in May, I attended a conference session called "Web Monetization and Social Signaling," hosted by Anselm Hook, a researcher at the web development non-profit Mozilla, where I also work.  He made an interesting assertion during his presentation, "Money appears to be a form of communication."  His study was observing platform-integrated social signals (such as up-voting, re-tweeting and applauding with hand-clapping emojis) to draw attention to content users had discovered on the web, in this case the Firefox Reality VR web browser.  There are multiple motivations and benefits for this kind of "social signaling."  It serves as a bookmarking method for the user, it signals to friends who might also like the content and it gives reinforcement to the content/comment provider.  However, he found in his research that participants actually reacted more strongly when they believed their action contributed financial benefit directly to the other participant.  The interactions we need to enable as web developers is a new kind of gesture akin to the act of tipping with cash in offline society.

Early "digital wallet" platforms such as Patreon, Flattr and Brave have demonstrated the concept of a crowdsourced contributions model as an alternative to pay-walls and banner-ad sponsorships.  Anselm is working with crypto-currency enabler Coil to try to apply this concept to user exchanges on the broader web.  He envisions a future where users could casually exchange funds in a virtual, web-based or real-world "augmented reality" transaction without needing to exchange credit card or personal account data.  This may sound mundane, because the use-case and need is obvious, because we're used to doing it with cash every day.  The question it begs is, why can't the web do this?#!  Why do I need to exchange credit cards (sensitive data) or email (not sensitive but not public) if I just want to send credit's or tips to somebody?  Ideally, there could be a standard for transaction handshakes that don't require users to know each other directly.  However, significant amounts of trust would need to be established in a cross-app cross-browser web standard to the point that users would be confident enough to make a small micro-payments to incentivize and reward web artists and developers to further the pursuits of their trade with financial benefit.

There was an early success in this kind of micropayments model when Anshe Chung became the world's first self-made millionaire by selling virtual goods to Second Life enthusiasts.  The LindenLabs virtual platform had the ability for users to pay money to other peer users inside the virtual environment.  With a bit more development collaboration, this kind of model may be beneficial to others outside of specific game environments.  


Anselm's speech at AWE was to introduce the concept of a "tip-jar," something we're familiar with from colloquial offline life, for the nascent developer ecosystem of virtual and augmented reality web developers.  For most people who are used to high-end software being sold as apps in a marketplace like iTunes or Android Play Store, the idea that we would pay web pages may seem peculiar.  But it's not too far a leap from how we generally spend our money in society.  Leaving tips with cash is common practice for Americans.  Even when service fees are not required, Americans tend to tip generously.  Lonely Planet dedicates sections of its guidebooks to concepts of money and I've typically seen that Americans have a looser idea of tip amount than other countries.

Anselm and the team managing the "Grant for the Web" hope to bring this kind of peer-to-peer mechanism to the broader web around us by utilizing Coil's grant of $100 Million in crypto-currency toward achieving this vision. 

If you're interested in learning more about web-monetization initiative from Coil and Mozilla please visit: https://www.grantfortheweb.org/








The Mozilla BlogWe’ve Got Work to Do

The promise of America is “liberty and justice for all.” We must do more to live up to this promise. The events of last week once again shine a spotlight on how much systemic change is still required. These events  — the deaths at the hands of police and civilians, the accusations that are outright lies — are not new, and are not isolated. African Americans continue to pay an obscene and unacceptable price for our nation’s failure to rectify our history of racial discrimination and violence. As a result, our communities and our nation are harmed and diminished.

Change is required. That change involves all of us. It’s not immediately clear all the actions an organization like Mozilla should take, but it’s clear action is required. As a starting point, we will use our products to highlight black and other under-represented voices in this unfolding dialog. And we’re looking hard at other actions, across the range of our activities and assets.

Closer to home we’ve reiterated our support for our black colleagues. We recognize the disproportionate impact of these events, as well as the disproportionate effect of COVID-19 on communities of color. We recognize that continued diligence could lead others to think it is “business as usual.” We know that it is not.

And this has left many of us once again, questioning how to meaningfully make our world better. As our starting point, Mozilla is committed to continuing to support our black employees, expanding our own diversity, and using our products to build a better world.

The post We’ve Got Work to Do appeared first on The Mozilla Blog.

About:CommunityFirefox 77 new contributors

With the release of Firefox 77, we are pleased to welcome the 38 developers who contributed their first code change to Firefox in this release, 36 of whom were brand new volunteers! Please join us in thanking each of these diligent and enthusiastic individuals, and take a look at their contributions:

Daniel Stenbergon-demand buffer alloc in libcurl

Okay, so I’ll delve a bit deeper into the libcurl internals than usual here. Beware of low-level talk!

There’s a never-ending stream of things to polish and improve in a software project and curl is no exception. Let me tell you what I fell over and worked on the other day.

Smaller than what holds Linux

We have users who are running curl on tiny devices, often put under the label of Internet of Things, IoT. These small systems typically have maybe a megabyte or two of ram and flash and are often too small to even run Linux. They typically run one of the many different RTOS flavors instead.

It is with these users in mind I’ve worked on the tiny-curl effort. To make curl a viable alternative even there. And believe me, the world of RTOSes and IoT is literally filled with really low quality and half-baked HTTP client implementations. Often certainly very small but equally as often with really horrible shortcuts or protocol misunderstandings in them.

Going with curl in your IoT device means going with decades of experience and reliability. But for libcurl to be an option for many IoT devices, a libcurl build has to be able to get really small. Both the footprint on storage but also in the required amount of dynamic memory used while executing.

Being feature-packed and attractive for the high-end users and yet at the same time being able to get really small for the low-end is a challenge. And who doesn’t like a good challenge?

Reduce reduce reduce

I’ve set myself on a quest to make it possible to build libcurl smaller than before and to use less dynamic memory. The first tiny-curl releases were only the beginning and I already then aimed for a libcurl + TLS library within 100K storage size. I believe that goal was met, but I also think there’s more to gain.

I will make tiny-curl smaller and use less memory by making sure that when we disable parts of the library or disable specific features and protocols at build-time, they should no longer affect storage or dynamic memory sizes – as far as possible. Tiny-curl is a good step in this direction but the job isn’t done yet – there’s more “dead meat” to carve off.

One example is my current work (PR #5466) on making sure there’s much less proxy remainders left when libcurl is built without support for such. This makes it smaller on disk but also makes it use less dynamic memory.

To decrease the maximum amount of allocated memory for a typical transfer, and in fact for all kinds of transfers, we’ve just switched to a model with on-demand download buffer allocations (PR #5472). Previously, the download buffer for a transfer was allocated at the same time as the handle (in the curl_easy_init call) and kept allocated until the handle was cleaned up again (with curl_easy_cleanup). Now, we instead lazy-allocate it first when the transfer starts, and we free it again immediately when the transfer is over.

It has several benefits. For starters, the previous initial allocation would always first allocate the buffer using the default size, and the user could then set a smaller size that would realloc a new smaller buffer. That double allocation was of course unfortunate, especially on systems that really do want to avoid mallocs and want a minimum buffer size.

The “price” of handling many handles drastically went down, as only transfers that are actively in progress will actually have a receive buffer allocated.

A positive side-effect of this refactor, is that we could now also make sure the internal “closure handle” actually doesn’t use any buffer allocation at all now. That’s the “spare” handle we create internally to be able to associate certain connections with, when there’s no user-provided handles left but we need to for example close down an FTP connection as there’s a command/response procedure involved.

Downsides? It means a slight increase in number of allocations and frees of dynamic memory for doing new transfers. We do however deem this a sensible trade-off.

Numbers

I always hesitate to bring up numbers since it will vary so much depending on your particular setup, build, platform and more. But okay, with that said, let’s take a look at the numbers I could generate on my dev machine. A now rather dated x86-64 machine running Linux.

For measurement, I perform a standard single transfer getting a 8GB file from http://localhost, written to stderr:

curl -s http://localhost/8GB -o /dev/null

With all the memory calls instrumented, my script counts the number of memory alloc/realloc/free/etc calls made as well as the maximum total memory allocation used.

The curl tool itself sets the download buffer size to a “whopping” 100K buffer (as it actually makes a difference to users doing for example transfers from localhost or other really high bandwidth setups or when doing SFTP over high-latency links). libcurl is more conservative and defaults it to 16K.

This command line of course creates a single easy handle and makes a single HTTP transfer without any redirects.

Before the lazy-alloc change, this operation would peak at 168978 bytes allocated. As you can see, the 100K receive buffer is a significant share of the memory used.

After the alloc work, the exact same transfer instead ended up using 136188 bytes.

102,400 bytes is for the receive buffer, meaning we reduced the amount of “extra” allocated data from 66578 to 33807. By 49%

Even tinier tiny-curl: in a feature-stripped tiny-curl build that does HTTPS GET only with a mere 1K receive buffer, the total maximum amount of dynamically allocated memory is now below 25K.

Caveats

The numbers mentioned above only count allocations done by curl code. It does not include memory used by system calls or, when used, third party libraries.

Landed

The changes mentioned in this blog post have landed in the master branch and will ship in the next release: curl 7.71.0.

Cameron KaiserTenFourFox FPR23 available

TenFourFox Feature Parity Release 23 final is now available for testing (downloads, hashes, release notes). This blog post was composed in the new Blogger interface, which works fine but is slower, so I'm going back to the old one. Anyway, there's no difference from the beta except for outstanding security fixes and as usual, if all goes well, it will go live Monday evening Pacific time.

Asa Dotzler20 Years with Mozilla

Today marks 20 years I’ve been working full-time for Mozilla.

As the Mozilla organization evolved, I moved with it. I started with staff@mozilla.org at Netscape 20 years ago, moved to the Mozilla Foundation ~17 years ago, and the Mozilla Corporation ~15 years ago.

Thank you to Mitchell Baker for taking a chance on me. I’m eternally grateful for that opportunity.

Mozilla VR BlogWebXR Viewer 2.0 Released

WebXR Viewer 2.0 Released

We are happy to announce that version 2.0 of WebXR Viewer, released today, is the first web browser on iOS to implement the new WebXR Device API, enabling high-performance AR experiences on the web that don't share pictures of your private spaces with third party Javascript libraries and websites.  

It's been almost a year since the previous release (version 1.17) of our experimental WebXR platform for iOS, and over the past year we've been working on two major changes to the app:  (1) we updated the Javascript API to implement the official WebXR Device API specification, and (2) we ported our ARKit-based WebXR implementation from our minimal single-page web browser to the full-featured Firefox for iOS code-base.

WebXR Device API: Past, Present, and Future

The first goal this release is to update the browser's Javascript API for WebXR to support the official WebXR Device API, including an assortment of approved and proposed AR features. The original goal with the WebXR Viewer was to give us an iOS-based platform to experiment with AR features for WebXR, and we've written previous posts about experimenting with privacy and world structure, computer vision, and progressive and responsive WebXR design. We would like to continue those explorations in the context of the emerging standard.

We developed the API used in the first version of the WebXR Viewer more than 3 years ago (as a proposal for how WebXR might combine AR and VR; see the WebXR API proposal here, if you are interested), and then updated it a year ago to match the evolving standard. While very similar to the official API, this early version of the official API is not compatible with the final standard, in some substantial ways.  Now that WebXR is appearing in mainstream browsers, it's confusing to developers to have an old, incompatible API out in the world.  

Over the past year, we rebuilt the API to conform to the official spec, and either updated our old API features to match current proposals (e.g., anchors, hit testing, and DOM overlay), marked them more explicitly as non-standard (e.g., by adding a nonStandard_ prefix to the method names), or removed them from the new version (e.g., camera access). Most WebXR AR examples on the web now work with the WebXR Viewer, such as the "galaxy" example from the WebXR Samples repository shown in the banner above.

(The WebXR Viewer's Javascript API is entirely defined in the Javascript library in the webxr-ios-js repository linked above, and the examples are there as well; the library is loaded on demand from the github master branch when a page calls one of the WebXR API calls. You can build the API yourself, and change the URL in the iOS app settings to load your version instead of ours, if you want to experiment with changes to the API.  We'd be happy to receive PRs, and issues, at that github repository.)

WebXR Viewer 2.0 Released<figcaption>Standards-based version of our old "Peoples" demo (left); the Three.js WebXR AR Paint demo (center); Brandon Jones' XR Dinosaurs demo (right)</figcaption>

In the near future, we're interested in continuing to experiment with more advanced AR capabilities for WebXR, and seeing what kinds of experimentation developers do with those capabilities. Most AR use cases need to integrate virtual content with meaningful things in the world;  putting cute dinosaurs or superheros on flat surfaces in the world makes for fun demos that run anywhere, but genuinely useful consumer and business applications need to sense, track, and augment "people, places, and things" and have content that persists over time. Enhancing the Immersive Web with these abilities, especially in a "webby" manner that offers privacy and security to users, is a key area Mozilla will be working on next. We need to ensure that there is a standards-based solution that is secure and private, unlike the proprietary solutions currently in the market that are siloed to create new, closed markets controlled by single companies.

While purely vision-based AR applications (implemented inside web pages using direct access to camera video) are showing great engagement, failing to use the underlying platform technology limits their capabilities, as well as using so much CPU and GPU resources that they can only run for a few seconds to minutes before thermal throttling renders them unusable (or your battery dead). WebXR offers the possibility for the underlying vision-based sensing techniques to be implemented natively so they can take advantage of the underlying platform APIs (both to maximize performance and to minimize CPU, GPU, and battery use).  

It is too early to standardize some of these capabilities and implement them in a open, cross-platform way (e.g., persistent anchors), but others could be implemented now (e.g., the face and image tracking examples shown below). In the newly announced Firefox Reality for Hololens2, we're experimenting with exposing hand tracking into WebXR for input, a key sort of sensing that will be vital for head-worn-display-based AR (Oculus is also experimenting with exposing hand tracking into VR in the Oculus Browser on Quest). APIs like ARKit and Vuforia let you detect and track faces, images, and objects in the world, capabilities that we explored early on with the WebXR Viewer. We've kept versions of the APIs we developed in the current WebXR Viewer, and are keen to see these capabilities standardized in the future.

WebXR Viewer 2.0 Released<figcaption>Leveraging ARKit's face-tracking to augment the author with a pair of sunglasses (left); Using ARKit's image tracker to put a model of a Duck on a printed images of the Hubs homepage (right)</figcaption>

Integrating with a Full-featured Web Browser

The second change will be immediately noticeable: when you launch the app, you'll be greeted by the familiar Firefox for iOS interface, and be able to take advantage of many of the features of its namesake (tabs, history, private browsing, and using your Firefox account to sync between devices, to name a few).  While not all Firefox features work, such as send-to-device from Firefox, the experience of using the WebXR Viewer should be more enjoyable and productive.

WebXR Viewer 2.0 Released<figcaption>The familiar Firefox for iOS new page in the WebXR Viewer app (left); the WebXR Viewer samples page containing the examples from our Javascript API page (center); and the new "..." menu options for WebXR pages (right).</figcaption>

Our goal for moving this code to the Firefox code-base wasn't just to create a better browsing experience for the WebXR Viewer, though.  This is an experimental app, after all, aimed at developers hoping to explore web-based AR on iOS, and we don't plan on supporting it as a separate product over the long term.  But Apple hasn't shown any sign of implementing WebXR, and it's critically important for the success of the immersive web that an implementation exists on all major platforms. Toward this end, we moved this implementation into the Firefox for iOS code-base to see how this approach to implementing WebXR would behave inside Firefox, with an eye towards (possibly) integrating these features into Firefox for iOS in the future.  Would the WebXR implmentation work at all? (Yes.) Would it perform better or worse than in the old app? (Better, it turns out!)  What UI and usability issues would arise? (Plenty.)  While there is still plenty of UI work to do before moving this to a mainstream browser, we're quite happy with the performance;  WebXR demos run better in this version of the app than they did in the previous one, and the impact on non-WebXR web pages seems minimal.  

We'd love for you to download the new version of the app and try out your WebXR content on it. If you do, please let us know what your experience is.  

Jeff KlukasEncoding Usage History in Bit Patterns

Originally published as a cookbook on docs.telemetry.mozilla.org to instruct data users within Mozilla how to take advantage of the usage history stored in our BigQuery tables.

DAU windows in a bit pattern

Monthly active users (MAU) is a windowed metric that requires joining data per client across 28 days. Calculating this from individual pings or daily aggregations can be computationally expensive, which motivated creation of the clients_last_seen dataset for desktop Firefox and similar datasets for other applications.

A powerful feature of the clients_last_seen methodology is that it doesn’t record specific metrics like MAU and WAU directly, but rather each row stores a history of the discrete days on which a client was active in the past 28 days. We could calculate active users in a 10 day or 25 day window just as efficiently as a 7 day (WAU) or 28 day (MAU) window. But we can also define completely new metrics based on these usage histories, such as various retention definitions.

Marco ZeheWelcome to Marco's Accessibility Blog 2.0!

Yes, you read that right! This blog has just relaunched. It runs on a new platform. And it is a lot faster, and has a very slick look and feel to it. Read on to find out some more details.

Why the switch?

Well, after 13 years, I felt it was time for something new. Also, as I wrote recently, Mozilla now has a dedicated accessibility blog, so I feel that I am free to do other things with my blog now. As a sign of that, I wanted to migrate it to a new platform.

This is not to say the old platform, WordPress, is bad or anything like that. But for my needs, it has become much too heavy-weight in features, and also in the way how it feels when performing day to day tasks. 80% of features it offers are features I don't use. This pertains both to the blog system itself as well as its new block editor. But those features don't get out of the way easily, so over the months and actually last two to three years, I felt that I was moving mountains just to accomplish simple things. It has nothing to do with the steadily improving accessibility, either. That is, as I said, getting better all the time. It just feels heavy-weight to the touch and keyboard when using it.

So one day earlier this year, I read a post on my favorite publishing editor's web site, where they told the story how they migrated to the Ghost platform. I must admit I had never heard of Ghost before, but was curious, so I started poking around.

Discovering the JAMstack

As I did so, I quickly stumbled on the term JAMstack. Some of you may now ask: "Stumbled upon? What rock have you been living under these past 5 or 6 years?" Well, you know, I had heard of some of the software packages I am going to mention, but I didn't have the time, and more recently, energy, to actually dig into these technology stacks at all.

The truth is, I started asking myself this question as I became more familiar with Ghost itself, static site generators, and how this can all hang together. JAM stands for JavaScript, APIs and Markup, and describes the mental separation between how and where content is created, how it's being transferred, and then finally, output to the world.

In a nutshell - and this is just the way I understand things so far -, applications like WordPress or Drupal serve the content from a database every time someone visits a site or page. So every time an article on my blog was being brought up, database queries were made, HTML was put together, and then served to the recipient. This all happens in the same place.

Better efficiency

However, there are other ways to do that, aren't there? Articles usually don't change every day, so it is actually not necessary to regenerate the whole thing each time. Granted, there are caching options for these platforms, but  from past experience, I know that these weren't always that reliable, even when they came from the same vendor as the main platform.

JAMstack setups deal with this whole thing in a different way. The content is generated somewhere, by writers who feel comfortable with a certain platform. This can, for all intents and purposes, even be WordPress nowadays since it also offers a REST API. But it can also be Ghost. Or NetlifyCMS together with a static site generator. Once the content is done, like this blog post, it is being published to that platform.

What can happen then depends on the setup. Ghost has its own front-end, written in Ember, and can serve the content directly using one of the many templates available now. This is how my blog is set up right now. So this is not that much different from WordPress, only that Ghost is much more light-weight and faster, and built entirely, not just partially, on modern JS stacks.

However, it doesn't have to be that way. Through integrations, web hooks and by leveraging source code management systems like Github or Gitlab, every time my content updates, a machinery can be set in motion that publishes my posts to a static site generator or fast JavaScript application framework. That then serves the content statically, and thus much faster than a constant rebuild, whenever it is being called from a visitor.

Such static site generators are, for example, Hugo or Eleventy, which both serve static HTML pages to the audience with only minimal JavaScript. Or they can be application frameworks like Gatsby.js, which is a single page application serving the content blazing fast from a local build which is based off of the content created in the publishing platform. That way, the actual presentation is completely decoupled from the publishing workflow, and the developer who works on the front-end doesn't even have to know Ghost, WordPress, or what not, just the API, to get the content and present it, in a way they feel most comfortable with.

As I mentioned, my blog currently serves the content directly from Ghost. But if I feel like it, I might also set up a Gatsby mirror on another domain that will also be up to date whenever something is being published here. The steps to do that are not that difficult at all.

Were there alternatives?

One path I was researching as a possible alternative to Ghost was going with Hugo. To get started, I read this excellent migration report by Sara Soueidan, and did some more research. One show stopper was that I like to blog from an iPad nowadays, and there was not a very elegant way to integrate Ulysses with Hugo or a Github repository. Yes, there is a workflow (umm, Siri Shortcut) available that could do that with an iOS Github client named WorkingCopy, but this all felt too fragile and cumbersome. So in the end, because I want to concentrate on the writing most, I decided not to go that route. Nothing beats native publishing from an app to the CMS.

The same was true for Eleventy, which I looked at just because there is such a great diverse community behind it, including quite a number of people I know and highly respect. And as hinted above, none of these packages is out of my mind yet when it comes to tinkering, researching, and getting up to speed with modern web technologies. After all, these packages are all interoperating with one another in an open fashion. They are the modern versioon of what the web stands for, an open, collaborative, interoperable resource for everyone.

And let's be honest, there are enough silos out there. Yes, even when open source, a platform that powers over a third of the web sites out there can be considered its own silo.

What about accessibility?

Here's another piece of good news: All these communities, which are interconnected and exchanging knowledge and wisdom, also have members with accessibility in mind. Some are strong advocates, some more the background worker, but all have in common that accessibility is no stranger to them. Ghost itself welcomes reports and pull requests, some theme authors have mentions of accessibility in their goals and theme features. Projects like Gatsby and Eleventy have people with strong voices among their staff or supporters, and just by looking at the project web sites shows that.

As for this blog, before I officially launched, I submitted some fixes to the theme I wanted to use, as well as Ghost itself, which were all quickly accepted. I am using a copy of the theme with these fixes on this blog already.

So where are the comments?

Yes, those have indeed gone from this site. They proved to be more trouble than they were worth in the last few years. Most of them were spam, and hardly any other comments came through. A recent informal survey I conducted on Twitter also showed that two thirds of my readers actually don't care much for comments.

So I decided that I am not going to integrate any commenting system into my Ghost setup for now, even though it is certainly possible using some 3rd party providers. If I change my mind in the future again, there are certainly some options available.

Conclusion

I hope you'll enjoy this new chapter of the journey with me, and stay a loyal reader! This blog will, as previously hinted, in the future focus more on personal topics, research, and other related items. For a glimpse, well, reread this post. ;-)

In a future article, I will go into some of the Ghost-specific details I dealt with when migrating from my WordPress setup.

Let's do this!

Mozilla VR BlogScaling Virtual Events with Hubs and Hubs Cloud

Scaling Virtual Events with Hubs and Hubs Cloud

Virtual events are unique, and each one has varying needs for how many users can be present. In this blog post, we’ll talk about the different ways that you can consider concurrency as part of a virtual event, the current capabilities of Mozilla Hubs and Hubs Cloud for supporting users, and considerations for using Hubs as part of events of varying sizes. If you’ve considered using Hubs for a meetup or conference, or are just generally interested in how the platform works, read on!

Concurrency Planning for Virtual Events

When we think about traditional event planning, we have one major restriction that guides us: the physical amount of space that is available to us. When we take away the physical location as a restriction for our event by moving our event online, it can be hard to understand what limits might exist for a given platform.

With online collaboration software, there are many factors that come into play. Applications might have a per-event limit, a per-room limit, or a per-platform limit that can influence how capacity planning is done. Hubs has both ‘per-room’ and ‘per-platform’ user limits. These limits are dependent on whether you are creating a room on hubs.mozilla.com, or using Hubs Cloud. When considering the number of people who you might want to have participate in your event, it’s important to think about the distribution of those users and the content of the event that you’re planning. This relates back to physical event planning: while your venue may have an overall capacity in the thousands, you will also need to consider how many people can fit in different rooms.

When thinking about how to use Hubs or Hubs Cloud for an event, you can consider two different options -- one where you start from how many people you want to support, and how they will be split across rooms, and one where you start from the total event size and figure out how many rooms will be necessary. Below, we cover some of the considerations for room and system-wide capabilities for Hubs and Hubs Cloud.

Hubs Room Capacity

With Hubs, the question gets a bit more complicated, because you can control the room capacity and the “venue” capacity via Hubs Cloud. Hubs supports up to 50 users in an individual room. However, it is important to note that this is the server limit on the number of people who can be accommodated in a single room - it does not guarantee that everyone will be able to have a good experience. Generally speaking, users who are connecting with a mobile phone or standalone virtual reality headset (for example, something with an Qualcomm 835 chipset) will start to see performance drops before users on a gaming PC with hardwired internet will. While Hubs offers a great amount of flexibility in sharing all sorts of content from around the web, user-generated content can often bring with it a large amount of overhead to support sharing large files or streaming content. Oftentimes, these performance issues manifest in a degraded audio experience or frame rate drops.

With virtual events, the device that your attendees are connecting from will make a difference, as will their home network configurations. Factors that impact performance in Hubs include:

  • The number of people who are in a room
  • The amount of content that is in a room
  • The type of content that is in a room

As a result of these considerations, we set a default room capacity at about half of the total server capacity, because users will likely experience issues connecting to a room that has 50 avatars in it. The server limit is capped because each user that connects to a room opens up a channel to the server to send network data (specifically, voice data) and at higher number of users, the software running on the server has to do a lot of work to get that data processed and sent back out to the other clients in real-time. While increasing the size and number of servers that are available can help the system-wide concurrency, it will not increase individual room capacity beyond the 50 connection cap given that the underlying session description protocol (SDP) negotiations between the connected clients is a single-threaded process.

Scaling Virtual Events with Hubs and Hubs Cloud<figcaption>The Room Lobby Page shows a list of people and objects in the room, chat, and allows users to see and hear what is going on before they enter</figcaption>

Hubs also has the concept of a room ‘lobby’. While in the lobby, visitors can see what is happening in the room, hear what is being discussed, and send messages via chat, but they are not represented as an avatar in the space. While the lobby system in Hubs was initially designed to provide context to a user before they were embodied in a room, it is now possible to use the lobby as a lighter-weight viewing experience for larger events similar to what you might experience on a 2D streaming platform, such as Twitch. We recently made an experimental change that tested up to 90 clients watching from the lobby, with 10 people in the room. For events where a passive viewing experience is contextually appropriate, this approach can facilitate a larger group than the room itself can, because the lobby viewers are not sending data to the server, only receiving it, which has a reduced impact on room load.

Scaling Hubs Cloud

While room limits are one consideration for virtual events, the system-wide concurrency then becomes another question. Like physical venues, virtual platforms will have a cap on the total number of connected users that it can support. This is generally the result of the server capabilities and hardware that the backend of the application is running on. For Hubs Cloud, this is primarily dependent on the EC2 server size that is running your deployment, and if you are using a single server or multiple servers. A small, t3.micro server (the smallest one that can run Hubs Cloud) will be able to handle a smaller simultaneous user load than a c5.24xlarge. This is an important consideration when figuring out how large of a server instance to use for a Hubs Cloud deployment.

Scaling Virtual Events with Hubs and Hubs Cloud

The exact configuration for a large event running on Hubs Cloud will be dependent on the type of sessions that will be running, how many users will be in each Hubs room, and whether the users will participate as audience members from the lobby or be embodied in a space. We recently released an estimated breakdown of how different instance sizes on AWS deployments of Hubs Cloud translate to a total number of concurrent users (CCU).

Hubs Strategies for Events

Building out a strategy to incorporate Hubs into a virtual event that you’re holding will be unique to your individual event. With any event, we recommend that you familiarize yourself with the moderation tools and best practices, but we’ve offered a few sample configurations and strategies below based on what we’ve heard works well for different types of meetings and organizations.

For groups up to 25 users (e.g. small meetup or meeting, breakout sessions for a larger event) - a single room on hubs.mozilla.com will generally be sufficient. If all of your users are connecting via mobile phones or standalone headsets as avatars, you may want to experiment with splitting the groups across two or three rooms and linking them together.

For groups up to 50 users (e.g. a networking event and panel of speakers) - a single room on hubs.mozilla.com, where the speakers are represented as avatars and about half of the participants view from the lobby, or two rooms on hubs.mozilla.com, where one room is the panel room and one room is for viewers.

For events with speakers broadcasting to more than 50 users (e.g. conference keynote) -  you will likely need to set up a streaming service that will allow you to broadcast video into several rooms simultaneously, with a central location made available for attendees to discover one another. This could be a separate “lobby” room with links to the other viewing areas, or a simple web page that has links or the different rooms embedded. While it is possible to host events this way on hubs.mozilla.com, managing more than two rooms as part of a single event on the hosted Mozilla Hubs infrastructure can be difficult to coordinate and create a unified experience. Instead, for events that require more than two or three rooms, we recommend deploying a Hubs Cloud instance.

Scaling Virtual Events with Hubs and Hubs Cloud<figcaption>Watching a presentation from IEEE VR in Hubs</figcaption>

With Hubs Cloud, you have more granular control over the rooms and availability of your event, because instead of simply controlling the permissions and settings of an individual set of rooms, you are hosting your own version of hubs.mozilla.com - so you not only can set platform-wide permissions and configurations, you also have the ability to add your own URL, branding, accounts, avatars, scenes, and more.

The Future of Scaling and Concurrency with Hubs and Hubs Cloud

We’ve been impressed with the different ways that groups have configured Hubs to meet, even with the existing infrastructure. Hubs was originally built to more closely mirror platforms that have closed, private meeting rooms, but as more people have looked to virtual solutions to stay connected during times of physical distance, we’ve been looking at new ways that we can scale the platform to better support larger audiences. This means considering a few big questions:

  • What is the right design for gathering large groups of people virtually? In thinking about this question, there are technical and social considerations that come into play when considering how to best support larger communities. We can take the approach of trying to mimic our physical environment, and simply focus on increasing the raw number of avatars that can be present in a room, or we can take more experimental approaches to the unique affordances that technology presents in reshaping how we socialize and gather.
  • What are the trade-offs in our assumptions about the capabilities offered by virtual meeting platforms, and how do we preserve principles of privacy and safety in larger, potentially less-trusted groups? In our day-to-day lives, we find our actions heavily influenced by the context and community around us. As we look to software solutions to enable some of these use cases, it is important for us to think about how these safety and privacy structures continue to be core considerations for the platform.

Of course, there are also the underlying architectural questions about the ways that web technologies are evolving, too, which also influences how we’re able to explore and respond to our community of users as the product grows. We welcome discussions, questions, and contributions as we explore this space in our community Discord server, on GitHub, or via email, and look forward to continuing to grow the platform in different ways to best support the needs of our users!

Mozilla Addons BlogExtensions in Firefox 77

Firefox 77 is loaded with great improvements for the WebExtensions API. These additions to the API will help you provide a great experience for your users.

Optional Permissions

Since Firefox 57, users have been able to see what permissions an extension wants to access during the installation process.  The addition of any new permissions to the extension triggers another notification that users must accept during the extension’s next update.  If they don’t, they won’t receive the updated version.

These notifications were intended to provide transparency about what extensions can do and help users make informed decisions about whether they should complete the installation process. However, we’ve seen that users can feel overwhelmed by repeated prompts. Worse, failure to see and accept new permissions requests for updated versions can leave users stranded on older versions.

We’re addressing this with optional permissions.  First, we have made a number of permissions optional. Optional permissions don’t trigger a permission prompt for users during installation or when the extension updates. It also means that users have less of a chance of becoming stranded.

If you use the following permissions, please feel welcome to move them from the permissions manifest.json key to the optional_permissions key:

  • management
  • devtools
  • browsingData
  • pkcs11
  • proxy
  • session

Second, we’re encouraging developers who use optional permissions to request them at runtime. When you use optional permissions with the permissions.request API, permission requests will be triggered when permissions are needed for a feature. Users can then see which permissions are being requested in context of using the extension. For more information, please see our guide on requesting permissions at runtime.

As an added bonus, we’ve also implemented the permissions.onAdded and permissions.onRemoved events, allowing you to react to permissions being granted or revoked.

Merging CSP headers

Users who have multiple add-ons installed that modify the content security policy headers of requests may have been seeing their add-ons behave erratically and will likely blame the add-on(s) for not working. Luckily, we now properly merge the CSP headers when two add-ons modify them via webRequest. This is especially important for content blockers leveraging the CSP to block resources such as scripts and images.

Handling SameSite cookie restrictions

We’ve seen developers trying to work around SameSite cookie restrictions. If you have been using iframes on your extension pages and expecting them to behave like first party frames, the SameSite cookie attribute will keep your add-on from working properly. In Firefox 77, the cookies for these frames will behave as if it was a first party request. This should ensure that your extension continues to work as expected.

Other updates

Please also see these additional changes:

I’m very excited about the number of patches from the community that are included in this release. Please congratulate Tom Schuster, Ajitesh, Tobias, Mélanie Chauvel, Atique Ahmed Ziad, and a few teams across Mozilla that are bringing these great additions to you. I’m looking forward to finding out what is in store for Firefox 78, please stay tuned!

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

The Firefox FrontierFirefox features for remote school (that can also be used for just about anything)

Helping kids with school work can be challenging in the best of times (“new” math anyone?) let alone during a worldwide pandemic. These Firefox features can help make managing school … Read more

The post Firefox features for remote school (that can also be used for just about anything) appeared first on The Firefox Frontier.

Mozilla Localization (L10N)L10n Report: May 2020 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 localizer

Are you a locale leader and want us to include new members in our upcoming reports? Contact us!

New community/locales added

New content and projects

What’s new or coming up in Firefox desktop

Upcoming deadlines:

  • Firefox 77 is currently in beta and will be released on Jun 2. The deadline to update localization was on May 19.
  • The deadline to update localizations for Firefox 78, currently in Nightly, will be Jun 16 (4 weeks after the previous deadline).

IMPORTANT: Firefox 78 is the next ESR (Extended Support Release) version. That’s a more stable version designed for enterprises, but also used in some Linux distributions, and it remains supported for about a year. Once Firefox 78 moves to release, that content will remain frozen until that version becomes unsupported (about 15 months), so it’s important to ship the best localization possible.

In Firefox 78 there’s a lot of focus on the about:protections page. Make sure to test your changes on a new profile and in different states (e.g. logged out of Firefox Account and Monitor, logged into one of them, etc.). For example, the initial description changes depending on the fact that the user has enabled Enhanced Tracking Protection (ETP) or not:

  • Protections enabled: Firefox is actively protecting them, hence “Firefox protects your privacy behind the scenes while you browse”.
  • Protections disabled: Firefox could protect them, but it currently isn’t. So, ““Firefox can protect your privacy behind the scenes while you browse”.

Make sure to keep these nuances in your translation.

New Locales

With Firefox 78 we added 3 new locales to Nightly, since they made good progress and are ready for initial testing:

  • Central Kurdish (ckb)
  • Eastern Armenian with Classic Orthography (hye)
  • Mixteco Yucuhiti (meh)

All three are available for download on mozilla.org.

What’s new or coming up in mobile

  • Fennec Nightly and Beta channels have been successfully migrated to Fenix! Depending on the outcome of an experiment that launched this week, we may see the release channel migration happen soon. We’ll be sending some Fenix-specific comms this week.
  • The localization cycle for Firefox for iOS v26 has ended as of Monday, May 25th.

What’s new or coming up in web projects

Mozilla.org

Mozilla.org is now at its new home: it was switched from .lang to Fluent format last Friday. Changing to the new format would allow us:

  • to put more natural expression power in localizers hands.
  • greater flexibility for translations & making string changes.
  • to make `en` as the source for localization, while en-US is a locale.
  • to push localized content to production more often and automatically throughout the day.

Only a handful high priority files have been migrated to the new format, as you have seen in the project dashboard. Please dedicate some time to go over the migrated files and report any technical issues you discover.  Please go over the updated How to test mozilla.org] documentation for what to focus on and how to report technical issues regarding the new file format.

The migration from the old format to the new would take some time to complete. Check the mozilla.org dashboard in Pontoon regularly for updates. In the coming weeks, there will be new pages added, including the next WNP.

Web of Things

No new feature development for the foreseeable future. However, adding new locales, bug fixes and localized content are being made to the GitHub repository on a regular basis.

What’s new or coming up in SuMo

Next week is Firefox 77 release. It presents few updates to our KB articles:

In the next weeks we will communicate with the members a lot of news we had been working in the past months, between those:

  • Reports on views and helpfulness of the translated articles
  • Content for new contribution channels

What’s new or coming up in Pontoon

Django 2. As of April, Pontoon runs on Django 2. The effort to make the transition happen was started a while ago by Jotes, who first made the Pontoon codebase run on Python 3, which is required for Django 2. And the effort was also completed by Jotes, who took care of squashing DB migrations and other required steps for Pontoon to say goodbye to Django 1. Well done, Jotes!

New user avatars. Pontoon uses the popular Gravatar service for displaying user avatars. Until recently, we’ve been showing a headshot of a red panda as the fallback avatar for users without a Gravatar. But that made it hard to distinguish users just by scanning their avatars sometimes, so we’re now building custom avatars from their initials. Thanks and welcome to our new contributor, Vishnudas!

Private projects. Don’t worry, we’re not limiting access to any projects on pontoon.mozilla.org, but there are 3rd party deployments of Pontoon, which would benefit from such a feature. Jotes started paving the way for that by adding the ability to switch projects between private and public and making all new projects private after they’ve been set up. That means they are only accessible to project managers, which allows the project setup to be tested without using a separate deployment for that purpose (e.g. a stage server) and without confusing users with broken projects. If any external team wants to take the feature forward as specified, we’d be happy to take patches upstream, but we don’t plan to develop the feature ourselves, since we don’t need it at Mozilla.

More reliable Sync. Thanks to Vishal, Pontoon sync is now more immune to errors we’ve been hitting every now and then and spending a bunch of time debugging. Each project sync task is now encapsulated in a single celery task, which makes it easier to rollback and recover from errors.

Newly published localizer facing documentation

Friends of the Lion

Image by Elio Qoshi

  • Gürkan Güllü, who is the second person to exceed 2000 suggestions on Pontoon in the Turkish community, and is making significant contributions to SUMO as well.

Know someone in your l10n community who’s been doing a great job and should appear here? Contact one 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 Mozilla BlogMozilla’s journey to environmental sustainability

Process, strategic goals, and next steps

The programme may be new, but the process has been shaping for years: In March 2020, Mozilla officially launched a dedicated Environmental Sustainability Programme, and I am proud and excited to be stewarding our efforts.

Since we launched, the world has been held captive by the COVID-19 pandemic. People occasionally ask me, “Is this really the time to build up and invest in such a large-scale, ambitious programme?” My answer is clear: Absolutely.

A sustainable internet is built to sustain economic well-being and meaningful social connection, just as it is mindful of a healthy environment. Through this pandemic, we’re reminded how fundamental the internet is to our social connections and that it is the baseline for many of the businesses that keep our economies from collapsing entirely. The internet has a significant carbon footprint of its own — data centers, offices, hardware and more require vast amounts of energy. The climate crisis will have lasting effects on infrastructure, connectivity and human migration. These affect the core of Mozilla’s business. Resilience and mitigation are therefore critical to our operations.

In this world, and looking towards desirable futures, sustainability is a catalyst for innovation.

To embark on this journey towards environmental sustainability, we’ve set three strategic goals:

  • Reduce and mitigate Mozilla’s operational impact;
  • Train and develop Mozilla staff to build with sustainability in mind;
  • Raise awareness for sustainability, internally and externally.

We are currently busy conducting our Greenhouse Gas (GHG) baseline emissions assessment, and we will publish the results later this year. This will only be the beginning of our sustainability work. We are already learning that transparently and openly creating, developing and assessing GHG inventories, sustainability data management platforms and environmental impact is a lot harder than it should be, given the importance of these assessments.

If Mozilla, as an international organisation, struggles with this, what must that mean for smaller non-profit organisations? That is why we plan to continuously share what we learn, how we decide, and where we see levers for change.

 

Four principles that guide us:

Be humble

We’re new to this journey and the larger environmental movement as well as recognising that the mitigation of our own operational impact won’t be enough to address the climate crisis. We understand what it means to fuel larger movements that create the change we want to see in the world. We are leveraging our roots and experience towards this global, systemic challenge.

Be open

We will openly share what we learn, where we make progress, and how our thinking evolves — in our culture as well as in our innovation efforts. We intend to focus our efforts and thinking on the internet’s impact. Mozilla’s business builds on and grows with the internet. We understand the tech, and we know where and how to challenge the elements that aren’t working in the public interest.

Be optimistic

We approach the future in an open-minded, creative and strategic manner. It is easy to be overwhelmed in the face of a systemic challenge like the climate crisis. We aim to empower ourselves and others to move from inertia towards action, working together to build a sustainable internet. Art, strategic foresight, and other thought-provoking engagements will help us imagine positive futures we want to create.

Be opinionated

Mozilla’s mission drives us to develop and maintain the internet as a global public resource. Today, we understand that an internet that serves the public interest must be sustainable. A sustainable internet is built to sustain economic wellbeing and meaningful social connection; it is also mindful of the environment. Starting with a shared glossary, we will finetune our language, step up, and speak out to drive change.

 

I look forward to embarking on this journey with all of you.

The post Mozilla’s journey to environmental sustainability appeared first on The Mozilla Blog.

Mike HommeyThe influence of hardware on Firefox build times

I recently upgraded my aging “fast” build machine. Back when I assembled the machine, it could do a full clobber build of Firefox in about 10 minutes. That was slightly more than 10 years ago. This upgrade, and the build times I’m getting on the brand new machine (now 6 months old) and other machines led me to look at how some parameters influence build times.

Note: most of the data that follows was gathered a few weeks ago, building off Mercurial revision 70f8ce3e2d394a8c4d08725b108003844abbbff9 of mozilla-central.

Old vs. new

The old “fast” build machine had a i7-870, with 4 cores, 8 threads running at 2.93GHz, turbo at 3.6GHz, and 16GiB RAM. The new machine has a Threadripper 3970X, with 32 cores, 64 threads running at 3.7GHz, turbo at 4.5GHz (rarely reached to be honest), and 128GiB RAM (unbuffered ECC).

Let’s compare build times between them, at the same level of parallelism:

Build times at -j8

That is 63 minutes for the i7-870 vs. 26 for the Threadripper, with a twist: the Threadripper was explicitly configured to use 4 physical cores (with 2 threads each) so as to be fair to the poor i7-870.

Assuming the i7 maxed out at its base clock, and the Threadripper at turbo speed (which it actually doesn’t, but it’s closer to the truth than the base clock is with a eighth of the cores activated), the speed-up from the difference in frequency alone would make the build 1.5 times faster, but we got close to 2.5 times faster.

But that doesn’t account for other factors we’ll explore further below.

Before going there, let’s look at what unleashing the full power of the Threadripper brings to the table:

Build times at -j8 vs. -j64

Yes, that is 5 minutes for the Threadripper 3970X, when using all its cores and threads.

Spinning disk vs. NVMe

The old machine was using spinning disks in RAID 1. I can’t really test much faster SSDs on that machine because I don’t have any that would fit, and the machine is now dismantled, but I was able to try the spinning disks on the Threadripper.

Build times with HDD vs NVMe vs RAM

Using spinning disks instead of modern solid-state makes the build almost 3 times as slow! (or an addition of almost 10 minutes). And while I kind of went overboard with this new machine by setting up not one but two NVMe PCIe 4.0 SSDs in RAID1, I also slowed them down by using Full Disk Encryption, but it doesn’t matter, because I get the same build times (within noise) if I put everything in memory (because I can).

It would be interesting to get more data with different generations of SSDs, though (SATA ones may still have a visible overhead, for instance).

Going back to the original comparison between the i7-870 and the downsized Threadripper, assuming the overhead from disk alone corresponds to what we see here (which it probably doesn’t, actually, because less parallelism means less concurrent accesses, means less seeks, means more speed), the speed difference now looks closer to “only” 2x.

Desktop vs. Laptop

My most recent laptop is a 3.5 years old Dell XPS13 9360, that came with a i7-7500U (2 cores, 4 threads, because that’s all you could get in the 13″ form factor back then; 2.7GHz, 3.5GHz turbo), and 16GiB RAM.

A more recent 13″ laptop would be the Apple Macbook Pro 13″ Mid 2019, sporting an i7-8569U (4 cores, 8 threads, 2.8GHz, 4.7GHz turbo), and 16GiB RAM. I don’t own one, but Mozilla’s procurement system contains build times for it (although I don’t know what changeset that corresponds to, or what compilers were used ; also, the OS is different).

Build times on laptops vs desktop

The XPS13 being old, it is subject to thermal throttling, making it slower than it should be, but it wouldn’t beat the 10 years old desktop anyway. Macbook Pros tend to get into these thermal issues after a while too.

I’ve relied on laptops for a long time. My previous laptop before this XPS was another XPS, that is now about 6 to 7 years old, and while the newer one had more RAM, it was barely getting better build times compared to the older one when I switched. The evolution of laptop performance has been underwelming for a long time, but things finally changed last year. At long last.

I wish I had numbers with a more recent laptop under the same OS as the XPS for fairer comparison. Or with the more recent larger laptops that sport even more cores, especially the fancy ones with Ryzen processors.

Local vs. Cloud

As seen above, my laptop was not really a great experience. Neither was my faster machine. When I needed power, I actually turned to AWS EC2. That’s not exactly cheap for long term use, but I only used it for a couple hours at a time, in relatively rare occasions.

Build times on EC2 vs. Threadripper

The c5d instances are AFAIK, and as of writing, the most powerful you can get on EC2 CPU-wise. They are based on 3.0GHz Xeon Platinum CPUs, either 8124M or 8275CL (which don’t exist on Intel’s website. Edit: apparently, at least the 8275CL can turbo up to 3.9GHz). The 8124M is Skylake-based and the 8275CL is Cascade Lake, which I guess is the best you could get from Intel at the moment. I’m not sure if it’s a lottery of some sort between 8124M and 8275CL, or if it’s based on instance type, but the 4xlarge, 9xlarge and 18xlarge were 8124M and 12xlarge, 24xlarge and metal were 8275CL. Skylake or Cascade Lake doesn’t seem to make much difference here, but that would need to be validated on a non-virtualized environment with full control over the number of cores and threads being used.

Speaking of virtualization, one might wonder what kind of overhead it has, and as far as building Firefox goes, the difference between c5d.metal (without) and c5d.24xlarge (with), is well within noise.

As seen earlier, storage can have an influence on build times, and EC2 instances can use either EBS storage or NVMe. On the c5d instances, it made virtually no difference. I even compared with everything in RAM (on instances with enough of it), and that didn’t make a difference either. Take this with a grain of salt, though, because EBS can be slower on other types of instances. Also, I didn’t test NVMe or RAM on c5d.4xlarge, and those have slower networking so there could be a difference there.

There are EPYC-based m5a instances, but they are not Zen 2 and have lower frequencies, so they’re not all that good. Who knows when Amazon will deliver their Zen 2 offerings.

Number of cores

The Firefox build system is not perfect, and the number of jobs it’s allowed to run at once can have an influence on the overall build times, even on the same machine. This can somehow be observed on the results on AWS above, but testing different values of -jn on a machine with a large number of cores is another way to investigate how well the build system scales. Here it is, on the Threadripper 3970X:

Build times at different -jn

Let’s pause a moment to appreciate that this machine can build slightly faster, with only 2 cores, than the old machine could with 4 cores and 8 threads.

You may also notice that the build times at -j6 and -j8 are better than the -j8 build time given earlier. More on that further below.

The data, however, is somehow skewed as far as getting a clear picture of how well the Firefox build system scales, because the less cores and threads are being used, the faster those cores can get, thanks to “Turbo”. As mentioned earlier, the base frequency for the processor is 3.7GHz, but it can go up to 4.5GHz. In practice, /proc/cpuinfo doesn’t show much more than 4.45GHz when few cores are used, but on the opposite end, would frequently show 3.8GHz when all of them are used. Which means all the values in that last graph are not entirely comparable to each other.

So let’s see how things go with Turbo disabled (note, though, that I didn’t disable dynamic CPU frequency scaling):

Build times at different -jn without turbo

The ideal scaling (red line) is the build time at -j1 divided by the n in -jn.

So, at the scale of the graph above, things look like there’s some kind of constant overhead (the parts of the build that aren’t parallelized all that well), and a part that is within what you’d expect for parallelization, except above -j32 (we’ll get to that last part further down).

Based on the above, let’s assume a modeled build time of the form O + P / n. We can find some O and P that makes the values for e.g. -j1 and -j32 correct. That works out to be 1.9534 + 146.294 / n (or, in time format: 1:57.2 + 2:26:17.64 / n).

Let’s see how it fares:

Model vs. ideal

The red line is how far from the ideal case (-j1/n) the actual data is, in percent from the ideal case. At -j32, the build time is slightly more than 1.4 times what it ideally would be. At -j24, about 1.3 times, etc.

The blue line is how far from the modeled case the actual data is, in percent from the modeled case. The model is within 3% of reality (without Turbo) until -j32.

And above -j32, things blow up. And the reason is obvious: the CPU only has 32 actual cores. Which brings us to…

Simultaneous Multithreading (aka Hyperthreading)

Ever since the Pentium 4, many (and now most) modern desktop and laptop processors have had some sort of Simultaneous Multithreading (SMT) technology. The underlying principle is that CPUs are waiting for something a lot of the time (usually data in RAM), and that they could actually be executing something else when that happens.

From the software perspective, though, it only appears to be more cores than there physically are. So on a processor with 2 threads per core like the Threadripper 3970X, that means the OS exposes 64 “virtual” cores instead of the 32 physical ones.

When the workload doesn’t require all the “virtual” cores, the OS will schedule code to run on virtual cores that don’t share the same physical core, so as to get the best of one’s machine.

This is why -jn on a machine that has n real cores or more will have better build times than -jn on a machine with less cores, but at least n virtual cores.

This was already exposed in some way above, where the first -j8 build time shown was worse than the subsequent ones. That one was taken while disabling all physical cores but 4, and still keeping 2 threads per core. Let’s compare that with similar number of real cores:

Build times with 4 to 8 threads

As we can see, 4 cores with 8 threads is better than 4 cores, but it doesn’t beat 6 physical cores. Which kind of matches the general wisdom that SMT brings an extra 30% performance.

By the way, this being all on a Zen 2 processor, I’d expect a Ryzen 3 3300X to provide similar build times to that 4 cores 8 threads case.

Let’s look at 16 cores and 32 threads:

Build times with 16 to 32 threads

Similar observation: obviously better than 16 cores alone, but worse than 24 physical cores. And again, this being all on a Zen 2 processor, I’d expect a Ryzen 9 3950X to provide similar build times to the 16 cores and 32 threads case.

Based on the above, I’d estimate a Threadripper 3960X to have build times close to those of 32 real cores on the 3970X (32 cores is 33% more cores than 24).

Operating System

All the build times mentioned above except for the Macbook Pro have been taken under Debian GNU/Linux 10, building Firefox for Linux64 from a specific revision of mozilla-central without any tweaks.

Things get different if you build for a different target (say, Firefox for Windows), or under a different operating system.

Our baseline on this machine is the Firefox for Linux64 build is 5 minutes. Building Firefox for Windows (as a cross-compilation) takes 40 more seconds (5:40), because of building some extra Windows-specific stuff.

A similar Firefox for Windows build, natively, on a fresh Windows 10 install takes … more than 12 minutes! Until you realize you can disable Windows Defender for the source and build tree, at which point it only takes 7:27. That’s still noticeably slower than cross-compiling, but not as catastrophic as when the antivirus is enabled.

Recent versions of Windows come with a Windows Subsystem for Linux (WSL), which allows to run native Linux programs unmodified. There are now actually two versions of WSL. One emulates Linux system calls (WSL1), and the other runs a real Linux kernel in a virtual machine (WSL2). With a Debian GNU/Linux 10 system under WSL1, building Firefox for Linux64 takes 6:25, while it takes 5:41 under WSL2, so WSL2 is definitely faster, but still not close to metal.

Edit: Ironically, it’s very much possible that a cross-compiled Firefox for Windows build in WSL2 would be faster than a native Firefox for Windows build on Windows (but I haven’t tried).

Finally, a Firefox for Windows build, on a fresh Windows 10 install in a KVM virtual machine under the original Debian GNU/Linux system takes 8:17, which is a lot of overhead. Maybe there are some tweaks to do to get better build times, but it’s probably better to go with cross-compilation.

Let’s recap as a graph:

Build times on different OS configurations

Automation

All the build times mentioned so far have been building off mozilla-central without any tweaks. That’s actually not how a real Firefox release is built, which enables more optimizations. Without even going to the full set of optimizations that go into building a real Firefox Nightly (including Link Time Optimizations and Profile Guided Optimizations), simply switching --enable-release on will up the optimization game.

Building on Mozilla automation also enables things that don’t happen during what we call “local developer builds”, such as dumping debug info for use to process crash reports, linking a second libxul library for some unit tests, the full packaging of Firefox, the preparation of archives that will be used to run tests, etc.

As of writing, most Firefox builds on Mozilla automation happen on c5d.4xlarge (or similarly sized) AWS EC2 instances. They benefit from the use of a shared compilation cache, so their build times are very noisy, as they depend on the cache hit rate.

So, I took some Linux64 optimized build that runs on automation (not one with LTO or PGO), and ran its full script, with the shared compilation cache disabled, on corresponding and larger AWS EC2 instances, as well as the Threadripper:

Build times for a linux64/opt build as per automation

The immediate observation is that these builds scale much less gracefully than a “local developer build” does, and there are multiple factors that come into play, but the common thread is that parts of the build that don’t run during those “local developer builds” are slow and not well parallelized. Work is in progress to make things better, though.

Another large contributor is that with the higher level of optimizations, the compilation of Rust code takes longer. And compiling Rust doesn’t parallelize very well at the moment (for a variety of reasons, but the main one is the long sequences of crate dependencies, i.e. when A depends on B, which depends on C, which depends on D, etc.). So what happens the more cores are available, is that compiling all the C/C++ code finishes well before compiling all the Rust code does, and with the long tail of crate dependencies, what’s remaining doesn’t parallelize well. And that also blocks other portions of the build that need the compiled Rust code, and aren’t very well parallelized themselves.

All in all, it’s not all that great to go with bigger instances, because they cost more but won’t compensate by doing as many more builds in the same amount of time… except if doing more builds in parallel, which is being experimented with.

On the Threadripper 3970X, I can do 2 “local developer builds” in parallel in less time than doing them one after the other (1:20 less, so 8:40 instead of 10 minutes). Even with -j64. Heck, I can do 4 builds in parallel at -j16 in 16 minutes and 15 seconds, which is somewhere between a single -j12 and single -j8, which is where one -j16 with 8 threads and 16 threads should be at. That doesn’t seem all that useful, until you think of it this way: I can locally build for multiple platforms at once in well under 20 minutes. All on one machine, from one source tree.

Closing words

We looked at various ways build times can vary depending on different hardware (and even software) configurations. Note this only covers hardware parameters that didn’t require reboots to test out (e.g. this excludes variations like RAM speed ; and yes, this means there are ways to disable turbo, cores and threads without fiddling with the BIOS, I’ll probably write a separate blog post about this).

We saw there is room for improvements in Firefox build times, especially on automation. But even for local builds, on machines like mine, it should be possible to get under 4 minutes eventually. Without any form of caching. Which is kind of mind blowing. Even without these future improvements, these build times changed the way I approach things. I don’t mind clobber builds anymore, although ideally we’d never need them.

If you’re on the market for a new machine, I’d advise getting a powerful desktop machine (based on a 3950X, a 3960X or a 3970X) rather than refreshing your aging laptop. I don’t think any laptop currently available would get below 15 minutes build times. And those that can build in less than 20 minutes probably cost more than a desktop machine that would build in well under half that. Edit: Also, pick a fast NVMe SSD that can sustain tons of IOPS.

Of course, if you use some caching method, build times will be much better even on a slower machine, but even with a cache, it happens quite often that you get a lot of cache misses that cancel out the benefit of the cache. YMMV.

You may also have legitimate concerns that rr doesn’t work yet, but when I need it, I can pull my old Intel-based laptop. rr actually works well enough on Ryzen for single-threaded workloads, and I haven’t needed to debug Firefox itself with rr recently, so I haven’t actually pulled the old laptop a lot (although I have been using rr and Pernosco).

Ryan HarterWriting inside organizations

Tom Critchlow has a great post here outlining some points on how important writing is for an organization.

I'm still working through the links, but his post already sparked some ideas. In particular, I'm very interested in the idea of an internal blog for sharing context.

Snippets

My team keeps …

Mozilla Privacy BlogAn opportunity for openness and user agency in the proposed Facebook-Giphy merger

Facebook is squarely in the crosshairs of global competition regulators, but despite that scrutiny, is moving to acquire Giphy, a popular platform that lets users share images on social platforms, such as Facebook, or messaging applications, such as WhatsApp. This merger – how it is reviewed, whether it is approved, and if approved under what sort of conditions – will set a precedent that will influence not only future mergers, but also the shape of legislative reforms being actively developed all around the world. It is crucial that antitrust agencies incorporate into their processes a deep understanding of the nature of the open internet and how it promotes competition, how data flows between integrated services, and in particular the role played by interoperability.

Currently Giphy is integrated with numerous independent social messaging services, including, for example, Slack, Signal, and Twitter. A combined Facebook-Giphy would be in a position to restrict access by those companies, whether to preserve their exclusivity or to get leverage for some other reason. This would bring clear harm to users who would suddenly lose the capabilities they currently enjoy, and make it harder for other companies to compete.

As is typical at this stage of a merger, Facebook said in its initial blog post that “developers and API partners will continue to have the same access to GIPHY’s APIs” and “we’re looking forward to investing further in its technology and relationships with content and API partners.” But we have to evaluate that promise in light of Facebook’s history of limiting third-party access to its own APIs and making plans to integrate its own messaging services into a modern-day messaging silo.

We also know of one other major risk: the loss of user agency and control over data. In 2014, Facebook acquired the new messaging service WhatsApp for a staggering $19 billion. WhatsApp had done something remarkable even for the high tech sector: its user growth numbers were off the charts. At that time, before today’s level of attention to interoperability and competition, the primary concern raised by the merger was the possibility of sharing user data and profiles across services. So the acquisition was permitted under conditions limiting such sharing, although Facebook was subsequently fined by the European Commission for violating these promises.

We don’t know, at this point, the full scale of potential data sharing harms that could result from the Giphy acquisition. Certainly, that’s a question that deserves substantial exploration. User data previously collected by Giphy – such as the terms used to look for images – may at some point in the future be collected by Facebook, and potentially integrated with other services, the same fact pattern as with WhatsApp.

We must learn from the missed opportunity of the Facebook/WhatsApp merger. If this merger is allowed to proceed, Facebook should at minimum be required to keep to its word and preserve the same access to Giphy’s APIs for developers and API partners. Facebook should go one step further, and commit to using open standards whenever possible, while also making available to third parties under fair, reasonable, and nondiscriminatory terms and conditions any APIs or other interoperability interfaces it develops between Giphy and Facebook’s current services. In order to protect users from yet more tracking of their behavior, Facebook should commit not to combine data collected by Giphy with other user data that it collects – a commitment that fell short in the WhatsApp case, but can be strengthened here. Together these restrictions would help open up the potential benefits of technology integration while simultaneously making them available to the entire ecosystem, protecting users broadly.

As antitrust agencies begin their investigations of this transaction, they must conduct a full and thorough review based on a detailed technical understanding of the services, data flows, and partnerships involved, and ensure that the outcome protects user agency and promotes openness and interoperability. It’s time to chart a new course for tech competition, and this case represents a golden opportunity.

The post An opportunity for openness and user agency in the proposed Facebook-Giphy merger appeared first on Open Policy & Advocacy.

This Week In RustThis Week in Rust 340

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.

Check out this week's This Week in Rust Podcast

Updates from Rust Community

News & Blog Posts

Crate of the Week

This week's crate is cargo-asm, a cargo subcommand to show the resulting assembly of a function. Useful for performance work.

Thanks to Jay Oster 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

359 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 last 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 the final comment period.

Tracking Issues & PRs

New RFCs

No new RFCs were proposed this week.

Upcoming Events

Online
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

Things that are programming patterns in C are types in Rust.

Kornel Lesiński on rust-users

Thanks to trentj for the suggestions!

Please submit quotes and vote for next week!

This Week in Rust is edited by: nellshamrell, llogiq, and cdmistman.

Discuss on r/rust.

Mozilla Localization (L10N)How to unleash the full power of Fluent as a localizer

Fluent is an extremely powerful system, providing localizers with a level of flexibility that has no equivalent in other localization systems. It can be as straightforward as older formats, thanks to Pontoon’s streamlined interface, but it requires some understanding of the syntax to fully utilize its potential.

Here are a few examples of how you can get the most out of Fluent. But, before jumping in, you should get familiar with our documentation about Fluent syntax for localizers, and make sure to know how to switch to the Advanced FTL mode, to work directly with the syntax of each message.

Plurals

Plural forms are a really complex subject; some locales don’t use any (e.g. Chinese), English and most Romance languages use two (one vs many), others use all the six forms defined by CLDR (e.g. Arabic). Fluent gives you all the flexibility that you need, without forcing you to provide all forms if you don’t need them (unlike Gettext, for example).

Consider this example displayed in Pontoon for Arabic:

Screenshot of a plural string in Pontoon for ArabicThe underlying reference message is:

# Variables:
# $numBreachesResolved (Number) - Number of breaches marked as resolved by the user on Monitor.
# $numBreaches (Number) - Number of breaches in which a user's data was involved, detected by Monitor.
monitor-partial-breaches-title =
    { $numBreaches ->
       *[other] { $numBreachesResolved } out of { $numBreaches } breaches marked as resolved
    }

You can see it if you switch to the FTL advanced mode, and temporarily COPY the English source.

This gives you a lot of information:

  • It’s a message with plurals, although only the other category is defined for English.
  • The other category is also the default, since it’s marked with an asterisk.
  • The value of $numBreaches defines which plural form will be used.

First of all, since you only have one form, you can decide to remove the select logic completely. This is equivalent to:

monitor-partial-breaches-title = { $numBreachesResolved } out of { $numBreaches } breaches marked as resolved

You might ask: why is there a plural in English then? That’s a great question! It’s just a small hack to trick Pontoon into displaying the UI for plurals.

But there’s more: what if this doesn’t work for your language? Consider Italian, for example: to get a more natural sounding sentence, I would translate it as “10 breaches out of 20 marked as resolved”. There are two issues to solve: I need $numBreachesResolved (number of solved breaches) to determine which plural form to use, not the total number, and I need a singular form. While I can’t make these changes directly through Pontoon’s UI, I can still write my own syntax:

monitor-partial-breaches-title =
    { $numBreachesResolved ->
        [one] { $numBreachesResolved } violazione su { $numBreaches } contrassegnata come risolta
       *[other] { $numBreachesResolved } violazioni su { $numBreaches } contrassegnate come risolte
    }

Notice the two relevant changes:

  • There is now a one form (used for 1 in Italian).
  • $numBreachesResolved is used to determine which plural form is selected ($numBreachesResolved ->).

Terms

We recently started migrating mozilla.org to Fluent, and there are a lot of terms defined for specific feature names and brands. Using terms instead of hard-coding text in strings helps ensure consistency and enforce branding rules. The best example is probably the term for Firefox Account, where the “account” part is localizable.

-brand-name-firefox-account = Firefox Account

In Italian it’s translated as “account Firefox”. But it should be “Account Firefox” if used at the beginning of a sentence. How can I solve this, without removing the term and getting warnings in Pontoon? I can define a parameterized term.

-brand-name-firefox-account =
    { $capitalization ->
       *[lowercase] account Firefox
        [uppercase] Account Firefox
    }

In this example, the default is lowercase, since it’s the most common form in Italian. By using only the term reference { -brand-name-firefox-account }, it will be automatically displayed as “account Firefox”.

login-button = Accedi al tuo { -brand-name-firefox-account }

What if I need the uppercase version?

login-title = { -brand-name-firefox-account(capitalization: "uppercase") }

You can find more information about terms, as well as other examples, in our documentation. And don’t forget to check the rules about brand names.

Things you shouldn’t translate

Variables and placeables should not be translated. The good news is that they’re easy to spot, since they’re surrounded by curly parentheses:

  • Variable reference: { $somevariable }
  • Term reference: { -someterm }
  • Message reference: { somemessage }

The content between parentheses must be kept as in the English source string.

The same is valid for the data-l10n-name attribute in HTML elements. Consider for example:

update-downloading = <img data-l10n-name="icon"/>Downloading update — 

The only thing to translate in this message is “Downloading update -”. “Icon” and “download-status” should be kept untranslated.

The rule of thumb is to pay extra attention when there are curly parentheses, since they’re used to identify special elements of the syntax.

Another example:

menu-menuitem-preferences =
   { PLATFORM() ->
       [windows] Options
      *[other] Preferences
   }

PLATFORM() is a function, and should not be translated. windows and other are variant names, and should be kept unchanged as well.

One other thing to look out for are style attributes, since they’re used for CSS rules.

downloads-panel-list =
    .style = width: 70ch

width: 70ch is a CSS rule to define the width of an element, and should be kept untranslated. The only thing that you might want to change is the actual value, for example to make it larger (width: 75ch). Note that ch is a unit of measure used in CSS.

Firefox NightlyThese Weeks in Firefox: Issue 74

Highlights

  • The Network panel is now showing even requests rejected by CORS (Cross-origin resource sharing). All rejected requests are using red color as you can see in the following screenshot. Note that there is also corresponding warning in the Console panel for each rejected request.

    Support for CORS rejected requests in the Network monitor

  • Console panel error inspection has been improved significantly and it should be possible to see all properties of an error object directly in the Console panel (by expanding the error object) in a lot more cases. You can also right  click on an error object and pick “Inspect object in Sidebar” from the context menu (bug). In addition to that you should be also able see callstack for unhandled rejected promises (bug)

    Error object inspection in the Console panel

  • The Network panel is showing name of the related Add-on responsible for blocking an HTTP request e.g. uBlock Origin or Adblock Plus (bug)

    Requests blocked by add-on

  • It is possible to manually block HTTP requests using drag-and-block. Just drag a request from the panel list and drop it onto the Blocking side panel (bug

    Manual request blocking using drag-and-drop

  • Updated password heuristics model to version 4.0 in order to bring password generation to even more websites.
    • Seeing a substantial increase in usage of Firefox’s password generation:

      Password generation usage
    • (Number of passwords generated, normalized by the number of sites without an existing saved password)
  • It’s now possible to directly search for strings like “class.method” without having to prefix them with a question mark, and we correct the most common suffix typos, like mozilla.ogr
  • Relatedly, the address bar can now recognize custom domain suffixes using browser.fixup.domainsuffixwhitelist.yoursuffix (.test, .example, .invalid, .localhost, .internal, .local are set by default)
  • Opening PDFs from Firefox’s download panel now opens the PDF directly within Firefox

 

Friends of the Firefox team

Resolved bugs (excluding employees)

Fixed more than one bug

  • Andrew Swan [:aswan]
  • Farooq AR
  • Itiel
  • Martin Stránský [:stransky]
  • Etienne Bruines

New contributors (🌟 = first patch)

 

Project Updates

Addon Manager & about:addons
  • Andrew Swan contributed the changes needed to handle updates for built-in extensions (the one bundled into the omni.ja) Bug 1571876, which was also a blocker for completing the migration of some system addons into built-in (e.g. Screenshots as part of bug 1568270), and another change to avoid checking the blocklist for built-in and system addons (Bug 1633396), which is likely helpful to avoid some additional work during the startup

 

WebExtensions Framework
  • Fixed a regression in Firefox 76 related to the runtime.onConnect API event (Bug 1635637), the regression has been reported on bugzilla for Amazon Assistant extension (but it was likely going to affect some other extension), thanks to Tomislav for quicking working on a fix (and Rob for helping on quickly investigating the reasons behind the regression).
  • :baku fixed a regression that was going to break “Reddit Enhancement Suite” in Firefox 77 (Bug 1635490)
  • Fixed a regression in Firefox 78, related to the webRequest event listeners, that was likely going to affect Adblock Plus (Bug 1638581). Fixing this regression did also fix Bug 1638476 (related to the new “blocking by extension” feature part of the devtools network panel)

 

WebExtension APIs
  • Additional parts of the new rust-based browser.storage.sync backend landed in the last two weeks (Bug 1623245, Bug 1634191, Bug 1637169, Bug 1635688, Bug 1637165), Thanks to the markh and lina!
  • Contributions:
    • The new browser.tabs.goForward and browser.tabs.goBack API methods are now also supported on GeckoView / Fenix (Bug 1633328). Thanks Atique for contributing this new API on both Firefox Desktop and GeckoView!
    • browser.downloads.download now remembers the most recently used directory when the API call does also use the “saveAs: true” option (Bug 1395207). Thanks to Mark Smith for contributing this enhancement!

 

Developer Tools

  • Console panel – On Nightly you can inspect an error object in the sidebar. Just right click on the error object and pick “Inspect object in Sidebar” menu action (Bug 1634432)

    Inspect error in a sidebar

  • Debugger panel – map scopes for Logpoints. This feature allows using original variable names within a logpoint (if source map is available) (bug)

    Map scopes works in logpoints

  • About:debugging – See/change remote URL from about:devtools-toolbox. This is handy features allows the user to change URL of remotely debugged page directly from DevTools. No more typing on small phone keyboard (bug)

    See/change remote URL

  • Network Panel – Headers panel facelift (better summary info + expandable URL & query arguments inspection). You’ll fall in love with the new side panel Bug 1631295

    Headers panel facelift

  • Fission – Call for Fission feedback (+ RDM shipped to DevEdition)

 

Lint

  • Kwan landed a set of patches to ensure that we don’t throw bare `Components.results` items in Javascript, instead ensuring they are wrapped in `Components.Exception`.

 

New Tab Page

  • The team is experimenting with a new card treatment for stories that link to videos.
  • The team is also experimenting with moving the popular topics element a bit further up the page.

 

Password Manager

 

PDFs & Printing 

  • Firefox opens infinite tabs when set as the OS default file handler for PDFs
  • pdfs with content-type application/octet-stream are downloaded without confirmation, even though Preview in Firefox is enabled
  • Should be able to view PDFs even if the response HTTP headers include Content-Disposition:attachment

    • View PDF

  • Labeling of default app handling in preferences is confusing for PDF files

    Labeling default app handling

 

Performance

  • bigiri working on running the snippets code entirely within the content process.
  • emalysz has a patch in review which shows a consistent 25% improvement in startup times on Windows reference hardware by changing the list of DLLs we preload during startup

    DLL preloads stats

  • florian landed work to exit(0) at the end of mochitests on opt builds, saving infra time.
  • Gijs and emalysz landed several patches to lazily insert panels and popups into the DOM only as needed.
  • dthayer is working on patches to eliminate omnijar reads during typical startups by expanding the scope of the startup cache, allowing us to avoid IO and lazily open omnijar files.
  • emalysz is experimenting to see if we can decrease the shutdown terminator’s timeout setting without substantially increasing overall shutdown hangs, with the hope of limiting time spent waiting for a hung shutdown (for instance, during OS shutdown).

 

Remote Protocol (Chrome DevTools Protocol subset) 

 

Search and Navigation

  • Modern Search Configuration
    • We have just finished landing a set of patches for integrating our partner distribution engines into the configuration. This allows us to manage these in a better way and reduces the amount of special code for distributions.
  • Improving region detection
  • Cleaning up the search service
    • With modernisation now almost shipping, the next steps will be to start a late spring clean on the search service. This is mainly aimed at cleaning up the startup code and handling of configuration changes, though other areas will be included as well.

 

Address Bar
  • Search suggestions are now highlighted differently, only non typed words and tail of typed words are highlighted – Bug 1636696
  • The team continues working on improving results matching and composition, a few things we’re currently looking into:
    • historical and tail search suggestions
    • experiments about new search experience
    • more consistent search or visit heuristic when typing
    • Improved autofill and scoring

 

User Journey

The multi-stage about:welcome project is underway

Data@MozillaHow does the Glean SDK send gzipped pings

(“This Week in Glean” is a series of blog posts that the Glean Team at Mozilla is using to try to communicate better about our work. They could be release notes, documentation, hopes, dreams, or whatever: so long as it is inspired by Glean.)

Last week’s blog post:This Week in Glean: mozregression telemetry (part 2) by William Lachance.

All “This Week in Glean” blog posts are listed in the TWiG index  (and on the Mozilla Data blog).

In the Glean SDK, when a ping is submitted it gets internally persisted to disk and then queued for upload. The actual upload may happen later on, depending on factors such as the availability of an Internet connection or throttling. To save users’ bandwidth and reduce the costs to move bytes within our pipeline, we recently introduced gzip compression for outgoing pings.

This article will go through some details of our upload system and what it took us to enable the ping compression.

How does ping uploading work?

Within the Glean SDK, the glean-core Rust component does not provide any specific implementation to perform the upload of pings. This means that either the language bindings (e.g. Glean APIs for Android in Kotlin) or the product itself (e.g. Fenix) have to provide a way to transport data from the client to the telemetry endpoint.

Before our recent changes (by Beatriz Rizental and Jan-Erik) to the ping upload system, the language bindings needed to understand the format with which pings were persisted to disk in order to read and finally upload them. This is not the case anymore: glean-core will provide language bindings with the headers and the data (ping payload!) of the request they need to upload.

The new upload API empowers the SDK to provide a single place in which to compress the payload to be uploaded: glean-core, right before serving upload requests to the language bindings.

gzipping: the implementation details

The implementation of the function to compress the payload is trivial, thanks to the `flate2` Rust crate:

/// Attempt to gzip the provided ping content.
fn gzip_content(path: &str, content: &[u8]) -> Option<Vec<u8>> {
let mut gzipper = GzEncoder::new(Vec::new(), Compression::default());
// Attempt to add the content to the gzipper.
if let Err(e) = gzipper.write_all(content) {
log::error!("Failed to write to the gzipper: {} - {:?}", path, e);
return None;
}
gzipper.finish().ok()
}

And an even simpler way to use it to compress the body of outgoing requests:

pub fn new(document_id: &str, path: &str, body: JsonValue) -> Self {
let original_as_string = body.to_string();
let gzipped_content = Self::gzip_content(path, original_as_string.as_bytes());
let add_gzip_header = gzipped_content.is_some();
let body = gzipped_content.unwrap_or_else(|| original_as_string.into_bytes());
let body_len = body.len();
Self {
document_id: document_id.into(),
path: path.into(),
body,
headers: Self::create_request_headers(add_gzip_header, body_len),
}
}

What’s next?

The new upload mechanism and its compression improvement is only currently available for the iOS and Android Glean SDK language bindings. Our next step (currently in progress!) is to add the newer APIs to the Python bindings as well, moving the complexity of handling the upload process to the shared Rust core.

In our future, the new upload mechanism will additionally provide a flexible constraint-based scheduler (e.g. “send at most 10 pings per hour”) in addition to pre-defined rules for products to use.

Daniel Stenbergcurl ootw: –socks5

(Previous option of the week posts.)

--socks5 was added to curl back in 7.18.0. It takes an argument and that argument is the host name (and port number) of your SOCKS5 proxy server. There is no short option version.

Proxy

A proxy, often called a forward proxy in the context of clients, is a server that the client needs to connect to in order to reach its destination. A middle man/server that we use to get us what we want. There are many kinds of proxies. SOCKS is one of the proxy protocols curl supports.

SOCKS

SOCKS is a really old proxy protocol. SOCKS4 is the predecessor protocol version to SOCKS5. curl supports both and the newer version of these two, SOCKS5, is documented in RFC 1928 dated 1996! And yes: they are typically written exactly like this, without any space between the word SOCKS and the version number 4 or 5.

One of the more known services that still use SOCKS is Tor. When you want to reach services on Tor, or the web through Tor, you run the client on your machine or local network and you connect to that over SOCKS5.

Which one resolves the host name

One peculiarity with SOCKS is that it can do the name resolving of the target server either in the client or have it done by the proxy. Both alternatives exists for both SOCKS versions. For SOCKS4, a SOCKS4a version was created that has the proxy resolve the host name and for SOCKS5, which is really the topic of today, the protocol has an option that lets the client pass on the IP address or the host name of the target server.

The --socks5 option makes curl itself resolve the name. You’d instead use --socks5-hostname if you want the proxy to resolve it.

--proxy

The --socks5 option is basically considered obsolete since curl 7.21.7. This is because starting in that release, you can now specify the proxy protocol directly in the string that you specify the proxy host name and port number with already. The server you specify with --proxy. If you use a socks5:// scheme, curl will go with SOCKS5 with local name resolve but if you instead sue socks5h:// it will pick SOCKS5 with proxy-resolved host name.

SOCKS authentication

A SOCKS5 proxy can also be setup to require authentication, so you might also have to specify name and password in the --proxy string, or set separately with --proxy-user. Or with GSSAPI, so curl also supports --socks5-gssapi and friends.

Examples

Fetch HTTPS from example.com over the SOCKS5 proxy at socks5.example.org port 1080. Remember that –socks5 implies that curl resolves the host name itself and passes the address to to use to the proxy.

curl --socks5 socks5.example.org:1080 https://example.com/

Or download FTP over the SOCKS5 proxy at socks5.example port 9999:

curl --socks5 socks5.example:9999 ftp://ftp.example.com/SECRET

Useful trick!

A very useful trick that involves a SOCKS proxy is the ability OpenSSH has to create a SOCKS tunnel for us. If you sit at your friends house, you can open a SOCKS proxy to your home machine and access the network via that. Like this. First invoke ssh, login to your home machine and ask it to setup a SOCKS proxy:

ssh -D 8080 user@home.example.com

Then tell curl (or your browser, or both) to use this new SOCKS proxy when you want to access the Internet:

curl --socks5 localhost:8080 https:///www.example.net/

This will effectively hide all your Internet traffic from your friends snooping and instead pass it all through your encrypted ssh tunnel.

Related options

As already mentioned above, --proxy is typically the preferred option these days to set the proxy. But --socks5-hostname is there too and the related --socks4 and --sock4a.

Mozilla Privacy BlogMozilla Mornings on advertising and micro-targeting in the EU Digital Services Act

On 4 June, Mozilla will host the next installment of Mozilla Mornings – our regular breakfast series that brings together policy experts, policymakers and practitioners for insight and discussion on the latest EU digital policy developments.

In 2020 Mozilla Mornings has adopted a thematic focus, starting with a three-part series on the upcoming Digital Services Act. This second virtual event in the series will focus on advertising and micro-targeting; whether and to what extent the DSA should address them. With several European Parliament resolutions dealing with this question and given its likely prominence in the upcoming European Commission public consultation, the discussion promises to be timely and insightful.

Speakers

Tiemo Wölken MEP
JURI committee rapporteur, Digital Services Act INI

Katarzyna Szymielewicz
President
Panoptykon Foundation

Stephen Dunne
Senior Policy Advisor
Centre for Data Ethics & Innovation

Brandi Geurkink
Senior Campaigner
Mozilla Foundation

With opening remarks by Raegan MacDonald
Head of European Public Policy, Mozilla Corporation

Moderated by Jennifer Baker
EU Tech Journalist

 

Logistical information

4 June, 2020
10:30-12:00 CEST
Zoom webinar (conferencing details post-registration)

Register here or by email to mozillabrussels@loweurope.eu

The post Mozilla Mornings on advertising and micro-targeting in the EU Digital Services Act appeared first on Open Policy & Advocacy.

William LachanceThe humble blog

I’ve been thinking a lot about markdown, presentation, dashboards, and other frontendy sorts of things lately, partly inspired by my work on Iodide last year, partly inspired by my recent efforts on improving docs.telemetry.mozilla.org. I haven’t fully fleshed out my thoughts on this yet, but in general I think blogs (for some value of “blog”) are still a great way to communicate ideas and concepts to an interested audience.

Like many organizations, Mozilla’s gone down the path of Google Docs, Zoom and Slack which makes me more than a little sad: good ideas disappear down the memory hole super quickly with these tools, not to mention the fact that they are closed-by-default (even to people inside Mozilla!). My view on “open” is a bit more nuanced than it used to be: I no longer think everything need be all-public, all-the-time— but I still think talking about and through our ideas (even if imperfectly formed or stated) with a broad audience builds trust and leads to better outcomes.

Is there some way we can blend some of these old school ideas (blogs, newsgroups, open discussion forums) with better technology and social practices? Let’s find out.

The Mozilla BlogThe USA Freedom Act and Browsing History

Last Thursday, the US Senate voted to renew the USA Freedom Act which authorizes a variety of forms of national surveillance. As has been reported, this renewal does not include an amendment offered by Sen. Ron Wyden and Sen. Steve Daines that would have explicitly prohibited the warrantless collection of Web browsing history. The legislation is now  being considered by the House of Representatives and today Mozilla and a number of other technology companies sent a letter urging them to adopt the Wyden-Daines language in their version of the bill. This post helps fill in the technical background of what all this means.

Despite what you might think from the term “browsing history,” we’re not talking about browsing data stored on your computer. Web browsers like Firefox store, on your computer, a list of the places you’ve gone so that you can go back and find things and to help provide better suggestions when you type stuff in the awesomebar. That’s how it is that you can type ‘f’ in the awesomebar and it might suggest you go to Facebook.

Browsers also store a pile of other information on your computer, like cookies, passwords, cached files, etc. that help improve your browsing experience and all of this can be used to infer where you have been. This information obviously has privacy implications if you share a computer or if someone gets access to your computer, and most browsers provide some sort of mode that lets you surf without storing history (Firefox calls this Private Browsing). Anyway, while this information can be accessed by law enforcement if they have access to your computer, it’s generally subject to the same conditions as other data on your computer and those conditions aren’t the topic at hand.

In this context, what “web browsing history” refers to is data which is stored outside your computer by third parties. It turns out there is quite a lot of this kind of data, generally falling into four broad categories:

  • Telecommunications metadata. Typically, as you browse the Internet, your Internet Service Provider (ISP) learns every website you visit. This information leaks via a variety of channels (DNS lookups), the IP address of sites, TLS Server Name Indication (SNI), and then ISPs have various policies for how much of this data they log and for how long. Now that most sites have TLS Encryption this data generally will be just the name of the Web site you are going to, but not what pages you go to on the site. For instance, if you go to WebMD, the ISP won’t know what page you went to, they just know that you went to WebMD.
  • Web Tracking Data. As is increasingly well known, a giant network of third party trackers follows you around the Internet. What these trackers are doing is building up a profile of your browsing history so that they can monetize it in various ways. This data often includes the exact pages that you visit  and will be tied to your IP address and other potentially identifying information.
  • Web Site Data. Any Web site that you go to is very likely to keep extensive logs of everything you do on the site, including what pages you visit and what links you click. They may also record what outgoing links you click. For instance, when you do searches, many search engines record not just the search terms, but what links you click on, even when they go to other sites. In addition, many sites include various third party analytics systems which themselves may record your browsing history or even make a recording of your behavior on the site, including keystrokes, mouse movements, etc. so it can be replayed later.
  • Browser Sync Data. Although the browsing history stored on your computer may not be directly accessible, many browsers offer a “sync” feature which lets you share history, bookmarks, passwords, etc. between browser instances (such as between your phone and your laptop). This information has to be stored on a server somewhere and so is potentially accessible. By default, Firefox encrypts this data by default, but in some other browsers you need to enable that feature yourself.

So there’s a huge amount of very detailed data about people’s browsing behavior sitting out there on various servers on the Internet. Because this is such sensitive information, in Mozilla’s products we try to minimize how much of it is collected with features such as encrypted sync (see above) or enhanced tracking protection. However, even so there is still far too much data about user browsing behavior being collected and stored by a variety of parties.

This information isn’t being collected for law enforcement purposes but rather for a variety of product and commercial reasons. However, the fact that it exists and is being stored means that it is accessible to law enforcement if they follow the right process; the question at hand here is what that process actually is, and specifically in the US what data requires a warrant to access — demanding a showing of ‘probable cause’ plus a lot of procedural safeguards — and what can be accessed with a more lightweight procedure. A more detailed treatment of this topic can be found in this Lawfare piece by Margaret Taylor, but at a high level, the question turns on whether data is viewed as content or metadata, with content generally requiring a more heavyweight process and a higher level of evidence.

Unfortunately, historically the line between content and metadata hasn’t been incredibly clear in the US courts. In some cases the sites you visit (e.g., www.webmd.com) are treated as metadata, in which case that data would not require a warrant. By contrast, the exact page you went to on WebMD would be content and would require a warrant. However, the sites themselves reveal a huge amount of information about you. Consider, for instance, the implications of having Ashley Madison or Stormfront in your browsing history. The Wyden-Daines amendment would have resolved that ambiguity in favor of requiring a warrant for all  Web browsing history and search history. If the House reauthorizes USA Freedom without this language, we will be left with this somewhat uncertain situation but one where in practice much of people’s activity on the Internet  — including activity which they would rather keep secret —  may be subject to surveillance without a warrant.

The post The USA Freedom Act and Browsing History appeared first on The Mozilla Blog.

The Mozilla BlogProtecting Search and Browsing Data from Warrantless Access

As the maker of Firefox, we know that browsing and search data can provide a detailed portrait of our private lives and needs to be protected. That’s why we work to safeguard your browsing data, with privacy features like Enhanced Tracking Protection and more secure DNS.

Unfortunately, too much search and browsing history still is collected and stored around the Web. We believe this data deserves strong legal protections when the government seeks access to it, but in many cases that protection is uncertain.

The US House of Representatives will have the opportunity to address this issue next week when it takes up the USA FREEDOM Reauthorization Act (H.R. 6172). We hope legislators will amend the bill to limit government access to internet browsing and search history without a warrant.

The letter in the link below, sent today from Mozilla and other companies and internet organizations, calls on the House to preserve this essential aspect of personal privacy online.

Read our letter (PDF)

 

The post Protecting Search and Browsing Data from Warrantless Access appeared first on The Mozilla Blog.

Cameron KaiserTenFourFox FPR23b1 available

TenFourFox Feature Parity Release 23 beta 1 is now available (downloads, hashes, release notes). This version brings various oddiments of image tags up to spec, fixing issues with broken or misdimensioned images on some sites, and also has a semantic upgrade to Content Security Policy which should fix other sites but is most important to me personally because now TenFourFox can directly talk to the web BMC interface on Raptor Talos II and Blackbird systems -- like the one sitting next to the G5. There is also a minor performance tweak to JavaScript strings and the usual security updates. Assuming no major issues, FPR23 should go live on or about June 2nd.

Mozilla VR BlogFirefox Reality for HoloLens 2

Firefox Reality for HoloLens 2

Mozilla's Mixed Reality team is excited to announce the first public release of Firefox Reality in the Microsoft store. We announced at Mobile World Congress 2019 that we were working with Microsoft to bring a mixed reality browser to the HoloLens 2 platform, and we're proud to share the result of that collaboration.

Firefox Reality is an experimental browser for a promising new platform, and this initial release focuses on exposing the powerful AR capabilities of HoloLens 2 devices to web developers through the new WebXR standard.

Firefox Reality for HoloLens 2<figcaption>The 2D browser window</figcaption>
Firefox Reality for HoloLens 2<figcaption>An immersive Babylon.js experience</figcaption>

This release highlights several early demos which are built on standard Babylon.js and three.js libraries. That means the same pages can be loaded in AR or VR headsets, or in a 2D desktop browser, without requiring the developer to create a custom experience for each platform.

The Firefox Reality team continues to work on standardizing and implementing new WebXR modules to expand the web platform's capabilities on the device. We encourage developers with HoloLens 2 access to give our new browser a spin and explore the potential for bringing new experiences to the augmented reality web!

Get it today!

Mozilla AccessibilityToday is Global Accessibility Awareness Day!

Thursday, May 21, 2020, marks the ninth annual Global Accessibility Awareness Day (GAAD). The purpose of GAAD is to get everyone talking, thinking and learning about digital access/inclusion and people with different disabilities.

Mozilla is committed to ensuring that all of our offerings are accessible and inclusive. Global Accessibility Awareness Day is a great opportunity to recognize and celebrate that.

At Mozilla, accessibility is a fundamental part of our mission, helping to empower people, regardless of their abilities.

Our mission is to ensure the Internet is a global public resource, open and accessible to all. An Internet that truly puts people first, where individuals can shape their own experience and are empowered, safe and independent.

And, from our Manifesto principles:

The internet is a global public resource that must remain open and accessible.

We are committed to an internet that includes all the peoples of the earth — where a person’s demographic characteristics do not determine their online access, opportunities, or quality of experience.

We are committed to an internet that catalyzes collaboration among diverse communities working together for the common good.

Over the last year, Mozilla has made significant progress in our efforts to ensure that all of our products and services are not only accessible, but a delight to use for people with disabilities.

  • We shipped full toolbar keyboard navigation for Firefox desktop which makes it possible for screen reader users and users who primarily use the keyboard to access all of Firefox’s most important features.
  • We delivered default page zoom and high contrast mode backplate, improving web page readability for people with low vision.
  • We shipped accessibility audits and a color deficiency simulator in the Firefox Dev Tools giving web developers more tools to make more accessible sites.
  • All new Firefox front end features, from a completely redesigned Awesome bar to Lockwise integration to picture-in-picture support, were accessible on day one of their release.
  • We made significant foundational progress onscreen reader support on Mac, the only platform for which Firefox lacked support.
  • We modernized and significantly improved support for Android accessibility services in Firefox Preview (our upcoming new mobile browser), including both Talkback and Switch Access.
  • We put in place a Firefox wide triage process for accessibility issues no matter where in the products they fall.
  • We publicly documented the Firefox Accessibility Roadmap and progress against major initiatives like screen reader support for Mac.
  • We moved much of our discussion to Matrix, allowing greater community participation and visibility.

And there’s more to come. We’re working to make the Firefox family of products and services a delightful experience for people with disabilities and we’re going to need your help. Stay tuned for upcoming posts on what we’re doing to be more inclusive and how you can participate.

The post Today is Global Accessibility Awareness Day! appeared first on Mozilla Accessibility.

Armen ZambranoMy pleasure!

My pleasure!

Mozilla VR BlogFirefox Reality 10

Firefox Reality 10

Our team has been hard at work on the latest version of Firefox Reality. In our last two versions, we had a heightened focus on performance and stability. With this release, fans of our browser on standalone VR headsets can enjoy the best of both worlds—a main course of in-demand features, with sides of performance and UI improvements. Firefox Reality 10 is a feature-packed release with something for every VR enthusiast.

But perhaps the most exciting news of this release is we’re releasing in conjunction with our new partner, Pico Interactive! We’re teaming up to bring the latest and greatest in VR browsing to Pico’s headsets, including the Neo 2 – an all-in-one (AIO) device with 6 degrees of freedom (DoF) head and controller tracking. Firefox Reality will be released and shipped with all Pico headsets. Learn more about what this partnership means here. And check out Firefox Reality in the Pico store.

Firefox Reality 10

What's New?

But what about all the exciting features we served up in this release, you might ask? Let’s dig in!

You Are Now Entering WebXR

Firefox Reality 10


Firefox Reality now supports WebXR! WebXR is the successor to the WebVR spec. It provides a host of improvements in cross-device functionality and tooling for both VR and AR applications. With WebXR, a site can support a wide variety of controller devices without writing support for each one individually.  WebXR takes care of choosing the right controls for actions such as selecting and grabbing objects.

You can get started right now using WebXR applications in Firefox Reality 10. If you’re looking for ways to get started building your own WebXR applications, take a look at the MDN Docs for the WebXR API.  And if you’re already working with Unity and want to explore developing WebXR  applications, check out our Unity WebXR Exporter.

Making the transition from WebVR to WebXR

We understand WebXR support among the most widely used browsers is fairly new and the community has largely been developing for WebVR until very recently. We want to help people to get to WebXR, but the vast majority of web content that is VR-enabled is WebVR content—twenty-five percent (25%) of our users consume WebVR content. Not to worry, we've got you covered.

This release also continues our support for WebVR, making Firefox Reality 10 the only standalone browser that supports both WebVR and WebXR experiences.

This will help our partners and developer community gracefully transition to WebXR without worrying that their audiences will lose functionality immediately. We will eventually deprecate WebVR. We’re currently working on a timeline for removing WebVR support,  but we’ll share that timeline with our community well in advance of any action.

Gaze Support

Another useful feature included in this release is gaze navigation support. This allows viewers to navigate within the browser without controllers, using only head movement and headset buttons. This is great for users who may not be able to use controllers, or  for use with headsets that don’t include controllers or allow you unbind controllers. See a quick demo of this feature on the Pico Neo 2 below. Here we’re able to scroll, select and type, all without the use of a physical controller.

Dual-controller typing

Many of us know how tedious it can be to type on a virtual keyboard with one controller. Additionally, one-hand typing may be counter-intuitive for those who are used to typing with two hands in most environments. With this version we’re introducing dual-controller typing to create a more natural keyboard experience.

Download Management

This version allows users to download files and manage previously downloaded files. Users can now view, sort and delete downloads without leaving the browser.

Firefox Reality 10

Enhanced Tracking Protection

At Mozilla, we always want to enable our users to take their privacy and security into their own hands. Our enhanced tracking protection makes users aware of potential privacy issues and allows users to fully control their privacy settings--from notifications of user activity tracking to our updated "Privacy and Security" UI.

Firefox Reality 10
Firefox Reality 10

These highlighted features, along with the many performance, DRM video playback and user experience improvements we’ve included make this a must-try release. Download it today in the Pico, HTC and Oculus app stores.

Contribute to Firefox Reality!

Firefox Reality is an open source project. We love hearing from and collaborating with our developer community. Check out Firefox Reality on GitHub and help build the open immersive web.

Mozilla Open Innovation TeamRedesigning Mozilla’s Contribute Page: A UX Overview

The previous Contribute page on Mozilla.org received around 100,000 views a month and had a 70% bounce rate.

For page engagements just over 1% of those viewers clicked on the “Get Involved” button, taking them to the Mozilla Activate page.

We wanted to change that.

We began this redesign project with a discovery phase. As a result of the strict environment the page would live in, all of our assumption testing had to be carried out through upfront discovery research as opposed to evaluative A/B testing post design.

We started to collate previous findings and analysis, drawing conclusions from past efforts like the Contribute Survey Analysis carried out in 2019.

With a broad idea of what visitors are looking for we looked internally with stakeholder interviews. A series of one to one remote meetings with Mozilla community staff were scheduled to uncover their hopes for a redesign and what they felt the current offering lacked. From this, two themes emerged:

  • A need to describe what the community and contribution look like.
  • Illustrating the breadth of volunteer opportunities.

The next exercise was to address the copy of the page. Using both analytics data and stakeholder feedback a series of “content blocks” were arranged to define what content we needed and the hierarchy it belonged in. A copywriter and marketing team member would review an initial draft however this was sufficient to populate wireframes for testing purposes.

Three wireframe layouts were produced, each putting slightly more emphasis on a different element of the page. One focused on telling a story, another focused on providing the widest volunteer entry points and the final layout was tasked with being direct and minimal.

<figcaption>The three wireframes we presented to interviewees</figcaption>

The Mozilla All Hands Event in Berlin was the perfect opportunity to gather some feedback from existing contributors. Both volunteers and staff were asked upfront questions about their expectations of a volunteer page before being presented with large printouts of each wireframe for review.

The community feedback was overwhelming with an emerging trend. “Story” was appreciated, however it was sufficient to know it was there “somewhere”. Conversely, volunteer opportunities needed to be clear and relatively upfront.

There was one additional research method we could utilise before casting some of our findings into design, remote unmoderated usability testing. With the ability to target participants with existing volunteer experience, we presented three wireframes to separate groups, again asking upfront questions on their expectations before revealing each design.

In three key ways the findings echoed the feedback of the All Hands interviews.

  1. An appreciation for a little upfront story, but not too much.
  2. An explicit, straight-talking tone was a clear preference.
  3. Volunteer opportunities should not be buried within the page.

Some additional findings revealed:

  • Participants liked to see the opportunities categorised as either Technical or Non Technical.
  • Participants were keen to understand the time and travel investment of each opportunity.

The feedback of the following research methods gave the team a shared vision of the final product before it had been designed:

  • Stakeholder interviews
  • User interviews
  • Guerilla usability testing
  • Unmoderated remote usability testing

Merging the copy approved content with Mozilla brand guidelines, a selection of designs were delivered and shared with the team for asynchronous feedback. After a final group call and some final tweaks we had our new Contribute page design ready for development.

<figcaption>The new Mozilla Contribute page</figcaption>

The page design pays various tributes to the Mozilla Community Portal, fitting, as both projects wish to serve Mozilla’s new and existing volunteer communities.

We will be monitoring the success of the page over time to determine the impact of the research-lead redesign. You can visit the new Contribute page on the Mozilla website, maybe you’ll discover something new about Mozilla when you get there!


Redesigning Mozilla’s Contribute Page: A UX Overview was originally published in Mozilla Open Innovation on Medium, where people are continuing the conversation by highlighting and responding to this story.

Hacks.Mozilla.OrgBuilding FunctionTrace, a graphical Python profiler

Firefox Profiler for performance analysis

Harald’s Introduction

Firefox Profiler became a cornerstone of Firefox’s performance work in the days of Project Quantum. When you open up an example recording, you first see a powerful web-based performance analysis interface featuring call trees, stack charts, flame graphs, and more. All data filtering, zooming, slicing, transformation actions are preserved in a sharable URL. You can share it in a bug, document your findings, compare it side-by-side with other recordings, or hand it  over for further investigation. Firefox DevEdition has a sneak peek of a built-in profiling flow that makes recording and sharing frictionless. Our goal is to empower all developers to collaborate on performance – even beyond Firefox.

Early on, the Firefox Profiler could import other formats, starting with Linux perf and Chrome’s profiles. More formats were added over time by individual developers. Today, the first projects are emerging that adopt Firefox for analysis tools. FunctionTrace is one of these, and here is Matt to tell the story of how he built it.

Meet FunctionTrace, a profiler for Python code

Matt’s Project

I recently built a tool to help developers better understand what their Python code is doing. FunctionTrace is a non-sampled profiler for Python that runs on unmodified Python applications with very low (<5%) overhead. Importantly, it’s integrated with the Firefox Profiler. This allows you to graphically interact with profiles, making it easier to spot patterns and make improvements to your codebase.

In this post, I’ll discuss why we built FunctionTrace, and share some technical details of its implementation. I’ll show how tools like this can target the Firefox Profiler as a powerful open-source visualization tool. To follow along, you can also play with a small demo of it!

Looking at a FunctionTrace profile

An example of a FunctionTrace profile opened in the Firefox Profiler.

Technical debt as motivation

Codebases tend to grow larger over time, especially when working on complex projects with many people. Some languages have great support for dealing with this, such as Java with its IDE capabilities built up over decades, or Rust with its strong type system that makes refactoring a breeze. Codebases in other languages sometimes seem to become increasingly less maintainable as they grow. This is particularly true in older Python codebases (at least we’re all on Python 3 now, right?).

It can be extremely difficult to make broad changes or refactor pieces of code you’re not familiar with. In contrast, I have a much easier time making correct changes when I’m able to see what a program is doing and all its interactions. Often, I even find myself making improvements to pieces of the code that I’d never intended to touch, as inefficiencies become glaringly obvious when presented on my screen.

I wanted to be able to understand what the Python codebases I work in were doing without needing to read through hundreds of files. I was unable to find existing tools for Python that were satisfactory, and I mostly lost interest in building a tool myself due the amount of UI work that would be necessary. However, when I stumbled across the Firefox Profiler, my hopes of quickly understanding a program’s execution were reignited.

The Profiler provided all of the “hard” pieces – an intuitive open-source UI that could display stack charts, time-correlated log markers, a flame graph, and the stability that comes from being tied to a major web browser. Any tool able to emit a properly-formatted JSON profile would be able to reuse all of the previously mentioned graphical analysis features.

Design of FunctionTrace

Luckily, I already had a week of vacation scheduled for a few days after I discovered the Firefox Profiler. I knew another friend who was interested in building it with me and also taking time off that week.

Goals

We had several goals when we started to build FunctionTrace:

  1. Give the ability to see everything occurring in the program.
  2. Handle multi-threaded/multi-process applications.
  3. Be low-overhead enough that we could use it without a performance tradeoff.

The first goal had a significant impact on the design, while the latter two added engineering complexity. From past experience with tools like this, we both knew the frustration of not being able to see function calls that are too short. When you’re sampling at 1ms but have important functions that run faster than that, you miss significant pieces of what’s occurring inside your program!

As a result, we knew we’d need to be able to trace all function calls and could not use a sampling profiler. Additionally, I’d recently spent time in a codebase where Python functions would exec other Python code (frequently via an intermediary shell script). From this, we knew we’d want to be able to also trace descendant Python processes.

Initial implementation

To support multiple processes and descendants, we settled on a client-server model. We’d instrument Python clients, which would send trace data to a Rust server. The server would aggregate and compress the data before generating a profile that could be consumed by the Firefox Profiler. We chose Rust for several reasons, including the strong type system, a desire for stable performance and predictable memory usage, and ease of prototyping and refactoring.

We prototyped the client as a Python module, called via python -m functiontrace code.py. This allowed us to easily use Python’s builtin tracing hooks to log what was executed. The initial implementation looked very similar to the following:

def profile_func(frame, event, arg):
    if event == "call" or event == "return" or event == "c_call" or event == "c_return":
        data = (event, time.time())
        server.sendall(json.dumps(data))

sys.setprofile(profile_func)

For the server, we listened on a Unix domain socket for client connections. Then we read data from the client and converted them into Firefox Profiler’s JSON format.

The Firefox Profiler supports various profile types, such as perf logs. However, we decided to emit directly to the Profiler’s internal format. It requires less space and maintenance than adding a new supported format. Importantly, the Firefox Profiler maintains backwards compatibility for profile versions. This means that any profile we emit targeting the current format version will be automatically converted to the latest version when loaded in the future. Additionally, the profiler format references strings by integer IDs. This allows significant space savings via deduplication (while being trivial to implement using indexmap).

A few optimizations

Generally, the initial base worked. On every function call/return Python would call our hook. The hook would then send a JSON message out over a socket for the server to convert into the proper format. However, it was incredibly slow. Even after batching the socket calls, we observed at least 8x overhead on some of our test programs!

At this point, we dropped down to C using Python’s C API instead. We got down to 1.1x overhead on the same programs. After that, we were able to do another key optimization by replacing calls to time.time() with rdtsc operations via clock_gettime(). We reduced the performance overhead for function calls to a few instructions and emitting 64 bits of data. This was much more efficient than having a chain of Python calls and complex arithmetic in the critical path.

I’ve mentioned that we support tracing multiple threads and descendant processes. Since this was one of the more difficult pieces of the client, it’s worth discussing some lower-level details.

Supporting multiple threads

We install a handler on all threads via threading.setprofile(). (Note: we register via a handler like this when we’re setting up our thread state to ensure that Python is running and the GIL is currently held. This allows us to simplify some assumptions.):

// This is installed as the setprofile() handler for new threads by
// threading.setprofile().  On its first execution, it initializes tracing for
// the thread, including creating the thread state, before replacing itself with
// the normal Fprofile_FunctionTrace handler.
static PyObject* Fprofile_ThreadFunctionTrace(..args..) {
    Fprofile_CreateThreadState();

    // Replace our setprofile() handler with the real one, then manually call
    // it to ensure this call is recorded.
    PyEval_SetProfile(Fprofile_FunctionTrace);
    Fprofile_FunctionTrace(..args..);
    Py_RETURN_NONE;
}

When our Fprofile_ThreadFunctionTrace() hook is called, it allocates a struct ThreadState, which contains information the thread will need to log events and communicate to the server. We then send an initial message to the profile server. Here we notify it that a new thread has started and provide some initial information (time, PID, etc). After this initialization, we replace the hook with Fprofile_FunctionTrace(), which does the actual tracing in the future.

Supporting descendant processes

When handling multiple processes, we make the assumption that children are being run via a python interpreter. Unfortunately, the children won’t be called with -m functiontrace, so we won’t know to trace them. To ensure that children processes are traced, on startup we modify the $PATH environment variable. In turn, this ensures python is pointing to an executable that knows to load functiontrace.

# Generate a temp directory to store our wrappers in.  We'll temporarily
# add this directory to our path.
tempdir = tempfile.mkdtemp(prefix="py-functiontrace")
os.environ["PATH"] = tempdir + os.pathsep + os.environ["PATH"]

# Generate wrappers for the various Python versions we support to ensure
# they're included in our PATH.
wrap_pythons = ["python", "python3", "python3.6", "python3.7", "python3.8"]
for python in wrap_pythons:
    with open(os.path.join(tempdir, python), "w") as f:
        f.write(PYTHON_TEMPLATE.format(python=python))
        os.chmod(f.name, 0o755)

Inside the wrappers, we simply need to call the real python interpreter with the additional argument of -m functiontrace. To wrap this support up, on startup we add an environment variable. The variable says what socket we’re using to communicate to the profile server. If a client initializes and sees this environment variable already set, it recognizes a descendant process. It then connects to the existing server instance, allowing us to correlate its trace with that of the original client.

Current implementation

The overall implementation of FunctionTrace today shares many similarities with the above descriptions. At a high level, the client is traced via FunctionTrace when invoked as python -m functiontrace code.py. This loads a Python module for some setups, then calls into our C module to install various tracing hooks. These hooks include the sys.setprofile hooks mentioned above, memory allocation hooks, and custom hooks on various “interesting” functions, like builtins.print or builtins.__import__. Additionally, we spawn a functiontrace-server instance, setup a socket for talking to it, and ensure that future threads and descendant processes will be talking to the same server.

On every trace event, the Python client emits a small MessagePack record. The record contains minimal event information and a timestamp to a thread-local memory buffer. When the buffer fills up (every 128KB), it is dumped to the server via a shared socket and the client continues to execute. The server listens asynchronously to each of the clients, quickly consuming their trace logs into a separate buffer to avoid blocking them. A thread corresponding to each client is then able to parse each trace event and convert it into the proper end format. Once all connected clients exit, the per-thread logs are aggregated into a full profile log. Finally, this is emitted to a file, which can then be used with the Firefox Profiler.

Lessons learned

Having a Python C module gives significantly more power and performance, but comes with costs. it requires more code, it’s harder to find good documentation; and few features are easily accessible. While C modules appear to be an under-utilized tool for writing high performance Python modules (based on some FunctionTrace profiles I’ve seen), we’d recommend a balance. Write most of the non-performance critical code in Python and call into inner loops or setup code in C, for the pieces where Python doesn’t shine.

JSON encoding/decoding can be incredibly slow when the human-readable aspect isn’t necessary. We switched to MessagePack for client-server communication and found it just as easy to work with while cutting some of our benchmark times in half!

Multithreading profiling support in Python is pretty hairy, so it’s understandable why it doesn’t seem to have been a key feature in previous mainstream Python profilers. It took several different approaches and many segfaults before we had a good understanding of how to operate around the GIL while maintaining high performance.

Please extend the profiler ecosystem!

This project wouldn’t have existed without the Firefox Profiler. It would’ve simply been too time-consuming to create a complex frontend for an unproven performance tool. We hope to see other projects targeting the Firefox Profiler, either by adding native support for the Profiler format like FunctionTrace did, or by contributing support for their own formats. While FunctionTrace isn’t entirely done yet, I hope sharing it on this blog can make other crafty developers aware of the Firefox Profiler’s potential. The Profiler offers a fantastic opportunity for some key development tooling to move beyond the command line and into a GUI that’s far better suited for quickly extracting relevant information.

The post Building FunctionTrace, a graphical Python profiler appeared first on Mozilla Hacks - the Web developer blog.

Daniel StenbergAI-powered code submissions

Who knows, maybe May 18 2020 will mark some sort of historic change when we look back on this day in the future.

On this day, the curl project received the first “AI-powered” submitted issues and pull-requests. They were submitted by MonocleAI, which is described as:

MonocleAI, an AI bug detection and fixing platform where we use AI & ML techniques to learn from previous vulnerabilities to discover and fix future software defects before they cause software failures.

I’m sure these are still early days and we can’t expect this to be perfected yet, but I would still claim that from the submissions we’ve seen so far that this is useful stuff! After I tweeted about this “event”, several people expressed interest in how well the service performs, so let me elaborate on what we’ve learned already in this early phase. I hope I can back in the future with updates.

Disclaimers: I’ve been invited to try this service out as an early (beta?) user. No one is saying that this is complete or that it replaces humans. I have no affiliation with the makers of this service other than as a receiver of their submissions to the project I manage. Also: since this service is run by others, I can’t actually tell how much machine vs humans this actually is or how much human “assistance” the AI required to perform these actions.

I’m looking forward to see if we get more contributions from this AI other than this first batch that we already dealt with, and if so, will the AI get better over time? Will it look at how we adjusted its suggested changes? We know humans adapt like that.

Pull-request quality

Monocle still needs to work on adapting its produced code to follow the existing code style when it submits a PR, as a human would. For example, in curl we always write the assignment that initializes a variable to something at declaration time immediately on the same line as the declaration. Like this:

int name = 0;

… while Monocle, when fixing cases where it thinks there was an assignment missing, adds it in a line below, like this:

int name;
name = 0;

I can only presume that in some projects that will be the preferred style. In curl it is not.

White space

Other things that maybe shouldn’t be that hard for an AI to adapt to, as you’d imagine an AI should be able to figure out, is other code style issues such as where to use white space and where not no. For example, in the curl project we write pointers like char * or void *. That is with the type, a space and then an asterisk. Our code style script will yell if you do this wrong. Monocle did it wrong and used it without space: void*.

C89

We use and stick to the most conservative ANSI C version in curl. C89/C90 (and we have CI jobs failing if we deviate from this). In this version of C you cannot mix variable declarations and code. Yet Monocle did this in one of its PRs. It figured out an assignment was missing and added the assignment in a new line immediately below, which of course is wrong if there are more variables declared below!

int missing;
missing = 0; /* this is not C89 friendly */
int fine = 0;

NULL

We use the symbol NULL in curl when we zero a pointer . Monocle for some reason decided it should use (void*)0 instead. Also seems like something virtually no human would do, and especially not after having taken a look at our code…

The first issues

MonocleAI found a few issues in curl without filing PRs for them, and they were basically all of the same kind of inconsistency.

It found function calls for which the return code wasn’t checked, while it was checked in some other places. With the obvious and rightful thinking that if it was worth checking at one place it should be worth checking at other places too.

Those kind of “suspicious” code are also likely much harder fix automatically as it will include decisions on what the correct action should actually be when checks are added, or perhaps the checks aren’t necessary…

Credits

Image by Couleur from Pixabay

Daniel Stenbergcurl ootw: –range

--range or -r for short. As the name implies, this option is for doing “range requests”. This flag was available already in the first curl release ever: version 4.0. This option requires an extra argument specifying the specific requested range. Read on the learn how!

What exactly is a range request?

Get a part of the remote resource

Maybe you have downloaded only a part of a remote file, or maybe you’re only interested in getting a fraction of a huge remote resource. Those are two situations in which you might want your internet transfer client to ask the server to only transfer parts of the remote resource back to you.

Let’s say you’ve tried to download a 32GB file (let’s call it a huge file) from a slow server on the other side of the world and when you only had 794 bytes left to transfer, the connection broke and the transfer was aborted. The transfer took a very long time and you prefer not to just restart it from the beginning and yet, with many file formats those final 794 bytes are critical and the content cannot be handled without them.

We need those final 794 bytes! Enter range requests.

With range requests, you can tell curl exactly what byte range to ask for from the server. “Give us bytes 12345-12567” or “give us the last 794 bytes”. Like this:

curl --range 12345-12567 https://example.com/

and:

curl --range -794 https://example.com/

This works with curl with several different protocols: HTTP(S), FTP(S) and SFTP. With HTTP(S), you can even be more fancy and ask for multiple ranges in the same request. Maybe you want the three sections of the resource?

curl --range 0-1000,2000-3000,4000-5000 https://example.com/

Let me again emphasize that this multi-range feature only exists for HTTP(S) with curl and not with the other protocols, and the reason is quite simply that HTTP provides this by itself and we haven’t felt motivated enough to implement it for the other protocols.

Not always that easy

The description above is for when everything is fine and easy. But as you know, life is rarely that easy and straight forward as we want it to be and nether is the --range option. Primarily because of this very important detail:

Range support in HTTP is optional.

It means that when curl asks for a particular byte range to be returned, the server might not obey or care and instead it delivers the whole thing anyway. As a client we can detect this refusal, since a range response has a special HTTP response code (206) which won’t be used if the entire thing is sent back – but that’s often of little use if you really want to get the remaining bytes of a larger resource out of which you already have most downloaded since before.

One reason it is optional for HTTP and why many sites and pages in the wild refuse range requests is that those sites and pages generate contend on demand, dynamically. If we ask for a byte range from a static file on disk in the server offering a byte range is easy. But if the document is instead the result of lots of scripts and dynamic content being generated uniquely in the server-side at the time of each request, it isn’t.

HTTP 416 Range Not Satisfiable

If you ask for a range that is outside of what the server can provide, it will respond with a 416 response code. Let’s say for example you download a complete 200 byte resource and then you ask that server for the range 200-202 – you’ll get a 416 back because 200 bytes are index 0-199 so there’s nothing available at byte index 200 and beyond.

HTTP other ranges

--range for HTTP content implies “byte ranges”. There’s this theoretical support for other units of ranges in HTTP but that’s not supported by curl and in fact is not widely used over the Internet. Byte ranges are complicated enough!

Related command line options

curl also offers the --continue-at (-C) option which is a perhaps more user-friendly way to resume transfers without the user having to specify the exact byte range and handle data concatenation etc.

This Week In RustThis Week in Rust 339

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.

Starting with this issue, there is now also a weekly This Week in Rust Podcast highlighting a few of the stories from each issue. You can check out the very first episode on The Rustacean Station.

Updates from Rust Community

News & Blog Posts

Crate of the Week

This week's crate is apply, a tiny library for chaining free functions into method call chains.

Thanks to Trevor Spiteri 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

359 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 last 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

Online
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

The whole motivation behind exceptions is to allow one to write ones business logic, concentrate on what one likes to think ones program will do, without having lots of fiddly error checking and handling code obscuring that logic. Error situations are therefore swept under the carpet with "try" and kept out of sight with "catch".

However in my world view failure is not exceptional, it is a common happening, it's too important to be hidden away. Therefor failure handling should be in ones face in the code you write. Certainly in the face of those that read it.

ZiCog on rust-users

Thanks to Lzutao for the suggestions!

Please submit quotes and vote for next week!

This Week in Rust is edited by: nellshamrell, llogiq, and cdmistman.

Discuss on r/rust.

François MarierHow to get a direct WebRTC connections between two computers

WebRTC is a standard real-time communication protocol built directly into modern web browsers. It enables the creation of video conferencing services which do not require participants to download additional software. Many services make use of it and it almost always works out of the box.

The reason it just works is that it uses a protocol called ICE to establish a connection regardless of the network environment. What that means however is that in some cases, your video/audio connection will need to be relayed (using end-to-end encryption) to the other person via third-party TURN server. In addition to adding extra network latency to your call that relay server might overloaded at some point and drop or delay packets coming through.

Here's how to tell whether or not your WebRTC calls are being relayed, and how to ensure you get a direct connection to the other host.

Testing basic WebRTC functionality

Before you place a real call, I suggest using the official test page which will test your camera, microphone and network connectivity.

Note that this test page makes use of a Google TURN server which is locked to particular HTTP referrers and so you'll need to disable privacy features that might interfere with this:

  • Brave: Disable Shields entirely for that page (Simple view) or allow all cookies for that page (Advanced view).

  • Firefox: Ensure that http.network.referer.spoofSource is set to false in about:config, which it is by default.

  • uMatrix: The "Spoof Referer header" option needs to be turned off for that site.

Checking the type of peer connection you have

Once you know that WebRTC is working in your browser, it's time to establish a connection and look at the network configuration that the two peers agreed on.

My favorite service at the moment is Whereby (formerly Appear.in), so I'm going to use that to connect from two different computers:

  • canada is a laptop behind a regular home router without any port forwarding.
  • siberia is a desktop computer in a remote location that is also behind a home router, but in this case its internal IP address (192.168.1.2) is set as the DMZ host.

Chromium

For all Chromium-based browsers, such as Brave, Chrome, Edge, Opera and Vivaldi, the debugging page you'll need to open is called chrome://webrtc-internals.

Look for RTCIceCandidatePair lines and expand them one at a time until you find the one which says:

  • state: succeeded (or state: in-progress)
  • nominated: true
  • writable: true

Then from the name of that pair (N6cxxnrr_OEpeash in the above example) find the two matching RTCIceCandidate lines (one local-candidate and one remote-candidate) and expand them.

In the case of a direct connection, I saw the following on the remote-candidate:

  • ip shows the external IP address of siberia
  • port shows a random number between 1024 and 65535
  • candidateType: srflx

and the following on local-candidate:

  • ip shows the external IP address of canada
  • port shows a random number between 1024 and 65535
  • candidateType: prflx

These candidate types indicate that a STUN server was used to determine the public-facing IP address and port for each computer, but the actual connection between the peers is direct.

On the other hand, for a relayed/proxied connection, I saw the following on the remote-candidate side:

  • ip shows an IP address belonging to the TURN server
  • candidateType: relay

and the same information as before on the local-candidate.

Firefox

If you are using Firefox, the debugging page you want to look at is about:webrtc.

Expand the top entry under "Session Statistics" and look for the line (should be the first one) which says the following in green:

  • ICE State: succeeded
  • Nominated: true
  • Selected: true

then look in the "Local Candidate" and "Remote Candidate" sections to find the candidate type in brackets.

Firewall ports to open to avoid using a relay

In order to get a direct connection to the other WebRTC peer, one of the two computers (in my case, siberia) needs to open all inbound UDP ports since there doesn't appear to be a way to restrict Chromium or Firefox to a smaller port range for incoming WebRTC connections.

This isn't great and so I decided to tighten that up in two ways by:

  • restricting incoming UDP traffic to the IP range of siberia's ISP, and
  • explicitly denying incoming to the UDP ports I know are open on siberia.

To get the IP range, start with the external IP address of the machine (I'll use the IP address of my blog in this example: 66.228.46.55) and pass it to the whois command:

$ whois 66.228.46.55 | grep CIDR
CIDR:           66.228.32.0/19

To get the list of open UDP ports on siberia, I sshed into it and ran nmap:

$ sudo nmap -sU localhost

Starting Nmap 7.60 ( https://nmap.org ) at 2020-03-28 15:55 PDT
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000015s latency).
Not shown: 994 closed ports
PORT      STATE         SERVICE
631/udp   open|filtered ipp
5060/udp  open|filtered sip
5353/udp  open          zeroconf

Nmap done: 1 IP address (1 host up) scanned in 190.25 seconds

I ended up with the following in my /etc/network/iptables.up.rules (ports below 1024 are denied by the default rule and don't need to be included here):

# Deny all known-open high UDP ports before enabling WebRTC for canada
-A INPUT -p udp --dport 5060 -j DROP
-A INPUT -p udp --dport 5353 -j DROP
-A INPUT -s 66.228.32.0/19 -p udp --dport 1024:65535 -j ACCEPT

The Firefox FrontierWe got your back-ground

A lot of us are spending more time collaborating on video conferences whether it’s for school, work or personal time. More time on video means a lot more opportunities for … Read more

The post We got your back-ground appeared first on The Firefox Frontier.

Firefox UXDesigning a content-first experience on Firefox Monitor

Image of Firefox Monitor logo

Six methods a UX content strategist at Firefox used during the product’s redesign.

As a UX content strategist at Mozilla, I support not only our browsers, but also stand alone products like Firefox Monitor. It’s a service that notifies you when you’ve been in a data breach and what steps to take to protect your personal info.

Designing content for a product that delivers bad news presents unique challenges. Data breaches are personal. They can be stressful. Sometimes the information exposed can be sensitive. How we organize, structure, and surface content in Firefox Monitor matters.

When we had the opportunity to redesign the end-to-end experience, content strategy played a key role. I identified ways our users were struggling with the current site, then worked in collaboration with interaction designer Ryan Gaddis to re-architect and design a new experience. These are a few of the tools and methods I leveraged.

About Firefox Monitor

Screenshot of the desktop version of the Firefox Monitor website, which prompts users to enter their email address and check for breaches.

Enter your email address to see if you’ve been part of an online data breach, then sign up for ongoing alerts about new breaches.

The goal of Firefox Monitor is to help people take back control of their personal data so they can protect their digital identity and feel safer online. When we first introduced Monitor to the world, our goal was 10,000 subscribers. Within six weeks, over 200,000 people had signed up.

As subscriptions continued climbing, the constraints of the MVP experience challenged our users and our ability to serve them. The one-page website offered the same generic recommendations to all visitors, regardless of the breach. It was complicated to add new functionality. We sought to create a more flexible platform that would better serve our users and our own business goals.

A year after the redesign launched, Monitor has 8 million subscribers and counting. The website is localized into 34 languages, making it free and accessible to as many people globally as possible.

1. Listen intently to user problems to identify areas for improvement

A side-by-side comparison of before and after of breach alert emails users receive.

Users are notified via email when their information appears in a new data breach. Culling through the replies to these emails helped us understand user pain points.

If you’re tasked with improving the user experience of an existing experience, listening to current users’ pain points is a great place to start. You can do this even if you don’t have direct access to those users. I culled through hundreds of user replies to automated emails.

When a data breach becomes public, Monitor alerts affected users via email. People replied to those email alerts with questions, concerns, and comments.

I reviewed these emails and grouped them into themes to identify trends.

  • Users weren’t sure what to do to resolve a breach.
  • They didn’t recognize the name of the breached site.
  • They were confused by the length of time it took to be notified.
  • They found language too jargony or confusing.
  • They weren’t sure who was responsible for the breach.

These were all helpful inputs to drive the information architecture and content decisions for improving the Firefox Monitor experience. We kept these pain points top of mind, working to ensure that the answers to these questions were proactively provided.

2. Run a usability test to learn what’s tripping people up

Screenshot of previous website, which leads with the headline “Your right to be safe from hackers starts here.”

In the usability study, participants misunderstood what Monitor did. They thought the service might protect against a variety of threats, such as against viruses, phishing, or unsafe websites.

When you’re immersed in the redesign of an experience, it’s impossible to know how it will be perceived by someone who experiences it for the first time. You simply know too much about how all the plumbing works. Usability testing provides valuable insight to uncover those blind spots.

Yixin Zou, a PhD student at the University of Michigan School of Information, led a usability study on the current experience. I observed all these sessions, taking notes on what could inform content and design improvements.

What mental models about data breaches and privacy did participants have? What were they confused about? In their own words, how did they describe what was happening and how they felt?

For example, we learned that the homepage copy was a bit too broad. Some users wondered if Monitor could protect them from phishing attempts, viruses, or visiting unsafe sites. In response, I tightened the focus on data breaches so people understood exactly what Monitor could do for them.

A side-by-side comparison of the Firefox Monitor homepage before and after the redesign.

The redesign reduced the amount of content and clarified the purpose of Firefox Monitor.

3. Re-architect content hierarchy to reduce cognitive load

A side-by-side comparison of breach results before and after the redesign.

The new experience reduces the cognitive load for users through improved content hierarchy. We also removed less critical content on first view so it would be easier for users to identify which breaches were most concerning to them.

Firefox Monitor delivers stressful news. You may learn that your personal data has been exposed in many breaches. The compromised account might be one you signed up for a decade ago. Or, you may have signed up for an account that has since been sold or acquired by another company you don’t recognize.

As user experience practitioners, it’s our job to consider these stress cases. We can’t eliminate the anxiety of the situation, but we can make the information about it as easy to parse as possible.

Usability testing helped us realize how overwhelming it could be to see a full list of past breaches at once. People didn’t know where to start. There was simply too much information on one screen.

Lead with the most relevant information

Getting to the point is the kindest thing we can do. Since many users check multiple email addresses for breaches, we now lead with the email and number of reported breaches.

Remove total number of compromised accounts

Some breaches affect millions of accounts. Those large numbers added complexity and are not relevant to you. Users are concerned about the impact on their own data — not what happened to millions of other people.

House more detailed information one layer deeper

Some breaches expose dozens of different types of data. When all compromised data for all breaches was displayed on a single page, it was too much to take in. Creating more detailed breach pages allowed us to simplify the report view, making it more scannable and digestible.

Screenshot of a breach detail page, localized into French.

To reduce cognitive load and help users parse information about each breach, we introduced a dedicated page for every single breach.

 

4. Collaborate with design and engineering to increase impact

Mobile wireframe of the Firefox Monitor homepage.

We avoided lorem ipsum and built out mobile-first wireframes with real copy.

Improving the user experience was a collaborative effort. Interaction designer Ryan Gaddis and I worked together to define the messaging goals and user needs. Though each of us brought different skills to the table, we welcomed each other’s feedback to make the end product better. We were able to avoid lorem ipsum throughout the entire design process.

Together, we designed the new mobile-first experience. This encouraged us to keep our design and content focused. Throughout multiple rounds of wireframes, I wrote multiple iterations of copy.

Co-designing in this way also allowed us to execute more quickly. By the time the website was ready for visual application and front-end development, most of the hard content problems had already been solved.

As the wireframes came together, we brought engineering into the conversation. This helped us understand what was feasible from a technical perspective. We were able to make adjustments based on engineering’s early input. The development process moved more quickly because engineering had early visibility into the design and content thinking.

5. Validate the appropriate tone to engage users

Table displaying neutral, positive, and negative variants of tone.

Examples of neutral, positive, and negative variants of tone we tested.

At Firefox, we’re committed to making the web open and accessible to all. We want people to engage with the web, not be scared off by it.

In our privacy and security products, we must call out risks and inform users of threats. But we are thoughtful with our tone. Scare tactics are cheap shots. We don’t take them. Instead, we provide measured facts. We want to earn users’ trust while educating and empowering them to better protect themselves online.

To validate that our tone was appropriate, I worked again with PhD student Yixin Zou to design a tone variants study. I wrote neutral, positive, and negative variants of protective actions Firefox Monitor recommends.

Neutral

→ Showing what the action is about and the high-level steps required to take the action.
→ Does not emphasize benefits or risks.

Positive

→ Empowering, encouraging, friendly.
→ Emphasizing benefits of taking action. Try to make these actions simple and easy.

Negative

→ Forbidding, warning.
→ Emphasizing risks of not taking action. Try to make these actions urgent and necessary.

We discovered that the negative tone did little to improve comprehension or willingness to take action. This validated our current course of action: to be direct, positive, and encouraging.

Here’s an example of what that content looks like in practice on the Monitor site.

Screenshot of passwords recommendations on the Firefox Monitor website.

These are the steps we recommend users take to keep their personal info safe and to protect their digital identity.

6. Bring legal and localization into the process

Examples of English, French, and German alerts that appear on sites where breaches have occurred.

If you visit a site that’s been breached, Firefox will direct you to Monitor to check to see if your information was compromised.

Legal and localization are key partners in the content strategy process. They need to have visibility into the work we do and have the opportunity to provide feedback so we can course-correct if needed.

The privacy and security space presents legal risk. Even though these data breaches are publicly known, companies aren’t always happy to get extra attention from Monitor. We also need to be careful that Monitor doesn’t over-promise its capabilities. Michael Feldman, our in-house product counsel, helps us ensure our content considers legal implications without reading like confusing legalese jargon.

Firefox Monitor is also localized into 34 languages. Our global community of localizers from all over the world help us extend the reach of Firefox Monitor. We strive to avoid US-centric jargon, phrasing, and figures of speech. We work with our localization project manager, Francesco Lodolo, to identify problematic language and sentence construction before it’s sent to localizers.

Wrapping up

Content strategy never works alone. We collaborate cross-functionally to deliver experiences that are useful and appropriate. The words you see on the page are one tangible output, but most of the work is done behind-the-scenes to drive the UX strategy.

The product continues to evolve as we look for more opportunities to help our users protect their online digital selves. To monitor known data breaches for your personal info, head to Firefox Monitor to sign up.

Acknowledgements

Thank you to Tony Cinotto, Luke Crouch, Jennifer Davidson, Peter DeHaan, Michael Feldman, Ryan Gaddis, Michelle Heubusch, Wennie Leung, Francesco Lodolo, Bob Micheletto, Lesley Norton, Cherry Park, Sandy Sage, Joni Savage, Nihanth Subramanya, Philip Walmsley, Yixin Zhou, and the entire Mozilla localization community for your contributions to Firefox Monitor. And thanks to Meridel Walkington for your editing help.

Data@MozillaSharing data on Italy’s mid-pandemic internet outage

As a data engineer at Mozilla, my colleagues and I study how internet connectivity changes over time and across regions. Like inclement weather, network outages are simply a fact of life: equipment that powers the internet can fail for numerous reasons in any country. As we know from reports of internet shutdowns and throttling by governments in different parts of the world, sometimes outages can also be intentional. But in terms of data, Mozilla measures outages and connection issues through a series of different metrics, including telemetry upload failures.

Today, we are releasing an aggregate open dataset (italy_covid19_outage) to show what one example of an outage looks like.

In Italy, for several hours on March 11, 2020 – just days after a nationwide COVID-19 lockdown was declared – life on the internet came to a partial halt for a portion of the country. From news reports (1, 2) we know that one of the biggest Italian internet service providers, TIM, experienced an internet outage. Many customers of the ISP were unable to use a number of applications requiring network connectivity, and many websites were unreachable.

As someone living in a small town in Italy, I experienced firsthand the anxiety of losing my connection to the internet in the middle of the pandemic. When out stocking up at the pharmacy a few days after the lockdown was declared, I tried to reach out to my wife over the phone. She wasn’t picking up, so I messaged her over WhatsApp. That didn’t work either. I tried to video call, and that failed. Because my wife’s phone was connected to our WiFi router at home, and due to the technical details of our setup, the outage brought down most of the connectivity on her phone without her noticing.

So what happened in Italy, exactly? TIM released a statement to the press mentioning “a failure on a “foreign network” resulting in some websites and apps hosted abroad to be unavailable. Because of that failure, people like me experienced congestion on the internet – as though suddenly hitting traffic on a highway that is normally clear. In my case, it wasn’t that WhatsApp was down. It was that the VPN at my house stopped working properly due to connectivity issues, leaving me feeling isolated at the pharmacy during a tense moment.

In a crisis like this one, any internet outage can be truly unsettling. It adds an edge to the anxiety we may already be experiencing. As the COVID-19 pandemic is forcing entire countries to lock down and practice social distancing, the internet offers people around the world the comfort to stay connected. At Mozilla, we have witnessed this firsthand: our telemetry from the Firefox browser shows how more people are spending far more time online.

Mozilla can measure outages and connection issues through telemetry upload failures – we send small amounts of telemetry called “health ping” that report errors in uploading our normal telemetry data, but does not identify the users who have contributed this information. You can think of this small amount of data as a motorcycle on a congested highway, weaving between cars stuck in traffic. If there is an internet congestion that keeps WhatsApp or Facebook from working properly, for instance, the health pings sent to our servers often still get through, giving us information about whether the browser has connectivity issues.

In Italy on March 11, we can see clear signals that Firefox users experienced an increase of network timeouts. This means a device sent a request to a server, and waited beyond what the browser allows, meaning the server didn’t respond in a timely fashion.

This is how it looked on our systems:

Network Outage in Italy during the COVID-19 lockdown

The series in the graph represent two reasons why network connections to Mozilla’s telemetry server failed (see detailed description below). For example, on March 11, we saw a sharp increase in reported “timeouts” (up to ~6%), and terminated connections (up to ~11%). As it happens, this wasn’t the only date with disruptions in Italy. We detected two other spikes in terminated connections, one in January and one in February, which is consistent with reports from the crowdsourced site Downdetector.it.

The outage data

The data we are releasing today includes aggregated Firefox Desktop data for Italy from the “health” ping and some fields of the “main” ping that were created between January 1, 2020 up until March 31, 2020. To make all of this possible while respecting the privacy of our users, all of our metrics go through an extensive public data-review process before collection. Moreover, the different types of failures are aggregated by day. These counts are then normalized by the total number of active daily users, and this gives an indication of how broadly a network problem is affecting a larger percentage of Firefox desktop clients. To further make aggregates safer, days for which there are less than 5,000 samples are discarded and not reported.

The code used to produce this data lives here. The metadata and caveats for the dataset are accessible from here (italy_covid19_outage).

Questions or feedback about the data can be directed to publicdata@mozilla.com, and press inquiries to press@mozilla.com.

Acknowledgements

This article was written in collaboration with Saptarshi Guha, Solana Larsen, Jochai Ben-Avie, Hamilton Ulmer. Thanks to Chris Hutten-Czapski, Jesse McCrosky, Jeff Klukas, Mark Reid and others for reviewing the initial investigation queries and to Anna Scholtz for the help with the dataset generation. And to Andrea Marchesini, for help navigating the Firefox network code and explaining the behaviour of each failure type.

Daniel StenbergHelp curl: the user survey 2020

The annual curl user survey is up. If you ever used curl or libcurl during the last year, please consider donating ten minutes of your time and fill in the question on the link below!

[no longer open]

The survey will be up for 14 days. Please share this with your curl-using friends as well and ask them to contribute. This is our only and primary way to find out what users actually do with curl and what you want with it – and don’t want it to do!

The survey is hosted by Google forms. The curl project will not track users and we will not ask who you are (and than some general details to get a picture of curl users in general).

The analysis from the 2019 survey is available.

Marco ZeheThe focus of this blog is changing

Recently, Mozilla introduced an official blog about all things accessibility. This blog is transitioning to a pure personal journal.

For years, this blog was a mixed bag between information about my official work at Mozilla and my personal views on accessibility. Now that Mozilla has its own accessibility blog, my personal blog at this space will contain less work-related material and more personal views on the broader subject of accessibility. I am also co-authoring the Mozilla accessibility blog, and will continue to inform the community about our work there. But this blog here will no longer receive such updates unless I find something personally noteworthy.

So, if you continue to follow this blog, I promise no duplicated content. If you are interested about what‘s happening at Mozilla, the new official source is linked above, and it also has an RSS feed to follow along.

Tantek Çelik🎂 This Week in the IndieWeb celebrates six years of weekly newsletters! 🎉

This week (no pun intended), the IndieWeb community’s “This Week in the IndieWeb” turned 6!

First published on 2014-05-12, the newsletter started as a fully-automatically generated weekly summary of activity on the IndieWeb’s community wiki: a list of edited and new pages, followed by the full content of the new pages, and then the recent edit histories of pages changed that week.

Since then the Newsletter has grown to include photos from recent events, the list of upcoming events, recent posts about the IndieWeb syndicated to the IndieNews aggregator, new community members (and their User pages), and a greatly simplified design of new & changed pages.

You can subscribe to the newsletter via email, RSS, or h-feed in your favorite Reader.

This week we also celebrated:

See the Timeline page for more significant events in IndieWeb community history.

Armen ZambranoTreeherder developer ergonomics

In the last few months I’ve worked with contributors who wanted to be selected to work on Treeherder during this year’s Google Summer of Code. The initial proposal was to improve various Treeherder developer ergonomics (read: make Treeherder development easier). I’ve had three very active contributors that have helped to make a big difference (in alphabetical order): Shubham, Shubhank and Suyash.

In this post I would like to thank them publicly for all the work they have accomplished as well as list some of what has been accomplished. There’s also listed some work from Kyle who tackled the initial work of allowing normal Python development outside of Docker (more about this later).

After all, I won’t be participating in GSoC due to burn-out and because this project is mostly completed (thanks to our contributors!). Nevertheless, two of the contributors managed to get selected to help with Treeherder (Suyash) and Firefox Accounts (Shubham) for GSoC. Congratulations!

Some of the developer ergonomics improvements that landed this year are:

  • Support running Treeherder & tests outside of Docker. Thanks to Kyle we can now set up a Python virtualenv outside of Docker and interact with all dependent services (mysql, redis and rabbitmq). This is incredibly useful to run tests and the backend code outside of Docker and to help your IDE install all Python packages in order to better analyze and integrate with your code (e.g., add breakpoints from your IDE). See PR here.
  • Support manual ingestion of data. Before, you could only ingest data when you would set up the Pulse ingestion. This mean that you could only ingest real-time data (and all of it!) and you could not ingest data from the past. Now, you can ingest pushes, tasks and even Github PRs. See documentation.
  • Add pre-commit hooks to catch linting issues. Prior to this, linting issues would require you to remember to run a script with all the linters or Travis to let you know. You can now get the linters to execute automatically on modified files (instead of all files in the repo), shortening the linting-feedback cycle. See hooks in pre-commit file
  • Use Poetry to generate the docs. Serving locally the Treeherder docs is now as simple as running “poetry install && poetry run mkdocs serve.” No more spinning up Docker containers or creating and activating virtualenvs. We also get to introduce Poetry as a modern dependency and virtualenv manager. See code in pyproject.toml file
  • Automatic syntax formatting. The black pre-commit hook now formats files that the developer touches. No need to fix the syntax after Travis fails with linting issues.
  • Ability to run the same tests as Travis locally. In order to reduce differences between what Travis tests remotely and what we test locally, we introduced tox. The Travis code simplifies, the tox code can even automate starting the Docker containers and it removed a bash script that was trying to do what tox does (Windows users cannot execute bash scripts).
  • Share Pulse credentials with random queue names. In the past we required users to set up an account with Pulse Guardian and generate their own PULSE_URL in order to ingest data. Last year, Dustin gave me the idea that we can share Pulse credentials; however, each consumer must ingest from dynamically generated queue names. This was initially added to support Heroku Review Apps, however, this works as well for local consumers. This means that a developer ingesting data would not be taking away Pulse messages from the queue of another developer.
  • Automatically delete Pulse queues. Since we started using shared credentials with random queue names, every time a developer started ingesting data locally it would leave some queues behind in Pulse. When the local consumers stopped, these queues would overgrow and send my team and I alerts about it. With this change, the queues would automatically be destroyed when the consumers ceased to consume.
  • Docker set up to automatically ingest data. This is useful since ingesting data locally required various steps in order to make it work. Now, the Docker set up ingests data without manual intervention.
  • Use pip-compile to generate requirement files with hashes. Before, when we needed to update or add a Python package, we also had to add the hashes manually. With pip-compile, we can generate the requirement files with all hashes and subdepencies automatically. You can see the documentation here.

There’s many more changes that got fixed by our contributors, however, I won’t cover all of them. You can see the complete list in here.

Thank you for reading this far and thanks again to our contributors for making development on Treeherder easier!

The Firefox FrontierRelaxing video series brings serenity to your day

Sitting in front of a computer all day (and getting caught up in the never-ending bad news cycle) can be draining. And if you happen to be working from home, … Read more

The post Relaxing video series brings serenity to your day appeared first on The Firefox Frontier.

Support.Mozilla.OrgMoving SUMO Community synchronous communications to Matrix

TL;DR: We are moving our Telegram group to the new Mozilla Matrix [https://chat.mozilla.org/#/room/#SUMO:mozilla.org]. Both systems are currently bridged but the Telegram group will be decommissioned on 30 May 2020. Please check the instructions on how to join the new system.

 

Dear SUMO Community,

As some of you already know, Mozilla has been working for some time to replace its official synchronous communication tool, and earlier this year we decided to launch our own Matrix instance to host our public conversations.

In SUMO, we historically maintained a Telegram group to enable synchronous communications, and now we want to transition it to the new Mozilla Matrix.

Which problems are we trying to solve?

  • You need to create an independent account to use Telegram, you can’t reuse your existing Mozilla account or use Firefox Accounts to authenticate or integrate it with Mozilla’s systems.
  • Telegram moderation tools do not allow a centralized Mozilla team to enforce our guidelines on groups or users across all channels.
  • Data is stored in a third party organization.
  • Private groups/conversations are not end-to-end encrypted by default and can be accessed by the provider.
  • The system is a silo that can’t be discovered/accessed from other Mozilla systems.

Why is Matrix a good solution?

  • 🧐 Visibility: Mozilla owns the server and data, you can use your existing Mozilla account to log-in. Linked from various Mozilla systems.
  • 🧭 Discoverability: Rooms can be easily discovered by other mozillians and people using the Matrix network.
  • 🏠 Feel at home: A lot of other Mozilla projects, volunteers, and employees are already actively collaborating on the new system.
  • 🔐 Safety: Community Participation Guidelines are enforceable through its moderation tooling, support for end-to-end encryption on private conversations.
  • 📜 Mission aligned: Decentralized protocol, both server and client code is open source.
  • 👨‍💻👩‍💻 Tech-friendly: Extensible & integrable via diverse clients, bridges, and bots.

Timeline

  • 27 March 2020: Telegram group is bridged to the new room over Matrix. People can start reading messages from both sides.
  • 15 May 2020: Community announcement about the full-transition
  • 15-30 May 2020: Reminders and support for people to start using the new system
  • 30 May 2020: Telegram group decommission.

How do I join?

Mozilla Wiki has a great page explaining how to join the new system, please check it out. You’ll find instructions on how to access from the web, desktop app or mobile.

Direct link to join our SUMO Matrix room 

[https://chat.mozilla.org/#/room/#SUMO:mozilla.org]

 

On top of this room, we also have the following room for our sub-community:

 

Please, help us spread the announcement to all community members and support them during this transition. Feel free to add any questions on this topic.

Thanks, everyone!

The Rust Programming Language BlogFive Years of Rust

With all that's going on in the world you'd be forgiven for forgetting that as of today, it has been five years since we released 1.0! Rust has changed a lot these past five years, so we wanted to reflect back on all of our contributors' work since the stabilization of the language.

Rust is a general purpose programming language empowering everyone to build reliable and efficient software. Rust can be built to run anywhere in the stack, whether as the kernel for your operating system or your next web app. It is built entirely by an open and diverse community of individuals, primarily volunteers who generously donate their time and expertise to help make Rust what it is.

Major Changes since 1.0

2015

1.2 — Parallel Codegen: Compile time improvements are a large theme to every release of Rust, and it's hard to imagine that there was a short time where Rust had no parallel code generation at all.

1.3 — The Rustonomicon: Our first release of the fantastic "Rustonomicon", a book that explores Unsafe Rust and its surrounding topics and has become a great resource for anyone looking to learn and understand one of the hardest aspects of the language.

1.4 — Windows MSVC Tier 1 Support: The first tier 1 platform promotion was bringing native support for 64-bit Windows using the Microsoft Visual C++ toolchain (MSVC). Before 1.4 you needed to also have MinGW (a third party GNU environment) installed in order to use and compile your Rust programs. Rust's Windows support is one of the biggest improvements these past five years. Just recently Microsoft announced a public preview of their official Rust support for the WinRT API! Now it's easier than ever build top quality native and cross platform apps.

1.5 — Cargo Install: The addition of being able to build Rust binaries alongside cargo's pre-existing plugin support has given birth to an entire ecosystem of apps, utilities, and developer tools that the community has come to love and depend on. Quite a few of the commands cargo has today were first plugins that the community built and shared on crates.io!

2016

1.6 — Libcore: libcore is a subset of the standard library that only contains APIs that don't require allocation or operating system level features. The stabilization of libcore brought the ability to compile Rust with no allocation or operating system dependency was one of the first major steps towards Rust's support for embedded systems development.

1.10 — C ABI Dynamic Libraries: The cdylib crate type allows Rust to be compiled as a C dynamic library, enabling you to embed your Rust projects in any system that supports the C ABI. Some of Rust's biggest success stories among users is being able to write a small critical part of their system in Rust and seamlessly integrate in the larger codebase, and it's now easier than ever.

1.12 — Cargo Workspaces: Workspaces allow you to organise multiple rust projects and share the same lockfile. Workspaces have been invaluable in building large multi-crate level projects.

1.13 — The Try Operator: The first major syntax addition was the ? or the "Try" operator. The operator allows you to easily propagate your error through your call stack. Previously you had to use the try! macro, which required you to wrap the entire expression each time you encountered a result, now you can easily chain methods with ? instead.

try!(try!(expression).method()); // Old
expression?.method()?;           // New

1.14 — Rustup 1.0: Rustup is Rust's Toolchain manager, it allows you to seamlessly use any version of Rust or any of its tooling. What started as a humble shell script has become what the maintainers affectionately call a "chimera". Being able to provide first class compiler version management across Linux, macOS, Windows, and the dozens of target platforms would have been a myth just five years ago.

2017

1.15 — Derive Procedural Macros: Derive Macros allow you to create powerful and extensive strongly typed APIs without all the boilerplate. This was the first version of Rust you could use libraries like serde or diesel's derive macros on stable.

1.17 — Rustbuild: One of the biggest improvements for our contributors to the language was moving our build system from the initial make based system to using cargo. This has opened up rust-lang/rust to being a lot easier for members and newcomers alike to build and contribute to the project.

1.20 — Associated Constants: Previously constants could only be associated with a module. In 1.20 we stabilised associating constants on struct, enums, and importantly traits. Making it easier to add rich sets of preset values for types in your API, such as common IP addresses or interesting numbers.

2018

1.24 — Incremental Compilation: Before 1.24 when you made a change in your library rustc would have to re-compile all of the code. Now rustc is a lot smarter about caching as much as possible and only needing to re-generate what's needed.

1.26 — impl Trait: The addition of impl Trait gives you expressive dynamic APIs with the benefits and performance of static dispatch.

1.28 — Global Allocators: Previously you were restricted to using the allocator that rust provided. With the global allocator API you can now customise your allocator to one that suits your needs. This was an important step in enabling the creation of the alloc library, another subset of the standard library containing only the parts of std that need an allocator like Vec or String. Now it's easier than ever to use even more parts of the standard library on a variety of systems.

1.31 — 2018 edition: The release of the 2018 edition was easily our biggest release since 1.0, adding a collection of syntax changes and improvements to writing Rust written in a completely backwards compatible fashion, allowing libraries built with different editions to seamlessly work together.

  • Non-Lexical Lifetimes A huge improvement to Rust's borrow checker, allowing it to accept more verifiable safe code.
  • Module System Improvements Large UX improvements to how we define and use modules.
  • Const Functions Const functions allow you to run and evaluate Rust code at compile time.
  • Rustfmt 1.0 A new code formatting tool built specifically for Rust.
  • Clippy 1.0 Rust's linter for catching common mistakes. Clippy makes it a lot easier to make sure that your code is not only safe but correct.
  • Rustfix With all the syntax changes, we knew we wanted to provide the tooling to make the transition as easy as possible. Now when changes are required to Rust's syntax they're just a cargo fix away from being resolved.
2019

1.34 — Alternative Crate Registries: As Rust is used more and more in production, there is a greater need to be able to host and use your projects in non-public spaces, while cargo has always allowed remote git dependencies, with Alternative Registries your organisation can easily build and share your own registry of crates that can be used in your projects like they were on crates.io.

1.39 — Async/Await: The stabilisation of the async/await keywords for handling Futures was one of the major milestones to making async programming in Rust a first class citizen. Even just six months after its release async programming in Rust has blossomed into a diverse and performant ecosystem.

2020

1.42 — Subslice patterns: While not the biggest change, the addition of the .. (rest) pattern has been a long awaited quality of life feature that greatly improves the expressivity of pattern matching with slices.

Error Diagnostics

One thing that we haven't mentioned much is how much Rust's error messages and diagnostics have improved since 1.0. Looking at older error messages now feels like looking at a different language.

We’ve highlighted a couple of examples that best showcase just how much we’ve improved showing users where they made mistakes and importantly help them understand why it doesn’t work and teach them how they can fix it.

First Example (Traits)
use std::io::Write;

fn trait_obj(w: &Write) {
    generic(w);
}

fn generic<W: Write>(_w: &W) {}
1.2.0 Error Message
   Compiling error-messages v0.1.0 (file:///Users/usr/src/rust/error-messages)
src/lib.rs:6:5: 6:12 error: the trait `core::marker::Sized` is not implemented for the type `std::io::Write` [E0277]
src/lib.rs:6     generic(w);
                 ^~~~~~~
src/lib.rs:6:5: 6:12 note: `std::io::Write` does not have a constant size known at compile-time
src/lib.rs:6     generic(w);
                 ^~~~~~~
error: aborting due to previous error
Could not compile `error-messages`.

To learn more, run the command again with --verbose.

A terminal screenshot of the 1.2.0 error message.

1.43.0 Error Message
   Compiling error-messages v0.1.0 (/Users/ep/src/rust/error-messages)
error[E0277]: the size for values of type `dyn std::io::Write` cannot be known at compilation time
 --> src/lib.rs:6:13
  |
6 |     generic(w);
  |             ^ doesn't have a size known at compile-time
...
9 | fn generic<W: Write>(_w: &W) {}
  |    ------- -       - help: consider relaxing the implicit `Sized` restriction: `+  ?Sized`
  |            |
  |            required by this bound in `generic`
  |
  = help: the trait `std::marker::Sized` is not implemented for `dyn std::io::Write`
  = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `error-messages`.

To learn more, run the command again with --verbose.

A terminal screenshot of the 1.43.0 error message.

Second Example (help)
fn main() {
    let s = "".to_owned();
    println!("{:?}", s.find("".to_owned()));
}
1.2.0 Error Message
   Compiling error-messages v0.1.0 (file:///Users/ep/src/rust/error-messages)
src/lib.rs:3:24: 3:43 error: the trait `core::ops::FnMut<(char,)>` is not implemented for the type `collections::string::String` [E0277]
src/lib.rs:3     println!("{:?}", s.find("".to_owned()));
                                    ^~~~~~~~~~~~~~~~~~~
note: in expansion of format_args!
<std macros>:2:25: 2:56 note: expansion site
<std macros>:1:1: 2:62 note: in expansion of print!
<std macros>:3:1: 3:54 note: expansion site
<std macros>:1:1: 3:58 note: in expansion of println!
src/lib.rs:3:5: 3:45 note: expansion site
src/lib.rs:3:24: 3:43 error: the trait `core::ops::FnOnce<(char,)>` is not implemented for the type `collections::string::String` [E0277]
src/lib.rs:3     println!("{:?}", s.find("".to_owned()));
                                    ^~~~~~~~~~~~~~~~~~~
note: in expansion of format_args!
<std macros>:2:25: 2:56 note: expansion site
<std macros>:1:1: 2:62 note: in expansion of print!
<std macros>:3:1: 3:54 note: expansion site
<std macros>:1:1: 3:58 note: in expansion of println!
src/lib.rs:3:5: 3:45 note: expansion site
error: aborting due to 2 previous errors
Could not compile `error-messages`.

To learn more, run the command again with --verbose.

A terminal screenshot of the 1.2.0 error message.

1.43.0 Error Message
   Compiling error-messages v0.1.0 (/Users/ep/src/rust/error-messages)
error[E0277]: expected a `std::ops::FnMut<(char,)>` closure, found `std::string::String`
 --> src/lib.rs:3:29
  |
3 |     println!("{:?}", s.find("".to_owned()));
  |                             ^^^^^^^^^^^^^
  |                             |
  |                             expected an implementor of trait `std::str::pattern::Pattern<'_>`
  |                             help: consider borrowing here: `&"".to_owned()`
  |
  = note: the trait bound `std::string::String: std::str::pattern::Pattern<'_>` is not satisfied
  = note: required because of the requirements on the impl of `std::str::pattern::Pattern<'_>` for `std::string::String`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `error-messages`.

To learn more, run the command again with --verbose.

A terminal screenshot of the 1.43.0 error message.

Third Example (Borrow checker)
fn main() {
    let mut x = 7;
    let y = &mut x;

    println!("{} {}", x, y);
}
1.2.0 Error Message
   Compiling error-messages v0.1.0 (file:///Users/ep/src/rust/error-messages)
src/lib.rs:5:23: 5:24 error: cannot borrow `x` as immutable because it is also borrowed as mutable
src/lib.rs:5     println!("{} {}", x, y);
                                   ^
note: in expansion of format_args!
<std macros>:2:25: 2:56 note: expansion site
<std macros>:1:1: 2:62 note: in expansion of print!
<std macros>:3:1: 3:54 note: expansion site
<std macros>:1:1: 3:58 note: in expansion of println!
src/lib.rs:5:5: 5:29 note: expansion site
src/lib.rs:3:18: 3:19 note: previous borrow of `x` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `x` until the borrow ends
src/lib.rs:3     let y = &mut x;
                              ^
src/lib.rs:6:2: 6:2 note: previous borrow ends here
src/lib.rs:1 fn main() {
src/lib.rs:2     let mut x = 7;
src/lib.rs:3     let y = &mut x;
src/lib.rs:4
src/lib.rs:5     println!("{} {}", x, y);
src/lib.rs:6 }
             ^
error: aborting due to previous error
Could not compile `error-messages`.

To learn more, run the command again with --verbose.

A terminal screenshot of the 1.2.0 error message.

1.43.0 Error Message
   Compiling error-messages v0.1.0 (/Users/ep/src/rust/error-messages)
error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable
 --> src/lib.rs:5:23
  |
3 |     let y = &mut x;
  |             ------ mutable borrow occurs here
4 |
5 |     println!("{} {}", x, y);
  |                       ^  - mutable borrow later used here
  |                       |
  |                       immutable borrow occurs here

error: aborting due to previous error

For more information about this error, try `rustc --explain E0502`.
error: could not compile `error-messages`.

To learn more, run the command again with --verbose.

A terminal screenshot of the 1.43.0 error message.

Quotes from the teams

Of course we can't cover every change that has happened. So we reached out and asked some of our teams what changes they are most proud of:

For rustdoc, the big things were:

  • The automatically generated documentation for blanket implementations
  • The search itself and its optimizations (last one being to convert it into JSON)
  • The possibility to test more accurately doc code blocks "compile_fail, should_panic, allow_fail"
  • Doc tests are now generated as their own seperate binaries.

— Guillaume Gomez (rustdoc)

Rust now has baseline IDE support! Between IntelliJ Rust, RLS and rust-analyzer, I feel that most users should be able to find "not horrible" experience for their editor of choice. Five years ago, "writing Rust" meant using old school Vim/Emacs setup.

— Aleksey Kladov (IDEs and editors)

For me that would be: Adding first class support for popular embedded architectures and achieving a striving ecosystem to make micro controller development with Rust an easy and safe, yet fun experience.

— Daniel Egger (Embedded WG)

The release team has only been around since (roughly) early 2018, but even in that time, we've landed ~40000 commits just in rust-lang/rust without any significant regressions in stable.

Considering how quickly we're improving the compiler and standard libraries, I think that's really impressive (though of course the release team is not the sole contributor here). Overall, I've found that the release team has done an excellent job of managing to scale to the increasing traffic on issue trackers, PRs being filed, etc.

— Mark Rousskov (Release)

Within the last 3 years we managed to turn Miri from an experimental interpreter into a practical tool for exploring language design and finding bugs in real code—a great combination of PL theory and practice. On the theoretical side we have Stacked Borrows, the most concrete proposal for a Rust aliasing model so far. On the practical side, while initially only a few key libraries were checked in Miri by us, recently we saw a great uptake of people using Miri to find and fix bugs in their own crates and dependencies, and a similar uptake in contributors improving Miri e.g. by adding support for file system access, unwinding, and concurrency.

— Ralf Jung (Miri)

If I had to pick one thing I'm most proud of, it was the work on non-lexical lifetimes (NLL). It's not only because I think it made a big difference in the usability of Rust, but also because of the way that we implemented it by forming the NLL working group. This working group brought in a lot of great contributors, many of whom are still working on the compiler today. Open source at its best!

— Niko Matsakis (Language)

The Community

As the language has changed and grown a lot in these past five years so has its community. There's been so many great projects written in Rust, and Rust's presence in production has grown exponentially. We wanted to share some statistics on just how much Rust has grown.

  • Rust has been voted "Most Loved Programming Language" every year in the past four Stack Overflow developer surveys since it went 1.0.
  • We have served over 2.25 Petabytes (1PB = 1,000 TB) of different versions of the compiler, tooling, and documentation this year alone!
  • In the same time we have served over 170TB of crates to roughly 1.8 billion requests on crates.io, doubling the monthly traffic compared to last year.

When Rust turned 1.0 you could count the number of companies that were using it in production on one hand. Today, it is being used by hundreds of tech companies with some of the largest tech companies such as Apple, Amazon, Dropbox, Facebook, Google, and Microsoft choosing to use Rust for its performance, reliability, and productivity in their projects.

Conclusion

Obviously we couldn't cover every change or improvement to Rust that's happened since 2015. What have been your favourite changes or new favourite Rust projects? Feel free to post your answer and discussion on our Discourse forum.

Lastly, we wanted to thank everyone who has to contributed to the Rust, whether you contributed a new feature or fixed a typo, your work has made Rust the amazing project it is today. We can't wait to see how Rust and its community will continue to grow and change, and see what you all will build with Rust in the coming decade!

The Mozilla BlogRequest for comment: how to collaboratively make trustworthy AI a reality


A little over a year ago, I wrote the first of many posts arguing: if we want a healthy internet — and a healthy digital society — we need to make sure AI is trustworthy. AI, and the large pools of data that fuel it, are central to how computing works today. If we want apps, social networks, online stores and digital government to serve us as people — and as citizens — we need to make sure the way we build with AI has things like privacy and fairness built in from the get go.

Since writing that post, a number of us at Mozilla — along with literally hundreds of partners and collaborators — have been exploring the questions: What do we really mean by ‘trustworthy AI’? And, what do we want to do about it?

 How do we collaboratively make trustworthy AI a reality? 

Today, we’re kicking off a request for comment on  v0.9 of Mozilla’s Trustworthy AI Whitepaper — and on the accompanying theory of change diagram that outlines the things we think need to happen. While I have fallen out of the habit, I have traditionally included a simple diagram in my blog posts to explain the core concept I’m trying to get at. I would like to come back to that old tradition here:

This cartoonish drawing gets to the essence of where we landed in our year of exploration: ‘agency’ and ‘accountability’ are the two things we need to focus on if we want the AI that surrounds us everyday to be more trustworthy. Agency is something that we need to proactively build into the digital products and services we use — we need computing norms and tech building blocks that put agency at the forefront of our design process. Accountability is about having effective ways to react if things go wrong — ways for people to demand better from the digital products and services we use everyday and for governments to enforce rules when things go wrong. Of course, I encourage  you to look at the full (and fancy) version of our theory of change diagram — but the fact that ‘agency’ (proactive) and ‘accountability’ (reactive) are the core, mutually reinforcing parts of our trustworthy AI vision is the key thing to understand.

In parallel to developing our theory of change, Mozilla has also been working closely with partners over the past year to show what we mean by trustworthy AI, especially as it relates to consumer internet technology. A significant portion of our 2019 Internet Health Report was dedicated to AI issues. We ran campaigns to: pressure platforms like YouTube to make sure their content recommendations don’t promote misinformation; and call on Facebook and others to open up APIs to make political ad targeting more transparent. We provided consumers with a critical buying guide for AI-centric smart home gadgets like Amazon Alexa. We invested ~$4M in art projects and awarded fellowships to explore AI’s impact on society. And, as the world faced a near universal health crisis, we asked  questions about how issues like AI, big data and privacy will play during — and after — the pandemic. As with all of Mozilla’s movement building work, our intention with our trustworthy AI efforts is to bias towards action and working with others.

A request for comments

It’s with this ‘act + collaborate’ bias in mind that we are embarking on a request for comments on v0.9 of the Mozilla Trustworthy AI Whitepaper. The paper talks about how industry, regulators and citizens of the internet can work together to build more agency and accountability into our digital world. It also talks briefly about some of the areas where Mozilla will focus, knowing that Mozilla is only one small actor in the bigger picture of shifting the AI tide.

Our aim is to use the current version of this paper as a foil for improving our thinking and — even more so — for identifying further opportunities to collaborate with others in building more trustworthy AI. This is why we’re using the term ‘request for comment’ (RFC). It is a very intentional hat tip to a long standing internet tradition of collaborating openly to figure out how things should work. For decades, the RFC process has been used by the internet community to figure out everything from standards for sharing email across different computer networks to best practices for defeating denial of service attacks. While this trustworthy AI effort is not primarily about technical standards (although that’s part of it), it felt (poetically) useful to frame this process as an RFC aimed at collaboratively and openly figuring out how to get to a world where AI and big data work quite differently than they do today.

We’re imagining that Mozilla’s trustworthy AI request for comment process includes three main steps, with the first step starting today.

Step 1: partners, friends and critics comment on the white paper

During this first part of the RFC, we’re interested in: feedback on our thinking; further examples to flesh out our points, especially from sources outside Europe and North America; and ideas for concrete collaboration.

The best way to provide input during this part of the process is to put up a blog post or some other document reacting to what we’ve written (and then share it with us). This will give you the space to flesh out your ideas and get them in front of both Mozilla (send us your post!) and a broader audience. If you want something quicker, there is also an online form where you can provide comments. We’ll be holding a number of online briefings and town halls for people who want to learn about and comment on the content in the paper — sign up through the form above to find out more. This phase of the process starts today and will run through September 2020.

Step 2: collaboratively map what’s happening — and what should happen 

Given our focus on action, mapping out real trustworthy AI work that is already happening — and that should happen — is even more critical than honing frameworks in the white paper. At a baseline, this means collecting information about educational programs, technology building blocks, product prototypes, consumer campaigns and emerging government policies that focus on making trustworthy AI a reality.

The idea is that the ‘maps’ we create will be a resource for both Mozilla and the broader field. They will help Mozilla direct its fellows, funding and publicity efforts to valuable projects. And, they will help people from across the field see each other so they can share ideas and collaborate completely independently of our work.

Process-wise, these maps will be developed collaboratively by Mozilla’s Insights Team with involvement of people and organizations from across the field. Using a mix of feedback from the white paper comment process (step 1) and direct research, they will develop a general map of who is working on key elements of trustworthy AI. They will also develop a deeper landscape analysis on the topic of data stewardship and alternative approaches to data governance. This work will take place from now until November 2020.

Step 3: do more things together, and update the paper

The final — and most important — part of the process will be to figure out where Mozilla can do more to support and collaborate with others. We already know that we want to work more with people who are developing new approaches to data stewardship, including trusts, commons and coops. We see efforts like these as foundational building blocks for trustworthy AI. Separately, we also know that we want to find ways to support African entrepreneurs, researchers and activists working to build out a vision of AI for that continent that is independent of the big tech players in the US and China. Through the RFC process, we hope to identify further areas for action and collaboration, both big and small.

Partnerships around data stewardship and AI in Africa are already being developed by teams within Mozilla. A team has also been tasked with identifying smaller collaborations that could grow into something bigger over the coming years. We imagine this will happen slowly through suggestions made and patterns identified during the RFC process. This will then shape our 2021 planning — and will feed back into a (hopefully much richer) v1.0 of the whitepaper. We expect all this to be done by the end of 2020.

Mozilla cannot do this alone. None of us can

As noted above: the task at hand is to collaboratively and openly figure out how to get to a world where AI and big data work quite differently than they do today. Mozilla cannot do this alone. None of us can. But together we are much greater than the sum of our parts. While this RFC process will certainly help us refine Mozilla’s approach and direction, it will hopefully also help others figure out where they want to take their efforts. And, where we can work together. We want our allies and our community not only to weigh in on the white paper, but also to contribute to the collective conversation about how we reshape AI in a way that lets us build — and live in — a healthier digital world.

PS. A huge thank you to all of those who have collaborated with us thus far and who will continue to provide valuable perspectives to our thinking on AI.

The post Request for comment: how to collaboratively make trustworthy AI a reality appeared first on The Mozilla Blog.

The Firefox FrontierHow to overcome distractions (and be more productive)

Distractions tempt us at every turn, from an ever-growing library of Netflix titles to video games (Animal Crossing is my current vice) to all of the other far more tantalizing … Read more

The post How to overcome distractions (and be more productive) appeared first on The Firefox Frontier.

Mozilla AccessibilityProper VoiceOver support coming soon to Firefox on MacOS

For several years, Firefox support for the VoiceOver accessibility technology on MacOS was mostly non-existent. In 2020, the team is finally changing that. Here is some insight into what’s happening.

The kick-off

In late 2019, the accessibility team at Mozilla resourced work on improving MacOS accessibility support over the course of 2020. In January, several members gathered in Berlin during an all-hands to scope out the work. There was a lot of old, mostly dysfunctional, code lying around that needs to be modernized and brought up to today’s standards. We agreed to tackle the problem in two stages.

Two stages to success

The first stage, due by the end of June, aims to implement basic VoiceOver support. For the most part, this means correcting and completing specific properties for various HTML elements and widgets. This is to give VoiceOver and other accessibility features correct information about what is happening inside our web area.

The aim of this first stage is to give web developers the chance to test their web sites with VoiceOver. The output should be good enough so they can feel confident that users visiting their offerings with assistive technology will get an accessible experience.

In the second stage, which we plan to complete by the end of the year, the goal is to improve the user experience for visually impaired VoiceOver users. This encompasses performance, text editing, live region support, and rotor item support. It will also include other bits that might turn out missing as more users start testing what we have.

What we have so far

Firefox 75

Firefox 75, released in April, saw the first fruits of this work. Most notably, we learned our way around the Mac code base and the accessibility APIs. In the process we uncovered a small, but significant, piece we were missing that made us very fast all of a sudden. This small, but mighty, patch, enabled us to progress much more rapidly than we had expected. We also made the VoiceOver cursor visible, and made it follow focus. Also, if navigating with VoiceOver, we made focus follow it if VoiceOver’s setting for that was enabled. And, we also fixed some initial labeling inconsistencies across the board.

Screenshot of the Firefox browser window with VoiceOver active and "Projects" link highlighted

Morgan and Eitan also developed some testing and benchmarking utilities. These allowed them to compare the accessibility property output between Safari and Firefox. It also gave us some first measures of performance. And let’s just say, the numbers weren’t bad at all!

Firefox 76

Loaded with confidence, the team started into the Firefox 76 development cycle. They quickly made much more progress with various elements, events, and properties. But most importantly, they developed a testing framework. This framework allows us to automatically test the attributes on the Mac platform for correctness. So for each element, we can query things such as the AXRole, AXSubRole, and other items that VoiceOver might ask for. If anything breaks, we now get immediate notification from our continuous integration cluster. Firefox 76 saw a total of 28 bug fixes, many of which contained more than one patch. Firefox 76 was released in May. If you are a Mac user, you can turn on VoiceOver and try out what we have so far.

Firefox 77 and beyond

In Firefox 77, which is in beta at the time this is written, work continued on more testing coverage. The team also added more correctness for elements and modernization of the Mac specific accessibility code. This helps us to comply with current standards on the MacOS platform.

At the time of this writing, we are in the Firefox 78 development cycle. So far, we have already tackled some more complex widgets. Also, we now have a much better understanding of how the Mac accessibility framework works. We will therefore spend some time refactoring the code to streamline how we do things internally to make it more future-proof. Thankfully, our test coverage is so good by now that the team feels confident to do the refactor. Any breakage will get flagged immediately.

The final piece for the first phase will be the Firefox 79 cycle, which will happen in June. What we will work on depends largely on how well this 78 cycle is going. We are using some collections of accessibility samples, such as a11ysupport.io, to manually test how well we’re doing and where we still have gaps.

Phase 2: VoiceOver excellence

And then, we will start with phase 2, which will be all about making Firefox on MacOS fit for use by heavy VoiceOver users, such as visually impaired users. This will offer them another choice of an accessible browser on the Mac giving them all the features that they might already know from Firefox on Windows or Linux. We aim to enable full text editing support and live regions. By the end of this project, the rotor (VoiceOver Modifier+U) will no longer come up empty. Consequently, the rotor gestures and quick navigation will work as you’d expect.

We’ll need your help

At some point later in this project, we will want your help in finding and fixing edge cases or user scenarios we didn’t anticipate. Right now, we are still very much aware that the support has gaps, and we’re working furiously on closing them. But as our Mac accessibility support matures, it will become important that you, who might have a Mac and be a VoiceOver user, try out what we have and give us feedback. We can test a lot of things, but we cannot test everything. We want to hear from you what you think, what bugs you might encounter, or what paper cuts make your lives difficult with Firefox on the Mac.

When the time comes, we will publish a call to action on this blog and in our Discourse forum. Until then, feel free to follow along our detailed progress. Links to all the open and fixed bugs are on our dedicated project wiki page. And if you’re curious and not afraid of cutting edge technology, by all means try it out for yourself. The first improvements are in either Nightly or Beta, or even on the current release.

Are you excited? We certainly are! And we always welcome your thoughts and comments.

The post Proper VoiceOver support coming soon to Firefox on MacOS appeared first on Mozilla Accessibility.

Nicholas NethercoteHow to get the size of Rust types with -Zprint-type-sizes

When optimizing Rust code it’s sometimes useful to know how big a type is, i.e. how many bytes it takes up in memory. std::mem::size_of can tell you, but often you want to know the exact layout as well. For example, an enum might be surprisingly big, in which case you probably will want to know if, for example, there is one variant that is much bigger than the others.

The -Zprint-type-sizes option does exactly this. It isn’t enabled on release versions of rustc, so you’ll need to a nightly version of rustc. Here is one possible invocation:

cargo +nightly rustc -- -Zprint-type-sizes

It will print out details of the size, layout, and alignment of all types in use. For example, for this type:

enum E {
    A,
    B(i32),
    C(u64, u8, u64, u8),
    D(Vec<u32>),
}

it prints the following, plus info about a few built-in types:

print-type-size type: `E`: 32 bytes, alignment: 8 bytes
print-type-size     discriminant: 1 bytes
print-type-size     variant `A`: 0 bytes
print-type-size     variant `B`: 7 bytes
print-type-size         padding: 3 bytes
print-type-size         field `.0`: 4 bytes, alignment: 4 bytes
print-type-size     variant `C`: 23 bytes
print-type-size         field `.1`: 1 bytes
print-type-size         field `.3`: 1 bytes
print-type-size         padding: 5 bytes
print-type-size         field `.0`: 8 bytes, alignment: 8 bytes
print-type-size         field `.2`: 8 bytes
print-type-size     variant `D`: 31 bytes
print-type-size         padding: 7 bytes
print-type-size         field `.0`: 24 bytes, alignment: 8 bytes

It shows:

  • the size and alignment of the type;
  • for enums, the size of the discriminant;
  • for enums, the size of each variant;
  • the size, alignment, and ordering of all fields (note that the compiler has reordered variant C‘s fields to minimize the size of E);
  • the size and location of all padding.

Every detail you could possibly want is there. Brilliant!

For rustc developers, there’s an extra-special trick for getting the size of a type within rustc itself. Put code like this into a file a.rs:

#![feature(rustc_private)]
extern crate syntax;
use syntax::ast::Expr;
fn main() {
    let _x = std::mem::size_of::<Expr>();
}

and then compile it like this:

RUSTC_BOOTSTRAP=1 rustc -Zprint-type-sizes a.rs

I won’t pretend to understand how it works, but the use of rustc_private and RUSTC_BOOTSTRAP somehow let you see inside rustc while using it, rather than while compiling it. I have used this trick for PRs such as this one.

The Mozilla BlogWelcome Adam Seligman, Mozilla’s new Chief Operating Officer

I’m excited to announce that Adam Seligman has joined Mozilla as our new Chief Operating Officer. Adam will work closely with me to help scale our businesses, growing capabilities, revenue and impact to fulfill Mozilla’s mission in service to internet users around the world.

Our goal at Mozilla is to build a better internet. To provide products and services that people flock to, and that elevate a safer, more humane, less surveillance and exploitation-based reality. To do this —  especially now — we need to engage with our customers and other technologists; ideate, test, iterate and ship products; and develop revenue sources faster than we’ve ever done.

Adam has a proven track record of building businesses and communities in the technology space. With a background in computer science, Adam comes to Mozilla with nearly two decades of experience in our industry. He managed a $1B+ cloud platform at Salesforce, led developer relations at Google and was a key member of the web platform strategy team at Microsoft.

Adding Adam to our team will accelerate our ability to solve big problems of online life, to create product offerings that connect to consumers, and to develop revenue models in ways that align with our mission. Adam is joining Mozilla at a time when people are more reliant than ever on the internet, but also questioning the impact of technology on their lives. They are looking for leadership and solutions from organizations like Mozilla. Adam will help grow Mozilla’s capacity to offer a range of products and services that meet people’s needs for online life.

“The open internet has brought incredible changes to our lives, and what we are witnessing now is a massive acceleration,” said Adam Seligman, Mozilla’s new Chief Operating Officer. “The open internet is keeping our industries running and our children learning. It’s our lifeline to family and friends, and it’s our primary source of information. It powers everything from small business to social movements. I want to give back to an internet that works for people — not against them. And there is no better champion for a people-first vision of the internet than Mozilla.”

In his capacity as Chief Operating Officer, Adam will lead the Pocket, Emerging Technologies, Marketing and Open Innovation teams to accelerate product growth and profitable business models, and work in close coordination with Dave Camp and the Firefox organization to do the same.

I eagerly look forward to working together with Adam to navigate these troubled times and build a vibrant future for Mozilla’s product and mission.

The post Welcome Adam Seligman, Mozilla’s new Chief Operating Officer appeared first on The Mozilla Blog.

Mozilla Open Innovation TeamRelaunching Mozilla’s Contribute Page: Applying Open By Design for a Better Volunteer Experience

Tl;dr: This week, the Open Innovation team published a redesigned version of the Contribute page at mozilla.org/contribute. This opens up a new and improved way for volunteers to get involved with Mozilla projects and communities.

At Mozilla, we believe in the power of our communities.

Contributors translate our products, answer support questions and make thousands of code contributions a year. Mozilla communities are a critical resource for making the internet a more open, diverse and accessible resource for all.

Over the last few years, we’ve started to look at how these contributors begin with Mozilla. How does someone initially get involved as a volunteer? How do they connect to our projects? Are they contributing to the projects that are ready and able to effectively appreciate their contributions?

Early incremental improvements

The start of the contributor journey has long been a challenge for Mozilla. Since 2015, Open Innovation has been thinking about how the Contribute page could be improved. Teams who were represented on the previous iteration of the page were passionate about what the page represented. They were overwhelmed, however, by the volume of people who wanted to contribute.

In 2016, we launched an experiment that fundamentally changed the purpose of the page. Visitors would be shown a variety of simple or challenging tasks they could participate in. All of the tasks were self-contained (tweet, donate, watch a video) and none of them provided pathways for participation with any Mozilla teams or projects.

<figcaption>Mozilla.org/Contribute circa 2015</figcaption>

Engagement on the page increased as the options for participation became simpler and more accessible. Staff teams were no longer overwhelmed by a deluge of requests from people discovering their projects from the site. But the Contribute page remained imperfect. It felt disconnected from our mission. We were still not being intentional about being open. We weren’t designing for the greatest impact or a rewarding experience.

The goal for the newest version of the page was that it would truly embody the principles of Open by Design.

Everything new: from on boarding to project curation

Being Open by Design” for us means “developing an understanding of how our products and technologies deliver value within an ecosystem. It means intentionally designing how we work with external collaborators and contributors to optimize that value.”

Often enough “openness by default” reflects an absence of strategic intent. Acting without clarity about why you’re doing something, or what the intended outcomes are, means your commitment to openness is likely to diminish over time. This is what we were seeing in the previous versions of the Contribute page.

The new version of the Contribute page that launched this week is based on extensive research into what page visitors wanted. It builds on the previous experiment with feedback gathered through interviews with users, staff and community members.

“There’s a mission here, a manifesto, so I’d be pretty much interested in a better way of getting involved with Mozilla. As a front end developer this is something I strongly believe in, an open and accessible web.” (usertesting.com quote)

The new page doesn’t send people directly to every Mozilla project. Instead it drives people through highly curated opportunities that are ready for high-volume participation like Support, to pages that thoughtfully onboard new contributors such as Localization, and Coding.

By applying the principles of open by design to the Contribute page we’re taking a more intentional approach to our communities. We hope that this page will encourage new visitors to make their first contribution to Mozilla. We hope that existing Mozillians will feel confident directing friends and family who are interested in learning more about contribution to this page.

And we hope this page helps all of our communities find the information they need to learn, explore, and stay involved with Mozilla.


Relaunching Mozilla’s Contribute Page: Applying Open By Design for a Better Volunteer Experience was originally published in Mozilla Open Innovation on Medium, where people are continuing the conversation by highlighting and responding to this story.

David BryantA Quantum Leap for the Web

Over the past year, our top priority for Firefox was the Electrolysis project to deliver a multi-process browsing experience to users. Running Firefox in multiple processes greatly improves security and performance. This is the largest change we’ve ever made to Firefox, and we’ll be rolling out the first stage of Electrolysis to 100% of Firefox desktop users over the next few months.

But, that doesn’t mean we’re all out of ideas in terms of how to improve performance and security. In fact, Electrolysis has just set us up to do something we think will be really big.

We’re calling it Project Quantum.

Quantum is our effort to develop Mozilla’s next-generation web engine and start delivering major improvements to users by the end of 2017. If you’re unfamiliar with the concept of a web engine, it’s the core of the browser that runs all the content you receive as you browse the web. Quantum is all about making extensive use of parallelism and fully exploiting modern hardware. Quantum has a number of components, including several adopted from the Servo project.

The resulting engine will power a fast and smooth user experience on both mobile and desktop operating systems — creating a “quantum leap” in performance. What does that mean? We are striving for performance gains from Quantum that will be so noticeable that your entire web experience will feel different. Pages will load faster, and scrolling will be silky smooth. Animations and interactive apps will respond instantly, and be able to handle more intensive content while holding consistent frame rates. And the content most important to you will automatically get the highest priority, focusing processing power where you need it the most.

So how will we achieve all this?

Web browsers first appeared in the era of desktop PCs. Those early computers only had single-core CPUs that could only process commands in a single stream, so they truly could only do one thing at a time. Even today, in most browsers an individual web page runs primarily on a single thread on a single core.

But nowadays we browse the web on phones, tablets, and laptops that have much more sophisticated processors, often with two, four or even more cores. Additionally, it’s now commonplace for devices to incorporate one or more high-performance GPUs that can accelerate rendering and other kinds of computations.

One other big thing that has changed over the past fifteen years is that the web has evolved from a collection of hyperlinked static documents to a constellation of rich, interactive apps. Developers want to build, and consumers expect, experiences with zero latency, rich animations, and real-time interactivity. To make this possible we need a web platform that allows developers to tap into the full power of the underlying device, without having to agonize about the complexities that come with parallelism and specialized hardware.

And so, Project Quantum is about developing a next-generation engine that will meet the demands of tomorrow’s web by taking full advantage of all the processing power in your modern devices. Quantum starts from Gecko, and replaces major engine components that will benefit most from parallelization, or from offloading to the GPU. One key part of our strategy is to incorporate groundbreaking components of Servo, an independent, community-based web engine sponsored by Mozilla. Initially, Quantum will share a couple of components with Servo, but as the projects evolve we will experiment with adopting even more.

A number of the Quantum components are written in Rust. If you’re not familiar with Rust, it’s a systems programming language that runs blazing fast, while simplifying development of parallel programs by guaranteeing thread and memory safety. In most cases, Rust code won’t even compile unless it is safe.

We’re taking on a lot of separate but related initiatives as part of Quantum, and we’re revisiting many old assumptions and implementations. The high-level approach is to rethink many fundamental aspects of how a browser engine works. We’ll be re-engineering foundational building blocks, like how we apply CSS styles, how we execute DOM operations, and how we render graphics to your screen.

Quantum is an ambitious project, but users won’t have to wait long to start seeing improvements roll out. We’re going to ship major improvements next year, and we’ll iterate from there. A first version of our new engine will ship on Android, Windows, Mac, and Linux. Someday we hope to offer this new engine for iOS, too.

We’re confident Quantum will deliver significantly improved performance. If you’re a developer and you’d like to get involved, you can learn more about Quantum on the the Mozilla wiki, and explore ways that you can contribute. We hope you’ll take the Quantum leap with us.

Special thanks to Ryan Pollock for contributing to this post.


A Quantum Leap for the Web was originally published in Mozilla Tech on Medium, where people are continuing the conversation by highlighting and responding to this story.

David BryantWhy WebAssembly is a game changer for the web — and a source of pride for Mozilla and Firefox

With today’s release of Firefox, we are the first browser to support WebAssembly. If you haven’t yet heard of WebAssembly, it’s an emerging standard inspired by our research to enable near-native performance for web applications.

WebAssembly is one of the biggest advances to the Web Platform over the past decade.

This new standard will enable amazing video games and high-performance web apps for things like computer-aided design, video and image editing, and scientific visualization. Over time, many existing productivity apps (e.g. email, social networks, word processing) and JavaScript frameworks will likely use WebAssembly to significantly reduce load times while simultaneously improving performance while running. Unlike other approaches that have required plug-ins to achieve near-native performance in the browser, WebAssembly runs entirely within the Web Platform. This means that developers can integrate WebAssembly libraries for CPU-intensive calculations (e.g. compression, face detection, physics) into existing web apps that use JavaScript for less intensive work.

To get a quick understanding of WebAssembly, and to get an idea of how some companies are looking at using it, check out this video. You’ll hear from engineers at Mozilla, and partners such as Autodesk, Epic, and Unity.

https://medium.com/media/1858e816355bfa288aa7294e39278e67/href

It’s been a long, winding, and exciting road getting here.

JavaScript was originally intended as a lightweight language for fairly simple scripts. It needed to be easy for novice developers to code in. You know — for relatively simple things like making sure that you fill out a form correctly when you submit it.

A lot has changed since then. Modern web apps are complex computer programs, with client and server code, much of it written in JavaScript.

But, for all the advances in the JavaScript programming language and the engines that run it (including Mozilla’s SpiderMonkey engine), JavaScript still has inherent limitations that make it a poor fit for some scenarios. Most notably, when a browser actually executes JavaScript it typically can’t run the program as fast as the operating system can run a comparable native program written in other programming languages.

We’ve always been well aware of this at Mozilla but that has never limited our ambitions for the web. So a few years ago we embarked on a research project — to build a true virtual machine in the browser that would be capable of safely running both JavaScript and high-speed languages at near-native speeds. In particular we set a goal to allow modern video games to run in Firefox without plug-ins, knowing the Web Platform would then be able to run nearly any kind of application. Our first major step, after a great deal of experimentation, was to demonstrate that games built upon popular game engines could run in Firefox using an exploratory low-level subset of JavaScript called asm.js.

The asm.js sub-language worked impressively well, and we knew the approach could work even better as a first-class web standard. So, using asm.js as a proof of concept, we set out to collaborate with other browser makers to establish such a standard that could run as part of browsers. Together with expert engineers across browser makers, we established consensus on WebAssembly. We expect support for it will soon start shipping in other browsers.

Web apps written with WebAssembly can run at near-native speeds because, unlike JavaScript, all the code a programmer writes is parsed and compiled ahead of time before reaching the browser. The browser then just sees low-level, machine-ready instructions it can quickly validate, optimize, and run.

In some ways, WebAssembly changes what it means to be a web developer, as well as the fundamental abilities of the web. With WebAssembly and an accompanying set of tools, programs written in languages like C/C++ can be ported to the web so they run with near-native performance. We expect that, as WebAssembly continues to evolve, you’ll also be able to use it with programming languages often used for mobile apps, like Java, Swift, and C#.

If you’re interested in hearing more about the backstory of WebAssembly, check out this behind-the-scenes look.

https://medium.com/media/7f594db82cecacb4cffaac7932ae1ac9/href

WebAssembly is shipping today in Firefox on Windows, MacOS, Linux, and Android. We’re particularly excited about the potential on mobile — do all those apps really need to be native?

If you’d like to try out some applications that use WebAssembly, upgrade to Firefox 52, and check out this demo of Zen Garden by Epic. For your convenience, we’ve embedded a video of the demo below.

https://medium.com/media/9c771666d7a80886c78da81479420ee7/href

If you’re a developer interested in working with WebAssembly, check out WebAssembly documentation on MDN. You might also want to see this series of blog posts by Lin Clark that explain WebAssembly through some cool cartoons.

Here at Mozilla we’re focused on moving the web forward and on making Firefox the best browser, hands down. With WebAssembly shipping today and Project Quantum well underway, we’re more bullish about the web — and about Firefox — than ever.

Special thanks to Ryan Pollock for contributing to this post.


Why WebAssembly is a game changer for the web — and a source of pride for Mozilla and Firefox was originally published in Mozilla Tech on Medium, where people are continuing the conversation by highlighting and responding to this story.

This Week In RustThis Week in Rust 338

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 cargo-workspaces, a cargo subcommand to manage your cargo workspace.

Thanks to Pavan Kumar Sunkara 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

375 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
Tracking Issues & PRs

New RFCs

Upcoming Events

Online
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

Ownership is purely conceptual: it is not something you can see in a disassembler.

Jay Oster on rust-users

Thanks to Daniel H-M for the suggestions!

Please submit quotes and vote for next week!

This Week in Rust is edited by: nellshamrell, llogiq, srikwit, and cdmistman.

Discuss on r/rust.

The Mozilla BlogWhat the heck happened with .org?

If you are following the tech news, you might have seen the announcement that ICANN withheld consent for the change of control of the Public Interest Registry and that this had some implications for .org.  However, unless you follow a lot of DNS inside baseball, it might not be that clear what all this means. This post is intended to give a high level overview of the background here and what happened with .org. In addition, Mozilla has been actively engaged in the public discussion on this topic; see here for a good starting point.

The Structure and History of Internet Naming

As you’ve probably noticed, Web sites have names like “mozilla.org”, “google.com”, etc. These are called “domain names.” The way this all works is that there are a number of “top-level domains” (.org, .com, .io, …) and then people can get names within those domains (i.e., that end in one of those). Top level domains (TLDs) come in two main flavors:

  • Country-code top-level domains (ccTLDs) which represent some country or region like .us (United States), .uk (United Kingdom, etc.)

Back at the beginning of the Internet, there were five gTLDs which were intended to roughly reflect the type of entity registering the name:

  • .com: for “commercial-related domains”
  • .edu: for educational institutions
  • .gov: for government entities (really, US government entities)
  • .mil: for the US Military (remember, the Internet came out of US government research)
  • .org: for organizations (“any other domains”)

It’s important to remember that until the 90s, much of the Internet ran under an Acceptable Use Policy which discouraged/forbid commercial use and so these distinctions were inherently somewhat fuzzy, but nevertheless people had the rough understanding that .org was for non-profits and the like and .com was for companies.

During this period the actual name registrations were handled by a series of government contractors (first SRI and then Network Solutions) but the creation and assignment of the top-level domains was under the control of the Internet Assigned Numbers Authority (IANA), which in practice, mostly meant the decisions of its Director, Jon Postel. However, as the Internet became bigger, this became increasingly untenable especially as IANA was run under a contract to the US government. Through a long and somewhat complicated series of events, in 1998 this responsibility was handed off to the Internet Corporation for Assigned Names and Numbers (ICANN), which administers the overall system, including setting the overall rules and determining which gTLDs will exist (which ccTLDs exist is determined by ISO 3166-1 country codes, as described in RFC 1591). ICANN has created a pile of new gTLDs, such as .dev, .biz, and .wtf (you may be wondering whether the world really needed .wtf, but there it is). As an aside, many of the newer names you see registered are not actually under gTLDs, but rather ccTLDs that happen to correspond to countries lucky enough to have cool sounding country codes. For instance, .io is actually the British Indian Ocean’s TLD and .tv belongs to Tuvalu.

One of the other things that ICANN does is determine who gets to run each TLD. The way this all works is that ICANN determines who gets to be the registry, i.e., who keeps the records of who has which name as well as some of the technical data needed to actually route name lookups. The actual work of registering domain names is done by a registrar, who engages with the customer. Importantly, while registrars compete for business at some level (i.e., multiple people can sell you a domain in .com), there is only one registry for a given TLD and so they don’t have any price competition within that TLD; if you want a .com domain, VeriSign gets to set the price floor. Moreover, ICANN doesn’t really try to keep prices down; in fact, they recently removed the cap on the price of .org domains (bringing it in line with most other TLDs). One interesting fact about these contracts is that they are effectively perpetual: the contracts themselves are for quite long terms and registry agreements typically provide for automatic renewal except under cases of significant misbehavior by the registry. In other words, this is a more or less permanent claim on the revenues for a given TLD.

The bottom line here is that this is all quite lucrative. For example, in FY19 VeriSign’s revenue was over $1.2 billion. ICANN itself makes money in two main ways. First, it takes a cut of the revenue from each domain registration and second it auctions off the contracts for new gTLDs if more than one entity wants to register them. In the fiscal year ending in June 2018, ICANN made $136 million in total revenues (it was $302 million the previous year due to a large amount of revenue from gTLD auctions).

ISOC and .org

This brings us to the story of ISOC and .org. Until 2003, VeriSign operated .com, .net, and .org, but ICANN and VeriSign agreed to give up running .org (while retaining the far more profitable .com). As stated in their proposal:

As a general matter, it will largely eliminate the vestiges of special or unique treatment of VeriSign based on its legacy activities before the formation of ICANN, and generally place VeriSign in the same relationship with ICANN as all other generic TLD registry operators. In addition, it will return the .org registry to its original purpose, separate the contract expiration dates for the .com and .net registries, and generally commit VeriSign to paying its fair share of the costs of ICANN without any artificial or special limits on that responsibility.

The Internet Society (ISOC) is a nonprofit organization with the mission to support and promote “the development of the Internet as a global technical infrastructure, a resource to enrich people’s lives, and a force for good in society”. In 2002, they submitted one of 11 proposals to take over as the registry for .org and ICANN ultimately selected them. ICANN had a list of 11 criteria for the selection and the board minutes are pretty vague on the reason for selecting ISOC, but at the time this was widely understood as ICANN using the .org contract to provide a subsidy for ISOC and ISOC’s work. In any case, it ended up being quite a large subsidy: in 2018, PIR’s revenue from .org was over $92 million.

The actual mechanics here are somewhat complicated: it’s not like ISOC runs the registry itself. Instead they created a new non-profit subsidiary, the Public Interest Registry (PIR), to hold the contract with ICANN to manage .org. PIR in turn contracts the actual operations to Afilias, which is also the registry for a pile of other domains in their own right. [This isn’t an uncommon structure. For instance, VeriSign is the registry for .com, but they also run .tv for Tuvalu.] This will become relevant to our story shortly. Additionally, in the summer of 2019, PIR’s ten year agreement with ICANN renewed, but under new terms: looser contractual conditions to mirror those for the new gTLDs (yes, including .wtf), including the removal of a price cap and certain other provisions.

The PIR Sale

So, by 2018, ISOC was sitting on a pretty large ongoing revenue stream in the form of .org registration fees. However, ISOC management felt that having essentially all of their funding dependent on one revenue source was unwise and that actually running .org was a mismatch with ISOC’s main mission. Instead, they entered into a deal to sell PIR (and hence the .org contract) to a private equity firm called Ethos Capital, which is where things get interesting.

Ordinarily, this would be a straightforward-seeming transaction, but under the terms of the .org Registry Agreement, ISOC had to get approval from ICANN for the sale (or at least for PIR to retain the contract):

7.5              Change of Control; Assignment and Subcontracting.  Except as set forth in this Section 7.5, neither party may assign any of its rights and obligations under this Agreement without the prior written approval of the other party, which approval will not be unreasonably withheld.  For purposes of this Section 7.5, a direct or indirect change of control of Registry Operator or any subcontracting arrangement that relates to any Critical Function (as identified in Section 6 of Specification 10) for the TLD (a “Material Subcontracting Arrangement”) shall be deemed an assignment.

Soon after the proposed transaction was announced, a number of organizations (especially Access Now and EFF) started to surface concerns about the transaction. You can find a detailed writeup of those concerns here but I think a fair summary of the argument is that .org was special (and in particular that a lot of NGOs relied on it) and that Ethos could not be trusted to manage it responsibly. A number of concerns were raised, including that Ethos might aggressively raise prices in order to maximize their profit or that they could be more susceptible to governmental pressure to remove the domain names of NGOs that were critical of them. You can find Mozilla’s comments on the proposed sale here. The California Attorney General’s Office also weighed in opposing the sale in a letter that implied it might take independent action to stop it, saying:

This office will continue to evaluate this matter, and will take whatever action necessary to protect Californians and the nonprofit community.

In turn, Ethos and ISOC mounted a fairly aggressive PR campaign of their own, including creating a number of new commitments intended to alleviate concerns that had been raised, such as a new “Stewardship Council” with some level of input into privacy and policy decisions, an amendment to the operating agreement with ICANN to provide for additional potential oversight going forward, and a promise not to raise prices by more than 10%/year for 8 years. At the end of the day these efforts did not succeed: ICANN announced on April 30 that they would withhold consent for the deal (see here for their reasoning).

What Now?

As far as I can tell, this decision merely returns the situation to the status quo ante (see this post by Milton Mueller for some more detailed analysis). In particular, ISOC will continue to operate PIR and be able to benefit from the automatic renewal (and the agreement runs through 2029 in any case). To the extent to which you trusted PIR to manage .org responsibly a month ago, there’s no reason to think that has changed (of course, people’s opinions may have changed because of the proposed sale). However, as Mueller points out, none of the commitments that Ethos made in order to make the deal more palatable apply here, and in particular, thanks to the new contract in 2019, PIR ISOC is free to raise prices without being bound by the 10% annual commitment that Ethos had offered.

It’s worth noting that “Save dot Org” at least doesn’t seem happy to leave .org in the hands of ISOC and in particular has called for ICANN to rebid the contract. Here’s what they say:

This is not the final step needed for protecting the .Org domain. ICANN must now open a public process for bids to find a new home for the .Org domain. ICANN has established processes and criteria that outline how to hold a reassignment process. We look forward to seeing a competitive process and are eager to support the participation in that process by the global nonprofit community.

For ICANN to actually try to take .org away from ISOC seems like it would be incredibly contentious and ICANN hasn’t given any real signals about what they intend to do here. It’s possible they will try to rebid the contract (though it’s not clear to me exactly whether the contract terms really permit this) or that they’ll just be content to leave things as they are, with ISOC running .org through 2029.

Regardless of what the Internet Society and ICANN choose to do here, I think that this has revealed the extent to which the current domain name ecosystem depends on informal understandings of what the various actors are going to do, as opposed to formal commitments to do them. For instance, many opposed to the sale seem to have expected that ISOC would continue to manage .org in the public interest and felt that the Ethos sale threatened that. However, as a practical matter the registry agreement doesn’t include any such obligation and in particular nothing really stops them from raising prices much higher in order to maximize profit as opponents argued Ethos might do (although ISOC’s nonprofit status means they can’t divest those profits directly). Similarly, those who were against the sale and those who were in favor of it seem to have had rather radically different expectations about what ICANN was supposed to do (actively ensure that .org be managed in a specific way versus just keep the system running with a light touch) and at the end of the day were relying on ICANN’s discretion to act one way or the other. It remains to be seen whether this is an isolated incident or whether this is a sign of a deeper disconnect that will cause increasing friction going forward.

The post What the heck happened with .org? appeared first on The Mozilla Blog.

Daniel Stenbergcurl ootw: -Y, –speed-limit

(Previous options of the week)

Today we take a closer look at one of the real vintage curl options. It was added already in early 1999. -Y for short, --speed-limit is the long version. This option needs an additional argument: <speed>. Let me describe exactly what that speed is and how it works below.

Slow or stale transfers

Very early on in curl’s lifetime, it became obvious to us that lots of times when you use curl in order to do an Internet transfer, that transfer could sometimes take a long time. Occasionally even ridiculously long times and it could seem that the transfers just stalled without any hope of resurrecting and completing its mission.

How do you tell curl to abandon such lost-hope transfers? The options we provide for timeouts provide one answer. But since the transfer speeds can vary greatly from time to time and machine to machine, you have to use a timeout value that uses an insane margin, which for the cases when everything flies fast turns out annoying.

We needed another way to detect and abort these stale transfers. Enter speed limit.

Lower than speed-limit bytes per second during speed-time

The --speed-limit <speed> you tell curl is the transfer speed threshold below which you think the transfer is untypically slow, specified as bytes per second. If you have a really fast Internet, you might for example think that a transfer that is below 1000 bytes/second is a sign of something not being right.

But just measuring a the transfer speed to be below that special threshold in a single snapshot is not a strong enough signal for curl to act on it. The speed also needs to be measure below that threshold during --limit-time <seconds>. If the transfer speed just incidentally sometimes and very quickly drops below the threshold (bad wifi?) that’s not a reason for concern. The default limit time (when --limit-speed is used without --limit-time set) is 30. The transfer speed needs to be measured below the threshold for that many consecutive seconds (and it samples once per second).

If curl deems that your transfer speed was too slow during the given period, it will break the transfer and return 28. Timeout.

These two options are entirely protocol independent and work for all transfers using any of the protocols curl supports.

Examples

Tell curl to give up the transfer if slower than 1000 bytes per second during 20 seconds:

curl --speed-limit 1000 --speed-time 20 https://example.com

Tell curl to give up the transfer if slower than 100000 bytes per second during 60 seconds:

curl --speed-limit 100000 --speed-time 60 https://example.com

It also works the same for uploads. If the speed is below 2000 bytes per second during 45 seconds, abort:

curl --speed-limit 2000 --speed-time 45 ftp://example.com/upload/ -T sendaway.txt

Related options

--max-time and --connect-timeout are options with similar functionality and purpose, and you can indeed in many cases add those as well.

Spidermonkey Development BlogSpiderMonkey Newsletter 4 (Firefox 76-77)

SpiderMonkey is the JavaScript engine used in Mozilla Firefox. This newsletter gives an overview of the JavaScript and WebAssembly work we’ve done as part of the Firefox 76 and 77 Nightly cycles.

JavaScript

🏆 New contributors

🎁 New features

🗑️ Garbage Collection

  • Jon made various changes to GC heuristics to avoid non-incremental GCs.
  • Steve landed and enabled incremental marking for WeakMaps, a big change that will help reduce long GC slices, but to reduce risk this was backed out for Firefox 77. We’re hoping this sticks in Firefox 78!
  • Jon made tracing of ‘auto rooters’ faster. He also noticed regressions on Linux64 from parallel unmarking and made performance improvements to fix that.
  • Jon optimized tracing of certain DOM objects in Firefox by allowing per-Zone tracing instead of tracing all of them.
  • Jon fixed various OOM (out of memory) crashes by adding memory accounting for malloc buffers associated with nursery cells and by improving GC malloc triggers.
  • Steve updated the static analysis for rooting hazards to GCC 9.

⏩ Regular expression engine update

Iain finished implementing the SpiderMonkey shims and JIT support for the new regular expression engine and is planning to land these in the FF 78 cycle to switch to the new engine in Nightly! This will bring support for lookbehind assertions, the dotAll flag and unicode escape sequences.

Iain has also started working on supporting named groups and match indices.

📚 JSScript/LazyScript unification

With all the groundwork in place (see previous newsletters), Ted was able to unify JSScript and LazyScript! Functions no longer require a separate LazyScript and JSScript and delazification and relazification now happen in-place.

He then removed the LazyScript type completely and landed various follow-up changes to take advantage of the new system.

❇️ Stencil

Stencil is our project to create an interface between the frontend (parser, bytecode emitter) and the rest of the VM, decoupling those components. This lets us improve performance, simplify a lot of code and improve bytecode caching. It also makes it possible to rewrite our frontend in Rust (see SmooshMonkey item below).

The team is making good progress:

  • Caroline split the script flags into multiple categories so it’s easier to assert correctness and reason about them. She also made various other changes to improve the script flags.
  • Ted also simplified some flags and then fixed their documentation.
  • Matthew removed more dependencies on JSScript and was then able to defer JSScript allocation to a later point in the bytecode emitter.
  • Matthew disconnected FunctionBox from ScriptStencil and started removing dependencies on JSFunction. This will allow us to defer JSFunction allocation as well.
  • André finished deferring RegExpObject allocation, unlocking more code simplifications.
  • Jason and Caroline landed changes to make ImmutableScriptData a part of the Stencil interface instead of its field being duplicated in ScriptStencil.
  • Kannan is making progress removing the frontend dependency on JSAtoms.

🐒 SmooshMonkey

SmooshMonkey is a reimplementation of the front end, with the goal of making it easier to add new features to the engine, and improve the long term perspective of maintaining the codebase. \

🚀 WarpBuilder

WarpBuilder is the JIT project to replace the frontend of our optimizing JIT (IonBuilder) and Type Inference with a new MIR builder based on compiling CacheIR to MIR. WarpBuilder will let us improve security, performance, memory usage and maintainability of the whole engine.

  • Jan implemented support for most bytecode instructions (the slow paths) and added a tier 2 ‘warp’ job to Treeherder that runs jit-tests with WarpBuilder enabled.
  • Jan added the CacheIR Transpiler for transpiling CacheIR to MIR and started using it for certain instructions.
  • Tom implemented support for various GetProp, GetElem cases in the transpiler.
  • Jan moved the list of all CacheIR instructions into a YAML file and used this to auto-generate reader/writer boilerplate and better debug printing code. This makes it easier and less error-prone to add new CacheIR instructions and to support new instructions in the transpiler.

💣 Exception handling improvements

  • Tom removed the “extra warnings” mode. If the pref for this was enabled, the engine would report warnings in certain situations. Modern linters do a better job at many of these things.
  • Tom then removed the “werror” (warnings-as-errors) mode.
  • Tom fixed location information for non-error uncaught exceptions.
  • Tom is now working on making it possible to inspect uncaught exceptions in the Web Console. Nicolas from the DevTools team is implementing the Console UI code for this.

📈 Miscellaneous performance improvements

  • Jeff changed the UTF-8 parsing functions to never inflate to UTF-16.
  • Ted removed metadata source notes from self-hosted code. This saved about 40 KB per process.
  • Tom implemented CacheIR support for binary operations involving a number and string to speed up paper.io
  • André moved the Object.prototype.__proto__ getter to self-hosted code so it benefits from JIT inlining support for getPrototypeOf.
  • Christian fixed some slow logging code that affected all debug builds.
  • André improved CacheIR support for JSOp::Pow (the **-operator).
  • André added CacheIR support for JSop::Pos (the +-operator) and optimized +string (to convert strings to numbers).
  • Jan added CacheIR support for JSOp::ToNumeric to improve WarpBuilder code generation.

🧹 Miscellaneous code cleanups

  • Arai converted the source notes code from old C macros to modern C++.
  • Jeff landed a lot of patches to clean up object creation code.
  • André removed a lot of dead code from various MIR instructions.
  • Tom continued converting some ancient jsid functions to PropertyKey methods.
  • Ted added a TrailingArray type and used it for various classes with variable-size trailing arrays.
  • André converted code to use <type_traits> instead of our own mfbt/TypeTraits.h
  • Jeff started using the C++17 if/switch statements with initializers.
  • André and Jan simplified some code with C++17 fold expressions.
  • Jon converted code using std type traits to the more concise *_v and *_t versions since C++17.
  • Jon gave all Cells a CellHeader type for the first word to improve the safety of GC flags and to make the code easier to understand.

✏️ Miscellaneous

  • Jason worked around a CPU bug that affected the bytecode emitter.
  • Yoshi is making changes to the helper thread system to make it possible to eventually use Gecko’s shared thread pool for SpiderMonkey’s background tasks.
  • Jeff is landing code changes for ReadableStream pipeTo/pipeThrough support.
  • Jeff and Tom Tung are working on conditionally hiding the SharedArrayBuffer constructor.
  • A last minute time zone data update made it just in time for Firefox 76. Big thanks to the release team for their prompt reaction!
  • Matthew added in-tree documentation on how to build and test the SpiderMonkey shell with mach.

WebAssembly

🏗︎ Cranelift

Cranelift is a low-level code generator written in Rust. While available in Firefox Nightly as backend for WebAssembly with the right about:config prefs, Cranelift is disabled by default, being still a work-in-progress. We’re continuing to refine performance and fill in some additional feature support before making this the default setting.

Experimental WebAssembly (MVP) support for the AArch64 (ARM64) instruction set has landed in Cranelift and in Firefox, and large WebAssembly programs can now run correctly using it!

The new backend also brings with it an updated machine-backend design for Cranelift, which we believe will make future work and contributions easier to develop. We’ve developed a new register allocator as part of this that is designed to be a reusable library (Rust crate) called regalloc.rs. Finally, the AArch64 support also benefits other users of Cranelift, such as Wasmtime.

This is the result of months of work carried out by Chris, Julian and Benjamin, with the help of Joey Gouly (of ARM).

William LachanceA principled reorganization of docs.telemetry.mozilla.org

(this post is aimed primarily at an internal audience, but I thought I’d go ahead and make it public as a blog post)

I’ve been thinking a bunch over the past few months about the Mozilla data organization’s documentation story. We have a first class data platform here at Mozilla, but using it to answer questions, especially for newer employees, can be quite intimidating. As we continue our collective journey to becoming a modern data-driven organization, part of the formula for unlocking this promise is making the tools and platforms we create accessible to a broad internal audience.

My data peers are a friendly group of people and we have historically been good at answering questions on forums like the #fx-metrics slack channel: we’ll keep doing this. That said, our time is limited: we need a common resource for helping bring people up to speed on how to use the data platform to answer common questions.

Our documentation site, docs.telemetry.mozilla.org, was meant to be this resource: however in the last couple of years an understanding of its purpose has been (at least partially) lost and it has become somewhat overgrown with content that isn’t very relevant to those it’s intended to help.

This post’s goal is to re-establish a mission for our documentation site — towards the end, some concrete proposals on what to change are also outlined.

Setting the audience

docs.telemetry.mozilla.org was and is meant to be a resource useful for data practitioners within Mozilla.

Examples of different data practioners and their use cases:

  • A data scientist performing an experiment analysis
  • A data analyst producing a report on the effectiveness of a recent marketing campaign
  • A Firefox engineer trying to understand the performance characteristics of a new feature
  • A technical product manager trying to understand the characteristics of a particular user segment
  • A quality assurance engineer trying to understand the severity of a Firefox crash

There are a range of skills that these different groups bring to the table, but there are some common things we expect a data practitioner to have, whatever their formal job description:

  • At least some programming and analytical experience
  • Comfortable working with and understanding complex data systems with multiple levels of abstraction (for example: the relationship between the Firefox browser which produces Telemetry data and the backend system which processes it)
  • The time necessary to dig into details

This also excludes a few groups:

  • Senior leadership or executives: they are of course free to use docs.telemetry.mozilla.org if helpful, but it is expected that the type of analytical work covered by the documentation will normally be done by a data practitioner and that relevant concepts and background information will be explained to them (in the form of high-level dashboards, presentations, etc.).
  • Data Engineering: some of the material on docs.telemetry.mozilla.org may be incidentally useful to this internal audience, but explaining the full details of the data platform itself belongs elsewhere.

What do these users need?

In general, a data practitioner is trying to answer a specific set of questions in the context of an exploration. There are a few things that they need:

  • A working knowledge of how to use the technological tools to answer the questions they might have: for example, how to create a SQL query counting the median value of a particular histogram for a particular usage segment.
  • A set of guidelines on best practices on how to measure specific things: for example, we want our people using our telemetry systems to use well-formulated practices for measuring things like “Monthly Active Users” rather than re-inventing such things themselves.

What serves this need?

A few years ago, Ryan Harter did an extensive literature review on writing documentation on technical subjects - the take away from this exploration is that the global consensus is that we should focus most of our attention on writing practical tutorials which enables our users to perform specific tasks in the service of the above objective.

There is a proverb, allegedly attributed to Confucius which goes something like this:

“I hear and I forget. I see and I remember. I do and I understand.”

The understanding we want to build is how to use our data systems and tools to answer questions. Some knowledge of how our data platform works is no doubt necessary to accomplish this, but it is mostly functional knowledge we care about imparting to data practitioners: the best way to build this understanding is to guide users in performing tasks.

This makes sense intuitively, but it is also borne out by the data that this is what our users are looking for. Looking through the top pages on Google Analytics, virtually all of them1 refer either to a cookbook or howto guide:

Happily, this allows us to significantly narrow our focus for docs.telemetry.mozilla.org. We no longer need to worry about:

  • Providing lists or summaries of data tools available inside Mozilla2: we can talk about tools only as needed in the context of tasks they want to accomplish. We may want to keep such a list handy elsewhere for some other reason (e.g. internal auditing purposes), but we can safely say that it belongs somewhere else, like the Mozilla wiki, mana, or the telemetry.mozilla.org portal.
  • Detailed reference on the technical details of the data platform implementation. Links to this kind of material can be surfaced inside the documentation where relevant, but it is expected that an implementation reference will normally be stored and presented within the context of the tools themselves (a good example would be the existing documentation for GCP ingestion).
  • Detailed reference on all data sets, ping types, or probes: hand-written documentation for this kind of information is difficult to keep up to date with manual processes3 and is best generated automatically and browsed with tools like the probe dictionary.
  • Detailed reference material on how to submit Telemetry. While an overview of how to think about submitting telemetry may be in scope (recall that we consider Firefox engineers a kind of data practitioner), the details are really a seperate topic that is better left to another resource which is closer to the implementation (for example, the Firefox Source Documentation or the Glean SDK reference).

Scanning through the above, you’ll see a common theme: avoid overly detailed reference material. The above is not to say that we should avoid background documentation altogether. For example, an understanding of how our data pipeline works is key to understanding how up-to-date a dashboard is expected to be. However, this type of documentation should be written bearing in mind the audience (focusing on what they need to know as data practitioners) and should be surfaced towards the end of the documentation as supporting material.

As an exception, there is also a very small amount of reference documentation which we want to put at top-level because it is so important: for example the standard metrics page describes how we define “MAU” and “DAU”: these are measures that we want to standardize in the organization, and not have someone re-invent every time they produce an analysis or report. However, we should be very cautious about how much of this “front facing” material we include: if we overwhelm our audience with details right out of the gate, they are apt to ignore them.

Concrete actions

  • We should continue working on tutorials on how to perform common tasks: this includes not only the low-level guides that we currently have (e.g. BigQuery and SQL tutorials) but also information on how to effectively use our higher-level, more accessible tools like GLAM and GUD to answer questions.
  • Medium term, we should remove the per-dataset documentation and replace it with a graphical tool for browsing this type of information (perhaps Google Data Catalog). Since this is likely to be a rather involved project, we can keep the existing documentation for now — but for new datasets, we should encourage their authors to write tutorials on how to use them effectively (assuming they are of broad general interest) instead of hand-creating schema definitions that are likely to go out of date quickly.
  • We should set clear expectations and guidelines of what does and doesn’t belong on docs.telemetry.mozilla.org as part of a larger style guide. This style guide should be referenced somewhere prominent (perhaps as part of a pull request template) so that historical knowledge of what this resource is for isn’t lost.

Footnotes

  1. For some reason which I cannot fathom, a broad (non-Mozilla) audience seems unusually interested in our SQL style guide. 

  2. The current Firefox data documentation has a project glossary that is riddled with links to obsolete and unused projects. 

  3. docs.telemetry.mozilla.org has a huge section devoted to derived datasets (20+), many of which are obsolete or not recommended. At the same time, we are missing explicit reference material for the most commonly used tables in BigQuery (e.g. telemetry.main). 

Daniel StenbergManual cURL cURL

The HP Color LaserJet CP3525 Printer looks like any other ordinary printer done by HP. But there’s a difference!

A friend of mine fell over this gem, and told me.

TCP/IP Settings

If you go to the machine’s TCP/IP settings using the built-in web server, the printer offers the ordinary network configure options but also one that sticks out a little exta. The “Manual cURL cURL” option! It looks like this:

I could easily confirm that this is genuine. I did this screenshot above by just googling for the string and printer model, since there appears to exist printers like this exposing their settings web server to the Internet. Hilarious!

What?

How on earth did that string end up there? Certainly there’s no relation to curl at all except for the actual name used there? Is it a sign that there’s basically no humans left at HP that understand what the individual settings on that screen are actually meant for?

Given the contents in the text field, a URL containing the letters WPAD twice, I can only presume this field is actually meant for Web Proxy Auto-Discovery. I spent some time trying to find the user manual for this printer configuration screen but failed. It would’ve been fun to find “manual cURL cURL” described in a manual! They do offer a busload of various manuals, maybe I just missed the right one.

Does it use curl?

Yes, it seems HP generally use curl at least as I found the “Open-Source Software License Agreements for HP LaserJet and ScanJet Printers” and it contains the curl license:

<figcaption>The curl license as found in the HP printer open source report.</figcaption>

HP using curl for Print-Uri?

Independently, someone else recently told me about another possible HP + curl connection. This user said his HP printer makes HTTP requests using the user-agent libcurl-agent/1.0:

I haven’t managed to get this confirmed by anyone else (although the license snippet above certainly implies they use curl) and that particular user-agent string has been used everywhere for a long time, as I believe it is copied widely from the popular libcurl example getinmemory.c where I made up the user-agent and put it there already in 2004.

Credits

Frank Gevaerts tricked me into going down this rabbit hole as he told me about this string.

Ludovic HirlimannRecommendations are moving entities

At my new job we publish an open source webapp map systems uxing a mix of technologies, we also offer it as SAS. Last Thursday I looked at how our Nginx server was configured TLS wise.

I was thrilled to see the comment in our nginx code saying the configuration had been built using mozilla's ssl config tool. At the same time I was shocked to see that the configuration that dated from early 2018 was completely out of date. Half of the ciphers were gone. So we took a modern config and applied it.

Once done we turned ourselves to the observatory to check out our score, and me and my colleague were disappointed to get an F. So we fixed what we could easily (the cyphers) and added an issue to our product to make it more secure for our users.

We'll also probably add a calendar entry to check our score on a regular basis, as the recommendation will change, our software configuration will change too.

Mozilla Security BlogMay 2020 CA Communication

Mozilla has sent a CA Communication and Survey to inform Certification Authorities (CAs) who have root certificates included in Mozilla’s program about current expectations. Additionally this survey will collect input from CAs on potential changes to Mozilla’s Root Store Policy. This CA communication and survey has been emailed to the Primary Point of Contact (POC) and an email alias for each CA in Mozilla’s program, and they have been asked to respond to the following items:

  1. Review guidance about actions a CA should take if they realize that mandated restrictions regarding COVID-19 will impact their audits or delay revocation of certificates.
  2. Inform Mozilla if their CA’s ability to fulfill the commitments that they made in response to the January 2020 CA Communication has been impeded.
  3. Provide input into potential policy changes that are under consideration, such as limiting maximum lifetimes for TLS certificates and limiting the re-use of domain name verification.

The full communication and survey can be read here. Responses to the survey will be automatically and immediately published by the CCADB.

With this CA Communication, we reiterate that participation in Mozilla’s CA Certificate Program is at our sole discretion, and we will take whatever steps are necessary to keep our users safe. Nevertheless, we believe that the best approach to safeguard that security is to work with CAs as partners, to foster open and frank communication, and to be diligent in looking for ways to improve.

The post May 2020 CA Communication appeared first on Mozilla Security Blog.

Data@MozillaThis Week in Glean: mozregression telemetry (part 2)

(“This Week in Glean” is a series of blog posts that the Glean Team at Mozilla is using to try to communicate better about our work. They could be release notes, documentation, hopes, dreams, or whatever: so long as it is inspired by Glean. You can find an index of all TWiG posts online.)

This is a special guest post by non-Glean-team member William Lachance!

This is a continuation of an exploration of adding Glean-based telemetry to a python application, in this case mozregression, a tool for automatically finding the source of Firefox regressions (breakage).

When we left off last time, we had written some test scripts and verified that the data was visible in the debug viewer.

Adding Telemetry to mozregression itself

In many ways, this is pretty similar to what I did inside the sample application: the only significant difference is that these are shipped inside a Python application that is meant to be be installable via pip. This means we need to specify the pings.yaml and metrics.yaml (located inside the mozregression subirectory) as package data inside setup.py:

setup(
    name="mozregression",
    ...
    package_data={"mozregression": ["*.yaml"]},
    ...
)

There were also a number of Glean SDK enhancements which we determined were necessary. Most notably, Michael Droettboom added 32-bit Windows wheels to the Glean SDK, which we need to make building the mozregression GUI on Windows possible. In addition, some minor changes needed to be made to Glean’s behaviour for it to work correctly with a command-line tool like mozregression — for example, Glean used to assume that Telemetry would always be disabled via a GUI action so that it would send a deletion ping, but this would obviously not work in an application like mozregression where there is only a configuration file — so for this case, Glean needed to be modified to check if it had been disabled between runs.

Many thanks to Mike (and others on the Glean team) for so patiently listening to my concerns and modifying Glean accordingly.

Getting Data Review

At Mozilla, we don’t just allow random engineers like myself to start collecting data in a product that we ship (even a semi-internal like mozregression). We have a process, overseen by Data Stewards to make sure the information we gather is actually answering important questions and doesn’t unnecessarily collect personally identifiable information (e.g. email addresses).

You can see the specifics of how this worked out in the case of mozregression in bug 1581647.

Documentation

Glean has some fantastic utilities for generating markdown-based documentation on what information is being collected, which I have made available on GitHub:

https://github.com/mozilla/mozregression/blob/master/docs/glean/metrics.md

The generation of this documentation is hooked up to mozregression’s continuous integration, so we can sure it’s up to date.

I also added a quick note to mozregression’s web site describing the feature, along with (very importantly) instructions on how to turn it off.

Enabling Data Ingestion

Once a Glean-based project has passed data review, getting our infrastructure to ingest it is pretty straightforward. Normally we would suggest just filing a bug and let us (the data team) handle the details, but since I’m on that team, I’m going to go a (little bit) of detail into how the sausage is made.

Behind the scenes, we have a collection of ETL (extract-transform-load) scripts in the probe-scraper repository which are responsible for parsing the ping and probe metadata files that I added to mozregression in the step above and then automatically creating BigQuery tables and updating our ingestion machinery to insert data passed to us there.

There’s quite a bit of complicated machinery being the scenes to make this all work, but since it’s already in place, adding a new thing like this is relatively simple. The changeset I submitted as part of a pull request to probe-scraper was all of 9 lines long:

diff --git a/repositories.yaml b/repositories.yaml
index dffcccf..6212e55 100644
--- a/repositories.yaml
+++ b/repositories.yaml
@@ -239,3 +239,12 @@ firefox-android-release:
     - org.mozilla.components:browser-engine-gecko-beta
     - org.mozilla.appservices:logins
     - org.mozilla.components:support-migration
+mozregression:
+  app_id: org-mozilla-mozregression
+  notification_emails:
+    - wlachance@mozilla.com
+  url: 'https://github.com/mozilla/mozregression'
+  metrics_files:
+    - 'mozregression/metrics.yaml'
+  ping_files:
+    - 'mozregression/pings.yaml'

A Pretty Graph

With the probe scraper change merged and deployed, we can now start querying! A number of tables are automatically created according to the schema outlined above: notably “live” and “stable” tables corresponding to the usage ping. Using sql.telemetry.mozilla.org we can start exploring what’s out there. Here’s a quick query I wrote up:

SELECT DATE(submission_timestamp) AS date,
       metrics.string.usage_variant AS variant,
       count(*),
FROM `moz-fx-data-shared-prod`.org_mozilla_mozregression_stable.usage_v1
WHERE DATE(submission_timestamp) >= '2020-04-14'
  AND client_info.app_display_version NOT LIKE '%.dev%'
GROUP BY date, variant;

Generating a chart like this:

This chart represents the absolute volume of mozregression usage since April 14th 2020 (around the time when we first released a version of mozregression with Glean telemetry), grouped by mozregression “variant” (GUI, console, and mach) and date – you can see that (unsurprisingly?) the GUI has the highest usage.

Next Steps

We’re not done yet! Next time, we’ll look into making a public-facing dashboard demonstrating these results and making an aggregated version of the mozregression telemetry data publicly accessible to researchers and the general public. If we’re lucky, there might even be a bit of data science. Stay tuned!

(( This is a syndicated copy of the original post. ))

William LachanceThis Week in Glean: mozregression telemetry (part 2)

(“This Week in Glean” is a series of blog posts that the Glean Team at Mozilla is using to try to communicate better about our work. They could be release notes, documentation, hopes, dreams, or whatever: so long as it is inspired by Glean. You can find an index of all TWiG posts online.)

This is a special guest post by non-Glean-team member William Lachance!

This is a continuation of an exploration of adding Glean-based telemetry to a python application, in this case mozregression, a tool for automatically finding the source of Firefox regressions (breakage).

When we left off last time, we had written some test scripts and verified that the data was visible in the debug viewer.

Adding Telemetry to mozregression itself

In many ways, this is pretty similar to what I did inside the sample application: the only significant difference is that these are shipped inside a Python application that is meant to be be installable via pip. This means we need to specify the pings.yaml and metrics.yaml (located inside the mozregression subirectory) as package data inside setup.py:

setup(
    name="mozregression",
    ...
    package_data={"mozregression": ["*.yaml"]},
    ...
)

There were also a number of Glean SDK enhancements which we determined were necessary. Most notably, Michael Droettboom added 32-bit Windows wheels to the Glean SDK, which we need to make building the mozregression GUI on Windows possible. In addition, some minor changes needed to be made to Glean’s behaviour for it to work correctly with a command-line tool like mozregression — for example, Glean used to assume that Telemetry would always be disabled via a GUI action so that it would send a deletion ping, but this would obviously not work in an application like mozregression where there is only a configuration file — so for this case, Glean needed to be modified to check if it had been disabled between runs.

Many thanks to Mike (and others on the Glean team) for so patiently listening to my concerns and modifying Glean accordingly.

Getting Data Review

At Mozilla, we don’t just allow random engineers like myself to start collecting data in a product that we ship (even a semi-internal like mozregression). We have a process, overseen by Data Stewards to make sure the information we gather is actually answering important questions and doesn’t unnecessarily collect personally identifiable information (e.g. email addresses).

You can see the specifics of how this worked out in the case of mozregression in bug 1581647.

Documentation

Glean has some fantastic utilities for generating markdown-based documentation on what information is being collected, which I have made available on GitHub:

https://github.com/mozilla/mozregression/blob/master/docs/glean/metrics.md

The generation of this documentation is hooked up to mozregression’s continuous integration, so we can sure it’s up to date.

I also added a quick note to mozregression’s web site describing the feature, along with (very importantly) instructions on how to turn it off.

Enabling Data Ingestion

Once a Glean-based project has passed data review, getting our infrastructure to ingest it is pretty straightforward. Normally we would suggest just filing a bug and let us (the data team) handle the details, but since I’m on that team, I’m going to go a (little bit) of detail into how the sausage is made.

Behind the scenes, we have a collection of ETL (extract-transform-load) scripts in the probe-scraper repository which are responsible for parsing the ping and probe metadata files that I added to mozregression in the step above and then automatically creating BigQuery tables and updating our ingestion machinery to insert data passed to us there.

There’s quite a bit of complicated machinery being the scenes to make this all work, but since it’s already in place, adding a new thing like this is relatively simple. The changeset I submitted as part of a pull request to probe-scraper was all of 9 lines long:

diff --git a/repositories.yaml b/repositories.yaml
index dffcccf..6212e55 100644
--- a/repositories.yaml
+++ b/repositories.yaml
@@ -239,3 +239,12 @@ firefox-android-release:
     - org.mozilla.components:browser-engine-gecko-beta
     - org.mozilla.appservices:logins
     - org.mozilla.components:support-migration
+mozregression:
+  app_id: org-mozilla-mozregression
+  notification_emails:
+    - wlachance@mozilla.com
+  url: 'https://github.com/mozilla/mozregression'
+  metrics_files:
+    - 'mozregression/metrics.yaml'
+  ping_files:
+    - 'mozregression/pings.yaml'

A Pretty Graph

With the probe scraper change merged and deployed, we can now start querying! A number of tables are automatically created according to the schema outlined above: notably “live” and “stable” tables corresponding to the usage ping. Using sql.telemetry.mozilla.org we can start exploring what’s out there. Here’s a quick query I wrote up:

SELECT DATE(submission_timestamp) AS date,
       metrics.string.usage_variant AS variant,
       count(*),
FROM `moz-fx-data-shared-prod`.org_mozilla_mozregression_stable.usage_v1
WHERE DATE(submission_timestamp) >= '2020-04-14'
  AND client_info.app_display_version NOT LIKE '%.dev%'
GROUP BY date, variant;

… which generates a chart like this:

This chart represents the absolute volume of mozregression usage since April 14th 2020 (around the time when we first released a version of mozregression with Glean telemetry), grouped by mozregression “variant” (GUI, console, and mach) and date - you can see that (unsurprisingly?) the GUI has the highest usage. I’ll talk about this more in an upcoming installment, speaking of…

Next Steps

We’re not done yet! Next time, we’ll look into making a public-facing dashboard demonstrating these results and making an aggregated version of the mozregression telemetry data publicly accessible to researchers and the general public. If we’re lucky, there might even be a bit of data science. Stay tuned!

Wladimir PalantWhat data does Xiaomi collect about you?

A few days ago I published a very technical article confirming that Xiaomi browsers collect a massive amount of private data. This fact was initially publicized in a Forbes article based on the research by Gabriel Cîrlig and Andrew Tierney. After initially dismissing the report as incorrect, Xiaomi has since updated their Mint and Mi Pro browsers to include an option to disable this tracking in incognito mode.

Xiaomi demonstrating a privacy fig leaf<figcaption> Image credits: 1mran IN, Openclipart </figcaption>

Is the problem solved now? Not really. There is now exactly one non-obvious setting combination where you can have your privacy with these browsers: “Incognito Mode” setting on, “Enhanced Incognito Mode” setting off. With these not being the default and the users not informed about the consequences, very few people will change to this configuration. So the browsers will continue spying on the majority of their user base.

In this article I want to provide a high-level overview of the data being exfiltrated here. TL;DR: Lots and lots of it.

Disclaimer: This article is based entirely on reverse engineering Xiaomi Mint Browser 3.4.3. I haven’t seen the browser in action, so some details might be wrong. Update (2020-05-08): From a quick glance at Xiaomi Mint Browser 3.4.4 which has been released in the meantime, no further changes to this functionality appear to have been implemented.

Event data

When allowed, Xiaomi browsers will send information about a multitude of different events, sometimes with specific data attached. For example, an event will typically be generated when some piece of the user interface shows up or is clicked, an error occurs or the current page’s address is copied to clipboard. There are more interesting events as well however, for example:

  • A page started or finished loading, with the page address attached
  • Change of default search engine, with old and new search engines attached
  • Search via the navigation bar, with the search query attached
  • Reader mode switched on, with the page address attached
  • A tab clicked, with the tab name attached
  • A page being shared, with the page address attached
  • Reminder shown to switch on Incognito Mode, with the porn site that triggered the reminder attached
  • YouTube searches, with the search query attached
  • Video details for a YouTube video opened or closed, with video ID attached
  • YouTube video played, with video ID attached
  • Page or file downloaded, with the address attached
  • Speed dial on the homepage clicked, added or modified, with the target address attached

Generic annotations

Some pieces of data will be attached to every event. These are meant to provide the context, and to group related events of course. This data includes among other things:

  • A randomly generated identifier that is unique to your browser instance. While this identifier is supposed to change every 90 days, this won’t actually happen due to a bug. In most cases, it should be fairly easy to recognize the person behind the identifier.
  • An additional device identifier (this one will stay unchanged even if app data is cleared)
  • If you are logged into your Mi Account: the identifier of this account
  • The exact time of the event
  • Device manufacturer and model
  • Browser version
  • Operating system version
  • Language setting of your Android system
  • Default search engine
  • Mobile network operator
  • Network type (wifi, mobile)
  • Screen size

Conclusions

Even with the recent changes, Xiaomi browsers are massively invading users’ privacy. The amount of data collected by default goes far beyond what’s necessary for application improvement. Instead, Xiaomi appears to be interested in where users go, what they search for and which videos they watch. Even with a fairly obscure setting to disable this tracking, the default behavior isn’t acceptable. If you happen to be using a Xiaomi device, you should install a different browser ASAP.

Daniel Stenbergvideo: common mistakes when using libcurl

As I posted previously, I did a webinar and here’s the recording and the slides I used for it.

The slides.

The Talospace ProjectFirefox 76 on POWER

Firefox 76 is released. Besides other CSS, HTML and developer features, it refines that somewhat obnoxious zooming bar a bit, improves Picture-in-Picture further (great for livestreams: using it a lot for church), and most notably adds critical alerts for website breaches and improved password security (both generating good secure passwords and notifying you when a password used on one or other sites may have been stolen). The .mozconfigs are unchanged from Firefox 67, which is good news, because we've been stable without changing build options for quite a while at this point and we might be able to start investigating why some build options fail which should function. In particular, PGO and LTO would be nice to get working.

Daniel Stenbergqlog with curl

I want curl to be on the very bleeding edge of protocol development to aid the Internet protocol development community to test out protocols early and to work out kinks in the protocols and server implementations using curl’s vast set of tools and switches.

For this, curl supported HTTP/2 really early on and helped shaping the protocol and testing out servers.

For this reason, curl supports HTTP/3 already since August 2019. A convenient and well-known client that you can then use to poke on your brand new HTTP/3 servers too and we can work on getting all the rough edges smoothed out before the protocol is reaching its final state.

QUIC tooling

One of the many challenges QUIC and HTTP/3 have is that with a new transport protocol comes entirely new paradigms. With new paradigms like this, we need improved or perhaps even new tools to help us understand the network flows back and forth, to make sure we all have a common understanding of the protocols and to make sure we implement our end-points correctly.

QUIC only exists as an encrypted-only protocol, meaning that we can no longer easily monitor and passively investigate network traffic like before, QUIC also encrypts more of the protocol than TCP + TLS do, leaving even less for an outsider to see.

The current QUIC analyzer tool lineup gives us two options.

Wireshark

We all of course love Wireshark and if you get a very recent version, you’ll be able to decrypt and view QUIC network data.

With curl, and a few other clients, you can ask to get the necessary TLS secrets exported at run-time with the SSLKEYLOGFILE environment variable. You’ll then be able to see every bit in every packet. This way to extract secrets works with QUIC as well as with the traditional TCP+TLS based protocols.

qvis/qlog

The qvis/qlog site. If you find the Wireshark network view a little bit too low level and leaving a lot for you to understand and draw conclusions from, the next-level tool here is the common QUIC logging format called qlog. This is an agreed-upon common standard to log QUIC traffic, which the accompanying qvis web based visualizer tool that lets you upload your logs and get visualizations generated. This becomes extra powerful if you have logs from both ends!

Starting with this commit (landed in the git master branch on May 7, 2020), all curl builds that support HTTP/3 – independent of what backend you pick – can be told to output qlogs.

Enable qlogging in curl by setting the new standard environment variable QLOGDIR to point to a directory in which you want qlogs to be generated. When you run curl then, you’ll get files creates in there named as [hex digits].log, where the hex digits is the “SCID” (Source Connection Identifier).

Credits

qlog and qvis are spear-headed by Robin Marx. qlogging for curl with Quiche was pushed for by Lucas Pardue and Alessandro Ghedini. In the ngtcp2 camp, Tatsuhiro Tsujikawa made it very easy for me to switch it on in curl.

The top image is snapped from the demo sample on the qvis web site.

The Mozilla BlogMozilla research shows some machine voices score higher than humans

This blog post is to accompany the publication of the paper Choice of Voices: A Large-Scale Evaluation of Text-to-Speech Voice Quality for Long-Form Content in the Proceedings of CHI’20, by Julia Cambre and Jessica Colnago from CMU, Jim Maddock from Northwestern, and Janice Tsai and Jofish Kaye from Mozilla. 

In 2019, Mozilla’s Voice team developed a method to evaluate the quality of text-to-speech voices. It turns out there was very little that had been done in the world of text to speech to evaluate voice for listening to long-form content — things like articles, book chapters, or blog posts. A lot of the existing work answered the core question ofcan you understand this voice?” So a typical test might use a syntactically correct but meaningless sentence, like “The masterly serials withdrew the collaborative brochure”, and have a listener type that in. That way, the listener couldn’t guess missed words from other words in the sentence. But now that we’ve reached a stage of computerized voice quality where so many voices can pass the comprehension test with flying colours, what’s the next step?

How can we determine if a voice is enjoyable to listen to, particularly for long-form content — something you’d listen to for more than a minute or two? Our team had a lot of experience with this: we had worked closely with our colleagues at Pocket to develop the Pocket Listen feature, so you can listen to articles you’ve saved, while driving or cooking. But we still didn’t know how to definitively say that one voice led to a better listening experience than another.

The method we used was developed by our intern Jessica Colnago during her internship at Mozilla, and it’s pretty simple in concept. We took one article, How to Reduce Your Stress in Two Minutes a Day, and we recorded each voice reading that article. Then we had 50 people on Mechanical Turk listen to each recording — 50 different people each time. (You can also listen to clips from most of these recordings to make your own judgement.). Nobody heard the article more than once. And at the end of the article, we’d ask them a couple of questions to check they were actually listening, and to see what they thought about the voice.

For example, we’d ask them to rate how much they liked the voice on a scale of one to five, and how willing they’d be to listen to more content recorded by that voice. We asked them why they thought that voice might be pleasant or unpleasant to listen to. We evaluated 27 voices, and here’s one graph which represents the results. (The paper has lots more rigorous analysis, and we explored various methods to sort the ratings, but the end results are all pretty similar. We also added a few more voices after the paper was finished, which is why there’s different numbers of voices in different places in this research.)

voice comparison graph As you can see, some voices rated better than others. The ones at the left are the ones people consistently rated positively, and the ones at the right are the ones that people liked less: just as examples, you’ll notice that the default (American) iOS female voice is pretty far to the right, although the Mac default voice has a pretty respectable showing. I was proud to find that the Mozilla Judy Wave1 voice, created by Mozilla research engineer Eren Gölge, is rated up there along with some of the best ones in the field. It turns out the best electronic voices we tested are Mozilla’s voices and the Polly Neural voices from Amazon. And while we still have some licensing questions to figure out, making sure we can create sustainable, publicly accessible, high quality voices, it’s exciting to see that we can do something in an open source way that is competitive with very well funded voice efforts out there, which don’t have the same aim of being private, secure and accessible to all.

We found there were some generalizable experiences. Listeners were 54% more likely to give a higher experience rating to the male voices we tested than the female voices. We also looked at the number of words spoken in a minute. Generally, our results indicated that there is a “just right speed” in the range of 163 to 177 words per minute, and people didn’t like listening to voices that were much faster or slower than that.

But the more interesting result comes from one of the things we did at a pretty late stage in the process, which was to include some humans reading the article directly into a microphone. Those are the voices circled in red:

voice comparison graph humans marked

What we found was that some of our human voices were being rated lower than some of the robot voices. And that’s fascinating. That suggests we are at a point in technology, in society right now, where there are mechanically generated voices that actually sound better than humans. And before you ask, I listened to those recordings of human voices. You can do the same. Janice (the recording labelled Human 2 in the dataset) has a perfectly normal voice that I find pleasant to listen to. And yet some people were finding these mechanically generated voices better.

That raises a whole host of interesting questions, concerns and opportunities. This is a snapshot of computerized voices, in the last two years or so. Even since we’ve done this study, we’ve seen the quality of voices improve. What happens when computers are more pleasant to listen to than our own voices? What happens when our children might prefer to listen to our computer reading a story than ourselves?

A potentially bigger ethical question comes with the question of persuasion. One question we didn’t ask in this study was whether people trusted or believed the content that was read to them. What happens when we can increase the number of people who believe something simply by changing the voice that it is read in? There are entire careers exploring the boundaries of influence and persuasion; how does easy access to “trustable” voices change our understanding of what signals point to trustworthiness? The BBC has been exploring British attitudes to regional accents in a similar way — drawing, fascinatingly, from a study of how British people reacted to different voices on the radio in 1927. We are clearly continuing a long tradition of analyzing the impact of voice and voices on how we understand and feel about information.

The post Mozilla research shows some machine voices score higher than humans appeared first on The Mozilla Blog.

Hacks.Mozilla.OrgHigh Performance Web Audio with AudioWorklet in Firefox

Audio Worklets arrive in Firefox

AudioWorklet was first introduced to the web in 2018. Ever since, Mozilla has been investigating how to deliver a “no-compromises” implementation of this feature in the WebAudio API. This week, Audio Worklets landed in the release of Firefox 76. We’re ready to start bridging the gap between what can be done with audio in native applications and what is available on the web.

Now developers can leverage AudioWorklet to write arbitrary audio processing code, enabling the creation of web apps that weren’t possible before. This exciting new functionality raises the bar for emerging web experiences like 3D games, VR, and music production.

Audio worklets bring power and flexibility to general purpose real-time audio synthesis and processing. This begins with the addModule() method to specify a script that can generate audio on the fly or perform arbitrary processing of audio. Various kinds of sources can now be connected through the Web Audio API to an AudioWorkletNode for immediate processing. Source examples include an HTMLMediaElement resource, a local microphone, or remote audio.  Alternatively, the AudioWorklet script itself can be the source of audio.

Benefits

The audio processing code runs on a dedicated real-time system thread for audio processing. This frees the audio from pauses that in the past might have been caused by all the other things happening in the browser.

A process() method registered by the script is called at regular intervals on the real-time thread. Each call provides input and output buffers of PCM (pulse-code modulation) audio samples corresponding to a single AudioContext rendering block.  Processing of input samples produces output samples synchronously. With no latency added to the audio pipeline, we can build more responsive applications. The approach will look familiar to developers experienced with native audio APIs. In native development, this model of registering a callback is ubiquitous. The code registers a callback, which is called by the system to fill in buffers.

Loading a worklet script in an AudioContext, via its AudioWorklet property:


<button>Play</button>
<audio src="t.mp3" controls></audio>
<input type=range min=0.5 max=10 step=0.1 value=0.5></input>
<script>
let ac = new AudioContext;
let audioElement = document.querySelector("audio");
let source = ac.createMediaElementSource(audioElement);

async function play() {
  await ac.audioWorklet.addModule('clipper.js');

  ac.resume();
  audioElement.play();

  let softclipper = new AudioWorkletNode(ac, 'soft-clipper-node');
  source.connect(softclipper).connect(ac.destination);

  document.querySelector("input").oninput = function(e) {
    console.log("Amount is now " + e.target.value);
    softclipper.parameters.get("amount").value = e.target.value;
  }
};

document.querySelector("button").onclick = function() {
  play();
}
</script>

clipper.js: Implementing a soft-clipper that can produce a configurable distortion effect. This is simple with an Audio Worklet, but would use lots of memory done without it:

class SoftClipper extends AudioWorkletProcessor {
  constructor() {
    super()
  }
  static get parameterDescriptors() {
    return [{
      name: 'amount',
      defaultValue: 0.5,
      minValue: 0,
      maxValue: 10,
      automationRate: "k-rate"
    }];
  }
  process(input, output, parameters) {
    // `input` is an array of input ports, each having multiple channels.
    // For each channel of each input port, a Float32Array holds the audio
    // input data.
    // `output` is an array of output ports, each having multiple channels.
    // For each channel of each output port, a Float32Array must be filled
    // to output data.
    // `parameters` is an object having a property for each parameter
    // describing its value over time.
    let amount = parameters["amount"][0];
    let inputPortCount = input.length;
    for (let portIndex = 0; portIndex < input.length; portIndex++) {
      let channelCount = input[portIndex].length;
      for (let channelIndex = 0; channelIndex < channelCount; channelIndex++) {
        let sampleCount = input[portIndex][channelIndex].length;
        for (let sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++) {
          output[0][channelIndex][sampleIndex] =
            Math.tanh(amount * input[portIndex][channelIndex][sampleIndex]);
        }
      }
    }
    return true;
  }
}

registerProcessor('soft-clipper-node', SoftClipper);

Real-time performance

With low latency, however, comes significant responsibility. Let’s draw a parallel from the graphics world, where 60 Hz is the common default screen refresh rate for mobile and desktop devices. Code that determines what to display is expected to run in less than

1000 / 60 = 16.6̇ ms

to ensure no dropped frames.

There are comparable expectations in the audio world. A typical audio system outputs 48000 audio frames per second, and the Web Audio API processes frames in blocks of 128. Thus, all audio computations for 128 frames (the current size of a block in the Web Audio API) must be performed in less than

128 * 1000 / 48000 ≅ 3 ms.

This includes all the process() calls of all the AudioWorkletProcessors in a Web Audio API graph, plus all of the native AudioNode processing.

On modern computers and mobile devices, 3 ms is plenty of time, but some programming patterns are better suited than others for this task. Missing this deadline will cause stuttering in the audio output, which is much more jarring than a dropped frame here and there on a display.

In order to always stay under your time budget, the number one rule of real-time audio programming is “avoid anything that can result in non-deterministic computation time”. Minimize or avoid anything beyond arithmetic operations, other math functions, and reading and writing from buffers.

In particular, for consistent processing times, scripts should keep the frequency of memory allocations to an absolute minimum.  If a working buffer is required, then allocate once and re-use the same buffer for each block of processing. MessagePort communication involves memory allocations, so we suggest you minimize complexity in copied data structures.  Try to do things on the real-time AudioWorklet thread only if absolutely necessary.

Garbage collection

Finally, because JavaScript is a garbage-collected language, and garbage collectors in today’s web browsers are not real-time safe, it’s necessary to minimize the creation of objects that are garbage collectable. This will minimize the non-determinism on the real-time thread.

With that said, the JavaScript JIT compilers and the garbage collectors of current generation JavaScript engines are advanced enough to allow many workloads to just work reliably, with a minimum of care in writing the code. In turn, this allows for rapid prototyping of ideas, or quick demos.

Firefox’s implementation

The principle of minimizing memory allocations, and only doing what is strictly necessary in audio processing, also applies to browser implementations of AudioWorklet.

A mistake in the Web Audio API specification accidentally required creation of new objects on each call to process() for its parameters. This requirement is to be removed from the specification for the sake of performance.  To allow developers to maximize the performance of their apps, Firefox does not create new objects for process() calls unless needed for a change in configuration. Currently, Firefox is the only major browser offering this feature.

If developers are careful to write JavaScript that does not create garbage collectable objects, then the garbage collector in Firefox will never be triggered on the real-time audio processing thread. This is simpler than it sounds, and it’s great for performance. You can use typed arrays, and reuse objects, but don’t use fancy features like promises. These simple pieces of advice go a long way, and only apply to the code that runs on the real-time audio thread.

When building Firefox’s implementation of AudioWorklet, we were extremely critical of the native code paths involved in processing audio.  Great care has been taken to allow developers to ship reliable audio applications on the web. We aim to deliver experiences that are as fast and stable as possible, on all operating systems where Firefox is available.

Several technical investigations supported our performance goals. Here are a few noteworthy ones: Profiling Firefox’s native memory allocation speed; only using threads with real-time priority on the critical path of the audio; and investigating the innards of SpiderMonkey. (SpiderMonkey is the JavaScript virtual machine of Firefox.) This ensures that our JavaScript engine isn’t doing any unbounded operation on the real-time audio threads.

WASM and Workers

The performance and potential of WebAssembly (WASM) is a perfect fit for complex audio processing or synthesis. WASM is available with AudioWorklet. In the professional audio industry, existing signal processing code is overwhelmingly implemented in languages that compile to WASM. Very often, this code is straightforward to compile to WASM and run on the web, because it’s solely doing audio processing. In addition, it is typically designed for a callback interface like what AudioWorklet offers.

For algorithms that need a large batch of processing, and cover significantly more data than a 128-frame block, it is better to split the processing across multiple blocks or perform it in a separate Web Worker thread.  When passing particularly large ArrayBuffers between Worker and AudioWorklet scripts, be sure to transfer ownership to avoid large copies. Then transfer the arrays back to avoid freeing memory on the real-time thread. This approach also avoids the need to allocate new buffers each time.

What’s next for web audio processing

AudioWorklet is the first of three features that will bridge the gap between native and web apps for low-latency audio processing. SharedArrayBuffer and WebAssembly SIMD are two other features that are coming soon to Firefox, and that are very interesting in combination with AudioWorklet. The former, SharedArrayBuffer, enables lock-free programming on the web, which is a technique audio programmers often rely on to reduce non-determinism of their real-time code. The latter, WebAssembly SIMD, will allow speeding up a variety of audio processing algorithms. It’s a technique very frequently found in audio software.

Want to take a closer look at how to use AudioWorklet in your web development work? You’ll find documentation and details of the spec on MDN. To share ideas for the spec, you can visit this WebAudio repo on github. And if you want to get more involved in the WebAudio community, there’s an active webaudio slack for that.

The post High Performance Web Audio with AudioWorklet in Firefox appeared first on Mozilla Hacks - the Web developer blog.

The Rust Programming Language BlogAnnouncing Rust 1.43.1

The Rust team has published a new point release of Rust, 1.43.1. 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.43.1 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.43.1 on GitHub.

What's in Rust 1.43.1

Rust 1.43.1 addresses two regressions introduced in the 1.43.0 stable release, and updates the OpenSSL version used by Cargo.

Fixed undetectable CPU features

Rust 1.27.0 introduced support for detecting x86 CPU features in the standard library, thanks to the is_x86_feature_detected! macro. Due to an internal refactoring, Rust 1.43.0 prevented the detection of features that can't be used on stable yet (such as AVX-512), even though detecting them was allowed in the past. Rust 1.43.1 fixes this regression. More information on the regression in available in issue #71473.

Fixed broken cargo package --list

Rust 1.43.0 broke support for listing the files included in packages published with Cargo, when inside a workspace with path dependencies or unpublished versions. A fix for the issue is included in Rust 1.43.1. More information on the bug is available in Cargo issue #8151.

OpenSSL updated to 1.1.1g

OpenSSL, one of the dependencies of Cargo, recently released a security advisory. Unfortunately we were not able to include the fix in time for Rust 1.43.0, so we upgraded OpenSSL in Rust 1.43.1. We have no evidence this vulnerability could compromise the security of Cargo users (if you do, please follow our security policy).

Contributors to 1.43.1

Many people came together to create Rust 1.43.1. We couldn't have done it without all of you. Thanks!