Daniel Stenberg2015 curl user poll analysis

My full 30 page document with all details and analyses of the curl user poll 2015 is now available. It shows details of all the questions, most of them with a comparison with last year’s survey. The write-ins are also full of good advice, wisdom and some signs of ignorance or unawareness.

I hope all curl hackers and others generally interested in the project can use my “report” to learn something about our users and our user’s view of the project and our products.

Let’s use this to guide us going forward.

keep-calm-and-improve-curl

Byron Joneshappy bmo push day!

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

  • [1166280] max-width missing from bottom-actions, causing “top” and “new bug” buttons misalignment on the right edge of window
  • [1163868] Include requests from others in RequestNagger
  • [1164321] fix chrome issues
  • [1166616] disabling of reviewer last-seen doesn’t work for users that don’t have a last_seen_date
  • [1166777] Script for generating API keys
  • [1166623] move MAX_REVIEWER_LAST_SEEN_DAYS_AGO from a constant to a parameter
  • [1135164] display a warning on show_bug when an unassigned bug has a patch attached
  • [1158513] Script to convert MozReview attachments from parents to children
  • [1168190] “See Also” should accept webcompat.com/issues/ – prefixed URLs

discuss these changes on mozilla.tools.bmo.


Filed under: bmo, mozilla

David AscherNot Technologism, Alchemy.

Heated argument...

A couple of years ago, I was part of a panel with the remarkable Evgeny Morozov, at an event hosted by the Museum of Vancouver.  The event wasn’t remarkable, except that I ended up in a somewhat high-energy debate with Mr. Morozov, without particularly understanding why.  He ascribed to me beliefs I didn’t hold, which made a rigorous intellectual argument (which I generally enjoy) quite elusive and baffling.

It took a follow-up discussion with my political theorist brother to elucidate it.  In particular, he helped me realize that while for decades I’ve described myself as a technologist, depending on your definition of that word, I was misrepresenting myself.  Starting with my first job in my mid teens, my career (modulo an academic side-trip) has essentially been to bring technological skills to bear on a situation.  Using the word technologist to describe myself felt right, without much analysis.  As my brother pointed out, using an academic lexicon, the word technologist can be used to mean “someone who thinks technology is the answer”.  Using that definition, capital is to capitalist as technology is to technologist.  Once I understood that, I realized why Mr. Morozov was arguing with me.  He thought I believed in technologism, much like the way the New Yorker describes Marc Andreesen (I’m no Andreesen in many ways, but I do think he’d have been a better foil for Morozov).  It also made me realize that he either didn’t understand what Mozilla is trying to do, or didn’t believe me/us.

Using that definition, I am not a technologist any more than I am a capitalist or a regulator[ist?].  I resist absolutes, as it seems to me blatantly obvious (and probably boring) that except for rhetorical/marketing purposes (such as Morozov’s), the choices which one should make when building or changing a system, at every scale from the individual to the society, must be thoughtfully balanced.  This balance is hard to articulate and even harder to maintain, in a political environment which blurs subtlety and a network environment which amplifies differences.

 

The Purpose of Argument

 

It is in this balance that lies evolutionary progress.  I have been re-re-watching The Wire, thinking about Baltimore.  In season 3, one of the district commanders, sick of the status quo, tries to create a “free zone” for unimpeded drug dealing, an Amsterdam-in-Baltimore, in order to draw many of the associated social ills away from the rest of the district.  In doing this, he uses his authority (and fearlessness, thanks to his impending retirement), and combines management techniques, marketing, and positive and negative incentives, to try fix a systemic social problem.  I want more stories like that (especially less fictional ones).

I don’t believe that technology is “the answer,” just like police vans aren’t the answer.  That said, ignoring the impact that technology can have on societal (or business!) challenges is just as silly as saying that technology holds the answer.  Yes, technology choices are often political, and that’s just fine, especially if we invite non-techies to help make those political decisions.  When it comes to driving behavioral change, tech is a tool like many others, from empathy and consumer marketing to capital and incentives.  Let’s understand and use all of these tools.

Human psychology explains why marketing works, and marketing has definitely been used for silly reasons in the past. Still, if part of your goal involves getting people to do something, refusing to use human psychology to further your well-intentioned outcome is cutting your nose to spite your face.  Similarly, it’s unarguable that those who wield gigantic capital have had outsize influence in our society, and some of them are sociopaths. Still, refusing to consider how one could use capital and incentives to drive behavior is an equally flawed limit.  Lastly, obviously, technology can be dehumanizing. But technology can also, if wielded thoughtfully, be liberating.  Each has power, and power isn’t intrinsically evil.

1+1+1 = magic

Tech companies of the last decade have shown the outsize impact that these three disciplines, when wielded in coordinated fashion, can have on the world.  Uber’s success isn’t due to smart deployment of tech, psychology or capital.  Uber’s success is due to a brilliant combination of all three (and more).  I’ll leave it history to figure out whether Uber’s impact will be net positive or negative based on metrics that I care about, but the magical quality that combination unleashed is awe inspiring.

 

object.

 

This effective combination of disciplines is a critical step which I think eludes many people and organizations, due to specialization without coordination.  It is relatively clear how to become a better technologist or marketer.  The ladder of capitalist success is equally straightforward.  But figuring out how to blend those disciplines and unlock magic is elusive, both within a career path and within organizations.

I wonder if it’s possible to label this pursuit, in a gang-signal sort of way. Venture capitalists, marketers, and technologists all gain a lot by simply affiliating with these fields.  I find any one of these dimensions deeply boring, and the combinations so much more provocative.  Who’s with me and what do you call yourselves?  Combinatorists? Alchemists?

Aki Sasakiintroducing scriptharness

I found myself missing mozharness at various points over the past 10 months. Several things kept me from using it at my then-new job:

  • Even though we had kept mozharness.base.* largely non-Mozilla-specific, the mozharness clone-and-run model meant there was a lot of Mozilla-specific code that came along with it.

  • The monolithic BaseScript + mixins model had a very steep barrier of entry. There's a significant learning curve, and scripts need to be fully ported to mozharness to take advantage of its features.

I had wanted to address these issues for years, but never had time to devote fully to harness-specific development.

Now I do.

Introducing scriptharness 0.1.0:

I'm proud of this. I'm also aware it's not mature [yet], and it's currently missing some functionality.

There are some ideas I'd love to explore before 1.0.0:

  • multiple Script objects with threading and separate logs

  • Config Type Definitions

  • rethink how to enable/disable actions. I could keep mozharness' --add-action clobber --no-upload structure, or play with --actions +clobber -upload or something. (The - before the upload in the latter might cause argparse issues?)

  • also, explore Maven-style actions (all actions before target action are enabled) and actions with dependencies on other actions. I prefer keeping each action independent, idempotent, and individually targetable, but I can see someone wanting the other behavior for certain scripts.

  • I've already split out strings from code in a number of places, for unit testing. I'm curious what it would take to make scriptharness localizable, and if there would be demand for it.

  • ahal suggested adding structured logging; I'd love to investigate that.

I already have 0.2.0 on the brain. I'd love any feedback or patches.



comment count unavailable comments

Aki Sasakimozharness turns 5

Five years ago today, I landed the first mozharness commit in my user repo. (github)

starting something, or wasting my time. Log.py + a scratch trunk_nightly.json

The project had three initial goals:

  • First and foremost, I was tasked with building a multi-locale Fennec on Maemo. This was a more complex task than could sanely fit in a buildbot factory.

  • The Mozilla Releng team was already discussing pulling logic out of buildbot factories and into client-side scripts. I had been wanting to write a second version of my script framework idea. The first version was closed-source, perl, and very company- and product-specific. The second would improve on the first in every way, while keeping its three central principles of full logging, flexible config, and modular actions.

  • Finally, at that point I was still a Perl developer learning Python. I tend learn languages by writing a project from scratch in that new language; this was my opportunity.

Multi-locale Fennec became a reality, and then we started adding projects to mozharness, one by one.

As of last July, mozharness was the client-side engine for the majority of Mozilla's CI and release infrastructure. I still see plenty of activity in bugmail and IRC these days. I'll be the first to point out its shortcomings, but I think overall it has been a success.

Happy birthday, mozharness!



comment count unavailable comments

Air MozillaMozilla Weekly Project Meeting

Mozilla Weekly Project Meeting The Monday Project Meeting

Nick DesaulniersInterpreter, Compiler, JIT

Interpreters and compilers are interesting programs, themselves used to run or translate other programs, respectively. Those other programs that might be interpreted might be languages like JavaScript, Ruby, Python, PHP, and Perl. The other programs that might be compiled are C, C++, and to some extent Java and C#.

Taking the time to do translation to native machine code ahead of time can result in better performance at runtime, but an interpreter can get to work right away without spending any time translating. There happens to be a sweet spot somewhere in between interpretation and compilation that combines the best of both worlds. Such a technique is called Just In Time (JIT) compiling. While interpreting, compiling, and JIT’ing code might sound radically different, they’re actually strikingly similar. In this post, I hope to show how similar by comparing the code for an interpreter, a compiler, and a JIT compiler for the language Brainfuck in around 100 lines of C code each.

All of the code in the post is up on GitHub.

Brainfuck is an interesting, if hard to read, language. It only has eight operations it can perform > < + - . , [ ], yet is Turing complete. There’s nothing really to lex; each character is a token, and if the token is not one of the eight operators, it’s ignored. There’s also not much of a grammar to parse; the forward jumping and backwards jumping operators should be matched for well formed input, but that’s about it. In this post, we’ll skip over validating input assuming well formed input so we can focus on the interpretation/code generation. You can read more about it on the Wikipedia page, which we’ll be using as a reference throughout.

A Brainfuck program operates on a 30,000 element byte array initialized to all zeros. It starts off with an instruction pointer, that initially points to the first element in the data array or “tape.” In C code for an interpreter that might look like:

1
2
3
4
5
// Initialize the tape with 30,000 zeroes.
unsigned char tape [30000] = { 0 };

// Set the pointer to point at the left most cell of the tape.
unsigned char* ptr = tape;

Then, since we’re performing an operation for each character in the Brainfuck source, we can have a for loop over every character with a nested switch statement containing case statements for each operator.

The first two operators, > and < increment and decrement the data pointer.

1
2
case '>': ++ptr; break;
case '<': --ptr; break;

One thing that could be bad is that because the interpreter is written in C and we’re representing the tape as an array but we’re not validating our inputs, there’s potential for stack buffer overrun since we’re not performing bounds checks. Again, punting and assuming well formed input to keep the code and the point more precise.

Next up are the + and - operators, used for incrementing and decrementing the cell pointed to by the data pointer by one.

1
2
case '+': ++(*ptr); break;
case '-': --(*ptr); break;

The operators . and , provide Brainfuck’s only means of input or output, by writing the value pointed to by the instruction pointer to stdout as an ASCII value, or reading one byte from stdin as an ASCII value and writing it to the cell pointed to by the instruction pointer.

1
2
case '.': putchar(*ptr); break;
case ',': *ptr = getchar(); break;

