Merge b2ginbound to central, a=merge
authorWes Kocher <wkocher@mozilla.com>
Wed, 30 Sep 2015 13:53:55 -0700
changeset 265274 9169f652fe5e69c2d77ac31929934a5bc3342e6e
parent 265228 f2f8cb92dce4ad314b3336f054f0609fdf8dbecc (current diff)
parent 265273 585285f0f23f2c5c3465b1c5cffac17807951b67 (diff)
child 265282 2c043cabe55ac12c6a2f0a33953ce2c4839e4178
child 265313 b00623eb77355e98ffc4584ac6baae8ce7b877a4
child 265409 9c3f3e60e52802422bd637a9273e11426bbeaada
push id29459
push userkwierso@gmail.com
push dateWed, 30 Sep 2015 20:54:00 +0000
treeherdermozilla-central@9169f652fe5e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone44.0a1
first release with
nightly win64
9169f652fe5e / 44.0a1 / 20150930155650 / files
nightly linux32
nightly linux64
nightly mac
nightly win32
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly win64
Merge b2ginbound to central, a=merge
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -1140,8 +1140,13 @@ pref("dom.audiochannel.mutedByDefault", 
 // requests.
 pref("dom.bluetooth.app-origin", "app://bluetooth.gaiamobile.org");
 
 // Default device name for Presentation API
 pref("dom.presentation.device.name", "Firefox OS");
 
 // Enable notification of performance timing
 pref("dom.performance.enable_notify_performance_timing", true);
+
+// Multi-screen
+pref("b2g.multiscreen.chrome_remote_url", "chrome://b2g/content/shell_remote.html");
+pref("b2g.multiscreen.system_remote_url", "index_remote.html");
+
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -15,16 +15,17 @@ Cu.import('resource://gre/modules/Paymen
 Cu.import("resource://gre/modules/AppsUtils.jsm");
 Cu.import('resource://gre/modules/UserAgentOverrides.jsm');
 Cu.import('resource://gre/modules/Keyboard.jsm');
 Cu.import('resource://gre/modules/ErrorPage.jsm');
 Cu.import('resource://gre/modules/AlertsHelper.jsm');
 Cu.import('resource://gre/modules/RequestSyncService.jsm');
 Cu.import('resource://gre/modules/SystemUpdateService.jsm');
 #ifdef MOZ_WIDGET_GONK
+Cu.import('resource://gre/modules/MultiscreenHandler.jsm');
 Cu.import('resource://gre/modules/NetworkStatsService.jsm');
 Cu.import('resource://gre/modules/ResourceStatsService.jsm');
 #endif
 Cu.import('resource://gre/modules/KillSwitchMain.jsm');
 
 // Identity
 Cu.import('resource://gre/modules/SignInToWebsite.jsm');
 SignInToWebsiteController.init();
new file mode 100644
--- /dev/null
+++ b/b2g/chrome/content/shell_remote.html
@@ -0,0 +1,19 @@
+<!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 xmlns="http://www.w3.org/1999/xhtml"
+      id="shellRemote"
+      windowtype="navigator:remote-browser"
+      sizemode="fullscreen"
+      >
+
+<head>
+  <link rel="stylesheet" href="shell.css" type="text/css">
+  <script type="application/javascript;version=1.8"
+          src="chrome://b2g/content/shell_remote.js"> </script>
+</head>
+  <body id="container">
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/b2g/chrome/content/shell_remote.js
@@ -0,0 +1,71 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- /
+/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
+/* 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/. */
+
+"use strict";
+
+const {utils: Cu} = Components;
+
+Cu.import("resource://gre/modules/Services.jsm");
+
+function debug(aStr) {
+  // dump(" -*- ShellRemote.js: " + aStr + "\n");
+}
+
+let remoteShell = {
+
+  get homeURL() {
+    let systemAppManifestURL = Services.io.newURI(this.systemAppManifestURL, null, null);
+    let shellRemoteURL = Services.prefs.getCharPref("b2g.multiscreen.system_remote_url");
+    shellRemoteURL = Services.io.newURI(shellRemoteURL, null, systemAppManifestURL);
+    return shellRemoteURL.spec;
+  },
+
+  get systemAppManifestURL() {
+    return Services.prefs.getCharPref("b2g.system_manifest_url");
+  },
+
+  _started: false,
+
+  hasStarted: function () {
+    return this._started;
+  },
+
+  start: function () {
+    this._started = true;
+
+    let homeURL = this.homeURL;
+    if (!homeURL) {
+      debug("ERROR! Remote home URL undefined.");
+      return;
+    }
+    let manifestURL = this.systemAppManifestURL;
+    // <html:iframe id="remote-systemapp"
+    //              mozbrowser="true" allowfullscreen="true"
+    //              src="blank.html"/>
+    let systemAppFrame =
+      document.createElementNS("http://www.w3.org/1999/xhtml", "html:iframe");
+    systemAppFrame.setAttribute("id", "remote-systemapp");
+    systemAppFrame.setAttribute("mozbrowser", "true");
+    systemAppFrame.setAttribute("mozapp", manifestURL);
+    systemAppFrame.setAttribute("allowfullscreen", "true");
+    systemAppFrame.setAttribute("src", "blank.html");
+
+    let container = document.getElementById("container");
+    this.contentBrowser = container.appendChild(systemAppFrame);
+    this.contentBrowser.src = homeURL + window.location.hash;
+  },
+
+  stop: function () {
+  },
+
+};
+
+window.onload = function() {
+  if (remoteShell.hasStarted() == false) {
+    remoteShell.start();
+  }
+};
+
--- a/b2g/chrome/jar.mn
+++ b/b2g/chrome/jar.mn
@@ -8,16 +8,18 @@ chrome.jar:
 % content branding %content/branding/
 % content b2g %content/
 
   content/arrow.svg                     (content/arrow.svg)
 * content/settings.js                   (content/settings.js)
 * content/shell.html                    (content/shell.html)
 * content/shell.js                      (content/shell.js)
   content/shell.css                     (content/shell.css)
+  content/shell_remote.html             (content/shell_remote.html)
+  content/shell_remote.js               (content/shell_remote.js)
   content/blank.html                    (content/blank.html)
   content/blank.css                     (content/blank.css)
 #ifdef MOZ_WIDGET_GONK
   content/devtools/adb.js               (content/devtools/adb.js)
 #endif
 * content/devtools/debugger.js          (content/devtools/debugger.js)
   content/devtools/hud.js               (content/devtools/hud.js)
 #ifdef FXOS_SIMULATOR
new file mode 100644
--- /dev/null
+++ b/b2g/components/MultiscreenHandler.jsm
@@ -0,0 +1,92 @@
+/* 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/. */
+
+"use strict";
+
+this.EXPORTED_SYMBOLS = ["MultiscreenHandler"];
+
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/Services.jsm");
+
+function debug(aStr) {
+  // dump("MultiscreenHandler: " + aStr + "\n");
+}
+
+let window = Services.wm.getMostRecentWindow("navigator:browser");
+
+// Multi-screen support on b2g. The following implementation will open a new
+// top-level window once we receive a display connected event.
+let MultiscreenHandler = {
+
+  topLevelWindows: new Map(),
+
+  init: function init() {
+    Services.obs.addObserver(this, "display-changed", false);
+    Services.obs.addObserver(this, "xpcom-shutdown", false);
+  },
+
+  uninit: function uninit() {
+    Services.obs.removeObserver(this, "display-changed");
+    Services.obs.removeObserver(this, "xpcom-shutdown");
+  },
+
+  observe: function observe(aSubject, aTopic, aData) {
+    switch (aTopic) {
+      case "display-changed":
+        this.handleDisplayChangeEvent(aSubject);
+        break
+      case "xpcom-shutdown":
+        this.uninit();
+        break
+    }
+  },
+
+  openTopLevelWindow: function openTopLevelWindow(aDisplay) {
+    if (this.topLevelWindows.get(aDisplay.id)) {
+      debug("Top level window for display id: " + aDisplay.id + " has been opened.");
+      return;
+    }
+
+    let flags = Services.prefs.getCharPref("toolkit.defaultChromeFeatures") +
+                ",mozDisplayId=" + aDisplay.id;
+    let remoteShellURL = Services.prefs.getCharPref("b2g.multiscreen.chrome_remote_url") +
+                         "#" + aDisplay.id;
+    let win = Services.ww.openWindow(null, remoteShellURL, "myTopWindow" + aDisplay.id, flags, null);
+
+    this.topLevelWindows.set(aDisplay.id, win);
+  },
+
+  closeTopLevelWindow: function closeTopLevelWindow(aDisplay) {
+    let win = this.topLevelWindows.get(aDisplay.id);
+
+    if (win) {
+      win.close();
+      this.topLevelWindows.delete(aDisplay.id);
+    }
+  },
+
+  handleDisplayChangeEvent: function handleDisplayChangeEvent(aSubject) {
+
+    let display = aSubject.QueryInterface(Ci.nsIDisplayInfo);
+    let name = "multiscreen.enabled";
+    let req = window.navigator.mozSettings.createLock().get(name);
+
+    req.addEventListener("success", () => {
+      let isMultiscreenEnabled = req.result[name];
+      if (display.connected) {
+        if (isMultiscreenEnabled) {
+          this.openTopLevelWindow(display);
+        }
+      } else {
+        this.closeTopLevelWindow(display);
+      }
+    });
+  },
+
+};
+
+MultiscreenHandler.init();
+this.MultiscreenHandler = MultiscreenHandler;
--- a/b2g/components/moz.build
+++ b/b2g/components/moz.build
@@ -62,16 +62,17 @@ EXTRA_JS_MODULES += [
     'ContentRequestHelper.jsm',
     'DebuggerActors.js',
     'ErrorPage.jsm',
     'Frames.jsm',
     'FxAccountsMgmtService.jsm',
     'LogCapture.jsm',
     'LogParser.jsm',
     'LogShake.jsm',
+    'MultiscreenHandler.jsm',
     'OrientationChangeHandler.jsm',
     'SafeMode.jsm',
     'Screenshot.jsm',
     'SignInToWebsite.jsm',
     'SystemAppProxy.jsm',
     'TelURIParser.jsm',
     'WebappsUpdater.jsm',
 ]
--- a/b2g/config/aries/sources.xml
+++ b/b2g/config/aries/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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="14a64f1ebd353bccc3f1c0399e1a01a03327749e"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="be2da974ba076e06e2ff96cd3ac911769d3067a3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
--- 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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="14a64f1ebd353bccc3f1c0399e1a01a03327749e"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="be2da974ba076e06e2ff96cd3ac911769d3067a3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
--- 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="1b0db93fb6b870b03467aff50d6419771ba0d88c">
     <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="14a64f1ebd353bccc3f1c0399e1a01a03327749e"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="be2da974ba076e06e2ff96cd3ac911769d3067a3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="27eb2f04e149fc2c9976d881b1b5984bbe7ee089"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="12ff7481566587aa4198cf1287598acb3a999973"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- 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="660169a3d7e034a892359e39135e8c2785a6ad6f">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="14a64f1ebd353bccc3f1c0399e1a01a03327749e"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="be2da974ba076e06e2ff96cd3ac911769d3067a3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <!-- 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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="14a64f1ebd353bccc3f1c0399e1a01a03327749e"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="be2da974ba076e06e2ff96cd3ac911769d3067a3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
--- a/b2g/config/emulator-l/sources.xml
+++ b/b2g/config/emulator-l/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="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="14a64f1ebd353bccc3f1c0399e1a01a03327749e"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="be2da974ba076e06e2ff96cd3ac911769d3067a3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
--- 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="1b0db93fb6b870b03467aff50d6419771ba0d88c">
     <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="14a64f1ebd353bccc3f1c0399e1a01a03327749e"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="be2da974ba076e06e2ff96cd3ac911769d3067a3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="27eb2f04e149fc2c9976d881b1b5984bbe7ee089"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="12ff7481566587aa4198cf1287598acb3a999973"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- 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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="14a64f1ebd353bccc3f1c0399e1a01a03327749e"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="be2da974ba076e06e2ff96cd3ac911769d3067a3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
-        "git_revision": "14a64f1ebd353bccc3f1c0399e1a01a03327749e", 
+        "git_revision": "be2da974ba076e06e2ff96cd3ac911769d3067a3", 
         "remote": "https://git.mozilla.org/releases/gaia.git", 
         "branch": ""
     }, 
-    "revision": "72d170d61e82726b0fd2a398d21796b11ab2ad66", 
+    "revision": "2194f873784f9366087ee7899640b58c7150dff4", 
     "repo_path": "integration/gaia-central"
 }
--- a/b2g/config/nexus-4-kk/sources.xml
+++ b/b2g/config/nexus-4-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="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="14a64f1ebd353bccc3f1c0399e1a01a03327749e"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="be2da974ba076e06e2ff96cd3ac911769d3067a3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -13,17 +13,17 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="660169a3d7e034a892359e39135e8c2785a6ad6f">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="14a64f1ebd353bccc3f1c0399e1a01a03327749e"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="be2da974ba076e06e2ff96cd3ac911769d3067a3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="f004530b30a63c08a16d82536858600446b2abf5"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
   <!-- 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/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/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="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="14a64f1ebd353bccc3f1c0399e1a01a03327749e"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="be2da974ba076e06e2ff96cd3ac911769d3067a3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9465d16f95ab87636b2ae07538ee88e5aeff2d7d"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="58909a53f638af022ab09f7a8f6976b0cae8f133"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="5f931350fbc87c3df9db8b0ceb37734b8b471593"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="48d8c7c950745f1b166b42125e6f0d3293d71636"/>
--- a/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp
@@ -356,17 +356,23 @@ BluetoothA2dpManager::Connect(const nsAS
   mController = aController;
 
   if (!sBtA2dpInterface) {
     BT_LOGR("sBluetoothA2dpInterface is null");
     aController->NotifyCompletion(NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
     return;
   }
 
-  sBtA2dpInterface->Connect(aDeviceAddress, new ConnectResultHandler());
+  BluetoothAddress deviceAddress;
+  nsresult rv = StringToAddress(aDeviceAddress, deviceAddress);
+  if (NS_FAILED(rv)) {
+    return;
+  }
+
+  sBtA2dpInterface->Connect(deviceAddress, new ConnectResultHandler());
 }
 
 void
 BluetoothA2dpManager::OnDisconnectError()
 {
   MOZ_ASSERT(NS_IsMainThread());
   NS_ENSURE_TRUE_VOID(mController);
 
@@ -417,17 +423,23 @@ BluetoothA2dpManager::Disconnect(Bluetoo
     BT_LOGR("sBluetoothA2dpInterface is null");
     if (aController) {
       aController->NotifyCompletion(
         NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
     }
     return;
   }
 
-  sBtA2dpInterface->Disconnect(mDeviceAddress, new DisconnectResultHandler());
+  BluetoothAddress deviceAddress;
+  nsresult rv = StringToAddress(mDeviceAddress, deviceAddress);
+  if (NS_FAILED(rv)) {
+    return;
+  }
+
+  sBtA2dpInterface->Disconnect(deviceAddress, new DisconnectResultHandler());
 }
 
 void
 BluetoothA2dpManager::OnConnect(const nsAString& aErrorStr)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   /**
@@ -563,18 +575,24 @@ BluetoothA2dpManager::HandleSinkProperty
 /*
  * Reset connection state to DISCONNECTED to handle backend error. The state
  * change triggers UI status bar update as ordinary bluetooth turn-off sequence.
  */
 void
 BluetoothA2dpManager::HandleBackendError()
 {
   if (mSinkState != SinkState::SINK_DISCONNECTED) {
+    BluetoothAddress deviceAddress;
+    nsresult rv = StringToAddress(mDeviceAddress, deviceAddress);
+    if (NS_FAILED(rv)) {
+      return;
+    }
+
     ConnectionStateNotification(A2DP_CONNECTION_STATE_DISCONNECTED,
-      mDeviceAddress);
+      deviceAddress);
   }
 }
 
 void
 BluetoothA2dpManager::NotifyConnectionStatusChanged()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
@@ -618,33 +636,36 @@ BluetoothA2dpManager::IsConnected()
 }
 
 /*
  * Notifications
  */
 
 void
 BluetoothA2dpManager::ConnectionStateNotification(
-  BluetoothA2dpConnectionState aState, const nsAString& aBdAddr)
+  BluetoothA2dpConnectionState aState, const BluetoothAddress& aBdAddr)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsString a2dpState;
   AvStatusToSinkString(aState, a2dpState);
 
   InfallibleTArray<BluetoothNamedValue> props;
   AppendNamedValue(props, "State", a2dpState);
 
+  nsAutoString addressStr;
+  AddressToString(aBdAddr, addressStr);
+
   HandleSinkPropertyChanged(BluetoothSignal(NS_LITERAL_STRING("AudioSink"),
-                                            nsString(aBdAddr), props));
+                                            addressStr, props));
 }
 
 void
 BluetoothA2dpManager::AudioStateNotification(BluetoothA2dpAudioState aState,
-                                             const nsAString& aBdAddr)
+                                             const BluetoothAddress& aBdAddr)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsString a2dpState;
 
   if (aState == A2DP_AUDIO_STATE_STARTED) {
     a2dpState = NS_LITERAL_STRING("playing");
   } else if (aState == A2DP_AUDIO_STATE_STOPPED) {
@@ -653,13 +674,16 @@ BluetoothA2dpManager::AudioStateNotifica
   } else if (aState == A2DP_AUDIO_STATE_REMOTE_SUSPEND) {
     // for avdtp state suspend stream from remote side
     a2dpState = NS_LITERAL_STRING("connected");
   }
 
   InfallibleTArray<BluetoothNamedValue> props;
   AppendNamedValue(props, "State", a2dpState);
 
+  nsAutoString addressStr;
+  AddressToString(aBdAddr, addressStr);
+
   HandleSinkPropertyChanged(BluetoothSignal(NS_LITERAL_STRING("AudioSink"),
-                                            nsString(aBdAddr), props));
+                                            addressStr, props));
 }
 
 NS_IMPL_ISUPPORTS(BluetoothA2dpManager, nsIObserver)
--- a/dom/bluetooth/bluedroid/BluetoothA2dpManager.h
+++ b/dom/bluetooth/bluedroid/BluetoothA2dpManager.h
@@ -55,19 +55,19 @@ private:
   class OnErrorProfileResultHandlerRunnable;
 
   BluetoothA2dpManager();
 
   void HandleShutdown();
   void NotifyConnectionStatusChanged();
 
   void ConnectionStateNotification(BluetoothA2dpConnectionState aState,
-                                   const nsAString& aBdAddr) override;
+                                   const BluetoothAddress& aBdAddr) override;
   void AudioStateNotification(BluetoothA2dpAudioState aState,
-                              const nsAString& aBdAddr) override;
+                              const BluetoothAddress& aBdAddr) override;
 
   nsString mDeviceAddress;
   nsRefPtr<BluetoothProfileController> mController;
 
   // A2DP data member
   bool mA2dpConnected;
   SinkState mSinkState;
 };
--- a/dom/bluetooth/bluedroid/BluetoothAvrcpManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothAvrcpManager.cpp
@@ -792,29 +792,29 @@ BluetoothAvrcpManager::RegisterNotificat
 
 /* This method is used to get CT features from the Feature Bit Mask. If
  * Advanced Control Player bit is set, the CT supports volume sync (absolute
  * volume feature). If Browsing bit is set, AVRCP 1.4 Browse feature will be
  * supported.
  */
 void
 BluetoothAvrcpManager::RemoteFeatureNotification(
-    const nsAString& aBdAddr, unsigned long aFeatures)
+  const BluetoothAddress& aBdAddr, unsigned long aFeatures)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // TODO: Support AVRCP 1.4 absolute volume/browse
 }
 
 /* This method is used to get notifications about volume changes on the
  * remote car kit (if it supports AVRCP 1.4), not notification from phone.
  */
 void
 BluetoothAvrcpManager::VolumeChangeNotification(uint8_t aVolume,
-                                               uint8_t aCType)
+                                                uint8_t aCType)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // TODO: Support AVRCP 1.4 absolute volume/browse
 }
 
 void
 BluetoothAvrcpManager::PassthroughCmdNotification(int aId, int aKeyState)
--- a/dom/bluetooth/bluedroid/BluetoothAvrcpManager.h
+++ b/dom/bluetooth/bluedroid/BluetoothAvrcpManager.h
@@ -96,17 +96,17 @@ private:
   void GetElementAttrNotification(
     uint8_t aNumAttrs,
     const BluetoothAvrcpMediaAttribute* aAttrs) override;
 
   void RegisterNotificationNotification(
     BluetoothAvrcpEvent aEvent, uint32_t aParam) override;
 
   void RemoteFeatureNotification(
-    const nsAString& aBdAddr, unsigned long aFeatures) override;
+    const BluetoothAddress& aBdAddr, unsigned long aFeatures) override;
 
   void VolumeChangeNotification(uint8_t aVolume, uint8_t aCType) override;
 
   void PassthroughCmdNotification(int aId, int aKeyState) override;
 
   nsString mDeviceAddress;
   nsRefPtr<BluetoothProfileController> mController;
 
--- a/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.cpp
@@ -47,47 +47,45 @@ BluetoothDaemonA2dpModule::HandleSvc(con
   (this->*(HandleOp[isNtf]))(aHeader, aPDU, aRes);
 }
 
 // Commands
 //
 
 nsresult
 BluetoothDaemonA2dpModule::ConnectCmd(
-  const nsAString& aRemoteAddr, BluetoothA2dpResultHandler* aRes)
+  const BluetoothAddress& aRemoteAddr, BluetoothA2dpResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(SERVICE_ID,
-                                                           OPCODE_CONNECT,
-                                                           6)); // Address
-  nsresult rv = PackPDU(
-    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), *pdu);
+                                                     OPCODE_CONNECT,
+                                                     6)); // Address
+  nsresult rv = PackPDU(aRemoteAddr, *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonA2dpModule::DisconnectCmd(
-  const nsAString& aRemoteAddr, BluetoothA2dpResultHandler* aRes)
+  const BluetoothAddress& aRemoteAddr, BluetoothA2dpResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(new DaemonSocketPDU(SERVICE_ID,
-                                                           OPCODE_DISCONNECT,
-                                                           6)); // Address
-  nsresult rv = PackPDU(
-    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), *pdu);
+                                                     OPCODE_DISCONNECT,
+                                                     6)); // Address
+  nsresult rv = PackPDU(aRemoteAddr, *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
@@ -177,29 +175,29 @@ class BluetoothDaemonA2dpModule::Connect
   : private PDUInitOp
 {
 public:
   ConnectionStateInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (BluetoothA2dpConnectionState& aArg1, nsString& aArg2) const
+  operator () (BluetoothA2dpConnectionState& aArg1,
+               BluetoothAddress& aArg2) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read state */
     nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     /* Read address */
-    rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
+    rv = UnpackPDU(pdu, aArg2);
     if (NS_FAILED(rv)) {
       return rv;
     }
     WarnAboutTrailingData();
     return NS_OK;
   }
 };
 
@@ -218,29 +216,28 @@ class BluetoothDaemonA2dpModule::AudioSt
 {
 public:
   AudioStateInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
   operator () (BluetoothA2dpAudioState& aArg1,
-               nsString& aArg2) const
+               BluetoothAddress& aArg2) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read state */
     nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     /* Read address */
-    rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
+    rv = UnpackPDU(pdu, aArg2);
     if (NS_FAILED(rv)) {
       return rv;
     }
     WarnAboutTrailingData();
     return NS_OK;
   }
 };
 
@@ -258,23 +255,22 @@ class BluetoothDaemonA2dpModule::AudioCo
   : private PDUInitOp
 {
 public:
   AudioConfigInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (nsString& aArg1, uint32_t aArg2, uint8_t aArg3) const
+  operator () (BluetoothAddress& aArg1, uint32_t aArg2, uint8_t aArg3) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read address */
-    nsresult rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg1));
+    nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     /* Read sample rate */
     rv = UnpackPDU(pdu, aArg2);
     if (NS_FAILED(rv)) {
       return rv;
@@ -441,29 +437,29 @@ BluetoothDaemonA2dpInterface::Cleanup(
     DispatchError(aRes, rv);
   }
 }
 
 /* Connect / Disconnect */
 
 void
 BluetoothDaemonA2dpInterface::Connect(
-  const nsAString& aBdAddr, BluetoothA2dpResultHandler* aRes)
+  const BluetoothAddress& aBdAddr, BluetoothA2dpResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ConnectCmd(aBdAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
 BluetoothDaemonA2dpInterface::Disconnect(
-  const nsAString& aBdAddr, BluetoothA2dpResultHandler* aRes)
+  const BluetoothAddress& aBdAddr, BluetoothA2dpResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->DisconnectCmd(aBdAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
--- a/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonA2dpInterface.h
@@ -44,19 +44,19 @@ public:
 
   void SetNotificationHandler(
     BluetoothA2dpNotificationHandler* aNotificationHandler);
 
   //
   // Commands
   //
 
-  nsresult ConnectCmd(const nsAString& aBdAddr,
+  nsresult ConnectCmd(const BluetoothAddress& aBdAddr,
                       BluetoothA2dpResultHandler* aRes);
-  nsresult DisconnectCmd(const nsAString& aBdAddr,
+  nsresult DisconnectCmd(const BluetoothAddress& aBdAddr,
                          BluetoothA2dpResultHandler* aRes);
 
 protected:
   void HandleSvc(const DaemonSocketPDUHeader& aHeader,
                  DaemonSocketPDU& aPDU, DaemonSocketResultHandler* aRes);
 
   //
   // Responses
@@ -88,28 +88,31 @@ protected:
 
   //
   // Notifications
   //
 
   class NotificationHandlerWrapper;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
-    NotificationHandlerWrapper, void, BluetoothA2dpConnectionState, nsString,
-    BluetoothA2dpConnectionState, const nsAString&>
+    NotificationHandlerWrapper, void,
+    BluetoothA2dpConnectionState, BluetoothAddress,
+    BluetoothA2dpConnectionState, const BluetoothAddress&>
     ConnectionStateNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
-    NotificationHandlerWrapper, void, BluetoothA2dpAudioState, nsString,
-    BluetoothA2dpAudioState, const nsAString&>
+    NotificationHandlerWrapper, void,
+    BluetoothA2dpAudioState, BluetoothAddress,
+    BluetoothA2dpAudioState, const BluetoothAddress&>
     AudioStateNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable3<
-    NotificationHandlerWrapper, void, nsString, uint32_t, uint8_t,
-    const nsAString&, uint32_t, uint8_t>
+    NotificationHandlerWrapper, void,
+    BluetoothAddress, uint32_t, uint8_t,
+    const BluetoothAddress&, uint32_t, uint8_t>
     AudioConfigNotification;
 
   class ConnectionStateInitOp;
   class AudioStateInitOp;
   class AudioConfigInitOp;
 
   void ConnectionStateNtf(const DaemonSocketPDUHeader& aHeader,
                           DaemonSocketPDU& aPDU);
@@ -139,19 +142,19 @@ public:
 
   void Init(
     BluetoothA2dpNotificationHandler* aNotificationHandler,
     BluetoothA2dpResultHandler* aRes) override;
   void Cleanup(BluetoothA2dpResultHandler* aRes) override;
 
   /* Connect / Disconnect */
 
-  void Connect(const nsAString& aBdAddr,
+  void Connect(const BluetoothAddress& aBdAddr,
                BluetoothA2dpResultHandler* aRes) override;
-  void Disconnect(const nsAString& aBdAddr,
+  void Disconnect(const BluetoothAddress& aBdAddr,
                   BluetoothA2dpResultHandler* aRes) override;
 
 private:
   void DispatchError(BluetoothA2dpResultHandler* aRes,
                      BluetoothStatus aStatus);
   void DispatchError(BluetoothA2dpResultHandler* aRes, nsresult aRv);
 
   BluetoothDaemonA2dpModule* mModule;
--- a/dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.cpp
@@ -478,23 +478,22 @@ class BluetoothDaemonAvrcpModule::Remote
   : private PDUInitOp
 {
 public:
   RemoteFeatureInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (nsString& aArg1, unsigned long& aArg2) const
+  operator () (BluetoothAddress& aArg1, unsigned long& aArg2) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read address */
-    nsresult rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg1));
+    nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     /* Read feature */
     rv = UnpackPDU(
       pdu,
       UnpackConversion<BluetoothAvrcpRemoteFeatureBits, unsigned long>(aArg2));
--- a/dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonAvrcpInterface.h
@@ -184,18 +184,19 @@ protected:
 
   //
   // Notifications
   //
 
   class NotificationHandlerWrapper;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
-    NotificationHandlerWrapper, void, nsString, unsigned long,
-    const nsAString&>
+    NotificationHandlerWrapper, void,
+    BluetoothAddress, unsigned long,
+    const BluetoothAddress&>
     RemoteFeatureNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable0<
     NotificationHandlerWrapper, void>
     GetPlayStatusNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable0<
     NotificationHandlerWrapper, void>
--- a/dom/bluetooth/bluedroid/BluetoothDaemonCoreInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonCoreInterface.cpp
@@ -146,125 +146,119 @@ BluetoothDaemonCoreModule::SetAdapterPro
     return rv;
   }
   unused << pdu.forget();
   return rv;
 }
 
 nsresult
 BluetoothDaemonCoreModule::GetRemoteDevicePropertiesCmd(
-  const nsAString& aRemoteAddr, BluetoothResultHandler* aRes)
+  const BluetoothAddress& aRemoteAddr, BluetoothResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_GET_REMOTE_DEVICE_PROPERTIES,
                         0));
 
-  nsresult rv = PackPDU(
-    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), *pdu);
+  nsresult rv = PackPDU(aRemoteAddr, *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return rv;
 }
 
 nsresult
 BluetoothDaemonCoreModule::GetRemoteDevicePropertyCmd(
-  const nsAString& aRemoteAddr,
+  const BluetoothAddress& aRemoteAddr,
   const nsAString& aName,
   BluetoothResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_GET_REMOTE_DEVICE_PROPERTY,
                         0));
 
   nsresult rv = PackPDU(
-    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr),
+    aRemoteAddr,
     PackConversion<nsAString, BluetoothPropertyType>(aName), *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return rv;
 }
 
 nsresult
 BluetoothDaemonCoreModule::SetRemoteDevicePropertyCmd(
-  const nsAString& aRemoteAddr,
+  const BluetoothAddress& aRemoteAddr,
   const BluetoothNamedValue& aProperty,
   BluetoothResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_SET_REMOTE_DEVICE_PROPERTY,
                         0));
 
-  nsresult rv = PackPDU(
-    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr),
-    aProperty, *pdu);
+  nsresult rv = PackPDU(aRemoteAddr, aProperty, *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return rv;
 }
 
 nsresult
 BluetoothDaemonCoreModule::GetRemoteServiceRecordCmd(
-  const nsAString& aRemoteAddr, const BluetoothUuid& aUuid,
+  const BluetoothAddress& aRemoteAddr, const BluetoothUuid& aUuid,
   BluetoothResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_GET_REMOTE_SERVICE_RECORD,
                         0));
 
-  nsresult rv = PackPDU(
-    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr),
-    aUuid, *pdu);
+  nsresult rv = PackPDU(aRemoteAddr, aUuid, *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return rv;
 }
 
 nsresult
 BluetoothDaemonCoreModule::GetRemoteServicesCmd(
-  const nsAString& aRemoteAddr, BluetoothResultHandler* aRes)
+  const BluetoothAddress& aRemoteAddr, BluetoothResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_GET_REMOTE_SERVICES, 0));
 
-  nsresult rv = PackPDU(
-    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), *pdu);
+  nsresult rv = PackPDU(aRemoteAddr, *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
@@ -301,131 +295,126 @@ BluetoothDaemonCoreModule::CancelDiscove
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return rv;
 }
 
 nsresult
-BluetoothDaemonCoreModule::CreateBondCmd(const nsAString& aBdAddr,
+BluetoothDaemonCoreModule::CreateBondCmd(const BluetoothAddress& aBdAddr,
                                          BluetoothTransport aTransport,
                                          BluetoothResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CREATE_BOND,
                         0));
 
 #if ANDROID_VERSION >= 21
-  nsresult rv = PackPDU(
-    PackConversion<nsAString, BluetoothAddress>(aBdAddr), aTransport, *pdu);
+  nsresult rv = PackPDU(aBdAddr, aTransport, *pdu);
 #else
-  nsresult rv = PackPDU(
-    PackConversion<nsAString, BluetoothAddress>(aBdAddr), *pdu);
+  nsresult rv = PackPDU(aBdAddr, *pdu);
 #endif
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return rv;
 }
 
 nsresult
-BluetoothDaemonCoreModule::RemoveBondCmd(const nsAString& aBdAddr,
+BluetoothDaemonCoreModule::RemoveBondCmd(const BluetoothAddress& aBdAddr,
                                          BluetoothResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_REMOVE_BOND,
                         0));
 
-  nsresult rv = PackPDU(
-    PackConversion<nsAString, BluetoothAddress>(aBdAddr), *pdu);
+  nsresult rv = PackPDU(aBdAddr, *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return rv;
 }
 
 nsresult
-BluetoothDaemonCoreModule::CancelBondCmd(const nsAString& aBdAddr,
+BluetoothDaemonCoreModule::CancelBondCmd(const BluetoothAddress& aBdAddr,
                                          BluetoothResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CANCEL_BOND,
                         0));
 
-  nsresult rv = PackPDU(
-    PackConversion<nsAString, BluetoothAddress>(aBdAddr), *pdu);
+  nsresult rv = PackPDU(aBdAddr, *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return rv;
 }
 
 nsresult
-BluetoothDaemonCoreModule::PinReplyCmd(const nsAString& aBdAddr, bool aAccept,
+BluetoothDaemonCoreModule::PinReplyCmd(const BluetoothAddress& aBdAddr,
+                                       bool aAccept,
                                        const nsAString& aPinCode,
                                        BluetoothResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_PIN_REPLY,
                         0));
 
   nsresult rv = PackPDU(
-    PackConversion<nsAString, BluetoothAddress>(aBdAddr),
+    aBdAddr,
     aAccept,
     PackConversion<nsAString, BluetoothPinCode>(aPinCode), *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return rv;
 }
 
 nsresult
-BluetoothDaemonCoreModule::SspReplyCmd(const nsAString& aBdAddr,
+BluetoothDaemonCoreModule::SspReplyCmd(const BluetoothAddress& aBdAddr,
                                        BluetoothSspVariant aVariant,
                                        bool aAccept, uint32_t aPasskey,
                                        BluetoothResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_SSP_REPLY,
                         0));
 
