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"
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"
21 #include "nsServiceManagerUtils.h"
23 BEGIN_BLUETOOTH_NAMESPACE
26 SetJsObject(JSContext
* aContext
,
27 const BluetoothValue
& aValue
,
28 JS::Handle
<JSObject
*> aObj
)
30 MOZ_ASSERT(aContext
&& aObj
);
32 if (aValue
.type() != BluetoothValue::TArrayOfBluetoothNamedValue
) {
33 BT_WARNING("SetJsObject: Invalid parameter type");
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();
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
);
53 case BluetoothValue::Tuint32_t
:
54 val
= INT_TO_JSVAL(v
.get_uint32_t());
56 case BluetoothValue::Tbool
:
57 val
= BOOLEAN_TO_JSVAL(v
.get_bool());
60 BT_WARNING("SetJsObject: Parameter is not handled");
64 if (!JS_SetProperty(aContext
, aObj
,
65 NS_ConvertUTF16toUTF8(arr
[i
].name()).get(),
67 BT_WARNING("Failed to set property");
76 GetObjectPathFromAddress(const nsAString
& aAdapterPath
,
77 const nsAString
& aDeviceAddress
)
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(':', '_');
90 GetAddressFromObjectPath(const nsAString
& aObjectPath
)
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
== address
.Length());
100 address
.Cut(0, addressHead
);
101 address
.ReplaceChar('_', ':');
107 BroadcastSystemMessage(const nsAString
& aType
,
108 const InfallibleTArray
<BluetoothNamedValue
>& aData
)
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, nullptr, nullptr));
116 BT_WARNING("Failed to new JSObject for system message!");
120 if (!SetJsObject(cx
, aData
, obj
)) {
121 BT_WARNING("Failed to set properties of system message!");
125 nsCOMPtr
<nsISystemMessagesInternal
> systemMessenger
=
126 do_GetService("@mozilla.org/system-message-internal;1");
127 NS_ENSURE_TRUE(systemMessenger
, false);
129 systemMessenger
->BroadcastMessage(aType
,
130 OBJECT_TO_JSVAL(obj
),
131 JS::UndefinedValue());
137 DispatchBluetoothReply(BluetoothReplyRunnable
* aRunnable
,
138 const BluetoothValue
& aValue
,
139 const nsAString
& aErrorStr
)
141 // Reply will be deleted by the runnable after running on main thread
142 BluetoothReply
* reply
;
143 if (!aErrorStr
.IsEmpty()) {
144 nsString
err(aErrorStr
);
145 reply
= new BluetoothReply(BluetoothReplyError(err
));
147 MOZ_ASSERT(aValue
.type() != BluetoothValue::T__None
);
148 reply
= new BluetoothReply(BluetoothReplySuccess(aValue
));
151 aRunnable
->SetReply(reply
);
152 if (NS_FAILED(NS_DispatchToMainThread(aRunnable
))) {
153 BT_WARNING("Failed to dispatch to main thread!");
158 ParseAtCommand(const nsACString
& aAtCommand
, const int aStart
,
159 nsTArray
<nsCString
>& aRetValues
)
161 int length
= aAtCommand
.Length();
164 for (int i
= aStart
; i
< length
; ++i
) {
165 // Use ',' as separator
166 if (aAtCommand
[i
] == ',') {
167 nsCString
tmp(nsDependentCSubstring(aAtCommand
, begin
, i
- begin
));
168 aRetValues
.AppendElement(tmp
);
174 nsCString
tmp(nsDependentCSubstring(aAtCommand
, begin
));
175 aRetValues
.AppendElement(tmp
);
179 DispatchStatusChangedEvent(const nsAString
& aType
,
180 const nsAString
& aAddress
,
183 MOZ_ASSERT(NS_IsMainThread());
185 InfallibleTArray
<BluetoothNamedValue
> data
;
187 BluetoothNamedValue(NS_LITERAL_STRING("address"), nsString(aAddress
)));
189 BluetoothNamedValue(NS_LITERAL_STRING("status"), aStatus
));
191 BluetoothSignal
signal(nsString(aType
), NS_LITERAL_STRING(KEY_ADAPTER
), data
);
193 BluetoothService
* bs
= BluetoothService::Get();
194 NS_ENSURE_TRUE_VOID(bs
);
195 bs
->DistributeSignal(signal
);
198 END_BLUETOOTH_NAMESPACE