Bug 969314: Merge BluetoothGonkService into BluetoothDBusService, r=echou

This patch merges the code from BluetoothGonkService into
BluetoothDBusService. The merged code is protected by ifdef
statements.
This commit is contained in:
Thomas Zimmermann 2014-02-13 16:28:07 +01:00
parent 333cb63fc2
commit e5ec01aca8
5 changed files with 122 additions and 233 deletions

View File

@ -47,7 +47,7 @@
* B2G blueZ:
* MOZ_B2G_BT and MOZ_B2G_BT_BLUEZ are both defined.
*/
#include "BluetoothGonkService.h"
#include "BluetoothDBusService.h"
#elif defined(MOZ_B2G_BT_BLUEDROID)
/**
* B2G bluedroid:
@ -315,7 +315,7 @@ BluetoothService::Create()
}
#if defined(MOZ_B2G_BT_BLUEZ)
return new BluetoothGonkService();
return new BluetoothDBusService();
#elif defined(MOZ_B2G_BT_BLUEDROID)
return new BluetoothServiceBluedroid();
#endif

View File

@ -1,165 +0,0 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* Copyright 2012 Mozilla Foundation and Mozilla contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "base/basictypes.h"
#include "BluetoothGonkService.h"
#include "BluetoothDBusService.h"
#include "nsDebug.h"
#include "nsError.h"
#include "nsThreadUtils.h"
#include <dlfcn.h>
USING_BLUETOOTH_NAMESPACE
static struct BluedroidFunctions
{
bool initialized;
BluedroidFunctions() :
initialized(false)
{
}
int (* bt_enable)();
int (* bt_disable)();
int (* bt_is_enabled)();
} sBluedroidFunctions;
static bool
EnsureBluetoothInit()
{
if (sBluedroidFunctions.initialized) {
return true;
}
void* handle = dlopen("libbluedroid.so", RTLD_LAZY);
if (!handle) {
NS_ERROR("Failed to open libbluedroid.so, bluetooth cannot run");
return false;
}
sBluedroidFunctions.bt_enable = (int (*)())dlsym(handle, "bt_enable");
if (!sBluedroidFunctions.bt_enable) {
NS_ERROR("Failed to attach bt_enable function");
return false;
}
sBluedroidFunctions.bt_disable = (int (*)())dlsym(handle, "bt_disable");
if (!sBluedroidFunctions.bt_disable) {
NS_ERROR("Failed to attach bt_disable function");
return false;
}
sBluedroidFunctions.bt_is_enabled = (int (*)())dlsym(handle, "bt_is_enabled");
if (!sBluedroidFunctions.bt_is_enabled) {
NS_ERROR("Failed to attach bt_is_enabled function");
return false;
}
sBluedroidFunctions.initialized = true;
return true;
}
static nsresult
StartStopGonkBluetooth(bool aShouldEnable)
{
bool result;
// Platform specific check for gonk until object is divided in
// different implementations per platform. Linux doesn't require
// bluetooth firmware loading, but code should work otherwise.
if (!EnsureBluetoothInit()) {
NS_ERROR("Failed to load bluedroid library.\n");
return NS_ERROR_FAILURE;
}
// return 1 if it's enabled, 0 if it's disabled, and -1 on error
int isEnabled = sBluedroidFunctions.bt_is_enabled();
if ((isEnabled == 1 && aShouldEnable) || (isEnabled == 0 && !aShouldEnable)) {
return NS_OK;
}
if (aShouldEnable) {
result = (sBluedroidFunctions.bt_enable() == 0) ? true : false;
if (sBluedroidFunctions.bt_is_enabled() < 0) {
// if isEnabled < 0, this means we brought up the firmware, but something
// went wrong with bluetoothd. Post a warning message, but try to proceed
// with firmware unloading if that was requested, so we can retry later.
BT_WARNING("Bluetooth firmware up, but cannot connect to HCI socket! "
"Check bluetoothd and try stopping/starting bluetooth again.");
// Just disable now, return an error.
if (sBluedroidFunctions.bt_disable() != 0) {
BT_WARNING("Problem shutting down bluetooth after error in bringup!");
}
return NS_ERROR_FAILURE;
}
} else {
result = (sBluedroidFunctions.bt_disable() == 0) ? true : false;
}
if (!result) {
BT_WARNING("Could not set gonk bluetooth firmware!");
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
BluetoothGonkService::StartInternal()
{
MOZ_ASSERT(!NS_IsMainThread());
nsresult ret;
ret = StartStopGonkBluetooth(true);
if (NS_FAILED(ret)) {
return ret;
}
return BluetoothDBusService::StartInternal();
}
nsresult
BluetoothGonkService::StopInternal()
{
MOZ_ASSERT(!NS_IsMainThread());
nsresult ret;
ret = BluetoothDBusService::StopInternal();
if (NS_FAILED(ret)) {
return ret;
}
return StartStopGonkBluetooth(false);
}
bool
BluetoothGonkService::IsEnabledInternal()
{
MOZ_ASSERT(!NS_IsMainThread());
if (!EnsureBluetoothInit()) {
NS_ERROR("Failed to load bluedroid library.\n");
return false;
}
return (sBluedroidFunctions.bt_is_enabled() == 1);
}

View File

@ -1,64 +0,0 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* Copyright 2012 Mozilla Foundation and Mozilla contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef mozilla_dom_bluetooth_bluetoothgonkservice_h__
#define mozilla_dom_bluetooth_bluetoothgonkservice_h__
#include "mozilla/Attributes.h"
#include "BluetoothCommon.h"
#include "BluetoothDBusService.h"
BEGIN_BLUETOOTH_NAMESPACE
/**
* BluetoothService functions are used to dispatch messages to Bluetooth DOM
* objects on the main thread, as well as provide platform independent access
* to BT functionality. Tasks for polling for outside messages will usually
* happen on the IO Thread (see ipc/dbus for instance), and these messages will
* be encased in runnables that will then be distributed via observers managed
* here.
*/
class BluetoothGonkService : public BluetoothDBusService
{
public:
/**
* Set up variables and start the platform specific connection. Must
* be called from non-main thread.
*
* @return NS_OK if connection starts successfully, NS_ERROR_FAILURE otherwise
*/
virtual nsresult StartInternal() MOZ_OVERRIDE;
/**
* Stop the platform specific connection. Must be called from non-main thread.
*
* @return NS_OK if connection starts successfully, NS_ERROR_FAILURE otherwise
*/
virtual nsresult StopInternal() MOZ_OVERRIDE;
/**
* Get status of Bluetooth. Must be called from non-main thread.
*
* @return true if Bluetooth is enabled, false otherwise
*/
virtual bool IsEnabledInternal() MOZ_OVERRIDE;
};
END_BLUETOOTH_NAMESPACE
#endif

