Merge m-c to mozilla-inbound
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Fri, 10 Oct 2014 15:09:16 +0200
changeset 209853 28be76cd55cf317e313bc5366ef6a6b3118213d3
parent 209852 f4fa7b1b3f3fc71096c6e5c262e90f83651b9790 (current diff)
parent 209753 097821fd89ed755f444f07ab501009855d996b2d (diff)
child 209854 311c125897e53e66c7c74fb9a935b88562771008
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
milestone35.0a1
Merge m-c to mozilla-inbound
--- a/b2g/chrome/content/devtools/hud.js
+++ b/b2g/chrome/content/devtools/hud.js
@@ -51,18 +51,19 @@ let developerHUD = {
    * observed metrics with `target.register(metric)`, and keep them up-to-date
    * with `target.update(metric, message)` when necessary.
    */
   registerWatcher: function dwp_registerWatcher(watcher) {
     this._watchers.unshift(watcher);
   },
 
   init: function dwp_init() {
-    if (this._client)
+    if (this._client) {
       return;
+    }
 
     if (!DebuggerServer.initialized) {
       RemoteDebugger.initServer();
     }
 
     // We instantiate a local debugger connection so that watchers can use our
     // DebuggerClient to send requests to tab actors (e.g. the consoleActor).
     // Note the special usage of the private _serverConnection, which we need
@@ -86,36 +87,38 @@ let developerHUD = {
     }
 
     SettingsListener.observe('hud.logging', this._logging, enabled => {
       this._logging = enabled;
     });
   },
 
   uninit: function dwp_uninit() {
-    if (!this._client)
+    if (!this._client) {
       return;
+    }
 
     for (let frame of this._targets.keys()) {
       this.untrackFrame(frame);
     }
 
     AppFrames.removeObserver(this);
 
     this._client.close();
     delete this._client;
   },
 
   /**
    * This method will ask all registered watchers to track and update metrics
    * on an app frame.
    */
   trackFrame: function dwp_trackFrame(frame) {
-    if (this._targets.has(frame))
+    if (this._targets.has(frame)) {
       return;
+    }
 
     DebuggerServer.connectToChild(this._conn, frame).then(actor => {
       let target = new Target(frame, actor);
       this._targets.set(frame, target);
 
       for (let w of this._watchers) {
         w.trackTarget(target);
       }
@@ -334,56 +337,56 @@ let consoleWatcher = {
 
     switch (packet.type) {
 
       case 'pageError':
         let pageError = packet.pageError;
 
         if (pageError.warning || pageError.strict) {
           metric.name = 'warnings';
-          output += 'warning (';
+          output += 'Warning (';
         } else {
           metric.name = 'errors';
-          output += 'error (';
+          output += 'Error (';
         }
 
         if (this._security.indexOf(pageError.category) > -1) {
           metric.name = 'security';
         }
 
         let {errorMessage, sourceName, category, lineNumber, columnNumber} = pageError;
         output += category + '): "' + (errorMessage.initial || errorMessage) +
           '" in ' + sourceName + ':' + lineNumber + ':' + columnNumber;
         break;
 
       case 'consoleAPICall':
         switch (packet.message.level) {
 
           case 'error':
             metric.name = 'errors';
-            output += 'error (console)';
+            output += 'Error (console)';
             break;
 
           case 'warn':
             metric.name = 'warnings';
-            output += 'warning (console)';
+            output += 'Warning (console)';
             break;
 
           default:
             return;
         }
         break;
 
       case 'reflowActivity':
         metric.name = 'reflows';
 
         let {start, end, sourceURL, interruptible} = packet;
         metric.interruptible = interruptible;
         let duration = Math.round((end - start) * 100) / 100;
-        output += 'reflow: ' + duration + 'ms';
+        output += 'Reflow: ' + duration + 'ms';
         if (sourceURL) {
           output += ' ' + this.formatSourceURL(packet);
         }
         break;
 
       default:
         return;
     }
@@ -420,16 +423,17 @@ let eventLoopLagWatcher = {
 
     SettingsListener.observe('hud.jank', false, this.settingsListener.bind(this));
   },
 
   settingsListener: function(value) {
     if (this._active == value) {
       return;
     }
+
     this._active = value;
 
     // Toggle the state of existing fronts.
     let fronts = this._fronts;
     for (let target of fronts.keys()) {
       if (value) {
         fronts.get(target).start();
       } else {
@@ -441,17 +445,17 @@ let eventLoopLagWatcher = {
 
   trackTarget: function(target) {
     target.register('jank');
 
     let front = new EventLoopLagFront(this._client, target.actor);
     this._fronts.set(target, front);
 
     front.on('event-loop-lag', time => {
-      target.update({name: 'jank', value: time}, 'jank: ' + time + 'ms');
+      target.update({name: 'jank', value: time}, 'Jank: ' + time + 'ms');
     });
 
     if (this._active) {
       front.start();
     }
   },
 
   untrackTarget: function(target) {
@@ -495,17 +499,17 @@ let memoryWatcher = {
         watching[category] = watch;
         this.update();
       });
     }
   },
 
   update: function mw_update() {
     let watching = this._watching;
-    let active = watching.memory || watching.uss;
+    let active = watching.appmemory || watching.uss;
 
     if (this._active) {
       for (let target of this._fronts.keys()) {
         if (!watching.appmemory) target.clear({name: 'memory'});
         if (!watching.uss) target.clear({name: 'uss'});
         if (!active) clearTimeout(this._timers.get(target));
       }
     } else if (active) {
@@ -514,58 +518,69 @@ let memoryWatcher = {
       }
     }
     this._active = active;
   },
 
   measure: function mw_measure(target) {
     let watch = this._watching;
     let front = this._fronts.get(target);
+    let format = this.formatMemory;
 
     if (watch.uss) {
       front.residentUnique().then(value => {
-        target.update({name: 'uss', value: value});
+        target.update({name: 'uss', value: value}, 'USS: ' + format(value));
       }, err => {
         console.error(err);
       });
     }
 
     if (watch.appmemory) {
       front.measure().then(data => {
         let total = 0;
-        if (watch.jsobjects) {
-          total += parseInt(data.jsObjectsSize);
-        }
-        if (watch.jsstrings) {
-          total += parseInt(data.jsStringsSize);
-        }
-        if (watch.jsother) {
-          total += parseInt(data.jsOtherSize);
+        let details = [];
+
+        function item(name, condition, value) {
+          if (!condition) {
+            return;
+          }
+
+          let v = parseInt(value);
+          total += v;
+          details.push(name + ': ' + format(v));
         }
-        if (watch.dom) {
-          total += parseInt(data.domSize);
-        }
-        if (watch.style) {
-          total += parseInt(data.styleSize);
-        }
-        if (watch.other) {
-          total += parseInt(data.otherSize);
-        }
+
+        item('JS objects', watch.jsobjects, data.jsObjectsSize);
+        item('JS strings', watch.jsstrings, data.jsStringsSize);
+        item('JS other', watch.jsother, data.jsOtherSize);
+        item('DOM', watch.dom, data.domSize);
+        item('Style', watch.style, data.styleSize);
+        item('Other', watch.other, data.otherSize);
         // TODO Also count images size (bug #976007).
 
-        target.update({name: 'memory', value: total});
+        target.update({name: 'memory', value: total},
+          'App Memory: ' + format(total) + ' (' + details.join(', ') + ')');
       }, err => {
         console.error(err);
       });
     }
 
-    let timer = setTimeout(() => this.measure(target), 500);
+    let timer = setTimeout(() => this.measure(target), 800);
     this._timers.set(target, timer);
   },
 
+  formatMemory: function mw_formatMemory(bytes) {
+    var prefix = ['','K','M','G','T','P','E','Z','Y'];
+    var i = 0;
+    for (; bytes > 1024 && i < prefix.length; ++i) {
+      bytes /= 1024;
+    }
+    return (Math.round(bytes * 100) / 100) + ' ' + prefix[i] + 'B';
+  },
+
   trackTarget: function mw_trackTarget(target) {
     target.register('uss');
     target.register('memory');
     this._fronts.set(target, MemoryFront(this._client, target.actor));
     if (this._active) {
       this.measure(target);
     }
   },
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1036b544b7e102592bd9fab95cd9317329ac1293"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="cc5da7b055e2b06fdeb46fa94970550392ee571d"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ca2008ac50b163d31244ef9f036cb224f4f229b"/>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="84923f1940625c47ff4c1fdf01b10fde3b7d909e">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="1036b544b7e102592bd9fab95cd9317329ac1293"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="cc5da7b055e2b06fdeb46fa94970550392ee571d"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ca2008ac50b163d31244ef9f036cb224f4f229b"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8986df0f82e15ac2798df0b6c2ee3435400677ac">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1036b544b7e102592bd9fab95cd9317329ac1293"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="cc5da7b055e2b06fdeb46fa94970550392ee571d"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ca2008ac50b163d31244ef9f036cb224f4f229b"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1036b544b7e102592bd9fab95cd9317329ac1293"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="cc5da7b055e2b06fdeb46fa94970550392ee571d"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ca2008ac50b163d31244ef9f036cb224f4f229b"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="84923f1940625c47ff4c1fdf01b10fde3b7d909e">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="1036b544b7e102592bd9fab95cd9317329ac1293"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="cc5da7b055e2b06fdeb46fa94970550392ee571d"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ca2008ac50b163d31244ef9f036cb224f4f229b"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1036b544b7e102592bd9fab95cd9317329ac1293"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="cc5da7b055e2b06fdeb46fa94970550392ee571d"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ca2008ac50b163d31244ef9f036cb224f4f229b"/>
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8986df0f82e15ac2798df0b6c2ee3435400677ac">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1036b544b7e102592bd9fab95cd9317329ac1293"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="cc5da7b055e2b06fdeb46fa94970550392ee571d"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ca2008ac50b163d31244ef9f036cb224f4f229b"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="e95b4ce22c825da44d14299e1190ea39a5260bde"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="471afab478649078ad7c75ec6b252481a59e19b8"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
         "git_revision": "", 
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "ab9466a85acc108164bc17b9064387142b82d4da", 
+    "revision": "eeeae73691f91cd5042660b0f19c84747ebc7be2", 
     "repo_path": "/integration/gaia-central"
 }
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="84923f1940625c47ff4c1fdf01b10fde3b7d909e">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="1036b544b7e102592bd9fab95cd9317329ac1293"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="cc5da7b055e2b06fdeb46fa94970550392ee571d"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ca2008ac50b163d31244ef9f036cb224f4f229b"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="84923f1940625c47ff4c1fdf01b10fde3b7d909e">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="1036b544b7e102592bd9fab95cd9317329ac1293"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="cc5da7b055e2b06fdeb46fa94970550392ee571d"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="8986df0f82e15ac2798df0b6c2ee3435400677ac">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="1036b544b7e102592bd9fab95cd9317329ac1293"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="cc5da7b055e2b06fdeb46fa94970550392ee571d"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ca2008ac50b163d31244ef9f036cb224f4f229b"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="84923f1940625c47ff4c1fdf01b10fde3b7d909e">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="1036b544b7e102592bd9fab95cd9317329ac1293"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="cc5da7b055e2b06fdeb46fa94970550392ee571d"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="cc1f362ce43dce92ac786187ff4abf39060094bd"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ca2008ac50b163d31244ef9f036cb224f4f229b"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
--- a/browser/components/loop/content/panel.html
+++ b/browser/components/loop/content/panel.html
@@ -1,16 +1,15 @@
 <!DOCTYPE html>
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/.  -->
 <html>
   <head>
     <meta charset="utf-8">
-    <title>Loop Panel</title>
     <link rel="stylesheet" type="text/css" href="loop/shared/css/reset.css">
     <link rel="stylesheet" type="text/css" href="loop/shared/css/common.css">
     <link rel="stylesheet" type="text/css" href="loop/shared/css/panel.css">
     <link rel="stylesheet" type="text/css" href="loop/shared/css/contacts.css">
   </head>
   <body class="panel">
 
     <div id="main"></div>
--- a/browser/components/loop/content/shared/css/common.css
+++ b/browser/components/loop/content/shared/css/common.css
@@ -228,17 +228,16 @@ p {
   border-radius: 2px;
   border-bottom-right-radius: 0;
   border-top-right-radius: 0;
 }
 
 /* Alerts/Notifications */
 .notificationContainer {
   border-bottom: 2px solid #E9E9E9;
-  margin-bottom: 1em;
 }
 
 .messages > .notificationContainer > .alert {
   text-align: center;
 }
 
 .notificationContainer > .detailsBar,
 .alert {
--- a/browser/components/loop/content/shared/css/panel.css
+++ b/browser/components/loop/content/shared/css/panel.css
@@ -20,16 +20,22 @@ body {
 }
 
 .panel .messages .alert {
   margin: 0;
 }
 
 /* Tabs and tab selection buttons */
 
+.tab-view-container {
+  background-image: url("../img/beta-ribbon.svg#beta-ribbon");
+  background-size: 36px 36px;
+  background-repeat: no-repeat;
+}
+
 .tab-view {
   display: flex;
   flex-direction: row;
   padding: 10px;
   border-bottom: 1px solid #ccc;
   color: #000;
   border-top-right-radius: 2px;
   border-top-left-radius: 2px;
@@ -88,16 +94,22 @@ body {
 /* Content area and input fields */
 
 .content-area {
   padding: 14px;
 }
 
 .content-area header {
   font-weight: 700;
+  -moz-padding-start: 20px;
+}
+
+.tab-view + .tab .content-area header {
+  /* The header shouldn't be indented if the tabs are present. */
+  -moz-padding-start: 0;
 }
 
 .content-area label {
   display: block;
   width: 100%;
   margin-top: 10px;
   font-size: 10px;
   color: #777;
new file mode 100644
--- /dev/null
+++ b/browser/components/loop/content/shared/img/beta-ribbon.svg
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg"
+     viewBox="0 0 100 100"
+     xmlns:xlink="http://www.w3.org/1999/xlink"
+     enable-background="new 0 0 100 100">
+<style>
+</style>
+<defs>
+  <g id="beta-ribbon">
+    <path fill="#e6e6e6" d="M0,100 100,0 49.1,0 0,49.2z"/>
+    <path fill="#fff" d="M0,94.7 94.7,0 46.5,0 0,46.6z"/>
+    <g fill="#999">
+      <path d="m25.9,56.7l-4,4-13.7-13.7 3.7-3.7c2.4-2.4 5.7-4.1 8.3-1.4 1.7,1.7 1.4,3.9 .5,5.3l.1,.1c1.6-1.1 4-1.9 6.3,.3 3,3 1.3,6.5-1.2,9.1zm-12.2-12.2l-2.2,2.2 4.3,4.3 2.3-2.3c1.6-1.6 1.8-3.1 .2-4.7-1.4-1.6-2.9-1.2-4.6,.5zm6.1,5.4l-2.5,2.5 4.9,4.9 2.4-2.4c1.3-1.3 2.5-3.3 .6-5.3-2-2-3.9-1.2-5.4,.3z"/>
+      <path d="m30.7,42.7c2.5,2.2 4.6,2.1 6.2,.5 1-1 1.5-2 1.6-3.6l2,.4c-.2,1.7-.9,3.4-2.2,4.7-3.1,3.1-6.9,2.5-10.2-.7-3.2-3.2-3.8-7.1-1.1-9.9 2.7-2.7 6.2-2.3 9.4,.9 .4,.4 .7,.7 .9,1l-6.6,6.7zm-1.4-1.4l4.9-4.9c-2.2-2.1-4.1-2.5-5.7-.9-1.4,1.5-1.3,3.4 .8,5.8z"/>
+      <path d="m49.8,31.8c-.2,1.1-.8,2.2-1.6,3.1-1.9,1.9-4,1.6-5.9-.2l-6.3-6.3-1.6,1.6-1.4-1.4 1.7-1.7-2.4-2.4 1.6-2 2.6,2.6 2.6-2.6 1.2,1.6-2.4,2.4 6.3,6.3c1.1,1.1 1.9,1.2 2.8,.3 .5-.5 .7-1 .9-1.8l1.9,.5z"/>
+      <path d="m57,20.8c.8,.8 1.4,.9 2.1,.6l.8,1.7c-1.1,.8-2.1,1.1-3.4,.5 .3,1.7-.4,3.3-1.6,4.6-2.1,2.1-4.7,2.1-6.6,.2-2.2-2.2-1.6-5.1 1.5-8.3l1.4-1.3-.8-.8c-1.5-1.5-2.8-1.3-4.3,.2-.7,.7-1.5,1.8-2.2,3.3l-1.8-.9c.8-1.8 1.8-3.1 2.8-4.2 2.7-2.7 5.1-2.5 7.2-.4l4.9,4.8zm-2,1.6l-2.6-2.6-1.3,1.3c-2.2,2.2-2.2,3.8-.9,5.1 1.3,1.3 2.5,1.4 3.8,.1 1.1-1.1 1.3-2.4 1-3.9z"/>
+      <path d="M93.4,0 0,94.1 0,96 95.2,0z"/>
+      <path d="M45.3,0 0,46 0,47.9 47,0z"/>
+    </g>
+  </g>
+</defs>
+<use id="beta-ribbon" xlink:href="#beta-ribbon"/>
+</svg>
--- a/browser/components/loop/jar.mn
+++ b/browser/components/loop/jar.mn
@@ -43,16 +43,17 @@ browser.jar:
   content/browser/loop/shared/img/video-inverse-14x14@2x.png    (content/shared/img/video-inverse-14x14@2x.png)
   content/browser/loop/shared/img/dropdown-inverse.png          (content/shared/img/dropdown-inverse.png)
   content/browser/loop/shared/img/dropdown-inverse@2x.png       (content/shared/img/dropdown-inverse@2x.png)
   content/browser/loop/shared/img/svg/glyph-settings-16x16.svg  (content/shared/img/svg/glyph-settings-16x16.svg)
   content/browser/loop/shared/img/svg/glyph-account-16x16.svg   (content/shared/img/svg/glyph-account-16x16.svg)
   content/browser/loop/shared/img/svg/glyph-signin-16x16.svg    (content/shared/img/svg/glyph-signin-16x16.svg)
   content/browser/loop/shared/img/svg/glyph-signout-16x16.svg   (content/shared/img/svg/glyph-signout-16x16.svg)
   content/browser/loop/shared/img/audio-call-avatar.svg         (content/shared/img/audio-call-avatar.svg)
+  content/browser/loop/shared/img/beta-ribbon.svg               (content/shared/img/beta-ribbon.svg)
   content/browser/loop/shared/img/icons-10x10.svg               (content/shared/img/icons-10x10.svg)
   content/browser/loop/shared/img/icons-14x14.svg               (content/shared/img/icons-14x14.svg)
   content/browser/loop/shared/img/icons-16x16.svg               (content/shared/img/icons-16x16.svg)
 
   # Shared scripts
   content/browser/loop/shared/js/actions.js           (content/shared/js/actions.js)
   content/browser/loop/shared/js/conversationStore.js (content/shared/js/conversationStore.js)
   content/browser/loop/shared/js/roomListStore.js     (content/shared/js/roomListStore.js)
--- a/browser/components/loop/standalone/content/index.html
+++ b/browser/components/loop/standalone/content/index.html
@@ -1,16 +1,15 @@
 <!DOCTYPE html>
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/.  -->
 <html>
   <head>
     <meta charset="utf-8">
-    <title>Loop</title>
     <link rel="stylesheet" type="text/css" href="shared/css/reset.css">
     <link rel="stylesheet" type="text/css" href="shared/css/common.css">
     <link rel="stylesheet" type="text/css" href="shared/css/conversation.css">
     <link rel="stylesheet" type="text/css" href="css/webapp.css">
     <link rel="localization" href="l10n/loop.{locale}.properties">
 
     <meta name="locales" content="en-US" />
     <meta name="default_locale" content="en-US" />
--- a/browser/components/loop/standalone/content/js/webapp.js
+++ b/browser/components/loop/standalone/content/js/webapp.js
@@ -20,51 +20,51 @@ loop.webapp = (function($, _, OT, mozL10
   var sharedUtils = loop.shared.utils;
 
   /**
    * Homepage view.
    */
   var HomeView = React.createClass({displayName: 'HomeView',
     render: function() {
       return (
-        React.DOM.p(null, mozL10n.get("welcome"))
+        React.DOM.p(null, mozL10n.get("welcome", {clientShortname: mozL10n.get("clientShortname2")}))
       );
     }
   });
 
   /**
    * Unsupported Browsers view.
    */
   var UnsupportedBrowserView = React.createClass({displayName: 'UnsupportedBrowserView',
     render: function() {
       var useLatestFF = mozL10n.get("use_latest_firefox", {
         "firefoxBrandNameLink": React.renderComponentToStaticMarkup(
-          React.DOM.a({target: "_blank", href: "https://www.mozilla.org/firefox/"}, "Firefox")
+          React.DOM.a({target: "_blank", href: mozL10n.get("brand_website")}, mozL10n.get("brandShortname"))
         )
       });
       return (
         React.DOM.div(null, 
           React.DOM.h2(null, mozL10n.get("incompatible_browser")), 
-          React.DOM.p(null, mozL10n.get("powered_by_webrtc")), 
+          React.DOM.p(null, mozL10n.get("powered_by_webrtc", {clientShortname: mozL10n.get("clientShortname2")})), 
           React.DOM.p({dangerouslySetInnerHTML: {__html: useLatestFF}})
         )
       );
     }
   });
 
   /**
    * Unsupported Device view.
    */
   var UnsupportedDeviceView = React.createClass({displayName: 'UnsupportedDeviceView',
     render: function() {
       return (
         React.DOM.div(null, 
           React.DOM.h2(null, mozL10n.get("incompatible_device")), 
-          React.DOM.p(null, mozL10n.get("sorry_device_unsupported")), 
-          React.DOM.p(null, mozL10n.get("use_firefox_windows_mac_linux"))
+          React.DOM.p(null, mozL10n.get("sorry_device_unsupported", {clientShortname: mozL10n.get("clientShortname2")})), 
+          React.DOM.p(null, mozL10n.get("use_firefox_windows_mac_linux", {brandShortname: mozL10n.get("brandShortname")}))
         )
       );
     }
   });
 
   /**
    * Firefox promotion interstitial. Will display only to non-Firefox users.
    */
@@ -74,21 +74,21 @@ loop.webapp = (function($, _, OT, mozL10
     },
 
     render: function() {
       if (this.props.helper.isFirefox(navigator.userAgent)) {
         return React.DOM.div(null);
       }
       return (
         React.DOM.div({className: "promote-firefox"}, 
-          React.DOM.h3(null, mozL10n.get("promote_firefox_hello_heading")), 
+          React.DOM.h3(null, mozL10n.get("promote_firefox_hello_heading", {brandShortname: mozL10n.get("brandShortname")})), 
           React.DOM.p(null, 
             React.DOM.a({className: "btn btn-large btn-accept", 
-               href: "https://www.mozilla.org/firefox/"}, 
-              mozL10n.get("get_firefox_button")
+               href: mozL10n.get("brand_website")}, 
+              mozL10n.get("get_firefox_button", {brandShortname: mozL10n.get("brandShortname")})
             )
           )
         )
       );
     }
   });
 
   /**
@@ -227,33 +227,37 @@ loop.webapp = (function($, _, OT, mozL10
 
       var callUrlCreationDateString = mozL10n.get("call_url_creation_date_label", {
         "call_url_creation_date": this.props.urlCreationDateString
       });
 
       return (
         React.DOM.header({className: "standalone-header header-box container-box"}, 
           ConversationBranding(null), 
-          React.DOM.div({className: "loop-logo", title: "Firefox WebRTC! logo"}), 
+          React.DOM.div({className: "loop-logo", 
+               title: mozL10n.get("client_alttext",
+                                  {clientShortname: mozL10n.get("clientShortname2")})}), 
           React.DOM.h3({className: "call-url"}, 
             conversationUrl
           ), 
           React.DOM.h4({className: urlCreationDateClasses}, 
             callUrlCreationDateString
           )
         )
       );
     }
   });
 
   var ConversationFooter = React.createClass({displayName: 'ConversationFooter',
     render: function() {
       return (
         React.DOM.div({className: "standalone-footer container-box"}, 
-          React.DOM.div({title: "Mozilla Logo", className: "footer-logo"})
+          React.DOM.div({title: mozL10n.get("vendor_alttext",
+                                  {vendorShortname: mozL10n.get("vendorShortname")}), 
+               className: "footer-logo"})
         )
       );
     }
   });
 
   var PendingConversationView = React.createClass({displayName: 'PendingConversationView',
     getInitialState: function() {
       return {
@@ -449,20 +453,21 @@ loop.webapp = (function($, _, OT, mozL10
       }
     },
 
     render: function() {
       var tosLinkName = mozL10n.get("terms_of_use_link_text");
       var privacyNoticeName = mozL10n.get("privacy_notice_link_text");
 
       var tosHTML = mozL10n.get("legal_text_and_links", {
-        "terms_of_use_url": "<a target=_blank href='/legal/terms/'>" +
+        "terms_of_use_url": "<a target=_blank href='" +
+          mozL10n.get("legal_website") + "'>" +
           tosLinkName + "</a>",
         "privacy_notice_url": "<a target=_blank href='" +
-          "https://www.mozilla.org/privacy/'>" + privacyNoticeName + "</a>"
+          mozL10n.get("privacy_website") + "'>" + privacyNoticeName + "</a>"
       });
 
       var tosClasses = React.addons.classSet({
         "terms-service": true,
         hide: (localStorage.getItem("has-seen-tos") === "true")
       });
 
       return (
@@ -904,16 +909,17 @@ loop.webapp = (function($, _, OT, mozL10
       notifications: notifications, 
       sdk: OT, 
       feedbackApiClient: feedbackApiClient}
     ), document.querySelector("#main"));
 
     // Set the 'lang' and 'dir' attributes to <html> when the page is translated
     document.documentElement.lang = mozL10n.language.code;
     document.documentElement.dir = mozL10n.language.direction;
+    document.title = mozL10n.get("clientShortname2");
   }
 
   return {
     CallUrlExpiredView: CallUrlExpiredView,
     PendingConversationView: PendingConversationView,
     StartConversationView: StartConversationView,
     FailedConversationView: FailedConversationView,
     OutgoingConversationView: OutgoingConversationView,
--- a/browser/components/loop/standalone/content/js/webapp.jsx
+++ b/browser/components/loop/standalone/content/js/webapp.jsx
@@ -20,51 +20,51 @@ loop.webapp = (function($, _, OT, mozL10
   var sharedUtils = loop.shared.utils;
 
   /**
    * Homepage view.
    */
   var HomeView = React.createClass({
     render: function() {
       return (
-        <p>{mozL10n.get("welcome")}</p>
+        <p>{mozL10n.get("welcome", {clientShortname: mozL10n.get("clientShortname2")})}</p>
       );
     }
   });
 
   /**
    * Unsupported Browsers view.
    */
   var UnsupportedBrowserView = React.createClass({
     render: function() {
       var useLatestFF = mozL10n.get("use_latest_firefox", {
         "firefoxBrandNameLink": React.renderComponentToStaticMarkup(
-          <a target="_blank" href="https://www.mozilla.org/firefox/">Firefox</a>
+          <a target="_blank" href={mozL10n.get("brand_website")}>{mozL10n.get("brandShortname")}</a>
         )
       });
       return (
         <div>
           <h2>{mozL10n.get("incompatible_browser")}</h2>
-          <p>{mozL10n.get("powered_by_webrtc")}</p>
+          <p>{mozL10n.get("powered_by_webrtc", {clientShortname: mozL10n.get("clientShortname2")})}</p>
           <p dangerouslySetInnerHTML={{__html: useLatestFF}}></p>
         </div>
       );
     }
   });
 
   /**
    * Unsupported Device view.
    */
   var UnsupportedDeviceView = React.createClass({
     render: function() {
       return (
         <div>
           <h2>{mozL10n.get("incompatible_device")}</h2>
-          <p>{mozL10n.get("sorry_device_unsupported")}</p>
-          <p>{mozL10n.get("use_firefox_windows_mac_linux")}</p>
+          <p>{mozL10n.get("sorry_device_unsupported", {clientShortname: mozL10n.get("clientShortname2")})}</p>
+          <p>{mozL10n.get("use_firefox_windows_mac_linux", {brandShortname: mozL10n.get("brandShortname")})}</p>
         </div>
       );
     }
   });
 
   /**
    * Firefox promotion interstitial. Will display only to non-Firefox users.
    */
@@ -74,21 +74,21 @@ loop.webapp = (function($, _, OT, mozL10
     },
 
     render: function() {
       if (this.props.helper.isFirefox(navigator.userAgent)) {
         return <div />;
       }
       return (
         <div className="promote-firefox">
-          <h3>{mozL10n.get("promote_firefox_hello_heading")}</h3>
+          <h3>{mozL10n.get("promote_firefox_hello_heading", {brandShortname: mozL10n.get("brandShortname")})}</h3>
           <p>
             <a className="btn btn-large btn-accept"
-               href="https://www.mozilla.org/firefox/">
-              {mozL10n.get("get_firefox_button")}
+               href={mozL10n.get("brand_website")}>
+              {mozL10n.get("get_firefox_button", {brandShortname: mozL10n.get("brandShortname")})}
             </a>
           </p>
         </div>
       );
     }
   });
 
   /**
@@ -227,33 +227,37 @@ loop.webapp = (function($, _, OT, mozL10
 
       var callUrlCreationDateString = mozL10n.get("call_url_creation_date_label", {
         "call_url_creation_date": this.props.urlCreationDateString
       });
 
       return (
         <header className="standalone-header header-box container-box">
           <ConversationBranding />
-          <div className="loop-logo" title="Firefox WebRTC! logo"></div>
+          <div className="loop-logo"
+               title={mozL10n.get("client_alttext",
+                                  {clientShortname: mozL10n.get("clientShortname2")})}></div>
           <h3 className="call-url">
             {conversationUrl}
           </h3>
           <h4 className={urlCreationDateClasses}>
             {callUrlCreationDateString}
           </h4>
         </header>
       );
     }
   });
 
   var ConversationFooter = React.createClass({
     render: function() {
       return (
         <div className="standalone-footer container-box">
-          <div title="Mozilla Logo" className="footer-logo"></div>
+          <div title={mozL10n.get("vendor_alttext",
+                                  {vendorShortname: mozL10n.get("vendorShortname")})}
+               className="footer-logo"></div>
         </div>
       );
     }
   });
 
   var PendingConversationView = React.createClass({
     getInitialState: function() {
       return {
@@ -449,20 +453,21 @@ loop.webapp = (function($, _, OT, mozL10
       }
     },
 
     render: function() {
       var tosLinkName = mozL10n.get("terms_of_use_link_text");
       var privacyNoticeName = mozL10n.get("privacy_notice_link_text");
 
       var tosHTML = mozL10n.get("legal_text_and_links", {
-        "terms_of_use_url": "<a target=_blank href='/legal/terms/'>" +
+        "terms_of_use_url": "<a target=_blank href='" +
+          mozL10n.get("legal_website") + "'>" +
           tosLinkName + "</a>",
         "privacy_notice_url": "<a target=_blank href='" +
-          "https://www.mozilla.org/privacy/'>" + privacyNoticeName + "</a>"
+          mozL10n.get("privacy_website") + "'>" + privacyNoticeName + "</a>"
       });
 
       var tosClasses = React.addons.classSet({
         "terms-service": true,
         hide: (localStorage.getItem("has-seen-tos") === "true")
       });
 
       return (
@@ -904,16 +909,17 @@ loop.webapp = (function($, _, OT, mozL10
       notifications={notifications}
       sdk={OT}
       feedbackApiClient={feedbackApiClient}
     />, document.querySelector("#main"));
 
     // Set the 'lang' and 'dir' attributes to <html> when the page is translated
     document.documentElement.lang = mozL10n.language.code;
     document.documentElement.dir = mozL10n.language.direction;
+    document.title = mozL10n.get("clientShortname2");
   }
 
   return {
     CallUrlExpiredView: CallUrlExpiredView,
     PendingConversationView: PendingConversationView,
     StartConversationView: StartConversationView,
     FailedConversationView: FailedConversationView,
     OutgoingConversationView: OutgoingConversationView,
--- a/browser/components/loop/standalone/content/l10n/loop.en-US.properties
+++ b/browser/components/loop/standalone/content/l10n/loop.en-US.properties
@@ -44,16 +44,24 @@ privacy_notice_link_text=Privacy notice
 invite_header_text=Invite someone to join you.
 
 ## LOCALIZATION NOTE(brandShortname): This should not be localized and
 ## should remain "Firefox" for all locales.
 brandShortname=Firefox
 ## LOCALIZATION NOTE(clientShortname2): This should not be localized and
 ## should remain "Firefox Hello" for all locales.
 clientShortname2=Firefox Hello
+## LOCALIZATION NOTE(vendorShortname): This should not be localized and
+## should remain "Mozilla" for all locales.
+vendorShortname=Mozilla
+
+## LOCALIZATION NOTE(client_alttext): {{clientShortname}} will be replaced with the
+## value of the clientShortname2 string above.
+client_alttext={{clientShortname}} logo
+vendor_alttext={{vendorShortname}} logo
 
 ## LOCALIZATION NOTE (call_url_creation_date_label): Example output: (from May 26, 2014)
 call_url_creation_date_label=(from {{call_url_creation_date}})
 call_progress_connecting_description=Connecting…
 call_progress_ringing_description=Ringing…
 fxos_app_needed=Please install the {{fxosAppName}} app from the Firefox Marketplace.
 
 feedback_call_experience_heading2=How was your conversation?
@@ -102,8 +110,12 @@ rooms_name_this_room_label=Name this con
 rooms_new_room_button_label=Start a conversation
 rooms_only_occupant_label=You're the first one here.
 rooms_panel_title=Choose a conversation or start a new one
 rooms_room_full_label=There are already two people in this conversation.
 rooms_room_full_call_to_action_nonFx_label=Download {{brandShortname}} to start your own
 rooms_room_full_call_to_action_label=Learn more about {{clientShortname}} »
 rooms_room_joined_label=Someone has joined the conversation!
 rooms_room_join_label=Join the conversation
+
+brand_website=https://www.mozilla.org/firefox/
+privacy_website=https://www.mozilla.org/privacy/
+legal_website=/legal/terms/
--- a/browser/components/loop/standalone/content/legal/terms/index.html
+++ b/browser/components/loop/standalone/content/legal/terms/index.html
@@ -2,31 +2,31 @@
 <!--[if lt IE 7]>      <html class="no-js lt-ie10 lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
 <!--[if IE 7]>         <html class="no-js lt-ie10 lt-ie9 lt-ie8"> <![endif]-->
 <!--[if IE 8]>         <html class="lt-ie10 lt-ie9"> <![endif]-->
 <!--[if IE 9]>         <html class="lt-ie10"> <![endif]-->
 <!--[if gt IE 9]><!--> <html dir="ltr" lang="en-US"> <!--<![endif]-->
     <head>
         <meta charset="utf-8">
         <meta http-equiv="X-UA-Compatible" content="IE=edge">
-        <title>WebRTC: Terms of Service</title>
+        <title>Firefox Hello: Terms of Service</title>
         <meta name="description" content="">
         <meta name="viewport" content="width=device-width">
 
         <link rel="stylesheet" href="/legal/styles/main.css">
     </head>
     <body>
         <div id="fox-logo" class="static"></div>
         <div id="stage">
           <div id="main-content">
             <!--[if lt IE 10]>
                 <p class="error browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
             <![endif]-->
             <header id="legal-header">
-              <h3>WebRTC</h3>
+              <h3>Firefox Hello</h3>
               <h1 id="webrtc-tos-header">Terms of Service</h1>
             </header>
 
             <section>
               <article id="legal-copy">
                 Loading...
               </article>
 
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -1155,27 +1155,35 @@ DataConnectionHandler.prototype = {
         return Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_IMS;
       case "dun":
         return Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_DUN;
       default:
         return Ci.nsINetworkInterface.NETWORK_TYPE_UNKNOWN;
      }
   },
 
+  _compareDataCallOptions: function(dataCall, newDataCall) {
+    return dataCall.apnProfile.apn == newDataCall.apn &&
+           dataCall.apnProfile.user == newDataCall.user &&
+           dataCall.apnProfile.password == newDataCall.password &&
+           dataCall.chappap == newDataCall.chappap &&
+           dataCall.pdptype == newDataCall.pdptype;
+  },
+
   _deliverDataCallMessage: function(name, args) {
     for (let i = 0; i < this._dataCalls.length; i++) {
       let datacall = this._dataCalls[i];
-      // Send message only to the DataCall that matches apn.
+      // Send message only to the DataCall that matches the data call options.
       // Currently, args always contain only one datacall info.
-      if (!args[0].apn || args[0].apn != datacall.apnProfile.apn) {
+      if (!this._compareDataCallOptions(datacall, args[0])) {
         continue;
       }
       // Do not deliver message to DataCall that contains cid but mistmaches
       // with the cid in the current message.
-      if (args[0].cid && datacall.linkInfo.cid &&
+      if (args[0].cid !== undefined && datacall.linkInfo.cid != null &&
           args[0].cid != datacall.linkInfo.cid) {
         continue;
       }
 
       try {
         let handler = datacall[name];
         if (typeof handler !== "function") {
           throw new Error("No handler for " + name);
@@ -1481,19 +1489,27 @@ DataConnectionHandler.prototype = {
 
   /**
    * Handle data errors.
    */
   handleDataCallError: function(message) {
     // Notify data call error only for data APN
     let networkInterface = this.dataNetworkInterfaces.get("default");
     if (networkInterface && networkInterface.enabled) {
-      let apnSetting = networkInterface.apnSetting;
-      if (message.apn == apnSetting.apn) {
-        gMobileConnectionService.notifyDataError(this.clientId, message);
+      let dataCall = networkInterface.dataCall;
+      // If there is a cid, compare cid; otherwise it is probably an error on
+      // data call setup.
+      if (message.cid !== undefined) {
+        if (message.cid == dataCall.linkInfo.cid) {
+          gMobileConnectionService.notifyDataError(this.clientId, message);
+        }
+      } else {
+        if (this._compareDataCallOptions(dataCall, message)) {
+          gMobileConnectionService.notifyDataError(this.clientId, message);
+        }
       }
     }
 
     this._deliverDataCallMessage("dataCallError", [message]);
   },
 
   /**
    * Handle data call state changes.
@@ -3889,16 +3905,22 @@ DataCall.prototype = {
   timer: null,
 
   // APN failed connections. Retry counter
   apnRetryCounter: 0,
 
   // Array to hold RILNetworkInterfaces that requested this DataCall.
   requestedNetworkIfaces: null,
 
+  // Holds the pdp type sent to ril worker.
+  pdptype: null,
+
+  // Holds the authentication type sent to ril worker.
+  chappap: null,
+
   dataCallError: function(message) {
     if (DEBUG) this.debug("Data call error on APN: " + message.apn);
     this.state = RIL.GECKO_NETWORK_STATE_DISCONNECTED;
     this.retry();
   },
 
   dataCallStateChanged: function(datacall) {
     if (DEBUG) {
@@ -4007,31 +4029,42 @@ DataCall.prototype = {
       if (this.requestedNetworkIfaces[i].type == type) {
         return true;
       }
     }
     return false;
   },
 
   canHandleApn: function(apnSetting) {
-    // TODO: compare authtype?
-    return (this.apnProfile.apn == apnSetting.apn &&
-            (this.apnProfile.user || '') == (apnSetting.user || '') &&
-            (this.apnProfile.password || '') == (apnSetting.password || ''));
+    let isIdentical = this.apnProfile.apn == apnSetting.apn &&
+                      (this.apnProfile.user || '') == (apnSetting.user || '') &&
+                      (this.apnProfile.password || '') == (apnSetting.password || '') &&
+                      (this.apnProfile.authType || '') == (apnSetting.authtype || '');
+
+    if (RILQUIRKS_HAVE_IPV6) {
+      isIdentical = isIdentical &&
+                    (this.apnProfile.protocol || '') == (apnSetting.protocol || '') &&
+                    (this.apnProfile.roaming_protocol || '') == (apnSetting.roaming_protocol || '');
+    }
+
+    return isIdentical;
   },
 
   reset: function() {
     this.linkInfo.cid = null;
     this.linkInfo.ifname = null;
     this.linkInfo.ips = [];
     this.linkInfo.prefixLengths = [];
     this.linkInfo.dnses = [];
     this.linkInfo.gateways = [];
 
     this.state = RIL.GECKO_NETWORK_STATE_UNKNOWN;
+
+    this.chappap = null;
+    this.pdptype = null;
   },
 
   connect: function(networkInterface) {
     if (DEBUG) this.debug("connect: " + networkInterface.type);
 
     if (this.requestedNetworkIfaces.indexOf(networkInterface) == -1) {
       this.requestedNetworkIfaces.push(networkInterface);
     }
@@ -4074,38 +4107,41 @@ DataCall.prototype = {
     if (dataInfo == null ||
         dataInfo.state != RIL.GECKO_MOBILE_CONNECTION_STATE_REGISTERED ||
         dataInfo.type == RIL.GECKO_MOBILE_CONNECTION_STATE_UNKNOWN) {
       return;
     }
 
     let radioTechType = dataInfo.type;
     let radioTechnology = RIL.GECKO_RADIO_TECH.indexOf(radioTechType);
-    let authType = RIL.RIL_DATACALL_AUTH_TO_GECKO.indexOf(this.apnProfile.authtype);
+    let authType = RIL.RIL_DATACALL_AUTH_TO_GECKO.indexOf(this.apnProfile.authType);
     // Use the default authType if the value in database is invalid.
     // For the case that user might not select the authentication type.
     if (authType == -1) {
       if (DEBUG) {
         this.debug("Invalid authType " + this.apnProfile.authtype);
       }
       authType = RIL.RIL_DATACALL_AUTH_TO_GECKO.indexOf(RIL.GECKO_DATACALL_AUTH_DEFAULT);
     }
+    this.chappap = authType;
+
     let pdpType = RIL.GECKO_DATACALL_PDP_TYPE_IP;
     if (RILQUIRKS_HAVE_IPV6) {
       pdpType = !dataInfo.roaming
               ? this.apnProfile.protocol
               : this.apnProfile.roaming_protocol;
       if (RIL.RIL_DATACALL_PDP_TYPES.indexOf(pdpType) < 0) {
         if (DEBUG) {
           this.debug("Invalid pdpType '" + pdpType + "', using '" +
                      RIL.GECKO_DATACALL_PDP_TYPE_DEFAULT + "'");
         }
         pdpType = RIL.GECKO_DATACALL_PDP_TYPE_DEFAULT;
       }
     }
+    this.pdptype = pdpType;
 
     let radioInterface = this.gRIL.getRadioInterface(this.clientId);
     radioInterface.sendWorkerMessage("setupDataCall", {
       radioTech: radioTechnology,
       apn: this.apnProfile.apn,
       user: this.apnProfile.user,
       passwd: this.apnProfile.password,
       chappap: authType,
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -4123,20 +4123,18 @@ RilObject.prototype = {
     return "identical";
   },
 
   _processDataCallList: function(datacalls, newDataCallOptions) {
     // Check for possible PDP errors: We check earlier because the datacall
     // can be removed if is the same as the current one.
     for each (let newDataCall in datacalls) {
       if (newDataCall.status != DATACALL_FAIL_NONE) {
-        if (newDataCallOptions) {
-          newDataCall.apn = newDataCallOptions.apn;
-        }
-        this._sendDataCallError(newDataCall, newDataCall.status);
+        this._sendDataCallError(newDataCallOptions || newDataCall,
+                                newDataCall.status);
       }
     }
 
     for each (let currentDataCall in this.currentDataCalls) {
       let updatedDataCall;
       if (datacalls) {
         updatedDataCall = datacalls[currentDataCall.cid];
         delete datacalls[currentDataCall.cid];