dom/bluetooth/BluetoothDevice.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.

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

mercurial