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

mercurial