diff --git a/accessible/jsat/ContentControl.jsm b/accessible/jsat/ContentControl.jsm index 741da1fb2bd9..96b0bb005c4a 100644 --- a/accessible/jsat/ContentControl.jsm +++ b/accessible/jsat/ContentControl.jsm @@ -425,7 +425,12 @@ this.ContentControl.prototype = { let sentToChild = this.sendToChild(vc, { name: 'AccessFu:AutoMove', - json: aOptions + json: { + moveMethod: aOptions.moveMethod, + moveToFocused: aOptions.moveToFocused, + noOpIfOnScreen: true, + forcePresent: true + } }); if (!moved && !sentToChild) { diff --git a/accessible/jsat/EventManager.jsm b/accessible/jsat/EventManager.jsm index f93932e8d991..c4d6fe52469b 100644 --- a/accessible/jsat/EventManager.jsm +++ b/accessible/jsat/EventManager.jsm @@ -279,8 +279,10 @@ this.EventManager.prototype = { // Put vc where the focus is at let acc = aEvent.accessible; let doc = aEvent.accessibleDocument; - if (acc.role != Roles.DOCUMENT && doc.role != Roles.CHROME_WINDOW) { - this.contentControl.autoMove(acc); + if ([Roles.CHROME_WINDOW, + Roles.DOCUMENT, + Roles.APPLICATION].indexOf(acc.role) < 0) { + this.contentControl.autoMove(acc); } break; } diff --git a/accessible/jsat/Gestures.jsm b/accessible/jsat/Gestures.jsm index cecd40b648a1..3d2fd2fde982 100644 --- a/accessible/jsat/Gestures.jsm +++ b/accessible/jsat/Gestures.jsm @@ -228,7 +228,7 @@ this.GestureTracker = { // jshint ignore:line * @param {Number} aTimeStamp A new pointer event timeStamp. */ handle: function GestureTracker_handle(aDetail, aTimeStamp) { - Logger.debug(() => { + Logger.gesture(() => { return ['Pointer event', aDetail.type, 'at:', aTimeStamp, JSON.stringify(aDetail.points)]; }); @@ -332,7 +332,7 @@ function compileDetail(aType, aPoints, keyMap = {x: 'startX', y: 'startY'}) { */ function Gesture(aTimeStamp, aPoints = {}, aLastEvent = undefined) { this.startTime = Date.now(); - Logger.debug('Creating', this.id, 'gesture.'); + Logger.gesture('Creating', this.id, 'gesture.'); this.points = aPoints; this.lastEvent = aLastEvent; this._deferred = Promise.defer(); @@ -509,7 +509,7 @@ Gesture.prototype = { if (this.isComplete) { return; } - Logger.debug('Resolving', this.id, 'gesture.'); + Logger.gesture('Resolving', this.id, 'gesture.'); this.isComplete = true; let detail = this.compile(); if (detail) { @@ -533,7 +533,7 @@ Gesture.prototype = { if (this.isComplete) { return; } - Logger.debug('Rejecting', this.id, 'gesture.'); + Logger.gesture('Rejecting', this.id, 'gesture.'); this.isComplete = true; return { id: this.id, diff --git a/accessible/jsat/Utils.jsm b/accessible/jsat/Utils.jsm index d7fc792578db..57ab6c5176d3 100644 --- a/accessible/jsat/Utils.jsm +++ b/accessible/jsat/Utils.jsm @@ -473,11 +473,12 @@ State.prototype = { }; this.Logger = { // jshint ignore:line + GESTURE: -1, DEBUG: 0, INFO: 1, WARNING: 2, ERROR: 3, - _LEVEL_NAMES: ['DEBUG', 'INFO', 'WARNING', 'ERROR'], + _LEVEL_NAMES: ['GESTURE', 'DEBUG', 'INFO', 'WARNING', 'ERROR'], logLevel: 1, // INFO; @@ -490,7 +491,7 @@ this.Logger = { // jshint ignore:line let args = Array.prototype.slice.call(arguments, 1); let message = (typeof(args[0]) === 'function' ? args[0]() : args).join(' '); - message = '[' + Utils.ScriptName + '] ' + this._LEVEL_NAMES[aLogLevel] + + message = '[' + Utils.ScriptName + '] ' + this._LEVEL_NAMES[aLogLevel + 1] + ' ' + message + '\n'; dump(message); // Note: used for testing purposes. If |this.test| is true, also log to @@ -509,6 +510,11 @@ this.Logger = { // jshint ignore:line this, [this.INFO].concat(Array.prototype.slice.call(arguments))); }, + gesture: function gesture() { + this.log.apply( + this, [this.GESTURE].concat(Array.prototype.slice.call(arguments))); + }, + debug: function debug() { this.log.apply( this, [this.DEBUG].concat(Array.prototype.slice.call(arguments))); @@ -552,14 +558,16 @@ this.Logger = { // jshint ignore:line }, accessibleToString: function accessibleToString(aAccessible) { - let str = '[ defunct ]'; - try { - str = '[ ' + Utils.AccRetrieval.getStringRole(aAccessible.role) + - ' | ' + aAccessible.name + ' ]'; - } catch (x) { + if (!aAccessible) { + return '[ null ]'; } - return str; + try { + return'[ ' + Utils.AccRetrieval.getStringRole(aAccessible.role) + + ' | ' + aAccessible.name + ' ]'; + } catch (x) { + return '[ defunct ]'; + } }, eventToString: function eventToString(aEvent) { diff --git a/accessible/tests/mochitest/jsat/jsatcommon.js b/accessible/tests/mochitest/jsat/jsatcommon.js index 97c566bb9fe4..0f97929460a6 100644 --- a/accessible/tests/mochitest/jsat/jsatcommon.js +++ b/accessible/tests/mochitest/jsat/jsatcommon.js @@ -255,7 +255,7 @@ AccessFuContentTest.prototype = { this.currentPair = this.queue.shift(); if (this.currentPair) { - if (this.currentPair[0] instanceof Function) { + if (typeof this.currentPair[0] === 'function') { this.currentPair[0](this.mms[0]); } else if (this.currentPair[0]) { this.mms[0].sendAsyncMessage(this.currentPair[0].name, @@ -290,7 +290,11 @@ AccessFuContentTest.prototype = { if (expected.speak) { var checkFunc = SimpleTest[expected.speak_checkFunc] || isDeeply; checkFunc.apply(SimpleTest, [speech, expected.speak, - '"' + JSON.stringify(speech) + '" spoken']); + 'spoken: ' + JSON.stringify(speech) + + ' expected: ' + JSON.stringify(expected.speak) + + ' after: ' + (typeof this.currentPair[0] === 'function' ? + this.currentPair[0].toString() : + JSON.stringify(this.currentPair[0]))]); } if (expected.android) { diff --git a/accessible/tests/mochitest/jsat/test_content_integration.html b/accessible/tests/mochitest/jsat/test_content_integration.html index 5bbac658c195..14f7a4a62570 100644 --- a/accessible/tests/mochitest/jsat/test_content_integration.html +++ b/accessible/tests/mochitest/jsat/test_content_integration.html @@ -136,8 +136,8 @@ speak: ['wow', {'string': 'headingLevel', 'args': [1]}, 'such app'] }], [ContentMessages.focusSelector('button#home', false), { - speak: ['Home button'] - }] + speak: ['Home', {'string': 'pushbutton'}] + }], // Blur button and reset cursor [ContentMessages.focusSelector('button#home', true), null], @@ -152,13 +152,13 @@ speak: ['Phone status bar', 'Traversal Rule test document'] }], [doc.defaultView.showAlert, { - speak: ['This is an alert! heading level 1 dialog'] + speak: ['This is an alert!', + {'string': 'headingLevel', 'args': [1]}, + {'string': 'dialog'}] }], - [function() { - doc.defaultView.hideAlert() - }, { - speak: ['wow', {'string': 'headingLevel', 'args': [1]}, 'such app'] + [doc.defaultView.hideAlert, { + speak: ["wow", {"string": "headingLevel","args": [1]}, "such app"], }], [ContentMessages.clearCursor, 'AccessFu:CursorCleared'], @@ -171,12 +171,14 @@ speak: ['wow', {'string': 'headingLevel', 'args': [1]}, 'such app'] }], [doc.defaultView.showAlert, { - speak: ['This is an alert! heading level 1 dialog'] + speak: ['This is an alert!', + {'string': 'headingLevel', 'args': [1]}, + {'string': 'dialog'}] }], // XXX: Place cursor back where it was. [doc.defaultView.hideAlert, { - speak: ['many option not checked check button such app'] + speak: ['wow', {'string': 'headingLevel', 'args': [1]}, 'such app'], }], [ContentMessages.clearCursor, 'AccessFu:CursorCleared'], @@ -186,7 +188,9 @@ speak: ['Phone status bar', 'Traversal Rule test document'] }], [doc.defaultView.showAlert, { - speak: ['This is an alert! heading level 1 dialog'] + speak: ['This is an alert!', + {'string': 'headingLevel', 'args': [1]}, + {'string': 'dialog'}] }], [function() { diff --git a/b2g/chrome/content/shell.js b/b2g/chrome/content/shell.js index 885e38f7115a..6341b26b580c 100644 --- a/b2g/chrome/content/shell.js +++ b/b2g/chrome/content/shell.js @@ -522,8 +522,8 @@ var shell = { // based on tab's coordinate. So get the actual offsets between shell and evt.target. let elt = evt.target; let win = elt.ownerDocument.defaultView; - let offsetX = win.mozInnerScreenX; - let offsetY = win.mozInnerScreenY; + let offsetX = win.mozInnerScreenX - window.mozInnerScreenX; + let offsetY = win.mozInnerScreenY - window.mozInnerScreenY; let rect = elt.getBoundingClientRect(); offsetX += rect.left; diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 3a4f590e65c1..7df0ca77ae71 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,13 +19,13 @@ - + - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index d9f07e68f6db..b9babb11b9cf 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,10 +17,10 @@ - + - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index ce0d311ed4d2..4a12dcff25a8 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 3a4f590e65c1..7df0ca77ae71 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,13 +19,13 @@ - + - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index adf020c02175..c858bc45d90f 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,10 +17,10 @@ - + - + diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index a0ce63d4cb4f..00ee864ac91a 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "2fb6119da922ebdab70c79e7f515f49fa582b2c5", + "revision": "a5d998cfe7cd004c7967e40efaaad0ccb829ecc4", "repo_path": "/integration/gaia-central" } diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 9ba977901cd1..a8b5d1703430 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,12 +17,12 @@ - + - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 814bba4a6cbe..27153a46f257 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index a1ce7155d5de..03d8a9eb2c98 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,10 +17,10 @@ - + - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index ce0fbfcb823b..cc3d0197d66a 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,12 +17,12 @@ - + - + diff --git a/b2g/confvars.sh b/b2g/confvars.sh index 98ef5283328a..e45d482220f7 100644 --- a/b2g/confvars.sh +++ b/b2g/confvars.sh @@ -23,7 +23,7 @@ MOZ_SERVICES_METRICS=1 MOZ_CAPTIVEDETECT=1 MOZ_WEBSMS_BACKEND=1 -MOZ_DISABLE_CRYPTOLEGACY=1 +MOZ_NO_SMART_CARDS=1 MOZ_APP_STATIC_INI=1 NSS_NO_LIBPKIX=1 NSS_DISABLE_DBM=1 diff --git a/browser/themes/shared/devtools/webconsole.inc.css b/browser/themes/shared/devtools/webconsole.inc.css index aa49039dfd75..f471a4e87467 100644 --- a/browser/themes/shared/devtools/webconsole.inc.css +++ b/browser/themes/shared/devtools/webconsole.inc.css @@ -17,24 +17,24 @@ a { .message { display: flex; - flex: 0 0 main-size; + flex: none; padding: 0 7px; width: 100%; box-sizing: border-box; } .message > .timestamp { - flex: 0 0 main-size; + flex: none; color: GrayText; margin: 4px 6px 0 0; } .message > .indent { - flex: 0 0 main-size; + flex: none; } .message > .icon { - flex: 0 0 main-size; + flex: none; margin: 3px 6px 0 0; padding: 0 4px; height: 1em; @@ -66,7 +66,7 @@ a { /* The red bubble that shows the number of times a message is repeated */ .message-repeats { -moz-user-select: none; - flex: 0 0 main-size; + flex: none; margin: 2px 6px; padding: 0 6px; height: 1.25em; @@ -84,7 +84,7 @@ a { .message-location { display: flex; - flex: 0 0 main-size; + flex: none; align-self: flex-start; justify-content: flex-end; width: 10em; @@ -106,7 +106,7 @@ a { } .message-location > .line-number { - flex: 0 0 main-size; + flex: none; } .message-flex-body { @@ -236,7 +236,7 @@ a { } .message[category=network] .method { - flex: 0 0 main-size; + flex: none; } .message[category=network]:not(.navigation-marker) .url { @@ -250,7 +250,7 @@ a { } .message[category=network] .status { - flex: 0 0 main-size; + flex: none; -moz-margin-start: 6px; } diff --git a/build/autoconf/icu.m4 b/build/autoconf/icu.m4 index f7417d8f096a..df7f5edf3efd 100644 --- a/build/autoconf/icu.m4 +++ b/build/autoconf/icu.m4 @@ -180,7 +180,7 @@ if test -z "$BUILDING_JS" -o -n "$JS_STANDALONE"; then # --with-cross-build requires absolute path ICU_HOST_PATH=`cd $_objdir/intl/icu/host && pwd` - ICU_CROSS_BUILD_OPT="--with-cross-build=$ICU_HOST_PATH" + ICU_CROSS_BUILD_OPT="--with-cross-build=$ICU_HOST_PATH --disable-tools" ICU_TARGET_OPT="--build=$build --host=$target" else # CROSS_COMPILE isn't set build and target are i386 and x86-64. diff --git a/build/macosx/universal/unify b/build/macosx/universal/unify index 82b24560f411..38dd354145a0 100755 --- a/build/macosx/universal/unify +++ b/build/macosx/universal/unify @@ -1395,7 +1395,7 @@ sub readZipCRCs($) { if ($$this{'magicInit'}) { if (defined($$this{'magicErrno'})) { if (defined($$this{'magicErrMsg'})) { - complain(1, 'FileAttrCache::magic: '.$$this{'magicErrMsg'}.' for:', + main::complain(1, 'FileAttrCache::magic: '.$$this{'magicErrMsg'}.' for:', $$this{'path'}); } $! = $$this{'magicErrno'}; @@ -1409,7 +1409,7 @@ sub readZipCRCs($) { if (!sysopen($fh, $$this{'path'}, O_RDONLY)) { $$this{'magicErrno'} = $!; $$this{'magicErrMsg'} = 'open "'.$$this{'path'}.'": '.$!; - complain(1, 'FileAttrCache::magic: '.$$this{'magicErrMsg'}.' for:', + main::complain(1, 'FileAttrCache::magic: '.$$this{'magicErrMsg'}.' for:', $$this{'path'}); return undef; } @@ -1419,7 +1419,7 @@ sub readZipCRCs($) { if (!defined($bytes = sysread($fh, $magic, 4))) { $$this{'magicErrno'} = $!; $$this{'magicErrMsg'} = 'read "'.$$this{'path'}.'": '.$!; - complain(1, 'FileAttrCache::magic: '.$$this{'magicErrMsg'}.' for:', + main::complain(1, 'FileAttrCache::magic: '.$$this{'magicErrMsg'}.' for:', $$this{'path'}); close($fh); return undef; diff --git a/config/external/nss/crmf/moz.build b/config/external/nss/crmf/moz.build index 3f51ab5f1a61..d0ceb4bd9cf4 100644 --- a/config/external/nss/crmf/moz.build +++ b/config/external/nss/crmf/moz.build @@ -8,7 +8,7 @@ LIBRARY_NAME = 'crmf' if CONFIG['MOZ_NATIVE_NSS']: OS_LIBS += [l for l in CONFIG['NSS_LIBS'] if l.startswith('-L')] - OS_LIBS += '-lcrmf' + OS_LIBS += ['-lcrmf'] else: USE_LIBS += [ # The dependency on nss is not real, but is required to force the diff --git a/configure.in b/configure.in index 7cbc077b5cb4..cd0e29e469ec 100644 --- a/configure.in +++ b/configure.in @@ -1992,7 +1992,10 @@ ia64*-hpux*) TARGET_NSPR_MDCPUCFG='\"md/_linux.cfg\"' MOZ_GFX_OPTIMIZE_MOBILE=1 - MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks -fno-reorder-functions" + MOZ_OPTIMIZE_FLAGS="-Os -fno-reorder-functions" + if test -z "$CLANG_CC"; then + MOZ_OPTIMIZE_FLAGS="-freorder-blocks $MOZ_OPTIMIZE_FLAGS" + fi ;; *-*linux*) @@ -2009,7 +2012,10 @@ ia64*-hpux*) MOZ_OPTIMIZE_SIZE_TWEAK="-finline-limit=50" esac MOZ_PGO_OPTIMIZE_FLAGS="-O3" - MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks $MOZ_OPTIMIZE_SIZE_TWEAK" + MOZ_OPTIMIZE_FLAGS="-Os $MOZ_OPTIMIZE_SIZE_TWEAK" + if test -z "$CLANG_CC"; then + MOZ_OPTIMIZE_FLAGS="-freorder-blocks $MOZ_OPTIMIZE_FLAGS" + fi fi TARGET_NSPR_MDCPUCFG='\"md/_linux.cfg\"' @@ -3779,7 +3785,7 @@ MOZ_WMF= if test -n "$MOZ_FMP4"; then MOZ_FMP4=1 else - MOZ_FMP4 = + MOZ_FMP4= fi MOZ_EME=1 MOZ_FFMPEG= @@ -3826,7 +3832,7 @@ MOZ_XUL=1 MOZ_ZIPWRITER=1 NS_PRINTING=1 MOZ_PDF_PRINTING= -MOZ_DISABLE_CRYPTOLEGACY= +MOZ_NO_SMART_CARDS= NSS_DISABLE_DBM= NECKO_COOKIES=1 NECKO_PROTOCOLS_DEFAULT="about app data file ftp http res viewsource websocket wyciwyg device" @@ -6342,12 +6348,12 @@ fi AC_SUBST(MOZ_DISABLE_PARENTAL_CONTROLS) dnl ======================================================== -dnl = Disable DOMCrypto +dnl = Disable smartcard support dnl ======================================================== -if test -n "$MOZ_DISABLE_CRYPTOLEGACY"; then - AC_DEFINE(MOZ_DISABLE_CRYPTOLEGACY) +if test -n "$MOZ_NO_SMART_CARDS"; then + AC_DEFINE(MOZ_NO_SMART_CARDS) fi -AC_SUBST(MOZ_DISABLE_CRYPTOLEGACY) +AC_SUBST(MOZ_NO_SMART_CARDS) dnl ======================================================== dnl = Disable EV certificate verification diff --git a/content/base/test/csp/file_CSP_evalscript_main_allowed_getCRMFRequest.html b/content/base/test/csp/file_CSP_evalscript_main_allowed_getCRMFRequest.html deleted file mode 100644 index a6b62d582183..000000000000 --- a/content/base/test/csp/file_CSP_evalscript_main_allowed_getCRMFRequest.html +++ /dev/null @@ -1,12 +0,0 @@ - - - CSP eval script tests - - - - - Foo. - - - diff --git a/content/base/test/csp/file_CSP_evalscript_main_allowed_getCRMFRequest.html^headers^ b/content/base/test/csp/file_CSP_evalscript_main_allowed_getCRMFRequest.html^headers^ deleted file mode 100644 index 0cb5288bec4e..000000000000 --- a/content/base/test/csp/file_CSP_evalscript_main_allowed_getCRMFRequest.html^headers^ +++ /dev/null @@ -1,2 +0,0 @@ -Cache-Control: no-cache -Content-Security-Policy: default-src 'self' ; script-src 'self' 'unsafe-eval' diff --git a/content/base/test/csp/file_CSP_evalscript_main_allowed_getCRMFRequest.js b/content/base/test/csp/file_CSP_evalscript_main_allowed_getCRMFRequest.js deleted file mode 100644 index dbcc66cb21c7..000000000000 --- a/content/base/test/csp/file_CSP_evalscript_main_allowed_getCRMFRequest.js +++ /dev/null @@ -1,42 +0,0 @@ -// some javascript for the CSP eval() tests -// all of these evals should succeed, as the document loading this script -// has script-src 'self' 'unsafe-eval' - -function logResult(str, passed) { - var elt = document.createElement('div'); - var color = passed ? "#cfc;" : "#fcc"; - elt.setAttribute('style', 'background-color:' + color + '; width:100%; border:1px solid black; padding:3px; margin:4px;'); - elt.innerHTML = str; - document.body.appendChild(elt); -} - -// callback for when stuff is allowed by CSP -var onevalexecuted = (function(window) { - return function(shouldrun, what, data) { - window.parent.scriptRan(shouldrun, what, data); - logResult((shouldrun ? "PASS: " : "FAIL: ") + what + " : " + data, shouldrun); - };})(window); - -// callback for when stuff is blocked -var onevalblocked = (function(window) { - return function(shouldrun, what, data) { - window.parent.scriptBlocked(shouldrun, what, data); - logResult((shouldrun ? "FAIL: " : "PASS: ") + what + " : " + data, !shouldrun); - };})(window); - - -// Defer until document is loaded so that we can write the pretty result boxes -// out. -addEventListener('load', function() { - // test that allows crypto.generateCRMFRequest eval to run - try { - var script = - 'console.log("dynamic script passed to crypto.generateCRMFRequest should execute")'; - crypto.generateCRMFRequest('CN=0', 0, 0, null, script, 384, null, 'rsa-dual-use'); - onevalexecuted(true, "eval(script) inside crypto.generateCRMFRequest", - "eval executed during crypto.generateCRMFRequest"); - } catch (e) { - onevalblocked(true, "eval(script) inside crypto.generateCRMFRequest", - "eval was blocked during crypto.generateCRMFRequest"); - } -}, false); diff --git a/content/base/test/csp/file_CSP_evalscript_main_getCRMFRequest.html b/content/base/test/csp/file_CSP_evalscript_main_getCRMFRequest.html deleted file mode 100644 index 7b122389be54..000000000000 --- a/content/base/test/csp/file_CSP_evalscript_main_getCRMFRequest.html +++ /dev/null @@ -1,12 +0,0 @@ - - - CSP eval script tests - - - - - Foo. - - - diff --git a/content/base/test/csp/file_CSP_evalscript_main_getCRMFRequest.html^headers^ b/content/base/test/csp/file_CSP_evalscript_main_getCRMFRequest.html^headers^ deleted file mode 100644 index b91ba384d948..000000000000 --- a/content/base/test/csp/file_CSP_evalscript_main_getCRMFRequest.html^headers^ +++ /dev/null @@ -1,2 +0,0 @@ -Cache-Control: no-cache -Content-Security-Policy: default-src 'self' diff --git a/content/base/test/csp/file_CSP_evalscript_main_getCRMFRequest.js b/content/base/test/csp/file_CSP_evalscript_main_getCRMFRequest.js deleted file mode 100644 index 90826e3bc9de..000000000000 --- a/content/base/test/csp/file_CSP_evalscript_main_getCRMFRequest.js +++ /dev/null @@ -1,48 +0,0 @@ -// some javascript for the CSP eval() tests - -function logResult(str, passed) { - var elt = document.createElement('div'); - var color = passed ? "#cfc;" : "#fcc"; - elt.setAttribute('style', 'background-color:' + color + '; width:100%; border:1px solid black; padding:3px; margin:4px;'); - elt.innerHTML = str; - document.body.appendChild(elt); -} - -window._testResults = {}; - -// callback for when stuff is allowed by CSP -var onevalexecuted = (function(window) { - return function(shouldrun, what, data) { - window._testResults[what] = "ran"; - window.parent.scriptRan(shouldrun, what, data); - logResult((shouldrun ? "PASS: " : "FAIL: ") + what + " : " + data, shouldrun); - };})(window); - -// callback for when stuff is blocked -var onevalblocked = (function(window) { - return function(shouldrun, what, data) { - window._testResults[what] = "blocked"; - window.parent.scriptBlocked(shouldrun, what, data); - logResult((shouldrun ? "FAIL: " : "PASS: ") + what + " : " + data, !shouldrun); - };})(window); - - -// Defer until document is loaded so that we can write the pretty result boxes -// out. -addEventListener('load', function() { - // generateCRMFRequest test -- make sure we cannot eval the callback if CSP is in effect - try { - var script = 'console.log("dynamic script eval\'d in crypto.generateCRMFRequest should be disallowed")'; - crypto.generateCRMFRequest('CN=0', 0, 0, null, script, 384, null, 'rsa-dual-use'); - onevalexecuted(false, "crypto.generateCRMFRequest()", - "crypto.generateCRMFRequest() should not run!"); - } catch (e) { - onevalblocked(false, "eval(script) inside crypto.generateCRMFRequest", - "eval was blocked during crypto.generateCRMFRequest"); - } - - -}, false); - - - diff --git a/content/base/test/csp/file_CSP_evalscript_no_CSP_at_all.html b/content/base/test/csp/file_CSP_evalscript_no_CSP_at_all.html deleted file mode 100644 index d36aeaaf1064..000000000000 --- a/content/base/test/csp/file_CSP_evalscript_no_CSP_at_all.html +++ /dev/null @@ -1,12 +0,0 @@ - - - CSP eval script tests: no CSP specified - - - - - Foo. See bug 824652 - - - diff --git a/content/base/test/csp/file_CSP_evalscript_no_CSP_at_all.html^headers^ b/content/base/test/csp/file_CSP_evalscript_no_CSP_at_all.html^headers^ deleted file mode 100644 index 9e23c73b7ffb..000000000000 --- a/content/base/test/csp/file_CSP_evalscript_no_CSP_at_all.html^headers^ +++ /dev/null @@ -1 +0,0 @@ -Cache-Control: no-cache diff --git a/content/base/test/csp/file_CSP_evalscript_no_CSP_at_all.js b/content/base/test/csp/file_CSP_evalscript_no_CSP_at_all.js deleted file mode 100644 index 520491fb8ef7..000000000000 --- a/content/base/test/csp/file_CSP_evalscript_no_CSP_at_all.js +++ /dev/null @@ -1,42 +0,0 @@ -// some javascript for the CSP eval() tests -// all of these evals should succeed, as the document loading this script -// has script-src 'self' 'unsafe-eval' - -function logResult(str, passed) { - var elt = document.createElement('div'); - var color = passed ? "#cfc;" : "#fcc"; - elt.setAttribute('style', 'background-color:' + color + '; width:100%; border:1px solid black; padding:3px; margin:4px;'); - elt.innerHTML = str; - document.body.appendChild(elt); -} - -// callback for when stuff is allowed by CSP -var onevalexecuted = (function(window) { - return function(shouldrun, what, data) { - window.parent.scriptRan(shouldrun, what, data); - logResult((shouldrun ? "PASS: " : "FAIL: ") + what + " : " + data, shouldrun); - };})(window); - -// callback for when stuff is blocked -var onevalblocked = (function(window) { - return function(shouldrun, what, data) { - window.parent.scriptBlocked(shouldrun, what, data); - logResult((shouldrun ? "FAIL: " : "PASS: ") + what + " : " + data, !shouldrun); - };})(window); - - -// Defer until document is loaded so that we can write the pretty result boxes -// out. -addEventListener('load', function() { - // test that allows crypto.generateCRMFRequest eval to run when there is no CSP at all in place - try { - var script = - 'console.log("dynamic script passed to crypto.generateCRMFRequest should execute")'; - crypto.generateCRMFRequest('CN=0', 0, 0, null, script, 384, null, 'rsa-dual-use'); - onevalexecuted(true, "eval(script) inside crypto.generateCRMFRequest: no CSP at all", - "eval executed during crypto.generateCRMFRequest where no CSP is set at all"); - } catch (e) { - onevalblocked(true, "eval(script) inside crypto.generateCRMFRequest", - "eval was blocked during crypto.generateCRMFRequest"); - } -}, false); diff --git a/content/base/test/csp/mochitest.ini b/content/base/test/csp/mochitest.ini index e3eaa4221b3f..12733d57aa69 100644 --- a/content/base/test/csp/mochitest.ini +++ b/content/base/test/csp/mochitest.ini @@ -20,19 +20,10 @@ support-files = file_CSP_bug888172.sjs file_CSP_evalscript_main.js file_CSP_evalscript_main_allowed.js - file_CSP_evalscript_main_allowed_getCRMFRequest.js - file_CSP_evalscript_main_getCRMFRequest.js file_CSP_evalscript_main.html file_CSP_evalscript_main.html^headers^ file_CSP_evalscript_main_allowed.html file_CSP_evalscript_main_allowed.html^headers^ - file_CSP_evalscript_main_allowed_getCRMFRequest.html - file_CSP_evalscript_main_allowed_getCRMFRequest.html^headers^ - file_CSP_evalscript_main_getCRMFRequest.html - file_CSP_evalscript_main_getCRMFRequest.html^headers^ - file_CSP_evalscript_no_CSP_at_all.html - file_CSP_evalscript_no_CSP_at_all.html^headers^ - file_CSP_evalscript_no_CSP_at_all.js file_CSP_frameancestors_main.html file_CSP_frameancestors_main.js file_CSP_frameancestors.sjs @@ -112,8 +103,6 @@ support-files = [test_CSP_bug885433.html] [test_CSP_bug888172.html] [test_CSP_evalscript.html] -[test_CSP_evalscript_getCRMFRequest.html] -skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # no (deprecated) window.crypto support in multiprocess (bug 824652) [test_CSP_frameancestors.html] skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || toolkit == 'android' # Times out, not sure why (bug 1008445) [test_CSP_inlinescript.html] diff --git a/content/base/test/csp/test_CSP_evalscript_getCRMFRequest.html b/content/base/test/csp/test_CSP_evalscript_getCRMFRequest.html deleted file mode 100644 index fa1f648a2561..000000000000 --- a/content/base/test/csp/test_CSP_evalscript_getCRMFRequest.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - Test for Content Security Policy "no eval" in crypto.getCRMFRequest() - - - - -

- - - - - - - - diff --git a/content/media/AudioStream.cpp b/content/media/AudioStream.cpp index 04c160c5ff5a..02a5282a9953 100644 --- a/content/media/AudioStream.cpp +++ b/content/media/AudioStream.cpp @@ -17,6 +17,7 @@ #include "mozilla/Telemetry.h" #include "soundtouch/SoundTouch.h" #include "Latency.h" +#include "nsPrintfCString.h" #ifdef XP_MACOSX #include #endif @@ -254,6 +255,7 @@ AudioStream::AudioStream() , mState(INITIALIZED) , mNeedsStart(false) , mShouldDropFrames(false) + , mPendingAudioInitTask(false) { // keep a ref in case we shut down later than nsLayoutStatics mLatencyLog = AsyncLatencyLogger::Get(true); @@ -535,19 +537,24 @@ AudioStream::Init(int32_t aNumChannels, int32_t aRate, // cause us to move from INITIALIZED to RUNNING. Until then, we // can't access any cubeb functions. // Use a RefPtr to avoid leaks if Dispatch fails + mPendingAudioInitTask = true; RefPtr init = new AudioInitTask(this, aLatencyRequest, params); - init->Dispatch(); - return NS_OK; + nsresult rv = init->Dispatch(); + if (NS_FAILED(rv)) { + mPendingAudioInitTask = false; + } + return rv; } // High latency - open synchronously nsresult rv = OpenCubeb(params, aLatencyRequest); + NS_ENSURE_SUCCESS(rv, rv); // See if we need to start() the stream, since we must do that from this // thread for now (cubeb API issue) { MonitorAutoLock mon(mMonitor); CheckForStart(); } - return rv; + return NS_OK; } // On certain MacBookPro, the microphone is located near the left speaker. @@ -627,15 +634,9 @@ nsresult AudioStream::OpenCubeb(cubeb_stream_params &aParams, LatencyRequest aLatencyRequest) { - { - MonitorAutoLock mon(mMonitor); - if (mState == AudioStream::SHUTDOWN) { - return NS_ERROR_FAILURE; - } - } - cubeb* cubebContext = GetCubebContext(); if (!cubebContext) { + NS_WARNING("Can't get cubeb context!"); MonitorAutoLock mon(mMonitor); mState = AudioStream::ERRORED; return NS_ERROR_FAILURE; @@ -658,21 +659,15 @@ AudioStream::OpenCubeb(cubeb_stream_params &aParams, if (cubeb_stream_init(cubebContext, &stream, "AudioStream", aParams, latency, DataCallback_S, StateCallback_S, this) == CUBEB_OK) { MonitorAutoLock mon(mMonitor); + MOZ_ASSERT(mState != SHUTDOWN); mCubebStream.own(stream); - // Make sure we weren't shut down while in flight! - if (mState == SHUTDOWN) { - mCubebStream.reset(); - LOG(("AudioStream::OpenCubeb() %p Shutdown while opening cubeb", this)); - return NS_ERROR_FAILURE; - } - // We can't cubeb_stream_start() the thread from a transient thread due to // cubeb API requirements (init can be called from another thread, but // not start/stop/destroy/etc) } else { MonitorAutoLock mon(mMonitor); mState = ERRORED; - LOG(("AudioStream::OpenCubeb() %p failed to init cubeb", this)); + NS_WARNING(nsPrintfCString("AudioStream::OpenCubeb() %p failed to init cubeb", this).get()); return NS_ERROR_FAILURE; } } @@ -693,6 +688,14 @@ AudioStream::OpenCubeb(cubeb_stream_params &aParams, return NS_OK; } +void +AudioStream::AudioInitTaskFinished() +{ + MonitorAutoLock mon(mMonitor); + mPendingAudioInitTask = false; + mon.NotifyAll(); +} + void AudioStream::CheckForStart() { @@ -731,6 +734,7 @@ AudioInitTask::Run() } nsresult rv = mAudioStream->OpenCubeb(mParams, mLatencyRequest); + mAudioStream->AudioInitTaskFinished(); // and now kill this thread NS_DispatchToMainThread(this); @@ -951,6 +955,10 @@ AudioStream::Shutdown() MonitorAutoLock mon(mMonitor); LOG(("AudioStream: Shutdown %p, state %d", this, mState)); + while (mPendingAudioInitTask) { + mon.Wait(); + } + if (mCubebStream) { MonitorAutoUnlock mon(mMonitor); // Force stop to put the cubeb stream in a stable state before deletion. diff --git a/content/media/AudioStream.h b/content/media/AudioStream.h index c2914b2f7425..927a5438ddb3 100644 --- a/content/media/AudioStream.h +++ b/content/media/AudioStream.h @@ -299,6 +299,7 @@ private: // So we can call it asynchronously from AudioInitTask nsresult OpenCubeb(cubeb_stream_params &aParams, LatencyRequest aLatencyRequest); + void AudioInitTaskFinished(); void CheckForStart(); @@ -425,6 +426,9 @@ private: // is not going to be called for a little while, simply drop incoming frames. // This is only on OSX for now, because other systems handle this gracefully. bool mShouldDropFrames; + // True if there is a pending AudioInitTask. Shutdown() will wait until the + // pending AudioInitTask is finished. + bool mPendingAudioInitTask; // This mutex protects the static members below. static StaticMutex sMutex; diff --git a/dom/base/Crypto.cpp b/dom/base/Crypto.cpp index ddff2aea59b8..52cfb880936c 100644 --- a/dom/base/Crypto.cpp +++ b/dom/base/Crypto.cpp @@ -127,82 +127,6 @@ Crypto::Subtle() return mSubtle; } -#ifndef MOZ_DISABLE_CRYPTOLEGACY -// Stub out the legacy nsIDOMCrypto methods. The actual -// implementations are in security/manager/ssl/src/nsCrypto.{cpp,h} - -NS_IMETHODIMP -Crypto::GetEnableSmartCardEvents(bool *aEnableSmartCardEvents) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -Crypto::SetEnableSmartCardEvents(bool aEnableSmartCardEvents) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -bool -Crypto::EnableSmartCardEvents() -{ - return false; -} - -void -Crypto::SetEnableSmartCardEvents(bool aEnable, ErrorResult& aRv) -{ - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); -} - -void -Crypto::GetVersion(nsString& aVersion) -{ -} - -mozilla::dom::CRMFObject* -Crypto::GenerateCRMFRequest(JSContext* aContext, - const nsCString& aReqDN, - const nsCString& aRegToken, - const nsCString& aAuthenticator, - const nsCString& aEaCert, - const nsCString& aJsCallback, - const Sequence& aArgs, - ErrorResult& aRv) -{ - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); - return nullptr; -} - -void -Crypto::ImportUserCertificates(const nsAString& aNickname, - const nsAString& aCmmfResponse, - bool aDoForcedBackup, - nsAString& aReturn, - ErrorResult& aRv) -{ - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); -} - -void -Crypto::SignText(JSContext* aContext, - const nsAString& aStringToSign, - const nsAString& aCaOption, - const Sequence& aArgs, - nsAString& aReturn) - -{ - aReturn.AssignLiteral("error:internalError"); -} - -void -Crypto::Logout(ErrorResult& aRv) -{ - aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); -} - -#endif - /* static */ uint8_t* Crypto::GetRandomValues(uint32_t aLength) { diff --git a/dom/base/Crypto.h b/dom/base/Crypto.h index dd2c204940bf..641e855453f8 100644 --- a/dom/base/Crypto.h +++ b/dom/base/Crypto.h @@ -4,17 +4,7 @@ #ifndef mozilla_dom_Crypto_h #define mozilla_dom_Crypto_h -#ifdef MOZ_DISABLE_CRYPTOLEGACY #include "nsIDOMCrypto.h" -#else -#include "nsIDOMCryptoLegacy.h" -namespace mozilla { -namespace dom { -class CRMFObject; -} -} -#endif - #include "mozilla/dom/SubtleCrypto.h" #include "nsPIDOMWindow.h" @@ -51,38 +41,6 @@ public: SubtleCrypto* Subtle(); -#ifndef MOZ_DISABLE_CRYPTOLEGACY - virtual bool EnableSmartCardEvents(); - virtual void SetEnableSmartCardEvents(bool aEnable, ErrorResult& aRv); - - virtual void GetVersion(nsString& aVersion); - - virtual mozilla::dom::CRMFObject* - GenerateCRMFRequest(JSContext* aContext, - const nsCString& aReqDN, - const nsCString& aRegToken, - const nsCString& aAuthenticator, - const nsCString& aEaCert, - const nsCString& aJsCallback, - const Sequence& aArgs, - ErrorResult& aRv); - - virtual void ImportUserCertificates(const nsAString& aNickname, - const nsAString& aCmmfResponse, - bool aDoForcedBackup, - nsAString& aReturn, - ErrorResult& aRv); - - virtual void SignText(JSContext* aContext, - const nsAString& aStringToSign, - const nsAString& aCaOption, - const Sequence& aArgs, - nsAString& aReturn); - - virtual void Logout(ErrorResult& aRv); - -#endif - // WebIDL nsPIDOMWindow* diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 87dfd49a02f9..d3f6cd9ccea5 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -83,9 +83,6 @@ #include "nsIDocCharset.h" #include "nsIDocument.h" #include "Crypto.h" -#ifndef MOZ_DISABLE_CRYPTOLEGACY -#include "nsIDOMCryptoLegacy.h" -#endif #include "nsIDOMDocument.h" #include "nsIDOMElement.h" #include "nsIDOMEvent.h" @@ -2364,14 +2361,6 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument, nsCOMPtr oldDoc = mDoc; -#ifndef MOZ_DISABLE_CRYPTOLEGACY - // clear smartcard events, our document has gone away. - if (mCrypto && XRE_GetProcessType() != GeckoProcessType_Content) { - nsresult rv = mCrypto->SetEnableSmartCardEvents(false); - NS_ENSURE_SUCCESS(rv, rv); - } -#endif - AutoJSAPI jsapi; jsapi.Init(); JSContext *cx = jsapi.cx(); @@ -4459,20 +4448,7 @@ nsGlobalWindow::GetCrypto(ErrorResult& aError) FORWARD_TO_INNER_OR_THROW(GetCrypto, (aError), aError, nullptr); if (!mCrypto) { -#ifndef MOZ_DISABLE_CRYPTOLEGACY - if (XRE_GetProcessType() != GeckoProcessType_Content) { - nsresult rv; - mCrypto = do_CreateInstance(NS_CRYPTO_CONTRACTID, &rv); - if (NS_FAILED(rv)) { - aError.Throw(rv); - return nullptr; - } - } else -#endif - { - mCrypto = new Crypto(); - } - + mCrypto = new Crypto(); mCrypto->Init(this); } return mCrypto; diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index fa49d1e9309e..06ebeb4482b0 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -251,14 +251,7 @@ DOMInterfaces = { 'headerFile': 'nsGeoPosition.h' }, -'CRMFObject': { - 'headerFile': 'nsCrypto.h', - 'nativeOwnership': 'owned', - 'wrapperCache': False, -}, - 'Crypto' : { - 'implicitJSContext': [ 'generateCRMFRequest', 'signText' ], 'headerFile': 'Crypto.h' }, diff --git a/dom/bluetooth/BluetoothCommon.h b/dom/bluetooth/BluetoothCommon.h index 85825f163022..a9ed3f475404 100644 --- a/dom/bluetooth/BluetoothCommon.h +++ b/dom/bluetooth/BluetoothCommon.h @@ -146,6 +146,94 @@ enum BluetoothStatus { STATUS_RMT_DEV_DOWN }; +enum BluetoothBondState { + BOND_STATE_NONE, + BOND_STATE_BONDING, + BOND_STATE_BONDED +}; + +enum BluetoothDeviceType { + DEVICE_TYPE_BREDR, + DEVICE_TYPE_BLE, + DEVICE_TYPE_DUAL +}; + +enum BluetoothPropertyType { + PROPERTY_BDNAME, + PROPERTY_BDADDR, + PROPERTY_UUIDS, + PROPERTY_CLASS_OF_DEVICE, + PROPERTY_TYPE_OF_DEVICE, + PROPERTY_SERVICE_RECORD, + PROPERTY_ADAPTER_SCAN_MODE, + PROPERTY_ADAPTER_BONDED_DEVICES, + PROPERTY_ADAPTER_DISCOVERY_TIMEOUT, + PROPERTY_REMOTE_FRIENDLY_NAME, + PROPERTY_REMOTE_RSSI, + PROPERTY_REMOTE_VERSION_INFO, + PROPERTY_REMOTE_DEVICE_TIMESTAMP +}; + +enum BluetoothScanMode { + SCAN_MODE_NONE, + SCAN_MODE_CONNECTABLE, + SCAN_MODE_CONNECTABLE_DISCOVERABLE +}; + +struct BluetoothUuid { + uint8_t mUuid[16]; +}; + +struct BluetoothServiceRecord { + BluetoothUuid mUuid; + uint16_t mChannel; + char mName[256]; +}; + +struct BluetoothRemoteInfo { + int mVerMajor; + int mVerMinor; + int mManufacturer; +}; + +struct BluetoothProperty { + /* Type */ + BluetoothPropertyType mType; + + /* Value + */ + + /* PROPERTY_BDNAME + PROPERTY_BDADDR + PROPERTY_REMOTE_FRIENDLY_NAME */ + nsString mString; + + /* PROPERTY_UUIDS */ + nsTArray mUuidArray; + + /* PROPERTY_ADAPTER_BONDED_DEVICES */ + nsTArray mStringArray; + + /* PROPERTY_CLASS_OF_DEVICE + PROPERTY_ADAPTER_DISCOVERY_TIMEOUT */ + uint32_t mUint32; + + /* PROPERTY_RSSI_VALUE */ + int32_t mInt32; + + /* PROPERTY_DEVICE_TYPE */ + BluetoothDeviceType mDeviceType; + + /* PROPERTY_SERVICE_RECORD */ + BluetoothServiceRecord mServiceRecord; + + /* PROPERTY_SCAN_MODE */ + BluetoothScanMode mScanMode; + + /* PROPERTY_REMOTE_VERSION_INFO */ + BluetoothRemoteInfo mRemoteInfo; +}; + enum BluetoothSocketType { RFCOMM = 1, SCO = 2, diff --git a/dom/bluetooth/bluedroid/BluetoothInterface.cpp b/dom/bluetooth/bluedroid/BluetoothInterface.cpp index e866659ba9e3..787c75de7bb1 100644 --- a/dom/bluetooth/bluedroid/BluetoothInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothInterface.cpp @@ -23,6 +23,8 @@ out_ #endif +#define MAX_UUID_SIZE 16 + BEGIN_BLUETOOTH_NAMESPACE template @@ -92,6 +94,23 @@ Convert(bool aIn, bt_scan_mode_t& aOut) return NS_OK; } + +static nsresult +Convert(bt_scan_mode_t aIn, BluetoothScanMode& aOut) +{ + static const BluetoothScanMode sScanMode[] = { + CONVERT(BT_SCAN_MODE_NONE, SCAN_MODE_NONE), + CONVERT(BT_SCAN_MODE_CONNECTABLE, SCAN_MODE_CONNECTABLE), + CONVERT(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE, + SCAN_MODE_CONNECTABLE_DISCOVERABLE) + }; + if (aIn >= MOZ_ARRAY_LENGTH(sScanMode)) { + return NS_ERROR_ILLEGAL_VALUE; + } + aOut = sScanMode[aIn]; + return NS_OK; +} + struct ConvertNamedValue { ConvertNamedValue(const BluetoothNamedValue& aNamedValue) @@ -173,6 +192,22 @@ Convert(const nsAString& aIn, bt_ssp_variant_t& aOut) return NS_OK; } +static nsresult +Convert(const bt_ssp_variant_t& aIn, nsAString& aOut) +{ + static const char * const sSspVariant[] = { + CONVERT(BT_SSP_VARIANT_PASSKEY_CONFIRMATION, "PasskeyConfirmation"), + CONVERT(BT_SSP_VARIANT_PASSKEY_ENTRY, "PasskeyEntry"), + CONVERT(BT_SSP_VARIANT_CONSENT, "Consent"), + CONVERT(BT_SSP_VARIANT_PASSKEY_NOTIFICATION, "PasskeyNotification") + }; + if (aIn >= MOZ_ARRAY_LENGTH(sSspVariant)) { + return NS_ERROR_ILLEGAL_VALUE; + } + aOut = NS_ConvertUTF8toUTF16(sSspVariant[aIn]); + return NS_OK; +} + static nsresult Convert(const bool& aIn, uint8_t& aOut) { @@ -193,6 +228,18 @@ Convert(const uint8_t aIn[16], bt_uuid_t& aOut) return NS_OK; } +static nsresult +Convert(const bt_uuid_t& aIn, BluetoothUuid& aOut) +{ + if (sizeof(aIn.uu) != sizeof(aOut.mUuid)) { + return NS_ERROR_ILLEGAL_VALUE; + } + + memcpy(aOut.mUuid, aIn.uu, sizeof(aOut.mUuid)); + + return NS_OK; +} + static nsresult Convert(const nsAString& aIn, bt_pin_code_t& aOut) { @@ -241,6 +288,166 @@ Convert(const bt_bdaddr_t& aIn, nsAString& aOut) return NS_OK; } +static nsresult +Convert(const bt_bdaddr_t* aIn, nsAString& aOut) +{ + if (!aIn) { + aOut.AssignLiteral(BLUETOOTH_ADDRESS_NONE); + return NS_OK; + } + return Convert(*aIn, aOut); +} + +static nsresult +Convert(bt_state_t aIn, bool& aOut) +{ + static const bool sState[] = { + CONVERT(BT_STATE_OFF, false), + CONVERT(BT_STATE_ON, true) + }; + if (aIn >= MOZ_ARRAY_LENGTH(sState)) { + return NS_ERROR_ILLEGAL_VALUE; + } + aOut = sState[aIn]; + return NS_OK; +} + +static nsresult +Convert(bt_property_type_t aIn, BluetoothPropertyType& aOut) +{ + static const BluetoothPropertyType sPropertyType[] = { + CONVERT(0, static_cast(0)), // invalid, required by gcc + CONVERT(BT_PROPERTY_BDNAME, PROPERTY_BDNAME), + CONVERT(BT_PROPERTY_BDADDR, PROPERTY_BDADDR), + CONVERT(BT_PROPERTY_UUIDS, PROPERTY_UUIDS), + CONVERT(BT_PROPERTY_CLASS_OF_DEVICE, PROPERTY_CLASS_OF_DEVICE), + CONVERT(BT_PROPERTY_TYPE_OF_DEVICE, PROPERTY_TYPE_OF_DEVICE), + CONVERT(BT_PROPERTY_SERVICE_RECORD, PROPERTY_SERVICE_RECORD), + CONVERT(BT_PROPERTY_ADAPTER_SCAN_MODE, PROPERTY_ADAPTER_SCAN_MODE), + CONVERT(BT_PROPERTY_ADAPTER_BONDED_DEVICES, + PROPERTY_ADAPTER_BONDED_DEVICES), + CONVERT(BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT, + PROPERTY_ADAPTER_DISCOVERY_TIMEOUT), + CONVERT(BT_PROPERTY_REMOTE_FRIENDLY_NAME, PROPERTY_REMOTE_FRIENDLY_NAME), + CONVERT(BT_PROPERTY_REMOTE_RSSI, PROPERTY_REMOTE_RSSI), + CONVERT(BT_PROPERTY_REMOTE_VERSION_INFO,PROPERTY_REMOTE_VERSION_INFO) + }; + if (aIn == BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP) { + /* This case is handled separately to not populate + * |sPropertyType| with empty entries. */ + aOut = PROPERTY_REMOTE_DEVICE_TIMESTAMP; + return NS_OK; + } + if (!aIn || aIn >= MOZ_ARRAY_LENGTH(sPropertyType)) { + return NS_ERROR_ILLEGAL_VALUE; + } + aOut = sPropertyType[aIn]; + return NS_OK; +} + +static nsresult +Convert(bt_discovery_state_t aIn, bool& aOut) +{ + static const bool sDiscoveryState[] = { + CONVERT(BT_DISCOVERY_STOPPED, false), + CONVERT(BT_DISCOVERY_STARTED, true) + }; + if (aIn >= MOZ_ARRAY_LENGTH(sDiscoveryState)) { + return NS_ERROR_ILLEGAL_VALUE; + } + aOut = sDiscoveryState[aIn]; + return NS_OK; +} + +static nsresult +Convert(const bt_bdname_t& aIn, nsAString& aOut) +{ + aOut = NS_ConvertUTF8toUTF16(reinterpret_cast(aIn.name)); + + return NS_OK; +} + +static nsresult +Convert(const bt_bdname_t* aIn, nsAString& aOut) +{ + if (!aIn) { + aOut.Truncate(); + return NS_OK; + } + return Convert(*aIn, aOut); +} + +static nsresult +Convert(bt_bond_state_t aIn, BluetoothBondState& aOut) +{ + static const BluetoothBondState sBondState[] = { + CONVERT(BT_BOND_STATE_NONE, BOND_STATE_NONE), + CONVERT(BT_BOND_STATE_BONDING, BOND_STATE_BONDING), + CONVERT(BT_BOND_STATE_BONDED, BOND_STATE_BONDED) + }; + if (aIn >= MOZ_ARRAY_LENGTH(sBondState)) { + return NS_ERROR_ILLEGAL_VALUE; + } + aOut = sBondState[aIn]; + return NS_OK; +} + +static nsresult +Convert(bt_acl_state_t aIn, bool& aOut) +{ + static const bool sAclState[] = { + CONVERT(BT_ACL_STATE_CONNECTED, true), + CONVERT(BT_ACL_STATE_DISCONNECTED, false) + }; + if (aIn >= MOZ_ARRAY_LENGTH(sAclState)) { + return NS_ERROR_ILLEGAL_VALUE; + } + aOut = sAclState[aIn]; + return NS_OK; +} + +static nsresult +Convert(bt_device_type_t aIn, BluetoothDeviceType& aOut) +{ + static const BluetoothDeviceType sDeviceType[] = { + CONVERT(0, static_cast(0)), // invalid, required by gcc + CONVERT(BT_DEVICE_DEVTYPE_BREDR, DEVICE_TYPE_BREDR), + CONVERT(BT_DEVICE_DEVTYPE_BLE, DEVICE_TYPE_BLE), + CONVERT(BT_DEVICE_DEVTYPE_DUAL, DEVICE_TYPE_DUAL) + }; + if (aIn >= MOZ_ARRAY_LENGTH(sDeviceType)) { + return NS_ERROR_ILLEGAL_VALUE; + } + aOut = sDeviceType[aIn]; + return NS_OK; +} + +static nsresult +Convert(const bt_remote_version_t& aIn, BluetoothRemoteInfo& aOut) +{ + aOut.mVerMajor = aIn.version; + aOut.mVerMinor = aIn.sub_ver; + aOut.mManufacturer = aIn.manufacturer; + + return NS_OK; +} + +static nsresult +Convert(const bt_service_record_t& aIn, BluetoothServiceRecord& aOut) +{ + nsresult rv = Convert(aIn.uuid, aOut.mUuid); + if (NS_FAILED(rv)) { + return rv; + } + + aOut.mChannel = aIn.channel; + + MOZ_ASSERT(sizeof(aIn.name) == sizeof(aOut.mName)); + memcpy(aOut.mName, aIn.name, sizeof(aOut.mName)); + + return NS_OK; +} + static nsresult Convert(BluetoothSocketType aIn, btsock_type_t& aOut) { @@ -556,6 +763,101 @@ ConvertDefault(const Tin& aIn, const Tout& aDefault) return out; } +/* This implementation of |Convert| is a helper for copying the + * input value into the output value. It handles all cases that + * need no conversion. + */ +template +static nsresult +Convert(const T& aIn, T& aOut) +{ + aOut = aIn; + + return NS_OK; +} + +static nsresult +Convert(const bt_property_t& aIn, BluetoothProperty& aOut) +{ + /* type conversion */ + + nsresult rv = Convert(aIn.type, aOut.mType); + if (NS_FAILED(rv)) { + return rv; + } + + /* value conversion */ + + switch (aOut.mType) { + case PROPERTY_BDNAME: + /* fall through */ + case PROPERTY_REMOTE_FRIENDLY_NAME: + { + // We construct an nsCString here because bdname + // returned from Bluedroid is not 0-terminated. + aOut.mString = NS_ConvertUTF8toUTF16( + nsCString(static_cast(aIn.val), aIn.len)); + } + break; + case PROPERTY_BDADDR: + rv = Convert(*static_cast(aIn.val), aOut.mString); + break; + case PROPERTY_UUIDS: + { + size_t numUuids = aIn.len / MAX_UUID_SIZE; + ConvertArray array( + static_cast(aIn.val), numUuids); + aOut.mUuidArray.SetLength(numUuids); + rv = Convert(array, aOut.mUuidArray); + } + break; + case PROPERTY_CLASS_OF_DEVICE: + /* fall through */ + case PROPERTY_ADAPTER_DISCOVERY_TIMEOUT: + aOut.mUint32 = *static_cast(aIn.val); + break; + case PROPERTY_TYPE_OF_DEVICE: + rv = Convert(*static_cast(aIn.val), + aOut.mDeviceType); + break; + case PROPERTY_SERVICE_RECORD: + rv = Convert(*static_cast(aIn.val), + aOut.mServiceRecord); + break; + case PROPERTY_ADAPTER_SCAN_MODE: + rv = Convert(*static_cast(aIn.val), + aOut.mScanMode); + break; + case PROPERTY_ADAPTER_BONDED_DEVICES: + { + size_t numAddresses = aIn.len / BLUETOOTH_ADDRESS_BYTES; + ConvertArray array( + static_cast(aIn.val), numAddresses); + aOut.mStringArray.SetLength(numAddresses); + rv = Convert(array, aOut.mStringArray); + } + break; + case PROPERTY_REMOTE_RSSI: + aOut.mInt32 = *static_cast(aIn.val); + break; + case PROPERTY_REMOTE_VERSION_INFO: + rv = Convert(*static_cast(aIn.val), + aOut.mRemoteInfo); + break; + case PROPERTY_REMOTE_DEVICE_TIMESTAMP: + /* nothing to do */ + break; + default: + /* mismatch with type conversion */ + NS_NOTREACHED("Unhandled property type"); + break; + } + if (NS_FAILED(rv)) { + return rv; + } + return NS_OK; +} + // // Result handling // @@ -646,6 +948,451 @@ private: Tin3 mArg3; }; +// +// Notification handling +// + +template +class BluetoothNotificationRunnable1 : public nsRunnable +{ +public: + typedef typename ObjectWrapper::ObjectType ObjectType; + typedef BluetoothNotificationRunnable1 SelfType; + + template + static already_AddRefed Create( + Res (ObjectType::*aMethod)(Arg1), const T1& aIn1) + { + nsRefPtr runnable(new SelfType(aMethod)); + + if (NS_FAILED(runnable->ConvertAndSet(aIn1))) { + return nullptr; + } + return runnable.forget(); + } + + template + static void + Dispatch(Res (ObjectType::*aMethod)(Arg1), const T1& aIn1) + { + nsRefPtr runnable = Create(aMethod, aIn1); + + if (!runnable) { + BT_WARNING("BluetoothNotificationRunnable1::Create failed"); + return; + } + nsresult rv = NS_DispatchToMainThread(runnable); + if (NS_FAILED(rv)) { + BT_WARNING("NS_DispatchToMainThread failed: %X", rv); + } + } + + NS_METHOD + Run() MOZ_OVERRIDE + { + MOZ_ASSERT(NS_IsMainThread()); + + ObjectType* obj = ObjectWrapper::GetInstance(); + + if (!obj) { + BT_WARNING("Notification handler not initialized"); + } else { + ((*obj).*mMethod)(mArg1); + } + return NS_OK; + } + +private: + BluetoothNotificationRunnable1(Res (ObjectType::*aMethod)(Arg1)) + : mMethod(aMethod) + { + MOZ_ASSERT(mMethod); + } + + template + nsresult + ConvertAndSet(const T1& aIn1) + { + nsresult rv = Convert(aIn1, mArg1); + if (NS_FAILED(rv)) { + return rv; + } + return NS_OK; + } + + Res (ObjectType::*mMethod)(Arg1); + Tin1 mArg1; +}; + +template +class BluetoothNotificationRunnable2 : public nsRunnable +{ +public: + typedef typename ObjectWrapper::ObjectType ObjectType; + typedef BluetoothNotificationRunnable2 SelfType; + + template + static already_AddRefed Create( + Res (ObjectType::*aMethod)(Arg1, Arg2), const T1& aIn1, const T2& aIn2) + { + nsRefPtr runnable(new SelfType(aMethod)); + + if (NS_FAILED(runnable->ConvertAndSet(aIn1, aIn2))) { + return nullptr; + } + return runnable.forget(); + } + + template + static void + Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2), + const T1& aIn1, const T2& aIn2) + { + nsRefPtr runnable = Create(aMethod, aIn1, aIn2); + + if (!runnable) { + BT_WARNING("BluetoothNotificationRunnable2::Create failed"); + return; + } + nsresult rv = NS_DispatchToMainThread(runnable); + if (NS_FAILED(rv)) { + BT_WARNING("NS_DispatchToMainThread failed: %X", rv); + } + } + + NS_METHOD + Run() MOZ_OVERRIDE + { + MOZ_ASSERT(NS_IsMainThread()); + + ObjectType* obj = ObjectWrapper::GetInstance(); + + if (!obj) { + BT_WARNING("Notification handler not initialized"); + } else { + ((*obj).*mMethod)(mArg1, mArg2); + } + return NS_OK; + } + +private: + BluetoothNotificationRunnable2(Res (ObjectType::*aMethod)(Arg1, Arg2)) + : mMethod(aMethod) + { + MOZ_ASSERT(mMethod); + } + + template + nsresult + ConvertAndSet(const T1& aIn1, const T2& aIn2) + { + nsresult rv = Convert(aIn1, mArg1); + if (NS_FAILED(rv)) { + return rv; + } + rv = Convert(aIn2, mArg2); + if (NS_FAILED(rv)) { + return rv; + } + return NS_OK; + } + + Res (ObjectType::*mMethod)(Arg1, Arg2); + Tin1 mArg1; + Tin2 mArg2; +}; + +template +class BluetoothNotificationRunnable3 : public nsRunnable +{ +public: + typedef typename ObjectWrapper::ObjectType ObjectType; + typedef BluetoothNotificationRunnable3 SelfType; + + template + static already_AddRefed Create( + Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3), + const T1& aIn1, const T2& aIn2, const T3& aIn3) + { + nsRefPtr runnable(new SelfType(aMethod)); + + if (NS_FAILED(runnable->ConvertAndSet(aIn1, aIn2, aIn3))) { + return nullptr; + } + return runnable.forget(); + } + + template + static void + Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3), + const T1& aIn1, const T2& aIn2, const T3& aIn3) + { + nsRefPtr runnable = Create(aMethod, aIn1, aIn2, aIn3); + + if (!runnable) { + BT_WARNING("BluetoothNotificationRunnable3::Create failed"); + return; + } + nsresult rv = NS_DispatchToMainThread(runnable); + if (NS_FAILED(rv)) { + BT_WARNING("NS_DispatchToMainThread failed: %X", rv); + } + } + + NS_METHOD + Run() MOZ_OVERRIDE + { + MOZ_ASSERT(NS_IsMainThread()); + + ObjectType* obj = ObjectWrapper::GetInstance(); + + if (!obj) { + BT_WARNING("Notification handler not initialized"); + } else { + ((*obj).*mMethod)(mArg1, mArg2, mArg3); + } + return NS_OK; + } + +private: + BluetoothNotificationRunnable3(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3)) + : mMethod(aMethod) + { + MOZ_ASSERT(mMethod); + } + + template + nsresult + ConvertAndSet(const T1& aIn1, const T2& aIn2, const T3& aIn3) + { + nsresult rv = Convert(aIn1, mArg1); + if (NS_FAILED(rv)) { + return rv; + } + rv = Convert(aIn2, mArg2); + if (NS_FAILED(rv)) { + return rv; + } + rv = Convert(aIn3, mArg3); + if (NS_FAILED(rv)) { + return rv; + } + return NS_OK; + } + + Res (ObjectType::*mMethod)(Arg1, Arg2, Arg3); + Tin1 mArg1; + Tin2 mArg2; + Tin3 mArg3; +}; + +template +class BluetoothNotificationRunnable4 : public nsRunnable +{ +public: + typedef typename ObjectWrapper::ObjectType ObjectType; + typedef BluetoothNotificationRunnable4 SelfType; + + template + static already_AddRefed Create( + Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4), + const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4) + { + nsRefPtr runnable(new SelfType(aMethod)); + + if (NS_FAILED(runnable->ConvertAndSet(aIn1, aIn2, aIn3, aIn4))) { + return nullptr; + } + return runnable.forget(); + } + + template + static void + Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4), + const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4) + { + nsRefPtr runnable = Create(aMethod, aIn1, aIn2, aIn3, aIn4); + + if (!runnable) { + BT_WARNING("BluetoothNotificationRunnable4::Create failed"); + return; + } + nsresult rv = NS_DispatchToMainThread(runnable); + if (NS_FAILED(rv)) { + BT_WARNING("NS_DispatchToMainThread failed: %X", rv); + } + } + + NS_METHOD + Run() MOZ_OVERRIDE + { + MOZ_ASSERT(NS_IsMainThread()); + + ObjectType* obj = ObjectWrapper::GetInstance(); + + if (!obj) { + BT_WARNING("Notification handler not initialized"); + } else { + ((*obj).*mMethod)(mArg1, mArg2, mArg3, mArg4); + } + return NS_OK; + } + +private: + BluetoothNotificationRunnable4( + Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4)) + : mMethod(aMethod) + { + MOZ_ASSERT(mMethod); + } + + template + nsresult + ConvertAndSet(const T1& aIn1, const T2& aIn2, + const T3& aIn3, const T4& aIn4) + { + nsresult rv = Convert(aIn1, mArg1); + if (NS_FAILED(rv)) { + return rv; + } + rv = Convert(aIn2, mArg2); + if (NS_FAILED(rv)) { + return rv; + } + rv = Convert(aIn3, mArg3); + if (NS_FAILED(rv)) { + return rv; + } + rv = Convert(aIn4, mArg4); + if (NS_FAILED(rv)) { + return rv; + } + return NS_OK; + } + + Res (ObjectType::*mMethod)(Arg1, Arg2, Arg3, Arg4); + Tin1 mArg1; + Tin2 mArg2; + Tin3 mArg3; + Tin4 mArg4; +}; + +template +class BluetoothNotificationRunnable5 : public nsRunnable +{ +public: + typedef typename ObjectWrapper::ObjectType ObjectType; + typedef BluetoothNotificationRunnable5 SelfType; + + template + static already_AddRefed Create( + Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5), + const T1& aIn1, const T2& aIn2, const T3& aIn3, + const T4& aIn4, const T5& aIn5) + { + nsRefPtr runnable(new SelfType(aMethod)); + + if (NS_FAILED(runnable->ConvertAndSet(aIn1, aIn2, aIn3, aIn4, aIn5))) { + return nullptr; + } + return runnable.forget(); + } + + template + static void + Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5), + const T1& aIn1, const T2& aIn2, const T3& aIn3, + const T4& aIn4, const T5& aIn5) + { + nsRefPtr runnable = Create(aMethod, + aIn1, aIn2, aIn3, aIn4, aIn5); + if (!runnable) { + BT_WARNING("BluetoothNotificationRunnable5::Create failed"); + return; + } + nsresult rv = NS_DispatchToMainThread(runnable); + if (NS_FAILED(rv)) { + BT_WARNING("NS_DispatchToMainThread failed: %X", rv); + } + } + + NS_METHOD + Run() MOZ_OVERRIDE + { + MOZ_ASSERT(NS_IsMainThread()); + + ObjectType* obj = ObjectWrapper::GetInstance(); + + if (!obj) { + BT_WARNING("Notification handler not initialized"); + } else { + ((*obj).*mMethod)(mArg1, mArg2, mArg3, mArg4, mArg5); + } + return NS_OK; + } + +private: + BluetoothNotificationRunnable5(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, + Arg4, Arg5)) + : mMethod(aMethod) + { + MOZ_ASSERT(mMethod); + } + + template + nsresult + ConvertAndSet(const T1& aIn1, const T2& aIn2, const T3& aIn3, + const T4& aIn4, const T5& aIn5) + { + nsresult rv = Convert(aIn1, mArg1); + if (NS_FAILED(rv)) { + return rv; + } + rv = Convert(aIn2, mArg2); + if (NS_FAILED(rv)) { + return rv; + } + rv = Convert(aIn3, mArg3); + if (NS_FAILED(rv)) { + return rv; + } + rv = Convert(aIn4, mArg4); + if (NS_FAILED(rv)) { + return rv; + } + rv = Convert(aIn5, mArg5); + if (NS_FAILED(rv)) { + return rv; + } + return NS_OK; + } + + Res (ObjectType::*mMethod)(Arg1, Arg2, Arg3, Arg4, Arg5); + Tin1 mArg1; + Tin2 mArg2; + Tin3 mArg3; + Tin4 mArg4; + Tin5 mArg5; +}; + // // Socket Interface // @@ -1985,6 +2732,233 @@ DispatchBluetoothResult(BluetoothResultHandler* aRes, return rv; } +// Notification handling +// + +BluetoothNotificationHandler::~BluetoothNotificationHandler() +{ } + +static BluetoothNotificationHandler* sNotificationHandler; + +struct BluetoothCallback +{ + class NotificationHandlerWrapper + { + public: + typedef BluetoothNotificationHandler ObjectType; + + static ObjectType* GetInstance() + { + MOZ_ASSERT(NS_IsMainThread()); + + return sNotificationHandler; + } + }; + + // Notifications + + typedef BluetoothNotificationRunnable1 + AdapterStateChangedNotification; + + typedef BluetoothNotificationRunnable3, + BluetoothStatus, int, + const BluetoothProperty*> + AdapterPropertiesNotification; + + typedef BluetoothNotificationRunnable4, + BluetoothStatus, const nsAString&, + int, const BluetoothProperty*> + RemoteDevicePropertiesNotification; + + typedef BluetoothNotificationRunnable2, + int, const BluetoothProperty*> + DeviceFoundNotification; + + typedef BluetoothNotificationRunnable1 + DiscoveryStateChangedNotification; + + typedef BluetoothNotificationRunnable3 + PinRequestNotification; + + typedef BluetoothNotificationRunnable5 + SspRequestNotification; + + typedef BluetoothNotificationRunnable3 + BondStateChangedNotification; + + typedef BluetoothNotificationRunnable3 + AclStateChangedNotification; + + typedef BluetoothNotificationRunnable3, + uint8_t, uint16_t, const uint8_t*> + DutModeRecvNotification; + + typedef BluetoothNotificationRunnable2 + LeTestModeNotification; + + // Bluedroid callbacks + + static const bt_property_t* + AlignedProperties(bt_property_t* aProperties, size_t aNumProperties, + nsAutoArrayPtr& aPropertiesArray) + { + // See Bug 989976: consider aProperties address is not aligned. If + // it is aligned, we return the pointer directly; otherwise we make + // an aligned copy. The argument |aPropertiesArray| keeps track of + // the memory buffer. + if (!(reinterpret_cast(aProperties) % sizeof(void*))) { + return aProperties; + } + + bt_property_t* properties = new bt_property_t[aNumProperties]; + memcpy(properties, aProperties, aNumProperties * sizeof(*properties)); + aPropertiesArray = properties; + + return properties; + } + + static void + AdapterStateChanged(bt_state_t aStatus) + { + AdapterStateChangedNotification::Dispatch( + &BluetoothNotificationHandler::AdapterStateChangedNotification, + aStatus); + } + + static void + AdapterProperties(bt_status_t aStatus, int aNumProperties, + bt_property_t* aProperties) + { + nsAutoArrayPtr propertiesArray; + + AdapterPropertiesNotification::Dispatch( + &BluetoothNotificationHandler::AdapterPropertiesNotification, + ConvertDefault(aStatus, STATUS_FAIL), aNumProperties, + ConvertArray( + AlignedProperties(aProperties, aNumProperties, propertiesArray), + aNumProperties)); + } + + static void + RemoteDeviceProperties(bt_status_t aStatus, bt_bdaddr_t* aBdAddress, + int aNumProperties, bt_property_t* aProperties) + { + nsAutoArrayPtr propertiesArray; + + RemoteDevicePropertiesNotification::Dispatch( + &BluetoothNotificationHandler::RemoteDevicePropertiesNotification, + ConvertDefault(aStatus, STATUS_FAIL), aBdAddress, aNumProperties, + ConvertArray( + AlignedProperties(aProperties, aNumProperties, propertiesArray), + aNumProperties)); + } + + static void + DeviceFound(int aNumProperties, bt_property_t* aProperties) + { + nsAutoArrayPtr propertiesArray; + + DeviceFoundNotification::Dispatch( + &BluetoothNotificationHandler::DeviceFoundNotification, + aNumProperties, + ConvertArray( + AlignedProperties(aProperties, aNumProperties, propertiesArray), + aNumProperties)); + } + + static void + DiscoveryStateChanged(bt_discovery_state_t aState) + { + DiscoveryStateChangedNotification::Dispatch( + &BluetoothNotificationHandler::DiscoveryStateChangedNotification, + aState); + } + + static void + PinRequest(bt_bdaddr_t* aRemoteBdAddress, + bt_bdname_t* aRemoteBdName, uint32_t aRemoteClass) + { + PinRequestNotification::Dispatch( + &BluetoothNotificationHandler::PinRequestNotification, + aRemoteBdAddress, aRemoteBdName, aRemoteClass); + } + + static void + SspRequest(bt_bdaddr_t* aRemoteBdAddress, bt_bdname_t* aRemoteBdName, + uint32_t aRemoteClass, bt_ssp_variant_t aPairingVariant, + uint32_t aPasskey) + { + SspRequestNotification::Dispatch( + &BluetoothNotificationHandler::SspRequestNotification, + aRemoteBdAddress, aRemoteBdName, aRemoteClass, + aPairingVariant, aPasskey); + } + + static void + BondStateChanged(bt_status_t aStatus, bt_bdaddr_t* aRemoteBdAddress, + bt_bond_state_t aState) + { + BondStateChangedNotification::Dispatch( + &BluetoothNotificationHandler::BondStateChangedNotification, + aStatus, aRemoteBdAddress, aState); + } + + static void + AclStateChanged(bt_status_t aStatus, bt_bdaddr_t* aRemoteBdAddress, + bt_acl_state_t aState) + { + AclStateChangedNotification::Dispatch( + &BluetoothNotificationHandler::AclStateChangedNotification, + aStatus, aRemoteBdAddress, aState); + } + + static void + ThreadEvt(bt_cb_thread_evt evt) + { + // This callback maintains internal state and is not exported. + } + + static void + DutModeRecv(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen) + { + DutModeRecvNotification::Dispatch( + &BluetoothNotificationHandler::DutModeRecvNotification, + aOpcode, ConvertArray(aBuf, aLen), aLen); + } + + static void + LeTestMode(bt_status_t aStatus, uint16_t aNumPackets) + { + LeTestModeNotification::Dispatch( + &BluetoothNotificationHandler::LeTestModeNotification, + aStatus, aNumPackets); + } +}; + +// Interface +// + /* returns the container structure of a variable; _t is the container's * type, _v the name of the variable, and _m is _v's field within _t */ @@ -2057,10 +3031,28 @@ BluetoothInterface::~BluetoothInterface() { } void -BluetoothInterface::Init(bt_callbacks_t* aCallbacks, +BluetoothInterface::Init(BluetoothNotificationHandler* aNotificationHandler, BluetoothResultHandler* aRes) { - int status = mInterface->init(aCallbacks); + static bt_callbacks_t sBluetoothCallbacks = { + sizeof(sBluetoothCallbacks), + .adapter_state_changed_cb = BluetoothCallback::AdapterStateChanged, + .adapter_properties_cb = BluetoothCallback::AdapterProperties, + .remote_device_properties_cb = BluetoothCallback::RemoteDeviceProperties, + .device_found_cb = BluetoothCallback::DeviceFound, + .discovery_state_changed_cb= BluetoothCallback::DiscoveryStateChanged, + .pin_request_cb = BluetoothCallback::PinRequest, + .ssp_request_cb = BluetoothCallback::SspRequest, + .bond_state_changed_cb = BluetoothCallback::BondStateChanged, + .acl_state_changed_cb = BluetoothCallback::AclStateChanged, + .thread_evt_cb = BluetoothCallback::ThreadEvt, + .dut_mode_recv_cb = BluetoothCallback::DutModeRecv, + .le_test_mode_cb = BluetoothCallback::LeTestMode + }; + + sNotificationHandler = aNotificationHandler; + + int status = mInterface->init(&sBluetoothCallbacks); if (aRes) { DispatchBluetoothResult(aRes, &BluetoothResultHandler::Init, @@ -2077,6 +3069,8 @@ BluetoothInterface::Cleanup(BluetoothResultHandler* aRes) DispatchBluetoothResult(aRes, &BluetoothResultHandler::Cleanup, STATUS_SUCCESS); } + + sNotificationHandler = nullptr; } void diff --git a/dom/bluetooth/bluedroid/BluetoothInterface.h b/dom/bluetooth/bluedroid/BluetoothInterface.h index 3720e33e73e6..dc2a272fe8b7 100644 --- a/dom/bluetooth/bluedroid/BluetoothInterface.h +++ b/dom/bluetooth/bluedroid/BluetoothInterface.h @@ -326,6 +326,50 @@ private: // Bluetooth Core Interface // +class BluetoothNotificationHandler +{ +public: + virtual ~BluetoothNotificationHandler(); + + virtual void AdapterStateChangedNotification(bool aState) { } + virtual void AdapterPropertiesNotification( + BluetoothStatus aStatus, int aNumProperties, + const BluetoothProperty* aProperties) { } + + virtual void RemoteDevicePropertiesNotification( + BluetoothStatus aStatus, const nsAString& 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, + const nsAString& aBdName, uint32_t aCod) { } + virtual void SspRequestNotification(const nsAString& aRemoteBdAddr, + const nsAString& aBdName, + uint32_t aCod, + const nsAString& 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 DutModeRecvNotification(uint16_t aOpcode, + const uint8_t* aBuf, uint8_t aLen) { } + virtual void LeTestModeNotification(BluetoothStatus aStatus, + uint16_t aNumPackets) { } + +protected: + BluetoothNotificationHandler() + { } +}; + class BluetoothResultHandler { public: @@ -375,7 +419,8 @@ class BluetoothInterface public: static BluetoothInterface* GetInstance(); - void Init(bt_callbacks_t* aCallbacks, BluetoothResultHandler* aRes); + void Init(BluetoothNotificationHandler* aNotificationHandler, + BluetoothResultHandler* aRes); void Cleanup(BluetoothResultHandler* aRes); void Enable(BluetoothResultHandler* aRes); diff --git a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp index 758ad680b82e..296d6486f7fb 100644 --- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp +++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp @@ -21,7 +21,6 @@ #include "BluetoothA2dpManager.h" #include "BluetoothHfpManager.h" #include "BluetoothOppManager.h" -#include "BluetoothInterface.h" #include "BluetoothProfileController.h" #include "BluetoothReplyRunnable.h" #include "BluetoothUtils.h" @@ -41,7 +40,6 @@ } \ } while(0) -#define MAX_UUID_SIZE 16 // Audio: Major service class = 0x100 (Bit 21 is set) #define SET_AUDIO_BIT(cod) (cod |= 0x200000) // Rendering: Major service class = 0x20 (Bit 18 is set) @@ -51,12 +49,9 @@ using namespace mozilla; using namespace mozilla::ipc; USING_BLUETOOTH_NAMESPACE -// TODO: Non thread-safe static variables static nsString sAdapterBdAddress; static nsString sAdapterBdName; static InfallibleTArray sAdapterBondedAddressArray; - -// Static variables below should only be used on *main thread* static BluetoothInterface* sBtInterface; static nsTArray > sControllerArray; static InfallibleTArray sRemoteDevicesPack; @@ -65,41 +60,12 @@ static nsTArray > sSetPropertyRunnableArray; static nsTArray > sGetDeviceRunnableArray; static nsTArray > sBondingRunnableArray; static nsTArray > sUnbondingRunnableArray; - -// Static variables below should only be used on *callback thread* - - -// Atomic static variables -static Atomic sAdapterDiscoverable(false); -static Atomic sAdapterDiscoverableTimeout(0); +static bool sAdapterDiscoverable(false); +static uint32_t sAdapterDiscoverableTimeout(0); /** * Classes only used in this file */ -class DistributeBluetoothSignalTask MOZ_FINAL : public nsRunnable -{ -public: - DistributeBluetoothSignalTask(const BluetoothSignal& aSignal) : - mSignal(aSignal) - { - } - - NS_IMETHOD - Run() - { - MOZ_ASSERT(NS_IsMainThread()); - - BluetoothService* bs = BluetoothService::Get(); - NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE); - - bs->DistributeSignal(mSignal); - - return NS_OK; - } - -private: - BluetoothSignal mSignal; -}; class SetupAfterEnabledTask MOZ_FINAL : public nsRunnable { @@ -327,509 +293,6 @@ PlayStatusStringToControlPlayStatus(const nsAString& aPlayStatus) return playStatus; } -/** - * Bluedroid HAL callback functions - * - * Several callbacks are dispatched to main thread to avoid racing issues. - */ -static void -AdapterStateChangeCallback(bt_state_t aStatus) -{ - MOZ_ASSERT(!NS_IsMainThread()); - - BT_LOGR("BT_STATE: %d", aStatus); - - bool isBtEnabled = (aStatus == BT_STATE_ON); - - if (!isBtEnabled && - NS_FAILED(NS_DispatchToMainThread(new CleanupTask()))) { - BT_WARNING("Failed to dispatch to main thread!"); - return; - } - - nsRefPtr runnable = - new BluetoothService::ToggleBtAck(isBtEnabled); - if (NS_FAILED(NS_DispatchToMainThread(runnable))) { - BT_WARNING("Failed to dispatch to main thread!"); - return; - } - - if (isBtEnabled && - NS_FAILED(NS_DispatchToMainThread(new SetupAfterEnabledTask()))) { - BT_WARNING("Failed to dispatch to main thread!"); - return; - } -} - -class AdapterPropertiesCallbackTask MOZ_FINAL : public nsRunnable -{ -public: - NS_IMETHOD - Run() - { - MOZ_ASSERT(NS_IsMainThread()); - - if (!sSetPropertyRunnableArray.IsEmpty()) { - DispatchBluetoothReply(sSetPropertyRunnableArray[0], - BluetoothValue(true), EmptyString()); - sSetPropertyRunnableArray.RemoveElementAt(0); - } - - return NS_OK; - } -}; - -/** - * AdapterPropertiesCallback will be called after enable() but before - * AdapterStateChangeCallback is called. At that moment, both - * BluetoothManager/BluetoothAdapter does not register observer yet. - */ -static void -AdapterPropertiesCallback(bt_status_t aStatus, int aNumProperties, - bt_property_t *aProperties) -{ - MOZ_ASSERT(!NS_IsMainThread()); - - BluetoothValue propertyValue; - InfallibleTArray props; - - for (int i = 0; i < aNumProperties; i++) { - bt_property_t p; - // See Bug 989976, consider aProperties address is not aligned - memcpy(&p, &aProperties[i], sizeof(p)); - - if (p.type == BT_PROPERTY_BDADDR) { - BdAddressTypeToString((bt_bdaddr_t*)p.val, sAdapterBdAddress); - propertyValue = sAdapterBdAddress; - BT_APPEND_NAMED_VALUE(props, "Address", propertyValue); - } else if (p.type == BT_PROPERTY_BDNAME) { - // Construct nsCString here because Bd name returned from bluedroid - // is missing a null terminated character after SetProperty. - propertyValue = sAdapterBdName = NS_ConvertUTF8toUTF16( - nsCString((char*)p.val, p.len)); - BT_APPEND_NAMED_VALUE(props, "Name", propertyValue); - } else if (p.type == BT_PROPERTY_ADAPTER_SCAN_MODE) { - bt_scan_mode_t newMode = *(bt_scan_mode_t*)p.val; - - if (newMode == BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE) { - propertyValue = sAdapterDiscoverable = true; - } else { - propertyValue = sAdapterDiscoverable = false; - } - - BT_APPEND_NAMED_VALUE(props, "Discoverable", propertyValue); - } else if (p.type == BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT) { - propertyValue = sAdapterDiscoverableTimeout = *(uint32_t*)p.val; - BT_APPEND_NAMED_VALUE(props, "DiscoverableTimeout", propertyValue); - } else if (p.type == BT_PROPERTY_ADAPTER_BONDED_DEVICES) { - // We have to cache addresses of bonded devices. Unlike BlueZ, - // bluedroid would not send an another BT_PROPERTY_ADAPTER_BONDED_DEVICES - // event after bond completed - bt_bdaddr_t* deviceBdAddressTypes = (bt_bdaddr_t*)p.val; - int numOfAddresses = p.len / BLUETOOTH_ADDRESS_BYTES; - BT_LOGD("Adapter property: BONDED_DEVICES. Count: %d", numOfAddresses); - - // Whenever reloading paired devices, force refresh - sAdapterBondedAddressArray.Clear(); - - for (int index = 0; index < numOfAddresses; index++) { - nsAutoString deviceBdAddress; - BdAddressTypeToString(deviceBdAddressTypes + index, deviceBdAddress); - sAdapterBondedAddressArray.AppendElement(deviceBdAddress); - } - - propertyValue = sAdapterBondedAddressArray; - BT_APPEND_NAMED_VALUE(props, "Devices", propertyValue); - } else if (p.type == BT_PROPERTY_UUIDS) { - //FIXME: This will be implemented in the later patchset - continue; - } else { - BT_LOGD("Unhandled adapter property type: %d", p.type); - continue; - } - } - - NS_ENSURE_TRUE_VOID(props.Length() > 0); - - BluetoothValue value(props); - BluetoothSignal signal(NS_LITERAL_STRING("PropertyChanged"), - NS_LITERAL_STRING(KEY_ADAPTER), value); - nsRefPtr - t = new DistributeBluetoothSignalTask(signal); - if (NS_FAILED(NS_DispatchToMainThread(t))) { - BT_WARNING("Failed to dispatch to main thread!"); - } - - // Redirect to main thread to avoid racing problem - NS_DispatchToMainThread(new AdapterPropertiesCallbackTask()); -} - -class RemoteDevicePropertiesCallbackTask : public nsRunnable -{ - const InfallibleTArray mProps; - nsString mRemoteDeviceBdAddress; -public: - RemoteDevicePropertiesCallbackTask( - const InfallibleTArray& aProps, - const nsAString& aRemoteDeviceBdAddress) - : mProps(aProps) - , mRemoteDeviceBdAddress(aRemoteDeviceBdAddress) - { } - - NS_IMETHOD - Run() - { - MOZ_ASSERT(NS_IsMainThread()); - - if (sRequestedDeviceCountArray.IsEmpty()) { - // This is possible because the callback would be called after turning - // Bluetooth on. - return NS_OK; - } - - // Update to registered BluetoothDevice objects - BluetoothSignal signal(NS_LITERAL_STRING("PropertyChanged"), - mRemoteDeviceBdAddress, mProps); - nsRefPtr - t = new DistributeBluetoothSignalTask(signal); - if (NS_FAILED(NS_DispatchToMainThread(t))) { - BT_WARNING("Failed to dispatch to main thread!"); - return NS_OK; - } - - // Use address as the index - sRemoteDevicesPack.AppendElement( - BluetoothNamedValue(mRemoteDeviceBdAddress, mProps)); - - if (--sRequestedDeviceCountArray[0] == 0) { - if (!sGetDeviceRunnableArray.IsEmpty()) { - DispatchBluetoothReply(sGetDeviceRunnableArray[0], - sRemoteDevicesPack, EmptyString()); - sGetDeviceRunnableArray.RemoveElementAt(0); - } - - sRequestedDeviceCountArray.RemoveElementAt(0); - sRemoteDevicesPack.Clear(); - } - - return NS_OK; - } -}; - -/** - * RemoteDevicePropertiesCallback will be called, as the following conditions: - * 1. When BT is turning on, bluedroid automatically execute this callback - * 2. When get_remote_device_properties() - */ -static void -RemoteDevicePropertiesCallback(bt_status_t aStatus, bt_bdaddr_t *aBdAddress, - int aNumProperties, bt_property_t *aProperties) -{ - MOZ_ASSERT(!NS_IsMainThread()); - - InfallibleTArray props; - - nsString remoteDeviceBdAddress; - BdAddressTypeToString(aBdAddress, remoteDeviceBdAddress); - BT_APPEND_NAMED_VALUE(props, "Address", remoteDeviceBdAddress); - - bool isCodInvalid = false; - for (int i = 0; i < aNumProperties; ++i) { - bt_property_t p = aProperties[i]; - - if (p.type == BT_PROPERTY_BDNAME) { - BluetoothValue propertyValue = NS_ConvertUTF8toUTF16((char*)p.val); - BT_APPEND_NAMED_VALUE(props, "Name", propertyValue); - } else if (p.type == BT_PROPERTY_CLASS_OF_DEVICE) { - uint32_t cod = *(uint32_t*)p.val; - nsString icon; - ClassToIcon(cod, icon); - if (!icon.IsEmpty()) { - // Valid CoD - BT_APPEND_NAMED_VALUE(props, "Class", cod); - BT_APPEND_NAMED_VALUE(props, "Icon", icon); - } else { - // If Cod is invalid, fallback to check UUIDs. It usually happens due to - // NFC directly trigger pairing. bluedroid sends wrong CoD due to missing - // EIR query records. - isCodInvalid = true; - } - } else if (p.type == BT_PROPERTY_UUIDS) { - InfallibleTArray uuidsArray; - int uuidListLength = p.len / MAX_UUID_SIZE; - uint32_t cod = 0; - - for (int i = 0; i < uuidListLength; i++) { - uint16_t uuidServiceClass = UuidToServiceClassInt((bt_uuid_t*)(p.val + - (i * MAX_UUID_SIZE))); - BluetoothServiceClass serviceClass = BluetoothUuidHelper:: - GetBluetoothServiceClass(uuidServiceClass); - - // Get Uuid string from BluetoothServiceClass - nsString uuid; - BluetoothUuidHelper::GetString(serviceClass, uuid); - uuidsArray.AppendElement(uuid); - - // Restore CoD value - if (isCodInvalid) { - if (serviceClass == BluetoothServiceClass::HANDSFREE || - serviceClass == BluetoothServiceClass::HEADSET) { - BT_LOGD("Restore Class Of Device to Audio bit"); - SET_AUDIO_BIT(cod); - } else if (serviceClass == BluetoothServiceClass::A2DP_SINK) { - BT_LOGD("Restore Class of Device to Rendering bit"); - SET_RENDERING_BIT(cod); - } - } - } - - if (isCodInvalid) { - BT_APPEND_NAMED_VALUE(props, "Class", cod); - // 'audio-card' refers to 'Audio' device - BT_APPEND_NAMED_VALUE(props, "Icon", NS_LITERAL_STRING("audio-card")); - } - BT_APPEND_NAMED_VALUE(props, "UUIDS", uuidsArray); - } else { - BT_LOGD("Other non-handled device properties. Type: %d", p.type); - } - } - - // Redirect to main thread to avoid racing problem - NS_DispatchToMainThread( - new RemoteDevicePropertiesCallbackTask(props, remoteDeviceBdAddress)); -} - -static void -DeviceFoundCallback(int aNumProperties, bt_property_t *aProperties) -{ - MOZ_ASSERT(!NS_IsMainThread()); - - BluetoothValue propertyValue; - InfallibleTArray propertiesArray; - - for (int i = 0; i < aNumProperties; i++) { - bt_property_t p = aProperties[i]; - - if (p.type == BT_PROPERTY_BDADDR) { - nsString remoteDeviceBdAddress; - BdAddressTypeToString((bt_bdaddr_t*)p.val, remoteDeviceBdAddress); - propertyValue = remoteDeviceBdAddress; - - BT_APPEND_NAMED_VALUE(propertiesArray, "Address", propertyValue); - } else if (p.type == BT_PROPERTY_BDNAME) { - propertyValue = NS_ConvertUTF8toUTF16((char*)p.val); - BT_APPEND_NAMED_VALUE(propertiesArray, "Name", propertyValue); - } else if (p.type == BT_PROPERTY_CLASS_OF_DEVICE) { - uint32_t cod = *(uint32_t*)p.val; - propertyValue = cod; - BT_APPEND_NAMED_VALUE(propertiesArray, "Class", propertyValue); - - nsString icon; - ClassToIcon(cod, icon); - propertyValue = icon; - BT_APPEND_NAMED_VALUE(propertiesArray, "Icon", propertyValue); - } else { - BT_LOGD("Not handled remote device property: %d", p.type); - } - } - - BluetoothValue value = propertiesArray; - BluetoothSignal signal(NS_LITERAL_STRING("DeviceFound"), - NS_LITERAL_STRING(KEY_ADAPTER), value); - nsRefPtr - t = new DistributeBluetoothSignalTask(signal); - if (NS_FAILED(NS_DispatchToMainThread(t))) { - BT_WARNING("Failed to dispatch to main thread!"); - } -} - -static void -DiscoveryStateChangedCallback(bt_discovery_state_t aState) -{ - MOZ_ASSERT(!NS_IsMainThread()); - - bool isDiscovering = (aState == BT_DISCOVERY_STARTED); - BluetoothSignal signal(NS_LITERAL_STRING(DISCOVERY_STATE_CHANGED_ID), - NS_LITERAL_STRING(KEY_ADAPTER), isDiscovering); - - nsRefPtr t = - new DistributeBluetoothSignalTask(signal); - if (NS_FAILED(NS_DispatchToMainThread(t))) { - BT_WARNING("Failed to dispatch to main thread!"); - } -} - -static void -PinRequestCallback(bt_bdaddr_t* aRemoteBdAddress, - bt_bdname_t* aRemoteBdName, uint32_t aRemoteClass) -{ - MOZ_ASSERT(!NS_IsMainThread()); - - InfallibleTArray propertiesArray; - nsAutoString remoteAddress; - BdAddressTypeToString(aRemoteBdAddress, remoteAddress); - - BT_APPEND_NAMED_VALUE(propertiesArray, "address", remoteAddress); - BT_APPEND_NAMED_VALUE(propertiesArray, "method", - NS_LITERAL_STRING("pincode")); - BT_APPEND_NAMED_VALUE(propertiesArray, "name", - NS_ConvertUTF8toUTF16( - (const char*)aRemoteBdName->name)); - - BluetoothValue value = propertiesArray; - BluetoothSignal signal(NS_LITERAL_STRING("RequestPinCode"), - NS_LITERAL_STRING(KEY_LOCAL_AGENT), value); - nsRefPtr - t = new DistributeBluetoothSignalTask(signal); - if (NS_FAILED(NS_DispatchToMainThread(t))) { - BT_WARNING("Failed to dispatch to main thread!"); - } -} - -static void -SspRequestCallback(bt_bdaddr_t* aRemoteBdAddress, bt_bdname_t* aRemoteBdName, - uint32_t aRemoteClass, bt_ssp_variant_t aPairingVariant, - uint32_t aPasskey) -{ - MOZ_ASSERT(!NS_IsMainThread()); - - InfallibleTArray propertiesArray; - nsAutoString remoteAddress; - BdAddressTypeToString(aRemoteBdAddress, remoteAddress); - - BT_APPEND_NAMED_VALUE(propertiesArray, "address", remoteAddress); - BT_APPEND_NAMED_VALUE(propertiesArray, "method", - NS_LITERAL_STRING("confirmation")); - BT_APPEND_NAMED_VALUE(propertiesArray, "name", - NS_ConvertUTF8toUTF16( - (const char*)aRemoteBdName->name)); - BT_APPEND_NAMED_VALUE(propertiesArray, "passkey", aPasskey); - - BluetoothValue value = propertiesArray; - BluetoothSignal signal(NS_LITERAL_STRING("RequestConfirmation"), - NS_LITERAL_STRING(KEY_LOCAL_AGENT), value); - nsRefPtr - t = new DistributeBluetoothSignalTask(signal); - if (NS_FAILED(NS_DispatchToMainThread(t))) { - BT_WARNING("Failed to dispatch to main thread!"); - } -} - -class BondStateChangedCallbackTask : public nsRunnable -{ - nsString mRemoteDeviceBdAddress; - bool mBonded; -public: - BondStateChangedCallbackTask(const nsAString& aRemoteDeviceBdAddress, - bool aBonded) - : mRemoteDeviceBdAddress(aRemoteDeviceBdAddress) - , mBonded(aBonded) - { } - - NS_IMETHOD - Run() - { - MOZ_ASSERT(NS_IsMainThread()); - - if (mBonded && !sBondingRunnableArray.IsEmpty()) { - DispatchBluetoothReply(sBondingRunnableArray[0], - BluetoothValue(true), EmptyString()); - - sBondingRunnableArray.RemoveElementAt(0); - } else if (!mBonded && !sUnbondingRunnableArray.IsEmpty()) { - DispatchBluetoothReply(sUnbondingRunnableArray[0], - BluetoothValue(true), EmptyString()); - - sUnbondingRunnableArray.RemoveElementAt(0); - } - - // Update bonding status to gaia - InfallibleTArray propertiesArray; - BT_APPEND_NAMED_VALUE(propertiesArray, "address", mRemoteDeviceBdAddress); - BT_APPEND_NAMED_VALUE(propertiesArray, "status", mBonded); - - BluetoothSignal signal(NS_LITERAL_STRING(PAIRED_STATUS_CHANGED_ID), - NS_LITERAL_STRING(KEY_ADAPTER), - BluetoothValue(propertiesArray)); - NS_DispatchToMainThread(new DistributeBluetoothSignalTask(signal)); - - return NS_OK; - } -}; - -static void -BondStateChangedCallback(bt_status_t aStatus, bt_bdaddr_t* aRemoteBdAddress, - bt_bond_state_t aState) -{ - MOZ_ASSERT(!NS_IsMainThread()); - - if (aState == BT_BOND_STATE_BONDING) { - // No need to handle bonding state - return; - } - - nsAutoString remoteBdAddress; - BdAddressTypeToString(aRemoteBdAddress, remoteBdAddress); - - if (aState == BT_BOND_STATE_BONDED && - sAdapterBondedAddressArray.Contains(remoteBdAddress)) { - // See bug 940271 for more details about this case. - return; - } - - bool bonded; - if (aState == BT_BOND_STATE_NONE) { - bonded = false; - sAdapterBondedAddressArray.RemoveElement(remoteBdAddress); - } else if (aState == BT_BOND_STATE_BONDED) { - bonded = true; - sAdapterBondedAddressArray.AppendElement(remoteBdAddress); - } - - // Update bonded address list to BluetoothAdapter - InfallibleTArray propertiesChangeArray; - BT_APPEND_NAMED_VALUE(propertiesChangeArray, "Devices", - sAdapterBondedAddressArray); - - BluetoothValue value(propertiesChangeArray); - BluetoothSignal signal(NS_LITERAL_STRING("PropertyChanged"), - NS_LITERAL_STRING(KEY_ADAPTER), - BluetoothValue(propertiesChangeArray)); - NS_DispatchToMainThread(new DistributeBluetoothSignalTask(signal)); - - // Redirect to main thread to avoid racing problem - NS_DispatchToMainThread( - new BondStateChangedCallbackTask(remoteBdAddress, bonded)); -} - -static void -AclStateChangedCallback(bt_status_t aStatus, bt_bdaddr_t* aRemoteBdAddress, - bt_acl_state_t aState) -{ - //FIXME: This will be implemented in the later patchset -} - -static void -CallbackThreadEvent(bt_cb_thread_evt evt) -{ - //FIXME: This will be implemented in the later patchset -} - -bt_callbacks_t sBluetoothCallbacks = -{ - sizeof(sBluetoothCallbacks), - AdapterStateChangeCallback, - AdapterPropertiesCallback, - RemoteDevicePropertiesCallback, - DeviceFoundCallback, - DiscoveryStateChangedCallback, - PinRequestCallback, - SspRequestCallback, - BondStateChangedCallback, - AclStateChangedCallback, - CallbackThreadEvent -}; - /** * Static functions */ @@ -952,7 +415,8 @@ StartGonkBluetooth() return NS_OK; } - sBtInterface->Init(&sBluetoothCallbacks, new InitResultHandler()); + sBtInterface->Init(reinterpret_cast(bs), + new InitResultHandler()); return NS_OK; } @@ -1750,3 +1214,402 @@ BluetoothServiceBluedroid::ToggleCalls(BluetoothReplyRunnable* aRunnable) { } +// +// Bluetooth notifications +// + +void +BluetoothServiceBluedroid::AdapterStateChangedNotification(bool aState) +{ + MOZ_ASSERT(NS_IsMainThread()); + + BT_LOGR("BT_STATE: %d", aState); + + bool isBtEnabled = (aState == true); + + if (!isBtEnabled && + NS_FAILED(NS_DispatchToMainThread(new CleanupTask()))) { + BT_WARNING("Failed to dispatch to main thread!"); + return; + } + + nsRefPtr runnable = + new BluetoothService::ToggleBtAck(isBtEnabled); + if (NS_FAILED(NS_DispatchToMainThread(runnable))) { + BT_WARNING("Failed to dispatch to main thread!"); + return; + } + + if (isBtEnabled && + NS_FAILED(NS_DispatchToMainThread(new SetupAfterEnabledTask()))) { + BT_WARNING("Failed to dispatch to main thread!"); + return; + } +} + +/** + * AdapterPropertiesNotification will be called after enable() but + * before AdapterStateChangeCallback is called. At that moment, both + * BluetoothManager and BluetoothAdapter, do not register observer + * yet. + */ +void +BluetoothServiceBluedroid::AdapterPropertiesNotification( + BluetoothStatus aStatus, int aNumProperties, + const BluetoothProperty* aProperties) +{ + MOZ_ASSERT(NS_IsMainThread()); + + BluetoothValue propertyValue; + InfallibleTArray props; + + for (int i = 0; i < aNumProperties; i++) { + + const BluetoothProperty& p = aProperties[i]; + + if (p.mType == PROPERTY_BDADDR) { + sAdapterBdAddress = p.mString; + propertyValue = sAdapterBdAddress; + BT_APPEND_NAMED_VALUE(props, "Address", propertyValue); + + } else if (p.mType == PROPERTY_BDNAME) { + sAdapterBdName = p.mString; + propertyValue = sAdapterBdName; + BT_APPEND_NAMED_VALUE(props, "Name", propertyValue); + + } else if (p.mType == PROPERTY_ADAPTER_SCAN_MODE) { + BluetoothScanMode newMode = p.mScanMode; + + if (newMode == SCAN_MODE_CONNECTABLE_DISCOVERABLE) { + propertyValue = sAdapterDiscoverable = true; + } else { + propertyValue = sAdapterDiscoverable = false; + } + + BT_APPEND_NAMED_VALUE(props, "Discoverable", propertyValue); + + } else if (p.mType == PROPERTY_ADAPTER_DISCOVERY_TIMEOUT) { + propertyValue = sAdapterDiscoverableTimeout = p.mUint32; + BT_APPEND_NAMED_VALUE(props, "DiscoverableTimeout", propertyValue); + + } 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()); + + // Whenever reloading paired devices, force refresh + sAdapterBondedAddressArray.Clear(); + + for (size_t index = 0; index < p.mStringArray.Length(); index++) { + sAdapterBondedAddressArray.AppendElement(p.mStringArray[index]); + } + + propertyValue = sAdapterBondedAddressArray; + BT_APPEND_NAMED_VALUE(props, "Devices", propertyValue); + + } else if (p.mType == PROPERTY_UUIDS) { + //FIXME: This will be implemented in the later patchset + continue; + } else { + BT_LOGD("Unhandled adapter property type: %d", p.mType); + continue; + } + } + + NS_ENSURE_TRUE_VOID(props.Length() > 0); + + DistributeSignal(BluetoothSignal(NS_LITERAL_STRING("PropertyChanged"), + NS_LITERAL_STRING(KEY_ADAPTER), + BluetoothValue(props))); + + // Send reply for SetProperty + + if (!sSetPropertyRunnableArray.IsEmpty()) { + DispatchBluetoothReply(sSetPropertyRunnableArray[0], + BluetoothValue(true), EmptyString()); + sSetPropertyRunnableArray.RemoveElementAt(0); + } +} + +/** + * RemoteDevicePropertiesNotification will be called + * + * (1) automatically by Bluedroid when BT is turning on, or + * (2) as result of GetRemoteDeviceProperties. + */ +void +BluetoothServiceBluedroid::RemoteDevicePropertiesNotification( + BluetoothStatus aStatus, const nsAString& aBdAddr, + int aNumProperties, const BluetoothProperty* aProperties) +{ + MOZ_ASSERT(NS_IsMainThread()); + + InfallibleTArray props; + + BT_APPEND_NAMED_VALUE(props, "Address", BluetoothValue(nsString(aBdAddr))); + + bool isCodInvalid = false; + for (int i = 0; i < aNumProperties; ++i) { + + const BluetoothProperty& p = aProperties[i]; + + if (p.mType == PROPERTY_BDNAME) { + BT_APPEND_NAMED_VALUE(props, "Name", p.mString); + } else if (p.mType == PROPERTY_CLASS_OF_DEVICE) { + uint32_t cod = p.mUint32; + nsString icon; + ClassToIcon(cod, icon); + if (!icon.IsEmpty()) { + // Valid CoD + BT_APPEND_NAMED_VALUE(props, "Class", cod); + BT_APPEND_NAMED_VALUE(props, "Icon", icon); + } else { + // If Cod is invalid, fallback to check UUIDs. It usually happens due to + // NFC directly trigger pairing. bluedroid sends wrong CoD due to missing + // EIR query records. + isCodInvalid = true; + } + } else if (p.mType == PROPERTY_UUIDS) { + InfallibleTArray uuidsArray; + uint32_t cod = 0; + + for (size_t i = 0; i < p.mUuidArray.Length(); i++) { + uint16_t uuidServiceClass = UuidToServiceClassInt(p.mUuidArray[i]); + BluetoothServiceClass serviceClass = + BluetoothUuidHelper::GetBluetoothServiceClass(uuidServiceClass); + + // Get Uuid string from BluetoothServiceClass + nsString uuid; + BluetoothUuidHelper::GetString(serviceClass, uuid); + uuidsArray.AppendElement(uuid); + + // Restore CoD value + if (isCodInvalid) { + if (serviceClass == BluetoothServiceClass::HANDSFREE || + serviceClass == BluetoothServiceClass::HEADSET) { + BT_LOGD("Restore Class Of Device to Audio bit"); + SET_AUDIO_BIT(cod); + } else if (serviceClass == BluetoothServiceClass::A2DP_SINK) { + BT_LOGD("Restore Class of Device to Rendering bit"); + SET_RENDERING_BIT(cod); + } + } + } + + if (isCodInvalid) { + BT_APPEND_NAMED_VALUE(props, "Class", cod); + // 'audio-card' refers to 'Audio' device + BT_APPEND_NAMED_VALUE(props, "Icon", NS_LITERAL_STRING("audio-card")); + } + BT_APPEND_NAMED_VALUE(props, "UUIDS", uuidsArray); + } else { + BT_LOGD("Other non-handled device properties. Type: %d", p.mType); + } + } + + if (sRequestedDeviceCountArray.IsEmpty()) { + // This is possible because the callback would be called after turning + // Bluetooth on. + return; + } + + // Use address as the index + sRemoteDevicesPack.AppendElement( + BluetoothNamedValue(nsString(aBdAddr), props)); + + if (--sRequestedDeviceCountArray[0] == 0) { + if (!sGetDeviceRunnableArray.IsEmpty()) { + DispatchBluetoothReply(sGetDeviceRunnableArray[0], + sRemoteDevicesPack, EmptyString()); + sGetDeviceRunnableArray.RemoveElementAt(0); + } + + sRequestedDeviceCountArray.RemoveElementAt(0); + sRemoteDevicesPack.Clear(); + } + + // Update to registered BluetoothDevice objects + DistributeSignal(BluetoothSignal(NS_LITERAL_STRING("PropertyChanged"), + nsString(aBdAddr), + BluetoothValue(props))); +} + +void +BluetoothServiceBluedroid::DeviceFoundNotification( + int aNumProperties, const BluetoothProperty* aProperties) +{ + MOZ_ASSERT(NS_IsMainThread()); + + BluetoothValue propertyValue; + InfallibleTArray propertiesArray; + + for (int i = 0; i < aNumProperties; i++) { + + const BluetoothProperty& p = aProperties[i]; + + if (p.mType == PROPERTY_BDADDR) { + propertyValue = p.mString; + + BT_APPEND_NAMED_VALUE(propertiesArray, "Address", propertyValue); + } else if (p.mType == PROPERTY_BDNAME) { + BT_APPEND_NAMED_VALUE(propertiesArray, "Name", p.mString); + } else if (p.mType == PROPERTY_CLASS_OF_DEVICE) { + uint32_t cod = p.mUint32; + propertyValue = cod; + BT_APPEND_NAMED_VALUE(propertiesArray, "Class", propertyValue); + + nsString icon; + ClassToIcon(cod, icon); + propertyValue = icon; + BT_APPEND_NAMED_VALUE(propertiesArray, "Icon", propertyValue); + } else { + BT_LOGD("Not handled remote device property: %d", p.mType); + } + } + + DistributeSignal(BluetoothSignal(NS_LITERAL_STRING("DeviceFound"), + NS_LITERAL_STRING(KEY_ADAPTER), + BluetoothValue(propertiesArray))); +} + +void +BluetoothServiceBluedroid::DiscoveryStateChangedNotification(bool aState) +{ + MOZ_ASSERT(NS_IsMainThread()); + + bool isDiscovering = (aState == true); + + DistributeSignal( + BluetoothSignal(NS_LITERAL_STRING(DISCOVERY_STATE_CHANGED_ID), + NS_LITERAL_STRING(KEY_ADAPTER), isDiscovering)); +} + +void +BluetoothServiceBluedroid::PinRequestNotification(const nsAString& aRemoteBdAddr, + const nsAString& aBdName, + uint32_t aCod) +{ + MOZ_ASSERT(NS_IsMainThread()); + + InfallibleTArray propertiesArray; + + BT_APPEND_NAMED_VALUE(propertiesArray, "address", nsString(aRemoteBdAddr)); + BT_APPEND_NAMED_VALUE(propertiesArray, "method", + NS_LITERAL_STRING("pincode")); + BT_APPEND_NAMED_VALUE(propertiesArray, "name", nsString(aBdName)); + + DistributeSignal(BluetoothSignal(NS_LITERAL_STRING("RequestPinCode"), + NS_LITERAL_STRING(KEY_LOCAL_AGENT), + BluetoothValue(propertiesArray))); +} + +void +BluetoothServiceBluedroid::SspRequestNotification( + const nsAString& aRemoteBdAddr, const nsAString& aBdName, uint32_t aCod, + const nsAString& aPairingaVariant, uint32_t aPassKey) +{ + MOZ_ASSERT(NS_IsMainThread()); + + InfallibleTArray propertiesArray; + + BT_APPEND_NAMED_VALUE(propertiesArray, "address", nsString(aRemoteBdAddr)); + BT_APPEND_NAMED_VALUE(propertiesArray, "method", + NS_LITERAL_STRING("confirmation")); + BT_APPEND_NAMED_VALUE(propertiesArray, "name", nsString(aBdName)); + BT_APPEND_NAMED_VALUE(propertiesArray, "passkey", aPassKey); + + DistributeSignal(BluetoothSignal(NS_LITERAL_STRING("RequestConfirmation"), + NS_LITERAL_STRING(KEY_LOCAL_AGENT), + BluetoothValue(propertiesArray))); +} + +void +BluetoothServiceBluedroid::BondStateChangedNotification( + BluetoothStatus aStatus, const nsAString& aRemoteBdAddr, + BluetoothBondState aState) +{ + MOZ_ASSERT(NS_IsMainThread()); + + if (aState == BOND_STATE_BONDING) { + // No need to handle bonding state + return; + } + + if (aState == BOND_STATE_BONDED && + sAdapterBondedAddressArray.Contains(aRemoteBdAddr)) { + // See bug 940271 for more details about this case. + return; + } + + bool bonded; + if (aState == BOND_STATE_NONE) { + bonded = false; + sAdapterBondedAddressArray.RemoveElement(aRemoteBdAddr); + } else if (aState == BOND_STATE_BONDED) { + bonded = true; + sAdapterBondedAddressArray.AppendElement(aRemoteBdAddr); + } else { + return; + } + + // Update bonded address list to BluetoothAdapter + InfallibleTArray propertiesChangeArray; + BT_APPEND_NAMED_VALUE(propertiesChangeArray, "Devices", + sAdapterBondedAddressArray); + + DistributeSignal(BluetoothSignal(NS_LITERAL_STRING("PropertyChanged"), + NS_LITERAL_STRING(KEY_ADAPTER), + BluetoothValue(propertiesChangeArray))); + + if (bonded && !sBondingRunnableArray.IsEmpty()) { + DispatchBluetoothReply(sBondingRunnableArray[0], + BluetoothValue(true), EmptyString()); + + sBondingRunnableArray.RemoveElementAt(0); + } else if (!bonded && !sUnbondingRunnableArray.IsEmpty()) { + DispatchBluetoothReply(sUnbondingRunnableArray[0], + BluetoothValue(true), EmptyString()); + + sUnbondingRunnableArray.RemoveElementAt(0); + } + + // Update bonding status to gaia + InfallibleTArray propertiesArray; + BT_APPEND_NAMED_VALUE(propertiesArray, "address", nsString(aRemoteBdAddr)); + BT_APPEND_NAMED_VALUE(propertiesArray, "status", bonded); + + DistributeSignal( + BluetoothSignal(NS_LITERAL_STRING(PAIRED_STATUS_CHANGED_ID), + NS_LITERAL_STRING(KEY_ADAPTER), + BluetoothValue(propertiesArray))); +} + +void +BluetoothServiceBluedroid::AclStateChangedNotification( + BluetoothStatus aStatus, const nsAString& aRemoteBdAddr, bool aState) +{ + MOZ_ASSERT(NS_IsMainThread()); + + // FIXME: This will be implemented in the later patchset +} + +void +BluetoothServiceBluedroid::DutModeRecvNotification(uint16_t aOpcode, + const uint8_t* aBuf, + uint8_t aLen) +{ + MOZ_ASSERT(NS_IsMainThread()); + + // FIXME: This will be implemented in the later patchset +} + +void +BluetoothServiceBluedroid::LeTestModeNotification(BluetoothStatus aStatus, + uint16_t aNumPackets) +{ + MOZ_ASSERT(NS_IsMainThread()); + + // FIXME: This will be implemented in the later patchset +} diff --git a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h index c77bb991f6ef..60d3651ad397 100644 --- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h +++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h @@ -8,11 +8,13 @@ #define mozilla_dom_bluetooth_bluetoothservicebluedroid_h__ #include "BluetoothCommon.h" +#include "BluetoothInterface.h" #include "BluetoothService.h" BEGIN_BLUETOOTH_NAMESPACE class BluetoothServiceBluedroid : public BluetoothService + , public BluetoothNotificationHandler { public: BluetoothServiceBluedroid(); @@ -153,6 +155,46 @@ public: virtual nsresult SendInputMessage(const nsAString& aDeviceAddresses, const nsAString& aMessage) MOZ_OVERRIDE; + + // + // Bluetooth notifications + // + + virtual void AdapterStateChangedNotification(bool aState) MOZ_OVERRIDE; + virtual void AdapterPropertiesNotification( + BluetoothStatus aStatus, int aNumProperties, + const BluetoothProperty* aProperties) MOZ_OVERRIDE; + + virtual void RemoteDevicePropertiesNotification( + BluetoothStatus aStatus, const nsAString& aBdAddr, + int aNumProperties, const BluetoothProperty* aProperties) MOZ_OVERRIDE; + + virtual void DeviceFoundNotification( + int aNumProperties, const BluetoothProperty* aProperties) MOZ_OVERRIDE; + + virtual void DiscoveryStateChangedNotification(bool aState) MOZ_OVERRIDE; + + virtual void PinRequestNotification(const nsAString& aRemoteBdAddr, + const nsAString& aBdName, + uint32_t aCod) MOZ_OVERRIDE; + virtual void SspRequestNotification(const nsAString& aRemoteBdAddr, + const nsAString& aBdName, + uint32_t aCod, + const nsAString& aPairingaVariant, + uint32_t aPassKey) MOZ_OVERRIDE; + + virtual void BondStateChangedNotification( + BluetoothStatus aStatus, const nsAString& aRemoteBdAddr, + BluetoothBondState aState) MOZ_OVERRIDE; + virtual void AclStateChangedNotification(BluetoothStatus aStatus, + const nsAString& aRemoteBdAddr, + bool aState) MOZ_OVERRIDE; + + virtual void DutModeRecvNotification(uint16_t aOpcode, + const uint8_t* aBuf, + uint8_t aLen) MOZ_OVERRIDE; + virtual void LeTestModeNotification(BluetoothStatus aStatus, + uint16_t aNumPackets) MOZ_OVERRIDE; }; END_BLUETOOTH_NAMESPACE diff --git a/dom/bluetooth/bluedroid/BluetoothUtils.cpp b/dom/bluetooth/bluedroid/BluetoothUtils.cpp index eb2b0e546e51..c89efef54f8a 100644 --- a/dom/bluetooth/bluedroid/BluetoothUtils.cpp +++ b/dom/bluetooth/bluedroid/BluetoothUtils.cpp @@ -23,19 +23,6 @@ BEGIN_BLUETOOTH_NAMESPACE -void -StringToBdAddressType(const nsAString& aBdAddress, - bt_bdaddr_t *aRetBdAddressType) -{ - NS_ConvertUTF16toUTF8 bdAddressUTF8(aBdAddress); - const char* str = bdAddressUTF8.get(); - - for (int i = 0; i < 6; i++) { - aRetBdAddressType->address[i] = (uint8_t) strtoul(str, (char **)&str, 16); - str++; - } -} - void BdAddressTypeToString(bt_bdaddr_t* aBdAddressType, nsAString& aRetBdAddress) { @@ -50,11 +37,11 @@ BdAddressTypeToString(bt_bdaddr_t* aBdAddressType, nsAString& aRetBdAddress) } uint16_t -UuidToServiceClassInt(bt_uuid_t* p_uuid) +UuidToServiceClassInt(const BluetoothUuid& mUuid) { // extract short UUID 0000xxxx-0000-1000-8000-00805f9b34fb uint16_t shortUuid; - memcpy(&shortUuid, &(p_uuid->uu[2]), sizeof(uint16_t)); + memcpy(&shortUuid, mUuid.mUuid + 2, sizeof(uint16_t)); return ntohs(shortUuid); } diff --git a/dom/bluetooth/bluedroid/BluetoothUtils.h b/dom/bluetooth/bluedroid/BluetoothUtils.h index 40bd2392bc14..4cf0c470cb19 100644 --- a/dom/bluetooth/bluedroid/BluetoothUtils.h +++ b/dom/bluetooth/bluedroid/BluetoothUtils.h @@ -18,16 +18,12 @@ class BluetoothNamedValue; class BluetoothValue; class BluetoothReplyRunnable; -void -StringToBdAddressType(const nsAString& aBdAddress, - bt_bdaddr_t *aRetBdAddressType); - void BdAddressTypeToString(bt_bdaddr_t* aBdAddressType, nsAString& aRetBdAddress); uint16_t -UuidToServiceClassInt(bt_uuid_t* p_uuid); +UuidToServiceClassInt(const BluetoothUuid& mUuid); bool SetJsObject(JSContext* aContext, diff --git a/dom/browser-element/BrowserElementChildPreload.js b/dom/browser-element/BrowserElementChildPreload.js index abeda31582c6..887c55d41d6b 100644 --- a/dom/browser-element/BrowserElementChildPreload.js +++ b/dom/browser-element/BrowserElementChildPreload.js @@ -644,15 +644,15 @@ BrowserElementChild.prototype = { isCollapsed: (e.selectedText.length == 0), }; - // Get correct geometry information if we have nested