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

     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 "BluetoothHidManager.h"
    11 #include "BluetoothCommon.h"
    12 #include "BluetoothService.h"
    13 #include "BluetoothUtils.h"
    15 #include "mozilla/dom/bluetooth/BluetoothTypes.h"
    16 #include "mozilla/Services.h"
    17 #include "mozilla/StaticPtr.h"
    18 #include "nsIObserverService.h"
    19 #include "MainThreadUtils.h"
    21 using namespace mozilla;
    22 USING_BLUETOOTH_NAMESPACE
    24 namespace {
    25   StaticRefPtr<BluetoothHidManager> sBluetoothHidManager;
    26   bool sInShutdown = false;
    27 } // anonymous namespace
    29 NS_IMETHODIMP
    30 BluetoothHidManager::Observe(nsISupports* aSubject,
    31                              const char* aTopic,
    32                              const char16_t* aData)
    33 {
    34   MOZ_ASSERT(sBluetoothHidManager);
    36   if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
    37     HandleShutdown();
    38     return NS_OK;
    39   }
    41   MOZ_ASSERT(false, "BluetoothHidManager got unexpected topic!");
    42   return NS_ERROR_UNEXPECTED;
    43 }
    45 BluetoothHidManager::BluetoothHidManager()
    46 {
    47   Reset();
    48 }
    50 void
    51 BluetoothHidManager::Reset()
    52 {
    53   mConnected = false;
    54   mController = nullptr;
    55 }
    57 bool
    58 BluetoothHidManager::Init()
    59 {
    60   MOZ_ASSERT(NS_IsMainThread());
    62   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
    63   NS_ENSURE_TRUE(obs, false);
    64   if (NS_FAILED(obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false))) {
    65     BT_WARNING("Failed to add shutdown observer!");
    66     return false;
    67   }
    69   return true;
    70 }
    72 BluetoothHidManager::~BluetoothHidManager()
    73 {
    74   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
    75   NS_ENSURE_TRUE_VOID(obs);
    76   if (NS_FAILED(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))) {
    77     BT_WARNING("Failed to remove shutdown observer!");
    78   }
    79 }
    81 //static
    82 BluetoothHidManager*
    83 BluetoothHidManager::Get()
    84 {
    85   MOZ_ASSERT(NS_IsMainThread());
    87   // If we already exist, exit early
    88   if (sBluetoothHidManager) {
    89     return sBluetoothHidManager;
    90   }
    92   // If we're in shutdown, don't create a new instance
    93   NS_ENSURE_FALSE(sInShutdown, nullptr);
    95   // Create a new instance, register, and return
    96   BluetoothHidManager* manager = new BluetoothHidManager();
    97   NS_ENSURE_TRUE(manager->Init(), nullptr);
    99   sBluetoothHidManager = manager;
   100   return sBluetoothHidManager;
   101 }
   103 void
   104 BluetoothHidManager::HandleShutdown()
   105 {
   106   MOZ_ASSERT(NS_IsMainThread());
   107   sInShutdown = true;
   108   Disconnect(nullptr);
   109   sBluetoothHidManager = nullptr;
   110 }
   112 void
   113 BluetoothHidManager::Connect(const nsAString& aDeviceAddress,
   114                              BluetoothProfileController* aController)
   115 {
   116   MOZ_ASSERT(NS_IsMainThread());
   117   MOZ_ASSERT(!aDeviceAddress.IsEmpty());
   118   MOZ_ASSERT(aController && !mController);
   120   BluetoothService* bs = BluetoothService::Get();
   121   if (!bs || sInShutdown) {
   122     aController->NotifyCompletion(NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
   123     return;
   124   }
   126   if (mConnected) {
   127     aController->NotifyCompletion(NS_LITERAL_STRING(ERR_ALREADY_CONNECTED));
   128     return;
   129   }
   131   mDeviceAddress = aDeviceAddress;
   132   mController = aController;
   134   if (NS_FAILED(bs->SendInputMessage(aDeviceAddress,
   135                                      NS_LITERAL_STRING("Connect")))) {
   136     aController->NotifyCompletion(NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
   137     return;
   138   }
   139 }
   141 void
   142 BluetoothHidManager::Disconnect(BluetoothProfileController* aController)
   143 {
   144   MOZ_ASSERT(NS_IsMainThread());
   146   BluetoothService* bs = BluetoothService::Get();
   147   if (!bs) {
   148     if (aController) {
   149       aController->NotifyCompletion(NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
   150     }
   151     return;
   152   }
   154   if (!mConnected) {
   155     if (aController) {
   156       aController->NotifyCompletion(NS_LITERAL_STRING(ERR_ALREADY_DISCONNECTED));
   157     }
   158     return;
   159   }
   161   MOZ_ASSERT(!mDeviceAddress.IsEmpty());
   162   MOZ_ASSERT(!mController);
   164   mController = aController;
   166   if (NS_FAILED(bs->SendInputMessage(mDeviceAddress,
   167                                      NS_LITERAL_STRING("Disconnect")))) {
   168     aController->NotifyCompletion(NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
   169     return;
   170   }
   171 }
   173 void
   174 BluetoothHidManager::OnConnect(const nsAString& aErrorStr)
   175 {
   176   MOZ_ASSERT(NS_IsMainThread());
   178   /**
   179    * On the one hand, notify the controller that we've done for outbound
   180    * connections. On the other hand, we do nothing for inbound connections.
   181    */
   182   NS_ENSURE_TRUE_VOID(mController);
   184   nsRefPtr<BluetoothProfileController> controller = mController.forget();
   185   controller->NotifyCompletion(aErrorStr);
   186 }
   188 void
   189 BluetoothHidManager::OnDisconnect(const nsAString& aErrorStr)
   190 {
   191   MOZ_ASSERT(NS_IsMainThread());
   193   /**
   194    * On the one hand, notify the controller that we've done for outbound
   195    * connections. On the other hand, we do nothing for inbound connections.
   196    */
   197   NS_ENSURE_TRUE_VOID(mController);
   199   nsRefPtr<BluetoothProfileController> controller = mController.forget();
   200   controller->NotifyCompletion(aErrorStr);
   201 }
   203 bool
   204 BluetoothHidManager::IsConnected()
   205 {
   206   return mConnected;
   207 }
   209 void
   210 BluetoothHidManager::HandleInputPropertyChanged(const BluetoothSignal& aSignal)
   211 {
   212   MOZ_ASSERT(NS_IsMainThread());
   213   MOZ_ASSERT(aSignal.value().type() == BluetoothValue::TArrayOfBluetoothNamedValue);
   215   const InfallibleTArray<BluetoothNamedValue>& arr =
   216     aSignal.value().get_ArrayOfBluetoothNamedValue();
   217   MOZ_ASSERT(arr.Length() == 1);
   219   const nsString& name = arr[0].name();
   220   const BluetoothValue& value = arr[0].value();
   222   if (name.EqualsLiteral("Connected")) {
   223     MOZ_ASSERT(value.type() == BluetoothValue::Tbool);
   224     MOZ_ASSERT(mConnected != value.get_bool());
   226     mConnected = value.get_bool();
   227     NotifyStatusChanged();
   228     if (mConnected) {
   229       OnConnect(EmptyString());
   230     } else {
   231       OnDisconnect(EmptyString());
   232     }
   233   }
   234 }
   236 void
   237 BluetoothHidManager::NotifyStatusChanged()
   238 {
   239   MOZ_ASSERT(NS_IsMainThread());
   241   NS_NAMED_LITERAL_STRING(type, BLUETOOTH_HID_STATUS_CHANGED_ID);
   242   InfallibleTArray<BluetoothNamedValue> parameters;
   244   BT_APPEND_NAMED_VALUE(parameters, "connected", mConnected);
   245   BT_APPEND_NAMED_VALUE(parameters, "address", mDeviceAddress);
   247   BT_ENSURE_TRUE_VOID_BROADCAST_SYSMSG(type, parameters);
   248 }
   250 void
   251 BluetoothHidManager::OnGetServiceChannel(const nsAString& aDeviceAddress,
   252                                          const nsAString& aServiceUuid,
   253                                          int aChannel)
   254 {
   255   // Do nothing here as bluez acquires service channel and connects for us
   256 }
   258 void
   259 BluetoothHidManager::OnUpdateSdpRecords(const nsAString& aDeviceAddress)
   260 {
   261   // Do nothing here as bluez acquires service channel and connects for us
   262 }
   264 void
   265 BluetoothHidManager::GetAddress(nsAString& aDeviceAddress)
   266 {
   267   aDeviceAddress = mDeviceAddress;
   268 }
   270 NS_IMPL_ISUPPORTS(BluetoothHidManager, nsIObserver)

mercurial