-  nsresult rv = PackPDU(
-    PackConversion<nsAString, BluetoothAddress>(aBdAddr),
-    aVariant, aAccept, aPasskey, *pdu);
+  nsresult rv = PackPDU(aBdAddr, aVariant, aAccept, aPasskey, *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
@@ -861,30 +850,29 @@ class BluetoothDaemonCoreModule::RemoteD
   : private PDUInitOp
 {
 public:
   RemoteDevicePropertiesInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (BluetoothStatus& aArg1, nsString& aArg2, int& aArg3,
+  operator () (BluetoothStatus& aArg1, BluetoothAddress& aArg2, int& aArg3,
                nsAutoArrayPtr<BluetoothProperty>& aArg4) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read status */
     nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     /* Read address */
-    rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
+    rv = UnpackPDU(pdu, aArg2);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     /* Read number of properties */
     uint8_t numProperties;
     rv = UnpackPDU(pdu, numProperties);
     if (NS_FAILED(rv)) {
@@ -968,23 +956,22 @@ class BluetoothDaemonCoreModule::PinRequ
   : private PDUInitOp
 {
 public:
   PinRequestInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (nsString& aArg1, nsString& aArg2, uint32_t& aArg3) const
+  operator () (BluetoothAddress& aArg1, nsString& aArg2, uint32_t& aArg3) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read remote address */
-    nsresult rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg1));
+    nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     /* Read remote name */
     rv = UnpackPDU(
       pdu, UnpackConversion<BluetoothRemoteName, nsAString>(aArg2));
     if (NS_FAILED(rv)) {
@@ -1015,24 +1002,23 @@ class BluetoothDaemonCoreModule::SspRequ
   : private PDUInitOp
 {
 public:
   SspRequestInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (nsString& aArg1, nsString& aArg2, uint32_t& aArg3,
+  operator () (BluetoothAddress& aArg1, nsString& aArg2, uint32_t& aArg3,
                BluetoothSspVariant& aArg4, uint32_t& aArg5) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read remote address */
-    nsresult rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg1));
+    nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     /* Read remote name */
     rv = UnpackPDU(
       pdu, UnpackConversion<BluetoothRemoteName, nsAString>(aArg2));
     if (NS_FAILED(rv)) {
@@ -1075,30 +1061,29 @@ class BluetoothDaemonCoreModule::BondSta
   : private PDUInitOp
 {
 public:
   BondStateChangedInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (BluetoothStatus& aArg1, nsString& aArg2,
+  operator () (BluetoothStatus& aArg1, BluetoothAddress& aArg2,
                BluetoothBondState& aArg3) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read status */
     nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     /* Read remote address */
-    rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
+    rv = UnpackPDU(pdu, aArg2);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     /* Read bond state */
     rv = UnpackPDU(pdu, aArg3);
     if (NS_FAILED(rv)) {
       return rv;
@@ -1122,29 +1107,29 @@ class BluetoothDaemonCoreModule::AclStat
   : private PDUInitOp
 {
 public:
   AclStateChangedInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (BluetoothStatus& aArg1, nsString& aArg2, bool& aArg3) const
+  operator () (BluetoothStatus& aArg1, BluetoothAddress& aArg2,
+               bool& aArg3) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read status */
     nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     /* Read remote address */
-    rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
+    rv = UnpackPDU(pdu, aArg2);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     /* Read ACL state */
     rv = UnpackPDU(
       pdu, UnpackConversion<BluetoothAclState, bool>(aArg3));
     if (NS_FAILED(rv)) {
--- a/dom/bluetooth/bluedroid/BluetoothDaemonCoreInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonCoreInterface.h
@@ -80,53 +80,54 @@ public:
   nsresult GetAdapterPropertiesCmd(BluetoothResultHandler* aRes);
 
   nsresult GetAdapterPropertyCmd(const nsAString& aName,
                                  BluetoothResultHandler* aRes);
 
   nsresult SetAdapterPropertyCmd(const BluetoothNamedValue& aProperty,
                                  BluetoothResultHandler* aRes);
 
-  nsresult GetRemoteDevicePropertiesCmd(const nsAString& aRemoteAddr,
+  nsresult GetRemoteDevicePropertiesCmd(const BluetoothAddress& aRemoteAddr,
                                         BluetoothResultHandler* aRes);
 
-  nsresult GetRemoteDevicePropertyCmd(const nsAString& aRemoteAddr,
+  nsresult GetRemoteDevicePropertyCmd(const BluetoothAddress& aRemoteAddr,
                                       const nsAString& aName,
                                       BluetoothResultHandler* aRes);
 
-  nsresult SetRemoteDevicePropertyCmd(const nsAString& aRemoteAddr,
+  nsresult SetRemoteDevicePropertyCmd(const BluetoothAddress& aRemoteAddr,
                                       const BluetoothNamedValue& aProperty,
                                       BluetoothResultHandler* aRes);
 
-  nsresult GetRemoteServiceRecordCmd(const nsAString& aRemoteAddr,
+  nsresult GetRemoteServiceRecordCmd(const BluetoothAddress& aRemoteAddr,
                                      const BluetoothUuid& aUuid,
                                      BluetoothResultHandler* aRes);
 
-  nsresult GetRemoteServicesCmd(const nsAString& aRemoteAddr,
+  nsresult GetRemoteServicesCmd(const BluetoothAddress& aRemoteAddr,
                                 BluetoothResultHandler* aRes);
 
   nsresult StartDiscoveryCmd(BluetoothResultHandler* aRes);
 
   nsresult CancelDiscoveryCmd(BluetoothResultHandler* aRes);
 
-  nsresult CreateBondCmd(const nsAString& aBdAddr,
+  nsresult CreateBondCmd(const BluetoothAddress& aBdAddr,
                          BluetoothTransport aTransport,
                          BluetoothResultHandler* aRes);
 
-  nsresult RemoveBondCmd(const nsAString& aBdAddr,
+  nsresult RemoveBondCmd(const BluetoothAddress& aBdAddr,
                          BluetoothResultHandler* aRes);
 
-  nsresult CancelBondCmd(const nsAString& aBdAddr,
+  nsresult CancelBondCmd(const BluetoothAddress& aBdAddr,
                          BluetoothResultHandler* aRes);
 
-  nsresult PinReplyCmd(const nsAString& aBdAddr, bool aAccept,
+  nsresult PinReplyCmd(const BluetoothAddress& aBdAddr, bool aAccept,
                        const nsAString& aPinCode,
                        BluetoothResultHandler* aRes);
 
-  nsresult SspReplyCmd(const nsAString& aBdAddr, BluetoothSspVariant aVariant,
+  nsresult SspReplyCmd(const BluetoothAddress& aBdAddr,
+                       BluetoothSspVariant aVariant,
                        bool aAccept, uint32_t aPasskey,
                        BluetoothResultHandler* aRes);
 
   nsresult DutModeConfigureCmd(bool aEnable, BluetoothResultHandler* aRes);
 
   nsresult DutModeSendCmd(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
                           BluetoothResultHandler* aRes);
 
@@ -245,48 +246,48 @@ private:
 
   typedef mozilla::ipc::DaemonNotificationRunnable3<
     NotificationHandlerWrapper, void, BluetoothStatus, int,
     nsAutoArrayPtr<BluetoothProperty>, BluetoothStatus, int,
     const BluetoothProperty*>
     AdapterPropertiesNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable4<
-    NotificationHandlerWrapper, void, BluetoothStatus, nsString, int,
-    nsAutoArrayPtr<BluetoothProperty>, BluetoothStatus, const nsAString&,
-    int, const BluetoothProperty*>
+    NotificationHandlerWrapper, void, BluetoothStatus, BluetoothAddress, int,
+    nsAutoArrayPtr<BluetoothProperty>, BluetoothStatus,
+    const BluetoothAddress&, int, const BluetoothProperty*>
     RemoteDevicePropertiesNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
     NotificationHandlerWrapper, void, int, nsAutoArrayPtr<BluetoothProperty>,
     int, const BluetoothProperty*>
     DeviceFoundNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable1<
     NotificationHandlerWrapper, void, bool>
     DiscoveryStateChangedNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable3<
-    NotificationHandlerWrapper, void, nsString, nsString, uint32_t,
-    const nsAString&, const nsAString&>
+    NotificationHandlerWrapper, void, BluetoothAddress, nsString, uint32_t,
+    const BluetoothAddress&, const nsAString&>
     PinRequestNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable5<
-    NotificationHandlerWrapper, void, nsString, nsString, uint32_t,
-    BluetoothSspVariant, uint32_t, const nsAString&, const nsAString&>
+    NotificationHandlerWrapper, void, BluetoothAddress, nsString, uint32_t,
+    BluetoothSspVariant, uint32_t, const BluetoothAddress&, const nsAString&>
     SspRequestNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable3<
-    NotificationHandlerWrapper, void, BluetoothStatus, nsString,
-    BluetoothBondState, BluetoothStatus, const nsAString&>
+    NotificationHandlerWrapper, void, BluetoothStatus, BluetoothAddress,
+    BluetoothBondState, BluetoothStatus, const BluetoothAddress&>
     BondStateChangedNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable3<
-    NotificationHandlerWrapper, void, BluetoothStatus, nsString, bool,
-    BluetoothStatus, const nsAString&>
+    NotificationHandlerWrapper, void, BluetoothStatus, BluetoothAddress, bool,
+    BluetoothStatus, const BluetoothAddress&>
     AclStateChangedNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable3<
     NotificationHandlerWrapper, void, uint16_t, nsAutoArrayPtr<uint8_t>,
     uint8_t, uint16_t, const uint8_t*>
     DutModeRecvNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
--- a/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.cpp
@@ -116,60 +116,60 @@ BluetoothDaemonGattModule::ClientScanCmd
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientConnectCmd(
-  int aClientIf, const nsAString& aBdAddr, bool aIsDirect,
+  int aClientIf, const BluetoothAddress& aBdAddr, bool aIsDirect,
   BluetoothTransport aTransport, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_CONNECT,
                         4 + // Client Interface
                         6 + // Remote Address
                         1 + // Is Direct
                         4)); // Transport
 
   nsresult rv = PackPDU(
     PackConversion<int, int32_t>(aClientIf),
-    PackConversion<nsAString, BluetoothAddress>(aBdAddr),
+    aBdAddr,
     PackConversion<bool, uint8_t>(aIsDirect),
     PackConversion<BluetoothTransport, int32_t>(aTransport), *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientDisconnectCmd(
-  int aClientIf, const nsAString& aBdAddr, int aConnId,
+  int aClientIf, const BluetoothAddress& aBdAddr, int aConnId,
   BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_DISCONNECT,
                         4 + // Client Interface
                         6 + // Remote Address
                         4)); // Connection ID
 
   nsresult rv;
   rv = PackPDU(PackConversion<int, int32_t>(aClientIf),
-               PackConversion<nsAString, BluetoothAddress>(aBdAddr),
+               aBdAddr,
                PackConversion<int, int32_t>(aConnId), *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
@@ -199,27 +199,28 @@ BluetoothDaemonGattModule::ClientListenC
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientRefreshCmd(
-  int aClientIf, const nsAString& aBdAddr, BluetoothGattResultHandler* aRes)
+  int aClientIf, const BluetoothAddress& aBdAddr,
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_REFRESH,
                         4 + // Client Interface
                         6)); // Remote Address
 
   nsresult rv = PackPDU(PackConversion<int, int32_t>(aClientIf),
-                        PackConversion<nsAString, BluetoothAddress>(aBdAddr),
+                        aBdAddr,
                         *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
@@ -479,110 +480,106 @@ BluetoothDaemonGattModule::ClientExecute
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientRegisterNotificationCmd(
-  int aClientIf, const nsAString& aBdAddr,
+  int aClientIf, const BluetoothAddress& aBdAddr,
   const BluetoothGattServiceId& aServiceId, const BluetoothGattId& aCharId,
   BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_REGISTER_NOTIFICATION,
                         4 + // Client Interface
                         6 + // Remote Address
                         18 + // Service ID
                         17)); // Characteristic ID
 
   nsresult rv = PackPDU(PackConversion<int, int32_t>(aClientIf),
-                        PackConversion<nsAString, BluetoothAddress>(aBdAddr),
-                        aServiceId, aCharId, *pdu);
+                        aBdAddr, aServiceId, aCharId, *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientDeregisterNotificationCmd(
-  int aClientIf, const nsAString& aBdAddr,
+  int aClientIf, const BluetoothAddress& aBdAddr,
   const BluetoothGattServiceId& aServiceId, const BluetoothGattId& aCharId,
   BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_DEREGISTER_NOTIFICATION,
                         4 + // Client Interface
                         6 + // Remote Address
                         18 + // Service ID
                         17)); // Characteristic ID
 
   nsresult rv = PackPDU(PackConversion<int, int32_t>(aClientIf),
-                        PackConversion<nsAString, BluetoothAddress>(aBdAddr),
-                        aServiceId, aCharId, *pdu);
+                        aBdAddr, aServiceId, aCharId, *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientReadRemoteRssiCmd(
-  int aClientIf, const nsAString& aBdAddr,
+  int aClientIf, const BluetoothAddress& aBdAddr,
   BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_READ_REMOTE_RSSI,
                         4 + // Client Interface
                         6)); // Remote Address
 
   nsresult rv = PackPDU(PackConversion<int, int32_t>(aClientIf),
-                        PackConversion<nsAString, BluetoothAddress>(aBdAddr),
-                        *pdu);
+                        aBdAddr, *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ClientGetDeviceTypeCmd(
-  const nsAString& aBdAddr, BluetoothGattResultHandler* aRes)
+  const BluetoothAddress& aBdAddr, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLIENT_GET_DEVICE_TYPE,
                         6)); // Remote Address
 
-  nsresult rv = PackPDU(
-    PackConversion<nsAString, BluetoothAddress>(aBdAddr), *pdu);
+  nsresult rv = PackPDU(aBdAddr, *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
@@ -640,17 +637,17 @@ BluetoothDaemonGattModule::ClientTestCom
                         2 + // U1
                         2 + // U2
                         2 + // U3
                         2 + // U4
                         2)); // U5
 
   nsresult rv = PackPDU(
     PackConversion<int, int32_t>(aCommand),
-    PackConversion<nsAString, BluetoothAddress>(aTestParam.mBdAddr),
+    aTestParam.mBdAddr,
     aTestParam.mU1, aTestParam.mU2, aTestParam.mU3, aTestParam.mU4,
     aTestParam.mU5, *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
@@ -700,59 +697,59 @@ BluetoothDaemonGattModule::ServerUnregis
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ServerConnectPeripheralCmd(
-  int aServerIf, const nsAString& aBdAddr, bool aIsDirect,
+  int aServerIf, const BluetoothAddress& aBdAddr, bool aIsDirect,
   BluetoothTransport aTransport, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_SERVER_CONNECT_PERIPHERAL,
                         4 + // Server Interface
                         6 + // Remote Address
                         1 + // Is Direct
                         4)); // Transport
 
   nsresult rv = PackPDU(
     PackConversion<int, int32_t>(aServerIf),
-    PackConversion<nsAString, BluetoothAddress>(aBdAddr),
+    aBdAddr,
     PackConversion<bool, uint8_t>(aIsDirect),
     PackConversion<BluetoothTransport, int32_t>(aTransport), *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonGattModule::ServerDisconnectPeripheralCmd(
-  int aServerIf, const nsAString& aBdAddr, int aConnId,
+  int aServerIf, const BluetoothAddress& aBdAddr, int aConnId,
   BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_SERVER_DISCONNECT_PERIPHERAL,
                         4 + // Server Interface
                         6 + // Remote Address
                         4)); // Connection Id
 
   nsresult rv = PackPDU(PackConversion<int, int32_t>(aServerIf),
-                        PackConversion<nsAString, BluetoothAddress>(aBdAddr),
+                        aBdAddr,
                         PackConversion<int, int32_t>(aConnId), *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
@@ -1524,25 +1521,24 @@ class BluetoothDaemonGattModule::ClientS
   : private PDUInitOp
 {
 public:
   ClientScanResultInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (nsString& aArg1,
+  operator () (BluetoothAddress& aArg1,
                int& aArg2,
                BluetoothGattAdvData& aArg3) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read address */
-    nsresult rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg1));
+    nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
     /* Read RSSI */
     rv = UnpackPDU(pdu, aArg2);
     if (NS_FAILED(rv)) {
       return rv;
     }
@@ -1580,17 +1576,17 @@ public:
   ClientConnectDisconnectInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
   operator () (int& aArg1,
                BluetoothGattStatus& aArg2,
                int& aArg3,
-               nsString& aArg4) const
+               BluetoothAddress& aArg4) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read connection ID */
     nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
@@ -1600,18 +1596,17 @@ public:
       return rv;
     }
     /* Read client interface */
     rv = UnpackPDU(pdu, aArg3);
     if (NS_FAILED(rv)) {
       return rv;
     }
     /* Read address */
-    rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg4));
+    rv = UnpackPDU(pdu, aArg4);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     WarnAboutTrailingData();
     return NS_OK;
   }
 };
@@ -1748,29 +1743,29 @@ class BluetoothDaemonGattModule::ClientR
 {
 public:
   ClientReadRemoteRssiInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
   operator () (int& aArg1,
-               nsString& aArg2,
+               BluetoothAddress& aArg2,
                int& aArg3,
                BluetoothGattStatus& aArg4) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read client interface */
     nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
     /* Read address */
-    rv = UnpackPDU(pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
+    rv = UnpackPDU(pdu, aArg2);
     if (NS_FAILED(rv)) {
       return rv;
     }
     /* Read RSSI */
     rv = UnpackPDU(pdu, aArg3);
     if (NS_FAILED(rv)) {
       return rv;
     }
@@ -1820,17 +1815,17 @@ public:
   ServerConnectionInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
   operator () (int& aArg1,
                int& aArg2,
                bool& aArg3,
-               nsString& aArg4) const
+               BluetoothAddress& aArg4) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read connection ID */
     nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
@@ -1840,18 +1835,17 @@ public:
       return rv;
     }
     /* Read connected */
     rv = UnpackPDU(pdu, UnpackConversion<int32_t, bool>(aArg3));
     if (NS_FAILED(rv)) {
       return rv;
     }
     /* Read address */
-    rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg4));
+    rv = UnpackPDU(pdu, aArg4);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     WarnAboutTrailingData();
     return NS_OK;
   }
 };
@@ -1935,17 +1929,17 @@ class BluetoothDaemonGattModule::ServerR
 public:
   ServerRequestReadInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
   operator () (int& aArg1,
                int& aArg2,
-               nsString& aArg3,
+               BluetoothAddress& aArg3,
                BluetoothAttributeHandle& aArg4,
                int& aArg5,
                bool& aArg6) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read connection ID */
     nsresult rv = UnpackPDU(pdu, aArg1);
@@ -1953,18 +1947,17 @@ public:
       return rv;
     }
     /* Read trans ID */
     rv = UnpackPDU(pdu, aArg2);
     if (NS_FAILED(rv)) {
       return rv;
     }
     /* Read address */
-    rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg3));
+    rv = UnpackPDU(pdu, aArg3);
     if (NS_FAILED(rv)) {
       return rv;
     }
     /* Read attribute handle */
     rv = UnpackPDU(pdu, aArg4);
     if (NS_FAILED(rv)) {
       return rv;
     }
@@ -2000,17 +1993,17 @@ class BluetoothDaemonGattModule::ServerR
 public:
   ServerRequestWriteInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
   operator () (int& aArg1,
                int& aArg2,
-               nsString& aArg3,
+               BluetoothAddress& aArg3,
                BluetoothAttributeHandle& aArg4,
                int& aArg5,
                int& aArg6,
                nsAutoArrayPtr<uint8_t>& aArg7,
                bool& aArg8,
                bool& aArg9) const
   {
     DaemonSocketPDU& pdu = GetPDU();
@@ -2021,18 +2014,17 @@ public:
       return rv;
     }
     /* Read trans ID */
     rv = UnpackPDU(pdu, aArg2);
     if (NS_FAILED(rv)) {
       return rv;
     }
     /* Read address */
-    rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg3));
+    rv = UnpackPDU(pdu, aArg3);
     if (NS_FAILED(rv)) {
       return rv;
     }
     /* Read attribute handle */
     rv = UnpackPDU(pdu, aArg4);
     if (NS_FAILED(rv)) {
       return rv;
     }
@@ -2084,34 +2076,33 @@ class BluetoothDaemonGattModule::ServerR
 public:
   ServerRequestExecuteWriteInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
   operator () (int& aArg1,
                int& aArg2,
-               nsString& aArg3,
+               BluetoothAddress& aArg3,
                bool& aArg4) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read connection ID */
     nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
     /* Read trans ID */
     rv = UnpackPDU(pdu, aArg2);
     if (NS_FAILED(rv)) {
       return rv;
     }
     /* Read address */
-    rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg3));
+    rv = UnpackPDU(pdu, aArg3);
     if (NS_FAILED(rv)) {
       return rv;
     }
     /* Read execute write */
     rv = UnpackPDU(pdu, aArg4);
     if (NS_FAILED(rv)) {
       return rv;
     }
@@ -2347,31 +2338,31 @@ BluetoothDaemonGattInterface::Scan(
     DispatchError(aRes, rv);
   }
 }
 
 /* Connect / Disconnect */
 
 void
 BluetoothDaemonGattInterface::Connect(
-  int aClientIf, const nsAString& aBdAddr, bool aIsDirect,
+  int aClientIf, const BluetoothAddress& aBdAddr, bool aIsDirect,
   BluetoothTransport aTransport, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientConnectCmd(
     aClientIf, aBdAddr, aIsDirect, aTransport, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
 BluetoothDaemonGattInterface::Disconnect(
-  int aClientIf, const nsAString& aBdAddr, int aConnId,
+  int aClientIf, const BluetoothAddress& aBdAddr, int aConnId,
   BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientDisconnectCmd(
     aClientIf, aBdAddr, aConnId, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
@@ -2389,17 +2380,18 @@ BluetoothDaemonGattInterface::Listen(
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 /* Clear the attribute cache for a given device*/
 void
 BluetoothDaemonGattInterface::Refresh(
-  int aClientIf, const nsAString& aBdAddr, BluetoothGattResultHandler* aRes)
+  int aClientIf, const BluetoothAddress& aBdAddr,
+  BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientRefreshCmd(aClientIf, aBdAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
@@ -2544,61 +2536,61 @@ BluetoothDaemonGattInterface::ExecuteWri
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 /* Register / Deregister Characteristic Notifications or Indications */
 void
 BluetoothDaemonGattInterface::RegisterNotification(
-  int aClientIf, const nsAString& aBdAddr,
+  int aClientIf, const BluetoothAddress& aBdAddr,
   const BluetoothGattServiceId& aServiceId, const BluetoothGattId& aCharId,
   BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientRegisterNotificationCmd(
     aClientIf, aBdAddr, aServiceId, aCharId, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
 BluetoothDaemonGattInterface::DeregisterNotification(
-  int aClientIf, const nsAString& aBdAddr,
+  int aClientIf, const BluetoothAddress& aBdAddr,
   const BluetoothGattServiceId& aServiceId, const BluetoothGattId& aCharId,
   BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientDeregisterNotificationCmd(
     aClientIf, aBdAddr, aServiceId, aCharId, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
 BluetoothDaemonGattInterface::ReadRemoteRssi(
-  int aClientIf, const nsAString& aBdAddr,
+  int aClientIf, const BluetoothAddress& aBdAddr,
   BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientReadRemoteRssiCmd(
     aClientIf, aBdAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
 BluetoothDaemonGattInterface::GetDeviceType(
-  const nsAString& aBdAddr, BluetoothGattResultHandler* aRes)
+  const BluetoothAddress& aBdAddr, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClientGetDeviceTypeCmd(aBdAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
@@ -2663,32 +2655,32 @@ BluetoothDaemonGattInterface::Unregister
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 /* Connect / Disconnect */
 void
 BluetoothDaemonGattInterface::ConnectPeripheral(
-  int aServerIf, const nsAString& aBdAddr, bool aIsDirect, /* auto connect */
+  int aServerIf, const BluetoothAddress& aBdAddr, bool aIsDirect, /* auto connect */
   BluetoothTransport aTransport, BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ServerConnectPeripheralCmd(
     aServerIf, aBdAddr, aIsDirect, aTransport, aRes);
 
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
 BluetoothDaemonGattInterface::DisconnectPeripheral(
-  int aServerIf, const nsAString& aBdAddr, int aConnId,
+  int aServerIf, const BluetoothAddress& aBdAddr, int aConnId,
   BluetoothGattResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ServerDisconnectPeripheralCmd(
     aServerIf, aBdAddr, aConnId, aRes);
 
   if (NS_FAILED(rv)) {
--- a/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonGattInterface.h
@@ -91,34 +91,34 @@ public:
                                BluetoothGattResultHandler* aRes);
 
   /* Start / Stop LE Scan */
   nsresult ClientScanCmd(int aClientIf, bool aStart,
                          BluetoothGattResultHandler* aRes);
 
   /* Connect / Disconnect */
   nsresult ClientConnectCmd(int aClientIf,
-                            const nsAString& aBdAddr,
+                            const BluetoothAddress& aBdAddr,
                             bool aIsDirect, /* auto connect */
                             BluetoothTransport aTransport,
                             BluetoothGattResultHandler* aRes);
 
   nsresult ClientDisconnectCmd(int aClientIf,
-                               const nsAString& aBdAddr,
+                               const BluetoothAddress& aBdAddr,
                                int aConnId,
                                BluetoothGattResultHandler* aRes);
 
   /* Start / Stop advertisements to listen for incoming connections */
   nsresult ClientListenCmd(int aClientIf,
                            bool aIsStart,
                            BluetoothGattResultHandler* aRes);
 
   /* Clear the attribute cache for a given device*/
   nsresult ClientRefreshCmd(int aClientIf,
-                            const nsAString& aBdAddr,
+                            const BluetoothAddress& aBdAddr,
                             BluetoothGattResultHandler* aRes);
 
   /* Enumerate Attributes */
   nsresult ClientSearchServiceCmd(int aConnId,
                                   bool aFiltered,
                                   const BluetoothUuid& aUuid,
                                   BluetoothGattResultHandler* aRes);
 
@@ -180,33 +180,33 @@ public:
   /* Execute / Abort Prepared Write*/
   nsresult ClientExecuteWriteCmd(int aConnId,
                                  int aIsExecute,
                                  BluetoothGattResultHandler* aRes);
 
   /* Register / Deregister Characteristic Notifications or Indications */
   nsresult ClientRegisterNotificationCmd(
     int aClientIf,
-    const nsAString& aBdAddr,
+    const BluetoothAddress& aBdAddr,
     const BluetoothGattServiceId& aServiceId,
     const BluetoothGattId& aCharId,
     BluetoothGattResultHandler* aRes);
 
   nsresult ClientDeregisterNotificationCmd(
     int aClientIf,
-    const nsAString& aBdAddr,
+    const BluetoothAddress& aBdAddr,
     const BluetoothGattServiceId& aServiceId,
     const BluetoothGattId& aCharId,
     BluetoothGattResultHandler* aRes);
 
   nsresult ClientReadRemoteRssiCmd(int aClientIf,
-                                   const nsAString& aBdAddr,
+                                   const BluetoothAddress& aBdAddr,
                                    BluetoothGattResultHandler* aRes);
 
-  nsresult ClientGetDeviceTypeCmd(const nsAString& aBdAddr,
+  nsresult ClientGetDeviceTypeCmd(const BluetoothAddress& aBdAddr,
                                   BluetoothGattResultHandler* aRes);
 
   /* Set advertising data or scan response data */
   nsresult ClientSetAdvDataCmd(int aServerIf,
                                bool aIsScanRsp,
                                bool aIsNameIncluded,
                                bool aIsTxPowerIncluded,
                                int aMinInterval,
@@ -228,24 +228,24 @@ public:
   nsresult ServerRegisterCmd(const BluetoothUuid& aUuid,
                              BluetoothGattResultHandler* aRes);
 
   nsresult ServerUnregisterCmd(int aServerIf,
                                BluetoothGattResultHandler* aRes);
 
   /* Connect / Disconnect */
   nsresult ServerConnectPeripheralCmd(int aServerIf,
-                                      const nsAString& aBdAddr,
+                                      const BluetoothAddress& aBdAddr,
                                       bool aIsDirect,
                                       BluetoothTransport aTransport,
                                       BluetoothGattResultHandler* aRes);
 
   nsresult ServerDisconnectPeripheralCmd(
     int aServerIf,
-    const nsAString& aBdAddr,
+    const BluetoothAddress& aBdAddr,
     int aConnId,
     BluetoothGattResultHandler* aRes);
 
   /* Add a services / a characteristic / a descriptor */
   nsresult ServerAddServiceCmd(int aServerIf,
                                const BluetoothGattServiceId& aServiceId,
                                uint16_t aNumHandles,
                                BluetoothGattResultHandler* aRes);
@@ -484,30 +484,30 @@ protected:
   typedef mozilla::ipc::DaemonNotificationRunnable3<
     NotificationHandlerWrapper, void,
     BluetoothGattStatus, int, BluetoothUuid,
     BluetoothGattStatus, int, const BluetoothUuid&>
     ClientRegisterNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable3<
     NotificationHandlerWrapper, void,
-    nsString, int, BluetoothGattAdvData,
-    const nsAString&, int, const BluetoothGattAdvData&>
+    BluetoothAddress, int, BluetoothGattAdvData,
+    const BluetoothAddress&, int, const BluetoothGattAdvData&>
     ClientScanResultNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable4<
     NotificationHandlerWrapper, void,
-    int, BluetoothGattStatus, int, nsString,
-    int, BluetoothGattStatus, int, const nsAString&>
+    int, BluetoothGattStatus, int, BluetoothAddress,
+    int, BluetoothGattStatus, int, const BluetoothAddress&>
     ClientConnectNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable4<
     NotificationHandlerWrapper, void,
-    int, BluetoothGattStatus, int, nsString,
-    int, BluetoothGattStatus, int, const nsAString&>
+    int, BluetoothGattStatus, int, BluetoothAddress,
+    int, BluetoothGattStatus, int, const BluetoothAddress&>
     ClientDisconnectNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
     NotificationHandlerWrapper, void,
     int, BluetoothGattStatus>
     ClientSearchCompleteNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
@@ -579,35 +579,35 @@ protected:
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
     NotificationHandlerWrapper, void,
     int, BluetoothGattStatus>
     ClientExecuteWriteNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable4<
     NotificationHandlerWrapper, void,
-    int, nsString, int, BluetoothGattStatus,
-    int, const nsAString&, int, BluetoothGattStatus>
+    int, BluetoothAddress, int, BluetoothGattStatus,
+    int, const BluetoothAddress&, int, BluetoothGattStatus>
     ClientReadRemoteRssiNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
     NotificationHandlerWrapper, void,
     BluetoothGattStatus, int>
     ClientListenNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable3<
     NotificationHandlerWrapper, void,
     BluetoothGattStatus, int, BluetoothUuid,
     BluetoothGattStatus, int, const BluetoothUuid&>
     ServerRegisterNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable4<
     NotificationHandlerWrapper, void,
-    int, int, bool, nsString,
-    int, int, bool, const nsAString&>
+    int, int, bool, BluetoothAddress,
+    int, int, bool, const BluetoothAddress&>
     ServerConnectionNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable4<
     NotificationHandlerWrapper, void,
     BluetoothGattStatus, int, BluetoothGattServiceId, BluetoothAttributeHandle,
     BluetoothGattStatus, int, const BluetoothGattServiceId&,
     const BluetoothAttributeHandle&>
     ServerServiceAddedNotification;
@@ -651,32 +651,34 @@ protected:
   typedef mozilla::ipc::DaemonNotificationRunnable3<
     NotificationHandlerWrapper, void,
     BluetoothGattStatus, int, BluetoothAttributeHandle,
     BluetoothGattStatus, int, const BluetoothAttributeHandle&>
     ServerServiceDeletedNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable6<
     NotificationHandlerWrapper, void,
-    int, int, nsString, BluetoothAttributeHandle, int, bool,
-    int, int, const nsAString&, const BluetoothAttributeHandle&, int, bool>
+    int, int, BluetoothAddress, BluetoothAttributeHandle,
+    int, bool,
+    int, int, const BluetoothAddress&, const BluetoothAttributeHandle&,
+    int, bool>
     ServerRequestReadNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable9<
     NotificationHandlerWrapper, void,
-    int, int, nsString, BluetoothAttributeHandle, int, int,
-    nsAutoArrayPtr<uint8_t>, bool, bool,
-    int, int, const nsAString&, const BluetoothAttributeHandle&, int, int,
-    const uint8_t*, bool, bool>
+    int, int, BluetoothAddress, BluetoothAttributeHandle,
+    int, int, nsAutoArrayPtr<uint8_t>, bool, bool,
+    int, int, const BluetoothAddress&, const BluetoothAttributeHandle&,
+    int, int, const uint8_t*, bool, bool>
     ServerRequestWriteNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable4<
     NotificationHandlerWrapper, void,
-    int, int, nsString, bool,
-    int, int, const nsAString&, bool>
+    int, int, BluetoothAddress, bool,
+    int, int, const BluetoothAddress&, bool>
     ServerRequestExecuteWriteNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
     NotificationHandlerWrapper, void,
     BluetoothGattStatus, int>
     ServerResponseConfirmationNotification;
 
   class ClientScanResultInitOp;
@@ -811,33 +813,33 @@ public:
                         BluetoothGattResultHandler* aRes) override;
 
   /* Start / Stop LE Scan */
   void Scan(int aClientIf, bool aStart,
             BluetoothGattResultHandler* aRes) override;
 
   /* Connect / Disconnect */
   void Connect(int aClientIf,
-               const nsAString& aBdAddr,
+               const BluetoothAddress& aBdAddr,
                bool aIsDirect, /* auto connect */
                BluetoothTransport aTransport,
                BluetoothGattResultHandler* aRes) override;
   void Disconnect(int aClientIf,
-                  const nsAString& aBdAddr,
+                  const BluetoothAddress& aBdAddr,
                   int aConnId,
                   BluetoothGattResultHandler* aRes) override;
 
   /* Start / Stop advertisements to listen for incoming connections */
   void Listen(int aClientIf,
               bool aIsStart,
               BluetoothGattResultHandler* aRes) override;
 
   /* Clear the attribute cache for a given device*/
   void Refresh(int aClientIf,
-               const nsAString& aBdAddr,
+               const BluetoothAddress& aBdAddr,
                BluetoothGattResultHandler* aRes) override;
 
   /* Enumerate Attributes */
   void SearchService(int aConnId,
                      bool aSearchAll,
                      const BluetoothUuid& aUuid,
                      BluetoothGattResultHandler* aRes) override;
   void GetIncludedService(int aConnId,
@@ -888,31 +890,31 @@ public:
   /* Execute / Abort Prepared Write*/
   void ExecuteWrite(int aConnId,
                     int aIsExecute,
                     BluetoothGattResultHandler* aRes) override;
 
 
   /* Register / Deregister Characteristic Notifications or Indications */
   void RegisterNotification(int aClientIf,
-                            const nsAString& aBdAddr,
+                            const BluetoothAddress& aBdAddr,
                             const BluetoothGattServiceId& aServiceId,
                             const BluetoothGattId& aCharId,
                             BluetoothGattResultHandler* aRes) override;
   void DeregisterNotification(int aClientIf,
-                              const nsAString& aBdAddr,
+                              const BluetoothAddress& aBdAddr,
                               const BluetoothGattServiceId& aServiceId,
                               const BluetoothGattId& aCharId,
                               BluetoothGattResultHandler* aRes) override;
 
   void ReadRemoteRssi(int aClientIf,
-                      const nsAString& aBdAddr,
+                      const BluetoothAddress& aBdAddr,
                       BluetoothGattResultHandler* aRes) override;
 
-  void GetDeviceType(const nsAString& aBdAddr,
+  void GetDeviceType(const BluetoothAddress& aBdAddr,
                      BluetoothGattResultHandler* aRes) override;
 
   /* Set advertising data or scan response data */
   void SetAdvData(int aServerIf,
                   bool aIsScanRsp,
                   bool aIsNameIncluded,
                   bool aIsTxPowerIncluded,
                   int aMinInterval,
@@ -930,22 +932,22 @@ public:
   /* Register / Unregister */
   void RegisterServer(const BluetoothUuid& aUuid,
                       BluetoothGattResultHandler* aRes) override;
   void UnregisterServer(int aServerIf,
                         BluetoothGattResultHandler* aRes) override;
 
   /* Connect / Disconnect */
   void ConnectPeripheral(int aServerIf,
-                         const nsAString& aBdAddr,
+                         const BluetoothAddress& aBdAddr,
                          bool aIsDirect, /* auto connect */
                          BluetoothTransport aTransport,
                          BluetoothGattResultHandler* aRes) override;
   void DisconnectPeripheral(int aServerIf,
-                            const nsAString& aBdAddr,
+                            const BluetoothAddress& aBdAddr,
                             int aConnId,
                             BluetoothGattResultHandler* aRes) override;
 
   /* Add a services / a characteristic / a descriptor */
   void AddService(int aServerIf,
                   const BluetoothGattServiceId& aServiceId,
                   uint16_t aNumHandles,
                   BluetoothGattResultHandler* aRes) override;
--- a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.cpp
@@ -14,18 +14,18 @@ using namespace mozilla::ipc;
 //
 // Handsfree module
 //
 
 BluetoothHandsfreeNotificationHandler*
   BluetoothDaemonHandsfreeModule::sNotificationHandler;
 
 #if ANDROID_VERSION < 21
-nsString BluetoothDaemonHandsfreeModule::sConnectedDeviceAddress(
-  NS_ConvertUTF8toUTF16(BLUETOOTH_ADDRESS_NONE));
+BluetoothAddress BluetoothDaemonHandsfreeModule::sConnectedDeviceAddress(
+  BluetoothAddress::ANY);
 #endif
 
 void
 BluetoothDaemonHandsfreeModule::SetNotificationHandler(
   BluetoothHandsfreeNotificationHandler* aNotificationHandler)
 {
   sNotificationHandler = aNotificationHandler;
 }
@@ -50,175 +50,168 @@ BluetoothDaemonHandsfreeModule::HandleSv
   (this->*(HandleOp[isNtf]))(aHeader, aPDU, aRes);
 }
 
 // Commands
 //
 
 nsresult
 BluetoothDaemonHandsfreeModule::ConnectCmd(
-  const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
+  const BluetoothAddress& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CONNECT,
                            6)); // Address
 
-  nsresult rv = PackPDU(
-    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), *pdu);
+  nsresult rv = PackPDU(aRemoteAddr, *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonHandsfreeModule::DisconnectCmd(
-  const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
+  const BluetoothAddress& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_DISCONNECT,
                            6)); // Address
 
-  nsresult rv = PackPDU(
-    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), *pdu);
+  nsresult rv = PackPDU(aRemoteAddr, *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonHandsfreeModule::ConnectAudioCmd(
-  const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
+  const BluetoothAddress& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CONNECT_AUDIO,
                            6)); // Address
 
-  nsresult rv = PackPDU(
-    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), *pdu);
+  nsresult rv = PackPDU(aRemoteAddr, *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonHandsfreeModule::DisconnectAudioCmd(
-  const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
+  const BluetoothAddress& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_DISCONNECT_AUDIO,
                            6)); // Address
 
-  nsresult rv = PackPDU(
-    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), *pdu);
+  nsresult rv = PackPDU(aRemoteAddr, *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonHandsfreeModule::StartVoiceRecognitionCmd(
-  const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
+  const BluetoothAddress& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_START_VOICE_RECOGNITION,
                            6)); // Address (BlueZ 5.25)
 
   nsresult rv;
 #if ANDROID_VERSION >= 21
-  rv = PackPDU(
-    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), *pdu);
+  rv = PackPDU(aRemoteAddr, *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
 #endif
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonHandsfreeModule::StopVoiceRecognitionCmd(
-  const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
+  const BluetoothAddress& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_STOP_VOICE_RECOGNITION,
                            6)); // Address (BlueZ 5.25)
 
   nsresult rv;
 #if ANDROID_VERSION >= 21
-  rv = PackPDU(
-    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), *pdu);
+  rv = PackPDU(aRemoteAddr, *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
 #endif
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonHandsfreeModule::VolumeControlCmd(
   BluetoothHandsfreeVolumeType aType, int aVolume,
-  const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
+  const BluetoothAddress& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_VOLUME_CONTROL,
                            1 + // Volume type
                            1 + // Volume
                            6)); // Address (BlueZ 5.25)
 
 #if ANDROID_VERSION >= 21
   nsresult rv = PackPDU(
-    aType, PackConversion<int, uint8_t>(aVolume),
-    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), *pdu);
+    aType, PackConversion<int, uint8_t>(aVolume), aRemoteAddr, *pdu);
 #else
   nsresult rv = PackPDU(aType, PackConversion<int, uint8_t>(aVolume), *pdu);
 #endif
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
@@ -254,30 +247,29 @@ BluetoothDaemonHandsfreeModule::DeviceSt
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonHandsfreeModule::CopsResponseCmd(
-  const char* aCops, const nsAString& aRemoteAddr,
+  const char* aCops, const BluetoothAddress& aRemoteAddr,
   BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_COPS_RESPONSE,
                            0 + // Dynamically allocated
                            6)); // Address (BlueZ 5.25)
 
 #if ANDROID_VERSION >= 21
-  nsresult rv = PackPDU(
-    PackCString0(nsDependentCString(aCops)),
-    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), *pdu);
+  nsresult rv = PackPDU(PackCString0(nsDependentCString(aCops)), aRemoteAddr,
+                        *pdu);
 #else
   nsresult rv = PackPDU(PackCString0(nsDependentCString(aCops)), *pdu);
 #endif
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
@@ -287,17 +279,17 @@ BluetoothDaemonHandsfreeModule::CopsResp
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonHandsfreeModule::CindResponseCmd(
   int aSvc, int aNumActive, int aNumHeld,
   BluetoothHandsfreeCallState aCallSetupState,
   int aSignal, int aRoam, int aBattChg,
-  const nsAString& aRemoteAddr,
+  const BluetoothAddress& aRemoteAddr,
   BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CIND_RESPONSE,
                            1 + // Service
                            1 + // # Active
@@ -312,17 +304,17 @@ BluetoothDaemonHandsfreeModule::CindResp
   nsresult rv = PackPDU(
     PackConversion<int, uint8_t>(aSvc),
     PackConversion<int, uint8_t>(aNumActive),
     PackConversion<int, uint8_t>(aNumHeld),
     aCallSetupState,
     PackConversion<int, uint8_t>(aSignal),
     PackConversion<int, uint8_t>(aRoam),
     PackConversion<int, uint8_t>(aBattChg),
-    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), *pdu);
+    aRemoteAddr, *pdu);
 #else
   nsresult rv = PackPDU(PackConversion<int, uint8_t>(aSvc),
                         PackConversion<int, uint8_t>(aNumActive),
                         PackConversion<int, uint8_t>(aNumHeld),
                         aCallSetupState,
                         PackConversion<int, uint8_t>(aSignal),
                         PackConversion<int, uint8_t>(aRoam),
                         PackConversion<int, uint8_t>(aBattChg), *pdu);
@@ -335,30 +327,29 @@ BluetoothDaemonHandsfreeModule::CindResp
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonHandsfreeModule::FormattedAtResponseCmd(
-  const char* aRsp, const nsAString& aRemoteAddr,
+  const char* aRsp, const BluetoothAddress& aRemoteAddr,
   BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_FORMATTED_AT_RESPONSE,
                            0 + // Dynamically allocated
                            6)); // Address (BlueZ 5.25)
 
 #if ANDROID_VERSION >= 21
-  nsresult rv = PackPDU(
-    PackCString0(nsDependentCString(aRsp)),
-    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), *pdu);
+  nsresult rv = PackPDU(PackCString0(nsDependentCString(aRsp)), aRemoteAddr,
+                                     *pdu);
 #else
   nsresult rv = PackPDU(PackCString0(nsDependentCString(aRsp)), *pdu);
 #endif
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
@@ -366,30 +357,30 @@ BluetoothDaemonHandsfreeModule::Formatte
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonHandsfreeModule::AtResponseCmd(
   BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode,
-  const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
+  const BluetoothAddress& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_AT_RESPONSE,
                            1 + // AT Response code
                            1 + // Error code
                            6)); // Address (BlueZ 5.25)
 
 #if ANDROID_VERSION >= 21
-  nsresult rv = PackPDU(
-    aResponseCode, PackConversion<int, uint8_t>(aErrorCode),
-    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), *pdu);
+  nsresult rv = PackPDU(aResponseCode,
+                        PackConversion<int, uint8_t>(aErrorCode),
+                        aRemoteAddr, *pdu);
 #else
   nsresult rv = PackPDU(aResponseCode,
                         PackConversion<int, uint8_t>(aErrorCode), *pdu);
 #endif
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
@@ -401,17 +392,17 @@ BluetoothDaemonHandsfreeModule::AtRespon
 }
 
 nsresult
 BluetoothDaemonHandsfreeModule::ClccResponseCmd(
   int aIndex,
   BluetoothHandsfreeCallDirection aDir, BluetoothHandsfreeCallState aState,
   BluetoothHandsfreeCallMode aMode, BluetoothHandsfreeCallMptyType aMpty,
   const nsAString& aNumber, BluetoothHandsfreeCallAddressType aType,
-  const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
+  const BluetoothAddress& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   NS_ConvertUTF16toUTF8 number(aNumber);
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CLCC_RESPONSE,
                            1 + // Call index
@@ -419,21 +410,19 @@ BluetoothDaemonHandsfreeModule::ClccResp
                            1 + // Call state
                            1 + // Call mode
                            1 + // Call MPTY
                            1 + // Address type
                            number.Length() + 1 + // Number string + \0
                            6)); // Address (BlueZ 5.25)
 
 #if ANDROID_VERSION >= 21
