dom/bluetooth/BluetoothManager.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 "BluetoothManager.h"
michael@0 9 #include "BluetoothCommon.h"
michael@0 10 #include "BluetoothAdapter.h"
michael@0 11 #include "BluetoothService.h"
michael@0 12 #include "BluetoothReplyRunnable.h"
michael@0 13
michael@0 14 #include "DOMRequest.h"
michael@0 15 #include "nsContentUtils.h"
michael@0 16 #include "nsDOMClassInfo.h"
michael@0 17 #include "nsIPermissionManager.h"
michael@0 18 #include "nsThreadUtils.h"
michael@0 19 #include "mozilla/dom/bluetooth/BluetoothTypes.h"
michael@0 20 #include "mozilla/dom/BluetoothManagerBinding.h"
michael@0 21
michael@0 22 using namespace mozilla;
michael@0 23
michael@0 24 USING_BLUETOOTH_NAMESPACE
michael@0 25
michael@0 26 // QueryInterface implementation for BluetoothManager
michael@0 27 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothManager)
michael@0 28 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
michael@0 29
michael@0 30 NS_IMPL_ADDREF_INHERITED(BluetoothManager, DOMEventTargetHelper)
michael@0 31 NS_IMPL_RELEASE_INHERITED(BluetoothManager, DOMEventTargetHelper)
michael@0 32
michael@0 33 class GetAdapterTask : public BluetoothReplyRunnable
michael@0 34 {
michael@0 35 public:
michael@0 36 GetAdapterTask(BluetoothManager* aManager,
michael@0 37 nsIDOMDOMRequest* aReq) :
michael@0 38 BluetoothReplyRunnable(aReq),
michael@0 39 mManagerPtr(aManager)
michael@0 40 {
michael@0 41 }
michael@0 42
michael@0 43 bool
michael@0 44 ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue)
michael@0 45 {
michael@0 46 aValue.setUndefined();
michael@0 47
michael@0 48 const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value();
michael@0 49 if (v.type() != BluetoothValue::TArrayOfBluetoothNamedValue) {
michael@0 50 BT_WARNING("Not a BluetoothNamedValue array!");
michael@0 51 SetError(NS_LITERAL_STRING("BluetoothReplyTypeError"));
michael@0 52 return false;
michael@0 53 }
michael@0 54
michael@0 55 if (!mManagerPtr->GetOwner()) {
michael@0 56 BT_WARNING("Bluetooth manager was disconnected from owner window.");
michael@0 57
michael@0 58 // Stop to create adapter since owner window of Bluetooth manager was
michael@0 59 // gone. These is no need to create a DOMEvent target which has no owner
michael@0 60 // to reply to.
michael@0 61 return false;
michael@0 62 }
michael@0 63
michael@0 64 const InfallibleTArray<BluetoothNamedValue>& values =
michael@0 65 v.get_ArrayOfBluetoothNamedValue();
michael@0 66 nsRefPtr<BluetoothAdapter> adapter =
michael@0 67 BluetoothAdapter::Create(mManagerPtr->GetOwner(), values);
michael@0 68
michael@0 69 nsresult rv;
michael@0 70 nsIScriptContext* sc = mManagerPtr->GetContextForEventHandlers(&rv);
michael@0 71 if (!sc) {
michael@0 72 BT_WARNING("Cannot create script context!");
michael@0 73 SetError(NS_LITERAL_STRING("BluetoothScriptContextError"));
michael@0 74 return false;
michael@0 75 }
michael@0 76
michael@0 77 AutoPushJSContext cx(sc->GetNativeContext());
michael@0 78
michael@0 79 JS::Rooted<JSObject*> scope(cx, sc->GetWindowProxy());
michael@0 80 JSAutoCompartment ac(cx, scope);
michael@0 81 rv = nsContentUtils::WrapNative(cx, adapter, aValue);
michael@0 82 if (NS_FAILED(rv)) {
michael@0 83 BT_WARNING("Cannot create native object!");
michael@0 84 SetError(NS_LITERAL_STRING("BluetoothNativeObjectError"));
michael@0 85 return false;
michael@0 86 }
michael@0 87
michael@0 88 return true;
michael@0 89 }
michael@0 90
michael@0 91 void
michael@0 92 ReleaseMembers()
michael@0 93 {
michael@0 94 BluetoothReplyRunnable::ReleaseMembers();
michael@0 95 mManagerPtr = nullptr;
michael@0 96 }
michael@0 97
michael@0 98 private:
michael@0 99 nsRefPtr<BluetoothManager> mManagerPtr;
michael@0 100 };
michael@0 101
michael@0 102 BluetoothManager::BluetoothManager(nsPIDOMWindow *aWindow)
michael@0 103 : DOMEventTargetHelper(aWindow)
michael@0 104 , BluetoothPropertyContainer(BluetoothObjectType::TYPE_MANAGER)
michael@0 105 {
michael@0 106 MOZ_ASSERT(aWindow);
michael@0 107 MOZ_ASSERT(IsDOMBinding());
michael@0 108
michael@0 109 mPath.AssignLiteral("/");
michael@0 110
michael@0 111 BluetoothService* bs = BluetoothService::Get();
michael@0 112 NS_ENSURE_TRUE_VOID(bs);
michael@0 113 bs->RegisterBluetoothSignalHandler(NS_LITERAL_STRING(KEY_MANAGER), this);
michael@0 114 }
michael@0 115
michael@0 116 BluetoothManager::~BluetoothManager()
michael@0 117 {
michael@0 118 BluetoothService* bs = BluetoothService::Get();
michael@0 119 NS_ENSURE_TRUE_VOID(bs);
michael@0 120 bs->UnregisterBluetoothSignalHandler(NS_LITERAL_STRING(KEY_MANAGER), this);
michael@0 121 }
michael@0 122
michael@0 123 void
michael@0 124 BluetoothManager::DisconnectFromOwner()
michael@0 125 {
michael@0 126 DOMEventTargetHelper::DisconnectFromOwner();
michael@0 127
michael@0 128 BluetoothService* bs = BluetoothService::Get();
michael@0 129 NS_ENSURE_TRUE_VOID(bs);
michael@0 130 bs->UnregisterBluetoothSignalHandler(NS_LITERAL_STRING(KEY_MANAGER), this);
michael@0 131 }
michael@0 132
michael@0 133 void
michael@0 134 BluetoothManager::SetPropertyByValue(const BluetoothNamedValue& aValue)
michael@0 135 {
michael@0 136 #ifdef DEBUG
michael@0 137 const nsString& name = aValue.name();
michael@0 138 nsCString warningMsg;
michael@0 139 warningMsg.AssignLiteral("Not handling manager property: ");
michael@0 140 warningMsg.Append(NS_ConvertUTF16toUTF8(name));
michael@0 141 BT_WARNING(warningMsg.get());
michael@0 142 #endif
michael@0 143 }
michael@0 144
michael@0 145 bool
michael@0 146 BluetoothManager::GetEnabled(ErrorResult& aRv)
michael@0 147 {
michael@0 148 BluetoothService* bs = BluetoothService::Get();
michael@0 149 if (!bs) {
michael@0 150 aRv.Throw(NS_ERROR_FAILURE);
michael@0 151 return false;
michael@0 152 }
michael@0 153
michael@0 154 return bs->IsEnabled();
michael@0 155 }
michael@0 156
michael@0 157 already_AddRefed<dom::DOMRequest>
michael@0 158 BluetoothManager::GetDefaultAdapter(ErrorResult& aRv)
michael@0 159 {
michael@0 160 nsCOMPtr<nsPIDOMWindow> win = GetOwner();
michael@0 161 if (!win) {
michael@0 162 aRv.Throw(NS_ERROR_FAILURE);
michael@0 163 return nullptr;
michael@0 164 }
michael@0 165
michael@0 166 nsRefPtr<DOMRequest> request = new DOMRequest(win);
michael@0 167 nsRefPtr<BluetoothReplyRunnable> results =
michael@0 168 new GetAdapterTask(this, request);
michael@0 169
michael@0 170 BluetoothService* bs = BluetoothService::Get();
michael@0 171 if (!bs) {
michael@0 172 aRv.Throw(NS_ERROR_FAILURE);
michael@0 173 return nullptr;
michael@0 174 }
michael@0 175
michael@0 176 nsresult rv = bs->GetDefaultAdapterPathInternal(results);
michael@0 177 if (NS_FAILED(rv)) {
michael@0 178 aRv.Throw(rv);
michael@0 179 return nullptr;
michael@0 180 }
michael@0 181
michael@0 182 return request.forget();
michael@0 183 }
michael@0 184
michael@0 185 // static
michael@0 186 already_AddRefed<BluetoothManager>
michael@0 187 BluetoothManager::Create(nsPIDOMWindow* aWindow)
michael@0 188 {
michael@0 189 MOZ_ASSERT(NS_IsMainThread());
michael@0 190 MOZ_ASSERT(aWindow);
michael@0 191
michael@0 192 nsRefPtr<BluetoothManager> manager = new BluetoothManager(aWindow);
michael@0 193 return manager.forget();
michael@0 194 }
michael@0 195
michael@0 196 // static
michael@0 197 bool
michael@0 198 BluetoothManager::CheckPermission(nsPIDOMWindow* aWindow)
michael@0 199 {
michael@0 200 NS_ASSERTION(aWindow, "Null pointer!");
michael@0 201
michael@0 202 nsCOMPtr<nsIPermissionManager> permMgr =
michael@0 203 do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
michael@0 204 NS_ENSURE_TRUE(permMgr, false);
michael@0 205
michael@0 206 uint32_t permission;
michael@0 207 nsresult rv =
michael@0 208 permMgr->TestPermissionFromWindow(aWindow, "bluetooth",
michael@0 209 &permission);
michael@0 210 NS_ENSURE_SUCCESS(rv, false);
michael@0 211
michael@0 212 return permission == nsIPermissionManager::ALLOW_ACTION;
michael@0 213 }
michael@0 214
michael@0 215 void
michael@0 216 BluetoothManager::Notify(const BluetoothSignal& aData)
michael@0 217 {
michael@0 218 BT_LOGD("[M] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aData.name()).get());
michael@0 219
michael@0 220 if (aData.name().EqualsLiteral("AdapterAdded")) {
michael@0 221 DispatchTrustedEvent(NS_LITERAL_STRING("adapteradded"));
michael@0 222 } else if (aData.name().EqualsLiteral("Enabled")) {
michael@0 223 DispatchTrustedEvent(NS_LITERAL_STRING("enabled"));
michael@0 224 } else if (aData.name().EqualsLiteral("Disabled")) {
michael@0 225 DispatchTrustedEvent(NS_LITERAL_STRING("disabled"));
michael@0 226 } else {
michael@0 227 #ifdef DEBUG
michael@0 228 nsCString warningMsg;
michael@0 229 warningMsg.AssignLiteral("Not handling manager signal: ");
michael@0 230 warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name()));
michael@0 231 BT_WARNING(warningMsg.get());
michael@0 232 #endif
michael@0 233 }
michael@0 234 }
michael@0 235
michael@0 236 bool
michael@0 237 BluetoothManager::IsConnected(uint16_t aProfileId, ErrorResult& aRv)
michael@0 238 {
michael@0 239 BluetoothService* bs = BluetoothService::Get();
michael@0 240 if (!bs) {
michael@0 241 aRv.Throw(NS_ERROR_FAILURE);
michael@0 242 return false;
michael@0 243 }
michael@0 244
michael@0 245 return bs->IsConnected(aProfileId);
michael@0 246 }
michael@0 247
michael@0 248 JSObject*
michael@0 249 BluetoothManager::WrapObject(JSContext* aCx)
michael@0 250 {
michael@0 251 return BluetoothManagerBinding::Wrap(aCx, this);
michael@0 252 }

mercurial