dom/bluetooth/BluetoothAdapter.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
michael@0 2 /* vim: set ts=2 et sw=2 tw=80: */
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 #include "base/basictypes.h"
michael@0 8 #include "nsCxPusher.h"
michael@0 9 #include "nsDOMClassInfo.h"
michael@0 10 #include "nsTArrayHelpers.h"
michael@0 11 #include "DOMRequest.h"
michael@0 12 #include "nsThreadUtils.h"
michael@0 13
michael@0 14 #include "mozilla/dom/bluetooth/BluetoothTypes.h"
michael@0 15 #include "mozilla/dom/BluetoothAdapterBinding.h"
michael@0 16 #include "mozilla/dom/BluetoothDeviceEvent.h"
michael@0 17 #include "mozilla/dom/BluetoothStatusChangedEvent.h"
michael@0 18 #include "mozilla/dom/ContentChild.h"
michael@0 19 #include "mozilla/LazyIdleThread.h"
michael@0 20
michael@0 21 #include "BluetoothAdapter.h"
michael@0 22 #include "BluetoothDevice.h"
michael@0 23 #include "BluetoothReplyRunnable.h"
michael@0 24 #include "BluetoothService.h"
michael@0 25 #include "BluetoothUtils.h"
michael@0 26
michael@0 27 using namespace mozilla;
michael@0 28 using namespace mozilla::dom;
michael@0 29
michael@0 30 USING_BLUETOOTH_NAMESPACE
michael@0 31
michael@0 32 NS_IMPL_CYCLE_COLLECTION_CLASS(BluetoothAdapter)
michael@0 33
michael@0 34 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(BluetoothAdapter,
michael@0 35 DOMEventTargetHelper)
michael@0 36 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJsUuids)
michael@0 37 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJsDeviceAddresses)
michael@0 38 NS_IMPL_CYCLE_COLLECTION_TRACE_END
michael@0 39
michael@0 40 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothAdapter,
michael@0 41 DOMEventTargetHelper)
michael@0 42 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
michael@0 43 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
michael@0 44
michael@0 45 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BluetoothAdapter,
michael@0 46 DOMEventTargetHelper)
michael@0 47 tmp->Unroot();
michael@0 48 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
michael@0 49
michael@0 50 // QueryInterface implementation for BluetoothAdapter
michael@0 51 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothAdapter)
michael@0 52 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
michael@0 53
michael@0 54 NS_IMPL_ADDREF_INHERITED(BluetoothAdapter, DOMEventTargetHelper)
michael@0 55 NS_IMPL_RELEASE_INHERITED(BluetoothAdapter, DOMEventTargetHelper)
michael@0 56
michael@0 57 class GetDevicesTask : public BluetoothReplyRunnable
michael@0 58 {
michael@0 59 public:
michael@0 60 GetDevicesTask(BluetoothAdapter* aAdapterPtr,
michael@0 61 nsIDOMDOMRequest* aReq) :
michael@0 62 BluetoothReplyRunnable(aReq),
michael@0 63 mAdapterPtr(aAdapterPtr)
michael@0 64 {
michael@0 65 MOZ_ASSERT(aReq && aAdapterPtr);
michael@0 66 }
michael@0 67
michael@0 68 virtual bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue)
michael@0 69 {
michael@0 70 aValue.setUndefined();
michael@0 71
michael@0 72 const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value();
michael@0 73 if (v.type() != BluetoothValue::TArrayOfBluetoothNamedValue) {
michael@0 74 BT_WARNING("Not a BluetoothNamedValue array!");
michael@0 75 SetError(NS_LITERAL_STRING("BluetoothReplyTypeError"));
michael@0 76 return false;
michael@0 77 }
michael@0 78
michael@0 79 const InfallibleTArray<BluetoothNamedValue>& values =
michael@0 80 v.get_ArrayOfBluetoothNamedValue();
michael@0 81
michael@0 82 nsTArray<nsRefPtr<BluetoothDevice> > devices;
michael@0 83 for (uint32_t i = 0; i < values.Length(); i++) {
michael@0 84 const BluetoothValue properties = values[i].value();
michael@0 85 if (properties.type() != BluetoothValue::TArrayOfBluetoothNamedValue) {
michael@0 86 BT_WARNING("Not a BluetoothNamedValue array!");
michael@0 87 SetError(NS_LITERAL_STRING("BluetoothReplyTypeError"));
michael@0 88 return false;
michael@0 89 }
michael@0 90 nsRefPtr<BluetoothDevice> d =
michael@0 91 BluetoothDevice::Create(mAdapterPtr->GetOwner(),
michael@0 92 mAdapterPtr->GetPath(),
michael@0 93 properties);
michael@0 94 devices.AppendElement(d);
michael@0 95 }
michael@0 96
michael@0 97 nsresult rv;
michael@0 98 nsIScriptContext* sc = mAdapterPtr->GetContextForEventHandlers(&rv);
michael@0 99 if (!sc) {
michael@0 100 BT_WARNING("Cannot create script context!");
michael@0 101 SetError(NS_LITERAL_STRING("BluetoothScriptContextError"));
michael@0 102 return false;
michael@0 103 }
michael@0 104
michael@0 105 AutoPushJSContext cx(sc->GetNativeContext());
michael@0 106 JSObject* JsDevices = nullptr;
michael@0 107 rv = nsTArrayToJSArray(cx, devices, &JsDevices);
michael@0 108 if (!JsDevices) {
michael@0 109 BT_WARNING("Cannot create JS array!");
michael@0 110 SetError(NS_LITERAL_STRING("BluetoothError"));
michael@0 111 return false;
michael@0 112 }
michael@0 113
michael@0 114 aValue.setObject(*JsDevices);
michael@0 115 return true;
michael@0 116 }
michael@0 117
michael@0 118 void
michael@0 119 ReleaseMembers()
michael@0 120 {
michael@0 121 BluetoothReplyRunnable::ReleaseMembers();
michael@0 122 mAdapterPtr = nullptr;
michael@0 123 }
michael@0 124 private:
michael@0 125 nsRefPtr<BluetoothAdapter> mAdapterPtr;
michael@0 126 };
michael@0 127
michael@0 128 class GetScoConnectionStatusTask : public BluetoothReplyRunnable
michael@0 129 {
michael@0 130 public:
michael@0 131 GetScoConnectionStatusTask(nsIDOMDOMRequest* aReq) :
michael@0 132 BluetoothReplyRunnable(aReq)
michael@0 133 {
michael@0 134 MOZ_ASSERT(aReq);
michael@0 135 }
michael@0 136
michael@0 137 virtual bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue)
michael@0 138 {
michael@0 139 aValue.setUndefined();
michael@0 140
michael@0 141 const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value();
michael@0 142 if (v.type() != BluetoothValue::Tbool) {
michael@0 143 BT_WARNING("Not a boolean!");
michael@0 144 SetError(NS_LITERAL_STRING("BluetoothReplyTypeError"));
michael@0 145 return false;
michael@0 146 }
michael@0 147
michael@0 148 aValue.setBoolean(v.get_bool());
michael@0 149 return true;
michael@0 150 }
michael@0 151
michael@0 152 void
michael@0 153 ReleaseMembers()
michael@0 154 {
michael@0 155 BluetoothReplyRunnable::ReleaseMembers();
michael@0 156 }
michael@0 157 };
michael@0 158
michael@0 159 static int kCreatePairedDeviceTimeout = 50000; // unit: msec
michael@0 160
michael@0 161 BluetoothAdapter::BluetoothAdapter(nsPIDOMWindow* aWindow,
michael@0 162 const BluetoothValue& aValue)
michael@0 163 : DOMEventTargetHelper(aWindow)
michael@0 164 , BluetoothPropertyContainer(BluetoothObjectType::TYPE_ADAPTER)
michael@0 165 , mJsUuids(nullptr)
michael@0 166 , mJsDeviceAddresses(nullptr)
michael@0 167 , mDiscoverable(false)
michael@0 168 , mDiscovering(false)
michael@0 169 , mPairable(false)
michael@0 170 , mPowered(false)
michael@0 171 , mIsRooted(false)
michael@0 172 {
michael@0 173 MOZ_ASSERT(aWindow);
michael@0 174 MOZ_ASSERT(IsDOMBinding());
michael@0 175
michael@0 176 const InfallibleTArray<BluetoothNamedValue>& values =
michael@0 177 aValue.get_ArrayOfBluetoothNamedValue();
michael@0 178 for (uint32_t i = 0; i < values.Length(); ++i) {
michael@0 179 SetPropertyByValue(values[i]);
michael@0 180 }
michael@0 181
michael@0 182 BluetoothService* bs = BluetoothService::Get();
michael@0 183 NS_ENSURE_TRUE_VOID(bs);
michael@0 184 bs->RegisterBluetoothSignalHandler(NS_LITERAL_STRING(KEY_ADAPTER), this);
michael@0 185 }
michael@0 186
michael@0 187 BluetoothAdapter::~BluetoothAdapter()
michael@0 188 {
michael@0 189 Unroot();
michael@0 190 BluetoothService* bs = BluetoothService::Get();
michael@0 191 // We can be null on shutdown, where this might happen
michael@0 192 NS_ENSURE_TRUE_VOID(bs);
michael@0 193 bs->UnregisterBluetoothSignalHandler(NS_LITERAL_STRING(KEY_ADAPTER), this);
michael@0 194 }
michael@0 195
michael@0 196 void
michael@0 197 BluetoothAdapter::DisconnectFromOwner()
michael@0 198 {
michael@0 199 DOMEventTargetHelper::DisconnectFromOwner();
michael@0 200
michael@0 201 BluetoothService* bs = BluetoothService::Get();
michael@0 202 NS_ENSURE_TRUE_VOID(bs);
michael@0 203 bs->UnregisterBluetoothSignalHandler(NS_LITERAL_STRING(KEY_ADAPTER), this);
michael@0 204 }
michael@0 205
michael@0 206 void
michael@0 207 BluetoothAdapter::Unroot()
michael@0 208 {
michael@0 209 if (!mIsRooted) {
michael@0 210 return;
michael@0 211 }
michael@0 212 mJsUuids = nullptr;
michael@0 213 mJsDeviceAddresses = nullptr;
michael@0 214 mozilla::DropJSObjects(this);
michael@0 215 mIsRooted = false;
michael@0 216 }
michael@0 217
michael@0 218 void
michael@0 219 BluetoothAdapter::Root()
michael@0 220 {
michael@0 221 if (mIsRooted) {
michael@0 222 return;
michael@0 223 }
michael@0 224 mozilla::HoldJSObjects(this);
michael@0 225 mIsRooted = true;
michael@0 226 }
michael@0 227
michael@0 228 void
michael@0 229 BluetoothAdapter::SetPropertyByValue(const BluetoothNamedValue& aValue)
michael@0 230 {
michael@0 231 const nsString& name = aValue.name();
michael@0 232 const BluetoothValue& value = aValue.value();
michael@0 233 if (name.EqualsLiteral("Name")) {
michael@0 234 mName = value.get_nsString();
michael@0 235 } else if (name.EqualsLiteral("Address")) {
michael@0 236 mAddress = value.get_nsString();
michael@0 237 } else if (name.EqualsLiteral("Path")) {
michael@0 238 mPath = value.get_nsString();
michael@0 239 } else if (name.EqualsLiteral("Discoverable")) {
michael@0 240 mDiscoverable = value.get_bool();
michael@0 241 } else if (name.EqualsLiteral("Discovering")) {
michael@0 242 mDiscovering = value.get_bool();
michael@0 243 } else if (name.EqualsLiteral("Pairable")) {
michael@0 244 mPairable = value.get_bool();
michael@0 245 } else if (name.EqualsLiteral("Powered")) {
michael@0 246 mPowered = value.get_bool();
michael@0 247 } else if (name.EqualsLiteral("PairableTimeout")) {
michael@0 248 mPairableTimeout = value.get_uint32_t();
michael@0 249 } else if (name.EqualsLiteral("DiscoverableTimeout")) {
michael@0 250 mDiscoverableTimeout = value.get_uint32_t();
michael@0 251 } else if (name.EqualsLiteral("Class")) {
michael@0 252 mClass = value.get_uint32_t();
michael@0 253 } else if (name.EqualsLiteral("UUIDs")) {
michael@0 254 mUuids = value.get_ArrayOfnsString();
michael@0 255 nsresult rv;
michael@0 256 nsIScriptContext* sc = GetContextForEventHandlers(&rv);
michael@0 257 NS_ENSURE_SUCCESS_VOID(rv);
michael@0 258 NS_ENSURE_TRUE_VOID(sc);
michael@0 259
michael@0 260 AutoPushJSContext cx(sc->GetNativeContext());
michael@0 261 JS::Rooted<JSObject*> uuids(cx);
michael@0 262 if (NS_FAILED(nsTArrayToJSArray(cx, mUuids, uuids.address()))) {
michael@0 263 BT_WARNING("Cannot set JS UUIDs object!");
michael@0 264 return;
michael@0 265 }
michael@0 266 mJsUuids = uuids;
michael@0 267 Root();
michael@0 268 } else if (name.EqualsLiteral("Devices")) {
michael@0 269 mDeviceAddresses = value.get_ArrayOfnsString();
michael@0 270
michael@0 271 nsresult rv;
michael@0 272 nsIScriptContext* sc = GetContextForEventHandlers(&rv);
michael@0 273 NS_ENSURE_SUCCESS_VOID(rv);
michael@0 274 NS_ENSURE_TRUE_VOID(sc);
michael@0 275
michael@0 276 AutoPushJSContext cx(sc->GetNativeContext());
michael@0 277 JS::Rooted<JSObject*> deviceAddresses(cx);
michael@0 278 if (NS_FAILED(nsTArrayToJSArray(cx, mDeviceAddresses,
michael@0 279 deviceAddresses.address()))) {
michael@0 280 BT_WARNING("Cannot set JS Devices object!");
michael@0 281 return;
michael@0 282 }
michael@0 283 mJsDeviceAddresses = deviceAddresses;
michael@0 284 Root();
michael@0 285 } else {
michael@0 286 #ifdef DEBUG
michael@0 287 nsCString warningMsg;
michael@0 288 warningMsg.AssignLiteral("Not handling adapter property: ");
michael@0 289 warningMsg.Append(NS_ConvertUTF16toUTF8(name));
michael@0 290 BT_WARNING(warningMsg.get());
michael@0 291 #endif
michael@0 292 }
michael@0 293 }
michael@0 294
michael@0 295 // static
michael@0 296 already_AddRefed<BluetoothAdapter>
michael@0 297 BluetoothAdapter::Create(nsPIDOMWindow* aWindow, const BluetoothValue& aValue)
michael@0 298 {
michael@0 299 MOZ_ASSERT(NS_IsMainThread());
michael@0 300 MOZ_ASSERT(aWindow);
michael@0 301
michael@0 302 nsRefPtr<BluetoothAdapter> adapter = new BluetoothAdapter(aWindow, aValue);
michael@0 303 return adapter.forget();
michael@0 304 }
michael@0 305
michael@0 306 void
michael@0 307 BluetoothAdapter::Notify(const BluetoothSignal& aData)
michael@0 308 {
michael@0 309 InfallibleTArray<BluetoothNamedValue> arr;
michael@0 310
michael@0 311 BT_LOGD("[A] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aData.name()).get());
michael@0 312
michael@0 313 BluetoothValue v = aData.value();
michael@0 314 if (aData.name().EqualsLiteral("DeviceFound")) {
michael@0 315 nsRefPtr<BluetoothDevice> device = BluetoothDevice::Create(GetOwner(), mPath, aData.value());
michael@0 316
michael@0 317 BluetoothDeviceEventInit init;
michael@0 318 init.mBubbles = false;
michael@0 319 init.mCancelable = false;
michael@0 320 init.mDevice = device;
michael@0 321 nsRefPtr<BluetoothDeviceEvent> event =
michael@0 322 BluetoothDeviceEvent::Constructor(this, NS_LITERAL_STRING("devicefound"), init);
michael@0 323 DispatchTrustedEvent(event);
michael@0 324 } else if (aData.name().EqualsLiteral("PropertyChanged")) {
michael@0 325 MOZ_ASSERT(v.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
michael@0 326
michael@0 327 const InfallibleTArray<BluetoothNamedValue>& arr =
michael@0 328 v.get_ArrayOfBluetoothNamedValue();
michael@0 329
michael@0 330 for (uint32_t i = 0, propCount = arr.Length(); i < propCount; ++i) {
michael@0 331 SetPropertyByValue(arr[i]);
michael@0 332 }
michael@0 333 } else if (aData.name().EqualsLiteral(PAIRED_STATUS_CHANGED_ID) ||
michael@0 334 aData.name().EqualsLiteral(HFP_STATUS_CHANGED_ID) ||
michael@0 335 aData.name().EqualsLiteral(SCO_STATUS_CHANGED_ID) ||
michael@0 336 aData.name().EqualsLiteral(A2DP_STATUS_CHANGED_ID)) {
michael@0 337 MOZ_ASSERT(v.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
michael@0 338 const InfallibleTArray<BluetoothNamedValue>& arr =
michael@0 339 v.get_ArrayOfBluetoothNamedValue();
michael@0 340
michael@0 341 MOZ_ASSERT(arr.Length() == 2 &&
michael@0 342 arr[0].value().type() == BluetoothValue::TnsString &&
michael@0 343 arr[1].value().type() == BluetoothValue::Tbool);
michael@0 344 nsString address = arr[0].value().get_nsString();
michael@0 345 bool status = arr[1].value().get_bool();
michael@0 346
michael@0 347 BluetoothStatusChangedEventInit init;
michael@0 348 init.mBubbles = false;
michael@0 349 init.mCancelable = false;
michael@0 350 init.mAddress = address;
michael@0 351 init.mStatus = status;
michael@0 352 nsRefPtr<BluetoothStatusChangedEvent> event =
michael@0 353 BluetoothStatusChangedEvent::Constructor(this, aData.name(), init);
michael@0 354 DispatchTrustedEvent(event);
michael@0 355 } else if (aData.name().EqualsLiteral(REQUEST_MEDIA_PLAYSTATUS_ID)) {
michael@0 356 nsCOMPtr<nsIDOMEvent> event;
michael@0 357 nsresult rv = NS_NewDOMEvent(getter_AddRefs(event), this, nullptr, nullptr);
michael@0 358 NS_ENSURE_SUCCESS_VOID(rv);
michael@0 359
michael@0 360 rv = event->InitEvent(aData.name(), false, false);
michael@0 361 NS_ENSURE_SUCCESS_VOID(rv);
michael@0 362
michael@0 363 DispatchTrustedEvent(event);
michael@0 364 } else {
michael@0 365 #ifdef DEBUG
michael@0 366 nsCString warningMsg;
michael@0 367 warningMsg.AssignLiteral("Not handling adapter signal: ");
michael@0 368 warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name()));
michael@0 369 BT_WARNING(warningMsg.get());
michael@0 370 #endif
michael@0 371 }
michael@0 372 }
michael@0 373
michael@0 374 already_AddRefed<DOMRequest>
michael@0 375 BluetoothAdapter::StartStopDiscovery(bool aStart, ErrorResult& aRv)
michael@0 376 {
michael@0 377 nsCOMPtr<nsPIDOMWindow> win = GetOwner();
michael@0 378 if (!win) {
michael@0 379 aRv.Throw(NS_ERROR_FAILURE);
michael@0 380 return nullptr;
michael@0 381 }
michael@0 382
michael@0 383 nsRefPtr<DOMRequest> request = new DOMRequest(win);
michael@0 384 nsRefPtr<BluetoothVoidReplyRunnable> results =
michael@0 385 new BluetoothVoidReplyRunnable(request);
michael@0 386
michael@0 387 BluetoothService* bs = BluetoothService::Get();
michael@0 388 if (!bs) {
michael@0 389 aRv.Throw(NS_ERROR_FAILURE);
michael@0 390 return nullptr;
michael@0 391 }
michael@0 392 nsresult rv;
michael@0 393 if (aStart) {
michael@0 394 rv = bs->StartDiscoveryInternal(results);
michael@0 395 } else {
michael@0 396 rv = bs->StopDiscoveryInternal(results);
michael@0 397 }
michael@0 398 if (NS_FAILED(rv)) {
michael@0 399 BT_WARNING("Start/Stop Discovery failed!");
michael@0 400 aRv.Throw(rv);
michael@0 401 return nullptr;
michael@0 402 }
michael@0 403
michael@0 404 // mDiscovering is not set here, we'll get a Property update from our external
michael@0 405 // protocol to tell us that it's been set.
michael@0 406
michael@0 407 return request.forget();
michael@0 408 }
michael@0 409
michael@0 410 already_AddRefed<DOMRequest>
michael@0 411 BluetoothAdapter::StartDiscovery(ErrorResult& aRv)
michael@0 412 {
michael@0 413 return StartStopDiscovery(true, aRv);
michael@0 414 }
michael@0 415
michael@0 416 already_AddRefed<DOMRequest>
michael@0 417 BluetoothAdapter::StopDiscovery(ErrorResult& aRv)
michael@0 418 {
michael@0 419 return StartStopDiscovery(false, aRv);
michael@0 420 }
michael@0 421
michael@0 422 void
michael@0 423 BluetoothAdapter::GetDevices(JSContext* aContext,
michael@0 424 JS::MutableHandle<JS::Value> aDevices,
michael@0 425 ErrorResult& aRv)
michael@0 426 {
michael@0 427 if (!mJsDeviceAddresses) {
michael@0 428 BT_WARNING("Devices not yet set!\n");
michael@0 429 aRv.Throw(NS_ERROR_FAILURE);
michael@0 430 return;
michael@0 431 }
michael@0 432
michael@0 433 JS::ExposeObjectToActiveJS(mJsDeviceAddresses);
michael@0 434 aDevices.setObject(*mJsDeviceAddresses);
michael@0 435 }
michael@0 436
michael@0 437 void
michael@0 438 BluetoothAdapter::GetUuids(JSContext* aContext,
michael@0 439 JS::MutableHandle<JS::Value> aUuids,
michael@0 440 ErrorResult& aRv)
michael@0 441 {
michael@0 442 if (!mJsUuids) {
michael@0 443 BT_WARNING("UUIDs not yet set!\n");
michael@0 444 aRv.Throw(NS_ERROR_FAILURE);
michael@0 445 return;
michael@0 446 }
michael@0 447
michael@0 448 JS::ExposeObjectToActiveJS(mJsUuids);
michael@0 449 aUuids.setObject(*mJsUuids);
michael@0 450 }
michael@0 451
michael@0 452 already_AddRefed<DOMRequest>
michael@0 453 BluetoothAdapter::SetName(const nsAString& aName, ErrorResult& aRv)
michael@0 454 {
michael@0 455 if (mName.Equals(aName)) {
michael@0 456 return FirePropertyAlreadySet(GetOwner(), aRv);
michael@0 457 }
michael@0 458 nsString name(aName);
michael@0 459 BluetoothValue value(name);
michael@0 460 BluetoothNamedValue property(NS_LITERAL_STRING("Name"), value);
michael@0 461 return SetProperty(GetOwner(), property, aRv);
michael@0 462 }
michael@0 463
michael@0 464 already_AddRefed<DOMRequest>
michael@0 465 BluetoothAdapter::SetDiscoverable(bool aDiscoverable, ErrorResult& aRv)
michael@0 466 {
michael@0 467 if (aDiscoverable == mDiscoverable) {
michael@0 468 return FirePropertyAlreadySet(GetOwner(), aRv);
michael@0 469 }
michael@0 470 BluetoothValue value(aDiscoverable);
michael@0 471 BluetoothNamedValue property(NS_LITERAL_STRING("Discoverable"), value);
michael@0 472 return SetProperty(GetOwner(), property, aRv);
michael@0 473 }
michael@0 474
michael@0 475 already_AddRefed<DOMRequest>
michael@0 476 BluetoothAdapter::SetDiscoverableTimeout(uint32_t aDiscoverableTimeout, ErrorResult& aRv)
michael@0 477 {
michael@0 478 if (aDiscoverableTimeout == mDiscoverableTimeout) {
michael@0 479 return FirePropertyAlreadySet(GetOwner(), aRv);
michael@0 480 }
michael@0 481 BluetoothValue value(aDiscoverableTimeout);
michael@0 482 BluetoothNamedValue property(NS_LITERAL_STRING("DiscoverableTimeout"), value);
michael@0 483 return SetProperty(GetOwner(), property, aRv);
michael@0 484 }
michael@0 485
michael@0 486 already_AddRefed<DOMRequest>
michael@0 487 BluetoothAdapter::GetConnectedDevices(uint16_t aServiceUuid, ErrorResult& aRv)
michael@0 488 {
michael@0 489 MOZ_ASSERT(NS_IsMainThread());
michael@0 490
michael@0 491 nsCOMPtr<nsPIDOMWindow> win = GetOwner();
michael@0 492 if (!win) {
michael@0 493 aRv.Throw(NS_ERROR_FAILURE);
michael@0 494 return nullptr;
michael@0 495 }
michael@0 496
michael@0 497 nsRefPtr<DOMRequest> request = new DOMRequest(win);
michael@0 498 nsRefPtr<BluetoothReplyRunnable> results =
michael@0 499 new GetDevicesTask(this, request);
michael@0 500
michael@0 501 BluetoothService* bs = BluetoothService::Get();
michael@0 502 if (!bs) {
michael@0 503 aRv.Throw(NS_ERROR_FAILURE);
michael@0 504 return nullptr;
michael@0 505 }
michael@0 506 nsresult rv = bs->GetConnectedDevicePropertiesInternal(aServiceUuid, results);
michael@0 507 if (NS_FAILED(rv)) {
michael@0 508 aRv.Throw(rv);
michael@0 509 return nullptr;
michael@0 510 }
michael@0 511
michael@0 512 return request.forget();
michael@0 513 }
michael@0 514
michael@0 515 already_AddRefed<DOMRequest>
michael@0 516 BluetoothAdapter::GetPairedDevices(ErrorResult& aRv)
michael@0 517 {
michael@0 518 nsCOMPtr<nsPIDOMWindow> win = GetOwner();
michael@0 519 if (!win) {
michael@0 520 aRv.Throw(NS_ERROR_FAILURE);
michael@0 521 return nullptr;
michael@0 522 }
michael@0 523
michael@0 524 nsRefPtr<DOMRequest> request = new DOMRequest(win);
michael@0 525 nsRefPtr<BluetoothReplyRunnable> results =
michael@0 526 new GetDevicesTask(this, request);
michael@0 527
michael@0 528 BluetoothService* bs = BluetoothService::Get();
michael@0 529 if (!bs) {
michael@0 530 aRv.Throw(NS_ERROR_FAILURE);
michael@0 531 return nullptr;
michael@0 532 }
michael@0 533 nsresult rv = bs->GetPairedDevicePropertiesInternal(mDeviceAddresses, results);
michael@0 534 if (NS_FAILED(rv)) {
michael@0 535 aRv.Throw(rv);
michael@0 536 return nullptr;
michael@0 537 }
michael@0 538
michael@0 539 return request.forget();
michael@0 540 }
michael@0 541
michael@0 542 already_AddRefed<DOMRequest>
michael@0 543 BluetoothAdapter::PairUnpair(bool aPair, const nsAString& aDeviceAddress,
michael@0 544 ErrorResult& aRv)
michael@0 545 {
michael@0 546 nsCOMPtr<nsPIDOMWindow> win = GetOwner();
michael@0 547 if (!win) {
michael@0 548 aRv.Throw(NS_ERROR_FAILURE);
michael@0 549 return nullptr;
michael@0 550 }
michael@0 551
michael@0 552 nsRefPtr<DOMRequest> request = new DOMRequest(win);
michael@0 553 nsRefPtr<BluetoothVoidReplyRunnable> results =
michael@0 554 new BluetoothVoidReplyRunnable(request);
michael@0 555
michael@0 556 BluetoothService* bs = BluetoothService::Get();
michael@0 557 if (!bs) {
michael@0 558 aRv.Throw(NS_ERROR_FAILURE);
michael@0 559 return nullptr;
michael@0 560 }
michael@0 561 nsresult rv;
michael@0 562 if (aPair) {
michael@0 563 rv = bs->CreatePairedDeviceInternal(aDeviceAddress,
michael@0 564 kCreatePairedDeviceTimeout,
michael@0 565 results);
michael@0 566 } else {
michael@0 567 rv = bs->RemoveDeviceInternal(aDeviceAddress, results);
michael@0 568 }
michael@0 569 if (NS_FAILED(rv)) {
michael@0 570 BT_WARNING("Pair/Unpair failed!");
michael@0 571 aRv.Throw(rv);
michael@0 572 return nullptr;
michael@0 573 }
michael@0 574
michael@0 575 return request.forget();
michael@0 576 }
michael@0 577
michael@0 578 already_AddRefed<DOMRequest>
michael@0 579 BluetoothAdapter::Pair(const nsAString& aDeviceAddress, ErrorResult& aRv)
michael@0 580 {
michael@0 581 return PairUnpair(true, aDeviceAddress, aRv);
michael@0 582 }
michael@0 583
michael@0 584 already_AddRefed<DOMRequest>
michael@0 585 BluetoothAdapter::Unpair(const nsAString& aDeviceAddress, ErrorResult& aRv)
michael@0 586 {
michael@0 587 return PairUnpair(false, aDeviceAddress, aRv);
michael@0 588 }
michael@0 589
michael@0 590 already_AddRefed<DOMRequest>
michael@0 591 BluetoothAdapter::SetPinCode(const nsAString& aDeviceAddress,
michael@0 592 const nsAString& aPinCode, ErrorResult& aRv)
michael@0 593 {
michael@0 594 nsCOMPtr<nsPIDOMWindow> win = GetOwner();
michael@0 595 if (!win) {
michael@0 596 aRv.Throw(NS_ERROR_FAILURE);
michael@0 597 return nullptr;
michael@0 598 }
michael@0 599
michael@0 600 nsRefPtr<DOMRequest> request = new DOMRequest(win);
michael@0 601 nsRefPtr<BluetoothVoidReplyRunnable> results =
michael@0 602 new BluetoothVoidReplyRunnable(request);
michael@0 603
michael@0 604 BluetoothService* bs = BluetoothService::Get();
michael@0 605 if (!bs) {
michael@0 606 aRv.Throw(NS_ERROR_FAILURE);
michael@0 607 return nullptr;
michael@0 608 }
michael@0 609 if (!bs->SetPinCodeInternal(aDeviceAddress, aPinCode, results)) {
michael@0 610 BT_WARNING("SetPinCode failed!");
michael@0 611 aRv.Throw(NS_ERROR_FAILURE);
michael@0 612 return nullptr;
michael@0 613 }
michael@0 614
michael@0 615 return request.forget();
michael@0 616 }
michael@0 617
michael@0 618 already_AddRefed<DOMRequest>
michael@0 619 BluetoothAdapter::SetPasskey(const nsAString& aDeviceAddress, uint32_t aPasskey,
michael@0 620 ErrorResult& aRv)
michael@0 621 {
michael@0 622 nsCOMPtr<nsPIDOMWindow> win = GetOwner();
michael@0 623 if (!win) {
michael@0 624 aRv.Throw(NS_ERROR_FAILURE);
michael@0 625 return nullptr;
michael@0 626 }
michael@0 627
michael@0 628 nsRefPtr<DOMRequest> request = new DOMRequest(win);
michael@0 629 nsRefPtr<BluetoothVoidReplyRunnable> results =
michael@0 630 new BluetoothVoidReplyRunnable(request);
michael@0 631
michael@0 632 BluetoothService* bs = BluetoothService::Get();
michael@0 633 if (!bs) {
michael@0 634 aRv.Throw(NS_ERROR_FAILURE);
michael@0 635 return nullptr;
michael@0 636 }
michael@0 637 if (bs->SetPasskeyInternal(aDeviceAddress, aPasskey, results)) {
michael@0 638 BT_WARNING("SetPasskeyInternal failed!");
michael@0 639 aRv.Throw(NS_ERROR_FAILURE);
michael@0 640 return nullptr;
michael@0 641 }
michael@0 642
michael@0 643 return request.forget();
michael@0 644 }
michael@0 645
michael@0 646 already_AddRefed<DOMRequest>
michael@0 647 BluetoothAdapter::SetPairingConfirmation(const nsAString& aDeviceAddress,
michael@0 648 bool aConfirmation, ErrorResult& aRv)
michael@0 649 {
michael@0 650 nsCOMPtr<nsPIDOMWindow> win = GetOwner();
michael@0 651 if (!win) {
michael@0 652 aRv.Throw(NS_ERROR_FAILURE);
michael@0 653 return nullptr;
michael@0 654 }
michael@0 655
michael@0 656 nsRefPtr<DOMRequest> request = new DOMRequest(win);
michael@0 657 nsRefPtr<BluetoothVoidReplyRunnable> results =
michael@0 658 new BluetoothVoidReplyRunnable(request);
michael@0 659
michael@0 660 BluetoothService* bs = BluetoothService::Get();
michael@0 661 if (!bs) {
michael@0 662 aRv.Throw(NS_ERROR_FAILURE);
michael@0 663 return nullptr;
michael@0 664 }
michael@0 665 if (!bs->SetPairingConfirmationInternal(aDeviceAddress,
michael@0 666 aConfirmation,
michael@0 667 results)) {
michael@0 668 BT_WARNING("SetPairingConfirmation failed!");
michael@0 669 aRv.Throw(NS_ERROR_FAILURE);
michael@0 670 return nullptr;
michael@0 671 }
michael@0 672
michael@0 673 return request.forget();
michael@0 674 }
michael@0 675
michael@0 676 already_AddRefed<DOMRequest>
michael@0 677 BluetoothAdapter::Connect(BluetoothDevice& aDevice,
michael@0 678 const Optional<short unsigned int>& aServiceUuid,
michael@0 679 ErrorResult& aRv)
michael@0 680 {
michael@0 681 nsCOMPtr<nsPIDOMWindow> win = GetOwner();
michael@0 682 if (!win) {
michael@0 683 aRv.Throw(NS_ERROR_FAILURE);
michael@0 684 return nullptr;
michael@0 685 }
michael@0 686
michael@0 687 nsRefPtr<DOMRequest> request = new DOMRequest(win);
michael@0 688 nsRefPtr<BluetoothVoidReplyRunnable> results =
michael@0 689 new BluetoothVoidReplyRunnable(request);
michael@0 690
michael@0 691 nsAutoString address;
michael@0 692 aDevice.GetAddress(address);
michael@0 693 uint32_t deviceClass = aDevice.Class();
michael@0 694 uint16_t serviceUuid = 0;
michael@0 695 if (aServiceUuid.WasPassed()) {
michael@0 696 serviceUuid = aServiceUuid.Value();
michael@0 697 }
michael@0 698
michael@0 699 BluetoothService* bs = BluetoothService::Get();
michael@0 700 if (!bs) {
michael@0 701 aRv.Throw(NS_ERROR_FAILURE);
michael@0 702 return nullptr;
michael@0 703 }
michael@0 704 bs->Connect(address, deviceClass, serviceUuid, results);
michael@0 705
michael@0 706 return request.forget();
michael@0 707 }
michael@0 708
michael@0 709 already_AddRefed<DOMRequest>
michael@0 710 BluetoothAdapter::Disconnect(BluetoothDevice& aDevice,
michael@0 711 const Optional<short unsigned int>& aServiceUuid,
michael@0 712 ErrorResult& aRv)
michael@0 713 {
michael@0 714 nsCOMPtr<nsPIDOMWindow> win = GetOwner();
michael@0 715 if (!win) {
michael@0 716 aRv.Throw(NS_ERROR_FAILURE);
michael@0 717 return nullptr;
michael@0 718 }
michael@0 719
michael@0 720 nsRefPtr<DOMRequest> request = new DOMRequest(win);
michael@0 721 nsRefPtr<BluetoothVoidReplyRunnable> results =
michael@0 722 new BluetoothVoidReplyRunnable(request);
michael@0 723
michael@0 724 nsAutoString address;
michael@0 725 aDevice.GetAddress(address);
michael@0 726 uint16_t serviceUuid = 0;
michael@0 727 if (aServiceUuid.WasPassed()) {
michael@0 728 serviceUuid = aServiceUuid.Value();
michael@0 729 }
michael@0 730
michael@0 731 BluetoothService* bs = BluetoothService::Get();
michael@0 732 if (!bs) {
michael@0 733 aRv.Throw(NS_ERROR_FAILURE);
michael@0 734 return nullptr;
michael@0 735 }
michael@0 736 bs->Disconnect(address, serviceUuid, results);
michael@0 737
michael@0 738 return request.forget();
michael@0 739 }
michael@0 740
michael@0 741 already_AddRefed<DOMRequest>
michael@0 742 BluetoothAdapter::SendFile(const nsAString& aDeviceAddress,
michael@0 743 nsIDOMBlob* aBlob, ErrorResult& aRv)
michael@0 744 {
michael@0 745 nsCOMPtr<nsPIDOMWindow> win = GetOwner();
michael@0 746 if (!win) {
michael@0 747 aRv.Throw(NS_ERROR_FAILURE);
michael@0 748 return nullptr;
michael@0 749 }
michael@0 750
michael@0 751 nsRefPtr<DOMRequest> request = new DOMRequest(win);
michael@0 752 nsRefPtr<BluetoothVoidReplyRunnable> results =
michael@0 753 new BluetoothVoidReplyRunnable(request);
michael@0 754
michael@0 755 BluetoothService* bs = BluetoothService::Get();
michael@0 756 if (!bs) {
michael@0 757 aRv.Throw(NS_ERROR_FAILURE);
michael@0 758 return nullptr;
michael@0 759 }
michael@0 760
michael@0 761 if (XRE_GetProcessType() == GeckoProcessType_Default) {
michael@0 762 // In-process transfer
michael@0 763 bs->SendFile(aDeviceAddress, aBlob, results);
michael@0 764 } else {
michael@0 765 ContentChild *cc = ContentChild::GetSingleton();
michael@0 766 if (!cc) {
michael@0 767 aRv.Throw(NS_ERROR_FAILURE);
michael@0 768 return nullptr;
michael@0 769 }
michael@0 770
michael@0 771 BlobChild* actor = cc->GetOrCreateActorForBlob(aBlob);
michael@0 772 if (!actor) {
michael@0 773 aRv.Throw(NS_ERROR_FAILURE);
michael@0 774 return nullptr;
michael@0 775 }
michael@0 776
michael@0 777 bs->SendFile(aDeviceAddress, nullptr, actor, results);
michael@0 778 }
michael@0 779
michael@0 780 return request.forget();
michael@0 781 }
michael@0 782
michael@0 783 already_AddRefed<DOMRequest>
michael@0 784 BluetoothAdapter::StopSendingFile(const nsAString& aDeviceAddress, ErrorResult& aRv)
michael@0 785 {
michael@0 786 nsCOMPtr<nsPIDOMWindow> win = GetOwner();
michael@0 787 if (!win) {
michael@0 788 aRv.Throw(NS_ERROR_FAILURE);
michael@0 789 return nullptr;
michael@0 790 }
michael@0 791
michael@0 792 nsRefPtr<DOMRequest> request = new DOMRequest(win);
michael@0 793 nsRefPtr<BluetoothVoidReplyRunnable> results =
michael@0 794 new BluetoothVoidReplyRunnable(request);
michael@0 795
michael@0 796 BluetoothService* bs = BluetoothService::Get();
michael@0 797 if (!bs) {
michael@0 798 aRv.Throw(NS_ERROR_FAILURE);
michael@0 799 return nullptr;
michael@0 800 }
michael@0 801 bs->StopSendingFile(aDeviceAddress, results);
michael@0 802
michael@0 803 return request.forget();
michael@0 804 }
michael@0 805
michael@0 806 already_AddRefed<DOMRequest>
michael@0 807 BluetoothAdapter::ConfirmReceivingFile(const nsAString& aDeviceAddress,
michael@0 808 bool aConfirmation, ErrorResult& aRv)
michael@0 809 {
michael@0 810 nsCOMPtr<nsPIDOMWindow> win = GetOwner();
michael@0 811 if (!win) {
michael@0 812 aRv.Throw(NS_ERROR_FAILURE);
michael@0 813 return nullptr;
michael@0 814 }
michael@0 815
michael@0 816 nsRefPtr<DOMRequest> request = new DOMRequest(win);
michael@0 817 nsRefPtr<BluetoothVoidReplyRunnable> results =
michael@0 818 new BluetoothVoidReplyRunnable(request);
michael@0 819
michael@0 820 BluetoothService* bs = BluetoothService::Get();
michael@0 821 if (!bs) {
michael@0 822 aRv.Throw(NS_ERROR_FAILURE);
michael@0 823 return nullptr;
michael@0 824 }
michael@0 825 bs->ConfirmReceivingFile(aDeviceAddress, aConfirmation, results);
michael@0 826
michael@0 827 return request.forget();
michael@0 828 }
michael@0 829
michael@0 830 already_AddRefed<DOMRequest>
michael@0 831 BluetoothAdapter::ConnectSco(ErrorResult& aRv)
michael@0 832 {
michael@0 833 nsCOMPtr<nsPIDOMWindow> win = GetOwner();
michael@0 834 if (!win) {
michael@0 835 aRv.Throw(NS_ERROR_FAILURE);
michael@0 836 return nullptr;
michael@0 837 }
michael@0 838
michael@0 839 nsRefPtr<DOMRequest> request = new DOMRequest(win);
michael@0 840 nsRefPtr<BluetoothVoidReplyRunnable> results =
michael@0 841 new BluetoothVoidReplyRunnable(request);
michael@0 842
michael@0 843 BluetoothService* bs = BluetoothService::Get();
michael@0 844 if (!bs) {
michael@0 845 aRv.Throw(NS_ERROR_FAILURE);
michael@0 846 return nullptr;
michael@0 847 }
michael@0 848 bs->ConnectSco(results);
michael@0 849
michael@0 850 return request.forget();
michael@0 851 }
michael@0 852
michael@0 853 already_AddRefed<DOMRequest>
michael@0 854 BluetoothAdapter::DisconnectSco(ErrorResult& aRv)
michael@0 855 {
michael@0 856 nsCOMPtr<nsPIDOMWindow> win = GetOwner();
michael@0 857 if (!win) {
michael@0 858 aRv.Throw(NS_ERROR_FAILURE);
michael@0 859 return nullptr;
michael@0 860 }
michael@0 861
michael@0 862 nsRefPtr<DOMRequest> request = new DOMRequest(win);
michael@0 863 nsRefPtr<BluetoothVoidReplyRunnable> results =
michael@0 864 new BluetoothVoidReplyRunnable(request);
michael@0 865
michael@0 866 BluetoothService* bs = BluetoothService::Get();
michael@0 867 if (!bs) {
michael@0 868 aRv.Throw(NS_ERROR_FAILURE);
michael@0 869 return nullptr;
michael@0 870 }
michael@0 871 bs->DisconnectSco(results);
michael@0 872
michael@0 873 return request.forget();
michael@0 874 }
michael@0 875
michael@0 876 already_AddRefed<DOMRequest>
michael@0 877 BluetoothAdapter::IsScoConnected(ErrorResult& aRv)
michael@0 878 {
michael@0 879 nsCOMPtr<nsPIDOMWindow> win = GetOwner();
michael@0 880 if (!win) {
michael@0 881 aRv.Throw(NS_ERROR_FAILURE);
michael@0 882 return nullptr;
michael@0 883 }
michael@0 884
michael@0 885 nsRefPtr<DOMRequest> request = new DOMRequest(win);
michael@0 886 nsRefPtr<BluetoothReplyRunnable> results =
michael@0 887 new GetScoConnectionStatusTask(request);
michael@0 888
michael@0 889 BluetoothService* bs = BluetoothService::Get();
michael@0 890 if (!bs) {
michael@0 891 aRv.Throw(NS_ERROR_FAILURE);
michael@0 892 return nullptr;
michael@0 893 }
michael@0 894 bs->IsScoConnected(results);
michael@0 895
michael@0 896 return request.forget();
michael@0 897 }
michael@0 898
michael@0 899 already_AddRefed<DOMRequest>
michael@0 900 BluetoothAdapter::AnswerWaitingCall(ErrorResult& aRv)
michael@0 901 {
michael@0 902 #ifdef MOZ_B2G_RIL
michael@0 903 nsCOMPtr<nsPIDOMWindow> win = GetOwner();
michael@0 904 if (!win) {
michael@0 905 aRv.Throw(NS_ERROR_FAILURE);
michael@0 906 return nullptr;
michael@0 907 }
michael@0 908
michael@0 909 nsRefPtr<DOMRequest> request = new DOMRequest(win);
michael@0 910 nsRefPtr<BluetoothVoidReplyRunnable> results =
michael@0 911 new BluetoothVoidReplyRunnable(request);
michael@0 912
michael@0 913 BluetoothService* bs = BluetoothService::Get();
michael@0 914 if (!bs) {
michael@0 915 aRv.Throw(NS_ERROR_FAILURE);
michael@0 916 return nullptr;
michael@0 917 }
michael@0 918 bs->AnswerWaitingCall(results);
michael@0 919
michael@0 920 return request.forget();
michael@0 921 #else
michael@0 922 aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
michael@0 923 return nullptr;
michael@0 924 #endif // MOZ_B2G_RIL
michael@0 925 }
michael@0 926
michael@0 927 already_AddRefed<DOMRequest>
michael@0 928 BluetoothAdapter::IgnoreWaitingCall(ErrorResult& aRv)
michael@0 929 {
michael@0 930 #ifdef MOZ_B2G_RIL
michael@0 931 nsCOMPtr<nsPIDOMWindow> win = GetOwner();
michael@0 932 if (!win) {
michael@0 933 aRv.Throw(NS_ERROR_FAILURE);
michael@0 934 return nullptr;
michael@0 935 }
michael@0 936
michael@0 937 nsRefPtr<DOMRequest> request = new DOMRequest(win);
michael@0 938 nsRefPtr<BluetoothVoidReplyRunnable> results =
michael@0 939 new BluetoothVoidReplyRunnable(request);
michael@0 940
michael@0 941 BluetoothService* bs = BluetoothService::Get();
michael@0 942 if (!bs) {
michael@0 943 aRv.Throw(NS_ERROR_FAILURE);
michael@0 944 return nullptr;
michael@0 945 }
michael@0 946 bs->IgnoreWaitingCall(results);
michael@0 947
michael@0 948 return request.forget();
michael@0 949 #else
michael@0 950 aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
michael@0 951 return nullptr;
michael@0 952 #endif // MOZ_B2G_RIL
michael@0 953 }
michael@0 954
michael@0 955 already_AddRefed<DOMRequest>
michael@0 956 BluetoothAdapter::ToggleCalls(ErrorResult& aRv)
michael@0 957 {
michael@0 958 #ifdef MOZ_B2G_RIL
michael@0 959 nsCOMPtr<nsPIDOMWindow> win = GetOwner();
michael@0 960 if (!win) {
michael@0 961 aRv.Throw(NS_ERROR_FAILURE);
michael@0 962 return nullptr;
michael@0 963 }
michael@0 964
michael@0 965 nsRefPtr<DOMRequest> request = new DOMRequest(win);
michael@0 966 nsRefPtr<BluetoothVoidReplyRunnable> results =
michael@0 967 new BluetoothVoidReplyRunnable(request);
michael@0 968
michael@0 969 BluetoothService* bs = BluetoothService::Get();
michael@0 970 if (!bs) {
michael@0 971 aRv.Throw(NS_ERROR_FAILURE);
michael@0 972 return nullptr;
michael@0 973 }
michael@0 974 bs->ToggleCalls(results);
michael@0 975
michael@0 976 return request.forget();
michael@0 977 #else
michael@0 978 aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
michael@0 979 return nullptr;
michael@0 980 #endif // MOZ_B2G_RIL
michael@0 981 }
michael@0 982
michael@0 983 already_AddRefed<DOMRequest>
michael@0 984 BluetoothAdapter::SendMediaMetaData(const MediaMetaData& aMediaMetaData, ErrorResult& aRv)
michael@0 985 {
michael@0 986 nsCOMPtr<nsPIDOMWindow> win = GetOwner();
michael@0 987 if (!win) {
michael@0 988 aRv.Throw(NS_ERROR_FAILURE);
michael@0 989 return nullptr;
michael@0 990 }
michael@0 991
michael@0 992 nsRefPtr<DOMRequest> request = new DOMRequest(win);
michael@0 993 nsRefPtr<BluetoothReplyRunnable> results =
michael@0 994 new BluetoothVoidReplyRunnable(request);
michael@0 995
michael@0 996 BluetoothService* bs = BluetoothService::Get();
michael@0 997 if (!bs) {
michael@0 998 aRv.Throw(NS_ERROR_FAILURE);
michael@0 999 return nullptr;
michael@0 1000 }
michael@0 1001 bs->SendMetaData(aMediaMetaData.mTitle,
michael@0 1002 aMediaMetaData.mArtist,
michael@0 1003 aMediaMetaData.mAlbum,
michael@0 1004 aMediaMetaData.mMediaNumber,
michael@0 1005 aMediaMetaData.mTotalMediaCount,
michael@0 1006 aMediaMetaData.mDuration,
michael@0 1007 results);
michael@0 1008
michael@0 1009 return request.forget();
michael@0 1010 }
michael@0 1011
michael@0 1012 already_AddRefed<DOMRequest>
michael@0 1013 BluetoothAdapter::SendMediaPlayStatus(const MediaPlayStatus& aMediaPlayStatus, ErrorResult& aRv)
michael@0 1014 {
michael@0 1015 nsCOMPtr<nsPIDOMWindow> win = GetOwner();
michael@0 1016 if (!win) {
michael@0 1017 aRv.Throw(NS_ERROR_FAILURE);
michael@0 1018 return nullptr;
michael@0 1019 }
michael@0 1020
michael@0 1021 nsRefPtr<DOMRequest> request = new DOMRequest(win);
michael@0 1022 nsRefPtr<BluetoothReplyRunnable> results =
michael@0 1023 new BluetoothVoidReplyRunnable(request);
michael@0 1024
michael@0 1025 BluetoothService* bs = BluetoothService::Get();
michael@0 1026 if (!bs) {
michael@0 1027 aRv.Throw(NS_ERROR_FAILURE);
michael@0 1028 return nullptr;
michael@0 1029 }
michael@0 1030 bs->SendPlayStatus(aMediaPlayStatus.mDuration,
michael@0 1031 aMediaPlayStatus.mPosition,
michael@0 1032 aMediaPlayStatus.mPlayStatus,
michael@0 1033 results);
michael@0 1034
michael@0 1035 return request.forget();
michael@0 1036 }
michael@0 1037
michael@0 1038 JSObject*
michael@0 1039 BluetoothAdapter::WrapObject(JSContext* aCx)
michael@0 1040 {
michael@0 1041 return BluetoothAdapterBinding::Wrap(aCx, this);
michael@0 1042 }

mercurial