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

     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"
     9 #include "BluetoothReplyRunnable.h"
    10 #include "BluetoothService.h"
    11 #include "BluetoothUtils.h"
    12 #include "jsapi.h"
    13 #include "mozilla/Scoped.h"
    14 #include "mozilla/dom/bluetooth/BluetoothTypes.h"
    15 #include "nsContentUtils.h"
    16 #include "nsCxPusher.h"
    17 #include "nsIScriptContext.h"
    18 #include "nsISystemMessagesInternal.h"
    19 #include "nsString.h"
    20 #include "nsTArray.h"
    21 #include "nsServiceManagerUtils.h"
    23 BEGIN_BLUETOOTH_NAMESPACE
    25 bool
    26 SetJsObject(JSContext* aContext,
    27             const BluetoothValue& aValue,
    28             JS::Handle<JSObject*> aObj)
    29 {
    30   MOZ_ASSERT(aContext && aObj);
    32   if (aValue.type() != BluetoothValue::TArrayOfBluetoothNamedValue) {
    33     BT_WARNING("SetJsObject: Invalid parameter type");
    34     return false;
    35   }
    37   const nsTArray<BluetoothNamedValue>& arr =
    38     aValue.get_ArrayOfBluetoothNamedValue();
    40   for (uint32_t i = 0; i < arr.Length(); i++) {
    41     JS::Rooted<JS::Value> val(aContext);
    42     const BluetoothValue& v = arr[i].value();
    44     switch(v.type()) {
    45        case BluetoothValue::TnsString: {
    46         JSString* jsData = JS_NewUCStringCopyN(aContext,
    47                                      v.get_nsString().BeginReading(),
    48                                      v.get_nsString().Length());
    49         NS_ENSURE_TRUE(jsData, false);
    50         val = STRING_TO_JSVAL(jsData);
    51         break;
    52       }
    53       case BluetoothValue::Tuint32_t:
    54         val = INT_TO_JSVAL(v.get_uint32_t());
    55         break;
    56       case BluetoothValue::Tbool:
    57         val = BOOLEAN_TO_JSVAL(v.get_bool());
    58         break;
    59       default:
    60         BT_WARNING("SetJsObject: Parameter is not handled");
    61         break;
    62     }
    64     if (!JS_SetProperty(aContext, aObj,
    65                         NS_ConvertUTF16toUTF8(arr[i].name()).get(),
    66                         val)) {
    67       BT_WARNING("Failed to set property");
    68       return false;
    69     }
    70   }
    72   return true;
    73 }
    75 nsString
    76 GetObjectPathFromAddress(const nsAString& aAdapterPath,
    77                          const nsAString& aDeviceAddress)
    78 {
    79   // The object path would be like /org/bluez/2906/hci0/dev_00_23_7F_CB_B4_F1,
    80   // and the adapter path would be the first part of the object path, according
    81   // to the example above, it's /org/bluez/2906/hci0.
    82   nsString devicePath(aAdapterPath);
    83   devicePath.AppendLiteral("/dev_");
    84   devicePath.Append(aDeviceAddress);
    85   devicePath.ReplaceChar(':', '_');
    86   return devicePath;
    87 }
    89 nsString
    90 GetAddressFromObjectPath(const nsAString& aObjectPath)
    91 {
    92   // The object path would be like /org/bluez/2906/hci0/dev_00_23_7F_CB_B4_F1,
    93   // and the adapter path would be the first part of the object path, according
    94   // to the example above, it's /org/bluez/2906/hci0.
    95   nsString address(aObjectPath);
    96   int addressHead = address.RFind("/") + 5;
    98   MOZ_ASSERT(addressHead + BLUETOOTH_ADDRESS_LENGTH == (int)address.Length());
   100   address.Cut(0, addressHead);
   101   address.ReplaceChar('_', ':');
   103   return address;
   104 }
   106 bool
   107 BroadcastSystemMessage(const nsAString& aType,
   108                        const InfallibleTArray<BluetoothNamedValue>& aData)
   109 {
   110   mozilla::AutoSafeJSContext cx;
   111   NS_ASSERTION(!::JS_IsExceptionPending(cx),
   112       "Shouldn't get here when an exception is pending!");
   114   JS::Rooted<JSObject*> obj(cx, JS_NewObject(cx, nullptr, JS::NullPtr(),
   115                                              JS::NullPtr()));
   116   if (!obj) {
   117     BT_WARNING("Failed to new JSObject for system message!");
   118     return false;
   119   }
   121   if (!SetJsObject(cx, aData, obj)) {
   122     BT_WARNING("Failed to set properties of system message!");
   123     return false;
   124   }
   126   nsCOMPtr<nsISystemMessagesInternal> systemMessenger =
   127     do_GetService("@mozilla.org/system-message-internal;1");
   128   NS_ENSURE_TRUE(systemMessenger, false);
   130   JS::Rooted<JS::Value> value(cx, JS::ObjectValue(*obj));
   131   systemMessenger->BroadcastMessage(aType, value,
   132                                     JS::UndefinedHandleValue);
   134   return true;
   135 }
   137 void
   138 DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
   139                        const BluetoothValue& aValue,
   140                        const nsAString& aErrorStr)
   141 {
   142   // Reply will be deleted by the runnable after running on main thread
   143   BluetoothReply* reply;
   144   if (!aErrorStr.IsEmpty()) {
   145     nsString err(aErrorStr);
   146     reply = new BluetoothReply(BluetoothReplyError(err));
   147   } else {
   148     MOZ_ASSERT(aValue.type() != BluetoothValue::T__None);
   149     reply = new BluetoothReply(BluetoothReplySuccess(aValue));
   150   }
   152   aRunnable->SetReply(reply);
   153   if (NS_FAILED(NS_DispatchToMainThread(aRunnable))) {
   154     BT_WARNING("Failed to dispatch to main thread!");
   155   }
   156 }
   158 void
   159 ParseAtCommand(const nsACString& aAtCommand, const int aStart,
   160                nsTArray<nsCString>& aRetValues)
   161 {
   162   int length = aAtCommand.Length();
   163   int begin = aStart;
   165   for (int i = aStart; i < length; ++i) {
   166     // Use ',' as separator
   167     if (aAtCommand[i] == ',') {
   168       nsCString tmp(nsDependentCSubstring(aAtCommand, begin, i - begin));
   169       aRetValues.AppendElement(tmp);
   171       begin = i + 1;
   172     }
   173   }
   175   nsCString tmp(nsDependentCSubstring(aAtCommand, begin));
   176   aRetValues.AppendElement(tmp);
   177 }
   179 void
   180 DispatchStatusChangedEvent(const nsAString& aType,
   181                            const nsAString& aAddress,
   182                            bool aStatus)
   183 {
   184   MOZ_ASSERT(NS_IsMainThread());
   186   InfallibleTArray<BluetoothNamedValue> data;
   187   data.AppendElement(
   188     BluetoothNamedValue(NS_LITERAL_STRING("address"), nsString(aAddress)));
   189   data.AppendElement(
   190     BluetoothNamedValue(NS_LITERAL_STRING("status"), aStatus));
   192   BluetoothSignal signal(nsString(aType), NS_LITERAL_STRING(KEY_ADAPTER), data);
   194   BluetoothService* bs = BluetoothService::Get();
   195   NS_ENSURE_TRUE_VOID(bs);
   196   bs->DistributeSignal(signal);
   197 }
   199 END_BLUETOOTH_NAMESPACE

mercurial