Finally, our looping constructs, [ and ]. From the definition on Wikipedia for [: if the byte at the data pointer is zero, then instead of moving the instruction pointer forward to the next command, jump it forward to the command after the matching ] command and for ]: if the byte at the data pointer is nonzero, then instead of moving the instruction pointer forward to the next command, jump it back to the command after the matching [ command.

I interpret that as:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
case '[':
  if (!(*ptr)) {
    int loop = 1;
    while (loop > 0) {
      unsigned char current_char = input[++i];
      if (current_char == ']') {
        --loop;
      } else if (current_char == '[') {
        ++loop;
      }
    }
  }
  break;
case ']':
  if (*ptr) {
    int loop = 1;
    while (loop > 0) {
      unsigned char current_char = input[--i];
      if (current_char == '[') {
        --loop;
      } else if (current_char == ']') {
        ++loop;
      }
    }
  }
  break;

Where the variable loop keeps track of open brackets for which we’ve not seen a matching close bracket, aka our nested depth.

So we can see the interpreter is quite basic, in around 50 SLOC were able to read a byte, and immediately perform an action based on the operator. How we perform that operation might not be the fastest though.

How about if we want to compile the Brainfuck source code to native machine code? Well, we need to know a little bit about our host machine’s Instruction Set Architecture (ISA) and Application Binary Interface (ABI). The rest of the code in this post will not be as portable as the above C code, since it assumes an x86-64 ISA and UNIX ABI. Now would be a good time to take a detour and learn more about writing assembly for x86-64. The interpreter is even portable enough to build with Emscripten and run in a browser!

For our compiler, we’ll iterate over every character in the source file again, switching on the recognized operator. This time, instead of performing an action right away, we’ll print assembly instructions to stdout. Doing so requires running the compiler on an input file, redirecting stdout to a file, then running the system assembler and linker on that file. We’ll stick with just compiling and not assembling (though it’s not too difficult), and linking (for now).

First, we need to print a prologue for our compiled code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const char* const prologue =
  ".text\n"
  ".globl _main\n"
  "_main:\n"
  "  pushq %rbp\n"
  "  movq %rsp, %rbp\n"
  "  pushq %r12\n"        // store callee saved register
  "  subq $30008, %rsp\n" // allocate 30,008 B on stack, and realign
  "  leaq (%rsp), %rdi\n" // address of beginning of tape
  "  movl $0, %esi\n"     // fill with 0's
  "  movq $30000, %rdx\n" // length 30,000 B
  "  call _memset\n"      // memset
  "  movq %rsp, %r12";
puts(prologue);

During the linking phase, we’ll make sure to link in libc so we can call memset. What we’re doing is backing up callee saved registers we’ll be using, stack allocating the tape, realigning the stack (x86-64 ABI point #1), copying the address of the only item on the stack into a register for our first argument, setting the second argument to the constant 0, the third arg to 30000, then calling memset. Finally, we use the callee saved register %r12 as our instruction pointer, which is the address into a value on the stack.

We can expect the call to memset to result in a segfault if simply subtract just 30000B, and not realign for the 2 registers (64 b each, 8 B each) we pushed on the stack. The first pushed register aligns the stack on a 16 B boundary, the second misaligns it; that’s why we allocate an additional 8 B on the stack (x86-64 ABI point #1). The stack is mis-aligned upon function entry in x86-64. 30000 is a multiple of 16.

Moving the instruction pointer (>, <) and modifying the pointed to value (+, -) are straight-forward:

1
2
3
4
5
6
7
8
9
10
11
12
case '>':
  puts("  inc %r12");
  break;
case '<':
  puts("  dec %r12");
  break;
case '+':
  puts("  incb (%r12)");
  break;
case '-':
  puts("  decb (%r12)");
  break;

For output, ., we need to copy the pointed to byte into the register for the first argument to putchar. We explicitly zero out the register before calling putchar, since it takes an int (32 b), but we’re only copying a char (8 b) (Look up C’s type promotion rules for more info). x86-64 has an instruction that does both, movzXX, Where the first X is the source size (b, w) and the second is the destination size (w, l, q). Thus movzbl moves a byte (8 b) into a double word (32 b). %rdi and %edi are the same register, but %rdi is the full 64 b register, while %edi is the lowest (or least significant) 32 b.

1
2
3
4
5
6
case '.':
  // move byte to double word and zero upper bits since putchar takes an
  // int.
  puts("  movzbl (%r12), %edi");
  puts("  call _putchar");
  break;

Input (,) is easy; call getchar, move the resulting lowest byte into the cell pointed to by the instruction pointer. %al is the lowest 8 b of the 64 b %rax register.

1
2
3
4
case ',':
  puts("  call _getchar");
  puts("  movb %al, (%r12)");
  break;

As usual, the looping constructs ([ & ]) are much more work. We have to match up jumps to matching labels, but for an assembly program, labels must be unique. One way we can solve for this is whenever we encounter an opening brace, push a monotonically increasing number that represents the numbers of opening brackets we’ve seen so far onto a stack like data structure. Then, we do our comparison and jump to what will be the label that should be produced by the matching close label. Next, we insert our starting label, and finally increment the number of brackets seen.

1
2
3
4
5
6
case '[':
  stack_push(&stack, num_brackets);
  puts("  cmpb $0, (%r12)");
  printf("  je bracket_%d_end\n", num_brackets);
  printf("bracket_%d_start:\n", num_brackets++);
  break;

For close brackets, we pop the number of brackets seen (or rather, number of pending open brackets which we have yet to see a matching close bracket) off of the stack, do our comparison, jump to the matching start label, and finally place our end label.

1
2
3
4
5
6
case ']':
  stack_pop(&stack, &matching_bracket);
  puts("  cmpb $0, (%r12)");
  printf("  jne bracket_%d_start\n", matching_bracket);
  printf("bracket_%d_end:\n", matching_bracket);
  break;

So for sequential loops ([][]) we can expect the relevant assembly to look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  cmpb $0, (%r12)
  je bracket_0_end
bracket_0_start:

  cmpb $0, (%r12)
  jne bracket_0_start
bracket_0_end:

  cmpb $0, (%r12)
  je bracket_1_end
bracket_1_start:

  cmpb $0, (%r12)
  jne bracket_1_start
bracket_1_end:

and for nested loops ([[]]), we can expect assembly like the following (note the difference in the order of numbered start and end labels):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  cmpb $0, (%r12)
  je bracket_0_end
bracket_0_start:

  cmpb $0, (%r12)
  je bracket_1_end
bracket_1_start:

  cmpb $0, (%r12)
  jne bracket_1_start
bracket_1_end:

  cmpb $0, (%r12)
  jne bracket_0_start
bracket_0_end:

Finally, we need an epilogue to clean up the stack and callee saved registers after ourselves.

1
2
3
4
5
6
const char* const epilogue =
  "  addq $30008, %rsp\n" // clean up tape from stack.
  "  popq %r12\n" // restore callee saved register
  "  popq %rbp\n"
  "  ret\n";
puts(epilogue);

The compiler is a pain when modifying and running a Brainfuck program; it takes a couple extra commands to compile the Brainfuck program to assembly, assemble the assembly into an object file, link it into an executable, and run it whereas with the interpreter we can just run it. The trade off is that the compiled version is quite a bit faster. How much faster? Let’s save that for later.

Wouldn’t it be nice if there was a translation & execution technique that didn’t force us to compile our code every time we changed it and wanted to run it, but also performance closer to that of compiled code? That’s where a JIT compiler comes in!

For the basics of JITing code, make sure you read my previous article on the basics of JITing code in C. We’re going to follow the same technique of creating executable memory, copying bytes into that memory, casting it to a function pointer, then calling it. Just like the interpreter and the compiler, we’re going to do a unique action for each recognized token. What’s different is that for each operator, we’re going to push opcodes into a dynamic array, that way it can grow based on our sequential reading of input and will simplify our calculation of relative offsets for branching operations.

The other special thing we’re going to do it that we’re going to pass the address of our libc functions (memset, putchar, and getchar) into our JIT’ed function at runtime. This avoids those kooky stub functions you might see in a disassembled executable. That means we’ll be invoking our JIT’ed function like:

1
2
3
4
5
typedef void* fn_memset (void*, int, size_t);
typedef int fn_putchar (int);
typedef int fn_getchar ();
void (*jitted_func) (fn_memset, fn_putchar, fn_getchar) = mem;
jitted_func(memset, putchar, getchar);

Where mem is our mmap’ed executable memory with our opcodes copied into it, and the typedef’s are for the respective function signatures for our function pointers we’ll be passing to our JIT’ed code. We’re kind of getting ahead of ourselves, but knowing how we will invoke the dynamically created executable code will give us an idea of how the code itself will work.

The prologue is quite a bit involved, so we’ll take it step at a time. First, we have the usual prologue:

1
2
3
char prologue [] = {
  0x55, // push rbp
  0x48, 0x89, 0xE5, // mov rsp, rbp

Then we want to back up our callee saved registers that we’ll be using. Expect horrific and difficult to debug bugs if you forget to do this.

1
2
3
  0x41, 0x54, // pushq %r12
  0x41, 0x55, // pushq %r13
  0x41, 0x56, // pushq %r14

At this point, %rdi will contain the address of memset, %rsi will contain the address of putchar, and %rdx will contain the address of getchar, see x86-64 ABI point #2. We want to store these in callee saved registers before calling any of them, else they may clobber %rdi, %rsi, or %rdx since they’re not “callee saved,” rather “call clobbered.” See x86-64 ABI point #4.

1
2
3
  0x49, 0x89, 0xFC, // movq %rdi, %r12
  0x49, 0x89, 0xF5, // movq %rsi, %r13
  0x49, 0x89, 0xD6, // movq %rdx, %r14

At this point, %r12 will contain the address of memset, %r13 will contain the address of putchar, and %r14 will contain the address of getchar.

Next up is allocating 30008 B on the stack:

1
  0x48, 0x81, 0xEC, 0x38, 0x75, 0x00, 0x00, // subq $30008, %rsp

This is our first hint at how numbers, whose value is larger than the maximum representable value in a byte, are represented on x86-64. Where in this instruction is the value 30008? The answer is the 4 byte sequence 0x38, 0x75, 0x00, 0x00. The x86-64 architecture is “Little Endian,” which means that the least significant bit (LSB) is first and the most significant bit (MSB) is last. When humans do math, they typically represent numbers the other way, or “Big Endian.” Thus we write decimal ten as “10” and not “01.” So that means that 0x38, 0x75, 0x00, 0x00 in Little Endian is 0x00, 0x00, 0x75, 0x38 in Big Endian, which then is 7*16^3+5*16^2+3*16^1+8*16^0 which is 30008 in decimal, the amount of bytes we want to subtract from the stack. We’re allocating an additional 8 B on the stack for alignment requirements, similar to the compiler. By pushing even numbers of 64 b registers, we need to realign our stack pointer.

Next in the prologue, we set up and call memset:

1
2
3
4
5
6
7
8
  // address of beginning of tape
  0x48, 0x8D, 0x3C, 0x24, // leaq (%rsp), %rdi
  // fill with 0's
  0xBE, 0x00, 0x00, 0x00, 0x00, // movl $0, %esi
  // length 30,000 B
  0x48, 0xC7, 0xC2, 0x30, 0x75, 0x00, 0x00, // movq $30000, %rdx
  // memset
  0x41, 0xFF, 0xD4, // callq *%r12

After invoking memset, %rdi, %rsi, & %rcx will contain garbage values since they are “call clobbered” registers. At this point we no longer need memset, so we now use %r12 as our instruction pointer. %rsp will point to the top (technically the bottom) of the stack, which is the beginning of our memset’ed tape. That’s the end of our prologue.

1
2
  0x49, 0x89, 0xE4 // movq %rsp, %r12
};

We can then push our prologue into our dynamic array implementation:

1
vector_push(&instruction_stream, prologue, sizeof(prologue))

Now we iterate over our Brainfuck program and switch on the operations again. For pointer increment and decrement, we just nudge %r12.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
case '>':
  {
    char opcodes [] = {
      0x49, 0xFF, 0xC4 // inc %r12
    };
    vector_push(&instruction_stream, opcodes, sizeof(opcodes));
  }
  break;
case '<':
  {
    char opcodes [] = {
      0x49, 0xFF, 0xCC // dec %r12
    };
    vector_push(&instruction_stream, opcodes, sizeof(opcodes));
  }
  break;

That extra fun block in the switch statement is because in C/C++, we can’t define variables in the branches of switch statements.

Pointer deref then increment/decrement are equally uninspiring:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
case '+':
  {
    char opcodes [] = {
      0x41, 0xFE, 0x04, 0x24 // incb (%r12)
    };
    vector_push(&instruction_stream, opcodes, sizeof(opcodes));
  }
  break;
case '-':
  {
    char opcodes [] = {
      0x41, 0xFE, 0x0C, 0x24 // decv (%r12)
    };
    vector_push(&instruction_stream, opcodes, sizeof(opcodes));
  }
  break;

I/O might be interesting, but in x86-64 we have an opcode for calling the function at the end of a pointer. %r13 contains the address of putchar while %r14 contains the address of getchar.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
case '.':
  {
    char opcodes [] = {
      0x41, 0x0F, 0xB6, 0x3C, 0x24, // movzbl (%r12), %edi
      0x41, 0xFF, 0xD5 // callq *%r13
    };
    vector_push(&instruction_stream, opcodes, sizeof(opcodes));
  }
  break;
case ',':
  {
    char opcodes [] = {
      0x41, 0xFF, 0xD6, // callq *%r14
      0x41, 0x88, 0x04, 0x24 // movb %al, (%r12)
    };
    vector_push(&instruction_stream, opcodes, sizeof(opcodes));
  }
  break;

Now with our looping constructs, we get to the fun part. With the compiler, we deferred the concept of “relocation” to the assembler. We simply emitted labels, that the assembler turned into relative offsets (jumps by values relative to the last byte in the jump instruction). We’ve found ourselves in a Catch-22 though: how many bytes forward do we jump to the matching close bracket that we haven’t seen yet?

Normally, an assembler might have a data structure known as a “relocation table.” It keeps track of the first byte after a label and jumps, rewriting jumps-to-labels (which aren’t kept around in the resulting binary executable) to relative jumps. Spidermonkey, Firefox’s JavaScript Virtual Machine has two classes for this, MacroAssembler and Label. Spidermonkey embeds a linked list in the opcodes it generates for jumps with which it’s yet to see a label for. Once it finds the label, it walks the linked list (which itself is embedded in the emitted instruction stream) patching up these locations as it goes.

For Brainfuck, we don’t have to anything quite as fancy since each label only ends up having one jump site. Instead, we can use a stack of integers that are offsets into our dynamic array, and do the relocation once we know where exactly we’re jumping to.

1
2
3
4
5
6
7
8
9
10
11
case '[':
  {
    char opcodes [] = {
      0x41, 0x80, 0x3C, 0x24, 0x00, // cmpb $0, (%r12)
      // Needs to be patched up
      0x0F, 0x84, 0x00, 0x00, 0x00, 0x00 // je <32b relative offset, 2's compliment, LE>
    };
    vector_push(&instruction_stream, opcodes, sizeof(opcodes));
  }
  stack_push(&relocation_table, instruction_stream.size); // create a label after
  break;

First we push the compare and jump opcodes, but for now we leave the relative offset blank (four zero bytes). We will come back and patch it up later. Then, we push the current length of dynamic array, which just so happens to be the offset into the instruction stream of the next instruction.

All of the relocation magic happens in the case for the closing bracket.

1
2
3
4
5
6
7
8
9
10
case ']':
  {
    char opcodes [] = {
      0x41, 0x80, 0x3C, 0x24, 0x00, // cmpb $0, (%r12)
      // Needs to be patched up
      0x0F, 0x85, 0x00, 0x00, 0x00, 0x00 // jne <33b relative offset, 2's compliment, LE>
    };
    vector_push(&instruction_stream, opcodes, sizeof(opcodes));
  }
  // ...

First, we push our comparison and jump instructions into the dynamic array. We should know the relative offset we need to jump back to at this point, and thus don’t need to push four empty bytes, but it makes the following math a little simpler, as were not done yet with this case.

1
2
3
4
  // ...
  stack_pop(&relocation_table, &relocation_site);
  relative_offset = instruction_stream.size - relocation_site;
  // ...

We pop the matching offset into the dynamic array (from the matching open bracket), and calculate the difference from the current size of the instruction stream to the matching offset to get our relative offset. What’s interesting is that this offset is equal in magnitude for the forward and backwards jumps that we now need to patch up. We simply go back in our instruction stream 4 B, and write that relative offset negated as a 32 b LE number (patching our backwards jump), then go back to the site of our forward jump minus 4 B and write that relative offset as a 32 b LE number (patching our forwards jump).

1
2
3
4
  // ...
  vector_write32LE(&instruction_stream, instruction_stream.size - 4, -relative_offset);
  vector_write32LE(&instruction_stream, relocation_site - 4, relative_offset);
  break;

Thus, when writing a JIT, one must worry about manual relocation. From the Intel 64 and IA-32 Architectures Software Developer’s Manual Volume 2 (2A, 2B & 2C): Instruction Set Reference, A-Z “A relative offset (rel8, rel16, or rel32) is generally specified as a label in assembly code, but at the machine code level, it is encoded as a signed, 8-bit or 32-bit immediate value, which is added to the instruction pointer.”

The last thing we push onto our instruction stream is clean up code in the epilogue.

1
2
3
4
5
6
7
8
9
10
char epilogue [] = {
  0x48, 0x81, 0xC4, 0x38, 0x75, 0x00, 0x00, // addq $30008, %rsp
  // restore callee saved registers
  0x41, 0x5E, // popq %r14
  0x41, 0x5D, // popq %r13
  0x41, 0x5C, // popq %r12
  0x5d, // pop rbp
  0xC3 // ret
};
vector_push(&instruction_stream, epilogue, sizeof(epilogue));

A dynamic array of bytes isn’t really useful, so we need to create executable memory the size of the current instruction stream and copy all of the machine opcodes into it, cast it to a function pointer, call it, and finally clean up:

1
2
3
4
5
6
7
void* mem = mmap(NULL, instruction_stream.size, PROT_WRITE | PROT_EXEC,
  MAP_ANON | MAP_PRIVATE, -1, 0);
memcpy(mem, instruction_stream.data, instruction_stream.size);
void (*jitted_func) (fn_memset, fn_putchar, fn_getchar) = mem;
jitted_func(memcpy, putchar, getchar);
munmap(mem, instruction_stream.size);
vector_destroy(&instruction_stream);

Note: we could have used the instruction stream rewinding technique to move the address of memset, putchar, and getchar as 64 b immediate values into %r12-%r14, which would have simplified our JIT’d function’s type signature.

Compile that, and we now have a function that will JIT compile and execute Brainfuck in roughly 141 SLOC. And, we can make changes to our Brainfuck program and not have to recompile it like we did with the Brainfuck compiler.

Hopefully it’s becoming apparent how similar an interpreter, compiler, and JIT behave. In the interpreter, we immediately execute some operation. In the compiler, we emit the equivalent text based assembly instructions corresponding to what the higher level language might get translated to in the interpreter. In the JIT, we emit the binary opcodes into executable memory and manually perform relocation, where the binary opcodes are equivalent to the text based assembly we might emit in the compiler. A production ready JIT would probably have macros for each operation in the JIT would perform, so the code would look more like the compiler rather than raw arrays of bytes (though the preprocessor would translate those macros into such). The entire process is basically disassembling C code with gobjdump -S -M suffix a.out, and punching in hex like one would a Gameshark.

Compare pointer incrementing from the three:

Interpreter:

1
case '>': ++ptr; break;

Compiler:

1
2
3
case '>':
  puts("  inc %r12");
  break;

JIT:

1
2
3
4
5
6
7
8
case '>':
  {
    char opcodes [] = {
      0x49, 0xFF, 0xC4 // inc %r12
    };
    vector_push(&instruction_stream, opcodes, sizeof(opcodes));
  }
  break;

Or compare the full sources of the the interpreter, the compiler, and the JIT. Each at ~100 lines of code should be fairly easy to digest.

Let’s now examine the performance of these three. One of the longer running Brainfuck programs I can find is one that prints the Mandelbrot set as ASCII art to stdout.

Running the UNIX command time on the interpreter, compiled result, and the JIT, we should expect numbers similar to:

1
2
3
4
5
6
7
8
$ time ./interpreter ../samples/mandelbrot.b
43.54s user 0.03s system 99% cpu 43.581 total

$ ./compiler ../samples/mandelbrot.b > temp.s; ../assemble.sh temp.s; time ./a.out
3.24s user 0.01s system 99% cpu 3.254 total

$ time ./jit ../samples/mandelbrot.b
3.27s user 0.01s system 99% cpu 3.282 total

The interpreter is an order of magnitude slower than the compiled result or run of the JIT. Then again, the interpreter isn’t able to jump back and forth as efficiently as the compiler or JIT, since it scans back and forth for matching brackets O(N), while the other two can jump to where they need to go in a few instructions O(1). A production interpreter would probably translate the higher level language to a byte code, and thus be able to calculate the offsets used for jumps directly, rather than scanning back and forth.

The interpreter bounces back and forth between looking up an operation, then doing something based on the operation, then lookup, etc.. The compiler and JIT preform the translation first, then the execution, not interleaving the two.

The compiled result is the fastest, as expected, since it doesn’t have the overhead the JIT does of having to read the input file or build up the instructions to execute at runtime. The compiler has read and translated the input file ahead of time.

What if we take into account the time it takes to compile the source code, and run it?

1
2
$ time (./compiler ../samples/mandelbrot.b > temp.s; ../assemble.sh temp.s; ./a.out)
3.27s user 0.08s system 99% cpu 3.353 total

Including the time it takes to compile the code then run it, the compiled results are now slightly slower than the JIT (though I bet the multiple processes we start up are suspect), but with the JIT we pay the price to compile each and every time we run our code. With the compiler, we pay that tax once. When compilation time is cheap, as is the case with our Brainfuck compiler & JIT, it makes sense to prefer the JIT; it allows us to quickly make changes to our code and re-run it. When compilation is expensive, we might only want to pay the compilation tax once, especially if we plan on running the program repeatedly.

JIT’s are neat but compared to compilers can be more complex to implement. They also repeatedly re-parse input files and re-build instruction streams at runtime. Where they can shine is bridging the gap for dynamically typed languages where the runtime itself is much more dynamic, and thus harder (if not, impossible) to optimize ahead of time. Being able to jump into JIT’d native code from an interpreter and back gives you the best of both (interpreted and compiled) worlds.

Nathan Froydwhite space as unused advertising space

I picked up Matthew Crawford’s The World Outside Your Head this weekend. The introduction, subtitled “Attention as a Cultural Problem”, opens with these words:

The idea of writing this book gained strength one day when I swiped my bank card to pay for groceries. I watched the screen intently, waiting for it to prompt me to do the next step. During the following seconds it became clear that some genius had realized that a person in this situation is a captive audience. During those intervals between swiping my card, confirming the amount, and entering my PIN, I was shown advertisements. The intervals themselves, which I had previously assumed were a mere artifact of the communication technology, now seemed to be something more deliberately calibrated. These haltings now served somebody’s interest.

I have had a similar experience: the gas station down the road from me has begun playing loud “news media” clips on the digital display of the gas pump while your car is being refueled, cleverly exploiting the driver as a captive audience. Despite this gas station being somewhat closer to my house and cheaper than the alternatives, I have not been back since I discovered this practice.

Crawford continues, describing how a recent airline trip bombarded him with advertisements in “unused” (“unmonetized”?) spaces: on the fold-down tray table in his airplane seat, the moving handrail on the escalator in the airport, on the key card (!) for his hotel room. The logic of filling up unused space reaches even to airport security:

But in the last few years, I have found I have to be careful at the far end of [going through airport security], because the bottoms of the gray trays that you place your items in for X-ray screening are now papered with advertisements, and their visual clutter makes it very easy to miss a pinky-sized flash memory stick against a picture of fanned-out L’Oréal lipstick colors…

Somehow L’Oréal has the Transportation Security Administration on its side. Who made the decision to pimp out the security trays with these advertisements? The answer, of course, is that Nobody decided on behalf of the public. Someone made a suggestion, and Nobody responded in the only way that seemed reasonable: here is an “inefficient” use of space that could instead be used to “inform” the public of “opportunities.” Justifications of this flavor are so much a part of the taken-for-granted field of public discourse that they may override our immediate experience and render it unintelligible to us. Our annoyance dissipates into vague impotence because we have no public language in which to articulate it, and we search instead for a diagnosis of ourselves: Why am I so angry? It may be time to adjust the meds.

Reading the introduction seemed especially pertinent to me in light of last week’s announcement about Suggested Tiles. The snippets in about:home featuring Mozilla properties or efforts, or even co-opting tiles on about:newtab for similar purposes feels qualitatively different than using those same tiles for advertisements from third parties bound only to Mozilla through the exchange of money. I have at least consented to the former, I think, by downloading Firefox and participating in that ecosystem, similar to how Chrome might ask you to sign into your Google account when the browser opens. The same logic is decidedly not true in the advertising case.

People’s attention is a scarce resource. We should be treating it as such in Firefox, not by “informing” them of “opportunities” from third parties unrelated to Mozilla’s mission, even if we act with the utmost concern for their privacy. Like the gas station near my house, people are not going to come to Firefox because it shows them advertisements in “inefficiently” used space. At best, they will tolerate the advertisements (maybe even taking steps to turn them off); at worst, they’ll use a different web browser and they won’t come back.

Mike HommeyDogfooding Firefox GTK+3

Thanks to Lee Salzman, the state of GTK+3 support in Firefox got better. Unit tests went from looking like this:

To looking like this:

elm-after

There’s obviously some work left to make those look even better, but we’ve come a long way.

Ludovic Hirlimann recently asked if there were builds to dogfood and that prompted me to attempt making the builds from the elm branch auto-update. Which, after several attempts, I managed to get working with gross (but small) hacks of the build system.

So here we are, if you want to dogfood GTK+3 Firefox, here is what you can do::

  • In a normal Linux nightly, go to about:config and create the following string preferences (right-click, New, String):
    • app.update.url.override” with the value “https://ftp.mozilla.org/pub/mozilla.org/firefox/tinderbox-builds/elm-linux/latest/update.xml” for 32-bits builds, or “https://ftp.mozilla.org/pub/mozilla.org/firefox/tinderbox-builds/elm-linux64/latest/update.xml” for 64-bits builds,
    • app.update.certs.3.issuerName” with the value “CN=DigiCert SHA2 Secure Server CA,O=DigiCert Inc,C=US“,
    • app.update.certs.3.commonName” with the value “ftp.mozilla.org“.
  • Open the burger menu, click the “?” icon, then choose “About Nightly”. This should check for an update, find one, and download it. This will upgrade to a GTK+3 build.

Alternatively, you can just download and install the elm builds directly (32-bits, 64-bits).

If for some reason, you want to go back to a normal GTK+2 nightly, go to about:config, find the “app.update.url.override” preference and set it to an empty value. Triggering the update from “About Nightly” won’t, however, work until the next nightly is available, so give it a day.

As mentioned in my previous post about GTK+3, if you’re interested in making those builds work better, you are welcome to help:

Alex GibsonUpFront Conference 2015

I took a trip to Manchester last week to attend UpFront Conf 2015. It was a full day of talks on web design and front-end development, and covered a range of topics including UI design, web performance, front-end testing, and typography. It even had a talk dedicated games console browsers! The line up of speakers delivered a good balance of both creative and technical talks, which made for an enjoyable day of brain-food. Here are my notes from the talks:

Brad Frost - Atomic design

Brad Frost started off the day by sharing his experience working with clients to design reusable, responsive UI components. Atomic Design focuses on building individual components instead of web pages. This helps to promote reusability, which in turn improves workflow, speeds up prototyping, and makes things more easily testable. Brad says we should be investing more time in keeping our style guides up to date, as well as developing common pattern libraries. These are things that often get treated as auxiliary aspects of a project, but if we prioritize our work using a clear methodology, we can work more efficiently in the long run.

Alica Sedlock - Jumping into front end testing

Alica Sedlock gave a useful high-level overview of front-end testing, which covered areas such as Unit tests, Integration tests, and Visual Regression testing. A lot of the usual suspects for unit & integration tests we’re covered, such as Jasmine, Mocha, Karma, and headless browsers such as PhantomJS. What I found particularly interesting (or new to me anyway), was how to test for visual regressions. This can be done using tools such as PhantomCSS and CasperJS to take screenshots of before & after states, and then diff the changes. Pretty neat!

Soledad Penadés - The disconnected ensemble: Scattered clouds, underground

Mozilla’s own Soledad Penadés gave a really fun talk & tech demo, sharing some of her experiments exploring the concepts of a P2P Web, and how this could be applied to mobile platforms such as Firefox OS. Sole built some musical toys, using Web Audio API and Web Components, which could be run and shared over a local network. This showed off some pretty interesting tech, including how an app can run its own local web server and share addresses to clients using NFC. Very cool!

I’d also never met Sole in person before, despite working at the same company (in the same country, even), so it was nice to get to say hi and chat a bit in the break!

View Sole’s demo source code.

Dean Hume - Faster mobile websites

In the first talk of the day dedicated to web performance, Dean Hume gave an overview on why page loading speed is so important, and how we are often failing horribly at performance when it comes to mobile. Dean gave an insight into using the RAIL approach (Response, Animate, Idle, Load) to help improve overall page speed, covering techniques such as image optimization, critical CSS, responsive images, and more. The most high level goals are to reduce overall page weight, minimize the number of requests a page needs to make, and speed up the time to first paint.

View Dean’s slides.

Ben Foxall - The Internet of browsers

Ben Foxall demoed a fun interactive concept that played on the “Internet of Things”, and showed that technology is very much a part of our physical world. Ben used browser meta data from devices in the audience to produce a visualization which highlighted where people we’re sat in relation to the speaker. This was accomplished using common Web API’s such as geolocation, orientation, proximity, ambient light, touch and sound.

View Ben’s interactive demo.

Richard Rutter - Web typography you could be doing now

Richard Rutter gave a talk on common typography best practices, and how best to apply them to web design. I found this quite insightful being more developer oriented, and also learnt a few new CSS properties that I never even knew existed (e.g. font-variant-numeric). Richard also made a great point that we should all be serving woff2 for our web fonts by now, which can save up to 30% in file size.

View Richard’s slides.

Anna Debenham - Games Console browsers

Anna Debenham gave a really interesting talk on the rise in use of games console browsers. Apparently 18% of people in the UK used a games console to log onto a social media web site in 2013. Another interesting group are 14-16 year olds, 20% of whom in the UK use a games console browser to access the internet (likely they don’t yet have a mobile device with data contract).

Anna went on to showcase the wide range of user inputs a games console can have, including gestures, voice commands, keypads, touch screens, and styluses to name just a few. Web browsers on these devices can also have very tight memory constraints, as well as pretty poor standards support. We need to try and optimize our web pages to be as light as possible, as well as make sure to always support common inputs such as keyboard, and use focus styles more effectively.

Yesenia Perez-Cruz - Design decisions through the lens of performance

Yesenia Perez-Cruz gave the second talk to focus on web performance, which was also the final talk of the day. I thought this one was particularly good as Yesenia shared how she works as a web designer to make informed decisions that won’t negatively impact a web page, taking into consideration factors like overall page weight, loading time and number of requests. This is something that designers don’t often prioritize, or consider being something a developer only needs worry about.

In Yesenia’s experience, slow and heavy sites are often a result of poor planning, communication, and awareness. Traditional waterfall processes often result with optimization being only an afterthought, or something that the developer needs to try and squeeze in toward the end of a project. It shouldn’t be this way. As a designer, Yesenia asks questions like, “How many requests will a carousel add?”, “How will performance be effected if we add another font weight?”, “Do we really need that parallax background?” Her suggestion to help weigh up these questions is to establish a web performance budget for any given page, and to make performance an overall project goal from the outset. Performance should be considered a design feature, not just a side effect of development.

John O'Duinn“RelEng as a Force Multiplier” at RelEng Conf 2015

Last week, I was honored to give the closing talk at RelEng Conf 2015, here in Florence, Italy.

I’ve used this same title in previous presentations; the mindset it portrays still feels important to me. Every time I give this presentation, I am invigorated by the enthusiastic response, and work to improve further, so I re-write it again. This most recent presentation at RelEngConf2015 was almost a complete re-write; only a couple of slides remain from the original. Click on the thumbnail to get the slides null

The main focus of this talk was:
1) Release Engineers build pipelines, while developers build products. When done correctly, this pipeline makes the entire company more effective. By contrast, done incorrectly, broken pipelines will hamper a company – sometimes fatally. This different perspective and career focus is important to keep in mind when hiring to solve company infrastructure problems.

2) Release Engineers routinely talk and listen with developers and testers, typically about the current project-in-progress. Thats good – we obviously need to keep doing that. However, I believe that Release Engineers also need to spend time talking to and listening with people who have a very different perspective – people who care about the fate of the *company*, as opposed to a specific project, and have a very different longer-term perspective. Typically, these people have titles like Founder/CxO/VP but every company has different cultural leaders and uses slightly different titles, so some detective work is in order. The important point here is to talk with people who care about the fate of the company, as opposed to the fate of a specific project – and keep that perspective in mind when building a pipeline that helps *all* your customers.

3) To illustrate these points, I then went into detail on some technical, and culture change, projects which highlighted the strategic importance of those points.