-  nsresult rv = PackPDU(
-    PackConversion<int, uint8_t>(aIndex),
-    aDir, aState, aMode, aMpty, aType,
-    PackCString0(number),
-    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), *pdu);
+  nsresult rv = PackPDU(PackConversion<int, uint8_t>(aIndex),
+                        aDir, aState, aMode, aMpty, aType,
+                        PackCString0(number), aRemoteAddr, *pdu);
 #else
   nsresult rv = PackPDU(PackConversion<int, uint8_t>(aIndex),
                         aDir, aState, aMode, aMpty, aType,
                         PackCString0(number), *pdu);
 #endif
   if (NS_FAILED(rv)) {
     return rv;
   }
@@ -475,29 +464,28 @@ BluetoothDaemonHandsfreeModule::PhoneSta
     return rv;
   }
   unused << pdu.forget();
   return NS_OK;
 }
 
 nsresult
 BluetoothDaemonHandsfreeModule::ConfigureWbsCmd(
-  const nsAString& aRemoteAddr,
+  const BluetoothAddress& aRemoteAddr,
   BluetoothHandsfreeWbsConfig aConfig,
   BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CONFIGURE_WBS,
                            6 + // Address
                            1)); // Config
 
-  nsresult rv = PackPDU(
-    PackConversion<nsAString, BluetoothAddress>(aRemoteAddr), aConfig, *pdu);
+  nsresult rv = PackPDU(aRemoteAddr, aConfig, *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
@@ -747,38 +735,37 @@ class BluetoothDaemonHandsfreeModule::Co
 {
 public:
   ConnectionStateInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
   operator () (BluetoothHandsfreeConnectionState& aArg1,
-               nsString& aArg2) const
+               BluetoothAddress& aArg2) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read state */
     nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     /* Read address */
-    rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
+    rv = UnpackPDU(pdu, aArg2);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
 #if ANDROID_VERSION < 21
     if (aArg1 == HFP_CONNECTION_STATE_CONNECTED) {
       sConnectedDeviceAddress = aArg2;
     } else if (aArg1 == HFP_CONNECTION_STATE_DISCONNECTED) {
-      sConnectedDeviceAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
+      sConnectedDeviceAddress = BluetoothAddress::ANY;
     }
 #endif
     WarnAboutTrailingData();
     return NS_OK;
   }
 };
 
 void
@@ -795,29 +782,29 @@ class BluetoothDaemonHandsfreeModule::Au
   : private PDUInitOp
 {
 public:
   AudioStateInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (BluetoothHandsfreeAudioState& aArg1, nsString& aArg2) const
+  operator () (BluetoothHandsfreeAudioState& aArg1,
+               BluetoothAddress& aArg2) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read state */
     nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     /* Read address */
-    rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
+    rv = UnpackPDU(pdu, aArg2);
     if (NS_FAILED(rv)) {
       return rv;
     }
     WarnAboutTrailingData();
     return NS_OK;
   }
 };
 
@@ -836,30 +823,29 @@ class BluetoothDaemonHandsfreeModule::Vo
 {
 public:
   VoiceRecognitionInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
   operator () (BluetoothHandsfreeVoiceRecognitionState& aArg1,
-               nsString& aArg2) const
+               BluetoothAddress& aArg2) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read state */
     nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     /* Read address */
 #if ANDROID_VERSION >= 21
-    rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
+    rv = UnpackPDU(pdu, aArg2);
     if (NS_FAILED(rv)) {
       return rv;
     }
 #else
     aArg2 = sConnectedDeviceAddress;
 #endif
     WarnAboutTrailingData();
     return NS_OK;
