dom/bluetooth/BluetoothManager.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/bluetooth/BluetoothManager.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,252 @@
     1.4 +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
     1.5 +/* vim: set ts=2 et sw=2 tw=80: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#include "base/basictypes.h"
    1.11 +#include "BluetoothManager.h"
    1.12 +#include "BluetoothCommon.h"
    1.13 +#include "BluetoothAdapter.h"
    1.14 +#include "BluetoothService.h"
    1.15 +#include "BluetoothReplyRunnable.h"
    1.16 +
    1.17 +#include "DOMRequest.h"
    1.18 +#include "nsContentUtils.h"
    1.19 +#include "nsDOMClassInfo.h"
    1.20 +#include "nsIPermissionManager.h"
    1.21 +#include "nsThreadUtils.h"
    1.22 +#include "mozilla/dom/bluetooth/BluetoothTypes.h"
    1.23 +#include "mozilla/dom/BluetoothManagerBinding.h"
    1.24 +
    1.25 +using namespace mozilla;
    1.26 +
    1.27 +USING_BLUETOOTH_NAMESPACE
    1.28 +
    1.29 +// QueryInterface implementation for BluetoothManager
    1.30 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothManager)
    1.31 +NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
    1.32 +
    1.33 +NS_IMPL_ADDREF_INHERITED(BluetoothManager, DOMEventTargetHelper)
    1.34 +NS_IMPL_RELEASE_INHERITED(BluetoothManager, DOMEventTargetHelper)
    1.35 +
    1.36 +class GetAdapterTask : public BluetoothReplyRunnable
    1.37 +{
    1.38 +public:
    1.39 +  GetAdapterTask(BluetoothManager* aManager,
    1.40 +                 nsIDOMDOMRequest* aReq) :
    1.41 +    BluetoothReplyRunnable(aReq),
    1.42 +    mManagerPtr(aManager)
    1.43 +  {
    1.44 +  }
    1.45 +
    1.46 +  bool
    1.47 +  ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue)
    1.48 +  {
    1.49 +    aValue.setUndefined();
    1.50 +
    1.51 +    const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value();
    1.52 +    if (v.type() != BluetoothValue::TArrayOfBluetoothNamedValue) {
    1.53 +      BT_WARNING("Not a BluetoothNamedValue array!");
    1.54 +      SetError(NS_LITERAL_STRING("BluetoothReplyTypeError"));
    1.55 +      return false;
    1.56 +    }
    1.57 +
    1.58 +    if (!mManagerPtr->GetOwner()) {
    1.59 +      BT_WARNING("Bluetooth manager was disconnected from owner window.");
    1.60 +
    1.61 +      // Stop to create adapter since owner window of Bluetooth manager was
    1.62 +      // gone. These is no need to create a DOMEvent target which has no owner
    1.63 +      // to reply to.
    1.64 +      return false;
    1.65 +    }
    1.66 +
    1.67 +    const InfallibleTArray<BluetoothNamedValue>& values =
    1.68 +      v.get_ArrayOfBluetoothNamedValue();
    1.69 +    nsRefPtr<BluetoothAdapter> adapter =
    1.70 +      BluetoothAdapter::Create(mManagerPtr->GetOwner(), values);
    1.71 +
    1.72 +    nsresult rv;
    1.73 +    nsIScriptContext* sc = mManagerPtr->GetContextForEventHandlers(&rv);
    1.74 +    if (!sc) {
    1.75 +      BT_WARNING("Cannot create script context!");
    1.76 +      SetError(NS_LITERAL_STRING("BluetoothScriptContextError"));
    1.77 +      return false;
    1.78 +    }
    1.79 +
    1.80 +    AutoPushJSContext cx(sc->GetNativeContext());
    1.81 +
    1.82 +    JS::Rooted<JSObject*> scope(cx, sc->GetWindowProxy());
    1.83 +    JSAutoCompartment ac(cx, scope);
    1.84 +    rv = nsContentUtils::WrapNative(cx, adapter, aValue);
    1.85 +    if (NS_FAILED(rv)) {
    1.86 +      BT_WARNING("Cannot create native object!");
    1.87 +      SetError(NS_LITERAL_STRING("BluetoothNativeObjectError"));
    1.88 +      return false;
    1.89 +    }
    1.90 +
    1.91 +    return true;
    1.92 +  }
    1.93 +
    1.94 +  void
    1.95 +  ReleaseMembers()
    1.96 +  {
    1.97 +    BluetoothReplyRunnable::ReleaseMembers();
    1.98 +    mManagerPtr = nullptr;
    1.99 +  }
   1.100 +
   1.101 +private:
   1.102 +  nsRefPtr<BluetoothManager> mManagerPtr;
   1.103 +};
   1.104 +
   1.105 +BluetoothManager::BluetoothManager(nsPIDOMWindow *aWindow)
   1.106 +  : DOMEventTargetHelper(aWindow)
   1.107 +  , BluetoothPropertyContainer(BluetoothObjectType::TYPE_MANAGER)
   1.108 +{
   1.109 +  MOZ_ASSERT(aWindow);
   1.110 +  MOZ_ASSERT(IsDOMBinding());
   1.111 +
   1.112 +  mPath.AssignLiteral("/");
   1.113 +
   1.114 +  BluetoothService* bs = BluetoothService::Get();
   1.115 +  NS_ENSURE_TRUE_VOID(bs);
   1.116 +  bs->RegisterBluetoothSignalHandler(NS_LITERAL_STRING(KEY_MANAGER), this);
   1.117 +}
   1.118 +
   1.119 +BluetoothManager::~BluetoothManager()
   1.120 +{
   1.121 +  BluetoothService* bs = BluetoothService::Get();
   1.122 +  NS_ENSURE_TRUE_VOID(bs);
   1.123 +  bs->UnregisterBluetoothSignalHandler(NS_LITERAL_STRING(KEY_MANAGER), this);
   1.124 +}
   1.125 +
   1.126 +void
   1.127 +BluetoothManager::DisconnectFromOwner()
   1.128 +{
   1.129 +  DOMEventTargetHelper::DisconnectFromOwner();
   1.130 +
   1.131 +  BluetoothService* bs = BluetoothService::Get();
   1.132 +  NS_ENSURE_TRUE_VOID(bs);
   1.133 +  bs->UnregisterBluetoothSignalHandler(NS_LITERAL_STRING(KEY_MANAGER), this);
   1.134 +}
   1.135 +
   1.136 +void
   1.137 +BluetoothManager::SetPropertyByValue(const BluetoothNamedValue& aValue)
   1.138 +{
   1.139 +#ifdef DEBUG
   1.140 +    const nsString& name = aValue.name();
   1.141 +    nsCString warningMsg;
   1.142 +    warningMsg.AssignLiteral("Not handling manager property: ");
   1.143 +    warningMsg.Append(NS_ConvertUTF16toUTF8(name));
   1.144 +    BT_WARNING(warningMsg.get());
   1.145 +#endif
   1.146 +}
   1.147 +
   1.148 +bool
   1.149 +BluetoothManager::GetEnabled(ErrorResult& aRv)
   1.150 +{
   1.151 +  BluetoothService* bs = BluetoothService::Get();
   1.152 +  if (!bs) {
   1.153 +    aRv.Throw(NS_ERROR_FAILURE);
   1.154 +    return false;
   1.155 +  }
   1.156 +
   1.157 +  return bs->IsEnabled();
   1.158 +}
   1.159 +
   1.160 +already_AddRefed<dom::DOMRequest>
   1.161 +BluetoothManager::GetDefaultAdapter(ErrorResult& aRv)
   1.162 +{
   1.163 +  nsCOMPtr<nsPIDOMWindow> win = GetOwner();
   1.164 +  if (!win) {
   1.165 +    aRv.Throw(NS_ERROR_FAILURE);
   1.166 +    return nullptr;
   1.167 +  }
   1.168 +
   1.169 +  nsRefPtr<DOMRequest> request = new DOMRequest(win);
   1.170 +  nsRefPtr<BluetoothReplyRunnable> results =
   1.171 +    new GetAdapterTask(this, request);
   1.172 +
   1.173 +  BluetoothService* bs = BluetoothService::Get();
   1.174 +  if (!bs) {
   1.175 +    aRv.Throw(NS_ERROR_FAILURE);
   1.176 +    return nullptr;
   1.177 +  }
   1.178 +
   1.179 +  nsresult rv = bs->GetDefaultAdapterPathInternal(results);
   1.180 +  if (NS_FAILED(rv)) {
   1.181 +    aRv.Throw(rv);
   1.182 +    return nullptr;
   1.183 +  }
   1.184 +
   1.185 +  return request.forget();
   1.186 +}
   1.187 +
   1.188 +// static
   1.189 +already_AddRefed<BluetoothManager>
   1.190 +BluetoothManager::Create(nsPIDOMWindow* aWindow)
   1.191 +{
   1.192 +  MOZ_ASSERT(NS_IsMainThread());
   1.193 +  MOZ_ASSERT(aWindow);
   1.194 +
   1.195 +  nsRefPtr<BluetoothManager> manager = new BluetoothManager(aWindow);
   1.196 +  return manager.forget();
   1.197 +}
   1.198 +
   1.199 +// static
   1.200 +bool
   1.201 +BluetoothManager::CheckPermission(nsPIDOMWindow* aWindow)
   1.202 +{
   1.203 +  NS_ASSERTION(aWindow, "Null pointer!");
   1.204 +
   1.205 +  nsCOMPtr<nsIPermissionManager> permMgr =
   1.206 +    do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
   1.207 +  NS_ENSURE_TRUE(permMgr, false);
   1.208 +
   1.209 +  uint32_t permission;
   1.210 +  nsresult rv =
   1.211 +    permMgr->TestPermissionFromWindow(aWindow, "bluetooth",
   1.212 +                                      &permission);
   1.213 +  NS_ENSURE_SUCCESS(rv, false);
   1.214 +
   1.215 +  return permission == nsIPermissionManager::ALLOW_ACTION;
   1.216 +}
   1.217 +
   1.218 +void
   1.219 +BluetoothManager::Notify(const BluetoothSignal& aData)
   1.220 +{
   1.221 +  BT_LOGD("[M] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aData.name()).get());
   1.222 +
   1.223 +  if (aData.name().EqualsLiteral("AdapterAdded")) {
   1.224 +    DispatchTrustedEvent(NS_LITERAL_STRING("adapteradded"));
   1.225 +  } else if (aData.name().EqualsLiteral("Enabled")) {
   1.226 +    DispatchTrustedEvent(NS_LITERAL_STRING("enabled"));
   1.227 +  } else if (aData.name().EqualsLiteral("Disabled")) {
   1.228 +    DispatchTrustedEvent(NS_LITERAL_STRING("disabled"));
   1.229 +  } else {
   1.230 +#ifdef DEBUG
   1.231 +    nsCString warningMsg;
   1.232 +    warningMsg.AssignLiteral("Not handling manager signal: ");
   1.233 +    warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name()));
   1.234 +    BT_WARNING(warningMsg.get());
   1.235 +#endif
   1.236 +  }
   1.237 +}
   1.238 +
   1.239 +bool
   1.240 +BluetoothManager::IsConnected(uint16_t aProfileId, ErrorResult& aRv)
   1.241 +{
   1.242 +  BluetoothService* bs = BluetoothService::Get();
   1.243 +  if (!bs) {
   1.244 +    aRv.Throw(NS_ERROR_FAILURE);
   1.245 +    return false;
   1.246 +  }
   1.247 +
   1.248 +  return bs->IsConnected(aProfileId);
   1.249 +}
   1.250 +
   1.251 +JSObject*
   1.252 +BluetoothManager::WrapObject(JSContext* aCx)
   1.253 +{
   1.254 +  return BluetoothManagerBinding::Wrap(aCx, this);
   1.255 +}

mercurial