As usual, it was a lively presentation with lots of active Q+A during the talk, as well as the following break-out session. Afterwards, 25 of us managed to find a great dinner (without a reservation!) in a nearby restaurant where the geek talk continued at full force for several more hours.

All in all, a wonderful day.

It was also great to meet up with catlee in person again. We both had lots to catch up on, in work and in life.

Bram Adams, Christian, Foutse, Kim and Stephany Bellomo all deserve ongoing credit for continuing to make this unusual and very educational conference come to life, as well as for curating the openness that is the hallmark of this event. As usual, I love the mix of academic researchers and industry practitioners, with talks alternating between industry and academic speakers all day long. The different perspectives, and the eagerness of everyone to have fully honest “what worked, what didnt work” conversations with others from very different backgrounds is truly refreshing… and was very informative for everyone. I’m already looking forward to the next RelEngConf!!

Christian HeilmannThe Ryanair approach to progressive enhancement

I fly – a lot. I spend more time in airports, in the air, hotel rooms and conferences than at home. As I am a natural recording and analysing device, I take in a lot of things on my travels. People at airports are stressed, confused, don’t pay attention to things, eat badly and are not always feeling good. They are tired, they feel rushed and they want just to get things over with and get where they want to go. Others – those new to travel – are overly excited about everything and want to things right, making mistakes because they are too eager. Exactly what users on the web are like. I found that companies who use technology for the benefit of their users are those people love and support. That’s what progressive enhancement means to me. But let’s start at the beginning.

Getting somewhere by plane is pretty simple. You buy a ticket and you get a booking confirmation number, an airport you leave from, a time and a destination airport. To claim all this and get on the flight, you also need to prove that you are you. You can do this in domestic flights with the credit card you booked the flight with, a driving license or your passport. For international travels, the latter is always the safest option.

The main thing you have to fear about flying is delays that make you miss your plane. Delays can be natural problems, technical failures with the plane or the airport. They could also be issues with air traffic control. It is busy up in the blue yonder, as this gorgeous visualisation shows. Another big issue is getting to the airport in time as all kind of traffic problems can delay you.

You can’t do much about that – you just have to take it in stride. I plan 3 hours from my house to sitting on the plane.

Avoid the queue

One thing you want to avoid is queues. The longer the queue, the more likely you are to miss your plane. Every single person in that queue and their problems become yours.

Airport QueuePhoto by James Emery

Airlines understand that and over the years have put improvements in place that make it easier for you to get up in the air.

In essence, what you need to get in exchange of your information is a boarding pass. It is the proof that all is well and you are good to go.

Passport with boarding passesPhoto by mroach

The fool-proof way of doing that is having check-in counters. These have people with computers and you go there, tell them your information and you get your boarding pass. You can also drop off your luggage and you get up-to-date information from them on delays, gates and – if you are lucky – upgrades. Be nice to them – they have a tough job and they can mess up your travels if you give them a tough time.

Improvement: self check-in counters

Manned check-in counters are also the most time consuming and expensive way. They also don’t scale to hundreds of customers – hence the queues.

Self check-in counters

The first step to improve this was self-check-in terminals. If you allow people to type in their booking confirmation and scan their passport, a machine can issue the boarding pass. You can then have a special check-in counter only for those who need to drop off luggage. Those without luggage, move on to the next level without having to interact with a person behind the counter and take up a space in the queue. Those who don’t know how to use the machine or who forgot some information or encounter a technical failure can still go to a manned check-in counter.

Improvement: mobile apps

Mobile boarding pass in app

Nowadays this is even better. We have online check-in that allows us to check in at home and print out our own boarding passes. As printer ink is expensive and boarding passes tend to be A4 and littered with ads, you can also use apps on smartphones.

Of course, every airline has their own app and all work different and – at times – in mysterious ways. But let’s not dwell on that.

Apps are incredible – they show you when your flight happens, delays, and you don’t need to print out anything. You get this uplifting feeling that you’re part of a technical elite and that you know your stuff.

Mobile app offering an upgrade for 'null'

Of course, as soon as you go high-tech, things also break:

  • You can always run out of battery
  • Apps crash and need to have a connection to re-start and re-fresh your booking content. That’s why a lot of people take screenshots of their boarding passes in the app.
  • You need to turn off your phone on planes, which means on changing to another plane you need to re-boot it, which takes time.
  • Some airports don’t have digital readers of QR codes or have access to priority lane only as a rubber stamp on a paper boarding pass (looking at you, SFO). That’s why you need a printout.
  • Staff checking your boarding pass at security and gate staff tend to wait for your phone display to go to sleep before trying to scan it. Then they ask you to enter your unlock code. There is probably some reason for that.
  • Some security lanes need you to keep your boarding pass with you but you can’t keep your phone on you as it needs to be X-Rayed. You see the problem…

Despite all that, you are still safe. When things go wrong, there are the fallbacks of the machines or the manned counter to go back to.

This is progressive enhancement

This, is progressive enhancement.

  • You put things in place that work and you make it more convenient for your users who have technical abilities.
  • You analyse the task at hand and offer the most basic solution.
  • With this as a security blanket, you think of ways to improve the experience and distribute the load.

You make it easier for users who are frequently using your product. That’s why I get access to fast-track security lanes and lounges. I get a reward for saving the company time and money and allowing them to cater to more users.

You almost never meet people in these lounges who have bad things to say about the airline. Of course they are stressed – everybody at an airport is – but there is a trust in the company they chose and good experiences means having a good relationship. You can check in 24 hours before your flight and all you bring to the airport is your phone and your passport. If you fail to do so, or you feel like it, you can still go to the counter. You feel like James Bond or Tony Stark.

Forcing your users to upgrade

Then there is Ryanair and other budget airlines. You will be hard pushed to find anyone who loves them. The mood ranges from “meh, it is convenient, as I can afford it” to “necessary evil” and ends in “spawn of satan and bane of my existence”. Why is that?

Well, budget airlines try to save and make money wherever they can. They have less ground staff and check-in counters. They have online check-in and expect you to bring a printout of your boarding pass. They have draconic measures when it comes to the size and weight of your luggage. They are less concerned when it comes to your available space on the plane or happy to charge extra for it. Instead of using a service it feels like you have to game it. You need to be on your toes, or you pay extra. You feel like you have to work for what you already paid for and you feel not empowered, but stupid when you forgot to have one thing the company requests you to have – things others don’t bother with.

They also have apps. And pretty ones at that. When everything goes right, these are cool. Yet, these come with silly limitations. These companies chose to offer apps so they can cut down on ground staff and less check-in counters. They are not an improvement or convenience, but become a necessity.

The “let’s make you queue anyways” app experience

The other day I was in Italy flying to Germany with Ryanair. I have no Italian data connection and roaming is expensive. I also had no wireless in the hotel or the convention I was at. Ryanair allows me to check-in online with a browser 24 hours before the flight. I couldn’t. When you use the app is even more draconic: you can only check in two hours before the flight. If you remember, I add a my 3 hour trip cushion to the airport to my travels. Which means I am on the road which in London means I am underground without a connection when I need to check in.

I grumpily queued up at the hot, packed airport in a massive queue full of screaming kids and drunk tourists. Others were people standing over half-unpacked luggage as their passports were missing. When I arrived at the counter, the clerk told me that as I needed to print out my boarding pass or check in with the app. As I failed to do so, I now need to pay 45 Euro for my boarding pass if he were to print it for me.

This was almost the price of the ticket. I told him that because of the 2 hour period and me not having connectivity, I couldn’t do that. All I got was “this is our policy”.

I ground my teeth, and connected my roaming data on my phone, trying to check in with the app. Instead of asking for my name and booking confirmation it asked for all kind of extra information. I guess the reason was that I hadn’t booked the ticket but someone had booked it for me. The necessary information included entering a lot of dates with a confusing date picker. In the end, I was one minute late and the app told me there is no way I can check in without going to a counter. I queued up again, and the clerk told me that I can not pay at his counter. Instead I needed to go to the other side of the airport to the ticketing counter, pay there and bring back a printout that I did pay. Of course, there was another queue. Coming back, I ended up in yet another queue, this time for another flight. I barely made it to my plane.

Guess what my attitude towards future business with this airline is. Right – they have a bleak future with me.

Progressive enhancement is for the user and you benefit, too

And this is when you use progressive enhancement the wrong way. Yes, an app is an improvement over queuing up or printing out. But you shouldn’t add arbitrary rules or punish those who can’t use it. Progressive enhancement is for the benefit of the end user. We also benefit a lot from it. Unlike the physical world of airport we can enhance without extra overhead. We don’t need to hire extra ground staff or put up hardware to read passports. All we need to do is to analyse:

  • What is the basic information the user needs to provide to fulfill a task
  • What is the simplest interface to reach this
  • How can we improve the experience for more advanced users and those on more advanced hardware?

The latter is the main thing: you don’t rely on any of those. Instead you test if they can be applied and apply them as needed.

Progressive enhancement is not about adding more work to your product. It is about protecting the main use case of your product and then enhance it with new functionality as it becomes available. Google is a great example of that. Turn off JavaScript and you still get a form to enter information in and you get a search result page with ads on it. This is how you find things and Google makes money. Anything else they added over time makes it more convenient for you but is not needed. It also offers them more opportunities to show you more ads and point at other services.

Use progressive enhancement as a means to reward your users. Don’t expect them to do things for you just to use your product. If the tools you use means your users have to have a “modern” browser and load a lot of script you share your problems with them. You can only get away with that if you offer them a cheaper version of what others offer but that’s a risky race to take part in. You can win their current business, but never their hearts or support. You become a necessary evil, not something they tell others about.

Mozilla Release Management TeamFirefox 38.0.5b3 to 38.0.5 RC

Ready for the release! This RC was mainly about fixing the last pocket bugs and some stability fixes.

  • 22 changesets
  • 47 files changed
  • 301 insertions
  • 191 deletions

ExtensionOccurrences
html13
cpp6
js3
sh2
properties2
ini2
py1
mn1
json1
jsm1
java1
h1

ModuleOccurrences
dom16
mobile15
browser7
toolkit2
testing2
js2
gfx2
layout1

List of changesets:

Jean-Yves AvenardBug 1154881 - Disable test. r=karlt, a=test-only - 573c47bc1bf2
Nick AlexanderBug 1151619 - Add Adjust SDK license. r=gerv, a=NPOTB - 62e7fffff542
Ryan VanderMeulenBug 1164866 - Bump mozharness.json to rev 6f91445be987. a=test-only - f2ef3e1dadaf
Jared WeinBug 1166240 - Add pocket.svg to aero section of toolkit's windows/jar.mn. r=Gijs, a=gavin - 58d8fb9fc5e3
James WillcoxBug 1163841 - Always call eglInitialize(), but kill the preloading hack (which was crashing before). r=nchen, a=sledru - daa1f205525a
Benjamin ChenBug 1149842 - Release the mutex for NS_OpenAnonymousTemporaryFile to prevent the deadlock. r=roc, a=sledru - 06bdddc6463d
Chris ManchesterBug 978846 - Add a file to the tree to tell mozharness what arguments from try are acceptable to pass on to the harness process. r=ahal, a=test-only - cda517b321ee
Alexandre LissyBug 960762 - Fix intermittence of Notification mochitests. r=mhenretty, a=test-only - fe2c942655ec
Aaron KlotzBug 1158761 - Part 1: Make CheckPluginStopEvent run asynchronously. r=bholley, a=sledru - c163f5453215
Aaron KlotzBug 1158761 - Part 2: Update checks for plugin stop event in tests. r=jimm, a=sledru - aa884d29e93c
tbirdbldAutomated checkin: version bump for thunderbird 38.0b6 release. DONTBUILD CLOSED TREE a=release - 7f925ad5b331
Justin DolskeBug 1164649 - More late string changes in Pocket. r=jaws a=Sylvestre - 36b60a224d01
Geoff BrownBug 1073761 - Increase timeout for test_value_storage. r=dholbert, a=test-only - 1266331d5bc7
Kyle MachulisBug 1166870 - Fix permissions on settings event tests. a=test-only - 9e473441cbd9
Albert CrespellBug 849642 - Intermittent test_networkstats_enabled_perm.html. r=ettseng, a=test-only - bee6825f6c92
Albert CrespellBug 958689 - Fix intermittent errors in networkstats tests. r=ettseng, a=test-only - ad098fdd6f81
Milan SreckovicBug 1156058 - Null pointer check. r=jgilbert, a=sledru - 013da2859c88
Nicholas NethercoteBug 1103375 - Fix some crashes triggered from about:memory. r=mrbkap, a=sledru - b90caf52b6e2
Gijs KruitboschBug 1166771 - Force isArticle to false on pushstate on non-article pages. r=margaret, a=sledru - 17169e355c59
Jeff MuizelaarBug 1165732 - Block WARP when using the built-in VGA driver. r=bas, a=sledru - a297bd71b81a
Gijs KruitboschBug 1167096 - Flip introductory prefs if there's no saved state. r=jaws, a=sledru - 3ef925962765
Nick ThomasBackout rev 27bacb9dff64 to make mozilla-release ready to do release builds again, ra=release DONTBUILD - 79f9cd31b4b1

Andy McKayAccept Header

Recently I used an endpoint that had the following HTTP Accept Header:

*/*; q=0.5, application/xml

This server is saying it will accept "application/xml", but if that's not available, then it will accept anything. The "q" indicates that "application/xml" is preferred.

The assumption is that if you send a piece of content, you will send an appropriate HTTP Content-Type Header. Then the server will know how to parse it.

This server wanted a token, just some string, echoed back to it. Given the HTTP headers, it seemed perfectly for me to send:

Content-Type: application/json
"some token"

Or even [1]:

Content-Type: application/xml
<?xml version="1.0" encoding="UTF-8"?><token>some token</token>

As it turned out, it only accepted one thing and thats "test/plain" so something like:

Content-Type: text/plain
some token

This endpoint was hit using web interface, which was hitting a remote server, so took a little time to debug. But here's the thing, I think accepting */* is a little unusual, unless you are you really going to accept anything, really anything? Will you accept text/csv, how about audio/ogg or video/ogg? Here's one list of types [2].

