dom/bluetooth/BluetoothDevice.cpp

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++; 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 "BluetoothDevice.h"
michael@0 9 #include "BluetoothReplyRunnable.h"
michael@0 10 #include "BluetoothService.h"
michael@0 11 #include "BluetoothUtils.h"
michael@0 12
michael@0 13 #include "nsDOMClassInfo.h"
michael@0 14 #include "nsTArrayHelpers.h"
michael@0 15
michael@0 16 #include "mozilla/dom/bluetooth/BluetoothTypes.h"
michael@0 17 #include "mozilla/dom/BluetoothDeviceBinding.h"
michael@0 18
michael@0 19 USING_BLUETOOTH_NAMESPACE
michael@0 20
michael@0 21 DOMCI_DATA(BluetoothDevice, BluetoothDevice)
michael@0 22
michael@0 23 NS_IMPL_CYCLE_COLLECTION_CLASS(BluetoothDevice)
michael@0 24
michael@0 25 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(BluetoothDevice,
michael@0 26 DOMEventTargetHelper)
michael@0 27 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJsUuids)
michael@0 28 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJsServices)
michael@0 29 NS_IMPL_CYCLE_COLLECTION_TRACE_END
michael@0 30
michael@0 31 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothDevice,
michael@0 32 DOMEventTargetHelper)
michael@0 33 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
michael@0 34 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
michael@0 35
michael@0 36 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BluetoothDevice,
michael@0 37 DOMEventTargetHelper)
michael@0 38 tmp->Unroot();
michael@0 39 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
michael@0 40
michael@0 41 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothDevice)
michael@0 42 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
michael@0 43
michael@0 44 NS_IMPL_ADDREF_INHERITED(BluetoothDevice, DOMEventTargetHelper)
michael@0 45 NS_IMPL_RELEASE_INHERITED(BluetoothDevice, DOMEventTargetHelper)
michael@0 46
michael@0 47 BluetoothDevice::BluetoothDevice(nsPIDOMWindow* aWindow,
michael@0 48 const nsAString& aAdapterPath,
michael@0 49 const BluetoothValue& aValue)
michael@0 50 : DOMEventTargetHelper(aWindow)
michael@0 51 , BluetoothPropertyContainer(BluetoothObjectType::TYPE_DEVICE)
michael@0 52 , mJsUuids(nullptr)
michael@0 53 , mJsServices(nullptr)
michael@0 54 , mAdapterPath(aAdapterPath)
michael@0 55 , mIsRooted(false)
michael@0 56 {
michael@0 57 MOZ_ASSERT(aWindow);
michael@0 58 MOZ_ASSERT(IsDOMBinding());
michael@0 59
michael@0 60 const InfallibleTArray<BluetoothNamedValue>& values =
michael@0 61 aValue.get_ArrayOfBluetoothNamedValue();
michael@0 62 for (uint32_t i = 0; i < values.Length(); ++i) {
michael@0 63 SetPropertyByValue(values[i]);
michael@0 64 }
michael@0 65
michael@0 66 BluetoothService* bs = BluetoothService::Get();
michael@0 67 NS_ENSURE_TRUE_VOID(bs);
michael@0 68 bs->RegisterBluetoothSignalHandler(mAddress, this);
michael@0 69 }
michael@0 70
michael@0 71 BluetoothDevice::~BluetoothDevice()
michael@0 72 {
michael@0 73 BluetoothService* bs = BluetoothService::Get();
michael@0 74 // bs can be null on shutdown, where destruction might happen.
michael@0 75 NS_ENSURE_TRUE_VOID(bs);
michael@0 76 bs->UnregisterBluetoothSignalHandler(mAddress, this);
michael@0 77 Unroot();
michael@0 78 }
michael@0 79
michael@0 80 void
michael@0 81 BluetoothDevice::DisconnectFromOwner()
michael@0 82 {
michael@0 83 DOMEventTargetHelper::DisconnectFromOwner();
michael@0 84
michael@0 85 BluetoothService* bs = BluetoothService::Get();
michael@0 86 NS_ENSURE_TRUE_VOID(bs);
michael@0 87 bs->UnregisterBluetoothSignalHandler(mAddress, this);
michael@0 88 }
michael@0 89
michael@0 90 void
michael@0 91 BluetoothDevice::Root()
michael@0 92 {
michael@0 93 if (!mIsRooted) {
michael@0 94 mozilla::HoldJSObjects(this);
michael@0 95 mIsRooted = true;
michael@0 96 }
michael@0 97 }
michael@0 98
michael@0 99 void
michael@0 100 BluetoothDevice::Unroot()
michael@0 101 {
michael@0 102 if (mIsRooted) {
michael@0 103 mJsUuids = nullptr;
michael@0 104 mJsServices = nullptr;
michael@0 105 mozilla::DropJSObjects(this);
michael@0 106 mIsRooted = false;
michael@0 107 }
michael@0 108 }
michael@0 109
michael@0 110 void
michael@0 111 BluetoothDevice::SetPropertyByValue(const BluetoothNamedValue& aValue)
michael@0 112 {
michael@0 113 const nsString& name = aValue.name();
michael@0 114 const BluetoothValue& value = aValue.value();
michael@0 115 if (name.EqualsLiteral("Name")) {
michael@0 116 mName = value.get_nsString();
michael@0 117 } else if (name.EqualsLiteral("Path")) {
michael@0 118 MOZ_ASSERT(value.get_nsString().Length() > 0);
michael@0 119 mPath = value.get_nsString();
michael@0 120 } else if (name.EqualsLiteral("Address")) {
michael@0 121 mAddress = value.get_nsString();
michael@0 122 } else if (name.EqualsLiteral("Class")) {
michael@0 123 mClass = value.get_uint32_t();
michael@0 124 } else if (name.EqualsLiteral("Icon")) {
michael@0 125 mIcon = value.get_nsString();
michael@0 126 } else if (name.EqualsLiteral("Connected")) {
michael@0 127 mConnected = value.get_bool();
michael@0 128 } else if (name.EqualsLiteral("Paired")) {
michael@0 129 mPaired = value.get_bool();
michael@0 130 } else if (name.EqualsLiteral("UUIDs")) {
michael@0 131 mUuids = value.get_ArrayOfnsString();
michael@0 132 nsresult rv;
michael@0 133 nsIScriptContext* sc = GetContextForEventHandlers(&rv);
michael@0 134 NS_ENSURE_SUCCESS_VOID(rv);
michael@0 135 NS_ENSURE_TRUE_VOID(sc);
michael@0 136
michael@0 137 AutoPushJSContext cx(sc->GetNativeContext());
michael@0 138
michael@0 139 JS::Rooted<JSObject*> uuids(cx);
michael@0 140 if (NS_FAILED(nsTArrayToJSArray(cx, mUuids, uuids.address()))) {
michael@0 141 BT_WARNING("Cannot set JS UUIDs object!");
michael@0 142 return;
michael@0 143 }
michael@0 144 mJsUuids = uuids;
michael@0 145 Root();
michael@0 146 } else if (name.EqualsLiteral("Services")) {
michael@0 147 mServices = value.get_ArrayOfnsString();
michael@0 148 nsresult rv;
michael@0 149 nsIScriptContext* sc = GetContextForEventHandlers(&rv);
michael@0 150 NS_ENSURE_SUCCESS_VOID(rv);
michael@0 151 NS_ENSURE_TRUE_VOID(sc);
michael@0 152
michael@0 153 AutoPushJSContext cx(sc->GetNativeContext());
michael@0 154
michael@0 155 JS::Rooted<JSObject*> services(cx);
michael@0 156 if (NS_FAILED(nsTArrayToJSArray(cx, mServices, services.address()))) {
michael@0 157 BT_WARNING("Cannot set JS Services object!");
michael@0 158 return;
michael@0 159 }
michael@0 160 mJsServices = services;
michael@0 161 Root();
michael@0 162 } else {
michael@0 163 nsCString warningMsg;
michael@0 164 warningMsg.AssignLiteral("Not handling device property: ");
michael@0 165 warningMsg.Append(NS_ConvertUTF16toUTF8(name));
michael@0 166 BT_WARNING(warningMsg.get());
michael@0 167 }
michael@0 168 }
michael@0 169
michael@0 170 // static
michael@0 171 already_AddRefed<BluetoothDevice>
michael@0 172 BluetoothDevice::Create(nsPIDOMWindow* aWindow,
michael@0 173 const nsAString& aAdapterPath,
michael@0 174 const BluetoothValue& aValue)
michael@0 175 {
michael@0 176 MOZ_ASSERT(NS_IsMainThread());
michael@0 177 MOZ_ASSERT(aWindow);
michael@0 178
michael@0 179 nsRefPtr<BluetoothDevice> device =
michael@0 180 new BluetoothDevice(aWindow, aAdapterPath, aValue);
michael@0 181 return device.forget();
michael@0 182 }
michael@0 183
michael@0 184 void
michael@0 185 BluetoothDevice::Notify(const BluetoothSignal& aData)
michael@0 186 {
michael@0 187 BT_LOGD("[D] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aData.name()).get());
michael@0 188
michael@0 189 BluetoothValue v = aData.value();
michael@0 190 if (aData.name().EqualsLiteral("PropertyChanged")) {
michael@0 191 MOZ_ASSERT(v.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
michael@0 192
michael@0 193 const InfallibleTArray<BluetoothNamedValue>& arr =
michael@0 194 v.get_ArrayOfBluetoothNamedValue();
michael@0 195
michael@0 196 for (uint32_t i = 0, propCount = arr.Length(); i < propCount; ++i) {
michael@0 197 SetPropertyByValue(arr[i]);
michael@0 198 }
michael@0 199 } else {
michael@0 200 #ifdef DEBUG
michael@0 201 nsCString warningMsg;
michael@0 202 warningMsg.AssignLiteral("Not handling device signal: ");
michael@0 203 warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name()));
michael@0 204 BT_WARNING(warningMsg.get());
michael@0 205 #endif
michael@0 206 }
michael@0 207 }
michael@0 208
michael@0 209 void
michael@0 210 BluetoothDevice::GetUuids(JSContext* aContext,
michael@0 211 JS::MutableHandle<JS::Value> aUuids,
michael@0 212 ErrorResult& aRv)
michael@0 213 {
michael@0 214 if (!mJsUuids) {
michael@0 215 BT_WARNING("UUIDs not yet set!");
michael@0 216 aRv.Throw(NS_ERROR_FAILURE);
michael@0 217 return;
michael@0 218 }
michael@0 219
michael@0 220 JS::ExposeObjectToActiveJS(mJsUuids);
michael@0 221 aUuids.setObject(*mJsUuids);
michael@0 222 }
michael@0 223
michael@0 224 void
michael@0 225 BluetoothDevice::GetServices(JSContext* aCx,
michael@0 226 JS::MutableHandle<JS::Value> aServices,
michael@0 227 ErrorResult& aRv)
michael@0 228 {
michael@0 229 if (!mJsServices) {
michael@0 230 BT_WARNING("Services not yet set!");
michael@0 231 aRv.Throw(NS_ERROR_FAILURE);
michael@0 232 return;
michael@0 233 }
michael@0 234
michael@0 235 JS::ExposeObjectToActiveJS(mJsServices);
michael@0 236 aServices.setObject(*mJsServices);
michael@0 237 }
michael@0 238
michael@0 239 JSObject*
michael@0 240 BluetoothDevice::WrapObject(JSContext* aContext)
michael@0 241 {
michael@0 242 return BluetoothDeviceBinding::Wrap(aContext, this);
michael@0 243 }

mercurial