@@ -880,22 +866,21 @@ class BluetoothDaemonHandsfreeModule::An
   : private PDUInitOp
 {
 public:
   AnswerCallInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (nsString& aArg1) const
+  operator () (BluetoothAddress& aArg1) const
   {
     /* Read address */
 #if ANDROID_VERSION >= 21
-    nsresult rv = UnpackPDU(
-      GetPDU(), UnpackConversion<BluetoothAddress, nsAString>(aArg1));
+    nsresult rv = UnpackPDU(GetPDU(), aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 #else
     aArg1 = sConnectedDeviceAddress;
 #endif
     WarnAboutTrailingData();
     return NS_OK;
@@ -916,22 +901,21 @@ class BluetoothDaemonHandsfreeModule::Ha
   : private PDUInitOp
 {
 public:
   HangupCallInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (nsString& aArg1) const
+  operator () (BluetoothAddress& aArg1) const
   {
     /* Read address */
 #if ANDROID_VERSION >= 21
-    nsresult rv = UnpackPDU(
-      GetPDU(), UnpackConversion<BluetoothAddress, nsAString>(aArg1));
+    nsresult rv = UnpackPDU(GetPDU(), aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 #else
     aArg1 = sConnectedDeviceAddress;
 #endif
     WarnAboutTrailingData();
     return NS_OK;
@@ -953,17 +937,17 @@ class BluetoothDaemonHandsfreeModule::Vo
 {
 public:
   VolumeInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
   operator () (BluetoothHandsfreeVolumeType& aArg1, int& aArg2,
-               nsString& aArg3) const
+               BluetoothAddress& aArg3) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read volume type */
     nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
@@ -971,18 +955,17 @@ public:
     /* Read volume */
     rv = UnpackPDU(pdu, UnpackConversion<uint8_t, int>(aArg2));
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     /* Read address */
 #if ANDROID_VERSION >= 21
-    rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg3));
+    rv = UnpackPDU(pdu, aArg3);
     if (NS_FAILED(rv)) {
       return rv;
     }
 #else
     aArg3 = sConnectedDeviceAddress;
 #endif
     WarnAboutTrailingData();
     return NS_OK;
@@ -1003,28 +986,27 @@ class BluetoothDaemonHandsfreeModule::Di
   : private PDUInitOp
 {
 public:
   DialCallInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (nsString& aArg1, nsString& aArg2) const
+  operator () (nsString& aArg1, BluetoothAddress& aArg2) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     nsresult rv;
     /* Read address
-     * It's a little weird to parse aArg2(aBdAddr) before parsing
-     * aArg1(aNumber), but this order is defined in BlueZ 5.25 anyway.
+     * It's a little weird to parse aArg2 (aBdAddr) before parsing
+     * aArg1 (aNumber), but this order is defined in BlueZ 5.25 anyway.
      */
 #if ANDROID_VERSION >= 21
-    rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
+    rv = UnpackPDU( pdu, aArg2);
     if (NS_FAILED(rv)) {
       return rv;
     }
 #else
     aArg2 = sConnectedDeviceAddress;
 #endif
 
     /* Read number */
@@ -1051,30 +1033,29 @@ class BluetoothDaemonHandsfreeModule::Dt
   : private PDUInitOp
 {
 public:
   DtmfInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (char& aArg1, nsString& aArg2) const
+  operator () (char& aArg1, BluetoothAddress& aArg2) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read tone */
     nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     /* Read address */
 #if ANDROID_VERSION >= 21
-    rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
+    rv = UnpackPDU(pdu, aArg2);
     if (NS_FAILED(rv)) {
       return rv;
     }
 #else
     aArg2 = sConnectedDeviceAddress;
 #endif
     WarnAboutTrailingData();
     return NS_OK;
@@ -1095,30 +1076,30 @@ class BluetoothDaemonHandsfreeModule::NR
   : private PDUInitOp
 {
 public:
   NRECInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (BluetoothHandsfreeNRECState& aArg1, nsString& aArg2) const
+  operator () (BluetoothHandsfreeNRECState& aArg1,
+               BluetoothAddress& aArg2) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read state */
     nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     /* Read address */
 #if ANDROID_VERSION >= 21
-    rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
+    rv = UnpackPDU(pdu, aArg2);
     if (NS_FAILED(rv)) {
       return rv;
     }
 #else
     aArg2 = sConnectedDeviceAddress;
 #endif
     WarnAboutTrailingData();
     return NS_OK;
@@ -1139,30 +1120,30 @@ class BluetoothDaemonHandsfreeModule::Ca
   : private PDUInitOp
 {
 public:
   CallHoldInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (BluetoothHandsfreeCallHoldType& aArg1, nsString& aArg2) const
+  operator () (BluetoothHandsfreeCallHoldType& aArg1,
+               BluetoothAddress& aArg2) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read type */
     nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     /* Read address */
 #if ANDROID_VERSION >= 21
-    rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
+    rv = UnpackPDU(pdu, aArg2);
     if (NS_FAILED(rv)) {
       return rv;
     }
 #else
     aArg2 = sConnectedDeviceAddress;
 #endif
     WarnAboutTrailingData();
     return NS_OK;
@@ -1183,22 +1164,21 @@ class BluetoothDaemonHandsfreeModule::Cn
   : private PDUInitOp
 {
 public:
   CnumInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (nsString& aArg1) const
+  operator () (BluetoothAddress& aArg1) const
   {
     /* Read address */
 #if ANDROID_VERSION >= 21
-    nsresult rv = UnpackPDU(
-      GetPDU(), UnpackConversion<BluetoothAddress, nsAString>(aArg1));
+    nsresult rv = UnpackPDU(GetPDU(), aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 #else
     aArg1 = sConnectedDeviceAddress;
 #endif
     WarnAboutTrailingData();
     return NS_OK;
@@ -1219,22 +1199,21 @@ class BluetoothDaemonHandsfreeModule::Ci
   : private PDUInitOp
 {
 public:
   CindInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (nsString& aArg1) const
+  operator () (BluetoothAddress& aArg1) const
   {
     /* Read address */
 #if ANDROID_VERSION >= 21
-    nsresult rv = UnpackPDU(
-      GetPDU(), UnpackConversion<BluetoothAddress, nsAString>(aArg1));
+    nsresult rv = UnpackPDU(GetPDU(), aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 #else
     aArg1 = sConnectedDeviceAddress;
 #endif
     WarnAboutTrailingData();
     return NS_OK;
@@ -1255,22 +1234,21 @@ class BluetoothDaemonHandsfreeModule::Co
   : private PDUInitOp
 {
 public:
   CopsInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (nsString& aArg1) const
+  operator () (BluetoothAddress& aArg1) const
   {
     /* Read address */
 #if ANDROID_VERSION >= 21
-    nsresult rv = UnpackPDU(
-      GetPDU(), UnpackConversion<BluetoothAddress, nsAString>(aArg1));
+    nsresult rv = UnpackPDU(GetPDU(), aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 #else
     aArg1 = sConnectedDeviceAddress;
 #endif
     WarnAboutTrailingData();
     return NS_OK;
@@ -1291,22 +1269,21 @@ class BluetoothDaemonHandsfreeModule::Cl
   : private PDUInitOp
 {
 public:
   ClccInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (nsString& aArg1) const
+  operator () (BluetoothAddress& aArg1) const
   {
     /* Read address */
 #if ANDROID_VERSION >= 21
-    nsresult rv = UnpackPDU(
-      GetPDU(), UnpackConversion<BluetoothAddress, nsAString>(aArg1));
+    nsresult rv = UnpackPDU(GetPDU(), aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 #else
     aArg1 = sConnectedDeviceAddress;
 #endif
     WarnAboutTrailingData();
     return NS_OK;
@@ -1327,28 +1304,27 @@ class BluetoothDaemonHandsfreeModule::Un
   : private PDUInitOp
 {
 public:
   UnknownAtInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (nsCString& aArg1, nsString& aArg2) const
+  operator () (nsCString& aArg1, BluetoothAddress& aArg2) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     nsresult rv;
     /* Read address
      * It's a little weird to parse aArg2(aBdAddr) before parsing
      * aArg1(aAtString), but this order is defined in BlueZ 5.25 anyway.
      */
 #if ANDROID_VERSION >= 21
-    rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
+    rv = UnpackPDU(pdu, aArg2);
     if (NS_FAILED(rv)) {
       return rv;
     }
 #else
     aArg2 = sConnectedDeviceAddress;
 #endif
 
     /* Read string */
@@ -1375,22 +1351,21 @@ class BluetoothDaemonHandsfreeModule::Ke
   : private PDUInitOp
 {
 public:
   KeyPressedInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (nsString& aArg1) const
+  operator () (BluetoothAddress& aArg1) const
   {
     /* Read address */
 #if ANDROID_VERSION >= 21
-    nsresult rv = UnpackPDU(
-      GetPDU(), UnpackConversion<BluetoothAddress, nsAString>(aArg1));
+    nsresult rv = UnpackPDU(GetPDU(), aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 #else
     aArg1 = sConnectedDeviceAddress;
 #endif
     WarnAboutTrailingData();
     return NS_OK;
@@ -1411,29 +1386,28 @@ class BluetoothDaemonHandsfreeModule::Wb
   : private PDUInitOp
 {
 public:
   WbsInitOp(DaemonSocketPDU& aPDU)
     : PDUInitOp(aPDU)
   { }
 
   nsresult
-  operator () (BluetoothHandsfreeWbsConfig& aArg1, nsString& aArg2) const
+  operator () (BluetoothHandsfreeWbsConfig& aArg1, BluetoothAddress& aArg2) const
   {
     DaemonSocketPDU& pdu = GetPDU();
 
     /* Read state */
     nsresult rv = UnpackPDU(pdu, aArg1);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     /* Read address */
-    rv = UnpackPDU(
-      pdu, UnpackConversion<BluetoothAddress, nsAString>(aArg2));
+    rv = UnpackPDU(pdu, aArg2);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     WarnAboutTrailingData();
     return NS_OK;
   }
 };
@@ -1607,93 +1581,94 @@ BluetoothDaemonHandsfreeInterface::Clean
     DispatchError(aRes, rv);
   }
 }
 
 /* Connect / Disconnect */
 
 void
 BluetoothDaemonHandsfreeInterface::Connect(
-  const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
+  const BluetoothAddress& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ConnectCmd(aBdAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
 BluetoothDaemonHandsfreeInterface::Disconnect(
-  const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
+  const BluetoothAddress& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->DisconnectCmd(aBdAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
 BluetoothDaemonHandsfreeInterface::ConnectAudio(
-  const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
+  const BluetoothAddress& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ConnectAudioCmd(aBdAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
 BluetoothDaemonHandsfreeInterface::DisconnectAudio(
-  const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
+  const BluetoothAddress& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->DisconnectAudioCmd(aBdAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 /* Voice Recognition */
 
 void
 BluetoothDaemonHandsfreeInterface::StartVoiceRecognition(
-  const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
+  const BluetoothAddress& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->StartVoiceRecognitionCmd(aBdAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
 BluetoothDaemonHandsfreeInterface::StopVoiceRecognition(
-  const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
+  const BluetoothAddress& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->StopVoiceRecognitionCmd(aBdAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 /* Volume */
 
 void
 BluetoothDaemonHandsfreeInterface::VolumeControl(
-  BluetoothHandsfreeVolumeType aType, int aVolume, const nsAString& aBdAddr,
+  BluetoothHandsfreeVolumeType aType, int aVolume,
+  const BluetoothAddress& aBdAddr,
   BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->VolumeControlCmd(aType, aVolume, aBdAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
@@ -1716,61 +1691,61 @@ BluetoothDaemonHandsfreeInterface::Devic
     DispatchError(aRes, rv);
   }
 }
 
 /* Responses */
 
 void
 BluetoothDaemonHandsfreeInterface::CopsResponse(
-  const char* aCops, const nsAString& aBdAddr,
+  const char* aCops, const BluetoothAddress& aBdAddr,
   BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->CopsResponseCmd(aCops, aBdAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
 BluetoothDaemonHandsfreeInterface::CindResponse(
   int aSvc, int aNumActive, int aNumHeld,
   BluetoothHandsfreeCallState aCallSetupState,
   int aSignal, int aRoam, int aBattChg,
-  const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
+  const BluetoothAddress& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->CindResponseCmd(aSvc, aNumActive, aNumHeld,
                                          aCallSetupState, aSignal,
                                          aRoam, aBattChg, aBdAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
 BluetoothDaemonHandsfreeInterface::FormattedAtResponse(
-  const char* aRsp, const nsAString& aBdAddr,
+  const char* aRsp, const BluetoothAddress& aBdAddr,
   BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->FormattedAtResponseCmd(aRsp, aBdAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
 BluetoothDaemonHandsfreeInterface::AtResponse(
   BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode,
-  const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
+  const BluetoothAddress& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->AtResponseCmd(aResponseCode, aErrorCode,
                                        aBdAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
@@ -1779,17 +1754,17 @@ BluetoothDaemonHandsfreeInterface::AtRes
 void
 BluetoothDaemonHandsfreeInterface::ClccResponse(
   int aIndex, BluetoothHandsfreeCallDirection aDir,
   BluetoothHandsfreeCallState aState,
   BluetoothHandsfreeCallMode aMode,
   BluetoothHandsfreeCallMptyType aMpty,
   const nsAString& aNumber,
   BluetoothHandsfreeCallAddressType aType,
-  const nsAString& aBdAddr,
+  const BluetoothAddress& aBdAddr,
   BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ClccResponseCmd(aIndex, aDir, aState, aMode, aMpty,
                                          aNumber, aType, aBdAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
@@ -1815,17 +1790,17 @@ BluetoothDaemonHandsfreeInterface::Phone
     DispatchError(aRes, rv);
   }
 }
 
 /* Wide Band Speech */
 
 void
 BluetoothDaemonHandsfreeInterface::ConfigureWbs(
-  const nsAString& aBdAddr, BluetoothHandsfreeWbsConfig aConfig,
+  const BluetoothAddress& aBdAddr, BluetoothHandsfreeWbsConfig aConfig,
   BluetoothHandsfreeResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
   nsresult rv = mModule->ConfigureWbsCmd(aBdAddr, aConfig, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
--- a/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonHandsfreeInterface.h
@@ -55,80 +55,81 @@ public:
 
   void SetNotificationHandler(
     BluetoothHandsfreeNotificationHandler* aNotificationHandler);
 
   //
   // Commands
   //
 
-  nsresult ConnectCmd(const nsAString& aBdAddr,
+  nsresult ConnectCmd(const BluetoothAddress& aBdAddr,
                       BluetoothHandsfreeResultHandler* aRes);
-  nsresult DisconnectCmd(const nsAString& aBdAddr,
+  nsresult DisconnectCmd(const BluetoothAddress& aBdAddr,
                          BluetoothHandsfreeResultHandler* aRes);
-  nsresult ConnectAudioCmd(const nsAString& aBdAddr,
+  nsresult ConnectAudioCmd(const BluetoothAddress& aBdAddr,
                            BluetoothHandsfreeResultHandler* aRes);
-  nsresult DisconnectAudioCmd(const nsAString& aBdAddr,
+  nsresult DisconnectAudioCmd(const BluetoothAddress& aBdAddr,
                               BluetoothHandsfreeResultHandler* aRes);
 
   /* Voice Recognition */
 
-  nsresult StartVoiceRecognitionCmd(const nsAString& aBdAddr,
+  nsresult StartVoiceRecognitionCmd(const BluetoothAddress& aBdAddr,
                                     BluetoothHandsfreeResultHandler* aRes);
-  nsresult StopVoiceRecognitionCmd(const nsAString& aBdAddr,
+  nsresult StopVoiceRecognitionCmd(const BluetoothAddress& aBdAddr,
                                    BluetoothHandsfreeResultHandler* aRes);
 
   /* Volume */
 
   nsresult VolumeControlCmd(BluetoothHandsfreeVolumeType aType, int aVolume,
-                            const nsAString& aBdAddr,
+                            const BluetoothAddress& aBdAddr,
                             BluetoothHandsfreeResultHandler* aRes);
 
   /* Device status */
 
   nsresult DeviceStatusNotificationCmd(
     BluetoothHandsfreeNetworkState aNtkState,
     BluetoothHandsfreeServiceType aSvcType,
     int aSignal, int aBattChg,
     BluetoothHandsfreeResultHandler* aRes);
 
   /* Responses */
 
-  nsresult CopsResponseCmd(const char* aCops, const nsAString& aBdAddr,
+  nsresult CopsResponseCmd(const char* aCops, const BluetoothAddress& aBdAddr,
                            BluetoothHandsfreeResultHandler* aRes);
   nsresult CindResponseCmd(int aSvc, int aNumActive, int aNumHeld,
                            BluetoothHandsfreeCallState aCallSetupState,
                            int aSignal, int aRoam, int aBattChg,
-                           const nsAString& aBdAddr,
+                           const BluetoothAddress& aBdAddr,
                            BluetoothHandsfreeResultHandler* aRes);
-  nsresult FormattedAtResponseCmd(const char* aRsp, const nsAString& aBdAddr,
+  nsresult FormattedAtResponseCmd(const char* aRsp,
+                                  const BluetoothAddress& aBdAddr,
                                   BluetoothHandsfreeResultHandler* aRes);
   nsresult AtResponseCmd(BluetoothHandsfreeAtResponse aResponseCode,
-                         int aErrorCode, const nsAString& aBdAddr,
+                         int aErrorCode, const BluetoothAddress& aBdAddr,
                          BluetoothHandsfreeResultHandler* aRes);
   nsresult ClccResponseCmd(int aIndex, BluetoothHandsfreeCallDirection aDir,
                            BluetoothHandsfreeCallState aState,
                            BluetoothHandsfreeCallMode aMode,
                            BluetoothHandsfreeCallMptyType aMpty,
                            const nsAString& aNumber,
                            BluetoothHandsfreeCallAddressType aType,
-                           const nsAString& aBdAddr,
+                           const BluetoothAddress& aBdAddr,
                            BluetoothHandsfreeResultHandler* aRes);
 
   /* Phone State */
 
   nsresult PhoneStateChangeCmd(int aNumActive, int aNumHeld,
                                BluetoothHandsfreeCallState aCallSetupState,
                                const nsAString& aNumber,
                                BluetoothHandsfreeCallAddressType aType,
                                BluetoothHandsfreeResultHandler* aRes);
 
   /* Wide Band Speech */
 
-  nsresult ConfigureWbsCmd(const nsAString& aBdAddr,
+  nsresult ConfigureWbsCmd(const BluetoothAddress& aBdAddr,
                            BluetoothHandsfreeWbsConfig aConfig,
                            BluetoothHandsfreeResultHandler* aRes);
 
 protected:
   void HandleSvc(const DaemonSocketPDUHeader& aHeader,
                  DaemonSocketPDU& aPDU,
                  DaemonSocketResultHandler* aRes);
 
@@ -214,90 +215,107 @@ protected:
 
   //
   // Notifications
   //
 
   class NotificationHandlerWrapper;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
-    NotificationHandlerWrapper, void, BluetoothHandsfreeConnectionState,
-    nsString, BluetoothHandsfreeConnectionState, const nsAString&>
+    NotificationHandlerWrapper, void,
+    BluetoothHandsfreeConnectionState, BluetoothAddress,
+    BluetoothHandsfreeConnectionState, const BluetoothAddress&>
     ConnectionStateNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
-    NotificationHandlerWrapper, void, BluetoothHandsfreeAudioState,
-    nsString, BluetoothHandsfreeAudioState, const nsAString&>
+    NotificationHandlerWrapper, void,
+    BluetoothHandsfreeAudioState, BluetoothAddress,
+    BluetoothHandsfreeAudioState, const BluetoothAddress&>
     AudioStateNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
-    NotificationHandlerWrapper, void, BluetoothHandsfreeVoiceRecognitionState,
-    nsString, BluetoothHandsfreeVoiceRecognitionState, const nsAString&>
+    NotificationHandlerWrapper, void,
+    BluetoothHandsfreeVoiceRecognitionState, BluetoothAddress,
+    BluetoothHandsfreeVoiceRecognitionState, const BluetoothAddress&>
     VoiceRecognitionNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable1<
-    NotificationHandlerWrapper, void, nsString, const nsAString&>
+    NotificationHandlerWrapper, void,
+    BluetoothAddress, const BluetoothAddress&>
     AnswerCallNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable1<
-    NotificationHandlerWrapper, void, nsString, const nsAString&>
+    NotificationHandlerWrapper, void,
+    BluetoothAddress, const BluetoothAddress&>
     HangupCallNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable3<
-    NotificationHandlerWrapper, void, BluetoothHandsfreeVolumeType,
-    int, nsString, BluetoothHandsfreeVolumeType, int, const nsAString&>
+    NotificationHandlerWrapper, void,
+    BluetoothHandsfreeVolumeType, int, BluetoothAddress,
+    BluetoothHandsfreeVolumeType, int, const BluetoothAddress&>
     VolumeNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
-    NotificationHandlerWrapper, void, nsString, nsString, const nsAString&,
-    const nsAString&>
+    NotificationHandlerWrapper, void,
+    nsString, BluetoothAddress,
+    const nsAString&, const BluetoothAddress&>
     DialCallNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
-    NotificationHandlerWrapper, void, char, nsString, char, const nsAString&>
+    NotificationHandlerWrapper, void,
+    char, BluetoothAddress, char, const BluetoothAddress&>
     DtmfNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
-    NotificationHandlerWrapper, void, BluetoothHandsfreeNRECState, nsString,
-    BluetoothHandsfreeNRECState, const nsAString&>
+    NotificationHandlerWrapper, void,
+    BluetoothHandsfreeNRECState, BluetoothAddress,
+    BluetoothHandsfreeNRECState, const BluetoothAddress&>
     NRECNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
-    NotificationHandlerWrapper, void, BluetoothHandsfreeCallHoldType,
-    nsString, BluetoothHandsfreeCallHoldType, const nsAString&>
+    NotificationHandlerWrapper, void,
+    BluetoothHandsfreeCallHoldType, BluetoothAddress,
+    BluetoothHandsfreeCallHoldType, const BluetoothAddress&>
     CallHoldNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable1<
-    NotificationHandlerWrapper, void, nsString, const nsAString&>
+    NotificationHandlerWrapper, void,
+    BluetoothAddress, const BluetoothAddress&>
     CnumNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable1<
-    NotificationHandlerWrapper, void, nsString, const nsAString&>
+    NotificationHandlerWrapper, void,
+    BluetoothAddress, const BluetoothAddress&>
     CindNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable1<
-    NotificationHandlerWrapper, void, nsString, const nsAString&>
+    NotificationHandlerWrapper, void,
+    BluetoothAddress, const BluetoothAddress&>
     CopsNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable1<
-    NotificationHandlerWrapper, void, nsString, const nsAString&>
+    NotificationHandlerWrapper, void,
+    BluetoothAddress, const BluetoothAddress&>
     ClccNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
-    NotificationHandlerWrapper, void, nsCString, nsString,
-    const nsACString&, const nsAString&>
+    NotificationHandlerWrapper, void,
+    nsCString, BluetoothAddress,
+    const nsACString&, const BluetoothAddress&>
     UnknownAtNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable1<
-    NotificationHandlerWrapper, void, nsString, const nsAString&>
+    NotificationHandlerWrapper, void,
+    BluetoothAddress, const BluetoothAddress&>
     KeyPressedNotification;
 
   typedef mozilla::ipc::DaemonNotificationRunnable2<
-    NotificationHandlerWrapper, void, BluetoothHandsfreeWbsConfig, nsString,
-    BluetoothHandsfreeWbsConfig, const nsAString&>
+    NotificationHandlerWrapper, void,
+    BluetoothHandsfreeWbsConfig, BluetoothAddress,
+    BluetoothHandsfreeWbsConfig, const BluetoothAddress&>
     WbsNotification;
 
   class ConnectionStateInitOp;
   class AudioStateInitOp;
   class VoiceRecognitionInitOp;
   class AnswerCallInitOp;
   class HangupCallInitOp;
   class VolumeInitOp;
@@ -367,21 +385,22 @@ protected:
 
   void HandleNtf(const DaemonSocketPDUHeader& aHeader,
                  DaemonSocketPDU& aPDU,
                  DaemonSocketResultHandler* aRes);
 
   static BluetoothHandsfreeNotificationHandler* sNotificationHandler;
 #if ANDROID_VERSION < 21
   /* |sConnectedDeviceAddress| stores Bluetooth device address of the
-   * connected device. Before BlueZ 5.25, we maintain this address by ourselves
-   * through ConnectionStateNtf(); after BlueZ 5.25, every callback carries
-   * this address directly so we don't have to keep it.
+   * connected device. Before BlueZ 5.25, we maintain this address by
+   * ourselves through ConnectionStateNtf(); after BlueZ 5.25, every
+   * callback carries this address directly so we don't have to keep
+   * it.
    */
-  static nsString sConnectedDeviceAddress;
+  static BluetoothAddress sConnectedDeviceAddress;
 #endif
 };
 
 class BluetoothDaemonHandsfreeInterface final
   : public BluetoothHandsfreeInterface
 {
   class CleanupResultHandler;
   class InitResultHandler;
@@ -398,78 +417,78 @@ public:
 
   void Init(
     BluetoothHandsfreeNotificationHandler* aNotificationHandler,
     int aMaxNumClients, BluetoothHandsfreeResultHandler* aRes) override;
   void Cleanup(BluetoothHandsfreeResultHandler* aRes) override;
 
   /* Connect / Disconnect */
 
-  void Connect(const nsAString& aBdAddr,
+  void Connect(const BluetoothAddress& aBdAddr,
                BluetoothHandsfreeResultHandler* aRes) override;
-  void Disconnect(const nsAString& aBdAddr,
+  void Disconnect(const BluetoothAddress& aBdAddr,
                   BluetoothHandsfreeResultHandler* aRes) override;
-  void ConnectAudio(const nsAString& aBdAddr,
+  void ConnectAudio(const BluetoothAddress& aBdAddr,
                     BluetoothHandsfreeResultHandler* aRes) override;
-  void DisconnectAudio(const nsAString& aBdAddr,
+  void DisconnectAudio(const BluetoothAddress& aBdAddr,
                        BluetoothHandsfreeResultHandler* aRes) override;
 
   /* Voice Recognition */
 
-  void StartVoiceRecognition(const nsAString& aBdAddr,
+  void StartVoiceRecognition(const BluetoothAddress& aBdAddr,
                              BluetoothHandsfreeResultHandler* aRes) override;
-  void StopVoiceRecognition(const nsAString& aBdAddr,
+  void StopVoiceRecognition(const BluetoothAddress& aBdAddr,
                             BluetoothHandsfreeResultHandler* aRes) override;
 
   /* Volume */
 
   void VolumeControl(BluetoothHandsfreeVolumeType aType, int aVolume,
-                     const nsAString& aBdAddr,
+                     const BluetoothAddress& aBdAddr,
                      BluetoothHandsfreeResultHandler* aRes) override;
 
   /* Device status */
 
   void DeviceStatusNotification(BluetoothHandsfreeNetworkState aNtkState,
                                 BluetoothHandsfreeServiceType aSvcType,
                                 int aSignal, int aBattChg,
                                 BluetoothHandsfreeResultHandler* aRes) override;
 
   /* Responses */
 
-  void CopsResponse(const char* aCops, const nsAString& aBdAddr,
+  void CopsResponse(const char* aCops, const BluetoothAddress& aBdAddr,
                     BluetoothHandsfreeResultHandler* aRes);
   void CindResponse(int aSvc, int aNumActive, int aNumHeld,
                     BluetoothHandsfreeCallState aCallSetupState,
                     int aSignal, int aRoam, int aBattChg,
-                    const nsAString& aBdAddr,
+                    const BluetoothAddress& aBdAddr,
                     BluetoothHandsfreeResultHandler* aRes) override;
-  void FormattedAtResponse(const char* aRsp, const nsAString& aBdAddr,
+  void FormattedAtResponse(const char* aRsp, const BluetoothAddress& aBdAddr,
                            BluetoothHandsfreeResultHandler* aRes) override;
   void AtResponse(BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode,
-                  const nsAString& aBdAddr,
+                  const BluetoothAddress& aBdAddr,
                   BluetoothHandsfreeResultHandler* aRes) override;
   void ClccResponse(int aIndex, BluetoothHandsfreeCallDirection aDir,
                     BluetoothHandsfreeCallState aState,
                     BluetoothHandsfreeCallMode aMode,
                     BluetoothHandsfreeCallMptyType aMpty,
                     const nsAString& aNumber,
                     BluetoothHandsfreeCallAddressType aType,
-                    const nsAString& aBdAddr,
+                    const BluetoothAddress& aBdAddr,
                     BluetoothHandsfreeResultHandler* aRes) override;
 
   /* Phone State */
 
   void PhoneStateChange(int aNumActive, int aNumHeld,
                         BluetoothHandsfreeCallState aCallSetupState,
                         const nsAString& aNumber,
                         BluetoothHandsfreeCallAddressType aType,
                         BluetoothHandsfreeResultHandler* aRes) override;
 
   /* Wide Band Speech */
-  void ConfigureWbs(const nsAString& aBdAddr,
+  void ConfigureWbs(const BluetoothAddress& aBdAddr,
                     BluetoothHandsfreeWbsConfig aConfig,
                     BluetoothHandsfreeResultHandler* aRes) override;
 
 private:
   void DispatchError(BluetoothHandsfreeResultHandler* aRes,
                      BluetoothStatus aStatus);
   void DispatchError(BluetoothHandsfreeResultHandler* aRes, nsresult aRv);
 
--- a/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.cpp
@@ -509,30 +509,16 @@ Convert(int32_t aIn, BluetoothGattStatus
     aOut = GATT_STATUS_UNKNOWN_ERROR;
   } else {
     aOut = sGattStatus[aIn];
   }
   return NS_OK;
 }
 
 nsresult
-Convert(const nsAString& aIn, BluetoothAddress& aOut)
-{
-  NS_ConvertUTF16toUTF8 bdAddressUTF8(aIn);
-  const char* str = bdAddressUTF8.get();
-
-  for (size_t i = 0; i < MOZ_ARRAY_LENGTH(aOut.mAddr); ++i, ++str) {
-    aOut.mAddr[i] =
-      static_cast<uint8_t>(strtoul(str, const_cast<char**>(&str), 16));
-  }
-
-  return NS_OK;
-}
-
-nsresult
 Convert(const nsAString& aIn, BluetoothPinCode& aOut)
 {
   if (MOZ_HAL_IPC_CONVERT_WARN_IF(
         aIn.Length() > MOZ_ARRAY_LENGTH(aOut.mPinCode), nsAString,
         BluetoothPinCode)) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
@@ -616,41 +602,16 @@ Convert(BluetoothAclState aIn, bool& aOu
         aIn >= MOZ_ARRAY_LENGTH(sBool), BluetoothAclState, bool)) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
   aOut = sBool[aIn];
   return NS_OK;
 }
 
 nsresult
-Convert(const BluetoothAddress& aIn, nsAString& aOut)
-{
-  char str[BLUETOOTH_ADDRESS_LENGTH + 1];
-
-  int res = snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
-                     static_cast<int>(aIn.mAddr[0]),
-                     static_cast<int>(aIn.mAddr[1]),
-                     static_cast<int>(aIn.mAddr[2]),
-                     static_cast<int>(aIn.mAddr[3]),
-                     static_cast<int>(aIn.mAddr[4]),
-                     static_cast<int>(aIn.mAddr[5]));
-  if (MOZ_HAL_IPC_CONVERT_WARN_IF(
-        res < 0, BluetoothAddress, nsAString)) {
-    return NS_ERROR_ILLEGAL_VALUE;
-  } else if (MOZ_HAL_IPC_CONVERT_WARN_IF(
-        (size_t)res >= sizeof(str), BluetoothAddress, nsAString)) {
-    return NS_ERROR_OUT_OF_MEMORY; /* string buffer too small */
-  }
-
-  aOut = NS_ConvertUTF8toUTF16(str);
-
-  return NS_OK;
-}
-
-nsresult
 Convert(const BluetoothAttributeHandle& aIn, int32_t& aOut)
 {
   aOut = static_cast<int32_t>(aIn.mHandle);
   return NS_OK;
 }
 
 nsresult
 Convert(BluetoothAvrcpEvent aIn, uint8_t& aOut)
@@ -1624,18 +1585,17 @@ UnpackPDU(DaemonSocketPDU& aPDU, Bluetoo
         }
         // We construct an nsCString here because the string
         // returned from the PDU is not 0-terminated.
         aOut.mString = NS_ConvertUTF8toUTF16(
           nsCString(reinterpret_cast<const char*>(data), len));
       }
       break;
     case PROPERTY_BDADDR:
-      rv = UnpackPDU<BluetoothAddress>(
-        aPDU, UnpackConversion<BluetoothAddress, nsAString>(aOut.mString));
+      rv = UnpackPDU(aPDU, aOut.mBdAddress);
       break;
     case PROPERTY_UUIDS: {
         size_t numUuids = len / MAX_UUID_SIZE;
         aOut.mUuidArray.SetLength(numUuids);
         rv = UnpackPDU(aPDU, aOut.mUuidArray);
       }
       break;
     case PROPERTY_CLASS_OF_DEVICE:
@@ -1650,27 +1610,18 @@ UnpackPDU(DaemonSocketPDU& aPDU, Bluetoo
       rv = UnpackPDU(aPDU, aOut.mServiceRecord);
       break;
     case PROPERTY_ADAPTER_SCAN_MODE:
       rv = UnpackPDU(aPDU, aOut.mScanMode);
       break;
     case PROPERTY_ADAPTER_BONDED_DEVICES: {
         /* unpack addresses */
         size_t numAddresses = len / BLUETOOTH_ADDRESS_BYTES;
-        nsAutoArrayPtr<BluetoothAddress> addresses;
-        UnpackArray<BluetoothAddress> addressArray(addresses, numAddresses);
-        rv = UnpackPDU(aPDU, addressArray);
-        if (NS_FAILED(rv)) {
-          return rv;
-        }
-        /* convert addresses to strings */
-        aOut.mStringArray.SetLength(numAddresses);
-        ConvertArray<BluetoothAddress> convertArray(addressArray.mData,
-                                                    addressArray.mLength);
-        rv = Convert(convertArray, aOut.mStringArray);
+        aOut.mBdAddressArray.SetLength(numAddresses);
+        rv = UnpackPDU(aPDU, aOut.mBdAddressArray);
       }
       break;
     case PROPERTY_REMOTE_RSSI: {
         int8_t rssi;
         rv = UnpackPDU(aPDU, rssi);
         aOut.mInt32 = rssi;
       }
       break;
@@ -1831,24 +1782,18 @@ UnpackPDU(DaemonSocketPDU& aPDU, Bluetoo
   }
   /* unpack status */
   return UnpackPDU(aPDU, aOut.mStatus);
 }
 
 nsresult
 UnpackPDU(DaemonSocketPDU& aPDU, BluetoothGattNotifyParam& aOut)
 {
-
-  /* unpack address and convert to nsString */
-  BluetoothAddress address;
-  nsresult rv = UnpackPDU(aPDU, address);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-  rv = Convert(address, aOut.mBdAddr);
+  /* unpack address */
+  nsresult rv = UnpackPDU(aPDU, aOut.mBdAddr);
   if (NS_FAILED(rv)) {
     return rv;
   }
   /* unpack service id */
   rv = UnpackPDU(aPDU, aOut.mServiceId);
   if (NS_FAILED(rv)) {
     return rv;
   }
--- a/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.h
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonHelpers.h
@@ -27,20 +27,16 @@ using namespace mozilla::ipc::DaemonSock
 // Helper structures
 //
 
 enum BluetoothAclState {
   ACL_STATE_CONNECTED,
   ACL_STATE_DISCONNECTED
 };
 
-struct BluetoothAddress {
-  uint8_t mAddr[6];
-};
-
 struct BluetoothAvrcpAttributeTextPairs {
   BluetoothAvrcpAttributeTextPairs(const uint8_t* aAttr,
                                    const char** aText,
                                    size_t aLength)
     : mAttr(aAttr)
     , mText(aText)
     , mLength(aLength)
   { }
@@ -200,34 +196,28 @@ Convert(uint8_t aIn, BluetoothStatus& aO
 
 nsresult
 Convert(int32_t aIn, BluetoothAttributeHandle& aOut);
 
 nsresult
 Convert(int32_t aIn, BluetoothGattStatus& aOut);
 
 nsresult
-Convert(const nsAString& aIn, BluetoothAddress& aOut);
-
-nsresult
 Convert(const nsAString& aIn, BluetoothPinCode& aOut);
 
 nsresult
 Convert(const nsAString& aIn, BluetoothPropertyType& aOut);
 
 nsresult
 Convert(const nsAString& aIn, BluetoothServiceName& aOut);
 
 nsresult
 Convert(BluetoothAclState aIn, bool& aOut);
 
 nsresult
-Convert(const BluetoothAddress& aIn, nsAString& aOut);
-
-nsresult
 Convert(const BluetoothAttributeHandle& aIn, int32_t& aOut);
 
 nsresult
 Convert(BluetoothAvrcpEvent aIn, uint8_t& aOut);
 
 nsresult
 Convert(BluetoothAvrcpNotification aIn, uint8_t& aOut);
 
--- a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
@@ -662,66 +662,66 @@ BluetoothDaemonInterface::SetAdapterProp
     DispatchError(aRes, rv);
   }
 }
 
 /* Remote Device Properties */
 
 void
 BluetoothDaemonInterface::GetRemoteDeviceProperties(
-  const nsAString& aRemoteAddr, BluetoothResultHandler* aRes)
+  const BluetoothAddress& aRemoteAddr, BluetoothResultHandler* aRes)
 {
   nsresult rv = static_cast<BluetoothDaemonCoreModule*>
     (mProtocol)->GetRemoteDevicePropertiesCmd(aRemoteAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
 BluetoothDaemonInterface::GetRemoteDeviceProperty(
-  const nsAString& aRemoteAddr, const nsAString& aName,
+  const BluetoothAddress& aRemoteAddr, const nsAString& aName,
   BluetoothResultHandler* aRes)
 {
   nsresult rv = static_cast<BluetoothDaemonCoreModule*>
     (mProtocol)->GetRemoteDevicePropertyCmd(aRemoteAddr, aName, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
 BluetoothDaemonInterface::SetRemoteDeviceProperty(
-  const nsAString& aRemoteAddr, const BluetoothNamedValue& aProperty,
+  const BluetoothAddress& aRemoteAddr, const BluetoothNamedValue& aProperty,
   BluetoothResultHandler* aRes)
 {
   nsresult rv = static_cast<BluetoothDaemonCoreModule*>
     (mProtocol)->SetRemoteDevicePropertyCmd(aRemoteAddr, aProperty, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 /* Remote Services */
 
 void
-BluetoothDaemonInterface::GetRemoteServiceRecord(const nsAString& aRemoteAddr,
-                                                 const BluetoothUuid& aUuid,
-                                                 BluetoothResultHandler* aRes)
+BluetoothDaemonInterface::GetRemoteServiceRecord(
+  const BluetoothAddress& aRemoteAddr, const BluetoothUuid& aUuid,
+  BluetoothResultHandler* aRes)
 {
   nsresult rv = static_cast<BluetoothDaemonCoreModule*>
     (mProtocol)->GetRemoteServiceRecordCmd(aRemoteAddr, aUuid, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonInterface::GetRemoteServices(const nsAString& aRemoteAddr,
-                                            BluetoothResultHandler* aRes)
+BluetoothDaemonInterface::GetRemoteServices(
+  const BluetoothAddress& aRemoteAddr, BluetoothResultHandler* aRes)
 {
   nsresult rv = static_cast<BluetoothDaemonCoreModule*>
     (mProtocol)->GetRemoteServicesCmd(aRemoteAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
@@ -745,74 +745,75 @@ BluetoothDaemonInterface::CancelDiscover
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 /* Bonds */
 
 void
-BluetoothDaemonInterface::CreateBond(const nsAString& aBdAddr,
+BluetoothDaemonInterface::CreateBond(const BluetoothAddress& aBdAddr,
                                      BluetoothTransport aTransport,
                                      BluetoothResultHandler* aRes)
 {
   nsresult rv = static_cast<BluetoothDaemonCoreModule*>
     (mProtocol)->CreateBondCmd(aBdAddr, aTransport, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonInterface::RemoveBond(const nsAString& aBdAddr,
+BluetoothDaemonInterface::RemoveBond(const BluetoothAddress& aBdAddr,
                                      BluetoothResultHandler* aRes)
 {
   nsresult rv = static_cast<BluetoothDaemonCoreModule*>
     (mProtocol)->RemoveBondCmd(aBdAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonInterface::CancelBond(const nsAString& aBdAddr,
+BluetoothDaemonInterface::CancelBond(const BluetoothAddress& aBdAddr,
                                      BluetoothResultHandler* aRes)
 {
   nsresult rv = static_cast<BluetoothDaemonCoreModule*>
     (mProtocol)->CancelBondCmd(aBdAddr, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 /* Connection */
 
 void
-BluetoothDaemonInterface::GetConnectionState(const nsAString& aBdAddr,
+BluetoothDaemonInterface::GetConnectionState(const BluetoothAddress& aBdAddr,
                                              BluetoothResultHandler* aRes)
 {
   // NO-OP: no corresponding interface of current BlueZ
 }
 
 /* Authentication */
 
 void
-BluetoothDaemonInterface::PinReply(const nsAString& aBdAddr, bool aAccept,
+BluetoothDaemonInterface::PinReply(const BluetoothAddress& aBdAddr,
+                                   bool aAccept,
                                    const nsAString& aPinCode,
                                    BluetoothResultHandler* aRes)
 {
   nsresult rv = static_cast<BluetoothDaemonCoreModule*>
     (mProtocol)->PinReplyCmd(aBdAddr, aAccept, aPinCode, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonInterface::SspReply(const nsAString& aBdAddr,
+BluetoothDaemonInterface::SspReply(const BluetoothAddress& aBdAddr,
                                    BluetoothSspVariant aVariant,
                                    bool aAccept, uint32_t aPasskey,
                                    BluetoothResultHandler* aRes)
 {
   nsresult rv = static_cast<BluetoothDaemonCoreModule*>
     (mProtocol)->SspReplyCmd(aBdAddr, aVariant, aAccept, aPasskey, aRes);
   if (NS_FAILED(rv)) {
     DispatchError(aRes, rv);
--- a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.h
@@ -57,59 +57,61 @@ public:
   void GetAdapterProperties(BluetoothResultHandler* aRes) override;
   void GetAdapterProperty(const nsAString& aName,
                           BluetoothResultHandler* aRes) override;
   void SetAdapterProperty(const BluetoothNamedValue& aProperty,
                           BluetoothResultHandler* aRes) override;
 
   /* Remote Device Properties */
 
-  void GetRemoteDeviceProperties(const nsAString& aRemoteAddr,
+  void GetRemoteDeviceProperties(const BluetoothAddress& aRemoteAddr,
                                  BluetoothResultHandler* aRes) override;
-  void GetRemoteDeviceProperty(const nsAString& aRemoteAddr,
+  void GetRemoteDeviceProperty(const BluetoothAddress& aRemoteAddr,
                                const nsAString& aName,
                                BluetoothResultHandler* aRes) override;
-  void SetRemoteDeviceProperty(const nsAString& aRemoteAddr,
+  void SetRemoteDeviceProperty(const BluetoothAddress& aRemoteAddr,
                                const BluetoothNamedValue& aProperty,
                                BluetoothResultHandler* aRes) override;
 
   /* Remote Services */
 
-  void GetRemoteServiceRecord(const nsAString& aRemoteAddr,
+  void GetRemoteServiceRecord(const BluetoothAddress& aRemoteAddr,
                               const BluetoothUuid& aUuid,
                               BluetoothResultHandler* aRes) override;
-  void GetRemoteServices(const nsAString& aRemoteAddr,
+  void GetRemoteServices(const BluetoothAddress& aRemoteAddr,
                          BluetoothResultHandler* aRes) override;
 
   /* Discovery */
 
   void StartDiscovery(BluetoothResultHandler* aRes) override;
   void CancelDiscovery(BluetoothResultHandler* aRes) override;
 
   /* Bonds */
 
-  void CreateBond(const nsAString& aBdAddr, BluetoothTransport aTransport,
+  void CreateBond(const BluetoothAddress& aBdAddr,
+                  BluetoothTransport aTransport,
                   BluetoothResultHandler* aRes) override;
-  void RemoveBond(const nsAString& aBdAddr,
+  void RemoveBond(const BluetoothAddress& aBdAddr,
                   BluetoothResultHandler* aRes) override;
-  void CancelBond(const nsAString& aBdAddr,
+  void CancelBond(const BluetoothAddress& aBdAddr,
                   BluetoothResultHandler* aRes) override;
 
   /* Connection */
 
-  void GetConnectionState(const nsAString& aBdAddr,
+  void GetConnectionState(const BluetoothAddress& aBdAddr,
                           BluetoothResultHandler* aRes) override;
 
   /* Authentication */
 
-  void PinReply(const nsAString& aBdAddr, bool aAccept,
+  void PinReply(const BluetoothAddress& aBdAddr, bool aAccept,
                 const nsAString& aPinCode,
                 BluetoothResultHandler* aRes) override;
 
-  void SspReply(const nsAString& aBdAddr, BluetoothSspVariant aVariant,
+  void SspReply(const BluetoothAddress& aBdAddr,
+                BluetoothSspVariant aVariant,
                 bool aAccept, uint32_t aPasskey,
                 BluetoothResultHandler* aRes) override;
 
   /* DUT Mode */
 
   void DutModeConfigure(bool aEnable, BluetoothResultHandler* aRes);
   void DutModeSend(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
                    BluetoothResultHandler* aRes) override;
--- a/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.cpp
@@ -49,31 +49,31 @@ BluetoothDaemonSocketModule::ListenCmd(B
   if (NS_FAILED(rv)) {
     return rv;
   }
   unused << pdu.forget();
   return rv;
 }
 
 nsresult
-BluetoothDaemonSocketModule::ConnectCmd(const nsAString& aBdAddr,
+BluetoothDaemonSocketModule::ConnectCmd(const BluetoothAddress& aBdAddr,
                                         BluetoothSocketType aType,
                                         const BluetoothUuid& aServiceUuid,
                                         int aChannel, bool aEncrypt,
                                         bool aAuth,
                                         BluetoothSocketResultHandler* aRes)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<DaemonSocketPDU> pdu(
     new DaemonSocketPDU(SERVICE_ID, OPCODE_CONNECT,
                         0));
 
   nsresult rv = PackPDU(
-    PackConversion<nsAString, BluetoothAddress>(aBdAddr),
+    aBdAddr,
     aType,
     aServiceUuid,
     PackConversion<int, int32_t>(aChannel),
     SocketFlags(aEncrypt, aAuth), *pdu);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Send(pdu, aRes);
@@ -116,20 +116,21 @@ class BluetoothDaemonSocketModule::Accep
 public:
   AcceptWatcher(int aFd, BluetoothSocketResultHandler* aRes)
   : SocketMessageWatcher(aFd, aRes)
   { }
 
   void Proceed(BluetoothStatus aStatus) override
   {
     if (aStatus == STATUS_SUCCESS) {
-      IntStringIntResultRunnable::Dispatch(
+      AcceptResultRunnable::Dispatch(
         GetResultHandler(), &BluetoothSocketResultHandler::Accept,
-        ConstantInitOp3<int, nsString, int>(GetClientFd(), GetBdAddress(),
-                                            GetConnectionStatus()));
+        ConstantInitOp3<int, BluetoothAddress, int>(GetClientFd(),
+                                                    GetBdAddress(),
+                                                    GetConnectionStatus()));
     } else {
       ErrorRunnable::Dispatch(GetResultHandler(),
                               &BluetoothSocketResultHandler::OnError,
                               ConstantInitOp1<BluetoothStatus>(aStatus));
     }
 
     MessageLoopForIO::current()->PostTask(
       FROM_HERE, new DeleteTask<AcceptWatcher>(this));
@@ -230,17 +231,17 @@ public:
   }
 };
 
 void
 BluetoothDaemonSocketModule::ListenRsp(const DaemonSocketPDUHeader& aHeader,
                                        DaemonSocketPDU& aPDU,
                                        BluetoothSocketResultHandler* aRes)
 {
-  IntResultRunnable::Dispatch(
+  ListenResultRunnable::Dispatch(
     aRes, &BluetoothSocketResultHandler::Listen, ListenInitOp(aPDU));
 }
 
 /* |ConnectWatcher| specializes SocketMessageWatcher for
  * connect operations by reading the socket messages from
  * Bluedroid and forwarding the connected socket to the
  * resource handler.
  */
@@ -250,20 +251,21 @@ class BluetoothDaemonSocketModule::Conne
 public:
   ConnectWatcher(int aFd, BluetoothSocketResultHandler* aRes)
   : SocketMessageWatcher(aFd, aRes)
   { }
 
   void Proceed(BluetoothStatus aStatus) override
   {
     if (aStatus == STATUS_SUCCESS) {
-      IntStringIntResultRunnable::Dispatch(
+      ConnectResultRunnable::Dispatch(
         GetResultHandler(), &BluetoothSocketResultHandler::Connect,
-        ConstantInitOp3<int, nsString, int>(GetFd(), GetBdAddress(),
-                                            GetConnectionStatus()));
+        ConstantInitOp3<int, BluetoothAddress, int>(GetFd(),
+                                                    GetBdAddress(),
+                                                    GetConnectionStatus()));
     } else {
       ErrorRunnable::Dispatch(GetResultHandler(),
                               &BluetoothSocketResultHandler::OnError,
                               ConstantInitOp1<BluetoothStatus>(aStatus));
     }
 
     MessageLoopForIO::current()->PostTask(
       FROM_HERE, new DeleteTask<ConnectWatcher>(this));
@@ -315,17 +317,17 @@ BluetoothDaemonSocketInterface::Listen(B
   nsresult rv = mModule->ListenCmd(aType, aServiceName, aServiceUuid,
                                    aChannel, aEncrypt, aAuth, aRes);
   if (NS_FAILED(rv))  {
     DispatchError(aRes, rv);
   }
 }
 
 void
-BluetoothDaemonSocketInterface::Connect(const nsAString& aBdAddr,
+BluetoothDaemonSocketInterface::Connect(const BluetoothAddress& aBdAddr,
                                         BluetoothSocketType aType,
                                         const BluetoothUuid& aServiceUuid,
                                         int aChannel, bool aEncrypt,
                                         bool aAuth,
                                         BluetoothSocketResultHandler* aRes)
 {
   MOZ_ASSERT(mModule);
 
--- a/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonSocketInterface.h
@@ -39,17 +39,17 @@ public:
   //
 
   nsresult ListenCmd(BluetoothSocketType aType,
                      const nsAString& aServiceName,
                      const BluetoothUuid& aServiceUuid,
                      int aChannel, bool aEncrypt, bool aAuth,
                      BluetoothSocketResultHandler* aRes);
 
-  nsresult ConnectCmd(const nsAString& aBdAddr,
+  nsresult ConnectCmd(const BluetoothAddress& aBdAddr,
                       BluetoothSocketType aType,
                       const BluetoothUuid& aServiceUuid,
                       int aChannel, bool aEncrypt, bool aAuth,
                       BluetoothSocketResultHandler* aRes);
 
   nsresult AcceptCmd(int aFd, BluetoothSocketResultHandler* aRes);
 
   nsresult CloseCmd(BluetoothSocketResultHandler* aRes);
@@ -64,32 +64,37 @@ private:
   class ConnectWatcher;
   class ListenInitOp;
 
   uint8_t SocketFlags(bool aEncrypt, bool aAuth);
 
   // Responses
   //
 
-  typedef mozilla::ipc::DaemonResultRunnable0<
-    BluetoothSocketResultHandler, void>
-    ResultRunnable;
+  typedef mozilla::ipc::DaemonResultRunnable3<
+    BluetoothSocketResultHandler, void, int, BluetoothAddress, int, int,
+    const BluetoothAddress&, int>
+    AcceptResultRunnable;
 
-  typedef mozilla::ipc::DaemonResultRunnable1<
-    BluetoothSocketResultHandler, void, int, int>
-    IntResultRunnable;
+  typedef mozilla::ipc::DaemonResultRunnable3<
+    BluetoothSocketResultHandler, void, int, BluetoothAddress, int, int,
+    const BluetoothAddress&, int>
+    ConnectResultRunnable;
 
   typedef mozilla::ipc::DaemonResultRunnable1<
     BluetoothSocketResultHandler, void, BluetoothStatus, BluetoothStatus>
     ErrorRunnable;
 
-  typedef mozilla::ipc::DaemonResultRunnable3<
-    BluetoothSocketResultHandler, void, int, nsString, int, int,
-    const nsAString_internal&, int>
-    IntStringIntResultRunnable;
+  typedef mozilla::ipc::DaemonResultRunnable1<
+    BluetoothSocketResultHandler, void, int, int>
+    ListenResultRunnable;
+
+  typedef mozilla::ipc::DaemonResultRunnable0<
+    BluetoothSocketResultHandler, void>
+    ResultRunnable;
 
   void ErrorRsp(const DaemonSocketPDUHeader& aHeader,
                 DaemonSocketPDU& aPDU,
                 BluetoothSocketResultHandler* aRes);
 
   void ListenRsp(const DaemonSocketPDUHeader& aHeader,
                  DaemonSocketPDU& aPDU,
                  BluetoothSocketResultHandler* aRes);
@@ -107,17 +112,17 @@ public:
   ~BluetoothDaemonSocketInterface();
 
   void Listen(BluetoothSocketType aType,
               const nsAString& aServiceName,
               const BluetoothUuid& aServiceUuid,
               int aChannel, bool aEncrypt, bool aAuth,
               BluetoothSocketResultHandler* aRes) override;
 
-  void Connect(const nsAString& aBdAddr,
+  void Connect(const BluetoothAddress& aBdAddr,
                BluetoothSocketType aType,
                const BluetoothUuid& aServiceUuid,
                int aChannel, bool aEncrypt, bool aAuth,
                BluetoothSocketResultHandler* aRes) override;
 
   void Accept(int aFd, BluetoothSocketResultHandler* aRes) override;
 
   void Close(BluetoothSocketResultHandler* aRes) override;
--- a/dom/bluetooth/bluedroid/BluetoothGattManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothGattManager.cpp
@@ -791,31 +791,48 @@ BluetoothGattManager::Connect(const nsAS
                               const nsAString& aDeviceAddr,
                               BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aRunnable);
 
   ENSURE_GATT_INTF_IS_READY_VOID(aRunnable);
 
+  BluetoothAddress deviceAddr;
+  nsresult rv = StringToAddress(aDeviceAddr, deviceAddr);
+  if (NS_FAILED(rv)) {
+    BluetoothService* bs = BluetoothService::Get();
+    NS_ENSURE_TRUE_VOID(bs);
+
+    // Notify BluetoothGatt for client disconnected
+    bs->DistributeSignal(
+      NS_LITERAL_STRING(GATT_CONNECTION_STATE_CHANGED_ID),
+      aAppUuid,
+      BluetoothValue(false)); // Disconnected
+
+    // Reject the connect request
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
+    return;
+  }
+
   size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
   if (index == sClients->NoIndex) {
     index = sClients->Length();
     sClients->AppendElement(new BluetoothGattClient(aAppUuid, aDeviceAddr));
   }
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
   client->mConnectRunnable = aRunnable;
 
   if (client->mClientIf > 0) {
     sBluetoothGattInterface->Connect(client->mClientIf,
-                                           aDeviceAddr,
-                                           true, // direct connect
-                                           TRANSPORT_AUTO,
-                                           new ConnectResultHandler(client));
+                                     deviceAddr,
+                                     true, // direct connect
+                                     TRANSPORT_AUTO,
+                                     new ConnectResultHandler(client));
   } else {
     BluetoothUuid uuid;
     StringToUuid(aAppUuid, uuid);
 
     // connect will be proceeded after client registered
     sBluetoothGattInterface->RegisterClient(
       uuid, new RegisterClientResultHandler(client));
   }
@@ -861,28 +878,45 @@ BluetoothGattManager::Disconnect(const n
                                  const nsAString& aDeviceAddr,
                                  BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aRunnable);
 
   ENSURE_GATT_INTF_IS_READY_VOID(aRunnable);
 
+  BluetoothAddress deviceAddr;
+  nsresult rv = StringToAddress(aDeviceAddr, deviceAddr);
+  if (NS_FAILED(rv)) {
+    BluetoothService* bs = BluetoothService::Get();
+    NS_ENSURE_TRUE_VOID(bs);
+
+    // Notify BluetoothGatt that client remains connected
+    bs->DistributeSignal(
+      NS_LITERAL_STRING(GATT_CONNECTION_STATE_CHANGED_ID),
+      aAppUuid,
+      BluetoothValue(true)); // Connected
+
+    // Reject the Disconnect request
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
+    return;
+  }
+
   size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
   if (NS_WARN_IF(index == sClients->NoIndex)) {
     DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
     return;
   }
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
   client->mDisconnectRunnable = aRunnable;
 
   sBluetoothGattInterface->Disconnect(
     client->mClientIf,
-    aDeviceAddr,
+    deviceAddr,
     client->mConnId,
     new DisconnectResultHandler(client));
 }
 
 class BluetoothGattManager::DiscoverResultHandler final
   : public BluetoothGattResultHandler
 {
 public:
@@ -976,28 +1010,35 @@ BluetoothGattManager::ReadRemoteRssi(int
                                      const nsAString& aDeviceAddr,
                                      BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aRunnable);
 
   ENSURE_GATT_INTF_IS_READY_VOID(aRunnable);
 
+  BluetoothAddress deviceAddr;
+  nsresult rv = StringToAddress(aDeviceAddr, deviceAddr);
+  if (NS_FAILED(rv)) {
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
+    return;
+  }
+
   size_t index = sClients->IndexOf(aClientIf, 0 /* Start */,
                                    InterfaceIdComparator());
   if (NS_WARN_IF(index == sClients->NoIndex)) {
     DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
     return;
   }
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
   client->mReadRemoteRssiRunnable = aRunnable;
 
   sBluetoothGattInterface->ReadRemoteRssi(
-    aClientIf, aDeviceAddr,
+    aClientIf, deviceAddr,
     new ReadRemoteRssiResultHandler(client));
 }
 
 class BluetoothGattManager::RegisterNotificationsResultHandler final
   : public BluetoothGattResultHandler
 {
 public:
   RegisterNotificationsResultHandler(BluetoothGattClient* aClient)
@@ -1060,20 +1101,27 @@ BluetoothGattManager::RegisterNotificati
   // Reject the request if there is an ongoing request or client is already
   // disconnected
   if (client->mRegisterNotificationsRunnable || client->mConnId <= 0) {
     DispatchReplyError(aRunnable,
                        NS_LITERAL_STRING("RegisterNotifications failed"));
     return;
   }
 
+  BluetoothAddress deviceAddr;
+  nsresult rv = StringToAddress(client->mDeviceAddr, deviceAddr);
+  if (NS_FAILED(rv)) {
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
+    return;
+  }
+
   client->mRegisterNotificationsRunnable = aRunnable;
 
   sBluetoothGattInterface->RegisterNotification(
-    client->mClientIf, client->mDeviceAddr, aServId, aCharId,
+    client->mClientIf, deviceAddr, aServId, aCharId,
     new RegisterNotificationsResultHandler(client));
 }
 
 class BluetoothGattManager::DeregisterNotificationsResultHandler final
   : public BluetoothGattResultHandler
 {
 public:
   DeregisterNotificationsResultHandler(BluetoothGattClient* aClient)
@@ -1135,20 +1183,27 @@ BluetoothGattManager::DeregisterNotifica
 
   // Reject the request if there is an ongoing request
   if (client->mDeregisterNotificationsRunnable) {
     DispatchReplyError(aRunnable,
                        NS_LITERAL_STRING("DeregisterNotifications failed"));
     return;
   }
 
+  BluetoothAddress deviceAddr;
+  nsresult rv = StringToAddress(client->mDeviceAddr, deviceAddr);
+  if (NS_FAILED(rv)) {
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
+    return;
+  }
+
   client->mDeregisterNotificationsRunnable = aRunnable;
 
   sBluetoothGattInterface->DeregisterNotification(
-    client->mClientIf, client->mDeviceAddr, aServId, aCharId,
+    client->mClientIf, deviceAddr, aServId, aCharId,
     new DeregisterNotificationsResultHandler(client));
 }
 
 class BluetoothGattManager::ReadCharacteristicValueResultHandler final
   : public BluetoothGattResultHandler
 {
 public:
   ReadCharacteristicValueResultHandler(BluetoothGattClient* aClient)
@@ -1517,52 +1572,62 @@ private:
   nsRefPtr<BluetoothGattServer> mServer;
 };
 
 class BluetoothGattManager::ConnectPeripheralResultHandler final
   : public BluetoothGattResultHandler
 {
 public:
   ConnectPeripheralResultHandler(BluetoothGattServer* aServer,
-                                 const nsAString& aDeviceAddr)
-  : mServer(aServer)
-  , mDeviceAddr(aDeviceAddr)
+                                 const BluetoothAddress& aDeviceAddr)
+    : mServer(aServer)
+    , mDeviceAddr(aDeviceAddr)
   {
     MOZ_ASSERT(mServer);
-    MOZ_ASSERT(!mDeviceAddr.IsEmpty());
+    MOZ_ASSERT(mDeviceAddr != BluetoothAddress::ANY);
   }
 
   void OnError(BluetoothStatus aStatus) override
   {
     BT_WARNING("BluetoothGattServerInterface::ConnectPeripheral failed: %d",
                (int)aStatus);
     MOZ_ASSERT(mServer->mConnectPeripheralRunnable);
 
+    nsAutoString addressStr;
+    AddressToString(mDeviceAddr, addressStr);
+
     DispatchReplyError(mServer->mConnectPeripheralRunnable,
                        NS_LITERAL_STRING("ConnectPeripheral failed"));
     mServer->mConnectPeripheralRunnable = nullptr;
-    mServer->mConnectionMap.Remove(mDeviceAddr);
+    mServer->mConnectionMap.Remove(addressStr);
   }
 
 private:
   nsRefPtr<BluetoothGattServer> mServer;
-  nsString mDeviceAddr;
+  BluetoothAddress mDeviceAddr;
 };
 
 void
 BluetoothGattManager::ConnectPeripheral(
   const nsAString& aAppUuid,
   const nsAString& aAddress,
   BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aRunnable);
 
   ENSURE_GATT_INTF_IS_READY_VOID(aRunnable);
 
+  BluetoothAddress address;
+  nsresult rv = StringToAddress(aAddress, address);
+  if (NS_FAILED(rv)) {
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
+    return;
+  }
+
   size_t index = sServers->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
   if (index == sServers->NoIndex) {
     index = sServers->Length();
     sServers->AppendElement(new BluetoothGattServer(aAppUuid));
   }
   nsRefPtr<BluetoothGattServer> server = (*sServers)[index];
 
   /**
@@ -1591,20 +1656,20 @@ BluetoothGattManager::ConnectPeripheral(
   }
 
   server->mConnectionMap.Put(aAddress, 0);
   server->mConnectPeripheralRunnable = aRunnable;
 
   if (server->mServerIf > 0) {
     sBluetoothGattInterface->ConnectPeripheral(
       server->mServerIf,
-      aAddress,
+      address,
       true, // direct connect
       TRANSPORT_AUTO,
-      new ConnectPeripheralResultHandler(server, aAddress));
+      new ConnectPeripheralResultHandler(server, address));
   } else if (!server->mIsRegistering) { /* avoid triggering another registration
                                          * procedure if there is an on-going one
                                          * already */
     BluetoothUuid uuid;
     StringToUuid(aAppUuid, uuid);
 
     // connect will be proceeded after server registered
     sBluetoothGattInterface->RegisterServer(
@@ -1644,16 +1709,23 @@ BluetoothGattManager::DisconnectPeripher
   const nsAString& aAddress,
   BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aRunnable);
 
   ENSURE_GATT_INTF_IS_READY_VOID(aRunnable);
 
+  BluetoothAddress address;
+  nsresult rv = StringToAddress(aAddress, address);
+  if (NS_FAILED(rv)) {
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
+    return;
+  }
+
   size_t index = sServers->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
   if (NS_WARN_IF(index == sServers->NoIndex)) {
     DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
     return;
   }
   nsRefPtr<BluetoothGattServer> server = (*sServers)[index];
 
   if (NS_WARN_IF(server->mServerIf <= 0)) {
@@ -1675,17 +1747,17 @@ BluetoothGattManager::DisconnectPeripher
     DispatchReplySuccess(aRunnable);
     return;
   }
 
   server->mDisconnectPeripheralRunnable = aRunnable;
 
   sBluetoothGattInterface->DisconnectPeripheral(
     server->mServerIf,
-    aAddress,
+    address,
     connId,
     new DisconnectPeripheralResultHandler(server));
 }
 
 class BluetoothGattManager::UnregisterServerResultHandler final
   : public BluetoothGattResultHandler
 {
 public:
@@ -2446,31 +2518,47 @@ BluetoothGattManager::RegisterClientNoti
 
   if (client->mStartLeScanRunnable) {
     // Client just registered, proceed remaining startLeScan request.
     sBluetoothGattInterface->Scan(
       aClientIf, true /* start */,
       new StartLeScanResultHandler(client));
   } else if (client->mConnectRunnable) {
     // Client just registered, proceed remaining connect request.
+    BluetoothAddress address;
+    nsresult rv = StringToAddress(client->mDeviceAddr, address);
+    if (NS_FAILED(rv)) {
+      // Notify BluetoothGatt for client disconnected
+      bs->DistributeSignal(
+        NS_LITERAL_STRING(GATT_CONNECTION_STATE_CHANGED_ID),
+        client->mAppUuid,
+        BluetoothValue(false)); // Disconnected
+
+      // Reject the connect request
+      DispatchReplyError(client->mConnectRunnable,
+                         NS_LITERAL_STRING("Connect failed"));
+      client->mConnectRunnable = nullptr;
+      return;
+    }
+
     sBluetoothGattInterface->Connect(
-      aClientIf, client->mDeviceAddr, true /* direct connect */,
+      aClientIf, address, true /* direct connect */,
       TRANSPORT_AUTO,
       new ConnectResultHandler(client));
   }
 }
 
 class BluetoothGattManager::ScanDeviceTypeResultHandler final
   : public BluetoothGattResultHandler
 {
 public:
-  ScanDeviceTypeResultHandler(const nsAString& aBdAddr, int aRssi,
+  ScanDeviceTypeResultHandler(const BluetoothAddress& aBdAddr, int aRssi,
                               const BluetoothGattAdvData& aAdvData)
-  : mBdAddr(aBdAddr)
-  , mRssi(static_cast<int32_t>(aRssi))
+    : mBdAddr(aBdAddr)
+    , mRssi(static_cast<int32_t>(aRssi))
   {
     mAdvData.AppendElements(aAdvData.mAdvData, sizeof(aAdvData.mAdvData));
   }
 
   void GetDeviceType(BluetoothTypeOfDevice type)
   {
     DistributeSignalDeviceFound(type);
   }
@@ -2482,37 +2570,40 @@ public:
 
 private:
   void DistributeSignalDeviceFound(BluetoothTypeOfDevice type)
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     InfallibleTArray<BluetoothNamedValue> properties;
 
-    AppendNamedValue(properties, "Address", mBdAddr);
+    nsAutoString addressStr;
+    AddressToString(mBdAddr, addressStr);
+
+    AppendNamedValue(properties, "Address", addressStr);
     AppendNamedValue(properties, "Rssi", mRssi);
     AppendNamedValue(properties, "GattAdv", mAdvData);
     AppendNamedValue(properties, "Type", static_cast<uint32_t>(type));
 
     BluetoothService* bs = BluetoothService::Get();
     NS_ENSURE_TRUE_VOID(bs);
 
     bs->DistributeSignal(NS_LITERAL_STRING("LeDeviceFound"),
                          NS_LITERAL_STRING(KEY_ADAPTER),
                          BluetoothValue(properties));
   }
 
-  nsString mBdAddr;
+  BluetoothAddress mBdAddr;
   int32_t mRssi;
   nsTArray<uint8_t> mAdvData;
 };
 
 void
 BluetoothGattManager::ScanResultNotification(
-  const nsAString& aBdAddr, int aRssi,
+  const BluetoothAddress& aBdAddr, int aRssi,
   const BluetoothGattAdvData& aAdvData)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   NS_ENSURE_TRUE_VOID(sBluetoothGattInterface);
 
   // Distribute "LeDeviceFound" signal after we know the corresponding
   // BluetoothTypeOfDevice of the device
@@ -2520,17 +2611,17 @@ BluetoothGattManager::ScanResultNotifica
     aBdAddr,
     new ScanDeviceTypeResultHandler(aBdAddr, aRssi, aAdvData));
 }
 
 void
 BluetoothGattManager::ConnectNotification(int aConnId,
                                           BluetoothGattStatus aStatus,
                                           int aClientIf,
-                                          const nsAString& aDeviceAddr)
+                                          const BluetoothAddress& aDeviceAddr)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   BluetoothService* bs = BluetoothService::Get();
   NS_ENSURE_TRUE_VOID(bs);
 
   size_t index = sClients->IndexOf(aClientIf, 0 /* Start */,
                                    InterfaceIdComparator());
@@ -2569,20 +2660,21 @@ BluetoothGattManager::ConnectNotificatio
   // Resolve the connect request
   if (client->mConnectRunnable) {
     DispatchReplySuccess(client->mConnectRunnable);
     client->mConnectRunnable = nullptr;
   }
 }
 
 void
-BluetoothGattManager::DisconnectNotification(int aConnId,
-                                             BluetoothGattStatus aStatus,
-                                             int aClientIf,
-                                             const nsAString& aDeviceAddr)
+BluetoothGattManager::DisconnectNotification(
+  int aConnId,
+  BluetoothGattStatus aStatus,
+  int aClientIf,
+  const BluetoothAddress& aDeviceAddr)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   BluetoothService* bs = BluetoothService::Get();
   NS_ENSURE_TRUE_VOID(bs);
 
   size_t index = sClients->IndexOf(aClientIf, 0 /* Start */,
                                    InterfaceIdComparator());
@@ -3094,32 +3186,35 @@ BluetoothGattManager::WriteDescriptorNot
 }
 
 void
 BluetoothGattManager::ExecuteWriteNotification(int aConnId,
                                                BluetoothGattStatus aStatus)
 { }
 
 void
-BluetoothGattManager::ReadRemoteRssiNotification(int aClientIf,
-                                                 const nsAString& aBdAddr,
-                                                 int aRssi,
-                                                 BluetoothGattStatus aStatus)
+BluetoothGattManager::ReadRemoteRssiNotification(
+  int aClientIf,
+  const BluetoothAddress& aBdAddr,
+  int aRssi,
+  BluetoothGattStatus aStatus)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   size_t index = sClients->IndexOf(aClientIf, 0 /* Start */,
                                    InterfaceIdComparator());
   NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
 
   if (aStatus != GATT_STATUS_SUCCESS) { // operation failed
-    BT_LOGD("ReadRemoteRssi failed: clientIf = %d, bdAddr = %s, rssi = %d, " \
-            "status = %d", aClientIf, NS_ConvertUTF16toUTF8(aBdAddr).get(),
+    nsAutoString addressStr;
+    AddressToString(aBdAddr, addressStr);
+    BT_LOGD("ReadRemoteRssi failed: clientIf = %d, bdAddr = %s, rssi = %d, "
+            "status = %d", aClientIf, NS_ConvertUTF16toUTF8(addressStr).get(),
             aRssi, (int)aStatus);
 
     // Reject the read remote rssi request
     if (client->mReadRemoteRssiRunnable) {
       DispatchReplyError(client->mReadRemoteRssiRunnable,
                          NS_LITERAL_STRING("ReadRemoteRssi failed"));
       client->mReadRemoteRssiRunnable = nullptr;
     }
@@ -3194,17 +3289,25 @@ BluetoothGattManager::RegisterServerNoti
 
   // Notify BluetoothGattServer to update the serverIf
   bs->DistributeSignal(
     NS_LITERAL_STRING("ServerRegistered"),
     uuid, BluetoothValue(uint32_t(aServerIf)));
 
   if (server->mConnectPeripheralRunnable) {
     // Only one entry exists in the map during first connect peripheral request
-    nsString deviceAddr(server->mConnectionMap.Iter().Key());
+    BluetoothAddress deviceAddr;
+    nsresult rv = StringToAddress(server->mConnectionMap.Iter().Key(), deviceAddr);
+    if (NS_FAILED(rv)) {
+      DispatchReplyError(server->mConnectPeripheralRunnable,
+                         NS_LITERAL_STRING("ConnectPeripheral failed"));
+      server->mConnectPeripheralRunnable = nullptr;
+      server->mConnectionMap.Remove(server->mConnectionMap.Iter().Key());
+      return;
+    }
 
     sBluetoothGattInterface->ConnectPeripheral(
       aServerIf, deviceAddr, true /* direct connect */, TRANSPORT_AUTO,
       new ConnectPeripheralResultHandler(server, deviceAddr));
   }
 
   if (server->mAddServiceState.mRunnable) {
     sBluetoothGattInterface->AddService(
@@ -3214,40 +3317,43 @@ BluetoothGattManager::RegisterServerNoti
       new ServerAddServiceResultHandler(server));
   }
 }
 
 void
 BluetoothGattManager::ConnectionNotification(int aConnId,
                                              int aServerIf,
                                              bool aConnected,
-                                             const nsAString& aBdAddr)
+                                             const BluetoothAddress& aBdAddr)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   BluetoothService* bs = BluetoothService::Get();
   NS_ENSURE_TRUE_VOID(bs);
 
   size_t index = sServers->IndexOf(aServerIf, 0 /* Start */,
                                    InterfaceIdComparator());
   NS_ENSURE_TRUE_VOID(index != sServers->NoIndex);
 
   nsRefPtr<BluetoothGattServer> server = (*sServers)[index];
 
+  nsAutoString addressStr;
+  AddressToString(aBdAddr, addressStr);
+
   // Update the connection map based on the connection status
   if (aConnected) {
-    server->mConnectionMap.Put(aBdAddr, aConnId);
+    server->mConnectionMap.Put(addressStr, aConnId);
   } else {
-    server->mConnectionMap.Remove(aBdAddr);
+    server->mConnectionMap.Remove(addressStr);
   }
 
   // Notify BluetoothGattServer that connection status changed
   InfallibleTArray<BluetoothNamedValue> props;
   AppendNamedValue(props, "Connected", aConnected);
-  AppendNamedValue(props, "Address", nsString(aBdAddr));
+  AppendNamedValue(props, "Address", addressStr);
   bs->DistributeSignal(
     NS_LITERAL_STRING(GATT_CONNECTION_STATE_CHANGED_ID),
     server->mAppUuid,
     BluetoothValue(props));
 
   // Resolve or reject connect/disconnect peripheral requests
   if (server->mConnectPeripheralRunnable) {
     if (aConnected) {
@@ -3514,17 +3620,17 @@ BluetoothGattManager::ServiceDeletedNoti
     server->mRemoveServiceRunnable = nullptr;
   }
 }
 
 void
 BluetoothGattManager::RequestReadNotification(
   int aConnId,
   int aTransId,
-  const nsAString& aBdAddr,
+  const BluetoothAddress& aBdAddr,
   const BluetoothAttributeHandle& aAttributeHandle,
   int aOffset,
   bool aIsLong)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   NS_ENSURE_TRUE_VOID(aConnId);
   BluetoothService* bs = BluetoothService::Get();
@@ -3544,35 +3650,38 @@ BluetoothGattManager::RequestReadNotific
       aConnId,
       aTransId,
       GATT_STATUS_REQUEST_NOT_SUPPORTED,
       response,
       new ServerSendResponseResultHandler(server));
     return;
   }
 
+  nsAutoString addressStr;
+  AddressToString(aBdAddr, addressStr);
+
   // Distribute a signal to gattServer
   InfallibleTArray<BluetoothNamedValue> properties;
 
   AppendNamedValue(properties, "TransId", aTransId);
   AppendNamedValue(properties, "AttrHandle", aAttributeHandle);
-  AppendNamedValue(properties, "Address", nsString(aBdAddr));
+  AppendNamedValue(properties, "Address", addressStr);
   AppendNamedValue(properties, "NeedResponse", true);
   AppendNamedValue(properties, "Value", new nsTArray<uint8_t>());
 
   bs->DistributeSignal(NS_LITERAL_STRING("ReadRequested"),
                        server->mAppUuid,
                        properties);
 }
 
 void
 BluetoothGattManager::RequestWriteNotification(
   int aConnId,
   int aTransId,
-  const nsAString& aBdAddr,
+  const BluetoothAddress& aBdAddr,
   const BluetoothAttributeHandle& aAttributeHandle,
   int aOffset,
   int aLength,
   const uint8_t* aValue,
   bool aNeedResponse,
   bool aIsPrepareWrite)
 {
   MOZ_ASSERT(NS_IsMainThread());
@@ -3597,22 +3706,25 @@ BluetoothGattManager::RequestWriteNotifi
         aTransId,
         GATT_STATUS_REQUEST_NOT_SUPPORTED,
         response,
         new ServerSendResponseResultHandler(server));
     }
     return;
   }
 
+  nsAutoString addressStr;
+  AddressToString(aBdAddr, addressStr);
+
   // Distribute a signal to gattServer
   InfallibleTArray<BluetoothNamedValue> properties;
 
   AppendNamedValue(properties, "TransId", aTransId);
   AppendNamedValue(properties, "AttrHandle", aAttributeHandle);
-  AppendNamedValue(properties, "Address", nsString(aBdAddr));
+  AppendNamedValue(properties, "Address", addressStr);
   AppendNamedValue(properties, "NeedResponse", aNeedResponse);
 
   nsTArray<uint8_t> value;
   value.AppendElements(aValue, aLength);
   AppendNamedValue(properties, "Value", value);
 
   bs->DistributeSignal(NS_LITERAL_STRING("WrtieRequested"),
                        server->mAppUuid,
--- a/dom/bluetooth/bluedroid/BluetoothGattManager.h
+++ b/dom/bluetooth/bluedroid/BluetoothGattManager.h
@@ -202,28 +202,28 @@ private:
 
   void HandleShutdown();
 
   void RegisterClientNotification(BluetoothGattStatus aStatus,
                                   int aClientIf,
                                   const BluetoothUuid& aAppUuid) override;
 
   void ScanResultNotification(
-    const nsAString& aBdAddr, int aRssi,
+    const BluetoothAddress& aBdAddr, int aRssi,
     const BluetoothGattAdvData& aAdvData) override;
 
   void ConnectNotification(int aConnId,
                            BluetoothGattStatus aStatus,
                            int aClientIf,
-                           const nsAString& aBdAddr) override;
+                           const BluetoothAddress& aBdAddr) override;
 
   void DisconnectNotification(int aConnId,
                               BluetoothGattStatus aStatus,
                               int aClientIf,
-                              const nsAString& aBdAddr) override;
+                              const BluetoothAddress& aBdAddr) override;
 
   void SearchCompleteNotification(int aConnId,
                                   BluetoothGattStatus aStatus) override;
 
   void SearchResultNotification(int aConnId,
                                 const BluetoothGattServiceId& aServiceId)
                                 override;
 
@@ -271,34 +271,34 @@ private:
                                    BluetoothGattStatus aStatus,
                                    const BluetoothGattWriteParam& aWriteParam)
                                    override;
 
   void ExecuteWriteNotification(int aConnId,
                                 BluetoothGattStatus aStatus) override;
 
   void ReadRemoteRssiNotification(int aClientIf,
-                                  const nsAString& aBdAddr,
+                                  const BluetoothAddress& aBdAddr,
                                   int aRssi,
                                   BluetoothGattStatus aStatus) override;
 
   void ListenNotification(BluetoothGattStatus aStatus,
                           int aServerIf) override;
 
   void ProceedDiscoverProcess(BluetoothGattClient* aClient,
                               const BluetoothGattServiceId& aServiceId);
 
   void RegisterServerNotification(BluetoothGattStatus aStatus,
                                   int aServerIf,
                                   const BluetoothUuid& aAppUuid) override;
 
   void ConnectionNotification(int aConnId,
                               int aServerIf,
                               bool aConnected,
-                              const nsAString& aBdAddr) override;
+                              const BluetoothAddress& aBdAddr) override;
 
   void
   ServiceAddedNotification(
     BluetoothGattStatus aStatus,
     int aServerIf,
     const BluetoothGattServiceId& aServiceId,
     const BluetoothAttributeHandle& aServiceHandle) override;
 
@@ -341,25 +341,25 @@ private:
   ServiceDeletedNotification(
     BluetoothGattStatus aStatus,
     int aServerIf,
     const BluetoothAttributeHandle& aServiceHandle) override;
 
   void
   RequestReadNotification(int aConnId,
                           int aTransId,
-                          const nsAString& aBdAddr,
+                          const BluetoothAddress& aBdAddr,
                           const BluetoothAttributeHandle& aAttributeHandle,
                           int aOffset,
                           bool aIsLong) override;
 
   void
   RequestWriteNotification(int aConnId,
                            int aTransId,
-                           const nsAString& aBdAddr,
+                           const BluetoothAddress& aBdAddr,
                            const BluetoothAttributeHandle& aAttributeHandle,
                            int aOffset,
                            int aLength,
                            const uint8_t* aValue,
                            bool aNeedResponse,
                            bool aIsPrepareWrite) override;
 
   static bool mInShutdown;
--- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp
@@ -795,25 +795,36 @@ BluetoothServiceBluedroid::GetAdaptersIn
    *     |
    *     |__ BluetoothNamedValue =
    *     |     {"Adapter", BluetoothValue = BluetoothNamedValue[]}
    *     ...
    */
   InfallibleTArray<BluetoothNamedValue> adaptersProperties;
   uint32_t numAdapters = 1; // Bluedroid supports single adapter only
 
+  nsAutoString bdAddressStr;
+  AddressToString(mBdAddress, bdAddressStr);
+
+  nsTArray<nsString> bondedAddresses;
+
+  for (uint32_t i = 0; i < mBondedAddresses.Length(); ++i) {
+    nsAutoString bondedAddressStr;
+    AddressToString(mBondedAddresses[i], bondedAddressStr);
+    bondedAddresses.AppendElement(bondedAddressStr);
+  }
+
   for (uint32_t i = 0; i < numAdapters; i++) {
     InfallibleTArray<BluetoothNamedValue> properties;
 
     AppendNamedValue(properties, "State", mEnabled);
-    AppendNamedValue(properties, "Address", mBdAddress);
+    AppendNamedValue(properties, "Address", bdAddressStr);
     AppendNamedValue(properties, "Name", mBdName);
     AppendNamedValue(properties, "Discoverable", mDiscoverable);
     AppendNamedValue(properties, "Discovering", mDiscovering);
-    AppendNamedValue(properties, "PairedDevices", mBondedAddresses);
+    AppendNamedValue(properties, "PairedDevices", bondedAddresses);
 
     AppendNamedValue(adaptersProperties, "Adapter",
                      BluetoothValue(properties));
   }
 
   DispatchReplySuccess(aRunnable, adaptersProperties);
   return NS_OK;
 }
@@ -833,42 +844,45 @@ public:
 
 class BluetoothServiceBluedroid::GetRemoteDevicePropertiesResultHandler
   final
   : public BluetoothResultHandler
 {
 public:
   GetRemoteDevicePropertiesResultHandler(
     nsTArray<GetDeviceRequest>& aRequests,
-    const nsAString& aDeviceAddress)
+    const BluetoothAddress& aDeviceAddress)
     : mRequests(aRequests)
     , mDeviceAddress(aDeviceAddress)
   { }
 
   void OnError(BluetoothStatus aStatus) override
   {
     MOZ_ASSERT(NS_IsMainThread());
     MOZ_ASSERT(!mRequests.IsEmpty());
 
+    nsAutoString addressString;
+    AddressToString(mDeviceAddress, addressString);
+
     BT_WARNING("GetRemoteDeviceProperties(%s) failed: %d",
-               NS_ConvertUTF16toUTF8(mDeviceAddress).get(), aStatus);
+               NS_ConvertUTF16toUTF8(addressString).get(), aStatus);
 
     /* Dispatch result after the final pending operation */
     if (--mRequests[0].mDeviceCount == 0) {
       if (mRequests[0].mRunnable) {
         DispatchReplySuccess(mRequests[0].mRunnable,
                              mRequests[0].mDevicesPack);
       }
       mRequests.RemoveElementAt(0);
     }
   }
 
 private:
   nsTArray<GetDeviceRequest>& mRequests;
-  nsString mDeviceAddress;
+  BluetoothAddress mDeviceAddress;
 };
 
 nsresult
 BluetoothServiceBluedroid::GetConnectedDevicePropertiesInternal(
   uint16_t aServiceUuid, BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
@@ -883,18 +897,25 @@ BluetoothServiceBluedroid::GetConnectedD
 
   // Reply success if no device of this profile is connected
   if (!profile->IsConnected()) {
     DispatchReplySuccess(aRunnable, InfallibleTArray<BluetoothNamedValue>());
     return NS_OK;
   }
 
   // Get address of the connected device
-  nsString address;
-  profile->GetAddress(address);
+  nsString addressString;
+  profile->GetAddress(addressString);
+
+  BluetoothAddress address;
+  nsresult rv = StringToAddress(addressString, address);
+  if (NS_FAILED(rv)) {
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
+    return rv;
+  }
 
   // Append request of the connected device
   GetDeviceRequest request(1, aRunnable);
   mGetDeviceRequests.AppendElement(request);
 
   sBtInterface->GetRemoteDeviceProperties(address,
     new GetRemoteDevicePropertiesResultHandler(mGetDeviceRequests, address));
 
@@ -914,20 +935,27 @@ BluetoothServiceBluedroid::GetPairedDevi
     return NS_OK;
   }
 
   // Append request of all paired devices
   GetDeviceRequest request(aDeviceAddress.Length(), aRunnable);
   mGetDeviceRequests.AppendElement(request);
 
   for (uint8_t i = 0; i < aDeviceAddress.Length(); i++) {
+
+    BluetoothAddress address;
+    nsresult rv = StringToAddress(aDeviceAddress[i], address);
+    if (NS_FAILED(rv)) {
+      DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
+      return rv;
+    }
+
     // Retrieve all properties of devices
-    sBtInterface->GetRemoteDeviceProperties(aDeviceAddress[i],
-      new GetRemoteDevicePropertiesResultHandler(mGetDeviceRequests,
-                                                 aDeviceAddress[i]));
+    sBtInterface->GetRemoteDeviceProperties(address,
+      new GetRemoteDevicePropertiesResultHandler(mGetDeviceRequests, address));
   }
 
   return NS_OK;
 }
 
 class BluetoothServiceBluedroid::DispatchReplyErrorResultHandler final
   : public BluetoothResultHandler
 {
@@ -977,18 +1005,25 @@ BluetoothServiceBluedroid::FetchUuidsInt
   /*
    * get_remote_services request will not be performed by bluedroid
    * if it is currently discovering nearby remote devices.
    */
   if (mDiscovering) {
     StopDiscoveryInternal(aRunnable);
   }
 
+  BluetoothAddress address;
+  nsresult rv = StringToAddress(aDeviceAddress, address);
+  if (NS_FAILED(rv)) {
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
+    return rv;
+  }
+
   mFetchUuidsRunnables.AppendElement(aRunnable);
-  sBtInterface->GetRemoteServices(aDeviceAddress,
+  sBtInterface->GetRemoteServices(address,
     new DispatchReplyErrorResultHandler(mFetchUuidsRunnables, aRunnable));
 
   return NS_OK;
 }
 
 void
 BluetoothServiceBluedroid::StopDiscoveryInternal(
   BluetoothReplyRunnable* aRunnable)
@@ -1016,64 +1051,62 @@ BluetoothServiceBluedroid::SetProperty(B
     new DispatchReplyErrorResultHandler(mSetAdapterPropertyRunnables,
                                         aRunnable));
 
   return NS_OK;
 }
 
 struct BluetoothServiceBluedroid::GetRemoteServiceRecordRequest final
 {
-  GetRemoteServiceRecordRequest(const nsAString& aDeviceAddress,
+  GetRemoteServiceRecordRequest(const BluetoothAddress& aDeviceAddress,
                                 const BluetoothUuid& aUuid,
                                 BluetoothProfileManagerBase* aManager)
     : mDeviceAddress(aDeviceAddress)
     , mUuid(aUuid)
     , mManager(aManager)
   {
-    MOZ_ASSERT(!mDeviceAddress.IsEmpty());
     MOZ_ASSERT(mManager);
   }
 
-  nsString mDeviceAddress;
+  BluetoothAddress mDeviceAddress;
   BluetoothUuid mUuid;
   BluetoothProfileManagerBase* mManager;
 };
 
 class BluetoothServiceBluedroid::GetRemoteServiceRecordResultHandler final
   : public BluetoothResultHandler
 {
 public:
   GetRemoteServiceRecordResultHandler(
     nsTArray<GetRemoteServiceRecordRequest>& aGetRemoteServiceRecordArray,
-    const nsAString& aDeviceAddress,
+    const BluetoothAddress& aDeviceAddress,
     const BluetoothUuid& aUuid)
     : mGetRemoteServiceRecordArray(aGetRemoteServiceRecordArray)
     , mDeviceAddress(aDeviceAddress)
     , mUuid(aUuid)
-  {
-    MOZ_ASSERT(!mDeviceAddress.IsEmpty());
-  }
+  { }
 
   void OnError(BluetoothStatus aStatus) override
   {
     // Find call in array
 
     ssize_t i = FindRequest();
 
     if (i == -1) {
       BT_WARNING("No GetRemoteService request found");
       return;
     }
 
     // Signal error to profile manager
 
-    nsAutoString uuidStr;
+    nsAutoString addressStr, uuidStr;
+    AddressToString(mDeviceAddress, addressStr);
     UuidToString(mUuid, uuidStr);
     mGetRemoteServiceRecordArray[i].mManager->OnGetServiceChannel(
-      mDeviceAddress, uuidStr, -1);
+      addressStr, uuidStr, -1);
     mGetRemoteServiceRecordArray.RemoveElementAt(i);
   }
 
   void CancelDiscovery() override
   {
     // Disabled discovery mode, now perform SDP operation.
     sBtInterface->GetRemoteServiceRecord(mDeviceAddress, mUuid, this);
   }
@@ -1087,70 +1120,75 @@ private:
         return i;
       }
     }
 
     return -1;
   }
 
   nsTArray<GetRemoteServiceRecordRequest>& mGetRemoteServiceRecordArray;
-  nsString mDeviceAddress;
+  BluetoothAddress mDeviceAddress;
   BluetoothUuid mUuid;
 };
 
 nsresult
 BluetoothServiceBluedroid::GetServiceChannel(
   const nsAString& aDeviceAddress,
   const nsAString& aServiceUuid,
   BluetoothProfileManagerBase* aManager)
 {
+  BluetoothAddress address;
+  nsresult rv = StringToAddress(aDeviceAddress, address);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+
   BluetoothUuid uuid;
   StringToUuid(aServiceUuid, uuid);
+
   mGetRemoteServiceRecordArray.AppendElement(
-    GetRemoteServiceRecordRequest(aDeviceAddress, uuid, aManager));
+    GetRemoteServiceRecordRequest(address, uuid, aManager));
 
   nsRefPtr<BluetoothResultHandler> res =
     new GetRemoteServiceRecordResultHandler(mGetRemoteServiceRecordArray,
-                                            aDeviceAddress, uuid);
+                                            address, uuid);
 
   /* Stop discovery of remote devices here, because SDP operations
    * won't be performed while the adapter is in discovery mode.
    */
   if (mDiscovering) {
     sBtInterface->CancelDiscovery(res);
   } else {
-    sBtInterface->GetRemoteServiceRecord(
-      aDeviceAddress, uuid, res);
+    sBtInterface->GetRemoteServiceRecord(address, uuid, res);
   }
 
   return NS_OK;
 }
 
 struct BluetoothServiceBluedroid::GetRemoteServicesRequest final
 {
-  GetRemoteServicesRequest(const nsAString& aDeviceAddress,
+  GetRemoteServicesRequest(const BluetoothAddress& aDeviceAddress,
                            BluetoothProfileManagerBase* aManager)
     : mDeviceAddress(aDeviceAddress)
     , mManager(aManager)
   {
-    MOZ_ASSERT(!mDeviceAddress.IsEmpty());
     MOZ_ASSERT(mManager);
   }
 
-  const nsString mDeviceAddress;
+  BluetoothAddress mDeviceAddress;
   BluetoothProfileManagerBase* mManager;
 };
 
 class BluetoothServiceBluedroid::GetRemoteServicesResultHandler final
   : public BluetoothResultHandler
 {
 public:
   GetRemoteServicesResultHandler(
     nsTArray<GetRemoteServicesRequest>& aGetRemoteServicesArray,
-    const nsAString& aDeviceAddress,
+    const BluetoothAddress& aDeviceAddress,
     BluetoothProfileManagerBase* aManager)
     : mGetRemoteServicesArray(aGetRemoteServicesArray)
     , mDeviceAddress(aDeviceAddress)
     , mManager(aManager)
   { }
 
   void OnError(BluetoothStatus aStatus) override
   {
@@ -1162,17 +1200,19 @@ public:
       BT_WARNING("No GetRemoteServices request found");
       return;
     }
 
     // Cleanup array
     mGetRemoteServicesArray.RemoveElementAt(i);
 
     // There's no error-signaling mechanism; just call manager
-    mManager->OnUpdateSdpRecords(mDeviceAddress);
+    nsAutoString addressStr;
+    AddressToString(mDeviceAddress, addressStr);
+    mManager->OnUpdateSdpRecords(addressStr);
   }
 
   void CancelDiscovery() override
   {
     // Disabled discovery mode, now perform SDP operation.
     sBtInterface->GetRemoteServices(mDeviceAddress, this);
   }
 
@@ -1185,70 +1225,90 @@ private:
         return i;
       }
     }
 
     return -1;
   }
 
   nsTArray<GetRemoteServicesRequest>& mGetRemoteServicesArray;
-  const nsString mDeviceAddress;
+  BluetoothAddress mDeviceAddress;
   BluetoothProfileManagerBase* mManager;
 };
 
 bool
 BluetoothServiceBluedroid::UpdateSdpRecords(
   const nsAString& aDeviceAddress,
   BluetoothProfileManagerBase* aManager)
 {
+  BluetoothAddress address;
+  nsresult rv = StringToAddress(aDeviceAddress, address);
+  if (NS_FAILED(rv)) {
+    return false;
+  }
+
   mGetRemoteServicesArray.AppendElement(
-    GetRemoteServicesRequest(aDeviceAddress, aManager));
+    GetRemoteServicesRequest(address, aManager));
 
   nsRefPtr<BluetoothResultHandler> res =
     new GetRemoteServicesResultHandler(mGetRemoteServicesArray,
-                                       aDeviceAddress, aManager);
+                                       address, aManager);
 
   /* Stop discovery of remote devices here, because SDP operations
    * won't be performed while the adapter is in discovery mode.
    */
   if (mDiscovering) {
     sBtInterface->CancelDiscovery(res);
   } else {
-    sBtInterface->GetRemoteServices(aDeviceAddress, res);
+    sBtInterface->GetRemoteServices(address, res);
   }
 
   return true;
 }
 
 nsresult
 BluetoothServiceBluedroid::CreatePairedDeviceInternal(
   const nsAString& aDeviceAddress, int aTimeout,
   BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   ENSURE_BLUETOOTH_IS_READY(aRunnable, NS_OK);
 
+  BluetoothAddress address;
+  nsresult rv = StringToAddress(aDeviceAddress, address);
+  if (NS_FAILED(rv)) {
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
+    return rv;
+  }
+
   mCreateBondRunnables.AppendElement(aRunnable);
-  sBtInterface->CreateBond(aDeviceAddress, TRANSPORT_AUTO,
+  sBtInterface->CreateBond(address, TRANSPORT_AUTO,
     new DispatchReplyErrorResultHandler(mCreateBondRunnables, aRunnable));
 
   return NS_OK;
 }
 
 nsresult
 BluetoothServiceBluedroid::RemoveDeviceInternal(
   const nsAString& aDeviceAddress, BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   ENSURE_BLUETOOTH_IS_READY(aRunnable, NS_OK);
 
+  BluetoothAddress address;
+  nsresult rv = StringToAddress(aDeviceAddress, address);
+  if (NS_FAILED(rv)) {
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
+    return rv;
+  }
+
   mRemoveBondRunnables.AppendElement(aRunnable);
-  sBtInterface->RemoveBond(aDeviceAddress,
+  sBtInterface->RemoveBond(address,
     new DispatchReplyErrorResultHandler(mRemoveBondRunnables, aRunnable));
 
   return NS_OK;
 }
 
 class BluetoothServiceBluedroid::PinReplyResultHandler final
   : public BluetoothResultHandler
 {
@@ -1275,17 +1335,24 @@ void
 BluetoothServiceBluedroid::PinReplyInternal(
   const nsAString& aDeviceAddress, bool aAccept,
   const nsAString& aPinCode, BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   ENSURE_BLUETOOTH_IS_READY_VOID(aRunnable);
 
-  sBtInterface->PinReply(aDeviceAddress, aAccept, aPinCode,
+  BluetoothAddress address;
+  nsresult rv = StringToAddress(aDeviceAddress, address);
+  if (NS_FAILED(rv)) {
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
+    return;
+  }
+
+  sBtInterface->PinReply(address, aAccept, aPinCode,
                          new PinReplyResultHandler(aRunnable));
 }
 
 void
 BluetoothServiceBluedroid::SetPinCodeInternal(
   const nsAString& aDeviceAddress, const nsAString& aPinCode,
   BluetoothReplyRunnable* aRunnable)
 {
@@ -1326,17 +1393,24 @@ void
 BluetoothServiceBluedroid::SspReplyInternal(
   const nsAString& aDeviceAddress, BluetoothSspVariant aVariant,
   bool aAccept, BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   ENSURE_BLUETOOTH_IS_READY_VOID(aRunnable);
 
-  sBtInterface->SspReply(aDeviceAddress, aVariant, aAccept, 0 /* passkey */,
+  BluetoothAddress address;
+  nsresult rv = StringToAddress(aDeviceAddress, address);
+  if (NS_FAILED(rv)) {
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
+    return;
+  }
+
+  sBtInterface->SspReply(address, aVariant, aAccept, 0 /* passkey */,
                          new SspReplyResultHandler(aRunnable));
 }
 
 void
 BluetoothServiceBluedroid::SetPairingConfirmationInternal(
   const nsAString& aDeviceAddress, bool aConfirm,
   BluetoothReplyRunnable* aRunnable)
 {
@@ -1806,22 +1880,25 @@ BluetoothServiceBluedroid::AdapterStateC
       BluetoothGattManager::DeinitGattInterface
     };
 
     // Return error if BluetoothService is unavailable
     BluetoothService* bs = BluetoothService::Get();
     NS_ENSURE_TRUE_VOID(bs);
 
     // Cleanup static adapter properties and notify adapter.
-    mBdAddress.Truncate();
+    mBdAddress.Clear();
     mBdName.Truncate();
 
+    nsAutoString bdAddressStr;
+    AddressToString(mBdAddress, bdAddressStr);
+
     InfallibleTArray<BluetoothNamedValue> props;
     AppendNamedValue(props, "Name", mBdName);
-    AppendNamedValue(props, "Address", mBdAddress);
+    AppendNamedValue(props, "Address", bdAddressStr);
     if (mDiscoverable) {
       mDiscoverable = false;
       AppendNamedValue(props, "Discoverable", false);
     }
     if (mDiscovering) {
       mDiscovering = false;
       AppendNamedValue(props, "Discovering", false);
     }
@@ -1910,18 +1987,21 @@ BluetoothServiceBluedroid::AdapterProper
 
   InfallibleTArray<BluetoothNamedValue> propertiesArray;
 
   for (int i = 0; i < aNumProperties; i++) {
 
     const BluetoothProperty& p = aProperties[i];
 
     if (p.mType == PROPERTY_BDADDR) {
-      mBdAddress = p.mString;
-      AppendNamedValue(propertiesArray, "Address", mBdAddress);
+      mBdAddress = p.mBdAddress;
+      nsAutoString addressStr;
+      AddressToString(mBdAddress, addressStr);
+
+      AppendNamedValue(propertiesArray, "Address", addressStr);
 
     } else if (p.mType == PROPERTY_BDNAME) {
       mBdName = p.mString;
       AppendNamedValue(propertiesArray, "Name", mBdName);
 
     } else if (p.mType == PROPERTY_ADAPTER_SCAN_MODE) {
 
       // If BT is not enabled, Bluetooth scan mode should be non-discoverable
@@ -1931,23 +2011,31 @@ BluetoothServiceBluedroid::AdapterProper
         mDiscoverable = (p.mScanMode == SCAN_MODE_CONNECTABLE_DISCOVERABLE);
         AppendNamedValue(propertiesArray, "Discoverable", mDiscoverable);
       }
     } else if (p.mType == PROPERTY_ADAPTER_BONDED_DEVICES) {
       // We have to cache addresses of bonded devices. Unlike BlueZ,
       // Bluedroid would not send another PROPERTY_ADAPTER_BONDED_DEVICES
       // event after bond completed.
       BT_LOGD("Adapter property: BONDED_DEVICES. Count: %d",
-              p.mStringArray.Length());
+              p.mBdAddressArray.Length());
 
       // Whenever reloading paired devices, force refresh
       mBondedAddresses.Clear();
-      mBondedAddresses.AppendElements(p.mStringArray);
-
-      AppendNamedValue(propertiesArray, "PairedDevices", mBondedAddresses);
+      mBondedAddresses.AppendElements(p.mBdAddressArray);
+
+      nsTArray<nsString> bondedAddresses;
+
+      for (unsigned int j = 0; j < p.mBdAddressArray.Length(); ++j) {
+        nsAutoString addressStr;
+        AddressToString(p.mBdAddressArray[j], addressStr);
+        bondedAddresses.AppendElement(addressStr);
+      }
+
+      AppendNamedValue(propertiesArray, "PairedDevices", bondedAddresses);
     } else if (p.mType == PROPERTY_UNKNOWN) {
       /* Bug 1065999: working around unknown properties */
     } else {
       BT_LOGD("Unhandled adapter property type: %d", p.mType);
       continue;
     }
   }
 
@@ -1970,36 +2058,38 @@ BluetoothServiceBluedroid::AdapterProper
  *   (1) automatically by Bluedroid when BT is turning on, or
  *   (2) as result of remote device properties update during discovery, or
  *   (3) as result of CreateBond, or
  *   (4) as result of GetRemoteDeviceProperties, or
  *   (5) as result of GetRemoteServices.
  */
 void
 BluetoothServiceBluedroid::RemoteDevicePropertiesNotification(
-  BluetoothStatus aStatus, const nsAString& aBdAddr,
+  BluetoothStatus aStatus, const BluetoothAddress& aBdAddr,
   int aNumProperties, const BluetoothProperty* aProperties)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   InfallibleTArray<BluetoothNamedValue> propertiesArray;
 
-  nsString bdAddr(aBdAddr);
-  AppendNamedValue(propertiesArray, "Address", bdAddr);
+  nsAutoString bdAddrStr;
+  AddressToString(aBdAddr, bdAddrStr);
+
+  AppendNamedValue(propertiesArray, "Address", bdAddrStr);
 
   for (int i = 0; i < aNumProperties; ++i) {
 
     const BluetoothProperty& p = aProperties[i];
 
     if (p.mType == PROPERTY_BDNAME) {
       AppendNamedValue(propertiesArray, "Name", p.mString);
 
       // Update <address, name> mapping
-      mDeviceNameMap.Remove(bdAddr);
-      mDeviceNameMap.Put(bdAddr, p.mString);
+      mDeviceNameMap.Remove(aBdAddr);
+      mDeviceNameMap.Put(aBdAddr, p.mString);
     } else if (p.mType == PROPERTY_CLASS_OF_DEVICE) {
       uint32_t cod = p.mUint32;
       AppendNamedValue(propertiesArray, "Cod", cod);
 
     } else if (p.mType == PROPERTY_UUIDS) {
 
       size_t index;
 
@@ -2007,17 +2097,17 @@ BluetoothServiceBluedroid::RemoteDeviceP
 
       for (index = 0; index < mGetRemoteServicesArray.Length(); ++index) {
         if (mGetRemoteServicesArray[index].mDeviceAddress == aBdAddr) {
           break;
         }
       }
 
       if (index < mGetRemoteServicesArray.Length()) {
-        mGetRemoteServicesArray[index].mManager->OnUpdateSdpRecords(aBdAddr);
+        mGetRemoteServicesArray[index].mManager->OnUpdateSdpRecords(bdAddrStr);
         mGetRemoteServicesArray.RemoveElementAt(index);
         continue; // continue with outer loop
       }
 
       // Handler for |FetchUuidsInternal|
 
       nsTArray<nsString> uuids;
 
@@ -2046,17 +2136,17 @@ BluetoothServiceBluedroid::RemoteDeviceP
         if ((mGetRemoteServiceRecordArray[i].mDeviceAddress == aBdAddr) &&
             (mGetRemoteServiceRecordArray[i].mUuid == p.mServiceRecord.mUuid)) {
 
           // Signal channel to profile manager
           nsAutoString uuidStr;
           UuidToString(mGetRemoteServiceRecordArray[i].mUuid, uuidStr);
 
           mGetRemoteServiceRecordArray[i].mManager->OnGetServiceChannel(
-            aBdAddr, uuidStr, p.mServiceRecord.mChannel);
+            bdAddrStr, uuidStr, p.mServiceRecord.mChannel);
 
           mGetRemoteServiceRecordArray.RemoveElementAt(i);
           break;
         }
       }
       unused << NS_WARN_IF(i == mGetRemoteServiceRecordArray.Length());
     } else if (p.mType == PROPERTY_UNKNOWN) {
       /* Bug 1065999: working around unknown properties */
@@ -2073,17 +2163,17 @@ BluetoothServiceBluedroid::RemoteDeviceP
   //
   // |DispatchReplySuccess| creates its own internal runnable, which is
   // always run after we completed the current method. This means that we
   // can exchange |DispatchReplySuccess| with other operations without
   // changing the order of (1,2) and (3).
 
   // Update to registered BluetoothDevice objects
   BluetoothSignal signal(NS_LITERAL_STRING("PropertyChanged"),
-                         bdAddr, propertiesArray);
+                         bdAddrStr, propertiesArray);
 
   // FetchUuids task
   if (!mFetchUuidsRunnables.IsEmpty()) {
     // propertiesArray contains Address and Uuids only
     DispatchReplySuccess(mFetchUuidsRunnables[0],
                          propertiesArray[1].value()); /* Uuids */
     mFetchUuidsRunnables.RemoveElementAt(0);
     DistributeSignal(signal);
@@ -2094,17 +2184,17 @@ BluetoothServiceBluedroid::RemoteDeviceP
   if (mGetDeviceRequests.IsEmpty()) {
     // Callback is called after Bluetooth is turned on
     DistributeSignal(signal);
     return;
   }
 
   // Use address as the index
   mGetDeviceRequests[0].mDevicesPack.AppendElement(
-    BluetoothNamedValue(bdAddr, propertiesArray));
+    BluetoothNamedValue(bdAddrStr, propertiesArray));
 
   if (--mGetDeviceRequests[0].mDeviceCount == 0) {
     if (mGetDeviceRequests[0].mRunnable) {
       DispatchReplySuccess(mGetDeviceRequests[0].mRunnable,
                            mGetDeviceRequests[0].mDevicesPack);
     }
     mGetDeviceRequests.RemoveElementAt(0);
   }
@@ -2115,24 +2205,28 @@ BluetoothServiceBluedroid::RemoteDeviceP
 void
 BluetoothServiceBluedroid::DeviceFoundNotification(
   int aNumProperties, const BluetoothProperty* aProperties)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   InfallibleTArray<BluetoothNamedValue> propertiesArray;
 
-  nsString bdAddr, bdName;
+  BluetoothAddress bdAddr;
+  nsString bdName;
+
   for (int i = 0; i < aNumProperties; i++) {
 
     const BluetoothProperty& p = aProperties[i];
 
     if (p.mType == PROPERTY_BDADDR) {
-      AppendNamedValue(propertiesArray, "Address", p.mString);
-      bdAddr = p.mString;
+      nsAutoString addressStr;
+      AddressToString(p.mBdAddress, addressStr);
+      AppendNamedValue(propertiesArray, "Address", addressStr);
+      bdAddr = p.mBdAddress;
     } else if (p.mType == PROPERTY_BDNAME) {
       AppendNamedValue(propertiesArray, "Name", p.mString);
       bdName = p.mString;
     } else if (p.mType == PROPERTY_CLASS_OF_DEVICE) {
       AppendNamedValue(propertiesArray, "Cod", p.mUint32);
 
     } else if (p.mType == PROPERTY_UUIDS) {
       nsTArray<nsString> uuids;
@@ -2187,62 +2281,66 @@ BluetoothServiceBluedroid::DiscoveryStat
   if (!mChangeDiscoveryRunnables.IsEmpty()) {
     DispatchReplySuccess(mChangeDiscoveryRunnables[0]);
     mChangeDiscoveryRunnables.RemoveElementAt(0);
   }
 }
 
 void
 BluetoothServiceBluedroid::PinRequestNotification(
-  const nsAString& aRemoteBdAddr, const nsAString& aBdName, uint32_t aCod)
+  const BluetoothAddress& aRemoteBdAddr, const nsAString& aBdName, uint32_t aCod)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   InfallibleTArray<BluetoothNamedValue> propertiesArray;
 
   // If |aBdName| is empty, get device name from |mDeviceNameMap|;
   // Otherwise update <address, name> mapping with |aBdName|
-  nsString bdAddr(aRemoteBdAddr);
+  nsAutoString bdAddr;
+  AddressToString(aRemoteBdAddr, bdAddr);
+
   nsString bdName(aBdName);
   if (bdName.IsEmpty()) {
-    mDeviceNameMap.Get(bdAddr, &bdName);
+    mDeviceNameMap.Get(aRemoteBdAddr, &bdName);
   } else {
-    mDeviceNameMap.Remove(bdAddr);
-    mDeviceNameMap.Put(bdAddr, bdName);
+    mDeviceNameMap.Remove(aRemoteBdAddr);
+    mDeviceNameMap.Put(aRemoteBdAddr, bdName);
   }
 
   AppendNamedValue(propertiesArray, "address", bdAddr);
   AppendNamedValue(propertiesArray, "name", bdName);
   AppendNamedValue(propertiesArray, "passkey", EmptyString());
   AppendNamedValue(propertiesArray, "type",
                    NS_LITERAL_STRING(PAIRING_REQ_TYPE_ENTERPINCODE));
 
   DistributeSignal(NS_LITERAL_STRING("PairingRequest"),
                    NS_LITERAL_STRING(KEY_PAIRING_LISTENER),
                    BluetoothValue(propertiesArray));
 }
 
 void
 BluetoothServiceBluedroid::SspRequestNotification(
-  const nsAString& aRemoteBdAddr, const nsAString& aBdName, uint32_t aCod,
-  BluetoothSspVariant aPairingVariant, uint32_t aPassKey)
+  const BluetoothAddress& aRemoteBdAddr, const nsAString& aBdName,
+  uint32_t aCod, BluetoothSspVariant aPairingVariant, uint32_t aPassKey)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   InfallibleTArray<BluetoothNamedValue> propertiesArray;
 
   // If |aBdName| is empty, get device name from |mDeviceNameMap|;
   // Otherwise update <address, name> mapping with |aBdName|
-  nsString bdAddr(aRemoteBdAddr);
+  nsAutoString bdAddr;
+  AddressToString(aRemoteBdAddr, bdAddr);
+
   nsString bdName(aBdName);
   if (bdName.IsEmpty()) {
-    mDeviceNameMap.Get(bdAddr, &bdName);
+    mDeviceNameMap.Get(aRemoteBdAddr, &bdName);
   } else {
-    mDeviceNameMap.Remove(bdAddr);
-    mDeviceNameMap.Put(bdAddr, bdName);
+    mDeviceNameMap.Remove(aRemoteBdAddr);
+    mDeviceNameMap.Put(aRemoteBdAddr, bdName);
   }
 
   /**
    * Assign pairing request type and passkey based on the pairing variant.
    *
    * passkey value based on pairing request type:
    * 1) aPasskey: PAIRING_REQ_TYPE_CONFIRMATION and
    *              PAIRING_REQ_TYPE_DISPLAYPASSKEY
@@ -2274,17 +2372,17 @@ BluetoothServiceBluedroid::SspRequestNot
 
   DistributeSignal(NS_LITERAL_STRING("PairingRequest"),
                    NS_LITERAL_STRING(KEY_PAIRING_LISTENER),
                    BluetoothValue(propertiesArray));
 }
 
 void
 BluetoothServiceBluedroid::BondStateChangedNotification(
-  BluetoothStatus aStatus, const nsAString& aRemoteBdAddr,
+  BluetoothStatus aStatus, const BluetoothAddress& aRemoteBdAddr,
   BluetoothBondState aState)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (aState == BOND_STATE_BONDING) {
     // No need to handle bonding state
     return;
   }
@@ -2310,27 +2408,29 @@ BluetoothServiceBluedroid::BondStateChan
       DispatchReplyError(mRemoveBondRunnables[0], aStatus);
       mRemoveBondRunnables.RemoveElementAt(0);
     }
 
     return;
   }
 
   // Query pairing device name from hash table
-  nsString remoteBdAddr(aRemoteBdAddr);
+  nsAutoString remoteBdAddr;
+  AddressToString(aRemoteBdAddr, remoteBdAddr);
+
   nsString remotebdName;
-  mDeviceNameMap.Get(remoteBdAddr, &remotebdName);
+  mDeviceNameMap.Get(aRemoteBdAddr, &remotebdName);
 
   // Update bonded address array and append pairing device name
   InfallibleTArray<BluetoothNamedValue> propertiesArray;
   if (!bonded) {
-    mBondedAddresses.RemoveElement(remoteBdAddr);
+    mBondedAddresses.RemoveElement(aRemoteBdAddr);
   } else {
-    if (!mBondedAddresses.Contains(remoteBdAddr)) {
-      mBondedAddresses.AppendElement(remoteBdAddr);
+    if (!mBondedAddresses.Contains(aRemoteBdAddr)) {
+      mBondedAddresses.AppendElement(aRemoteBdAddr);
     }
 
     // We don't assert |!remotebdName.IsEmpty()| since empty string is also
     // valid, according to Bluetooth Core Spec. v3.0 - Sec. 6.22:
     // "a valid Bluetooth name is a UTF-8 encoding string which is up to 248
     // bytes in length."
     AppendNamedValue(propertiesArray, "Name", remotebdName);
   }
@@ -2355,17 +2455,17 @@ BluetoothServiceBluedroid::BondStateChan
   } else if (!bonded && !mRemoveBondRunnables.IsEmpty()) {
     DispatchReplySuccess(mRemoveBondRunnables[0]);
     mRemoveBondRunnables.RemoveElementAt(0);
   }
 }
 
 void
 BluetoothServiceBluedroid::AclStateChangedNotification(
-  BluetoothStatus aStatus, const nsAString& aRemoteBdAddr, bool aState)
+  BluetoothStatus aStatus, const BluetoothAddress& aRemoteBdAddr, bool aState)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // FIXME: This will be implemented in the later patchset
 }
 
 void
 BluetoothServiceBluedroid::DutModeRecvNotification(uint16_t aOpcode,
--- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h
+++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h
@@ -3,16 +3,17 @@
 /* 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/. */
 
 #ifndef mozilla_dom_bluetooth_bluedroid_BluetoothServiceBluedroid_h
 #define mozilla_dom_bluetooth_bluedroid_BluetoothServiceBluedroid_h
 
 #include "BluetoothCommon.h"
+#include "BluetoothHashKeys.h"
 #include "BluetoothInterface.h"
 #include "BluetoothService.h"
 #include "nsDataHashtable.h"
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 class BluetoothServiceBluedroid : public BluetoothService
                                 , public BluetoothNotificationHandler
@@ -383,39 +384,39 @@ public:
   //
 
   virtual void AdapterStateChangedNotification(bool aState) override;
   virtual void AdapterPropertiesNotification(
     BluetoothStatus aStatus, int aNumProperties,
     const BluetoothProperty* aProperties) override;
 
   virtual void RemoteDevicePropertiesNotification(
-    BluetoothStatus aStatus, const nsAString& aBdAddr,
+    BluetoothStatus aStatus, const BluetoothAddress& aBdAddr,
     int aNumProperties, const BluetoothProperty* aProperties) override;
 
   virtual void DeviceFoundNotification(
     int aNumProperties, const BluetoothProperty* aProperties) override;
 
   virtual void DiscoveryStateChangedNotification(bool aState) override;
 
-  virtual void PinRequestNotification(const nsAString& aRemoteBdAddr,
+  virtual void PinRequestNotification(const BluetoothAddress& aRemoteBdAddr,
                                       const nsAString& aBdName,
                                       uint32_t aCod) override;
-  virtual void SspRequestNotification(const nsAString& aRemoteBdAddr,
+  virtual void SspRequestNotification(const BluetoothAddress& aRemoteBdAddr,
                                       const nsAString& aBdName,
                                       uint32_t aCod,
                                       BluetoothSspVariant aPairingVariant,
                                       uint32_t aPasskey) override;
 
   virtual void BondStateChangedNotification(
-    BluetoothStatus aStatus, const nsAString& aRemoteBdAddr,
+    BluetoothStatus aStatus, const BluetoothAddress& aRemoteBdAddr,
     BluetoothBondState aState) override;
-  virtual void AclStateChangedNotification(BluetoothStatus aStatus,
-                                           const nsAString& aRemoteBdAddr,
-                                           bool aState) override;
+  virtual void AclStateChangedNotification(
+    BluetoothStatus aStatus, const BluetoothAddress& aRemoteBdAddr,
+    bool aState) override;
 
   virtual void DutModeRecvNotification(uint16_t aOpcode,
                                        const uint8_t* aBuf,
                                        uint8_t aLen) override;
   virtual void LeTestModeNotification(BluetoothStatus aStatus,
                                       uint16_t aNumPackets) override;
 
   virtual void EnergyInfoNotification(
@@ -434,22 +435,22 @@ protected:
 
   static void ConnectDisconnect(bool aConnect,
                                 const nsAString& aDeviceAddress,
                                 BluetoothReplyRunnable* aRunnable,
                                 uint16_t aServiceUuid, uint32_t aCod = 0);
   static void NextBluetoothProfileController();
 
   // Adapter properties
-  nsString mBdAddress;
+  BluetoothAddress mBdAddress;
   nsString mBdName;
   bool mEnabled;
   bool mDiscoverable;
   bool mDiscovering;
-  nsTArray<nsString> mBondedAddresses;
+  nsTArray<BluetoothAddress> mBondedAddresses;
 
   // Backend error recovery
   bool mIsRestart;
   bool mIsFirstTimeToggleOffBt;
 
   // Runnable arrays
   nsTArray<nsRefPtr<BluetoothReplyRunnable>> mChangeAdapterStateRunnables;
   nsTArray<nsRefPtr<BluetoothReplyRunnable>> mSetAdapterPropertyRunnables;
@@ -460,17 +461,17 @@ protected:
 
   // Array of get device requests. Each request remembers
   // 1) remaining device count to receive properties,
   // 2) received remote device properties, and
   // 3) runnable to reply success/error
   nsTArray<GetDeviceRequest> mGetDeviceRequests;
 
   // <address, name> mapping table for remote devices
-  nsDataHashtable<nsStringHashKey, nsString> mDeviceNameMap;
+  nsDataHashtable<BluetoothAddressHashKey, nsString> mDeviceNameMap;
 
   // Arrays for SDP operations
   nsTArray<GetRemoteServiceRecordRequest> mGetRemoteServiceRecordArray;
   nsTArray<GetRemoteServicesRequest> mGetRemoteServicesArray;
 };
 
 END_BLUETOOTH_NAMESPACE
 
--- a/dom/bluetooth/bluedroid/BluetoothSocket.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothSocket.cpp
@@ -381,34 +381,37 @@ class AcceptResultHandler final : public
 {
 public:
   AcceptResultHandler(DroidSocketImpl* aImpl)
   : mImpl(aImpl)
   {
     MOZ_ASSERT(mImpl);
   }
 
-  void Accept(int aFd, const nsAString& aBdAddress,
+  void Accept(int aFd, const BluetoothAddress& aBdAddress,
               int aConnectionStatus) override
   {
     MOZ_ASSERT(mImpl->IsConsumerThread());
 
     mozilla::ScopedClose fd(aFd); // Close received socket fd on error
 
     if (mImpl->IsShutdownOnConsumerThread()) {
       BT_LOGD("mConsumer is null, aborting receive!");
       return;
     }
 
     if (aConnectionStatus != 0) {
       mImpl->mConsumer->NotifyError();
       return;
     }
 
-    mImpl->mConsumer->SetAddress(aBdAddress);
+    nsAutoString addressStr;
+    AddressToString(aBdAddress, addressStr);
+
+    mImpl->mConsumer->SetAddress(addressStr);
     mImpl->GetIOLoop()->PostTask(FROM_HERE,
                                  new AcceptTask(mImpl, fd.forget()));
   }
 
   void OnError(BluetoothStatus aStatus) override
   {
     MOZ_ASSERT(mImpl->IsConsumerThread());
     BT_LOGR("BluetoothSocketInterface::Accept failed: %d", (int)aStatus);
@@ -602,32 +605,35 @@ class ConnectSocketResultHandler final :
 {
 public:
   ConnectSocketResultHandler(DroidSocketImpl* aImpl)
   : mImpl(aImpl)
   {
     MOZ_ASSERT(mImpl);
   }
 
-  void Connect(int aFd, const nsAString& aBdAddress,
+  void Connect(int aFd, const BluetoothAddress& aBdAddress,
                int aConnectionStatus) override
   {
     MOZ_ASSERT(mImpl->IsConsumerThread());
 
     if (mImpl->IsShutdownOnConsumerThread()) {
       BT_LOGD("mConsumer is null, aborting send!");
       return;
     }
 
     if (aConnectionStatus != 0) {
       mImpl->mConsumer->NotifyError();
       return;
     }
 
-    mImpl->mConsumer->SetAddress(aBdAddress);
+    nsAutoString addressStr;
+    AddressToString(aBdAddress, addressStr);
+
+    mImpl->mConsumer->SetAddress(addressStr);
     mImpl->GetIOLoop()->PostTask(FROM_HERE,
                                  new SocketConnectTask(mImpl, aFd));
   }
 
   void OnError(BluetoothStatus aStatus) override
   {
     MOZ_ASSERT(mImpl->IsConsumerThread());
     BT_WARNING("Connect failed: %d", (int)aStatus);
@@ -658,18 +664,24 @@ BluetoothSocket::Connect(const nsAString
 
   SetConnectionStatus(SOCKET_CONNECTING);
 
   mImpl = new DroidSocketImpl(aConsumerLoop, aIOLoop, this);
 
   BluetoothSocketResultHandler* res = new ConnectSocketResultHandler(mImpl);
   SetCurrentResultHandler(res);
 
+  BluetoothAddress deviceAddress;
+  nsresult rv = StringToAddress(aDeviceAddress, deviceAddress);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+
   sBluetoothSocketInterface->Connect(
-    aDeviceAddress, aType,
+    deviceAddress, aType,
     aServiceUuid, aChannel,
     aEncrypt, aAuth, res);
 
   return NS_OK;
 }
 
 nsresult
 BluetoothSocket::Connect(const nsAString& aDeviceAddress,
--- a/dom/bluetooth/bluedroid/BluetoothSocketMessageWatcher.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothSocketMessageWatcher.cpp
@@ -130,20 +130,20 @@ SocketMessageWatcher::GetChannel1() cons
 }
 
 int32_t
 SocketMessageWatcher::GetSize() const
 {
   return ReadInt16(OFF_SIZE);
 }
 
-nsString
+BluetoothAddress
 SocketMessageWatcher::GetBdAddress() const
 {
-  nsString bdAddress;
+  BluetoothAddress bdAddress;
   ReadBdAddress(OFF_BDADDRESS, bdAddress);
   return bdAddress;
 }
 
 int32_t
 SocketMessageWatcher::GetChannel2() const
 {
   return ReadInt32(OFF_CHANNEL2);
@@ -254,34 +254,24 @@ SocketMessageWatcher::ReadInt32(unsigned
   return (static_cast<int32_t>(mBuf[aOffset + 3]) << 24) |
          (static_cast<int32_t>(mBuf[aOffset + 2]) << 16) |
          (static_cast<int32_t>(mBuf[aOffset + 1]) << 8) |
           static_cast<int32_t>(mBuf[aOffset]);
 }
 
 void
 SocketMessageWatcher::ReadBdAddress(unsigned long aOffset,
-                                    nsAString& aBdAddress) const
+                                    BluetoothAddress& aBdAddress) const
 {
-  char str[BLUETOOTH_ADDRESS_LENGTH + 1];
-
-  int res = snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
-                     static_cast<int>(mBuf[aOffset + 0]),
-                     static_cast<int>(mBuf[aOffset + 1]),
-                     static_cast<int>(mBuf[aOffset + 2]),
-                     static_cast<int>(mBuf[aOffset + 3]),
-                     static_cast<int>(mBuf[aOffset + 4]),
-                     static_cast<int>(mBuf[aOffset + 5]));
-  if (res < 0) {
-    aBdAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
-  } else if ((size_t)res >= sizeof(str)) { /* string buffer too small */
-    aBdAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
-  } else {
-    aBdAddress = NS_ConvertUTF8toUTF16(str);
-  }
+  aBdAddress = BluetoothAddress(mBuf[aOffset + 0],
+                                mBuf[aOffset + 1],
+                                mBuf[aOffset + 2],
+                                mBuf[aOffset + 3],
+                                mBuf[aOffset + 4],
+                                mBuf[aOffset + 5]);
 }
 
 //
 // SocketMessageWatcherTask
 //
 
 SocketMessageWatcherTask::SocketMessageWatcherTask(
   SocketMessageWatcher* aWatcher)
--- a/dom/bluetooth/bluedroid/BluetoothSocketMessageWatcher.h
+++ b/dom/bluetooth/bluedroid/BluetoothSocketMessageWatcher.h
@@ -47,36 +47,36 @@ public:
   void OnFileCanReadWithoutBlocking(int aFd) override;
   void OnFileCanWriteWithoutBlocking(int aFd) override;
 
   void Watch();
   void StopWatching();
 
   bool IsComplete() const;
 
-  int      GetFd() const;
-  int32_t  GetChannel1() const;
-  int32_t  GetSize() const;
-  nsString GetBdAddress() const;
-  int32_t  GetChannel2() const;
-  int32_t  GetConnectionStatus() const;
-  int      GetClientFd() const;
+  int              GetFd() const;
+  int32_t          GetChannel1() const;
+  int32_t          GetSize() const;
+  BluetoothAddress GetBdAddress() const;
+  int32_t          GetChannel2() const;
+  int32_t          GetConnectionStatus() const;
+  int              GetClientFd() const;
 
   BluetoothSocketResultHandler* GetResultHandler() const;
 
 protected:
   SocketMessageWatcher(int aFd, BluetoothSocketResultHandler* aRes);
 
 private:
   BluetoothStatus RecvMsg1();
   BluetoothStatus RecvMsg2();
 
   int16_t ReadInt16(unsigned long aOffset) const;
   int32_t ReadInt32(unsigned long aOffset) const;
-  void    ReadBdAddress(unsigned long aOffset, nsAString& aBdAddress) const;
+  void    ReadBdAddress(unsigned long aOffset, BluetoothAddress& aBdAddress) const;
 
   MessageLoopForIO::FileDescriptorWatcher mWatcher;
   int mFd;
   int mClientFd;
   unsigned char mLen;
   uint8_t mBuf[MSG1_SIZE + MSG2_SIZE];
   nsRefPtr<BluetoothSocketResultHandler> mRes;
 };
--- a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp
@@ -649,19 +649,25 @@ BluetoothHfpManager::HandleVolumeChanged
   // Adjust volume by headset and we don't have to send volume back to headset
   if (mReceiveVgsFlag) {
     mReceiveVgsFlag = false;
     return;
   }
 
   // Only send volume back when there's a connected headset
   if (IsConnected()) {
+    BluetoothAddress deviceAddress;
+    nsresult rv = StringToAddress(mDeviceAddress, deviceAddress);
+    if (NS_FAILED(rv)) {
+      return;
+    }
+
     NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface);
     sBluetoothHfpInterface->VolumeControl(
-      HFP_VOLUME_TYPE_SPEAKER, mCurrentVgs, mDeviceAddress,
+      HFP_VOLUME_TYPE_SPEAKER, mCurrentVgs, deviceAddress,
       new VolumeControlResultHandler());
   }
 }
 
 void
 BluetoothHfpManager::HandleVoiceConnectionChanged(uint32_t aClientId)
 {
   nsCOMPtr<nsIMobileConnectionService> mcService =
@@ -786,20 +792,26 @@ BluetoothHfpManager::SendCLCC(Call& aCal
                                                HFP_CALL_STATE_ACTIVE;
   }
 
   if (callState == HFP_CALL_STATE_INCOMING &&
       FindFirstCall(nsITelephonyService::CALL_STATE_CONNECTED)) {
     callState = HFP_CALL_STATE_WAITING;
   }
 
+  BluetoothAddress deviceAddress;
+  nsresult rv = StringToAddress(mDeviceAddress, deviceAddress);
+  if (NS_FAILED(rv)) {
+    return;
+  }
+
   sBluetoothHfpInterface->ClccResponse(
     aIndex, aCall.mDirection, callState, HFP_CALL_MODE_VOICE,
     HFP_CALL_MPTY_TYPE_SINGLE, aCall.mNumber,
-    aCall.mType, mDeviceAddress, new ClccResponseResultHandler());
+    aCall.mType, deviceAddress, new ClccResponseResultHandler());
 }
 
 class BluetoothHfpManager::FormattedAtResponseResultHandler final
   : public BluetoothHandsfreeResultHandler
 {
 public:
   void OnError(BluetoothStatus aStatus) override
   {
@@ -808,18 +820,24 @@ public:
   }
 };
 
 void
 BluetoothHfpManager::SendLine(const char* aMessage)
 {
   NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface);
 
+  BluetoothAddress deviceAddress;
+  nsresult rv = StringToAddress(mDeviceAddress, deviceAddress);
+  if (NS_FAILED(rv)) {
+    return;
+  }
+
   sBluetoothHfpInterface->FormattedAtResponse(
-    aMessage, mDeviceAddress, new FormattedAtResponseResultHandler());
+    aMessage, deviceAddress, new FormattedAtResponseResultHandler());
 }
 
 class BluetoothHfpManager::AtResponseResultHandler final
   : public BluetoothHandsfreeResultHandler
 {
 public:
   void OnError(BluetoothStatus aStatus) override
   {
@@ -828,18 +846,24 @@ public:
   }
 };
 
 void
 BluetoothHfpManager::SendResponse(BluetoothHandsfreeAtResponse aResponseCode)
 {
   NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface);
 
+  BluetoothAddress deviceAddress;
+  nsresult rv = StringToAddress(mDeviceAddress, deviceAddress);
+  if (NS_FAILED(rv)) {
+    return;
+  }
+
   sBluetoothHfpInterface->AtResponse(
-    aResponseCode, 0, mDeviceAddress, new AtResponseResultHandler());
+    aResponseCode, 0, deviceAddress, new AtResponseResultHandler());
 }
 
 class BluetoothHfpManager::PhoneStateChangeResultHandler final
   : public BluetoothHandsfreeResultHandler
 {
 public:
   void OnError(BluetoothStatus aStatus) override
   {
@@ -1130,23 +1154,29 @@ BluetoothHfpManager::ToggleCalls()
  * error. The state change triggers UI status bar update as ordinary bluetooth
  * turn-off sequence.
  */
 void
 BluetoothHfpManager::HandleBackendError()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
+  BluetoothAddress deviceAddress;
+  nsresult rv = StringToAddress(mDeviceAddress, deviceAddress);
+  if (NS_FAILED(rv)) {
+    return;
+  }
+
   if (mConnectionState != HFP_CONNECTION_STATE_DISCONNECTED) {
     ConnectionStateNotification(HFP_CONNECTION_STATE_DISCONNECTED,
-      mDeviceAddress);
+      deviceAddress);
   }
 
   if (mAudioState != HFP_AUDIO_STATE_DISCONNECTED) {
-    AudioStateNotification(HFP_AUDIO_STATE_DISCONNECTED, mDeviceAddress);
+    AudioStateNotification(HFP_AUDIO_STATE_DISCONNECTED, deviceAddress);
   }
 }
 
 class BluetoothHfpManager::ConnectAudioResultHandler final
   : public BluetoothHandsfreeResultHandler
 {
 public:
   void OnError(BluetoothStatus aStatus) override
@@ -1160,17 +1190,23 @@ bool
 BluetoothHfpManager::ConnectSco()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   NS_ENSURE_TRUE(!sInShutdown, false);
   NS_ENSURE_TRUE(IsConnected() && !IsScoConnected(), false);
   NS_ENSURE_TRUE(sBluetoothHfpInterface, false);
 
-  sBluetoothHfpInterface->ConnectAudio(mDeviceAddress,
+  BluetoothAddress deviceAddress;
+  nsresult rv = StringToAddress(mDeviceAddress, deviceAddress);
+  if (NS_FAILED(rv)) {
+    return false;
+  }
+
+  sBluetoothHfpInterface->ConnectAudio(deviceAddress,
                                        new ConnectAudioResultHandler());
 
   return true;
 }
 
 class BluetoothHfpManager::DisconnectAudioResultHandler final
   : public BluetoothHandsfreeResultHandler
 {
@@ -1183,17 +1219,23 @@ public:
 };
 
 bool
 BluetoothHfpManager::DisconnectSco()
 {
   NS_ENSURE_TRUE(IsScoConnected(), false);
   NS_ENSURE_TRUE(sBluetoothHfpInterface, false);
 
-  sBluetoothHfpInterface->DisconnectAudio(mDeviceAddress,
+  BluetoothAddress deviceAddress;
+  nsresult rv = StringToAddress(mDeviceAddress, deviceAddress);
+  if (NS_FAILED(rv)) {
+    return false;
+  }
+
+  sBluetoothHfpInterface->DisconnectAudio(deviceAddress,
                                           new DisconnectAudioResultHandler());
 
   return true;
 }
 
 bool
 BluetoothHfpManager::IsScoConnected()
 {
@@ -1260,17 +1302,23 @@ BluetoothHfpManager::Connect(const nsASt
     BT_LOGR("sBluetoothHfpInterface is null");
     aController->NotifyCompletion(NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
     return;
   }
 
   mDeviceAddress = aDeviceAddress;
   mController = aController;
 
-  sBluetoothHfpInterface->Connect(mDeviceAddress,
+  BluetoothAddress deviceAddress;
+  nsresult rv = StringToAddress(mDeviceAddress, deviceAddress);
+  if (NS_FAILED(rv)) {
+    return;
+  }
+
+  sBluetoothHfpInterface->Connect(deviceAddress,
                                   new ConnectResultHandler(this));
 }
 
 void
 BluetoothHfpManager::OnDisconnectError()
 {
   MOZ_ASSERT(NS_IsMainThread());
   NS_ENSURE_TRUE_VOID(mController);
@@ -1311,17 +1359,23 @@ BluetoothHfpManager::Disconnect(Bluetoot
     if (aController) {
       aController->NotifyCompletion(NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
     }
     return;
   }
 
   mController = aController;
 
-  sBluetoothHfpInterface->Disconnect(mDeviceAddress,
+  BluetoothAddress deviceAddress;
+  nsresult rv = StringToAddress(mDeviceAddress, deviceAddress);
+  if (NS_FAILED(rv)) {
+    return;
+  }
+
+  sBluetoothHfpInterface->Disconnect(deviceAddress,
                                      new DisconnectResultHandler(this));
 }
 
 void
 BluetoothHfpManager::OnConnect(const nsAString& aErrorStr)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
@@ -1373,77 +1427,83 @@ BluetoothHfpManager::GetAddress(nsAStrin
 }
 
 //
 // Bluetooth notifications
 //
 
 void
 BluetoothHfpManager::ConnectionStateNotification(
-  BluetoothHandsfreeConnectionState aState, const nsAString& aBdAddress)
+  BluetoothHandsfreeConnectionState aState, const BluetoothAddress& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   BT_LOGR("state %d", aState);
 
   mPrevConnectionState = mConnectionState;
   mConnectionState = aState;
 
   if (aState == HFP_CONNECTION_STATE_SLC_CONNECTED) {
-    mDeviceAddress = aBdAddress;
+    AddressToString(aBdAddress, mDeviceAddress);
     NotifyConnectionStateChanged(
       NS_LITERAL_STRING(BLUETOOTH_HFP_STATUS_CHANGED_ID));
 
   } else if (aState == HFP_CONNECTION_STATE_DISCONNECTED) {
     DisconnectSco();
     NotifyConnectionStateChanged(
       NS_LITERAL_STRING(BLUETOOTH_HFP_STATUS_CHANGED_ID));
 
   } else if (aState == HFP_CONNECTION_STATE_CONNECTED) {
+    BluetoothAddress deviceAddress;
+    nsresult rv = StringToAddress(mDeviceAddress, deviceAddress);
+    if (NS_FAILED(rv)) {
+      return;
+    }
+
     // Once RFCOMM is connected, enable NREC before each new SLC connection
-    NRECNotification(HFP_NREC_STARTED, mDeviceAddress);
+    NRECNotification(HFP_NREC_STARTED, deviceAddress);
   }
 }
 
 void
 BluetoothHfpManager::AudioStateNotification(
-  BluetoothHandsfreeAudioState aState, const nsAString& aBdAddress)
+  BluetoothHandsfreeAudioState aState, const BluetoothAddress& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   BT_LOGR("state %d", aState);
 
   mAudioState = aState;
 
   if (aState == HFP_AUDIO_STATE_CONNECTED ||
       aState == HFP_AUDIO_STATE_DISCONNECTED) {
     NotifyConnectionStateChanged(
       NS_LITERAL_STRING(BLUETOOTH_SCO_STATUS_CHANGED_ID));
   }
 }
 
 void
-BluetoothHfpManager::AnswerCallNotification(const nsAString& aBdAddress)
+BluetoothHfpManager::AnswerCallNotification(const BluetoothAddress& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   NotifyDialer(NS_LITERAL_STRING("ATA"));
 }
 
 void
-BluetoothHfpManager::HangupCallNotification(const nsAString& aBdAddress)
+BluetoothHfpManager::HangupCallNotification(const BluetoothAddress& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   NotifyDialer(NS_LITERAL_STRING("CHUP"));
 }
 
 void
 BluetoothHfpManager::VolumeNotification(
-  BluetoothHandsfreeVolumeType aType, int aVolume, const nsAString& aBdAddress)
+  BluetoothHandsfreeVolumeType aType, int aVolume, const BluetoothAddress& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   NS_ENSURE_TRUE_VOID(aVolume >= 0 && aVolume <= 15);
 
   if (aType == HFP_VOLUME_TYPE_MICROPHONE) {
     mCurrentVgm = aVolume;
   } else if (aType == HFP_VOLUME_TYPE_SPEAKER) {
@@ -1460,17 +1520,17 @@ BluetoothHfpManager::VolumeNotification(
     nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
     NS_ENSURE_TRUE_VOID(os);
 
     os->NotifyObservers(nullptr, "bluetooth-volume-change", data.get());
   }
 }
 
 void
-BluetoothHfpManager::DtmfNotification(char aDtmf, const nsAString& aBdAddress)
+BluetoothHfpManager::DtmfNotification(char aDtmf, const BluetoothAddress& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   NS_ENSURE_TRUE_VOID(IsValidDtmf(aDtmf));
 
   nsAutoCString message("VTS=");
   message += aDtmf;
   NotifyDialer(NS_ConvertUTF8toUTF16(message));
@@ -1479,17 +1539,17 @@ BluetoothHfpManager::DtmfNotification(ch
 /**
  * NREC status will be set when:
  * 1. Get an AT command from HF device.
  *    (Bluetooth HFP spec v1.6 merely defines for the "Disable" part.)
  * 2. Once RFCOMM is connected, enable NREC before each new SLC connection.
  */
 void
 BluetoothHfpManager::NRECNotification(BluetoothHandsfreeNRECState aNrec,
-                                      const nsAString& aBdAddr)
+                                      const BluetoothAddress& aBdAddr)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // Notify Gecko observers
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   NS_ENSURE_TRUE_VOID(obs);
 
   mNrecEnabled = static_cast<bool>(aNrec);
@@ -1500,17 +1560,17 @@ BluetoothHfpManager::NRECNotification(Bl
                                      mDeviceAddress.get()))) {
     BT_WARNING("Failed to notify bluetooth-hfp-nrec-status-changed observsers!");
   }
 
 }
 
 void
 BluetoothHfpManager::CallHoldNotification(BluetoothHandsfreeCallHoldType aChld,
-                                          const nsAString& aBdAddress)
+                                          const BluetoothAddress& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (!IsSupportedChld((int)aChld)) {
     // We currently don't support Enhanced Call Control.
     // AT+CHLD=1x and AT+CHLD=2x will be ignored
     SendResponse(HFP_AT_RESPONSE_ERROR);
     return;
@@ -1519,17 +1579,17 @@ BluetoothHfpManager::CallHoldNotificatio
   SendResponse(HFP_AT_RESPONSE_OK);
 
   nsAutoCString message("CHLD=");
   message.AppendInt((int)aChld);
   NotifyDialer(NS_ConvertUTF8toUTF16(message));
 }
 
 void BluetoothHfpManager::DialCallNotification(const nsAString& aNumber,
-                                               const nsAString& aBdAddress)
+                                               const BluetoothAddress& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsCString message = NS_ConvertUTF16toUTF8(aNumber);
 
   // There are three cases based on aNumber,
   // 1) Empty value:    Redial, BLDN
   // 2) >xxx:           Memory dial, ATD>xxx
@@ -1560,17 +1620,17 @@ void BluetoothHfpManager::DialCallNotifi
 
     nsAutoCString newMsg("ATD");
     newMsg += StringHead(message, message.Length() - 1);
     NotifyDialer(NS_ConvertUTF8toUTF16(newMsg));
   }
 }
 
 void
-BluetoothHfpManager::CnumNotification(const nsAString& aBdAddress)
+BluetoothHfpManager::CnumNotification(const BluetoothAddress& aBdAddress)
 {
   static const uint8_t sAddressType[] {
     [HFP_CALL_ADDRESS_TYPE_UNKNOWN] = 0x81,
     [HFP_CALL_ADDRESS_TYPE_INTERNATIONAL] = 0x91 // for completeness
   };
 
   MOZ_ASSERT(NS_IsMainThread());
 
@@ -1594,17 +1654,17 @@ public:
   void OnError(BluetoothStatus aStatus) override
   {
     BT_WARNING("BluetoothHandsfreeInterface::CindResponse failed: %d",
                (int)aStatus);
   }
 };
 
 void
-BluetoothHfpManager::CindNotification(const nsAString& aBdAddress)
+BluetoothHfpManager::CindNotification(const BluetoothAddress& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface);
 
   int numActive = GetNumberOfCalls(nsITelephonyService::CALL_STATE_CONNECTED);
   int numHeld = GetNumberOfCalls(nsITelephonyService::CALL_STATE_HELD);
   BluetoothHandsfreeCallState callState =
@@ -1624,29 +1684,29 @@ public:
   void OnError(BluetoothStatus aStatus) override
   {
     BT_WARNING("BluetoothHandsfreeInterface::CopsResponse failed: %d",
                (int)aStatus);
   }
 };
 
 void
-BluetoothHfpManager::CopsNotification(const nsAString& aBdAddress)
+BluetoothHfpManager::CopsNotification(const BluetoothAddress& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface);
 
   sBluetoothHfpInterface->CopsResponse(
     NS_ConvertUTF16toUTF8(mOperatorName).get(),
     aBdAddress, new CopsResponseResultHandler());
 }
 
 void
-BluetoothHfpManager::ClccNotification(const nsAString& aBdAddress)
+BluetoothHfpManager::ClccNotification(const BluetoothAddress& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   uint32_t callNumbers = mCurrentCallArray.Length();
   uint32_t i;
   for (i = 1; i < callNumbers; i++) {
     SendCLCC(mCurrentCallArray[i], i);
   }
@@ -1658,27 +1718,27 @@ BluetoothHfpManager::ClccNotification(co
     SendCLCC(mCdmaSecondCall, 2);
   }
 
   SendResponse(HFP_AT_RESPONSE_OK);
 }
 
 void
 BluetoothHfpManager::UnknownAtNotification(const nsACString& aAtString,
-                                           const nsAString& aBdAddress)
+                                           const BluetoothAddress& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   BT_LOGR("[%s]", nsCString(aAtString).get());
 
   SendResponse(HFP_AT_RESPONSE_ERROR);
 }
 
 void
-BluetoothHfpManager::KeyPressedNotification(const nsAString& aBdAddress)
+BluetoothHfpManager::KeyPressedNotification(const BluetoothAddress& aBdAddress)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   bool hasActiveCall =
     (FindFirstCall(nsITelephonyService::CALL_STATE_CONNECTED) > 0);
 
   // Refer to AOSP HeadsetStateMachine.processKeyPressed
   if (FindFirstCall(nsITelephonyService::CALL_STATE_INCOMING)
--- a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h
+++ b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.h
@@ -112,39 +112,39 @@ public:
   // Handle unexpected backend crash
   void HandleBackendError();
 
   //
   // Bluetooth notifications
   //
 
   void ConnectionStateNotification(BluetoothHandsfreeConnectionState aState,
-                                   const nsAString& aBdAddress) override;
+                                   const BluetoothAddress& aBdAddress) override;
   void AudioStateNotification(BluetoothHandsfreeAudioState aState,
-                              const nsAString& aBdAddress) override;
-  void AnswerCallNotification(const nsAString& aBdAddress) override;
-  void HangupCallNotification(const nsAString& aBdAddress) override;
+                              const BluetoothAddress& aBdAddress) override;
+  void AnswerCallNotification(const BluetoothAddress& aBdAddress) override;
+  void HangupCallNotification(const BluetoothAddress& aBdAddress) override;
   void VolumeNotification(BluetoothHandsfreeVolumeType aType,
                           int aVolume,
-                          const nsAString& aBdAddress) override;
+                          const BluetoothAddress& aBdAddress) override;
   void DtmfNotification(char aDtmf,
-                        const nsAString& aBdAddress) override;
+                        const BluetoothAddress& aBdAddress) override;
   void NRECNotification(BluetoothHandsfreeNRECState aNrec,
-                        const nsAString& aBdAddr) override;
+                        const BluetoothAddress& aBdAddr) override;
   void CallHoldNotification(BluetoothHandsfreeCallHoldType aChld,
-                            const nsAString& aBdAddress) override;
+                            const BluetoothAddress& aBdAddress) override;
   void DialCallNotification(const nsAString& aNumber,
-                            const nsAString& aBdAddress) override;
-  void CnumNotification(const nsAString& aBdAddress) override;
-  void CindNotification(const nsAString& aBdAddress) override;
-  void CopsNotification(const nsAString& aBdAddress) override;
-  void ClccNotification(const nsAString& aBdAddress) override;
+                            const BluetoothAddress& aBdAddress) override;
+  void CnumNotification(const BluetoothAddress& aBdAddress) override;
+  void CindNotification(const BluetoothAddress& aBdAddress) override;
+  void CopsNotification(const BluetoothAddress& aBdAddress) override;
+  void ClccNotification(const BluetoothAddress& aBdAddress) override;
   void UnknownAtNotification(const nsACString& aAtString,
-                             const nsAString& aBdAddress) override;
-  void KeyPressedNotification(const nsAString& aBdAddress) override;
+                             const BluetoothAddress& aBdAddress) override;
+  void KeyPressedNotification(const BluetoothAddress& aBdAddress) override;
 
 protected:
   virtual ~BluetoothHfpManager();
 
 private:
   class AtResponseResultHandler;
   class CindResponseResultHandler;
   class ConnectAudioResultHandler;
new file mode 100644
--- /dev/null
+++ b/dom/bluetooth/common/BluetoothCommon.cpp
@@ -0,0 +1,24 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "BluetoothCommon.h"
+
+BEGIN_BLUETOOTH_NAMESPACE
+
+//
+// |BluetoothAddress|
+//
+
+const BluetoothAddress BluetoothAddress::ANY(0x00, 0x00, 0x00,
+                                             0x00, 0x00, 0x00);
+
+const BluetoothAddress BluetoothAddress::ALL(0xff, 0xff, 0xff,
+                                             0xff, 0xff, 0xff);
+
+const BluetoothAddress BluetoothAddress::LOCAL(0x00, 0x00, 0x00,
+                                               0xff, 0xff, 0xff);
+
+END_BLUETOOTH_NAMESPACE
--- a/dom/bluetooth/common/BluetoothCommon.h
+++ b/dom/bluetooth/common/BluetoothCommon.h
@@ -366,16 +366,118 @@ struct BluetoothActivityEnergyInfo {
   uint8_t mStatus;
   uint8_t mStackState;  /* stack reported state */
   uint64_t mTxTime;     /* in ms */
   uint64_t mRxTime;     /* in ms */
   uint64_t mIdleTime;   /* in ms */
   uint64_t mEnergyUsed; /* a product of mA, V and ms */
 };
 
+/**
+ * |BluetoothAddress| stores the 6-byte MAC address of a Bluetooth
+ * device. The constants ANY, ALL and LOCAL represent addresses with
+ * special meaning.
+ */
+struct BluetoothAddress {
+
+  static const BluetoothAddress ANY;
+  static const BluetoothAddress ALL;
+  static const BluetoothAddress LOCAL;
+
+  uint8_t mAddr[6];
+
+  BluetoothAddress()
+  {
+    Clear(); // assign ANY
+  }
+
+  MOZ_IMPLICIT BluetoothAddress(const BluetoothAddress&) = default;
+
+  BluetoothAddress(uint8_t aAddr0, uint8_t aAddr1,
+                   uint8_t aAddr2, uint8_t aAddr3,
+                   uint8_t aAddr4, uint8_t aAddr5)
+  {
+    mAddr[0] = aAddr0;
+    mAddr[1] = aAddr1;
+    mAddr[2] = aAddr2;
+    mAddr[3] = aAddr3;
+    mAddr[4] = aAddr4;
+    mAddr[5] = aAddr5;
+  }
+
+  BluetoothAddress& operator=(const BluetoothAddress&) = default;
+
+  bool operator==(const BluetoothAddress& aRhs) const
+  {
+    return !memcmp(mAddr, aRhs.mAddr, sizeof(mAddr));
+  }
+
+  bool operator!=(const BluetoothAddress& aRhs) const
+  {
+    return !operator==(aRhs);
+  }
+
+  /**
+   * |Clear| assigns an invalid value (i.e., ANY) to the address.
+   */
+  void Clear()
+  {
+    operator=(ANY);
+  }
+
+  /*
+   * Getter and setter methods for the address parts. The figure
+   * below illustrates the mapping to bytes; from LSB to MSB.
+   *
+   *    |       LAP       | UAP |    NAP    |
+   *    |  0  |  1  |  2  |  3  |  4  |  5  |
+   *
+   * See Bluetooth Core Spec 2.1, Sec 1.2.
+   */
+
+  uint32_t GetLAP() const
+  {
+    return (static_cast<uint32_t>(mAddr[0])) |
+           (static_cast<uint32_t>(mAddr[1]) << 8) |
+           (static_cast<uint32_t>(mAddr[2]) << 16);
+  }
+
+  void SetLAP(uint32_t aLAP)
+  {
+    MOZ_ASSERT(!(aLAP & 0xff000000)); // no top-8 bytes in LAP
+
+    mAddr[0] = aLAP;
+    mAddr[1] = aLAP >> 8;
+    mAddr[2] = aLAP >> 16;
+  }
+
+  uint8_t GetUAP() const
+  {
+    return mAddr[3];
+  }
+
+  void SetUAP(uint8_t aUAP)
+  {
+    mAddr[3] = aUAP;
+  }
+
+  uint16_t GetNAP() const
+  {
+    return (static_cast<uint16_t>(mAddr[4])) |
+           (static_cast<uint16_t>(mAddr[5]) << 8);
+  }
+
+  void SetNAP(uint16_t aNAP)
+  {
+    mAddr[4] = aNAP;
+    mAddr[5] = aNAP >> 8;
+  }
+
+};
+
 struct BluetoothUuid {
   uint8_t mUuid[16];
 
   bool operator==(const BluetoothUuid& aOther) const
   {
     for (uint8_t i = 0; i < sizeof(mUuid); i++) {
       if (mUuid[i] != aOther.mUuid[i]) {
         return false;
@@ -404,26 +506,28 @@ struct BluetoothRemoteInfo {
 
 struct BluetoothProperty {
   /* Type */
   BluetoothPropertyType mType;
 
   /* Value
    */
 
+  /* PROPERTY_BDADDR */
+  BluetoothAddress mBdAddress;
+
   /* PROPERTY_BDNAME
-     PROPERTY_BDADDR
      PROPERTY_REMOTE_FRIENDLY_NAME */
   nsString mString;
 
   /* PROPERTY_UUIDS */
   nsTArray<BluetoothUuid> mUuidArray;
 
   /* PROPERTY_ADAPTER_BONDED_DEVICES */
-  nsTArray<nsString> mStringArray;
+  nsTArray<BluetoothAddress> mBdAddressArray;
 
   /* PROPERTY_CLASS_OF_DEVICE
      PROPERTY_ADAPTER_DISCOVERY_TIMEOUT */
   uint32_t mUint32;
 
   /* PROPERTY_RSSI_VALUE */
   int32_t mInt32;
 
@@ -806,26 +910,26 @@ struct BluetoothGattReadParam {
 struct BluetoothGattWriteParam {
   BluetoothGattServiceId mServiceId;
   BluetoothGattId mCharId;
   BluetoothGattId mDescriptorId;
   uint8_t mStatus;
 };
 
 struct BluetoothGattNotifyParam {
-  nsString mBdAddr;
+  BluetoothAddress mBdAddr;
   BluetoothGattServiceId mServiceId;
   BluetoothGattId mCharId;
   uint16_t mLength;
   uint8_t mValue[BLUETOOTH_GATT_MAX_ATTR_LEN];
   bool mIsNotify;
 };
 
 struct BluetoothGattTestParam {
-  nsString mBdAddr;
+  BluetoothAddress mBdAddr;
   BluetoothUuid mUuid;
   uint16_t mU1;
   uint16_t mU2;
   uint16_t mU3;
   uint16_t mU4;
   uint16_t mU5;
 };
 
new file mode 100644
--- /dev/null
+++ b/dom/bluetooth/common/BluetoothHashKeys.h
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+/* This file contains hash-table keys for Bluetooth classes. */
+
+#ifndef mozilla_dom_bluetooth_BluetoothHashKeys_h
+#define mozilla_dom_bluetooth_BluetoothHashKeys_h
+
+#include "BluetoothCommon.h"
+#include <mozilla/HashFunctions.h>
+#include <nsHashKeys.h>
+
+BEGIN_BLUETOOTH_NAMESPACE
+
+/**
+ * Implements a hash-table key for |BluetoothAddress|.
+ */
+class BluetoothAddressHashKey : public PLDHashEntryHdr
+{
+public:
+  enum {
+    ALLOW_MEMMOVE = true
+  };
+
+  typedef const BluetoothAddress& KeyType;
+  typedef const BluetoothAddress* KeyTypePointer;
+
+  explicit BluetoothAddressHashKey(KeyTypePointer aKey)
+    : mValue(*aKey)
+  { }
+  BluetoothAddressHashKey(const BluetoothAddressHashKey& aToCopy)
+    : mValue(aToCopy.mValue)
+  { }
+  ~BluetoothAddressHashKey()
+  { }
+  KeyType GetKey() const
+  {
+    return mValue;
+  }
+  bool KeyEquals(KeyTypePointer aKey) const
+  {
+    return *aKey == mValue;
+  }
+  static KeyTypePointer KeyToPointer(KeyType aKey)
+  {
+    return &aKey;
+  }
+  static PLDHashNumber HashKey(KeyTypePointer aKey)
+  {
+    return HashBytes(aKey->mAddr, MOZ_ARRAY_LENGTH(aKey->mAddr));
+  }
+private:
+  const BluetoothAddress mValue;
+};
+
+END_BLUETOOTH_NAMESPACE
+
+#endif // mozilla_dom_bluetooth_BluetoothHashKeys_h
--- a/dom/bluetooth/common/BluetoothInterface.cpp
+++ b/dom/bluetooth/common/BluetoothInterface.cpp
@@ -53,23 +53,23 @@ BluetoothSocketResultHandler::OnError(Bl
 }
 
 void
 BluetoothSocketResultHandler::Listen(int aSockFd)
 { }
 
 void
 BluetoothSocketResultHandler::Connect(int aSockFd,
-                                      const nsAString& aBdAddress,
+                                      const BluetoothAddress& aBdAddress,
                                       int aConnectionState)
 { }
 
 void
 BluetoothSocketResultHandler::Accept(int aSockFd,
-                                     const nsAString& aBdAddress,
+                                     const BluetoothAddress& aBdAddress,
                                      int aConnectionState)
 { }
 
 // Interface
 //
 
 BluetoothSocketInterface::~BluetoothSocketInterface()
 { }
@@ -84,97 +84,97 @@ BluetoothSocketInterface::~BluetoothSock
 BluetoothHandsfreeNotificationHandler::BluetoothHandsfreeNotificationHandler()
 { }
 
 BluetoothHandsfreeNotificationHandler::~BluetoothHandsfreeNotificationHandler()
 { }
 
 void
 BluetoothHandsfreeNotificationHandler::ConnectionStateNotification(
-  BluetoothHandsfreeConnectionState aState, const nsAString& aBdAddr)
+  BluetoothHandsfreeConnectionState aState, const BluetoothAddress& aBdAddr)
 { }
 
 void
 BluetoothHandsfreeNotificationHandler::AudioStateNotification(
-  BluetoothHandsfreeAudioState aState, const nsAString& aBdAddr)
+  BluetoothHandsfreeAudioState aState, const BluetoothAddress& aBdAddr)
 { }
 
 void
 BluetoothHandsfreeNotificationHandler::VoiceRecognitionNotification(
-  BluetoothHandsfreeVoiceRecognitionState aState, const nsAString& aBdAddr)
+  BluetoothHandsfreeVoiceRecognitionState aState, const BluetoothAddress& aBdAddr)
 { }
 
 void
 BluetoothHandsfreeNotificationHandler::AnswerCallNotification(
-  const nsAString& aBdAddr)
+  const BluetoothAddress& aBdAddr)
 { }
 
 void
 BluetoothHandsfreeNotificationHandler::HangupCallNotification(
-  const nsAString& aBdAddr)
+  const BluetoothAddress& aBdAddr)
 { }
 
 void
 BluetoothHandsfreeNotificationHandler::VolumeNotification(
-  BluetoothHandsfreeVolumeType aType, int aVolume, const nsAString& aBdAddr)
+  BluetoothHandsfreeVolumeType aType, int aVolume, const BluetoothAddress& aBdAddr)
 { }
 
 void
 BluetoothHandsfreeNotificationHandler::DialCallNotification(
-  const nsAString& aNumber, const nsAString& aBdAddr)
+  const nsAString& aNumber, const BluetoothAddress& aBdAddr)
 { }
 
 void
 BluetoothHandsfreeNotificationHandler::DtmfNotification(
-  char aDtmf, const nsAString& aBdAddr)
+  char aDtmf, const BluetoothAddress& aBdAddr)
 { }
 
 void
 BluetoothHandsfreeNotificationHandler::NRECNotification(
-  BluetoothHandsfreeNRECState aNrec, const nsAString& aBdAddr)
+  BluetoothHandsfreeNRECState aNrec, const BluetoothAddress& aBdAddr)
 { }
 
 void
 BluetoothHandsfreeNotificationHandler::WbsNotification(
-  BluetoothHandsfreeWbsConfig aWbs, const nsAString& aBdAddr)
+  BluetoothHandsfreeWbsConfig aWbs, const BluetoothAddress& aBdAddr)
 { }
 
 void
 BluetoothHandsfreeNotificationHandler::CallHoldNotification(
-  BluetoothHandsfreeCallHoldType aChld, const nsAString& aBdAddr)
+  BluetoothHandsfreeCallHoldType aChld, const BluetoothAddress& aBdAddr)
 { }
 
 void
 BluetoothHandsfreeNotificationHandler::CnumNotification(
-  const nsAString& aBdAddr)
+  const BluetoothAddress& aBdAddr)
 { }
 
 void
 BluetoothHandsfreeNotificationHandler::CindNotification(
-  const nsAString& aBdAddr)
+  const BluetoothAddress& aBdAddr)
 { }
 
 void
 BluetoothHandsfreeNotificationHandler::CopsNotification(
-  const nsAString& aBdAddr)
+  const BluetoothAddress& aBdAddr)
 { }
 
 void
 BluetoothHandsfreeNotificationHandler::ClccNotification(
-  const nsAString& aBdAddr)
+  const BluetoothAddress& aBdAddr)
 { }
 
 void
 BluetoothHandsfreeNotificationHandler::UnknownAtNotification(
-  const nsACString& aAtString, const nsAString& aBdAddr)
+  const nsACString& aAtString, const BluetoothAddress& aBdAddr)
 { }
 
 void
 BluetoothHandsfreeNotificationHandler::KeyPressedNotification(
-  const nsAString& aBdAddr)
+  const BluetoothAddress& aBdAddr)
 { }
 
 // Result handling
 //
 
 void
 BluetoothHandsfreeResultHandler::OnError(BluetoothStatus aStatus)
 {
@@ -268,27 +268,27 @@ BluetoothHandsfreeInterface::~BluetoothH
 BluetoothA2dpNotificationHandler::BluetoothA2dpNotificationHandler()
 { }
 
 BluetoothA2dpNotificationHandler::~BluetoothA2dpNotificationHandler()
 { }
 
 void
 BluetoothA2dpNotificationHandler::ConnectionStateNotification(
-  BluetoothA2dpConnectionState aState, const nsAString& aBdAddr)
+  BluetoothA2dpConnectionState aState, const BluetoothAddress& aBdAddr)
 { }
 
 void
 BluetoothA2dpNotificationHandler::AudioStateNotification(
-  BluetoothA2dpAudioState aState, const nsAString& aBdAddr)
+  BluetoothA2dpAudioState aState, const BluetoothAddress& aBdAddr)
 { }
 
 void
 BluetoothA2dpNotificationHandler::AudioConfigNotification(
-  const nsAString& aBdAddr, uint32_t aSampleRate, uint8_t aChannelCount)
+  const BluetoothAddress& aBdAddr, uint32_t aSampleRate, uint8_t aChannelCount)
 { }
 
 // Result handling
 //
 
 void
 BluetoothA2dpResultHandler::OnError(BluetoothStatus aStatus)
 {
@@ -373,17 +373,17 @@ BluetoothAvrcpNotificationHandler::GetEl
 
 void
 BluetoothAvrcpNotificationHandler::RegisterNotificationNotification(
   BluetoothAvrcpEvent aEvent, uint32_t aParam)
 { }
 
 void
 BluetoothAvrcpNotificationHandler::RemoteFeatureNotification(
-  const nsAString& aBdAddr, unsigned long aFeatures)
+  const BluetoothAddress& aBdAddr, unsigned long aFeatures)
 { }
 
 void
 BluetoothAvrcpNotificationHandler::VolumeChangeNotification(
   uint8_t aVolume, uint8_t aCType)
 { }
 
 void
@@ -472,29 +472,29 @@ BluetoothGattNotificationHandler::~Bluet
 
 void
 BluetoothGattNotificationHandler::RegisterClientNotification(
   BluetoothGattStatus aStatus, int aClientIf, const BluetoothUuid& aAppUuid)
 { }
 
 void
 BluetoothGattNotificationHandler::ScanResultNotification(
-  const nsAString& aBdAddr, int aRssi, const BluetoothGattAdvData& aAdvData)
+  const BluetoothAddress& aBdAddr, int aRssi, const BluetoothGattAdvData& aAdvData)
 { }
 
 void
 BluetoothGattNotificationHandler::ConnectNotification(
   int aConnId, BluetoothGattStatus aStatus, int aClientIf,
-  const nsAString& aBdAddr)
+  const BluetoothAddress& aBdAddr)
 { }
 
 void
 BluetoothGattNotificationHandler::DisconnectNotification(
   int aConnId, BluetoothGattStatus aStatus, int aClientIf,
-  const nsAString& aBdAddr)
+  const BluetoothAddress& aBdAddr)
 { }
 
 void
 BluetoothGattNotificationHandler::SearchCompleteNotification(
   int aConnId, BluetoothGattStatus aStatus)
 { }
 
 void
@@ -562,33 +562,33 @@ BluetoothGattNotificationHandler::WriteD
 
 void
 BluetoothGattNotificationHandler::ExecuteWriteNotification(
   int aConnId, BluetoothGattStatus aStatus)
 { }
 
 void
 BluetoothGattNotificationHandler::ReadRemoteRssiNotification(
-  int aClientIf, const nsAString& aBdAddr, int aRssi,
+  int aClientIf, const BluetoothAddress& aBdAddr, int aRssi,
   BluetoothGattStatus aStatus)
 { }
 
 void
 BluetoothGattNotificationHandler::ListenNotification(
   BluetoothGattStatus aStatus, int aServerIf)
 { }
 
 void
 BluetoothGattNotificationHandler::RegisterServerNotification(
   BluetoothGattStatus aStatus, int aServerIf, const BluetoothUuid& aAppUuid)
 { }
 
 void
 BluetoothGattNotificationHandler::ConnectionNotification(
-  int aConnId, int aServerIf, bool aConnected, const nsAString& aBdAddr)
+  int aConnId, int aServerIf, bool aConnected, const BluetoothAddress& aBdAddr)
 { }
 
 void
 BluetoothGattNotificationHandler::ServiceAddedNotification(
   BluetoothGattStatus aStatus, int aServerIf,
   const BluetoothGattServiceId& aServiceId,
   const BluetoothAttributeHandle& aServiceHandle)
 { }
@@ -629,30 +629,30 @@ BluetoothGattNotificationHandler::Servic
 void
 BluetoothGattNotificationHandler::ServiceDeletedNotification(
   BluetoothGattStatus aStatus, int aServerIf,
   const BluetoothAttributeHandle& aServiceHandle)
 { }
 
 void
 BluetoothGattNotificationHandler::RequestReadNotification(
-  int aConnId, int aTransId, const nsAString& aBdAddr,
+  int aConnId, int aTransId, const BluetoothAddress& aBdAddr,
   const BluetoothAttributeHandle& aAttributeHandle, int aOffset, bool aIsLong)
 { }
 
 void
 BluetoothGattNotificationHandler::RequestWriteNotification(
-  int aConnId, int aTransId, const nsAString& aBdAddr,
+  int aConnId, int aTransId, const BluetoothAddress& aBdAddr,
   const BluetoothAttributeHandle& aAttributeHandle, int aOffset, int aLength,
   const uint8_t* aValue, bool aNeedResponse, bool aIsPrepareWrite)
 { }
 
 void
 BluetoothGattNotificationHandler::RequestExecuteWriteNotification(
-  int aConnId, int aTransId, const nsAString& aBdAddr, bool aExecute)
+  int aConnId, int aTransId, const BluetoothAddress& aBdAddr, bool aExecute)
 { }
 
 void
 BluetoothGattNotificationHandler::ResponseConfirmationNotification(
   BluetoothGattStatus aStatus, int aHandle)
 { }
 
 void
@@ -856,49 +856,50 @@ BluetoothNotificationHandler::AdapterSta
 void
 BluetoothNotificationHandler::AdapterPropertiesNotification(
   BluetoothStatus aStatus,int aNumProperties,
   const BluetoothProperty* aProperties)
 { }
 
 void
 BluetoothNotificationHandler::RemoteDevicePropertiesNotification(
-  BluetoothStatus aStatus, const nsAString& aBdAddr, int aNumProperties,
-  const BluetoothProperty* aProperties)
+  BluetoothStatus aStatus, const BluetoothAddress& aBdAddr,
+  int aNumProperties, const BluetoothProperty* aProperties)
 { }
 
 void
 BluetoothNotificationHandler::DeviceFoundNotification(
   int aNumProperties, const BluetoothProperty* aProperties)
 { }
 
 void
 BluetoothNotificationHandler::DiscoveryStateChangedNotification(bool aState)
 { }
 
 void
 BluetoothNotificationHandler::PinRequestNotification(
-  const nsAString& aRemoteBdAddr, const nsAString& aBdName, uint32_t aCod)
+  const BluetoothAddress& aRemoteBdAddr, const nsAString& aBdName,
+  uint32_t aCod)
 { }
 
 void
 BluetoothNotificationHandler::SspRequestNotification(
-  const nsAString& aRemoteBdAddr, const nsAString& aBdName, uint32_t aCod,
-  BluetoothSspVariant aPairingVariant, uint32_t aPassKey)
+  const BluetoothAddress& aRemoteBdAddr, const nsAString& aBdName,
+  uint32_t aCod, BluetoothSspVariant aPairingVariant, uint32_t aPassKey)
 { }
 
 void
 BluetoothNotificationHandler::BondStateChangedNotification(
-  BluetoothStatus aStatus, const nsAString& aRemoteBdAddr,
+  BluetoothStatus aStatus, const BluetoothAddress& aRemoteBdAddr,
   BluetoothBondState aState)
 { }
 
 void
 BluetoothNotificationHandler::AclStateChangedNotification(
-  BluetoothStatus aStatus, const nsAString& aRemoteBdAddr, bool aState)
+  BluetoothStatus aStatus, const BluetoothAddress& aRemoteBdAddr, bool aState)
 { }
 
 void
 BluetoothNotificationHandler::DutModeRecvNotification(uint16_t aOpcode,
                                                       const uint8_t* aBuf,
                                                       uint8_t aLen)
 { }
 
--- a/dom/bluetooth/common/BluetoothInterface.h
+++ b/dom/bluetooth/common/BluetoothInterface.h
@@ -36,19 +36,19 @@ protected:
 
 class BluetoothSocketResultHandler
   : public mozilla::ipc::DaemonSocketResultHandler
 {
 public:
   virtual void OnError(BluetoothStatus aStatus);
 
   virtual void Listen(int aSockFd);
-  virtual void Connect(int aSockFd, const nsAString& aBdAddress,
+  virtual void Connect(int aSockFd, const BluetoothAddress& aBdAddress,
                        int aConnectionState);
-  virtual void Accept(int aSockFd, const nsAString& aBdAddress,
+  virtual void Accept(int aSockFd, const BluetoothAddress& aBdAddress,
                       int aConnectionState);
 
 protected:
   virtual ~BluetoothSocketResultHandler() { }
 };
 
 class BluetoothSocketInterface
 {
@@ -56,17 +56,17 @@ public:
   // Init and Cleanup is handled by BluetoothInterface
 
   virtual void Listen(BluetoothSocketType aType,
                       const nsAString& aServiceName,
                       const BluetoothUuid& aServiceUuid,
                       int aChannel, bool aEncrypt, bool aAuth,
                       BluetoothSocketResultHandler* aRes) = 0;
 
-  virtual void Connect(const nsAString& aBdAddr,
+  virtual void Connect(const BluetoothAddress& aBdAddr,
                        BluetoothSocketType aType,
                        const BluetoothUuid& aServiceUuid,
                        int aChannel, bool aEncrypt, bool aAuth,
                        BluetoothSocketResultHandler* aRes) = 0;
 
   virtual void Accept(int aFd, BluetoothSocketResultHandler* aRes) = 0;
 
   virtual void Close(BluetoothSocketResultHandler* aRes) = 0;
@@ -79,75 +79,75 @@ protected:
 // Handsfree Interface
 //
 
 class BluetoothHandsfreeNotificationHandler
 {
 public:
   virtual void
   ConnectionStateNotification(BluetoothHandsfreeConnectionState aState,
-                              const nsAString& aBdAddr);
+                              const BluetoothAddress& aBdAddr);
 
   virtual void
   AudioStateNotification(BluetoothHandsfreeAudioState aState,
-                         const nsAString& aBdAddr);
+                         const BluetoothAddress& aBdAddr);
 
   virtual void
   VoiceRecognitionNotification(BluetoothHandsfreeVoiceRecognitionState aState,
-                               const nsAString& aBdAddr);
+                               const BluetoothAddress& aBdAddr);
 
   virtual void
-  AnswerCallNotification(const nsAString& aBdAddr);
+  AnswerCallNotification(const BluetoothAddress& aBdAddr);
 
   virtual void
-  HangupCallNotification(const nsAString& aBdAddr);
+  HangupCallNotification(const BluetoothAddress& aBdAddr);
 
   virtual void
   VolumeNotification(BluetoothHandsfreeVolumeType aType,
                      int aVolume,
-                     const nsAString& aBdAddr);
+                     const BluetoothAddress& aBdAddr);
 
   virtual void
   DialCallNotification(const nsAString& aNumber,
-                       const nsAString& aBdAddr);
+                       const BluetoothAddress& aBdAddr);
 
   virtual void
   DtmfNotification(char aDtmf,
-                   const nsAString& aBdAddr);
+                   const BluetoothAddress& aBdAddr);
 
   virtual void
   NRECNotification(BluetoothHandsfreeNRECState aNrec,
-                   const nsAString& aBdAddr);
+                   const BluetoothAddress& aBdAddr);
 
   virtual void
   WbsNotification(BluetoothHandsfreeWbsConfig aWbs,
-                  const nsAString& aBdAddr);
+                  const BluetoothAddress& aBdAddr);
 
   virtual void
   CallHoldNotification(BluetoothHandsfreeCallHoldType aChld,
-                       const nsAString& aBdAddr);
+                       const BluetoothAddress& aBdAddr);
 
   virtual void
-  CnumNotification(const nsAString& aBdAddr);
+  CnumNotification(const BluetoothAddress& aBdAddr);
 
   virtual void
-  CindNotification(const nsAString& aBdAddr);
+  CindNotification(const BluetoothAddress& aBdAddr);
 
   virtual void
-  CopsNotification(const nsAString& aBdAddr);
+  CopsNotification(const BluetoothAddress& aBdAddr);
 
   virtual void
-  ClccNotification(const nsAString& aBdAddr);
+  ClccNotification(const BluetoothAddress& aBdAddr);
 
   virtual void
   UnknownAtNotification(const nsACString& aAtString,
-                        const nsAString& aBdAddr);
+                        const BluetoothAddress& aBdAddr);
 
   virtual void
-  KeyPressedNotification(const nsAString& aBdAddr);
+  KeyPressedNotification(const BluetoothAddress& aBdAddr);
 
 protected:
   BluetoothHandsfreeNotificationHandler();
   virtual ~BluetoothHandsfreeNotificationHandler();
 };
 
 class BluetoothHandsfreeResultHandler
   : public mozilla::ipc::DaemonSocketResultHandler
@@ -188,78 +188,79 @@ class BluetoothHandsfreeInterface
 public:
   virtual void Init(
     BluetoothHandsfreeNotificationHandler* aNotificationHandler,
     int aMaxNumClients, BluetoothHandsfreeResultHandler* aRes) = 0;
   virtual void Cleanup(BluetoothHandsfreeResultHandler* aRes) = 0;
 
   /* Connect / Disconnect */
 
-  virtual void Connect(const nsAString& aBdAddr,
+  virtual void Connect(const BluetoothAddress& aBdAddr,
                        BluetoothHandsfreeResultHandler* aRes) = 0;
-  virtual void Disconnect(const nsAString& aBdAddr,
+  virtual void Disconnect(const BluetoothAddress& aBdAddr,
                           BluetoothHandsfreeResultHandler* aRes) = 0;
-  virtual void ConnectAudio(const nsAString& aBdAddr,
+  virtual void ConnectAudio(const BluetoothAddress& aBdAddr,
                             BluetoothHandsfreeResultHandler* aRes) = 0;
-  virtual void DisconnectAudio(const nsAString& aBdAddr,
+  virtual void DisconnectAudio(const BluetoothAddress& aBdAddr,
                                BluetoothHandsfreeResultHandler* aRes) = 0;
 
   /* Voice Recognition */
 
-  virtual void StartVoiceRecognition(const nsAString& aBdAddr,
+  virtual void StartVoiceRecognition(const BluetoothAddress& aBdAddr,
                                      BluetoothHandsfreeResultHandler* aRes) = 0;
-  virtual void StopVoiceRecognition(const nsAString& aBdAddr,
+  virtual void StopVoiceRecognition(const BluetoothAddress& aBdAddr,
                                     BluetoothHandsfreeResultHandler* aRes) = 0;
 
   /* Volume */
 
   virtual void VolumeControl(BluetoothHandsfreeVolumeType aType, int aVolume,
-                             const nsAString& aBdAddr,
+                             const BluetoothAddress& aBdAddr,
                              BluetoothHandsfreeResultHandler* aRes) = 0;
 
   /* Device status */
 
   virtual void DeviceStatusNotification(
     BluetoothHandsfreeNetworkState aNtkState,
     BluetoothHandsfreeServiceType aSvcType,
     int aSignal, int aBattChg, BluetoothHandsfreeResultHandler* aRes) = 0;
 
   /* Responses */
 
-  virtual void CopsResponse(const char* aCops, const nsAString& aBdAddr,
+  virtual void CopsResponse(const char* aCops, const BluetoothAddress& aBdAddr,
                             BluetoothHandsfreeResultHandler* aRes) = 0;
   virtual void CindResponse(int aSvc, int aNumActive, int aNumHeld,
                             BluetoothHandsfreeCallState aCallSetupState,
                             int aSignal, int aRoam, int aBattChg,
-                            const nsAString& aBdAddr,
+                            const BluetoothAddress& aBdAddr,
                             BluetoothHandsfreeResultHandler* aRes) = 0;
-  virtual void FormattedAtResponse(const char* aRsp, const nsAString& aBdAddr,
+  virtual void FormattedAtResponse(const char* aRsp,
+                                   const BluetoothAddress& aBdAddr,
                                    BluetoothHandsfreeResultHandler* aRes) = 0;
   virtual void AtResponse(BluetoothHandsfreeAtResponse aResponseCode,
-                          int aErrorCode, const nsAString& aBdAddr,
+                          int aErrorCode, const BluetoothAddress& aBdAddr,
                           BluetoothHandsfreeResultHandler* aRes) = 0;
   virtual void ClccResponse(int aIndex, BluetoothHandsfreeCallDirection aDir,
                             BluetoothHandsfreeCallState aState,
                             BluetoothHandsfreeCallMode aMode,
                             BluetoothHandsfreeCallMptyType aMpty,
                             const nsAString& aNumber,
                             BluetoothHandsfreeCallAddressType aType,
-                            const nsAString& aBdAddr,
+                            const BluetoothAddress& aBdAddr,
                             BluetoothHandsfreeResultHandler* aRes) = 0;
 
   /* Phone State */
 
   virtual void PhoneStateChange(int aNumActive, int aNumHeld,
                                 BluetoothHandsfreeCallState aCallSetupState,
                                 const nsAString& aNumber,
                                 BluetoothHandsfreeCallAddressType aType,
                                 BluetoothHandsfreeResultHandler* aRes) = 0;
 
   /* Wide Band Speech */
-  virtual void ConfigureWbs(const nsAString& aBdAddr,
+  virtual void ConfigureWbs(const BluetoothAddress& aBdAddr,
                             BluetoothHandsfreeWbsConfig aConfig,
                             BluetoothHandsfreeResultHandler* aRes) = 0;
 
 protected:
   BluetoothHandsfreeInterface();
   virtual ~BluetoothHandsfreeInterface();
 };
 
@@ -267,24 +268,24 @@ protected:
 // Bluetooth Advanced Audio Interface
 //
 
 class BluetoothA2dpNotificationHandler
 {
 public:
   virtual void
   ConnectionStateNotification(BluetoothA2dpConnectionState aState,
-                              const nsAString& aBdAddr);
+                              const BluetoothAddress& aBdAddr);
 
   virtual void
   AudioStateNotification(BluetoothA2dpAudioState aState,
-                         const nsAString& aBdAddr);
+                         const BluetoothAddress& aBdAddr);
 
   virtual void
-  AudioConfigNotification(const nsAString& aBdAddr,
+  AudioConfigNotification(const BluetoothAddress& aBdAddr,
                           uint32_t aSampleRate,
                           uint8_t aChannelCount);
 
 protected:
   BluetoothA2dpNotificationHandler();
   virtual ~BluetoothA2dpNotificationHandler();
 };
 
@@ -305,19 +306,19 @@ protected:
 
 class BluetoothA2dpInterface
 {
 public:
   virtual void Init(BluetoothA2dpNotificationHandler* aNotificationHandler,
                     BluetoothA2dpResultHandler* aRes) = 0;
   virtual void Cleanup(BluetoothA2dpResultHandler* aRes) = 0;
 
-  virtual void Connect(const nsAString& aBdAddr,
+  virtual void Connect(const BluetoothAddress& aBdAddr,
                        BluetoothA2dpResultHandler* aRes) = 0;
-  virtual void Disconnect(const nsAString& aBdAddr,
+  virtual void Disconnect(const BluetoothAddress& aBdAddr,
                           BluetoothA2dpResultHandler* aRes) = 0;
 
 protected:
   BluetoothA2dpInterface();
   virtual ~BluetoothA2dpInterface();
 };
 
 //
@@ -356,17 +357,17 @@ public:
   GetElementAttrNotification(uint8_t aNumAttrs,
                              const BluetoothAvrcpMediaAttribute* aAttrs);
 
   virtual void
   RegisterNotificationNotification(BluetoothAvrcpEvent aEvent,
                                    uint32_t aParam);
 
   virtual void
-  RemoteFeatureNotification(const nsAString& aBdAddr,
+  RemoteFeatureNotification(const BluetoothAddress& aBdAddr,
                             unsigned long aFeatures);
 
   virtual void
   VolumeChangeNotification(uint8_t aVolume, uint8_t aCType);
 
   virtual void
   PassthroughCmdNotification(int aId, int aKeyState);
 
@@ -463,31 +464,31 @@ class BluetoothGattNotificationHandler
 {
 public:
   virtual void
   RegisterClientNotification(BluetoothGattStatus aStatus,
                              int aClientIf,
                              const BluetoothUuid& aAppUuid);
 
   virtual void
-  ScanResultNotification(const nsAString& aBdAddr,
+  ScanResultNotification(const BluetoothAddress& aBdAddr,
                          int aRssi,
                          const BluetoothGattAdvData& aAdvData);
 
   virtual void
   ConnectNotification(int aConnId,
                       BluetoothGattStatus aStatus,
                       int aClientIf,
-                      const nsAString& aBdAddr);
+                      const BluetoothAddress& aBdAddr);
 
   virtual void
   DisconnectNotification(int aConnId,
                          BluetoothGattStatus aStatus,
                          int aClientIf,
-                         const nsAString& aBdAddr);
+                         const BluetoothAddress& aBdAddr);
 
   virtual void
   SearchCompleteNotification(int aConnId, BluetoothGattStatus aStatus);
 
   virtual void
   SearchResultNotification(int aConnId,
                            const BluetoothGattServiceId& aServiceId);
 
@@ -542,33 +543,33 @@ public:
                               BluetoothGattStatus aStatus,
                               const BluetoothGattWriteParam& aWriteParam);
 
   virtual void
   ExecuteWriteNotification(int aConnId, BluetoothGattStatus aStatus);
 
   virtual void
   ReadRemoteRssiNotification(int aClientIf,
-                             const nsAString& aBdAddr,
+                             const BluetoothAddress& aBdAddr,
                              int aRssi,
                              BluetoothGattStatus aStatus);
 
   virtual void
   ListenNotification(BluetoothGattStatus aStatus, int aServerIf);
 
   virtual void
   RegisterServerNotification(BluetoothGattStatus aStatus,
                              int aServerIf,
                              const BluetoothUuid& aAppUuid);
 
   virtual void
   ConnectionNotification(int aConnId,
                          int aServerIf,
                          bool aConnected,
-                         const nsAString& aBdAddr);
+                         const BluetoothAddress& aBdAddr);
 
   virtual void
   ServiceAddedNotification(BluetoothGattStatus aStatus,
                            int aServerIf,
                            const BluetoothGattServiceId& aServiceId,
                            const BluetoothAttributeHandle& aServiceHandle);
 
   virtual void
@@ -607,36 +608,36 @@ public:
   virtual void
   ServiceDeletedNotification(BluetoothGattStatus aStatus,
                              int aServerIf,
                              const BluetoothAttributeHandle& aServiceHandle);
 
   virtual void
   RequestReadNotification(int aConnId,
                           int aTransId,
-                          const nsAString& aBdAddr,
+                          const BluetoothAddress& aBdAddr,
                           const BluetoothAttributeHandle& aAttributeHandle,
                           int aOffset,
                           bool aIsLong);
 
   virtual void
   RequestWriteNotification(int aConnId,
                            int aTransId,
-                           const nsAString& aBdAddr,
+                           const BluetoothAddress& aBdAddr,
                            const BluetoothAttributeHandle& aAttributeHandle,
                            int aOffset,
                            int aLength,
                            const uint8_t* aValue,
                            bool aNeedResponse,
                            bool aIsPrepareWrite);
 
   virtual void
   RequestExecuteWriteNotification(int aConnId,
                                   int aTransId,
-                                  const nsAString& aBdAddr,
+                                  const BluetoothAddress& aBdAddr,
                                   bool aExecute); /* true: execute */
                                                   /* false: cancel */
 
   virtual void
   ResponseConfirmationNotification(BluetoothGattStatus aStatus,
                                    int aHandle);
 
   virtual void
@@ -733,33 +734,33 @@ public:
                                 BluetoothGattResultHandler* aRes) = 0;
 
   /* Start / Stop LE Scan */
   virtual void Scan(int aClientIf, bool aStart,
                     BluetoothGattResultHandler* aRes) = 0;
 
   /* Connect / Disconnect */
   virtual void Connect(int aClientIf,
-                       const nsAString& aBdAddr,
+                       const BluetoothAddress& aBdAddr,
                        bool aIsDirect, /* auto connect */
                        BluetoothTransport aTransport,
                        BluetoothGattResultHandler* aRes) = 0;
   virtual void Disconnect(int aClientIf,
-                          const nsAString& aBdAddr,
+                          const BluetoothAddress& aBdAddr,
                           int aConnId,
                           BluetoothGattResultHandler* aRes) = 0;
 
   /* Start / Stop advertisements to listen for incoming connections */
   virtual void Listen(int aClientIf,
                       bool aIsStart,
                       BluetoothGattResultHandler* aRes) = 0;
 
   /* Clear the attribute cache for a given device*/
   virtual void Refresh(int aClientIf,
-                       const nsAString& aBdAddr,
+                       const BluetoothAddress& aBdAddr,
                        BluetoothGattResultHandler* aRes) = 0;
 
   /* Enumerate Attributes */
   virtual void SearchService(int aConnId,
                              bool aSearchAll,
                              const BluetoothUuid& aUuid,
                              BluetoothGattResultHandler* aRes) = 0;
   virtual void GetIncludedService(
@@ -811,32 +812,32 @@ public:
   /* Execute / Abort Prepared Write*/
   virtual void ExecuteWrite(int aConnId,
                             int aIsExecute,
                             BluetoothGattResultHandler* aRes) = 0;
 
   /* Register / Deregister Characteristic Notifications or Indications */
   virtual void RegisterNotification(
     int aClientIf,
-    const nsAString& aBdAddr,
+    const BluetoothAddress& aBdAddr,
     const BluetoothGattServiceId& aServiceId,
     const BluetoothGattId& aCharId,
     BluetoothGattResultHandler* aRes) = 0;
   virtual void DeregisterNotification(
     int aClientIf,
-    const nsAString& aBdAddr,
+    const BluetoothAddress& aBdAddr,
     const BluetoothGattServiceId& aServiceId,
     const BluetoothGattId& aCharId,
     BluetoothGattResultHandler* aRes) = 0;
 
   virtual void ReadRemoteRssi(int aClientIf,
-                              const nsAString& aBdAddr,
+                              const BluetoothAddress& aBdAddr,
                               BluetoothGattResultHandler* aRes) = 0;
 
-  virtual void GetDeviceType(const nsAString& aBdAddr,
+  virtual void GetDeviceType(const BluetoothAddress& aBdAddr,
                              BluetoothGattResultHandler* aRes) = 0;
 
   /* Set advertising data or scan response data */
   virtual void SetAdvData(int aServerIf,
                           bool aIsScanRsp,
                           bool aIsNameIncluded,
                           bool aIsTxPowerIncluded,
                           int aMinInterval,
@@ -857,22 +858,22 @@ public:
   /* Register / Unregister */
   virtual void RegisterServer(const BluetoothUuid& aUuid,
                               BluetoothGattResultHandler* aRes) = 0;
   virtual void UnregisterServer(int aServerIf,
                                 BluetoothGattResultHandler* aRes) = 0;
 
   /* Connect / Disconnect */
   virtual void ConnectPeripheral(int aServerIf,
-                                 const nsAString& aBdAddr,
+                                 const BluetoothAddress& aBdAddr,
                                  bool aIsDirect, /* auto connect */
                                  BluetoothTransport aTransport,
                                  BluetoothGattResultHandler* aRes) = 0;
   virtual void DisconnectPeripheral(int aServerIf,
-                                    const nsAString& aBdAddr,
+                                    const BluetoothAddress& aBdAddr,
                                     int aConnId,
                                     BluetoothGattResultHandler* aRes) = 0;
 
   /* Add a services / a characteristic / a descriptor */
   virtual void AddService(int aServerIf,
                           const BluetoothGattServiceId& aServiceId,
                           uint16_t aNumHandles,
                           BluetoothGattResultHandler* aRes) = 0;
@@ -934,39 +935,39 @@ class BluetoothNotificationHandler
 {
 public:
   virtual void AdapterStateChangedNotification(bool aState);
   virtual void AdapterPropertiesNotification(
     BluetoothStatus aStatus, int aNumProperties,
     const BluetoothProperty* aProperties);
 
   virtual void RemoteDevicePropertiesNotification(
-    BluetoothStatus aStatus, const nsAString& aBdAddr,
+    BluetoothStatus aStatus, const BluetoothAddress& aBdAddr,
     int aNumProperties, const BluetoothProperty* aProperties);
 
   virtual void DeviceFoundNotification(
     int aNumProperties, const BluetoothProperty* aProperties);
 
   virtual void DiscoveryStateChangedNotification(bool aState);
 
-  virtual void PinRequestNotification(const nsAString& aRemoteBdAddr,
+  virtual void PinRequestNotification(const BluetoothAddress& aRemoteBdAddr,
                                       const nsAString& aBdName,
                                       uint32_t aCod);
-  virtual void SspRequestNotification(const nsAString& aRemoteBdAddr,
+  virtual void SspRequestNotification(const BluetoothAddress& aRemoteBdAddr,
                                       const nsAString& aBdName,
                                       uint32_t aCod,
                                       BluetoothSspVariant aPairingVariant,
                                       uint32_t aPassKey);
 
-  virtual void BondStateChangedNotification(BluetoothStatus aStatus,
-                                            const nsAString& aRemoteBdAddr,
-                                            BluetoothBondState aState);
-  virtual void AclStateChangedNotification(BluetoothStatus aStatus,
-                                           const nsAString& aRemoteBdAddr,
-                                           bool aState);
+  virtual void BondStateChangedNotification(
+    BluetoothStatus aStatus, const BluetoothAddress& aRemoteBdAddr,
+    BluetoothBondState aState);
+  virtual void AclStateChangedNotification(
+    BluetoothStatus aStatus, const BluetoothAddress& aRemoteBdAddr,
+    bool aState);
 
   virtual void DutModeRecvNotification(uint16_t aOpcode,
                                        const uint8_t* aBuf, uint8_t aLen);
   virtual void LeTestModeNotification(BluetoothStatus aStatus,
                                       uint16_t aNumPackets);
 
   virtual void EnergyInfoNotification(const BluetoothActivityEnergyInfo& aInfo);
 
@@ -1039,60 +1040,61 @@ public:
   virtual void GetAdapterProperties(BluetoothResultHandler* aRes) = 0;
   virtual void GetAdapterProperty(const nsAString& aName,
                                   BluetoothResultHandler* aRes) = 0;
   virtual void SetAdapterProperty(const BluetoothNamedValue& aProperty,
                                   BluetoothResultHandler* aRes) = 0;
 
   /* Remote Device Properties */
 
-  virtual void GetRemoteDeviceProperties(const nsAString& aRemoteAddr,
+  virtual void GetRemoteDeviceProperties(const BluetoothAddress& aRemoteAddr,
                                          BluetoothResultHandler* aRes) = 0;
-  virtual void GetRemoteDeviceProperty(const nsAString& aRemoteAddr,
+  virtual void GetRemoteDeviceProperty(const BluetoothAddress& aRemoteAddr,
                                        const nsAString& aName,
                                        BluetoothResultHandler* aRes) = 0;
-  virtual void SetRemoteDeviceProperty(const nsAString& aRemoteAddr,
+  virtual void SetRemoteDeviceProperty(const BluetoothAddress& aRemoteAddr,
                                        const BluetoothNamedValue& aProperty,
                                        BluetoothResultHandler* aRes) = 0;
 
   /* Remote Services */
 
-  virtual void GetRemoteServiceRecord(const nsAString& aRemoteAddr,
+  virtual void GetRemoteServiceRecord(const BluetoothAddress& aRemoteAddr,
                                       const BluetoothUuid& aUuid,
                                       BluetoothResultHandler* aRes) = 0;
-  virtual void GetRemoteServices(const nsAString& aRemoteAddr,
+  virtual void GetRemoteServices(const BluetoothAddress& aRemoteAddr,
                                  BluetoothResultHandler* aRes) = 0;
 
   /* Discovery */
 
   virtual void StartDiscovery(BluetoothResultHandler* aRes) = 0;
   virtual void CancelDiscovery(BluetoothResultHandler* aRes) = 0;
 
   /* Bonds */
 
-  virtual void CreateBond(const nsAString& aBdAddr,
+  virtual void CreateBond(const BluetoothAddress& aBdAddr,
                           BluetoothTransport aTransport,
                           BluetoothResultHandler* aRes) = 0;
-  virtual void RemoveBond(const nsAString& aBdAddr,
+  virtual void RemoveBond(const BluetoothAddress& aBdAddr,
                           BluetoothResultHandler* aRes) = 0;
-  virtual void CancelBond(const nsAString& aBdAddr,
+  virtual void CancelBond(const BluetoothAddress& aBdAddr,
                           BluetoothResultHandler* aRes) = 0;
 
   /* Connection */
 
-  virtual void GetConnectionState(const nsAString& aBdAddr,
+  virtual void GetConnectionState(const BluetoothAddress& aBdAddr,
                                   BluetoothResultHandler* aRes) = 0;
 
   /* Authentication */
 
-  virtual void PinReply(const nsAString& aBdAddr, bool aAccept,
+  virtual void PinReply(const BluetoothAddress& aBdAddr, bool aAccept,
                         const nsAString& aPinCode,
                         BluetoothResultHandler* aRes) = 0;
 
-  virtual void SspReply(const nsAString& aBdAddr, BluetoothSspVariant aVariant,
+  virtual void SspReply(const BluetoothAddress& aBdAddr,
+                        BluetoothSspVariant aVariant,
                         bool aAccept, uint32_t aPasskey,
                         BluetoothResultHandler* aRes) = 0;
 
   /* DUT Mode */
 
   virtual void DutModeConfigure(bool aEnable,
                                 BluetoothResultHandler* aRes) = 0;
   virtual void DutModeSend(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
--- a/dom/bluetooth/common/BluetoothUtils.cpp
+++ b/dom/bluetooth/common/BluetoothUtils.cpp
@@ -15,16 +15,58 @@
 #include "nsISystemMessagesInternal.h"
 #include "nsIUUIDGenerator.h"
 #include "nsServiceManagerUtils.h"
 #include "nsXULAppAPI.h"
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 void
+AddressToString(const BluetoothAddress& aAddress, nsAString& aString)
+{
+  char str[BLUETOOTH_ADDRESS_LENGTH + 1];
+
+  int res = snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
+                     static_cast<int>(aAddress.mAddr[0]),
+                     static_cast<int>(aAddress.mAddr[1]),
+                     static_cast<int>(aAddress.mAddr[2]),
+                     static_cast<int>(aAddress.mAddr[3]),
+                     static_cast<int>(aAddress.mAddr[4]),
+                     static_cast<int>(aAddress.mAddr[5]));
+
+  if ((res == EOF) ||
+      (res < 0) ||
+      (static_cast<size_t>(res) >= sizeof(str))) {
+    /* Conversion should have succeeded or (a) we're out of memory, or
+     * (b) our code is massively broken. We should crash in both cases.
+     */
+    MOZ_CRASH("Failed to convert Bluetooth address to string");
+  }
+
+  aString = NS_ConvertUTF8toUTF16(str);
+}
+
+nsresult
+StringToAddress(const nsAString& aString, BluetoothAddress& aAddress)
+{
+  int res = sscanf(NS_ConvertUTF16toUTF8(aString).get(),
+                   "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
+                   &aAddress.mAddr[0],
+                   &aAddress.mAddr[1],
+                   &aAddress.mAddr[2],
+                   &aAddress.mAddr[3],
+                   &aAddress.mAddr[4],
+                   &aAddress.mAddr[5]);
+  if (res < static_cast<ssize_t>(MOZ_ARRAY_LENGTH(aAddress.mAddr))) {
+    return NS_ERROR_ILLEGAL_VALUE;
+  }
+  return NS_OK;
+}
+
+void
 UuidToString(const BluetoothUuid& aUuid, nsAString& aString)
 {
   char uuidStr[37];
   uint32_t uuid0, uuid4;
   uint16_t uuid1, uuid2, uuid3, uuid5;
 
   memcpy(&uuid0, &aUuid.mUuid[0], sizeof(uint32_t));
   memcpy(&uuid1, &aUuid.mUuid[4], sizeof(uint16_t));
--- a/dom/bluetooth/common/BluetoothUtils.h
+++ b/dom/bluetooth/common/BluetoothUtils.h
@@ -19,16 +19,26 @@ class GattCharacteristicProperties;
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 class BluetoothNamedValue;
 class BluetoothReplyRunnable;
 class BluetoothValue;
 
 //
+// Address/String conversion
+//
+
+void
+AddressToString(const BluetoothAddress& aAddress, nsAString& aString);
+
+nsresult
+StringToAddress(const nsAString& aString, BluetoothAddress& aAddress);
+
+//
 // BluetoothUuid <-> uuid string conversion
 //
 
 /**
  * Convert BluetoothUuid object to xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx uuid string.
  *
  * Note: This utility function is used by gecko internal only to convert
  * BluetoothUuid created by bluetooth stack to uuid string representation.
--- a/dom/bluetooth/moz.build
+++ b/dom/bluetooth/moz.build
@@ -11,16 +11,17 @@ if CONFIG['MOZ_B2G_BT']:
     #
 
     if CONFIG['MOZ_B2G_RIL']:
         SOURCES += [
             'common/BluetoothRilListener.cpp'
         ]
 
     SOURCES += [
+        'common/BluetoothCommon.cpp',
         'common/BluetoothHidManager.cpp',
         'common/BluetoothInterface.cpp',
         'common/BluetoothProfileController.cpp',
         'common/BluetoothReplyRunnable.cpp',
         'common/BluetoothService.cpp',
         'common/BluetoothUtils.cpp',
         'common/BluetoothUuid.cpp',
         'common/ObexBase.cpp',
@@ -132,16 +133,17 @@ if CONFIG['MOZ_B2G_BT']:
 # Exported interfaces
 #
 
 EXPORTS.mozilla.dom.bluetooth.ipc += [
     'ipc/BluetoothMessageUtils.h',
 ]
 EXPORTS.mozilla.dom.bluetooth += [
     'common/BluetoothCommon.h',
+    'common/BluetoothHashKeys.h',
     'common/webapi/BluetoothAdapter.h',
     'common/webapi/BluetoothClassOfDevice.h',
     'common/webapi/BluetoothDevice.h',
     'common/webapi/BluetoothDiscoveryHandle.h',
     'common/webapi/BluetoothGatt.h',
     'common/webapi/BluetoothGattAttributeEvent.h',
     'common/webapi/BluetoothGattCharacteristic.h',
     'common/webapi/BluetoothGattDescriptor.h',
--- a/dom/settings/tests/test_settings_service.js
+++ b/dom/settings/tests/test_settings_service.js
@@ -91,16 +91,20 @@ var tests = [
               ok(false, "Event is not mozsettings-changed.");
               return;
             }
             // Data is now stored in subject
             if ("wrappedJSObject" in subject) {
               ok(true, "JS object wrapped into subject");
               subject = subject.wrappedJSObject;
             }
+            if (subject["key"] != TEST_OBSERVER_KEY) {
+              return;
+            }
+
             function checkProp(name, type, value) {
               ok(name in subject, "subject." + name + " is present");
               is(typeof subject[name], type, "subject." + name + " is " + type);
               is(subject[name], value, "subject." + name + " is " + value);
             }
 
             checkProp("key", "string", TEST_OBSERVER_KEY);
             checkProp("value", "boolean", TEST_OBSERVER_VALUE);
--- a/dom/system/gonk/AudioManager.cpp
+++ b/dom/system/gonk/AudioManager.cpp
@@ -123,16 +123,33 @@ public:
   void Run() override
   {
     mRunnable->Run();
   }
 protected:
   nsCOMPtr<nsIRunnable> mRunnable;
 };
 
+nsCOMPtr<nsISettingsServiceLock>
+GetSettingServiceLock()
+{
+  nsresult rv;
+  nsCOMPtr<nsISettingsService> service = do_GetService(SETTINGS_SERVICE, &rv);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return nullptr;
+  }
+
+  nsCOMPtr<nsISettingsServiceLock> lock;
+  rv = service->CreateLock(nullptr, getter_AddRefs(lock));
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return nullptr;
+  }
+  return lock.forget();
+}
+
 class AudioProfileData final
 {
 public:
   explicit AudioProfileData(AudioOutputProfiles aProfile)
     : mProfile(aProfile)
     , mActive(false)
   {
     for (uint32_t idx = 0; idx < VOLUME_TOTAL_NUMBER; ++idx) {
@@ -494,16 +511,22 @@ AudioManager::Observe(nsISupports* aSubj
     if (!setting.mValue.isNumber()) {
       return NS_OK;
     }
 
     uint32_t volIndex = setting.mValue.toNumber();
     for (uint32_t idx = 0; idx < VOLUME_TOTAL_NUMBER; ++idx) {
       if (setting.mKey.EqualsASCII(gVolumeData[idx].mChannelName)) {
         SetVolumeByCategory(gVolumeData[idx].mCategory, volIndex);
+        nsCOMPtr<nsISettingsServiceLock> lock = GetSettingServiceLock();
+        UpdateVolumeSettingToDatabase(lock.get(),
+                                      AppendProfileToVolumeSetting(
+                                        gVolumeData[idx].mChannelName,
+                                        mPresentProfile).get(),
+                                      volIndex);
         return NS_OK;
       }
     }
   }
 
   NS_WARNING("Unexpected topic in AudioManager");
   return NS_ERROR_FAILURE;
 }
@@ -658,19 +681,16 @@ AudioManager::~AudioManager() {
     NS_WARNING("Failed to remove bluetooth hfp NREC status changed observer!");
   }
   if (NS_FAILED(obs->RemoveObserver(this, MOZ_SETTINGS_CHANGE_ID))) {
     NS_WARNING("Failed to remove mozsettings-changed observer!");
   }
   if (NS_FAILED(obs->RemoveObserver(this,  AUDIO_CHANNEL_PROCESS_CHANGED))) {
     NS_WARNING("Failed to remove audio-channel-process-changed!");
   }
-
-  // Store the present volume setting to setting database.
-  SendVolumeChangeNotification(FindAudioProfileData(mPresentProfile));
 }
 
 static StaticRefPtr<AudioManager> sAudioManager;
 
 already_AddRefed<AudioManager>
 AudioManager::GetInstance()
 {
   // Avoid createing AudioManager from content process.
@@ -1138,43 +1158,43 @@ AudioManager::InitProfileVolumeSucceeded
 
 void
 AudioManager::InitProfileVolumeFailed(const char* aError)
 {
   NS_WARNING(aError);
 }
 
 void
+AudioManager::UpdateVolumeSettingToDatabase(nsISettingsServiceLock* aLock,
+                                            const char* aTopic,
+                                            uint32_t aVolIndex)
+{
+  MOZ_ASSERT(aLock);
+
+  mozilla::AutoSafeJSContext cx;
+  JS::Rooted<JS::Value> value(cx);
+  value.setInt32(aVolIndex);
+  aLock->Set(aTopic, value, nullptr, nullptr);
+}
+
+void
 AudioManager::SendVolumeChangeNotification(AudioProfileData* aProfileData)
 {
   MOZ_ASSERT(aProfileData);
-  nsresult rv;
-  nsCOMPtr<nsISettingsService> service = do_GetService(SETTINGS_SERVICE, &rv);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return;
-  }
 
-  nsCOMPtr<nsISettingsServiceLock> lock;
-  rv = service->CreateLock(nullptr, getter_AddRefs(lock));
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return;
-  }
-
-  // Send events to update the Gaia volume
-  mozilla::AutoSafeJSContext cx;
-  JS::Rooted<JS::Value> value(cx);
+  // Change the value of the current volume setting, so that the Gaia can get
+  // correct volume values and update the volume UI. In addition, for reducing
+  // the code dependency, Gaia doesn't need to know the current profile, it
+  // only need to care about different volume categories.
+  nsCOMPtr<nsISettingsServiceLock> lock = GetSettingServiceLock();
   for (uint32_t idx = 0; idx < VOLUME_TOTAL_NUMBER; ++idx) {
-    value.setInt32(aProfileData->mVolumeTable[gVolumeData[idx].mCategory]);
-    // For reducing the code dependency, Gaia doesn't need to know the current
-    // profile, it only need to care about different volume categories.
-    // However, we need to send the setting volume to the permanent database,
-    // so that we can store the volume setting even if the phone reboots.
-    lock->Set(gVolumeData[idx].mChannelName, value, nullptr, nullptr);
-    lock->Set(AppendProfileToVolumeSetting(gVolumeData[idx].mChannelName,
-               mPresentProfile).get(), value, nullptr, nullptr);
+    uint32_t volSetting = gVolumeData[idx].mCategory;
+    UpdateVolumeSettingToDatabase(lock.get(),
+                                  gVolumeData[idx].mChannelName,
+                                  aProfileData->mVolumeTable[volSetting]);
   }
 }
 
 void
 AudioManager::CreateAudioProfilesData()
 {
   MOZ_ASSERT(mAudioProfiles.IsEmpty(), "mAudioProfiles should be empty!");
   for (uint32_t idx = 0; idx < DEVICE_TOTAL_NUMBER; ++idx) {
--- a/dom/system/gonk/AudioManager.h
+++ b/dom/system/gonk/AudioManager.h
@@ -23,16 +23,18 @@
 #include "nsIObserver.h"
 #include "android_audio/AudioSystem.h"
 
 // {b2b51423-502d-4d77-89b3-7786b562b084}
 #define NS_AUDIOMANAGER_CID {0x94f6fd70, 0x7615, 0x4af9, \
       {0x89, 0x10, 0xf9, 0x3c, 0x55, 0xe6, 0x62, 0xec}}
 #define NS_AUDIOMANAGER_CONTRACTID "@mozilla.org/telephony/audiomanager;1"
 
+class nsISettingsServiceLock;
+
 namespace mozilla {
 namespace hal {
 class SwitchEvent;
 typedef Observer<SwitchEvent> SwitchObserver;
 } // namespace hal
 
 namespace dom {
 namespace gonk {
@@ -162,18 +164,21 @@ private:
   uint32_t GetMaxVolumeByCategory(uint32_t aCategory) const;
 
   AudioProfileData* FindAudioProfileData(AudioOutputProfiles aProfile);
 
   // Append the profile to the volume setting string.
   nsAutoCString AppendProfileToVolumeSetting(const char* aName,
                                              AudioOutputProfiles aProfile);
 
-  // Init volume from the settings database.
+  // We store the volume setting in the database, these are related functions.
   void InitVolumeFromDatabase();
+  void UpdateVolumeSettingToDatabase(nsISettingsServiceLock* aLock,
+                                     const char* aTopic,
+                                     uint32_t aVolIndex);
 
   // Promise functions.
   void InitProfileVolumeSucceeded();
   void InitProfileVolumeFailed(const char* aError);
 
   void UpdateHeadsetConnectionState(hal::SwitchState aState);
 
   AudioManager();