View File

@ -49,6 +49,7 @@
#if defined(MOZ_WIDGET_GONK)
#include "cutils/properties.h"
#include <dlfcn.h>
#endif
/**
@ -87,6 +88,56 @@ USING_BLUETOOTH_NAMESPACE
*/
#define TIMEOUT_FORCE_TO_DISABLE_BT 5
#ifdef MOZ_WIDGET_GONK
static struct BluedroidFunctions
{
bool initialized;
BluedroidFunctions() :
initialized(false)
{
}
int (* bt_enable)();
int (* bt_disable)();
int (* bt_is_enabled)();
} sBluedroidFunctions;
static bool
EnsureBluetoothInit()
{
if (sBluedroidFunctions.initialized) {
return true;
}
void* handle = dlopen("libbluedroid.so", RTLD_LAZY);
if (!handle) {
NS_ERROR("Failed to open libbluedroid.so, bluetooth cannot run");
return false;
}
sBluedroidFunctions.bt_enable = (int (*)())dlsym(handle, "bt_enable");
if (!sBluedroidFunctions.bt_enable) {
NS_ERROR("Failed to attach bt_enable function");
return false;
}
sBluedroidFunctions.bt_disable = (int (*)())dlsym(handle, "bt_disable");
if (!sBluedroidFunctions.bt_disable) {
NS_ERROR("Failed to attach bt_disable function");
return false;
}
sBluedroidFunctions.bt_is_enabled = (int (*)())dlsym(handle, "bt_is_enabled");
if (!sBluedroidFunctions.bt_is_enabled) {
NS_ERROR("Failed to attach bt_is_enabled function");
return false;
}
sBluedroidFunctions.initialized = true;
return true;
}
#endif
typedef struct {
const char* name;
int type;
@ -1732,12 +1783,66 @@ BluetoothDBusService::IsReady()
return true;
}
#if MOZ_WIDGET_GONK
static nsresult
StartStopGonkBluetooth(bool aShouldEnable)
{
bool result;
// Platform specific check for gonk until object is divided in
// different implementations per platform. Linux doesn't require
// bluetooth firmware loading, but code should work otherwise.
if (!EnsureBluetoothInit()) {
NS_ERROR("Failed to load bluedroid library.\n");
return NS_ERROR_FAILURE;
}
// return 1 if it's enabled, 0 if it's disabled, and -1 on error
int isEnabled = sBluedroidFunctions.bt_is_enabled();
if ((isEnabled == 1 && aShouldEnable) || (isEnabled == 0 && !aShouldEnable)) {
return NS_OK;
}
if (aShouldEnable) {
result = (sBluedroidFunctions.bt_enable() == 0) ? true : false;
if (sBluedroidFunctions.bt_is_enabled() < 0) {
// if isEnabled < 0, this means we brought up the firmware, but something
// went wrong with bluetoothd. Post a warning message, but try to proceed
// with firmware unloading if that was requested, so we can retry later.
BT_WARNING("Bluetooth firmware up, but cannot connect to HCI socket! "
"Check bluetoothd and try stopping/starting bluetooth again.");
// Just disable now, return an error.
if (sBluedroidFunctions.bt_disable() != 0) {
BT_WARNING("Problem shutting down bluetooth after error in bringup!");
}
return NS_ERROR_FAILURE;
}
} else {
result = (sBluedroidFunctions.bt_disable() == 0) ? true : false;
}
if (!result) {
BT_WARNING("Could not set gonk bluetooth firmware!");
return NS_ERROR_FAILURE;
}
return NS_OK;
}
#endif
nsresult
BluetoothDBusService::StartInternal()
{
// This could block. It should never be run on the main thread.
MOZ_ASSERT(!NS_IsMainThread());
#ifdef MOZ_WIDGET_GONK
nsresult ret = StartStopGonkBluetooth(true);
if (NS_FAILED(ret)) {
return ret;
}
#endif
if (!StartDBus()) {
BT_WARNING("Cannot start DBus thread!");
return NS_ERROR_FAILURE;
@ -1858,13 +1963,28 @@ BluetoothDBusService::StopInternal()
sControllerArray.Clear();
StopDBus();
#ifdef MOZ_WIDGET_GONK
return StartStopGonkBluetooth(false);
#else
return NS_OK;
#endif
}
bool
BluetoothDBusService::IsEnabledInternal()
{
#ifdef MOZ_WIDGET_GONK
MOZ_ASSERT(!NS_IsMainThread());
if (!EnsureBluetoothInit()) {
NS_ERROR("Failed to load bluedroid library.\n");
return false;
}
return (sBluedroidFunctions.bt_is_enabled() == 1);
#else
return mEnabled;
#endif
}
class DefaultAdapterPathReplyHandler : public DBusReplyHandler

View File

@ -35,12 +35,10 @@ if CONFIG['MOZ_B2G_BT']:
'bluez/BluetoothSocket.cpp',
'bluez/BluetoothUnixSocketConnector.cpp',
'bluez/BluetoothUtils.cpp',
'bluez/gonk/BluetoothGonkService.cpp',
'bluez/linux/BluetoothDBusService.cpp',
]
LOCAL_INCLUDES += [
'bluez',
'bluez/gonk',
'bluez/linux',
]
DEFINES['MOZ_B2G_BT_BLUEZ'] = True