The advantage of using a limited Accept header is that the server and client in question can figure things out without you having to do extra code. If the server explicitly declares what kinds of responses it can accept, then the client can check it can actually return the data encoded in that manner.

If your endpoint sends a */* Accept header and someone sends you something you don't know how to parse, hopefully you'll send them back a 406 response back. To tell the caller that you don't Accept that kind of response.

In this example, I've been talking about a server API. But of course this is for anything in the HTTP world, for example my browser sends the following: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8. It would much rather rather have HTML or XHTML, but will Accept anything and then do its best to render it. That seems reasonable for a browser.

But for an API that only accepts JSON or XML? Maybe we should make an effort to tighten up our Accept values on our APIs [3].

Footnotes

  1. Although it was never stated what the syntax for the XML was, so who knows.
  2. There isn't really a definitive list.
  3. Yes, that includes some APIs I've written.

Mike ConleyThings I’ve Learned This Week (May 18 – May 22, 2015)

You might have noticed that I had no “Things I’ve Learned This Week” post last week. Sorry about that – by the end of the week, I looked at my Evernote of “lessons from the week”, and it was empty. I’m certain I’d learned stuff, but I just failed to write it down. So I guess the lesson I learned last week was, always write down what you learn.

How to make your mozilla-central Mercurial clone work faster

I like Mercurial. I also like Git, but recently, I’ve gotten pretty used to Mercurial.

One complaint I hear over and over (and I’m guilty of it myself sometimes), is that “Mercurial is slow”. I’ve even experienced that slowness during some of my Joy of Coding episodes.

This past week, I was helping my awesome new intern get set up to tear into some e10s bugs, and at some point we went through this document to get her .hgrc all set up.

This document did not exist when I first started working with Mercurial – back then, I was using mq or sometimes pbranch, and grumbling about how I missed Git.

But there is some gold in this document.

gps has been doing some killer work documenting best practices with Mercurial, and this document is one of the results of his labour.

The part that’s really made the difference for me is the hgwatchman bit.

watchman is a tool that some folks at Facebook wrote to monitor changes in a folder. hgwatchman is an extension for Mercurial that takes advantage of watchman for a repository, smartly precomputing a bunch of stuff when the folder changes so that when you fire a command, like

hg status

It takes a fraction of the time it’d take without hgwatchman. A fraction.

Here’s how I set hgwatchman up on my MacBook (though you should probably go by the Mercurial for Mozillians doc as the official reference):

  1. Install watchman with brew:
    brew install watchman
  2. Clone the hgwatchman extension to some folder that you can easily remember and build it:
    hg clone https://bitbucket.org/facebook/hgwatchman
    cd hgwatchman
    make local
  3. Add the following lines to my user .hgrc:
    [extensions]
    hgwatchman = cloned-in-dir/hgwatchman/hgwatchman
  4. Make sure the extension is properly installed by running:
    hg help extensions
  5. hgwatchman should be listed under “enabled extensions”. If it didn’t work, keep in mind that you want to target the hgwatchman directory
  6. And then in my mozilla-central .hg/.hgrc:
    [watchman]
    mode = on
  7. Boom, you’re done!

Congratulations, hg should feel snappier now!

Next step is to try out this chg thingthough I’m having some issues still.

Mike ConleyThe Joy of Coding (Ep. 15): OS X Printing Returns

In Episode 15, we kept working on the same bug as the last two episodes – proxying the printing dialog on OS X to the parent process from the content process. At the end of Episode 14, we’d finished the serialization bits, and put in the infrastructure for deserialization. In this episode, we did the rest of the deserialization work.

And then we attempted to print a test page. And it worked!

We did it!

Then, we cleaned up the patches and posted them up for review. I had a lot of questions about my Objective-C++ stuff, specifically with regards to memory management (it seems as if some things in Objective-C++ are memory managed, and it’s not immediately obvious what that applies to). So I’ve requested review, and I hope to hear back from someone more experienced soon!

I also plugged a new show that’s starting up! If you’re a designer, and want to see how a designer at Mozilla does their work, you’ll love The Design Hour, by Ricardo Vazquez. His design chops are formidable, and he shows you exactly how he operates. It’s great!

Finally, I failed to mention that I’m on holiday next week, so I can’t stream live. I have, however, pre-recorded a shorter Episode 16, which should air at the right time slot next week. The show must go on!

Episode Agenda

References

Bug 1091112 – Print dialog doesn’t get focus automatically, if e10s is enabled – Notes

Air MozillaMozilla Balkans Meetup

Mozilla Balkans Meetup The Balkans Inter-Community meet-up 2015 will take place in Bucharest, Romania, on May 22-24th. Lead contributors from Balkan communities will be invited and sponsored by...

Robert O'Callahanrr Performance Update

It's been a while (March 2014 to be precise) since I gathered meaningful rr performance numbers. I'm preparing a talk for the TCE 2015 conference and as part of that I ran some new benchmarks with mozilla-central Firefox. It turned out that numbers had regressed --- unsurprisingly, since we don't have continuous performance tests for rr, and a lot has changed since March 2014. In particular, Firefox has evolved a lot, our tests have changed, we're using x86-64 now instead of x86-32, and rr has changed a lot. Over the last few days I studied the regressions and fixed a number of issues: in particular, during the transition to x86-64 some of the optimizations related to syscall-buffering were lost because we weren't patching some important syscall callsites and we weren't handling the recvfrom syscall, which is common in 64-bit Firefox. I also realized that in some cases we were flushing much more data from the syscallbuf to the trace file than we'd actually recorded in the buffer, massively bloating the traces, and fixed that.

There are still some regressions evident since last March. Octane overhead has increased significantly. Forcing Octane to run on a single core without rr shows a similar overhead; in particular that alone causes one test (Mandreel) to regress by a factor of 10! My guess is that Spidermonkey is using multiple cores much more aggressively that it did last year and because it's carefully tuned for Octane, going back to a single core really hurts performance. Replay overhead on the HTML mochitests has also increased significantly; I think this is partly because we changed rr to disable syscall buffering on writes to standard output. This improves the debugging experience but it results in a lot more overhead during replay.

Overall though, I remain very happy with rr performance, especially recording performance, which is critical when you're trying to capture a test failure under rr. Replay performance is becoming more important since it impacts the debugging experience, especially reverse execution; but doing a lot of work to improve raw replay performance is low priority since I think there are projects that could provide a better improvement in the debugging experience for less work (e.g. the ability to take a checkpoint during a recording and start debugging from there, and implement support for gdb's evaluate-in-target conditional breakpoints).

Mozilla Reps CommunityReps Weekly Call – May 21th 2015

Last Thursday we had our weekly call about the Reps program, where we talk about what’s going on in the program and what Reps have been doing during the last week.

webmaker-tiles

Summary

  • Webmaker & Mozilla Learning Update.
  • Suggested Tiles for Firefox update.
  • Featured Events.
  • Help me with my project.
  • Whistler WorkWeek – Reimbursements
  • Mozilla Reps SEA (SouthEast Asia) Online Meetup

AirMozilla video

Detailed notes

Shoutouts to Alex Wafula, African Reps, @konstantina, @Ioana and @lshapiro

Webmaker & Mozilla Learning update

Michelle joined the call to talk about webmaker and Mozilla Learning projects.

Blog post about Webmaker changes.

Have a question? Ask on discourse.

Elio share his experience on how they set up a Club and what does it look like. More about how to set up a club. Also we have create a topic to share your experience or ask questions about clubs.

Suggested Tiles for Firefox update

Patrick joined the call to update Reps about suggested Tiles in Firefox.

This week is going to be announced that it’s landing in beta starting with US users.

Firefox will use locally use the history to suggest interesting tiles for the user and it’s going to be super easy to opt-out or hide tiles you are not interested in. Firefox is the one deciding which tiles to show, not the partners.

Reps can be involved with this projects in two ways:

  • Suggesting community tiles.
  • Helping to curate relevant local content from partners.

Patrick will work with the Reps team to open this opportunity and to improve localization around this announcement and the technical details.

We have opened a discourse topic to ask any questions you might have.

Featured events

These are some events that have happened or are happening this week.

  • Mozilla Balkans: 22-25 May. More info on the wiki
  • Rust Releases parties: 23rd (Pune, Bangalore)
  • Debian/Ubuntu community Conference: 23-24 (Milano).
  • Mozilla QA Bangladesh, Train the contributors: 26th (Dhaka).
  • Festival TIK 2015 – Bandung: 28-29 (Bandung, Indonesia).

Help me with my project!

Staff onboarding

@george would love to know if a few volunteers would be excited to help out with new staff onboarding.

Requires availability at 17:15 UTC on Mondays for a 15min presentation, the benefit is that we would provide public speaking/presentation training and coaching and you will talk to new hires about the community and how awesome it is.

Business card generator

@helios needs help with the business card generator, which is written in nodejs.

Original generator idea.

Firefox e10s

@lshapiro needs help to test multiprocess in Firefox Developer Edition and add-ons.

http://arewee10syet.com

Whistler WorkWeek – Reimbursements

We are only one month to the workweek and there might be some questions about how to help volunteers that need reimbursements.

Reps will be reached out from Mozillians for reimbursement, so help them as better as possible to make the reimbursement smooth.

There will be an event created on reps portal to use on the budget form, otherwise add the mozillians page URL as event in the request form (or Reps profile URL).

Contact your mentor if you have doubts about reimbursing without an event, other questions reach out to @franc.

Mozilla Reps SEA (SouthEast Asia) Online Meetup

The next online meetup of ReMo SEA will be on Fri 22 MAY 2015 at 1200Z (UTC)

This is a monthly meet-up held by @bobreyes. Reps based in nearby countries (i.e. China [including Hong Kong], Taiwan, Japan and Korea) are also welcome to attend the online meetup, even people from Europe/Americas are invited to join!

They will share more details once the meet-up is over.

Full raw notes.

Don’t forget to comment about this call on Discourse and we hope to see you next week!

Andy McKayCommon People

Twenty years ago (May 22nd 1995), Pulp released the single "Common People":

Unfortunately, that version is censored. At 2 mins 30 seconds the lyrics are:

You'll never watch your life slide out of view,
and dance and drink and screw
Because there's nothing else to do.

The version on youtube omits "and screw". This song has some great lyrics:

Smoke some fags and play some pool, pretend you never went to school.
But still you'll never get it right
'cos when you're laid in bed at night watching roaches climb the wall
If you call your Dad he could stop it all.

This was a defining song of the Britpop era and I can remember it clearly being part of an Oasis (Manchester) vs Pulp (London) rivalry.

Of course, you haven't made it until William Shatner covers it:

Of that Jarvis said:

In 2011 Jarvis Cocker praised the cover version: "I was very flattered by that because I was a massive Star Trek fan as a kid and so you know, Captain Kirk is singing my song! So that was amazing."

Wikipedia

Apparently the subject of song is a lady who might have been named Danae, my wife's name.

There is a documentary about Pulp I haven't seen:

I'm now going to go listen to every Pulp song ever.

Robert O'CallahanBlinkOn 4

Last week I went to BlinkOn 4 in Sydney, having been invited by a Google developer. It was a lot of fun and I'm glad I was able to go. A few impressions:

It was good to hear talk about acting responsibly for the Web platform. My views about Google are a matter of public record, but the Blink developers I talked to have good intentions.

The talks were generally good, but there wasn't as much audience interaction as I'd expected. In my experience interaction makes most talks a lot better, and the BlinkOn environment is well-suited to interaction, so I'd encourage BlinkOn speakers and audiences to be a bit more interactive next time. I admit I didn't ask as many questions during talks as I usually do, because I felt the time belonged to actual Blink developers.

Blink project leaders felt that there wasn't enough long-term code ownership, so they formed subteams to own specific areas. It's a tricky balance between strong ownership, agile migration to areas of need, and giving people the flexibility to work on what excites them. I think Mozilla has a good balance right now.

The Blink event scheduling work is probably the only engine work I saw at BlinkOn that I thought was really important and that we're not currently working on in Gecko. We need to get going on that.

Another nice thing that Blink has that Gecko needs is the ability to do A/B performance testing on users in the field, i.e. switch on a new code path for N% of users and see how that affects performance telemetry.

On the other hand, we're doing some cool stuff that Blink doesn't have people working on --- e.g. image downscaling during decode, and compositor-driven video frame selection.

I spent a lot of time talking to Google staff working on the Blink "slimming paint" project. Their design is similar to some of what Gecko does, so I had information for them, but I also learned a fair bit by talking to their people. I think their design can be improved on, but we'll have to see about that.

Perhaps the best part of the conference was swapping war stories, realizing that we all struggle with basically the same set of problems, and remembering that the grass is definitely not all green on anyone's side of the fence. For example, Blink struggles with flaky tests just as we do, and deals with them the same way (by disabling them!).

It would be cool to have a browser implementors' workshop after some TPAC; a venue to swap war stories and share knowledge about how to implement all the specs we agreed on at TPAC :-).

Monica ChewTracking Protection for Firefox at Web 2.0 Security and Privacy 2015

My paper with Georgios Kontaxis got best paper award at the Web 2.0 Security and Privacy workshop today! Georgios re-ran the performance evaluations on top news sites and the decrease in page load time with tracking protection enabled is even higher (44%!) than in our Air Mozilla talk last August, due to prevalence of embedded third party content on news sites. You can read the paper here.

This paper is the last artifact of my work at Mozilla, since I left employment there at the beginning of April. I believe that Mozilla can make progress in privacy, but leadership needs to recognize that current advertising practices that enable "free" content are in direct conflict with security, privacy, stability, and performance concerns -- and that Firefox is first and foremost a user-agent, not an industry-agent.

Advertising does not make content free. It merely externalizes the costs in a way that incentivizes malicious or incompetent players to build things like Superfish, infect 1 in 20 machines with ad injection malware, and create sites that require unsafe plugins and take twice as many resources to load, quite expensive in terms of bandwidth, power, and stability.

It will take a major force to disrupt this ecosystem and motivate alternative revenue models. I hope that Mozilla can be that force.

Monica ChewFirefox 32 supports Public Key Pinning

Public Key Pinning helps ensure that people are connecting to the sites they intend. Pinning allows site operators to specify which certificate authorities (CAs) issue valid certificates for them, rather than accepting any one of the hundreds of built-in root certificates that ship with Firefox. If any certificate in the verified certificate chain corresponds to one of the known good certificates, Firefox displays the lock icon as normal.

Pinning helps protect users from man-in-the-middle-attacks and rogue certificate authorities. When the root cert for a pinned site does not match one of the known good CAs, Firefox will reject the connection with a pinning error. This type of error can also occur if a CA mis-issues a certificate.

Pinning errors can be transient. For example, if a person is signing into WiFi, they may see an error like the one below when visiting a pinned site. The error should disappear if the person reloads after the WiFi access is setup.

Firefox 32 and above supports built-in pins, which means that the list of acceptable certificate authorities must be set at time of build for each pinned domain. Pinning is enforced by default. Sites may advertise their support for pinning with the Public Key Pinning Extension for HTTP, which we hope to implement soon. Pinned domains include addons.mozilla.org and Twitter in Firefox 32, and Google domains in Firefox 33, with more domains to come. That means that Firefox users can visit Mozilla, Twitter and Google domains more safely. For the full list of pinned domains and rollout status, please see the Public Key Pinning wiki.

Thanks to Camilo Viecco for the initial implementation and David Keeler for many reviews!

Air MozillaGerman speaking community bi-weekly meeting

German speaking community bi-weekly meeting Zweiwöchentliches Meeting der deutschsprachigen Community. ==== German speaking community bi-weekly meeting.

Mozilla WebDev CommunityBeer and Tell – May 2015

Once a month, web developers from across the Mozilla Project get together to organize our poltical lobbying group, Web Developers Against Reality. In between sessions with titles like “Three Dimensions: The Last Great Lie” and “You Aren’t Real, Start Acting Like It”, we find time to talk about our side projects and drink, an occurrence we like to call “Beer and Tell”.

There’s a wiki page available with a list of the presenters, as well as links to their presentation materials. There’s also a recording available courtesy of Air Mozilla.

Groovecoder: WellHub

Groovecoder stopped by to share WellHub, a site for storing and visualizing log data from wells. The site was created for StartupWeekend Tulsa, and uses WebGL (via ThreeJS) + WebVR to allow for visualization of the wells based on their longitude/latitude and altitude using an Oculus Rift or similar virtual reality headset.

Osmose: Refract

Next up was Osmose (that’s me!), who shared some updates to Refract, a webpage previously shown in Beer and Tell that turns any webpage into an installable application. The main change this month was added support for generating Chrome Apps in addition to the Open Web Apps that it already supported.


This month’s session was a productive one, up until a pro-reality plant asked why we were having a real-life meetup for an anti-reality group, at which point most of the people in attendance began to scream uncontrollably.

If you’re interested in attending the next Beer and Tell, sign up for the dev-webdev@lists.mozilla.org mailing list. An email is sent out a week beforehand with connection details. You could even add yourself to the wiki and show off your side-project!

See you next month!

Aaron ThornburghWhy a Triceratops?

How to represent everyone without representing anyone.

Main image - Detail of infographic

Illustrating something highly-technical is more about storytelling than it is about design. My personal process often starts with a deluge of diagrams, wiki pages, stakeholder meetings, and follow-up discussions with engineers. Once I finally understand the details myself, it’s then my job to distill all that raw information into a single, coherent story.

That’s where the plot usually takes an interesting detour.

+++++

The Content Services team recently asked me to develop an infographic depicting “How user data is protected on Firefox New Tab” (PDF – 633 kB). The narrative itself was easy to illustrate because I had tremendous help from my teammates. But regardless of the refinements I continued making to the design, a crucial element always remained conspicuously absent:

The main character.

In this case, the main character was a Firefox User. My principle challenge, of course, was representing a person of any age, gender, ethnicity or language from around the globe. Secondarily, I wanted readers to feel something – maybe even smile. But most importantly, I wanted readers to clearly identify the User as the star of the infographic.

In other words, I needed a good mascot.

Folks don’t generally connect with the generic on an emotional level; so, I instinctively knew that flat, vaguely male or female silhouettes would be overly general for a global audience.

Maybe an animal? The Firefox mascot is a fox, after all, and small furry creatures are inherently disarming. I quickly discovered, though, that many animals could be interpreted as personalities types or even specific nations. Every option seemed close to the mark, but fell short upon further reflection.

Then the obvious roared in my face.

Historically, Mozilla has been represented by a dinosaur. And not the dead-fossil kind, either, but a living, breathing carnivore. I’ve always liked that image. The Mozilla T-rex, however, wasn’t the star of the story (and Mozillians aren’t all that carnivorous, anyway). Still, I could easily build upon this imagery without fear of alienating any particular person or group.

In the end, the species I chose to represent Users is one of the most recognizable. Besides being herbivores (which somehow seemed more appropriate), Triceratops command attention and demand respect. They’re creatures who appeal to our cooperative, yet intensely protective, instincts. They’re  important, impossible to ignore.

And when they’re smiling, it’s hard not to love them.

Done and done.


Air MozillaMay Brantina: Onboarding and the Cost of Team Debt with Kate Heddleston

May Brantina: Onboarding and the Cost of Team Debt with Kate Heddleston At our May Brantina (Breakfast + Cantina), we'll be joined by Kate Heddleston, a software engineer in San Francisco. Kate will share how effective onboarding...

Mozilla Privacy BlogPutting Our Data Privacy Principles Into Action

In November, we told you about Mozilla’s updated Data Privacy Principles, which inform how we build products, manage user data, and select and interact with partners. Today, Mozilla’s Content Services team is announcing its latest innovation in Web advertising – … Continue reading

Advancing ContentProviding a Valuable Platform for Advertisers, Content Publishers, and Users

Mozilla has a long history of innovating with how users interact with content: tabs, add-ons, live bookmarks, the Awesome bar – these and many more innovations  have helped the Web to dominate desktop computing for the last decade. Six months ago we launched Directory Tiles in Firefox, and have had great success with commercial partnerships and in aiding awareness for content important to the project, including Mozilla advocacy campaigns in support of net neutrality and the Mozilla Manifesto.

Today, I’m pleased to announce Suggested Tiles – our latest innovation and complement to Directory Tiles, as we work to create a more powerful and personalized Web experience for our users.  I discussed the Mozilla mission in the context of digital advertising earlier this year.  Suggested Tiles represents an important step for us to improve the state of digital advertising for the Web, and to deliver greater user agency.

Much of today’s digital advertising utilizes data harvested through a user’s browsing habits to target ads. However, many consumers are increasingly weary of how their data is being collected and shared in the advertising ecosystem without transparency and consent – and complex opt-outs or unreadable privacy policies exacerbate this. Many users even block advertisements altogether.  This situation is bad for users, bad for advertisers and bad for the Web.

With Suggested Tiles, we want to show the world that it is possible to do relevant advertising and content recommendations while still respecting users’ privacy and giving them control over their data.  And to bring influence to bear on the whole industry, we know we will need to deliver a highly effective advertising product.

A Suggested Tile In Context

A Suggested Tile In Context

 

We believe users should be able easily to understand what content is promoted, who it is from and why they are seeing it.  It is the user who owns the profile: only a Firefox user can edit their own browsing history.  And for users who do not want to see Suggested Tiles, opting out only takes two clicks from the New Tab page, without having to read a lot of instructions.  To deliver Suggested Tiles we do not retain or share personal data, nor are we using cookies.  If you want to learn more about how Suggested Tiles protect a user’s data, we produced this infographic, and the Mozilla policy team have described the details of how our data principles translate to the data policy for Suggested Tiles.

New Tab Controls

New Tab Controls

 

Suggested Tiles are controlled by the user, respect their privacy and are not directed towards a captive audience.  As different as this sounds, we believe that this makes Tiles a better experience for users and for advertisers.

Suggested Tiles will help advertisers and content owners connect with millions of Firefox users, and do so at a time when the user is receptive to hearing from them, making it a much more valuable connection. By delivering content experiences based on the user’s recent and most frequent browsing, we know when content will have high relevance.  And because we are delivering this content early in a browsing session – rather than mixed in with the user’s activity – we know they are more likely to engage with it.  We already have some very satisfied partners for Directory Tiles, and I am confident that Suggested Tiles will deliver even higher levels of engagement.

For partners who are interested in getting involved with the Suggested Tiles initiative, we have a site where you can learn more and register your interest: http://content.mozilla.org.

So what happens next? Suggested Tiles will be going to Beta soon and then live later in the summer. Initially, users will first see “Affiliate” Tiles advertisements for other Mozilla causes and Firefox products before Suggested Tiles from our content partners appear. Note that we’ll be rolling out the product in phases starting first with Firefox users in the US.

If you have any questions about how Suggested Tiles will work, need more information or want to explore a potential partnership with us, please visit content.mozilla.org.

This is still one of our early steps towards our goal of improving the state of digital advertising for the Web – delivering greater transparency for advertisers, better, more relevant content experiences and, above all, greater control for Firefox users.

Daniel Stenbergstatus update: http2 multiplexed uploads

I wrote a previous update about my work on multiplexing in curl. This is a follow-up to describe the status as of today.

I’ve successfully used the http2-upload.c code to upload 600 parallel streams to the test server and they were all sent off fine and the responses received were stored fine. MAX_CONCURRENT_STREAMS on the server was set to 100.

This is using curl git master as of right now (thus scheduled for inclusion in the pending curl 7.43.0 release).  I’m not celebrating just yet, but it is looking pretty good. I’ll continue testing.

Commit b0143a2a3 was crucial for this, as I realized we didn’t store and use the read callback in the easy handle but in the connection struct which is completely wrong when many easy handles are using the same connection! I don’t recall the exact reason why I put the data in that struct (I went back and read the commit messages etc) but I think this setup is correct conceptually and code-wise, so if this leads to some side-effects I think we need to just fix it.

Next up: more testing, and then taking on the concept of server push to make libcurl able to support it. It will certainly be a subject for future blog posts…

cURL

Mozilla Security BlogMozDef: The Mozilla Defense Platform v1.9

At Mozilla we’ve been using The Mozilla Defense Platform (lovingly referred to as MozDef) for almost two years now and we are happy to release v1.9. If you are unfamiliar, MozDef is a Security Information and Event Management (SIEM) overlay for ElasticSearch.

MozDef aims to bring real-time incident response and investigation to the defensive tool kits of security operations groups in the same way that Metasploit, LAIR and Armitage have revolutionized the capabilities of attackers.

We use MozDef to ingest security events, alert us to security issues, investigate suspicious activities, handle security incidents and to visualize and categorize threat actors. The real-time capabilities allow our security personnel all over the world to work collaboratively even though we may not sit in the same room together and see changes as they occur. The integration plugins allow us to have the system automatically respond to attacks in a preplanned fashion to mitigate threats as they occur.

We’ve been on a monthly release cycle since the launch, adding features and squashing bugs as we find them. You can find the release notes for this version here.

Notable changes include:

  •  Support for Google API logs (login/logout/suspicious activity for Google Drive/Docs)
  •  http://cymon.io api integration
  •  myo armband integration

Using the Myo armband in a TLS environment may require some tweaking to allow the browser to connect to the local Myo agent. Look for a how-to in the docs section soon.

Feel free to take it for a spin on the demo site. You can login by creating any test email/password combination you like. The demo site is rebuilt occasionally so don’t expect anything you put there to live for more than a couple days but feel free to test it out.

Development for the project takes place at mozdef.com and report any issues using the github issue tracker.

Air MozillaKids' Vision - Mentorship Series

Kids' Vision - Mentorship Series Mozilla hosts Kids Vision Bay Area Mentor Series

Mozilla Addons BlogAdd-ons Update – Week of 2015/05/20

I post these updates every 3 weeks to inform add-on developers about the status of the review queues, add-on compatibility, and other happenings in the add-ons world.

The Review Queues

  • Most nominations for full review are taking less than 10 weeks to review.
  • 194 nominations in the queue awaiting review.
  • Most updates are being reviewed within 6 weeks.
  • 112 updates in the queue awaiting review.
  • Most preliminary reviews are being reviewed within 9 weeks.
  • 222 preliminary review submissions in the queue awaiting review.

If you’re an add-on developer and would like to see add-ons reviewed faster, please consider joining us. Add-on reviewers get invited to Mozilla events and earn cool gear with their work. Visit our wiki page for more information.

Firefox 38 Compatibility

The Firefox 38 compatibility blog post is up. The automatic AMO validation was already run. There’s a second blog post covering the upcoming 38.0.5 release and in-content preferences, which were an oversight in the first post.

Firefox 39 Compatibility

The Firefox 39 compatibility blog post is up. I don’t know when the compatibility validation will be run yet.

As always, we recommend that you test your add-ons on Beta and Firefox Developer Edition (formerly known as Aurora) to make sure that they continue to work correctly. End users can install the Add-on Compatibility Reporter to identify and report any add-ons that aren’t working anymore.

Extension Signing

We announced that we will require extensions to be signed in order for them to continue to work in release and beta versions of Firefox. A followup post was published recently, addressing some of the reasons behind this initiative.

A couple notable things are happening related to signing:

  • Signing will be enabled for AMO-listed add-ons. This means that new versions will be automatically signed, and the latest versions of all listed add-ons will also be signed. Expect this to happen within a week or so (developers will be emailed when this happens). Signing for unlisted (non-AMO) add-ons is still not enabled.
  • The signature verification code is now active on Developer Edition, in case you want to try it out with unsigned extensions. The preference is set to warn about unsigned extensions, but still accept and install them. You can use Developer Edition to test your extensions after we let you know they’ve been signed.
  • A new Developer Agreement will be published on AMO. This is a significant update over the current years-old agreement, covering signing, listed and unlisted add-ons, themes, and other developments that have happened since. Developers will be notified when the new agreement is up.

Electrolysis

Electrolysis, also known as e10s, is the next major compatibility change coming to Firefox. In a nutshell, Firefox will run on multiple processes now, running each content tab in a different one. This should improve responsiveness and overall stability, but it also means many add-ons will need to be updated to support this.

We will be talking more about these changes in this blog in the future. For now we recommend you start looking at the available documentation.

Jim ChenPost Fennec logs to Pastebin with LogView add-on

The LogView add-on for Fennec now lets you copy the logcat to clipboard or post the logcat to pastebin.mozilla.org. Simply go to the about:logs page from Menu → Tools → Logs and tap on “Copy” or “Pastebin”. This feature is very useful if you encounter a bug and need the logs, but you are not next to a computer or don't have the Android SDK installed.

Copy to clipboard Posting to Pastebin Posted to Pastebin


Last modified: 2015/05/20 15:49

Air MozillaProduct Coordination Meeting

Product Coordination Meeting Duration: 10 minutes This is a weekly status meeting, every Wednesday, that helps coordinate the shipping of our products (across 4 release channels) in order...

Joel Maherre-triggering for a [root] cause – version 1.57

Last week I wrote some notes about re-triggering jobs to find a root cause.  This week I decided to look at the orange factor email of the top 10 bugs and see how I could help.  Looking at each of the 10 bugs, I had 3 worth investigating and 7 I ignored.

Investigate:

  • Bug 1163911 test_viewport_resize.html – new test which was added 15 revisions back from the first instance in the bug.  The sheriffs had already worked to get this test disabled prior to my results coming in!
  • Bug 1081925 browser_popup_blocker.js – previous test in the directory was modified to work in e10s 4 revisions back from the first instance reported in the bug, causing this to fail
  • Bug 1118277 browser_popup_blocker.js (different symptom, same test pattern and root cause as bug 1081925)

Ignore:

  • Bug 1073442 – Intermittent command timed out; might not be code related and >30 days of history.
  • Bug 1096302test_collapse.html | Test timed out. >30 days of history.
  • Bug 1151786 testOfflinePage. >30 days of history. (and a patch exists).
  • Bug 1145199 browser_referrer_open_link_in_private.js. >30 days of history.
  • Bug 1073761 test_value_storage.html. >30 days of history.
  • Bug 1161537 test_dev_mode_activity.html. resolved (a result from the previous bisection experiment).
  • Bug 1153454 browser_tabfocus.js. >30 days of history.

Looking at the bugs of interest, I jumped right in in retriggering.  This time around I did 20 retriggers for the original changeset, then went back to 30 revisions (every 5th) doing the same thing.  Effectively this was doing 20 retriggers for the 0, 5th, 10th, 15th, 20th, 25th, and 30th revisions in the history list (140 retriggers).

I ran into issues doing this, specifically on Bug 1073761.  The reason why is that for about 7 revisions in history the windows 8 builds failed!  Luckily the builds finished enough to get a binary+tests package so we could run tests, but mozci didn’t understand that the build was available.  That required some manual retriggering.  Actually a few cases on both retriggers were actual build failures which resulted in having to manually pick a different revision to retrigger on.  This was fairly easy to then run my tool again and fill in the 4 missing revisions using slightly different mozci parameters.

This was a bit frustrating as there was a lot of manual digging and retriggering due to build failures.  Luckily 2 of the top 10 bugs are the same root cause and we figured it out.  Including irc chatter and this blog post, I have roughly 3 hours invested into this experiment.


Mozilla Release Management TeamFirefox 38.0.5 beta 2 to 38.0.5 beta 3

As all the release of this special 38.0.5 cycle, we took mostly patches for the Pocket integration, some reader view improvements and stability fixes.

The next version should be 38.0.5 rc1 (go to build Thursday, go live Friday).

  • 21 changesets
  • 38 files changed
  • 393 insertions
  • 132 deletions

ExtensionOccurrences
js6
jsm5
cpp5
properties4
ini3
html3
txt2
inc2
h2
xul1
sh1
nsi1
mk1
dtd1
css1

ModuleOccurrences
browser21
dom7
testing3
widget2
mobile2
toolkit1
editor1
config1

List of changesets:

Gijs KruitboschBug 1160775 - fix reader mode detection to force 1 flush so we don't think the entire page is invisible, r=margaret a=lmandel - 93b96d846d47
Margaret LeibovicBug 1152412 - Handle errors downloading and parsing documents for reader view. r=bnicholson a=lmandel - 964442785c00
Gijs KruitboschBug 1134501 - add way for UITour'd page to force-show the reader mode button, r=margaret a=lmandel - 5741ccc7bb74
Kartikaya GuptaBug 1163640 - Fix the test for Bug 417418 to not leave the widget in a drag session. r=ehsan, a=test-only - df02fefaa438
Mike ShalBug 1122746 - Ignore *.pyc in zip instead of removing them. r=ted, a=test-only - 06cc113b476f
James GrahamBug 1135515 - Fix relevant mutations tests to avoid intermittent issues. a=test-only - 82e59df1da4e
Martin ThomsonBug 1158296 - Allow ECDSA key export in WebCrypto. r=rbarnes, a=sledru - 1a8cd9f5bdad
Karl TomlinsonBug 1159456 - Finish and exit from Flush() even if MFTManager rejects sample. r=cpearce, a=sledru - 825e8ac4ab29
Jan-Ivar BruaroeyBug 1150539 - getUserMedia: default to aPrefs.mFPS, not aPrefs.mMinFPS. r=jesup, a=lizzard - cfa10b9f0f9d
Jan-Ivar BruaroeyBug 1162412 - Part 1: Don't treat plain facingMode constraint as required. r=jesup, a=lmandel - c14434ed2197
Jan-Ivar BruaroeyBug 1162412 - Part 2: Order devices by shortest fitness distance. r=jesup, a=lmandel - 9c1d3c0257ec
Jan-Ivar BruaroeyBug 1162412 - Part 3: Treat plain values as exact in advanced. r=jesup, a=lmandel - e3045256cb27
Jeff MuizelaarBug 1157784 - Avoid compositing at the same time as WM_SETTEXT. r=bas, f=jimm, a=sledru - ecbce7532a0a
Jared WeinBug 1162713 - Implement "Save Link to Pocket" context menu item. r+a=dolske, l10n=dolske - e13a7a312aa5
Gijs KruitboschBug 1164940 - Lazily create iframe. r=jaws, a=sledru - 24524667128b
Gijs KruitboschBug 1164426 - Build reader mode blocklist. r=margaret, a=sledru - 6ec85b777880
Robert StrongBug 1165135 - Distribution directory not removed on pave over install. r=spohl, a=sledru - 4bfd19d00ed4
Jared WeinBug 1163917 - Remove the widget from its area if the conditionalDestroy promise is resolved truthy. r=gijs, a=sledru - f9328a6ea6bd
Nate WeinerBug 1165416 - Update Pocket code to latest version (May 15th code drop). r=dolske, r=jaws, a=sledru - e6f89a184268
Jared WeinBug 1160407 - Redirect links within the Pocket panel to open in non-private windows when temporary Private Browsing is used. r=dolske, a=sledru - f5828f333524
Gijs KruitboschBug 1147487 - Don't try to reader-ize non-HTML documents. r=margaret, r=jaws, a=lmandel - f44dff585598

Mike ConleyLost in Data!

Keeping Firefox zippy involves running performance tests on each push to make sure we’re not making Firefox slower.

How does that even work? This used to be a mystery. NO LONGER. jmaher lets you peek behind the curtain here in the first episode of Lost in Data!

Christie KoehlerThe Recompiler: Now with more podcast!

The Recompiler logoIf you’ve been watching my tweetstream recently, you know that The Recompiler (@recompilermag), a magazine about technology, is in the final days hours of it’s inaugural subscription drive.

Yesterday, Audrey announced that we’re going create a podcast version of The Recompiler!

Some of you may have listened to In Beta, which I co-hosted last year. Doing that podcast was great fun and I’m so looking forward to hosting this supplement to The Recompiler. The podcast will enhance the written version of the magazine with tech news, criticism & commentary plus interviews with our authors.

If you’re craving awesome, insightful conversation on technical topics from fresh, less-heard-from voices, then The Recompiler podcast is for you!

Get involved and support The Recompiler today by purchasing a subscription and look for the first written issue and episode this summer!

Gavin Sharpleaving mozilla

I started contributing to Mozilla nearly 11 years ago, in 2004, and joined as a full-time employee over 8 years ago. Suffice it to say, Mozilla has been a big part of my life in a lot of ways. I’ve dedicated essentially my entire career so far to Mozilla, and it introduced me to my wife, just to name a couple.

Mozilla’s in a great place now – still a tough challenge ahead, but plenty of great people willing and able to tackle it. Firefox has new leadership, the team is being re-organized and groups merged together in what I think are the right ways, and I’m optimistic about their prospects. But it’s time for me to move on and find The Next Thing – that I have no idea what it is now is both exciting and a little bit terrifying, but I feel good about it.

It will probably take me a while to figure out what exactly a post-Mozilla Gavin-life looks like, given the various ways Mozilla’s been injected into my life. I won’t disappear entirely, certainly, and I know the many relationships I’ve built through Mozilla will continue to be a huge part of my life.

I’m looking forward to what’s next!

Air MozillaLost in Data - Episode 1

Lost in Data - Episode 1 Join Joel Maher in a livehacking session where he is triaging and investigating Firefox performance alerts.

Mozilla Open Policy & Advocacy BlogMozilla Advocacy – 2015 Plan

Mozilla Advocacy — Our 2015 Plan for Protecting and Advancing the Open Web

Advocacy is a relatively new area of focus for Mozilla. Our increased emphasis on advocacy is born out of the recognition that, like code, public policy has an impact on the shape and health of the open web — and that a vital force protecting the web will be the millions of people who consider themselves to be citizens of the web.

Over the next few weeks, the Mozilla Advocacy team — including Andrea Wood, Director of Digital Advocacy and Fundraising; Melissa Romaine, Advocacy Manager; Chris Riley, Head of Public Policy; Stacy Martin, Senior Manager of Privacy and Engagement; Jochai Ben-Avie, Internet Policy Manager; and, Alina Hua, Senior Data Privacy Manager —  will lay out our latest thinking about how we’re developing public policy and creating advocacy initiatives.

Our goal with Mozilla Advocacy is to advance the Mozilla mission by empowering people to create measurable changes in public policy to protect the Internet as a global public resource, open and accessible to all. Our three strategies to achieve this goal are:

  1. Leadership Development — Grow a global cadre of leaders — activists, technologists, policy experts — who advance the free and open web.

  2. Community — Assist, grow, and enable the wider policy & advocacy community.

  3. Grassroots Advocacy — Run issue-based campaigns to grow mainstream engagement with Mozilla and open web issues.

Each of these strategies ties directly to the goal of empowering people. Yet, as we execute there are still open questions that need input and more thought from the community. For instance, how can we create better scale and participation, recognizing that real impact happens when the community is empowered to take action on policy and advocacy initiatives. A key to this is making our own policy positions and advocacy efforts easier for people to understand and engage with.

We need you to play an active role. Because the web is growing in markets where we are not experts, the Mozilla community will play a central role in scaling efforts to protect the open web throughout the world. We invite you to help shape our thinking by reading the 2015 Policy & Advocacy Plan and offering input through this thread in the Mozilla Advocacy Community.

–Dave Steer, Director of Advocacy, Mozilla

Mozilla Addons BlogWhich T-shirt Design is Your Favorite?

The judges have selected their three favorite designs for a new AMO t-shirt, and now it’s your turn to tell us which one you’d like to see printed. The shirts will be sent to add-on developers as a thank-you gift, so choose wisely!

The deadline to vote is Tuesday, June 2.

Michael Kaplydistribution/bundles Directory Gone in Firefox 40

Bug 1144127 was checked in. This means that starting in Firefox 40, placing add-ons in the distribution/bundles directory will no longer work.

For many years I recommended distribution/bundles as the best place for enterprises to deploy non bootstrapped extensions. It allowed them to make their extensions a part of core Firefox and prevent users from removing them. Unfortunately adware/spyware folks started using this method as well, so we lost this ability. (This is why we can't have nice things.)

So what does this mean going forward?

  • You will no longer be able to disable safe mode. You can set the environment variable MOZ_DISABLE_SAFE_MODE_KEY to prevent using the startup shortcut or set MOZ_DISABLE_AUTO_SAFE_MODE to prevent crashes from starting safe mode, but a user will always be able to start Firefox in safe mode from the command line.
  • It's much more difficult for you to prevent a user from disabling any extensions you need to add for your company. You'll probably need to do something evil like hide them inside of the add-ons manager. You can contact me if you need code to do that.
  • AutoConfig now becomes the preferred method of doing pretty much any Firefox configuration (since you can't place a custom extension into the distribution/bundles directory).

I'm actively working on making the CCK2 work without the distribution directory. The latest beta is here. Obviously some features will be lost st first. I hope to bring as many back as I can. It should be ready by the end of the week I hope.

As a side note, this means that many of my blog posts will have incorrect information. I'm still trying to figure out how to solve that going forward.

Adam LoftingThe importance of retention rates, explained by @bbalfour

In my last post I shared a tool for playing with the numbers that matter for growing a product or service. (I.e. Conversion, retention and referral rates).

This video of a talk by Brian Balfour is a perfect introduction / guide to watch if you’re also playing with that tool. In particular, the graphs from 1:46 onwards.

Mozilla Release Management TeamFirefox 38.0.5b1 to 38.0.5b2

Mostly a Pocket's change beta release.

  • 23 changesets
  • 45 files changed
  • 549 insertions
  • 136 deletions

ExtensionOccurrences
js13
jsm5
css4
mn3
cpp3
ini2
handlebars2
h2
xul1
txt1
svg1
java1
inc1

ModuleOccurrences
browser27
toolkit5
image4
mobile1
gfx1
config1
browser1

List of changesets:

tbirdbldAutomated checkin: version bump for thunderbird 38.0b5 release. DONTBUILD CLOSED TREE a=release - 88aaccce3910
Nick ThomasBacked out changeset 88aaccce3910, a thunderbird specific version change on default DONTBUILD CLOSED TREE, a=release - 983ca4a03205
David MajorBug 1154703 - Fix typo in nvdxgiwrap filename. r=jrmuizel, a=lmandel - fff54632eedd
Matthew NoorenbergheBug 1162205 - Don't import encrypted cookies from Chrome. r=mak a=lmandel - c5a80a2102b6
Seth FowlerBug 1161859 - Compute the size of animated image frames correctly in the SurfaceCache. r=dholbert, a=lmandel - aa3a683fd335
Garvan KeeleyBug 1164468 - Boolean got incorrectly flipped and stumbling uploads stopped. r=rnewman, a=lmandel - 4aac185d033d
Blake WintonBug 1158289 - Use ems to keep the Reader View's line length between 45 and 75 characters. ui-r=mmaslaney, r=margaret, a=lmandel - 5fff1e20ed9c
Seth FowlerBug 1161859 (Followup) - Correct nsIntSize / IntSize mismatch in Decoder.cpp on a CLOSED TREE. a=KWierso - 5da39cd23ade
Jared WeinBug 1162316 - Update the Pocket Toolbar @2x asset on OSX with the correct aspect ratios. r=dolske a=dolske - 21c86665a21d
Jared WeinBug 1155517 - Change Reader View to have a "Save Page to Pocket" button instead of "Add To Reader List". r=dolske a=dolske - 921eb304600e
Nate WeinerBug 1163576 - Pages that were only added to Pocket by one user failed to get removed. r=jaws a=dolske - f7f9fc975cdc
Jared WeinBug 1163651 - [Windows]View Pocket List icon from Bookmarks menu is missing. r=dolske a=dolske - 01c7b55e4a28
Nate WeinerBug 1164161 - Panel dictionary file missing entries for some languages. r=jaws a=dolske - 98b2f2b5af65
Justin DolskeBug 1164253 - Save request is sent twice for every button press. r=jaws a=dolske - 89ef57a1733a
Justin DolskeBug 1164208 - Update Pocket code to latest version (May 11th code drop) r=jaws a=dolske - 55c04a549775
Nate WeinerBug 1163411 - Update View Pocket Menu Link. r=jaws a=dolske - 9a7a198e1b06
Gijs KruitboschBug 1164302 - pocket button gets lost after a restart, r=jaws a=dolske - d5ba1bc97911
Matthew NoorenbergheBug 1161810 - UITour: Allow opening the Pocket panel via showMenu("pocket"). r=jaws a=dolske - 06499c7a81a9
Gijs KruitboschBug 1164410 - fix l10n use in pocket, r=jaws a=dolske - 48eaac80d6b5
Justin DolskeBug 1164407 - Pocket not enabled on ja builds under Mac OS X. r=adw a=dolske - 99ea3c3c13f6
Nate WeinerBug 1164419 - [OSX] Pocket panel for ru locale build has misaligned elements. r=dolske a=dolske - f724af08988f
Nate WeinerBug 1164698 - Update Pocket code to latest version (May 13th code drop). r=dolske a=dolske - 11c4678a21bb
Jared WeinBug 1163519 - Add in missing CustomizableUI getter to ReaderParent.jsm. r=gijs, a=dolske - 195e873a8ab1

Mozilla Release Management TeamFirefox 38.0.1 to 38.0.5b1

For this first beta of this special cycle, we took two kind of changes: * the Pocket feature * stability fixes

  • 59 changesets
  • 226 files changed
  • 12063 insertions
  • 919 deletions

ExtensionOccurrences
java36
js29
css16
mn8
jsm8
xul5
properties5
html5
handlebars5
gradle5
cpp5
inc4
h4
txt3
ini3
in3
build3
xml2
sh2
rst2
cfg2
py1
json1
hgtags1
dtd1
cc1

ModuleOccurrences
mobile69
browser38
browser30
toolkit11
layout7
browser6
testing3
media3
dom3
config1

List of changesets:

Shane CaraveoBug 936426 - Fix intermittent error, reduce testing to what we actually need here. r=markh, a=test-only - f33925faccee
Ryan VanderMeulenMerge release to beta. CLOSED TREE - f84585d763a5
Rail AliievBug 1158760 - Wrong branding on the 38 Beta 8, backout d27c9211ebb3. IGNORE BROKEN CHANGESETS CLOSED TREE a=release ba=release - b91226cec861
Ryan VanderMeulenBacked out changeset b1bfde2ccb22 to revert back to beta branding while Fx 38.0.5 is still shipping betas. - 27bacb9dff64
Ed LeeBug 1161245 - Backout Suggested Tiles (Bug 1120311) from 38.0.5 [a=sylvestre, a=lmandel] - 9a494b64194e
Margaret LeibovicBug 1144822 - Hide elements with common hidden class names in reader content. r=Gijs, a=sledru - e4a70d181871
Margaret LeibovicBug 1154028 - Move reader content styles to scoped style sheet. r=Gijs, a=sledru - 80a9584ac5e4
Margaret LeibovicBug 1154028 - Move reader controls styles to scoped style sheet. r=Gijs, a=sledru - c64ca42b7490
Blake WintonBug 1158302 - Increase the Font Size of Reader's H1 and H2 Headers. ui-r=mmaslaney, r=Gijs, a=lizzard - 3058929d4335
Blake WintonBug 1158294 - Increase Reader Views Default Type Size. ui-r=mmaslaney, r=margaret, a=lizzard - 8cba8416a229
Matthew NoorenbergheBug 1134507 - Implement infopanel to promote Reader View when first available. r=Gijs, a=sledru - f53c601dafa3
Blake WintonBug 1158281 - Match Pocket's Reader View Sepia Theme. ui-r=mmaslaney, r=margaret, a=sledru - 810e81a9bced
Gijs KruitboschBug 1154063 - Fix CSS issue in aboutReader.css. r=bwinton, a=sledru - cc2718d0f570
Gijs KruitboschBug 1158322 - force-display-none the toolbar and footer when printing. r=margaret, a=sledru - 16cdaa6a3712
Ryan VanderMeulenBug 1131931 - Skip various tests on OSX and Windows debug for intermittent crashes. a=test-only - 010ace914d50
Morris TsengBug 1151111 - Append iframe2 after iframe1 has loaded. r=kchen, a=test-only - e4e557754405
Maire ReavyBug 1159659 - Allow tab sharing on XP and OSX 10.6. r=pkerr, a=lizzard - db14fef19c05
Margaret LeibovicBug 1158228 - Merge github's readability code into m-c. a=sledru - 503f9aa61c25
Margaret LeibovicBug 1158228 - Disable visibility check helper function to avoid test bustage. a=sledru - 46b968653f4d
Jared WeinBug 1155523 - Implement Pocket toolbarbutton and subview. r=gijs - 3e9805c11aa3
Florian QuèzeBug 1156878 - Send a request to the server when clicking the Pocket toolbar button, r=jaws. - 16e406d46c18
Jared WeinBug 1159744 - Use the panel implementations from the Pocket add-on for the Pocket feature. r=dolske - 1c86609b511c
Florian QuèzeBug 1155518 - Implement "Save to Pocket" context menu item, r=jaws. - 0a18ef5ab9b7
Florian QuèzeBug 1155519 - Add "View Pocket Items" menuitem to the bookmarks menu, r=dolske. - a1b09394f8c5
Jared WeinBug 1161654 - Import latest Pocket code. r=dolske - 3d9d572c9ec4
Jared WeinBug 1160578 - Disable the Pocket button for logged-in users on internal Firefox pages. r=dolske - 77ec9aee0263
Jared WeinBug 1161654 - Remove some dead code in Pocket.jsm and use pktApi for checking if the user is logged in. r=dolske - 125c7dbe7528
Jared WeinBug 1160678 - Pocket door hangers arent automatically closed. r=dolske a=sledru - 53b766c68811
Gavin SharpBug 1138079 - Fix focus issue that sometimes affects browser-chrome test runs. r=enndeakin, a=test-only - 96da8302e8a2
Justin DolskeBug 1162198 - [EME] Doorhanger that notifies user of DRM usage should include a Learn More link. r=gijs, a=sledru - 121ed6b9b6dd
David MajorBug 1155836: Template on aComputeData in the DoGetStyle* helpers. r=dbaron f=bz a=sylvestre - 7e44bac27dd6
Randell JesupBug 1162251: Fix WebRTC jitter buffer ignoring partial frames if the packet holds a complete NAL r=ehugg a=sylvestre - 124857c54a1b
Byron Campen [:bwc]Bug 1161317: Fix bug where sendonly video RTCP would be treated as outgoing RTP r=jesup a=sylvestre - 62ee103ccbbe
Gijs KruitboschBug 1158884 - hide pocket on android, fix AboutReader.jsm on android, r=margaret,jaws a=dolske - 20872d739a18
Jared WeinBug 1158960 - Reader view is broken in e10s mode. r=Gijs a=dolske - 92c7576dce37
Jared WeinBug 1159410 - Update the Pocket toolbar icon highlight to coral. r=dolske a=dolske - 8c8f410e61e8
Justin DolskeBug 1161796 - Remove unused strings from Pocket. r=jaws a=dolske: - 52bc3790d7b0
Justin DolskeBug 1160663 - Allow hilighting the Pocket button via UITour. r=MattN a=sledru - 1701e22c91f6
Gijs KruitboschBug 1155521 - Migrate Pocket add-on and social provider users to the new Pocket button (part 1, CustomizableUI changes). r=jaws, a=dolske - 6be4fccbdfa3
Drew WillcoxonBug 1155521 - Migrate Pocket add-on and social provider users to the new Pocket button (part 2, migration). r=jaws, a=dolske - 257c096c7673
Gijs KruitboschBug 1161838 - fix positioning of newly added widgets, r=jaws a=dolske - 2eeb61f35995
Jared WeinBug 1162735 - Re-add code that got removed accidentally to fix context menus. r=florian a=dolske - ccec3836123c
Jared WeinBug 1161793 - Wait to run the Pocket popupshowing code until the popupshowing event is dispatched, same for the popupshown code. r=dolske a=dolske - 18bf7b4baaac
Justin DolskeBug 1161881 - Enable Pocket by default (in supported locales), r=gavin a=sledru - 067c9c7a5e75
Justin DolskeBug 1162253 - Update the Pocket Menu Icon with the correct aspect ratios. r=jaws, a=dolske - 3f2619b0d039
Justin DolskeBug 1162147 - "View Pocket List" menuitem should be at top of bookmarks menu. r=jaws, a=dolske - 740f3d68a0f6
Justin DolskeBug 1163349 - "View Pocket List" menuitem not working. r=gavin, a=dolske - 83c0c74947a3
Jared WeinBug 1163111 - Update Pocket code to latest version (May 7th code drop). r=dolske a=dolske - a1c5d7a6a784
Drew WillcoxonBug 1162283 - Add support for limited hard-coded localizations to Pocket. r=dolske, a=dolske - e7c47480555d
Justin DolskeBug 1163265 - Update Pocket code to latest version (May 8th code drop) r=jaws, a=dolske - 86e98ffc152b
Justin DolskeBug 1163360 - Update Pocket code to latest version (May 9th code drop) r=jaws, a=dolske - f4179577249b
Justin DolskeBug 1163319 - Pocket button in hamburger menu breaks layout. r=jaws, a=dolske - 32b69592b334
Shane CaraveoBug 1024253 - Fix chat tests on ubuntu. r=markh, a=test-only - 5081fb1d38f0
Tim TaubertBug 961215 - Fix intermittent browser_tabview_bug625269.js failures by taking into account that window.resizeTo() can fail to change the window size sometimes. r=MattN, a=test-only - 97b29f79be5c
Margaret LeibovicBug 1160577 - Set styles on #reader-message div instead of wrapper div. r=MattN a=sledru - ad9164105253
Florian QuèzeBug 1160076 - Hide the in-content preferences Search pane when browser.search.showOneOffButtons is false. r=Gijs, a=sledru - 855c88138927
Gijs KruitboschBug 1162917 - Update readability from github repo. a=sledru - 5fc66f6dd277
Margaret LeibovicBug 1129029 - Telemetry probes for reader mode performance. r=Gijs, a=sledru - 85229fbaf017
Justin DolskeBug 1163645 - Pocket only enabled on en-US, hard-coded locales aren't picked up. r=adw, a=dolske - fff143cacb66

Mozilla Release Management TeamFirefox 38.0 to 38.0.1

This dot release contains some important fixes impacting a lartge number of users. For more information => the release notes.

  • 6 changesets
  • 14 files changed
  • 136 insertions
  • 18 deletions

ExtensionOccurrences
js3
cpp3
txt2
h2
java1
ini1

ModuleOccurrences
browser6
image4
mobile1
gfx1
config1

List of changesets:

Matthew NoorenbergheBug 1162205 - Don't import encrypted cookies from Chrome. r=mak a=lmandel - 7bf6c9a78588
David MajorBug 1154703 - Fix typo in nvdxgiwrap filename. r=jrmuizel, a=lmandel - d204dd3fd48b
Matthew NoorenbergheBustage fix for 7bf6c9a78588 due to lack of Bug 982852. a=bustage - f0fbb7ca3977
Seth FowlerBug 1161859 - Compute the size of animated image frames correctly in the SurfaceCache. r=dholbert, a=lmandel - 570b63d791b9
Garvan KeeleyBug 1164468 - Boolean got incorrectly flipped and stumbling uploads stopped. r=rnewman, a=lmandel - 273d39c4aa20
Seth FowlerBug 1161859 (Followup) - Correct nsIntSize / IntSize mismatch in Decoder.cpp on a CLOSED TREE. a=KWierso - bb7af314a8ac

Air MozillaMartes Mozilleros

Martes Mozilleros Reunión bi-semanal para hablar sobre el estado de Mozilla, la comunidad y sus proyectos. Bi-weekly meeting to talk (in Spanish) about Mozilla status, community and...

Christian Heilmann</may-tour> – I did it!

Sitting in the lovely conference hotel Estherea in Amsterdam, I am ready to go to Schipol to fly back home to London. This marks the end of the massive conference tour in beggining May. I can’t believe it all worked out, although I had to re-book one flight and I stayed for two days at each location.

Chris pumping up a boat called internet others punch holes in
(sketch from my Beyond Tellerand keynote by Manuel Ortiz)

Here’s what happened:

Now it is time to wash my clothes, send all the emails I stacked up during bad connectivity times and clean out my flat to move to another one. Oh yeah, and two more conferences this month :)

Marco ZeheAccessibility in 64-bit versions of Firefox for Windows

Over the past two weeks, Trevor, Alex and I worked on 64-bit support for Firefox on Windows. I am pleased to announce that we were successful, and that Win-64 versions of Firefox Nightly builds should now work with screen readers. So if you have a 64-bit edition of Windows 7, 8.x or 10 Preview, and run NVDA, JAWS, Window-Eyes or other screen readers that support Firefox, you should be able to uninstall the 32-bitz version of Firefox Nightly if you have it installed, and download and run the 64-bit installer from the above linked page.

It is expected that everything works as in the 32-bit version. If, for some reason, you find oddities, we do want to know about them ASAP. We plan to backport support to Firefox Dev Edition (currently at version 40), and maybe 39 beta, but the latter is not certain yet.

So if you use Nightly anyway, and would like to help, we definitely appreciate you switching over to the 64 bit edition and give us feedback! Thanks!

Air MozillaMaintaining & growing a technical community

Maintaining & growing a technical community How do you support a diverse community, acknowledge many different voices and perspectives, be open and inclusive, and still get things done (especially when you...

Air MozillaWhat's new in Firefox?

What's new in Firefox? Let's review together what happened with Firefox in 2014 and where we are headed in 2015.

Wil ClouserEnabling Encryption in Weechat

Here are some step by step instructions for enabling encryption using crypt.py in weechat.

First, ensure the crypt.py script is installed. The easiest way is from within weechat itself:

/plugin load script
/script install crypt.py
/script autoload crypt.py

You should see some simple messages saying crypt.py was installed and enabled for automatic loading.

Next you need to generate an encryption key. This just needs to be named with the channel you want to use the key with (I use #channel below). For example:

cd .weechat
openssl genrsa -out cryptkey.#channel 4096

We might as well make sure only we can read it:

chmod 600 cryptkey.#channel

At this point typing any text in #channel will automatically be encrypted (use a second client if you'd like to verify it). For example, I typed:

1811 clouserw │ testo

And the other clients in #channel see:

1811 clouserw | +qRy3GsV2sPRlJSdP1IqqV|

The next step is to distribute the key to the other people who will need to decrypt the chat. Take a minute to consider the best way to do this as the chat will only be as secure as this key.

Lastly, you can optionally add an indicator to the status bar by adding 'encrypted' to weechat.bar.status.items. This command will tell you your current value:

/set weechat.bar.status.items

Copy that value and add 'encrypted' where you'd like it to show up. Mine is:

/set weechat.bar.status.items "[time],[buffer_count],[buffer_plugin],buffer_number+:+buffer_name+{buffer_nicklist_count}+buffer_filter,encryption,[lag],[hotlist],completion,scroll"

which looks like this:

[18:16] [32] [irc/freenode] 30:#channel{3}⚑ (encrypted)  [H: 3, 4]

That's all there is too it!

Byron Joneshappy bmo push day!

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

  • [1146770] implement comment preview
  • [1116118] 003safesys.t shouldn’t compile all files by default
  • [1163326] implement dirty select tracking in bug-modal to address firefox refresh issue
  • [1160430] Add the ability to deactivate keywords
  • [1164863] checksetup.pl is unable to run if File::Slurp is missing
  • [908387] product/component searching should sort hits on product/component name before hits on descriptions
  • [1165741] query.cgi’s Component list should be sorted case-independent
  • [1165464] Incorrect link used for firefox help
  • [1162334] email_enabled value inverted in User.update RPC call
  • [1165917] support tbplbot@gmail.com and treeherder@bots.tld as the tbpl/treeheder bot name

discuss these changes on mozilla.tools.bmo.


Filed under: bmo, mozilla

The Mozilla BlogOpen Web Device Compliance Review Board Certifies First Handsets

Announcement Marks Key Point in Development of Open Source Mobile Ecosystem

San Francisco, Calif. – May 18, 2015: – The Open Web Device Compliance Review Board (CRB), in conjunction with its members ALCATEL ONE TOUCH, Deutsche Telekom, Mozilla, Qualcomm Technologies, Inc., and Telefónica, has announced the first handsets to be certified by the CRB. The CRB is an independently operated organization designed to promote the success of the open Web device ecosystem by encouraging API compliance as well as ensuring competitive performance.

The two devices are the Alcatel ONETOUCH Fire C and the Alcatel ONETOUCH Fire E. ALCATEL ONETOUCH has also authorized a CRB lab.

The certification process involves OEMs applying to the CRB for their device to be certified. CRB’s authorized labs test the device for open web APIs and key performance benchmarks. CRB’s subject matter experts review the results and validate against CRB stipulated benchmarks with a reference device to ensure compatibility and performance across key use cases. The two ALCATEL ONETOUCH devices passed the CRB authorized test lab procedure and met all CRB certification requirements.

The process is open to all device vendors whether they are a member of CRB or not. The CRB website www.openwebdevice.org will publish the process for applying for certification.

CRB certification testing is conducted by industry labs authorized by the CRB, with each submission expected to be completed within approximately three days. The CRB offers a platform for the rest of the industry to request certification.

“As an initial founding member of the CRB, we are pleased to know that the Board has achieved one of its major objectives in certifying Firefox OS devices on a standard set of Web APIs and performance metrics,” said Jason Bremner, Senior Vice President of Product Management, Qualcomm Technologies, Inc. “We expect other companies will also certify, improving their product development cycle time while ensuring a compelling user experience and compliance to standard Web APIs.”

“As one of the partners of the CRB and owners of these certified devices, ALCATEL ONETOUCH is excited to witness the solid progress and achievements made by all members,” said Alain Lejeune, Senior Vice President, ALCATEL ONETOUCH. “In the coming year, ALCATEL ONETOUCH will continue to contribute to the CRB and establishment of the Firefox OS ecosystem. This news is not only an honor for us but will inspire more Firefox OS partners to strive for certification.”

“In the last three years Mozilla has proven with Firefox OS that open Web technology is a strong, viable platform for mobile,” said Andreas Gal, Chief Technology Officer, Mozilla. “Certification by the CRB provides a launch pad for those who complete to prove that their device offers a consistent and excellent experience for users, reducing time and cost to qualify across operators and markets. Today’s announcement paves the way for other device makers to reach this milestone.”

“TELEFÓNICA supports the opportunities that an open Web ecosystem delivers to mobile consumers,” said Francisco Montalvo, Head of Group Devices Unit at TELEFÓNICA S.A.. “Having CRB as a product certification scheme helps all the partners guarantee that rich Web content is delivered to certified devices with the right level of quality. We are glad to collaborate on this effort.”

“Deutsche Telekom is pleased to be a close partner with Mozilla, Qualcomm, Telefonica, and ALCATEL ONETOUCH among others in the development of the Firefox OS,” said Louis Schreier, Vice President of Telekom Innovation Laboratories’ Silicon Valley Innovation Center. “As one of the founding members of the CRB, our goal in focusing on API compliance and performance is to establish a uniform set of requirements, test and acceptance criteria, enabling uniform and independent testing by accredited labs.”

For more information about the Open Web Device Compliance Review Board, please visit https://openwebdevice.org.

About the CRB
The Open Web Device Compliance Review Board (CRB) is an independently operated organization designed to promote the success of the open Web device ecosystem. It is a partnership between operators, device OEMs, silicon vendors and test solution providers to define and evolve a process to encourage API compatibility and competitive performance for devices. Standards are based on Mozilla’s principles of user privacy and control.

Media Contact: press@mozilla.com

The Mozilla BlogOpen Web Device Compliance Review Board Certifies First Handsets

Announcement Marks Key Point in Development of Open Source Mobile Ecosystem

San Francisco, Calif. – May 18, 2015: – The Open Web Device Compliance Review Board (CRB), in conjunction with its members ALCATEL ONE TOUCH, Deutsche Telekom, Mozilla, Qualcomm Technologies, Inc., and Telefónica, has announced the first handsets to be certified by the CRB. The CRB is an independently operated organization designed to promote the success of the open Web device ecosystem by encouraging API compliance as well as ensuring competitive performance.

The two devices are the Alcatel ONETOUCH Fire C and the Alcatel ONETOUCH Fire E. ALCATEL ONETOUCH has also authorized a CRB lab.

The certification process involves OEMs applying to the CRB for their device to be certified. CRB’s authorized labs test the device for open web APIs and key performance benchmarks. CRB’s subject matter experts review the results and validate against CRB stipulated benchmarks with a reference device to ensure compatibility and performance across key use cases. The two ALCATEL ONETOUCH devices passed the CRB authorized test lab procedure and met all CRB certification requirements.

The process is open to all device vendors whether they are a member of CRB or not. The CRB website will publish the process for applying for certification for their devices.

CRB certification testing will be conducted by industry labs authorized by the CRB, with each submission expected to be completed within approximately three days. The CRB offers a platform for the rest of the industry to request certification.

“As an initial founding member of the CRB, we are pleased to know that the Board has achieved one of its major objectives in certifying Firefox OS devices on a standard set of Web APIs and performance metrics,” said Jason Bremner, Senior Vice President of Product Management, Qualcomm Technologies, Inc. “We expect other companies will also certify, improving their product development cycle time while ensuring a compelling user experience and compliance to standard Web APIs.”

“As one of the partners of the CRB and owners of these certified devices, ALCATEL ONETOUCH is excited to witness the solid progress and achievements made by all members,” said Alain Lejeune, Senior Vice President, ALCATEL ONETOUCH. “In the coming year, ALCATEL ONETOUCH will continue to contribute to the CRB and establishment of the Firefox OS ecosystem. This news is not only an honor for us but will inspire more Firefox OS partners to strive for certification.”

“In the last three years Mozilla has proven with Firefox OS that open Web technology is a strong, viable platform for mobile,” said Andreas Gal, Chief Technology Officer, Mozilla. “Certification by the CRB provides a launch pad for those who complete to prove that their device offers a consistent and excellent experience for users, reducing time and cost to qualify across operators and markets. Today’s announcement paves the way for other device makers to reach this milestone.”

“TELEFÓNICA supports the opportunities that an open Web ecosystem delivers to mobile consumers,” said Francisco Montalvo, Head of Group Devices Unit at TELEFÓNICA S.A.. “Having CRB as a product certification scheme helps all the partners guarantee that rich Web content is delivered to certified devices with the right level of quality. We are glad to collaborate on this effort.”

“Deutsche Telekom is pleased to be a close partner with Mozilla, Qualcomm, Telefonica, and ALCATEL ONETOUCH among others in the development of the Firefox OS,” said Louis Schreier, Vice President of Telekom Innovation Laboratories’ Silicon Valley Innovation Center. “As one of the founding members of the CRB, our goal in focusing on API compliance and performance is to establish a uniform set of requirements, test and acceptance criteria, enabling uniform and independent testing by accredited labs.”

For more information about the Open Web Device Compliance Review Board, please visit https://openwebdevice.org.

About the Open Web Device Compliance Review Board
The Open Web Device Compliance Review Board (CRB) is an independently operated organization designed to promote the success of the open Web device ecosystem. It is a partnership between operators, device OEMs, silicon vendors and test solution providers to define and evolve a process to encourage API compatibility and competitive performance for devices. Standards are based on Mozilla’s principles of user privacy and control.

Media Contact:
press@mozilla.com

Joel MaherA-Team contribution opportunity – Dashboard Hacker

I am excited to announce a new focused project for contribution – Dashboard Hacker.  Last week we gave a preview that today we would be announcing 2 contribution projects.  This is an unpaid program where we are looking for 1-2 contributors who will dedicate between 5-10 hours/week for at least 8 weeks.  More time is welcome, but not required.

What is a dashboard hacker?

When a developer is ready to land code, they want to test it. Getting the results and understanding the results is made a lot easier by good dashboards and tools. For this project, we have a starting point with our performance data view to fix up a series of nice to have polish features and then ensure that it is easy to use with a normal developer workflow. Part of the developer work flow is the regular job view, If time permits there are some fun experiments we would like to implement in the job view.  These bugs, features, projects are all smaller and self contained which make great projects for someone looking to contribute.

What is required of you to participate?

  • A willingness to learn and ask questions
  • A general knowledge of programming (most of this will be in javascript, django, angularJS, and some work will be in python.
  • A promise to show up regularly and take ownership of the issues you are working on
  • Good at solving problems and thinking out of the box
  • Comfortable with (or willing to try) working with a variety of people

What we will guarantee from our end:

  • A dedicated mentor for the project whom you will work with regularly throughout the project
  • A single area of work to reduce the need to get up to speed over and over again.
    • This project will cover many tools, but the general problem space will be the same
  • The opportunity to work with many people (different bugs could have a specific mentor) while retaining a single mentor to guide you through the process
  • The ability to be part of the team- you will be welcome in meetings, we will value your input on solving problems, brainstorming, and figuring out new problems to tackle.

How do you apply?

Get in touch with us either by replying to the post, commenting in the bug or just contacting us on IRC (I am :jmaher in #ateam on irc.mozilla.org, wlach on IRC will be the primary mentor).  We will point you at a starter bug and introduce you to the bugs and problems to solve.  If you have prior work (links to bugzilla, github, blogs, etc.) that would be useful to learn more about you that would be a plus.

How will you select the candidates?

There is no real criteria here.  One factor will be if you can meet the criteria outlined above and how well you do at picking up the problem space.  Ultimately it will be up to the mentor (for this project, it will be :wlach).  If you do apply and we already have a candidate picked or don’t choose you for other reasons, we do plan to repeat this every few months.

Looking forward to building great things!


Joel MaherA-Team contribution opportunity – DX (Developer Ergonomics)

I am excited to announce a new focused project for contribution – Developer Ergonomics/Experience, otherwise known as DX.  Last week we gave a preview that today we would be announcing 2 contribution projects.  This is an unpaid program where we are looking for 1-2 contributors who will dedicate between 5-10 hours/week for at least 8 weeks.  More time is welcome, but not required.

What does DX mean?

We chose this project as we continue to experience frustration while fixing bugs and debugging test failures.  Many people suggest great ideas, in this case we have set aside a few ideas (look at the dependent bugs to clean up argument parsers, help our tests run in smarter chunks, make it easier to run tests locally or on server, etc.) which would clean up stuff and be harder than a good first bug, yet each issue by itself would be too easy for an internship.  Our goal is to clean up our test harnesses and tools and if time permits, add stuff to the workflow which makes it easier for developers to do their job!

What is required of you to participate?

  • A willingness to learn and ask questions
  • A general knowledge of programming (this will be mostly in python with some javascript as well)
  • A promise to show up regularly and take ownership of the issues you are working on
  • Good at solving problems and thinking out of the box
  • Comfortable with (or willing to try) working with a variety of people

What we will guarantee from our end:

  • A dedicated mentor for the project whom you will work with regularly throughout the project
  • A single area of work to reduce the need to get up to speed over and over again.
    • This project will cover many tools, but the general problem space will be the same
  • The opportunity to work with many people (different bugs could have a specific mentor) while retaining a single mentor to guide you through the process
  • The ability to be part of the team- you will be welcome in meetings, we will value your input on solving problems, brainstorming, and figuring out new problems to tackle.

How do you apply?

Get in touch with us either by replying to the post, commenting in the bug or just contacting us on IRC (I am :jmaher in #ateam on irc.mozilla.org).  We will point you at a starter bug and introduce you to the bugs and problems to solve.  If you have prior work (links to bugzilla, github, blogs, etc.) that would be useful to learn more about you that would be a plus.

How will you select the candidates?

There is no real criteria here.  One factor will be if you can meet the criteria outlined above and how well you do at picking up the problem space.  Ultimately it will be up to the mentor (for this project, it will be me).  If you do apply and we already have a candidate picked or don’t choose you for other reasons, we do plan to repeat this every few months.

Looking forward to building great things!


Daniel PocockFree and open WebRTC for the Fedora Community

In January 2014, we launched the rtc.debian.org service for the Debian community. An equivalent service has been in testing for the Fedora community at FedRTC.org.

Some key points about the Fedora service:

  • The web front-end is just HTML, CSS and JavaScript. PHP is only used for account creation, the actual WebRTC experience requires no server-side web framework, just a SIP proxy.
  • The web code is all available in a Github repository so people can extend it.
  • Anybody who can authenticate against the FedOAuth OpenID is able to get a fedrtc.org test account immediately.
  • The server is built entirely with packages from CentOS 7 + EPEL 7, except for the SIP proxy itself. The SIP proxy is reSIProcate, which is available as a Fedora package and builds easily on RHEL / CentOS.

Testing it with WebRTC

Create an RTC password and then log in. Other users can call you. It is federated, so people can also call from rtc.debian.org or from freephonebox.net.

Testing it with other SIP softphones

You can use the RTC password to connect to the SIP proxy from many softphones, including Jitsi or Lumicall on Android.

Copy it

The process to replicate the server for another domain is entirely described in the Real-Time Communications Quick Start Guide.

Discuss it

The FreeRTC mailing list is a great place to discuss any issues involving this site or free RTC in general.

WebRTC opportunities expanding

Just this week, the first batch of Firefox OS televisions are hitting the market. Every one of these is a potential WebRTC client that can interact with free communications platforms.

Mozilla Reps CommunityNew council members – Spring 2015

We are happy to announce that three new members of the Council have been elected.

Welcome Michael, Shahid and Christos! They bring with them skills they have picked up as Reps mentors, and as community leaders both inside Mozilla and in other fields. A HUGE thank you to the outgoing council members – Arturo, Emma and Raj. We are hoping you continue to use your talents and experience to continue in a leadership role in Reps and Mozilla.

The new members will be gradually on boarding during the following 3 weeks.

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

Congratulate new Council members on this Discourse topic!

Air MozillaFirefox OS Tricoder

Firefox OS Tricoder Reading device sensor data in JavaScript

Tim TaubertImplementing a PBKDF2-based Password Storage Scheme for Firefox OS

My esteemed colleague Frederik Braun recently took on to rewrite the module responsible for storing and checking passcodes that unlock Firefox OS phones. While we are still working on actually landing it in Gaia I wanted to seize the chance to talk about this great use case of the WebCrypto API in the wild and highlight a few important points when using password-based key derivation (PBKDF2) to store passwords.

The Passcode Module

Let us take a closer look at not the verbatim implementation but at a slightly simplified version. The API offers the only two operations such a module needs to support: setting a new passcode and verifying that a given passcode matches the stored one.

let Passcode = {
  store(code) {
    // ...
  },

  verify(code) {
    // ...
  }
};

When setting up the phone for the first time - or when changing the passcode later - we call Passcode.store() to write a new code to disk. Passcode.verify() will help us determine whether we should unlock the phone. Both methods return a Promise as all operations exposed by the WebCrypto API are asynchronous.

Passcode.store("1234").then(() => {
  return Passcode.verify("1234");
}).then(valid => {
  console.log(valid);
});

// Output: true

Make the passcode look “random”

The module should absolutely not store passcodes in the clear. We will use PBKDF2 as a pseudorandom function (PRF) to retrieve a result that looks random. An attacker with read access to the part of the disk storing the user’s passcode should not be able to recover the original input, assuming limited computational resources.

The function deriveBits() is a PRF that takes a passcode and returns a Promise resolving to a random looking sequence of bytes. To be a little more specific, it uses PBKDF2 to derive pseudorandom bits.

function deriveBits(code) {
  // Convert string to a TypedArray.
  let bytes = new TextEncoder("utf-8").encode(code);

  // Create the base key to derive from.
  let importedKey = crypto.subtle.importKey(
    "raw", bytes, "PBKDF2", false, ["deriveBits"]);

  return importedKey.then(key => {
    // Salt should be at least 64 bits.
    let salt = crypto.getRandomValues(new Uint8Array(8));

    // All required PBKDF2 parameters.
    let params = {name: "PBKDF2", hash: "SHA-1", salt, iterations: 5000};

    // Derive 160 bits using PBKDF2.
    return crypto.subtle.deriveBits(params, key, 160);
  });
}

Choosing PBKDF2 parameters

As you can see above PBKDF2 takes a whole bunch of parameters. Choosing good values is crucial for the security of our passcode module so it is best to take a detailed look at every single one of them.

Select a cryptographic hash function

PBKDF2 is a big PRF that iterates a small PRF. The small PRF, iterated multiple times (more on why this is done later), is fixed to be an HMAC construction; you are however allowed to specify the cryptographic hash function used inside HMAC itself. To understand why you need to select a hash function it helps to take a look at HMAC’s definition, here with SHA-1 at its core:

HMAC-SHA-1(k, m) = SHA-1((k ⊕ opad) + SHA-1((k ⊕ ipad) + m))

The outer and inner padding opad and ipad are static values that can be ignored for our purpose, the important takeaway is that the given hash function will be called twice, combining the message m and the key k. Whereas HMAC is usually used for authentication PBKDF2 makes use of its PRF properties, that means its output is computationally indistinguishable from random.

deriveBits() as defined above uses SHA-1 as well, and although it is considered broken as a collision-resistant hash function it is still a safe building block in the HMAC-SHA-1 construction. HMAC only relies on a hash function’s PRF properties, and while finding SHA-1 collisions is considered feasible it is still believed to be a secure PRF.

That said, it would not hurt to switch to a secure cryptographic hash function like SHA-256. Chrome supports other hash functions for PBKDF2 today, Firefox unfortunately has to wait for an NSS fix before those can be unlocked for the WebCrypto API.

Pass a random salt

The salt is a random component that PBKDF2 feeds into the HMAC function along with the passcode. This prevents an attacker from simply computing the hashes of for example all 8-character combinations of alphanumerics (~5.4 PetaByte of storage for SHA-1) and use a huge lookup table to quickly reverse a given password hash. Specify 8 random bytes as the salt and the poor attacker will have to suddenly compute (and store!) 264 of those lookup tables and face 8 additional random characters in the input. Even without the salt the effort to create even one lookup table would be hard to justify because chances are high you cannot reuse it to attack another target, they might be using a different hash function or combine two or more of them.

The same goes for Rainbow Tables. A random salt included with the password would have to be incorporated when precomputing the hash chains and the attacker is back to square one where she has to compute a Rainbow Table for every possible salt value. That certainly works ad-hoc for a single salt value but preparing and storing 264 of those tables is impossible.

The salt is public and will be stored in the clear along with the derived bits. We need the exact same salt to arrive at the exact same derived bits later again. We thus have to modify deriveBits() to accept the salt as an argument so that we can either generate a random one or read it from disk.

function deriveBits(code, salt) {
  // Convert string to a TypedArray.
  let bytes = new TextEncoder("utf-8").encode(code);

  // Create the base key to derive from.
  let importedKey = crypto.subtle.importKey(
    "raw", bytes, "PBKDF2", false, ["deriveBits"]);

  return importedKey.then(key => {
    // All required PBKDF2 parameters.
    let params = {name: "PBKDF2", hash: "SHA-1", salt, iterations: 5000};

    // Derive 160 bits using PBKDF2.
    return crypto.subtle.deriveBits(params, key, 160);
  });
}

Keep in mind though that Rainbow tables today are mainly a thing from the past where password hashes were smaller and shittier. Salts are the bare minimum a good password storage scheme needs, but they merely protect against a threat that is largely irrelevant today.

Specify a number of iterations

As computers became faster and Rainbow Table attacks infeasible due to the prevalent use of salts everywhere, people started attacking password hashes with dictionaries, simply by taking the public salt value and passing that combined with their educated guess to the hash function until a match was found. Modern password schemes thus employ a “work factor” to make hashing millions of password guesses unbearably slow.

By specifying a sufficiently high number of iterations we can slow down PBKDF2’s inner computation so that an attacker will have to face a massive performance decrease and be able to only try a few thousand passwords per second instead of millions.

For a single-user disk or file encryption it might be acceptable if computing the password hash takes a few seconds; for a lock screen 300-500ms might be the upper limit to not interfere with user experience. Take a look at this great StackExchange post for more advice on what might be the right number of iterations for your application and environment.

A much more secure version of a lock screen would allow to not only use four digits but any number of characters. An additional delay of a few seconds after a small number of wrong guesses might increase security even more, assuming the attacker cannot access the PRF output stored on disk.

Determine the number of bits to derive

PBKDF2 can output an almost arbitrary amount of pseudo-random data. A single execution yields the number of bits that is equal to the chosen hash function’s output size. If the desired number of bits exceeds the hash function’s output size PBKDF2 will be repeatedly executed until enough bits have been derived.

function getHashOutputLength(hash) {
  switch (hash) {
    case "SHA-1":   return 160;
    case "SHA-256": return 256;
    case "SHA-384": return 384;
    case "SHA-512": return 512;
  }

  throw new Error("Unsupported hash function");
}

Choose 160 bits for SHA-1, 256 bits for SHA-256, and so on. Slowing down the key derivation even further by requiring more than one round of PBKDF2 will not increase the security of the password storage.

Do not hard-code parameters

Hard-coding PBKDF2 parameters - the name of the hash function to use in the HMAC construction, and the number of HMAC iterations - is tempting at first. We however need to be flexible if for example it turns out that SHA-1 can no longer be considered a secure PRF, or you need to increase the number of iterations to keep up with faster hardware.

To ensure future code can verify old passwords we store the parameters that were passed to PBKDF2 at the time, including the salt. When verifying the passcode we will read the hash function name, the number of iterations, and the salt from disk and pass those to deriveBits() along with the passcode itself. The number of bits to derive will be the hash function’s output size.

function deriveBits(code, salt, hash, iterations) {
  // Convert string to a TypedArray.
  let bytes = new TextEncoder("utf-8").encode(code);

  // Create the base key to derive from.
  let importedKey = crypto.subtle.importKey(
    "raw", bytes, "PBKDF2", false, ["deriveBits"]);

  return importedKey.then(key => {
    // Output length in bits for the given hash function.
    let hlen = getHashOutputLength(hash);

    // All required PBKDF2 parameters.
    let params = {name: "PBKDF2", hash, salt, iterations};

    // Derive |hlen| bits using PBKDF2.
    return crypto.subtle.deriveBits(params, key, hlen);
  });
}

Storing a new passcode

Now that we are done implementing deriveBits(), the heart of the Passcode module, completing the API is basically a walk in the park. For the sake of simplicity we will use localforage as the storage backend. It provides a simple, asynchronous, and Promise-based key-value store.

// <script src="localforage.min.js"/>

const HASH = "SHA-1";
const ITERATIONS = 4096;

Passcode.store = function (code) {
  // Generate a new random salt for every new passcode.
  let salt = crypto.getRandomValues(new Uint8Array(8));

  return deriveBits(code, salt, HASH, ITERATIONS).then(bits => {
    return Promise.all([
      localforage.setItem("digest", bits),
      localforage.setItem("salt", salt),
      localforage.setItem("hash", HASH),
      localforage.setItem("iterations", ITERATIONS)
    ]);
  });
};

We generate a new random salt for every new passcode. The derived bits are stored along with the salt, the hash function name, and the number of iterations. HASH and ITERATIONS are constants that provide default values for our PBKDF2 parameters and can be updated whenever desired. The Promise returned by Passcode.store() will resolve when all values have been successfully stored in the backend.

Verifying a given passcode

To verify a passcode all values and parameters stored by Passcode.store() will have to be read from disk and passed to deriveBits(). Comparing the derived bits with the value stored on disk tells whether the passcode is valid.

Passcode.verify = function (code) {
  let loadValues = Promise.all([
    localforage.getItem("digest"),
    localforage.getItem("salt"),
    localforage.getItem("hash"),
    localforage.getItem("iterations")
  ]);

  return loadValues.then(([digest, salt, hash, iterations]) => {
    return deriveBits(code, salt, hash, iterations).then(bits => {
      return compare(bits, digest);
    });
  });
};

Should compare() be a constant-time operation?

compare() does not have to be constant-time. Even if the attacker learns the first byte of the final digest stored on disk she cannot easily produce inputs to guess the second byte - the opposite would imply knowing the pre-images of all those two-byte values. She cannot do better than submitting simple guesses that become harder the more bytes are known. For a successful attack all bytes have to be recovered, which in turns means a valid pre-image for the full final digest needs to be found.

If it makes you feel any better, you can of course implement compare() as a constant-time operation. This might be tricky though given that all modern JavaScript engines optimize code heavily.

What about bcrypt or scrypt?

Both bcrypt and scrypt are probably better alternatives to PBKDF2. Bcrypt automatically embeds the salt and cost factor into its output, most APIs are clever enough to parse and use those parameters when verifying a given password.

Scrypt implementations can usually securely generate a random salt, that is one less thing for you to care about. The most important aspect of scrypt though is that it allows consuming a lot of memory when computing the password hash which makes cracking passwords using ASICs or FPGAs close to impossible.

The Web Cryptography API does unfortunately support neither of the two algorithms and currently there are no proposals to add those. In the case of scrypt it might also be somewhat controversial to allow a website to consume arbitrary amounts of memory.

Gregory SzorcFirefox Mercurial Repository with CVS History

When Firefox made the switch from CVS to Mercurial in March 2007, the CVS history wasn't imported into Mercurial. There were good reasons for this at the time. But it's a decision that continues to have side-effects. I am surprised how often I hear of engineers wanting to access blame and commit info from commits now more than 9 years old!

When individuals created a Git mirror of the Firefox repository a few years ago, they correctly decided that importing CVS history would be a good idea. They also correctly decided to combine the logically same but physically separate release and integration repositories into a unified Git repository. These are things we can't easily do to the canonical Mercurial repository because it would break SHA-1 hashes, breaking many systems, and it would require significant changes in process, among other reasons.

While Firefox developers do have access to a single Firefox repository with full CVS history (the Git mirror), they still aren't satisfied.

Running git blame (or hg blame for that matter) can be very expensive. For this reason, the blame interface is disabled on many web-based source viewers by default. On GitHub, some blame URLs for the Firefox repository time out and cause GitHub to display an error message. No matter how hard you try, you can't easily get blame results (running a local Git HTTP/HTML interface is still difficult compared to hg serve).

Another reason developers aren't satisfied with the Git mirror is that Git's querying tools pale in comparison to Mercurial's. I've said it before and I'll say it again: Mercurial's revision sets and templates are incredibly useful features that enable advanced repository querying and reporting. Git's offerings come nowhere close. (I really wish Git would steal these awesome features from Mercurial.)

Anyway, enough people were complaining about the lack of a Mercurial Firefox repository with full CVS history that I decided to create one. If you point your browsers or Mercurial clients to https://hg.mozilla.org/users/gszorc_mozilla.com/gecko-full, you'll be able to access it.

The process used for the conversion was the simplest possible: I used hg-git to convert the Git mirror back to Mercurial.

Unlike the Git mirror, I didn't include all heads in this new repository. Instead, there is only mozilla-central's head (the current development tip). If I were doing this properly, I'd include all heads, like gecko-aggregate.

I'm well aware there are oddities in the Git mirror and they now exist in this new repository as well. My goal for this conversion was to deliver something: it wasn't a goal to deliver the most correct result possible.

At this time, this repository should be considered an unstable science experiment. By no means should you rely on this repository. But if you find it useful, I'd appreciate hearing about it. If enough people ask, we could probably make this more official.

Gervase MarkhamEurovision Bingo

Some people say that all Eurovision songs are the same. That’s probably not quite true, but there is perhaps a hint of truth in the suggestion that some themes tend to recur from year to year. Hence, I thought, Eurovision Bingo.

I wrote some code to analyse a directory full of lyrics, normally those from the previous year of the competition, and work out the frequency of occurrence of each word. It will then generate Bingo cards, with sets of words of different levels of commonness. You can then use them to play Bingo while watching this year’s competition (which is on Saturday).

There’s a Github repo, or if you want to go straight to pre-generated cards for this year, they are here.

Here’s a sample card from the 2014 lyrics:

fell cause rising gonna rain
world believe dancing hold once
every mean LOVE something chance
hey show or passed say
because light hard home heart

Have fun :-)

Air MozillaOuiShare Labs Camp #3

OuiShare Labs Camp #3 OuiShare Labs Camp #3 is a participative conference dedicated to decentralization, IndieWeb, semantic web and open source community tools.

This Week In RustThis Week in Rust 81

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? Send me an email! Want to get involved? We love contributions.

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

What's cooking on master?

273 pull requests were merged in the last two weeks, and 4 RFC PRs.

Now you can follow breaking changes as they happen!

Breaking Changes

Other Changes

New Contributors

  • らいどっと
  • Aaron Gallagher
  • Alexander Polakov
  • Alex Burka
  • Andrei Oprea
  • Andrew Kensler
  • Andrew Straw
  • Ben Gesoff
  • Chris Hellmuth
  • Cole Reynolds
  • Colin Walters
  • David Reid
  • Don Petersen
  • Emilio Cobos Álvarez
  • Franziska Hinkelmann
  • Garming Sam
  • Hika Hibariya
  • Isaac Ge
  • Jan Andersson
  • Jan-Erik Rediger
  • Jannis Redmann
  • Jason Yeo
  • Jeremy Schlatter
  • Johann
  • Johann Hofmann
  • Lee Jeffery
  • leunggamciu
  • Marin Atanasov Nikolov
  • Mário Feroldi
  • Mathieu Rochette
  • Michael Park
  • Michael Wu
  • Michał Czardybon
  • Mike Sampson
  • Nick Platt
  • parir
  • Paul Banks
  • Paul Faria
  • Paul Quint
  • peferron
  • Pete Hunt
  • robertfoss
  • Rob Young
  • Russell Johnston
  • Shmuale Mark
  • Simon Kern
  • Sindre Johansen
  • sumito3478
  • Swaroop C H
  • Tincan
  • Wei-Ming Yang
  • Wilfred Hughes
  • Will Engler
  • Wojciech Ogrodowczyk
  • XuefengWu
  • Z1

Approved RFCs

New RFCs

Betawatch!

The current beta is 1.1.0-beta (cd7d89af9 2015-05-16) (built 2015-05-16).

Notable Links

Project Updates

Upcoming Events

If you are running a Rust event please add it to the calendar to get it mentioned here. Email Erick Tryzelaar or Brian Anderson for access.

Quote of the Week

"Yes, because laundry eating has evolved to be a specific design goal now; and the initial portions of the planned laundry eating API have been landed behind the #![feature(no_laundry)] gate. no_laundry should become stable in 6-8 weeks, though the more complicated portions, including DRY cleaning, Higher Kinded T-shirts, Opt-in Builtin Detergent, and Rinse Time Optimization will not be stabilized until much later."

"We hope this benefits the Laundry as a Service community immensely."

Manish explains Rust's roadmap for laundry-eating.

Thanks to filsmick for the tip.

And since there were so many quotables in the last two weeks, here's one from Evan Miller's evaluation of Rust:

"Rust is a systems language. I’m not sure what that term means, but it seems to imply some combination of native code compilation, not being Fortran, and making no mention of category theory in the documentation."

Thanks to ruudva for the tip. Submit your quotes for next week!.

Mark CôtéIntegration

The other day I read about another new Mozilla project that decided to go with GitHub issues instead of our Bugzilla installation (BMO). The author’s arguments make a lot of sense: GitHub issues are much simpler and faster, and if you keep your code in GitHub, you get tighter integration. The author notes that a downside is the inability to file security or confidential bugs, for which Bugzilla has a fine-grained permission system, and that he’d just put those (rare) issues on BMO.

The one downside he doesn’t mention is interdependencies with other Mozilla projects, e.g. the Depends On/Blocks fields. This is where Bugzilla gets into project, product, and perhaps even program management by allowing people to easily track dependency chains, which is invaluable in planning. Many people actually file bugs solely as trackers for a particular feature or project, hanging all the work items and bugs off of it, and sometimes that work crosses product boundaries. There are also a number of tracking flags and fields that managers use to prioritize work and decide which releases to target.

If I had to rebut my own point, I would argue that the projects that use GitHub issues are relatively isolated, and so dependency tracking is not particularly important. Why clutter up and slow down the UI with lots of features that I don’t need for my project? In particular, most of the tracking features are currently used only by, and thus designed for, the Firefox products (aside: this is one reason the new modal UI hides most of these fields by default if they have never been set).

This seems hard to refute, and I certainly wouldn’t want to force an admittedly complex tool on anyone who had much simpler needs. But something still wasn’t sitting right with me, and it took a while to figure out what it was. As usual, it was that a different question was going unasked, leading to unspoken assumptions: why do we have so many isolated projects, and what are we giving up by having such loose (or even no) integration amongst all our work?

Working on projects in isolation is comforting because you don’t have to think about all the other things going on in your organization—in other words, you don’t have to communicate with very many people. A lack of communication, however, leads to several problems:

  • low visibility: what is everyone working on?
  • redundancy: how many times are we solving the same problem?
  • barriers to coordination: how can we become greater than the sum of our parts by delivering inter-related features and products?

By working in isolation, we can’t leverage each other’s strengths and accomplishments. We waste effort and lose great opportunities to deliver amazing things. We know that places like Twitter use monorepos to get some of these benefits, like a single build/test/deploy toolchain and coordination of breaking changes. This is what facilitates architectures like microservices and SOAs. Even if we don’t want to go down those paths, there is still a clear benefit to program management by at least integrating the tracking and planning of all of our various endeavours and directions. We need better organization-wide coordination.

We’re already taking some steps in this direction, like moving Firefox and Cloud Services to one division. But there are many other teams that could benefit from better integration, many teams that are duplicating effort and missing out on chances to work together. It’s a huge effort, but maybe we need to form a team to define a strategy and process—a Strategic Integration Team perhaps?

Mark CôtéProject Isolation

The other day I read about another new Mozilla project that decided to go with GitHub issues instead of our Bugzilla installation (BMO). The author’s arguments make a lot of sense: GitHub issues are much simpler and faster, and if you keep your code in GitHub, you get tighter integration. The author notes that a downside is the inability to file security or confidential bugs, for which Bugzilla has a fine-grained permission system, and that he’d just put those (rare) issues on BMO.

The one downside he doesn’t mention is interdependencies with other Mozilla projects, e.g. the Depends On/Blocks fields. This is where Bugzilla gets into project, product, and perhaps even program management by allowing people to easily track dependency chains, which is invaluable in planning. Many people actually file bugs solely as trackers for a particular feature or project, hanging all the work items and bugs off of it, and sometimes that work crosses product boundaries. There are also a number of tracking flags and fields that managers use to prioritize work and decide which releases to target.

If I had to rebut my own point, I would argue that the projects that use GitHub issues are relatively isolated, and so dependency tracking is not particularly important. Why clutter up and slow down the UI with lots of features that I don’t need for my project? In particular, most of the tracking features are currently used only by, and thus designed for, the Firefox products (aside: this is one reason the new modal UI hides most of these fields by default if they have never been set).

This seems hard to refute, and I certainly wouldn’t want to force an admittedly complex tool on anyone who had much simpler needs. But something still wasn’t sitting right with me, and it took a while to figure out what it was. As usual, it was that a different question was going unasked, leading to unspoken assumptions: why do we have so many isolated projects, and what are we giving up by having such loose (or even no) integration amongst all our work?

Working on projects in isolation is comforting because you don’t have to think about all the other things going on in your organization—in other words, you don’t have to communicate with very many people. A lack of communication, however, leads to several problems:

  • low visibility: what is everyone working on?
  • redundancy: how many times are we solving the same problem?
  • barriers to coordination: how can we become greater than the sum of our parts by delivering inter-related features and products?

By working in isolation, we can’t leverage each other’s strengths and accomplishments. We waste effort and lose great opportunities to deliver amazing things. We know that places like Twitter use monorepos to get some of these benefits, like a single build/test/deploy toolchain and coordination of breaking changes. This is what facilitates architectures like microservices and SOAs. Even if we don’t want to go down those paths, there is still a clear benefit to program management by at least integrating the tracking and planning of all of our various endeavours and directions. We need better organization-wide coordination.

We’re already taking some steps in this direction, like moving Firefox and Cloud Services to one division. But there are many other teams that could benefit from better integration, many teams that are duplicating effort and missing out on chances to work together. It’s a huge effort, but maybe we need to form a team to define a strategy and process—a Strategic Integration Team perhaps?

Mike ConleyThe Joy of Coding (Ep. 14): More OS X Printing

In this episode, I kept working on the same bug as last week – proxying the print dialog from the content process on OS X. We actually finished the serialization bit, and started doing deserialization!

Hopefully, next episode we can polish off the deserialization and we’l be done. Fingers crossed!

Note that this episode was about 2 hours and 10 minutes, but the standard-definition recording up on Air Mozilla only plays for about 13 minutes and 5 seconds. Not too sure what’s going on there – we’ve filed a bug with the people who’ve encoded it. Hopefully, we’ll have the full episode up for standard-definition soon.

In the meantime, if you’d like to watch the whole episode, you can go to the Air Mozilla page and watch it in HD, or you can go to the YouTube mirror.

Episode Agenda

References

Bug 1091112 – Print dialog doesn’t get focus automatically, if e10s is enabled – Notes