gecko/dom/bluetooth2/bluedroid/BluetoothGattManager.cpp

322 lines
8.1 KiB
C++

/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BluetoothGattManager.h"
#include "BluetoothCommon.h"
#include "BluetoothUtils.h"
#include "BluetoothInterface.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPtr.h"
#include "MainThreadUtils.h"
#include "nsIObserverService.h"
#include "nsThreadUtils.h"
using namespace mozilla;
USING_BLUETOOTH_NAMESPACE
namespace {
StaticRefPtr<BluetoothGattManager> sBluetoothGattManager;
static BluetoothGattInterface* sBluetoothGattInterface;
static BluetoothGattClientInterface* sBluetoothGattClientInterface;
} // anonymous namespace
bool BluetoothGattManager::mInShutdown = false;
/*
* Static functions
*/
BluetoothGattManager*
BluetoothGattManager::Get()
{
MOZ_ASSERT(NS_IsMainThread());
// If sBluetoothGattManager already exists, exit early
if (sBluetoothGattManager) {
return sBluetoothGattManager;
}
// If we're in shutdown, don't create a new instance
NS_ENSURE_FALSE(mInShutdown, nullptr);
// Create a new instance, register, and return
BluetoothGattManager* manager = new BluetoothGattManager();
sBluetoothGattManager = manager;
return sBluetoothGattManager;
}
class InitGattResultHandler MOZ_FINAL : public BluetoothGattResultHandler
{
public:
InitGattResultHandler(BluetoothProfileResultHandler* aRes)
: mRes(aRes)
{ }
void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
{
BT_WARNING("BluetoothGattInterface::Init failed: %d",
(int)aStatus);
if (mRes) {
mRes->OnError(NS_ERROR_FAILURE);
}
}
void Init() MOZ_OVERRIDE
{
if (mRes) {
mRes->Init();
}
}
private:
nsRefPtr<BluetoothProfileResultHandler> mRes;
};
// static
void
BluetoothGattManager::InitGattInterface(BluetoothProfileResultHandler* aRes)
{
BluetoothInterface* btInf = BluetoothInterface::GetInstance();
if (!btInf) {
BT_LOGR("Error: Bluetooth interface not available");
if (aRes) {
aRes->OnError(NS_ERROR_FAILURE);
}
return;
}
sBluetoothGattInterface = btInf->GetBluetoothGattInterface();
if (!sBluetoothGattInterface) {
BT_LOGR("Error: Bluetooth GATT interface not available");
if (aRes) {
aRes->OnError(NS_ERROR_FAILURE);
}
return;
}
sBluetoothGattClientInterface =
sBluetoothGattInterface->GetBluetoothGattClientInterface();
NS_ENSURE_TRUE_VOID(sBluetoothGattClientInterface);
BluetoothGattManager* gattManager = BluetoothGattManager::Get();
sBluetoothGattInterface->Init(gattManager,
new InitGattResultHandler(aRes));
}
class CleanupResultHandler MOZ_FINAL : public BluetoothGattResultHandler
{
public:
CleanupResultHandler(BluetoothProfileResultHandler* aRes)
: mRes(aRes)
{ }
void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
{
BT_WARNING("BluetoothGattInterface::Cleanup failed: %d",
(int)aStatus);
if (mRes) {
mRes->OnError(NS_ERROR_FAILURE);
}
}
void Cleanup() MOZ_OVERRIDE
{
sBluetoothGattClientInterface = nullptr;
sBluetoothGattInterface = nullptr;
if (mRes) {
mRes->Deinit();
}
}
private:
nsRefPtr<BluetoothProfileResultHandler> mRes;
};
class CleanupResultHandlerRunnable MOZ_FINAL : public nsRunnable
{
public:
CleanupResultHandlerRunnable(BluetoothProfileResultHandler* aRes)
: mRes(aRes)
{
MOZ_ASSERT(mRes);
}
NS_IMETHOD Run() MOZ_OVERRIDE
{
mRes->Deinit();
return NS_OK;
}
private:
nsRefPtr<BluetoothProfileResultHandler> mRes;
};
// static
void
BluetoothGattManager::DeinitGattInterface(BluetoothProfileResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
if (sBluetoothGattInterface) {
sBluetoothGattInterface->Cleanup(new CleanupResultHandler(aRes));
} else if (aRes) {
// We dispatch a runnable here to make the profile resource handler
// behave as if GATT was initialized.
nsRefPtr<nsRunnable> r = new CleanupResultHandlerRunnable(aRes);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch cleanup-result-handler runnable");
}
}
}
//
// Notification Handlers
//
void
BluetoothGattManager::RegisterClientNotification(int aStatus,
int aClientIf,
const BluetoothUuid& aAppUuid)
{ }
void
BluetoothGattManager::ScanResultNotification(
const nsAString& aBdAddr, int aRssi,
const BluetoothGattAdvData& aAdvData)
{ }
void
BluetoothGattManager::ConnectNotification(int aConnId,
int aStatus,
int aClientIf,
const nsAString& aBdAddr)
{ }
void
BluetoothGattManager::DisconnectNotification(int aConnId,
int aStatus,
int aClientIf,
const nsAString& aBdAddr)
{ }
void
BluetoothGattManager::SearchCompleteNotification(int aConnId, int aStatus)
{ }
void
BluetoothGattManager::SearchResultNotification(
int aConnId, const BluetoothGattServiceId& aServiceId)
{ }
void
BluetoothGattManager::GetCharacteristicNotification(
int aConnId, int aStatus,
const BluetoothGattServiceId& aServiceId,
const BluetoothGattId& aCharId,
int aCharProperty)
{ }
void
BluetoothGattManager::GetDescriptorNotification(
int aConnId, int aStatus,
const BluetoothGattServiceId& aServiceId,
const BluetoothGattId& aCharId,
const BluetoothGattId& aDescriptorId)
{ }
void
BluetoothGattManager::GetIncludedServiceNotification(
int aConnId, int aStatus,
const BluetoothGattServiceId& aServiceId,
const BluetoothGattServiceId& aIncludedServId)
{ }
void
BluetoothGattManager::RegisterNotificationNotification(
int aConnId, int aIsRegister, int aStatus,
const BluetoothGattServiceId& aServiceId,
const BluetoothGattId& aCharId)
{ }
void
BluetoothGattManager::NotifyNotification(
int aConnId, const BluetoothGattNotifyParam& aNotifyParam)
{ }
void
BluetoothGattManager::ReadCharacteristicNotification(
int aConnId, int aStatus, const BluetoothGattReadParam& aReadParam)
{ }
void
BluetoothGattManager::WriteCharacteristicNotification(
int aConnId, int aStatus, const BluetoothGattWriteParam& aWriteParam)
{ }
void
BluetoothGattManager::ReadDescriptorNotification(
int aConnId, int aStatus, const BluetoothGattReadParam& aReadParam)
{ }
void
BluetoothGattManager::WriteDescriptorNotification(
int aConnId, int aStatus, const BluetoothGattWriteParam& aWriteParam)
{ }
void
BluetoothGattManager::ExecuteWriteNotification(int aConnId, int aStatus)
{ }
void
BluetoothGattManager::ReadRemoteRssiNotification(int aClientIf,
const nsAString& aBdAddr,
int aRssi,
int aStatus)
{ }
void
BluetoothGattManager::ListenNotification(int aStatus,
int aServerIf)
{ }
BluetoothGattManager::BluetoothGattManager()
{ }
BluetoothGattManager::~BluetoothGattManager()
{
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
NS_ENSURE_TRUE_VOID(obs);
if (NS_FAILED(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))) {
BT_WARNING("Failed to remove shutdown observer!");
}
}
NS_IMETHODIMP
BluetoothGattManager::Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData)
{
MOZ_ASSERT(sBluetoothGattManager);
if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
HandleShutdown();
return NS_OK;
}
MOZ_ASSERT(false, "BluetoothGattManager got unexpected topic!");
return NS_ERROR_UNEXPECTED;
}
void
BluetoothGattManager::HandleShutdown()
{
MOZ_ASSERT(NS_IsMainThread());
mInShutdown = true;
sBluetoothGattManager = nullptr;
}
NS_IMPL_ISUPPORTS(BluetoothGattManager, nsIObserver)