Bug 891257 - Disconnect gracefully when the user turns off Bluetooth, r=mrbkap

This commit is contained in:
Eric Chou 2013-08-08 17:51:37 +08:00
Родитель b70e29eef3
Коммит 602b30d510
2 изменённых файлов: 43 добавлений и 8 удалений

Просмотреть файл

@ -9,7 +9,9 @@
#include "BluetoothService.h"
#include "BluetoothCommon.h"
#include "BluetoothHfpManager.h"
#include "BluetoothManager.h"
#include "BluetoothOppManager.h"
#include "BluetoothParent.h"
#include "BluetoothReplyRunnable.h"
#include "BluetoothServiceChildProcess.h"
@ -475,6 +477,14 @@ BluetoothService::StartStopBluetooth(bool aStart, bool aIsStartup)
NS_ENSURE_SUCCESS(rv, rv);
}
if (!aStart) {
BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
hfp->Disconnect();
BluetoothOppManager* opp = BluetoothOppManager::Get();
opp->Disconnect();
}
nsCOMPtr<nsIRunnable> runnable = new ToggleBtTask(aStart, aIsStartup);
rv = mBluetoothCommandThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
NS_ENSURE_SUCCESS(rv, rv);

Просмотреть файл

@ -34,14 +34,16 @@
#include "nsDebug.h"
#include "nsDataHashtable.h"
#include "mozilla/Atomics.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/Hal.h"
#include "mozilla/ipc/UnixSocket.h"
#include "mozilla/ipc/DBusThread.h"
#include "mozilla/ipc/DBusUtils.h"
#include "mozilla/ipc/RawDBusConnection.h"
#include "mozilla/Util.h"
#include "mozilla/Mutex.h"
#include "mozilla/NullPtr.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/StaticMutex.h"
#include "mozilla/Util.h"
#if defined(MOZ_WIDGET_GONK)
#include "cutils/properties.h"
#endif
@ -75,6 +77,13 @@ USING_BLUETOOTH_NAMESPACE
#define ERR_AVRCP_IS_DISCONNECTED "AvrcpIsDisconnected"
#define ERR_UNKNOWN_PROFILE "UnknownProfileError"
/**
* To not lock Bluetooth switch button on Settings UI because of any accident,
* we will force disabling Bluetooth 5 seconds after the user requesting to
* turn off Bluetooth.
*/
#define TIMEOUT_FORCE_TO_DISABLE_BT 5
typedef struct {
const char* name;
int type;
@ -159,8 +168,10 @@ static const char* sBluetoothDBusSignals[] =
static nsRefPtr<RawDBusConnection> gThreadConnection;
static nsDataHashtable<nsStringHashKey, DBusMessage* > sPairingReqTable;
static nsDataHashtable<nsStringHashKey, DBusMessage* > sAuthorizeReqTable;
static Atomic<int32_t> sIsPairing;
static nsString sAdapterPath;
static Atomic<int32_t> sIsPairing(0);
static int sConnectedDeviceCount = 0;
static Monitor sStopBluetoothMonitor("BluetoothService.sStopBluetoothMonitor");
typedef void (*UnpackFunc)(DBusMessage*, DBusError*, BluetoothValue&, nsAString&);
typedef bool (*FilterFunc)(const BluetoothValue&);
@ -1499,6 +1510,19 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
signal.path() = NS_LITERAL_STRING(KEY_ADAPTER);
signal.value() = parameters;
NS_DispatchToMainThread(new DistributeBluetoothSignalTask(signal));
} else if (property.name().EqualsLiteral("Connected")) {
MonitorAutoLock lock(sStopBluetoothMonitor);
if (property.value().get_bool()) {
++sConnectedDeviceCount;
} else {
MOZ_ASSERT(sConnectedDeviceCount > 0);
--sConnectedDeviceCount;
if (sConnectedDeviceCount == 0) {
lock.Notify();
}
}
}
} else if (dbus_message_is_signal(aMsg, DBUS_MANAGER_IFACE, "AdapterAdded")) {
const char* str;
@ -1689,11 +1713,11 @@ BluetoothDBusService::StopInternal()
// This could block. It should never be run on the main thread.
MOZ_ASSERT(!NS_IsMainThread());
// If Bluetooth is turned off while connections exist, in order not to only
// disconnect with profile connections with low level ACL connections alive,
// we disconnect ACLs directly instead of closing each socket.
if (!sAdapterPath.IsEmpty()) {
DisconnectAllAcls(sAdapterPath);
{
MonitorAutoLock lock(sStopBluetoothMonitor);
if (sConnectedDeviceCount > 0) {
lock.Wait(PR_SecondsToInterval(TIMEOUT_FORCE_TO_DISABLE_BT));
}
}
if (!mConnection) {
@ -1737,6 +1761,7 @@ BluetoothDBusService::StopInternal()
sAuthorizeReqTable.Clear();
sIsPairing = 0;
sConnectedDeviceCount = 0;
StopDBus();
return NS_OK;