dom/bluetooth/tests/marionette/head.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 * vim: sw=2 ts=2 sts=2 et filetype=javascript
michael@0 3 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 // https://github.com/mozilla-b2g/platform_external_qemu/blob/master/vl-android.c#L765
michael@0 8 // static int bt_hci_parse(const char *str) {
michael@0 9 // ...
michael@0 10 // bdaddr.b[0] = 0x52;
michael@0 11 // bdaddr.b[1] = 0x54;
michael@0 12 // bdaddr.b[2] = 0x00;
michael@0 13 // bdaddr.b[3] = 0x12;
michael@0 14 // bdaddr.b[4] = 0x34;
michael@0 15 // bdaddr.b[5] = 0x56 + nb_hcis;
michael@0 16 const EMULATOR_ADDRESS = "56:34:12:00:54:52";
michael@0 17
michael@0 18 // $ adb shell hciconfig /dev/ttyS2 name
michael@0 19 // hci0: Type: BR/EDR Bus: UART
michael@0 20 // BD Address: 56:34:12:00:54:52 ACL MTU: 512:1 SCO MTU: 0:0
michael@0 21 // Name: 'Full Android on Emulator'
michael@0 22 const EMULATOR_NAME = "Full Android on Emulator";
michael@0 23
michael@0 24 // $ adb shell hciconfig /dev/ttyS2 class
michael@0 25 // hci0: Type: BR/EDR Bus: UART
michael@0 26 // BD Address: 56:34:12:00:54:52 ACL MTU: 512:1 SCO MTU: 0:0
michael@0 27 // Class: 0x58020c
michael@0 28 // Service Classes: Capturing, Object Transfer, Telephony
michael@0 29 // Device Class: Phone, Smart phone
michael@0 30 const EMULATOR_CLASS = 0x58020c;
michael@0 31
michael@0 32 // Use same definition in QEMU for special bluetooth address,
michael@0 33 // which were defined at external/qemu/hw/bt.h:
michael@0 34 const BDADDR_ANY = "00:00:00:00:00:00";
michael@0 35 const BDADDR_ALL = "ff:ff:ff:ff:ff:ff";
michael@0 36 const BDADDR_LOCAL = "ff:ff:ff:00:00:00";
michael@0 37
michael@0 38 // A user friendly name for remote BT device.
michael@0 39 const REMOTE_DEVICE_NAME = "Remote BT Device";
michael@0 40
michael@0 41 let Promise =
michael@0 42 SpecialPowers.Cu.import("resource://gre/modules/Promise.jsm").Promise;
michael@0 43
michael@0 44 let bluetoothManager;
michael@0 45
michael@0 46 let pendingEmulatorCmdCount = 0;
michael@0 47
michael@0 48 /**
michael@0 49 * Send emulator command with safe guard.
michael@0 50 *
michael@0 51 * We should only call |finish()| after all emulator command transactions
michael@0 52 * end, so here comes with the pending counter. Resolve when the emulator
michael@0 53 * gives positive response, and reject otherwise.
michael@0 54 *
michael@0 55 * Fulfill params:
michael@0 56 * result -- an array of emulator response lines.
michael@0 57 *
michael@0 58 * Reject params:
michael@0 59 * result -- an array of emulator response lines.
michael@0 60 *
michael@0 61 * @return A deferred promise.
michael@0 62 */
michael@0 63 function runEmulatorCmdSafe(aCommand) {
michael@0 64 let deferred = Promise.defer();
michael@0 65
michael@0 66 ++pendingEmulatorCmdCount;
michael@0 67 runEmulatorCmd(aCommand, function(aResult) {
michael@0 68 --pendingEmulatorCmdCount;
michael@0 69
michael@0 70 ok(true, "Emulator response: " + JSON.stringify(aResult));
michael@0 71 if (Array.isArray(aResult) && aResult[aResult.length - 1] === "OK") {
michael@0 72 deferred.resolve(aResult);
michael@0 73 } else {
michael@0 74 ok(false, "Got an abnormal response from emulator.");
michael@0 75 log("Fail to execute emulator command: [" + aCommand + "]");
michael@0 76 deferred.reject(aResult);
michael@0 77 }
michael@0 78 });
michael@0 79
michael@0 80 return deferred.promise;
michael@0 81 }
michael@0 82
michael@0 83 /**
michael@0 84 * Add a Bluetooth remote device to scatternet and set its properties.
michael@0 85 *
michael@0 86 * Use QEMU command 'bt remote add' to add a virtual Bluetooth remote
michael@0 87 * and set its properties by setEmulatorDeviceProperty().
michael@0 88 *
michael@0 89 * Fulfill params:
michael@0 90 * result -- bluetooth address of the remote device.
michael@0 91 * Reject params: (none)
michael@0 92 *
michael@0 93 * @param aProperies
michael@0 94 * A javascript object with zero or several properties for initializing
michael@0 95 * the remote device. By now, the properies could be 'name' or
michael@0 96 * 'discoverable'. It valid to put a null object or a javascript object
michael@0 97 * which don't have any properies.
michael@0 98 *
michael@0 99 * @return A promise object.
michael@0 100 */
michael@0 101 function addEmulatorRemoteDevice(aProperties) {
michael@0 102 let address;
michael@0 103 let promise = runEmulatorCmdSafe("bt remote add")
michael@0 104 .then(function(aResults) {
michael@0 105 address = aResults[0].toUpperCase();
michael@0 106 });
michael@0 107
michael@0 108 for (let key in aProperties) {
michael@0 109 let value = aProperties[key];
michael@0 110 let propertyName = key;
michael@0 111 promise = promise.then(function() {
michael@0 112 return setEmulatorDeviceProperty(address, propertyName, value);
michael@0 113 });
michael@0 114 }
michael@0 115
michael@0 116 return promise.then(function() {
michael@0 117 return address;
michael@0 118 });
michael@0 119 }
michael@0 120
michael@0 121 /**
michael@0 122 * Remove Bluetooth remote devices in scatternet.
michael@0 123 *
michael@0 124 * Use QEMU command 'bt remote remove <addr>' to remove a specific virtual
michael@0 125 * Bluetooth remote device in scatternet or remove them all by QEMU command
michael@0 126 * 'bt remote remove BDADDR_ALL'.
michael@0 127 *
michael@0 128 * @param aAddress
michael@0 129 * The string of Bluetooth address with format xx:xx:xx:xx:xx:xx.
michael@0 130 *
michael@0 131 * Fulfill params:
michael@0 132 * result -- an array of emulator response lines.
michael@0 133 * Reject params: (none)
michael@0 134 *
michael@0 135 * @return A promise object.
michael@0 136 */
michael@0 137 function removeEmulatorRemoteDevice(aAddress) {
michael@0 138 let cmd = "bt remote remove " + aAddress;
michael@0 139 return runEmulatorCmdSafe(cmd)
michael@0 140 .then(function(aResults) {
michael@0 141 // 'bt remote remove <bd_addr>' returns a list of removed device one at a line.
michael@0 142 // The last item is "OK".
michael@0 143 return aResults.slice(0, -1);
michael@0 144 });
michael@0 145 }
michael@0 146
michael@0 147 /**
michael@0 148 * Set a property for a Bluetooth device.
michael@0 149 *
michael@0 150 * Use QEMU command 'bt property <bd_addr> <prop_name> <value>' to set property.
michael@0 151 *
michael@0 152 * Fulfill params:
michael@0 153 * result -- an array of emulator response lines.
michael@0 154 * Reject params:
michael@0 155 * result -- an array of emulator response lines.
michael@0 156 *
michael@0 157 * @param aAddress
michael@0 158 * The string of Bluetooth address with format xx:xx:xx:xx:xx:xx.
michael@0 159 * @param aPropertyName
michael@0 160 * The property name of Bluetooth device.
michael@0 161 * @param aValue
michael@0 162 * The new value of the specifc property.
michael@0 163 *
michael@0 164 * @return A deferred promise.
michael@0 165 */
michael@0 166 function setEmulatorDeviceProperty(aAddress, aPropertyName, aValue) {
michael@0 167 let cmd = "bt property " + aAddress + " " + aPropertyName + " " + aValue;
michael@0 168 return runEmulatorCmdSafe(cmd);
michael@0 169 }
michael@0 170
michael@0 171 /**
michael@0 172 * Get a property from a Bluetooth device.
michael@0 173 *
michael@0 174 * Use QEMU command 'bt property <bd_addr> <prop_name>' to get properties.
michael@0 175 *
michael@0 176 * Fulfill params:
michael@0 177 * result -- a string with format <prop_name>: <value_of_prop>
michael@0 178 * Reject params:
michael@0 179 * result -- an array of emulator response lines.
michael@0 180 *
michael@0 181 * @param aAddress
michael@0 182 * The string of Bluetooth address with format xx:xx:xx:xx:xx:xx.
michael@0 183 * @param aPropertyName
michael@0 184 * The property name of Bluetooth device.
michael@0 185 *
michael@0 186 * @return A deferred promise.
michael@0 187 */
michael@0 188 function getEmulatorDeviceProperty(aAddress, aPropertyName) {
michael@0 189 let cmd = "bt property " + aAddress + " " + aPropertyName;
michael@0 190 return runEmulatorCmdSafe(cmd)
michael@0 191 .then(function(aResults) {
michael@0 192 return aResults[0];
michael@0 193 });
michael@0 194 }
michael@0 195
michael@0 196 /**
michael@0 197 * Start dicovering Bluetooth devices.
michael@0 198 *
michael@0 199 * Allows the device's adapter to start seeking for remote devices.
michael@0 200 *
michael@0 201 * Fulfill params: (none)
michael@0 202 * Reject params: a DOMError
michael@0 203 *
michael@0 204 * @param aAdapter
michael@0 205 * A BluetoothAdapter which is used to interact with local BT dev
michael@0 206 *
michael@0 207 * @return A deferred promise.
michael@0 208 */
michael@0 209 function startDiscovery(aAdapter) {
michael@0 210 let deferred = Promise.defer();
michael@0 211
michael@0 212 let request = aAdapter.startDiscovery();
michael@0 213 request.onsuccess = function () {
michael@0 214 log(" Start discovery - Success");
michael@0 215 // TODO (bug 892207): Make Bluetooth APIs available for 3rd party apps.
michael@0 216 // Currently, discovering state wouldn't change immediately here.
michael@0 217 // We would turn on this check when the redesigned API are landed.
michael@0 218 // is(aAdapter.discovering, true, "BluetoothAdapter.discovering");
michael@0 219 deferred.resolve();
michael@0 220 }
michael@0 221 request.onerror = function (aEvent) {
michael@0 222 ok(false, "Start discovery - Fail");
michael@0 223 deferred.reject(aEvent.target.error);
michael@0 224 }
michael@0 225
michael@0 226 return deferred.promise;
michael@0 227 }
michael@0 228
michael@0 229 /**
michael@0 230 * Stop dicovering Bluetooth devices.
michael@0 231 *
michael@0 232 * Allows the device's adapter to stop seeking for remote devices.
michael@0 233 *
michael@0 234 * Fulfill params: (none)
michael@0 235 * Reject params: a DOMError
michael@0 236 *
michael@0 237 * @param aAdapter
michael@0 238 * A BluetoothAdapter which is used to interact with local BT device.
michael@0 239 *
michael@0 240 * @return A deferred promise.
michael@0 241 */
michael@0 242 function stopDiscovery(aAdapter) {
michael@0 243 let deferred = Promise.defer();
michael@0 244
michael@0 245 let request = aAdapter.stopDiscovery();
michael@0 246 request.onsuccess = function () {
michael@0 247 log(" Stop discovery - Success");
michael@0 248 // TODO (bug 892207): Make Bluetooth APIs available for 3rd party apps.
michael@0 249 // Currently, discovering state wouldn't change immediately here.
michael@0 250 // We would turn on this check when the redesigned API are landed.
michael@0 251 // is(aAdapter.discovering, false, "BluetoothAdapter.discovering");
michael@0 252 deferred.resolve();
michael@0 253 }
michael@0 254 request.onerror = function (aEvent) {
michael@0 255 ok(false, "Stop discovery - Fail");
michael@0 256 deferred.reject(aEvent.target.error);
michael@0 257 }
michael@0 258 return deferred.promise;
michael@0 259 }
michael@0 260
michael@0 261 /**
michael@0 262 * Get mozSettings value specified by @aKey.
michael@0 263 *
michael@0 264 * Resolve if that mozSettings value is retrieved successfully, reject
michael@0 265 * otherwise.
michael@0 266 *
michael@0 267 * Fulfill params:
michael@0 268 * The corresponding mozSettings value of the key.
michael@0 269 * Reject params: (none)
michael@0 270 *
michael@0 271 * @param aKey
michael@0 272 * A string.
michael@0 273 *
michael@0 274 * @return A deferred promise.
michael@0 275 */
michael@0 276 function getSettings(aKey) {
michael@0 277 let deferred = Promise.defer();
michael@0 278
michael@0 279 let request = navigator.mozSettings.createLock().get(aKey);
michael@0 280 request.addEventListener("success", function(aEvent) {
michael@0 281 ok(true, "getSettings(" + aKey + ")");
michael@0 282 deferred.resolve(aEvent.target.result[aKey]);
michael@0 283 });
michael@0 284 request.addEventListener("error", function() {
michael@0 285 ok(false, "getSettings(" + aKey + ")");
michael@0 286 deferred.reject();
michael@0 287 });
michael@0 288
michael@0 289 return deferred.promise;
michael@0 290 }
michael@0 291
michael@0 292 /**
michael@0 293 * Set mozSettings values.
michael@0 294 *
michael@0 295 * Resolve if that mozSettings value is set successfully, reject otherwise.
michael@0 296 *
michael@0 297 * Fulfill params: (none)
michael@0 298 * Reject params: (none)
michael@0 299 *
michael@0 300 * @param aSettings
michael@0 301 * An object of format |{key1: value1, key2: value2, ...}|.
michael@0 302 *
michael@0 303 * @return A deferred promise.
michael@0 304 */
michael@0 305 function setSettings(aSettings) {
michael@0 306 let deferred = Promise.defer();
michael@0 307
michael@0 308 let request = navigator.mozSettings.createLock().set(aSettings);
michael@0 309 request.addEventListener("success", function() {
michael@0 310 ok(true, "setSettings(" + JSON.stringify(aSettings) + ")");
michael@0 311 deferred.resolve();
michael@0 312 });
michael@0 313 request.addEventListener("error", function() {
michael@0 314 ok(false, "setSettings(" + JSON.stringify(aSettings) + ")");
michael@0 315 deferred.reject();
michael@0 316 });
michael@0 317
michael@0 318 return deferred.promise;
michael@0 319 }
michael@0 320
michael@0 321 /**
michael@0 322 * Get mozSettings value of 'bluetooth.enabled'.
michael@0 323 *
michael@0 324 * Resolve if that mozSettings value is retrieved successfully, reject
michael@0 325 * otherwise.
michael@0 326 *
michael@0 327 * Fulfill params:
michael@0 328 * A boolean value.
michael@0 329 * Reject params: (none)
michael@0 330 *
michael@0 331 * @return A deferred promise.
michael@0 332 */
michael@0 333 function getBluetoothEnabled() {
michael@0 334 return getSettings("bluetooth.enabled");
michael@0 335 }
michael@0 336
michael@0 337 /**
michael@0 338 * Set mozSettings value of 'bluetooth.enabled'.
michael@0 339 *
michael@0 340 * Resolve if that mozSettings value is set successfully, reject otherwise.
michael@0 341 *
michael@0 342 * Fulfill params: (none)
michael@0 343 * Reject params: (none)
michael@0 344 *
michael@0 345 * @param aEnabled
michael@0 346 * A boolean value.
michael@0 347 *
michael@0 348 * @return A deferred promise.
michael@0 349 */
michael@0 350 function setBluetoothEnabled(aEnabled) {
michael@0 351 let obj = {};
michael@0 352 obj["bluetooth.enabled"] = aEnabled;
michael@0 353 return setSettings(obj);
michael@0 354 }
michael@0 355
michael@0 356 /**
michael@0 357 * Push required permissions and test if |navigator.mozBluetooth| exists.
michael@0 358 * Resolve if it does, reject otherwise.
michael@0 359 *
michael@0 360 * Fulfill params:
michael@0 361 * bluetoothManager -- an reference to navigator.mozBluetooth.
michael@0 362 * Reject params: (none)
michael@0 363 *
michael@0 364 * @param aPermissions
michael@0 365 * Additional permissions to push before any test cases. Could be either
michael@0 366 * a string or an array of strings.
michael@0 367 *
michael@0 368 * @return A deferred promise.
michael@0 369 */
michael@0 370 function ensureBluetoothManager(aPermissions) {
michael@0 371 let deferred = Promise.defer();
michael@0 372
michael@0 373 let permissions = ["bluetooth"];
michael@0 374 if (aPermissions) {
michael@0 375 if (Array.isArray(aPermissions)) {
michael@0 376 permissions = permissions.concat(aPermissions);
michael@0 377 } else if (typeof aPermissions == "string") {
michael@0 378 permissions.push(aPermissions);
michael@0 379 }
michael@0 380 }
michael@0 381
michael@0 382 let obj = [];
michael@0 383 for (let perm of permissions) {
michael@0 384 obj.push({
michael@0 385 "type": perm,
michael@0 386 "allow": 1,
michael@0 387 "context": document,
michael@0 388 });
michael@0 389 }
michael@0 390
michael@0 391 SpecialPowers.pushPermissions(obj, function() {
michael@0 392 ok(true, "permissions pushed: " + JSON.stringify(permissions));
michael@0 393
michael@0 394 bluetoothManager = window.navigator.mozBluetooth;
michael@0 395 log("navigator.mozBluetooth is " +
michael@0 396 (bluetoothManager ? "available" : "unavailable"));
michael@0 397
michael@0 398 if (bluetoothManager instanceof BluetoothManager) {
michael@0 399 deferred.resolve(bluetoothManager);
michael@0 400 } else {
michael@0 401 deferred.reject();
michael@0 402 }
michael@0 403 });
michael@0 404
michael@0 405 return deferred.promise;
michael@0 406 }
michael@0 407
michael@0 408 /**
michael@0 409 * Wait for one named BluetoothManager event.
michael@0 410 *
michael@0 411 * Resolve if that named event occurs. Never reject.
michael@0 412 *
michael@0 413 * Fulfill params: the DOMEvent passed.
michael@0 414 *
michael@0 415 * @param aEventName
michael@0 416 * The name of the EventHandler.
michael@0 417 *
michael@0 418 * @return A deferred promise.
michael@0 419 */
michael@0 420 function waitForManagerEvent(aEventName) {
michael@0 421 let deferred = Promise.defer();
michael@0 422
michael@0 423 bluetoothManager.addEventListener(aEventName, function onevent(aEvent) {
michael@0 424 bluetoothManager.removeEventListener(aEventName, onevent);
michael@0 425
michael@0 426 ok(true, "BluetoothManager event '" + aEventName + "' got.");
michael@0 427 deferred.resolve(aEvent);
michael@0 428 });
michael@0 429
michael@0 430 return deferred.promise;
michael@0 431 }
michael@0 432
michael@0 433 /**
michael@0 434 * Wait for one named BluetoothAdapter event.
michael@0 435 *
michael@0 436 * Resolve if that named event occurs. Never reject.
michael@0 437 *
michael@0 438 * Fulfill params: the DOMEvent passed.
michael@0 439 *
michael@0 440 * @param aAdapter
michael@0 441 * The BluetoothAdapter you want to use.
michael@0 442 * @param aEventName
michael@0 443 * The name of the EventHandler.
michael@0 444 *
michael@0 445 * @return A deferred promise.
michael@0 446 */
michael@0 447 function waitForAdapterEvent(aAdapter, aEventName) {
michael@0 448 let deferred = Promise.defer();
michael@0 449
michael@0 450 aAdapter.addEventListener(aEventName, function onevent(aEvent) {
michael@0 451 aAdapter.removeEventListener(aEventName, onevent);
michael@0 452
michael@0 453 ok(true, "BluetoothAdapter event '" + aEventName + "' got.");
michael@0 454 deferred.resolve(aEvent);
michael@0 455 });
michael@0 456
michael@0 457 return deferred.promise;
michael@0 458 }
michael@0 459
michael@0 460 /**
michael@0 461 * Convenient function for setBluetoothEnabled and waitForManagerEvent
michael@0 462 * combined.
michael@0 463 *
michael@0 464 * Resolve if that named event occurs. Reject if we can't set settings.
michael@0 465 *
michael@0 466 * Fulfill params: the DOMEvent passed.
michael@0 467 * Reject params: (none)
michael@0 468 *
michael@0 469 * @return A deferred promise.
michael@0 470 */
michael@0 471 function setBluetoothEnabledAndWait(aEnabled) {
michael@0 472 let promises = [];
michael@0 473
michael@0 474 // Bug 969109 - Intermittent test_dom_BluetoothManager_adapteradded.js
michael@0 475 //
michael@0 476 // Here we want to wait for two events coming up -- Bluetooth "settings-set"
michael@0 477 // event and one of "enabled"/"disabled" events. Special care is taken here
michael@0 478 // to ensure that we can always receive that "enabled"/"disabled" event by
michael@0 479 // installing the event handler *before* we ever enable/disable Bluetooth. Or
michael@0 480 // we might just miss those events and get a timeout error.
michael@0 481 promises.push(waitForManagerEvent(aEnabled ? "enabled" : "disabled"));
michael@0 482 promises.push(setBluetoothEnabled(aEnabled));
michael@0 483
michael@0 484 return Promise.all(promises);
michael@0 485 }
michael@0 486
michael@0 487 /**
michael@0 488 * Get default adapter.
michael@0 489 *
michael@0 490 * Resolve if that default adapter is got, reject otherwise.
michael@0 491 *
michael@0 492 * Fulfill params: a BluetoothAdapter instance.
michael@0 493 * Reject params: a DOMError, or null if if there is no adapter ready yet.
michael@0 494 *
michael@0 495 * @return A deferred promise.
michael@0 496 */
michael@0 497 function getDefaultAdapter() {
michael@0 498 let deferred = Promise.defer();
michael@0 499
michael@0 500 let request = bluetoothManager.getDefaultAdapter();
michael@0 501 request.onsuccess = function(aEvent) {
michael@0 502 let adapter = aEvent.target.result;
michael@0 503 if (!(adapter instanceof BluetoothAdapter)) {
michael@0 504 ok(false, "no BluetoothAdapter ready yet.");
michael@0 505 deferred.reject(null);
michael@0 506 return;
michael@0 507 }
michael@0 508
michael@0 509 ok(true, "BluetoothAdapter got.");
michael@0 510 // TODO: We have an adapter instance now, but some of its attributes may
michael@0 511 // still remain unassigned/out-dated. Here we waste a few seconds to
michael@0 512 // wait for the property changed events.
michael@0 513 //
michael@0 514 // See https://bugzilla.mozilla.org/show_bug.cgi?id=932914
michael@0 515 window.setTimeout(function() {
michael@0 516 deferred.resolve(adapter);
michael@0 517 }, 3000);
michael@0 518 };
michael@0 519 request.onerror = function(aEvent) {
michael@0 520 ok(false, "Failed to get default adapter.");
michael@0 521 deferred.reject(aEvent.target.error);
michael@0 522 };
michael@0 523
michael@0 524 return deferred.promise;
michael@0 525 }
michael@0 526
michael@0 527 /**
michael@0 528 * Flush permission settings and call |finish()|.
michael@0 529 */
michael@0 530 function cleanUp() {
michael@0 531 waitFor(function() {
michael@0 532 SpecialPowers.flushPermissions(function() {
michael@0 533 // Use ok here so that we have at least one test run.
michael@0 534 ok(true, "permissions flushed");
michael@0 535
michael@0 536 finish();
michael@0 537 });
michael@0 538 }, function() {
michael@0 539 return pendingEmulatorCmdCount === 0;
michael@0 540 });
michael@0 541 }
michael@0 542
michael@0 543 function startBluetoothTestBase(aPermissions, aTestCaseMain) {
michael@0 544 ensureBluetoothManager(aPermissions)
michael@0 545 .then(aTestCaseMain)
michael@0 546 .then(cleanUp, function() {
michael@0 547 ok(false, "Unhandled rejected promise.");
michael@0 548 cleanUp();
michael@0 549 });
michael@0 550 }
michael@0 551
michael@0 552 function startBluetoothTest(aReenable, aTestCaseMain) {
michael@0 553 startBluetoothTestBase(["settings-read", "settings-write"], function() {
michael@0 554 let origEnabled, needEnable;
michael@0 555
michael@0 556 return getBluetoothEnabled()
michael@0 557 .then(function(aEnabled) {
michael@0 558 origEnabled = aEnabled;
michael@0 559 needEnable = !aEnabled;
michael@0 560 log("Original 'bluetooth.enabled' is " + origEnabled);
michael@0 561
michael@0 562 if (aEnabled && aReenable) {
michael@0 563 log(" Disable 'bluetooth.enabled' ...");
michael@0 564 needEnable = true;
michael@0 565 return setBluetoothEnabledAndWait(false);
michael@0 566 }
michael@0 567 })
michael@0 568 .then(function() {
michael@0 569 if (needEnable) {
michael@0 570 log(" Enable 'bluetooth.enabled' ...");
michael@0 571
michael@0 572 // See setBluetoothEnabledAndWait(). We must install all event
michael@0 573 // handlers *before* enabling Bluetooth.
michael@0 574 let promises = [];
michael@0 575 promises.push(waitForManagerEvent("adapteradded"));
michael@0 576 promises.push(setBluetoothEnabledAndWait(true));
michael@0 577 return Promise.all(promises);
michael@0 578 }
michael@0 579 })
michael@0 580 .then(getDefaultAdapter)
michael@0 581 .then(aTestCaseMain)
michael@0 582 .then(function() {
michael@0 583 if (!origEnabled) {
michael@0 584 return setBluetoothEnabledAndWait(false);
michael@0 585 }
michael@0 586 });
michael@0 587 });
michael@0 588 }

mercurial