mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1063066 - [Flame][KK] Bluetooth transfer does not work in Gallery App. r=tzimmermann
This commit is contained in:
parent
4d79d2b206
commit
515bb0d108
@ -54,6 +54,8 @@ public:
|
||||
|
||||
virtual void Accept(int aFd, BluetoothSocketResultHandler* aRes) = 0;
|
||||
|
||||
virtual void Close(BluetoothSocketResultHandler* aRes) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~BluetoothSocketInterface();
|
||||
};
|
||||
|
@ -395,7 +395,10 @@ public:
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(sBluetoothSocketInterface);
|
||||
|
||||
sBluetoothSocketInterface->Accept(mFd, new AcceptResultHandler(GetIO()));
|
||||
BluetoothSocketResultHandler* res = new AcceptResultHandler(GetIO());
|
||||
GetIO()->mConsumer->SetCurrentResultHandler(res);
|
||||
|
||||
sBluetoothSocketInterface->Accept(mFd, res);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -476,6 +479,7 @@ BluetoothSocket::BluetoothSocket(BluetoothSocketObserver* aObserver,
|
||||
bool aAuth,
|
||||
bool aEncrypt)
|
||||
: mObserver(aObserver)
|
||||
, mCurrentRes(nullptr)
|
||||
, mImpl(nullptr)
|
||||
, mAuth(aAuth)
|
||||
, mEncrypt(aEncrypt)
|
||||
@ -527,13 +531,15 @@ BluetoothSocket::ConnectSocket(const nsAString& aDeviceAddress, int aChannel)
|
||||
|
||||
mImpl = new DroidSocketImpl(XRE_GetIOMessageLoop(), this);
|
||||
|
||||
BluetoothSocketResultHandler* res = new ConnectSocketResultHandler(mImpl);
|
||||
SetCurrentResultHandler(res);
|
||||
|
||||
// TODO: uuid as argument
|
||||
sBluetoothSocketInterface->Connect(
|
||||
aDeviceAddress,
|
||||
BluetoothSocketType::RFCOMM,
|
||||
UUID_OBEX_OBJECT_PUSH,
|
||||
aChannel, mEncrypt, mAuth,
|
||||
new ConnectSocketResultHandler(mImpl));
|
||||
aChannel, mEncrypt, mAuth, res);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -576,12 +582,14 @@ BluetoothSocket::ListenSocket(int aChannel)
|
||||
|
||||
mImpl = new DroidSocketImpl(XRE_GetIOMessageLoop(), this);
|
||||
|
||||
BluetoothSocketResultHandler* res = new ListenResultHandler(mImpl);
|
||||
SetCurrentResultHandler(res);
|
||||
|
||||
sBluetoothSocketInterface->Listen(
|
||||
BluetoothSocketType::RFCOMM,
|
||||
NS_LITERAL_STRING("OBEX Object Push"),
|
||||
UUID_OBEX_OBJECT_PUSH,
|
||||
aChannel, mEncrypt, mAuth,
|
||||
new ListenResultHandler(mImpl));
|
||||
aChannel, mEncrypt, mAuth, res);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -590,10 +598,16 @@ void
|
||||
BluetoothSocket::CloseSocket()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(sBluetoothSocketInterface);
|
||||
if (!mImpl) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Stop any watching |SocketMessageWatcher|
|
||||
if (mCurrentRes) {
|
||||
sBluetoothSocketInterface->Close(mCurrentRes);
|
||||
}
|
||||
|
||||
// From this point on, we consider mImpl as being deleted.
|
||||
// We sever the relationship here so any future calls to listen or connect
|
||||
// will create a new implementation.
|
||||
@ -633,6 +647,8 @@ BluetoothSocket::OnConnectSuccess()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mObserver);
|
||||
|
||||
SetCurrentResultHandler(nullptr);
|
||||
mObserver->OnSocketConnectSuccess(this);
|
||||
}
|
||||
|
||||
@ -641,6 +657,8 @@ BluetoothSocket::OnConnectError()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mObserver);
|
||||
|
||||
SetCurrentResultHandler(nullptr);
|
||||
mObserver->OnSocketConnectError(this);
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
class BluetoothSocketObserver;
|
||||
class BluetoothSocketResultHandler;
|
||||
class DroidSocketImpl;
|
||||
|
||||
class BluetoothSocket : public mozilla::ipc::SocketConsumerBase
|
||||
@ -47,8 +48,14 @@ public:
|
||||
mDeviceAddress = aDeviceAddress;
|
||||
}
|
||||
|
||||
inline void SetCurrentResultHandler(BluetoothSocketResultHandler* aRes)
|
||||
{
|
||||
mCurrentRes = aRes;
|
||||
}
|
||||
|
||||
private:
|
||||
BluetoothSocketObserver* mObserver;
|
||||
BluetoothSocketResultHandler* mCurrentRes;
|
||||
DroidSocketImpl* mImpl;
|
||||
nsString mDeviceAddress;
|
||||
bool mAuth;
|
||||
|
@ -9,24 +9,25 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include "BluetoothHALHelpers.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
typedef
|
||||
BluetoothHALInterfaceRunnable1<BluetoothSocketResultHandler, void,
|
||||
int, int>
|
||||
int, int>
|
||||
BluetoothSocketHALIntResultRunnable;
|
||||
|
||||
typedef
|
||||
BluetoothHALInterfaceRunnable3<BluetoothSocketResultHandler, void,
|
||||
int, const nsString, int,
|
||||
int, const nsAString_internal&, int>
|
||||
int, const nsString, int,
|
||||
int, const nsAString_internal&, int>
|
||||
BluetoothSocketHALIntStringIntResultRunnable;
|
||||
|
||||
typedef
|
||||
BluetoothHALInterfaceRunnable1<BluetoothSocketResultHandler, void,
|
||||
BluetoothStatus, BluetoothStatus>
|
||||
BluetoothStatus, BluetoothStatus>
|
||||
BluetoothSocketHALErrorRunnable;
|
||||
|
||||
static nsresult
|
||||
@ -78,11 +79,11 @@ DispatchBluetoothSocketHALResult(
|
||||
|
||||
void
|
||||
BluetoothSocketHALInterface::Listen(BluetoothSocketType aType,
|
||||
const nsAString& aServiceName,
|
||||
const uint8_t aServiceUuid[16],
|
||||
int aChannel, bool aEncrypt,
|
||||
bool aAuth,
|
||||
BluetoothSocketResultHandler* aRes)
|
||||
const nsAString& aServiceName,
|
||||
const uint8_t aServiceUuid[16],
|
||||
int aChannel, bool aEncrypt,
|
||||
bool aAuth,
|
||||
BluetoothSocketResultHandler* aRes)
|
||||
{
|
||||
int fd;
|
||||
bt_status_t status;
|
||||
@ -109,6 +110,34 @@ BluetoothSocketHALInterface::Listen(BluetoothSocketType aType,
|
||||
( ((_cmsghdr)->cmsg_level == SOL_SOCKET) && \
|
||||
((_cmsghdr)->cmsg_type == SCM_RIGHTS) )
|
||||
|
||||
class SocketMessageWatcher;
|
||||
|
||||
/* |SocketMessageWatcherWrapper| wraps SocketMessageWatcher to keep it from
|
||||
* being released by hash table's Remove() method.
|
||||
*/
|
||||
class SocketMessageWatcherWrapper
|
||||
{
|
||||
public:
|
||||
SocketMessageWatcherWrapper(SocketMessageWatcher* aSocketMessageWatcher)
|
||||
: mSocketMessageWatcher(aSocketMessageWatcher)
|
||||
{
|
||||
MOZ_ASSERT(mSocketMessageWatcher);
|
||||
}
|
||||
|
||||
SocketMessageWatcher* GetSocketMessageWatcher()
|
||||
{
|
||||
return mSocketMessageWatcher;
|
||||
}
|
||||
|
||||
private:
|
||||
SocketMessageWatcher* mSocketMessageWatcher;
|
||||
};
|
||||
|
||||
/* |sWatcherHashTable| maps result handlers to corresponding watchers */
|
||||
static nsClassHashtable<nsRefPtrHashKey<BluetoothSocketResultHandler>,
|
||||
SocketMessageWatcherWrapper>
|
||||
sWatcherHashtable;
|
||||
|
||||
/* |SocketMessageWatcher| receives Bluedroid's socket setup
|
||||
* messages on the I/O thread. You need to inherit from this
|
||||
* class to make use of it.
|
||||
@ -135,11 +164,14 @@ public:
|
||||
static const unsigned char OFF_CHANNEL2 = 12;
|
||||
static const unsigned char OFF_STATUS = 16;
|
||||
|
||||
SocketMessageWatcher(int aFd)
|
||||
SocketMessageWatcher(int aFd, BluetoothSocketResultHandler* aRes)
|
||||
: mFd(aFd)
|
||||
, mClientFd(-1)
|
||||
, mLen(0)
|
||||
{ }
|
||||
, mRes(aRes)
|
||||
{
|
||||
MOZ_ASSERT(mRes);
|
||||
}
|
||||
|
||||
virtual ~SocketMessageWatcher()
|
||||
{ }
|
||||
@ -164,7 +196,7 @@ public:
|
||||
}
|
||||
|
||||
if (IsComplete() || status != STATUS_SUCCESS) {
|
||||
mWatcher.StopWatchingFileDescriptor();
|
||||
StopWatching();
|
||||
Proceed(status);
|
||||
}
|
||||
}
|
||||
@ -174,6 +206,9 @@ public:
|
||||
|
||||
void Watch()
|
||||
{
|
||||
// add this watcher and its result handler to hash table
|
||||
sWatcherHashtable.Put(mRes, new SocketMessageWatcherWrapper(this));
|
||||
|
||||
MessageLoopForIO::current()->WatchFileDescriptor(
|
||||
mFd,
|
||||
true,
|
||||
@ -182,6 +217,14 @@ public:
|
||||
this);
|
||||
}
|
||||
|
||||
void StopWatching()
|
||||
{
|
||||
mWatcher.StopWatchingFileDescriptor();
|
||||
|
||||
// remove this watcher and its result handler from hash table
|
||||
sWatcherHashtable.Remove(mRes);
|
||||
}
|
||||
|
||||
bool IsComplete() const
|
||||
{
|
||||
return mLen == (MSG1_SIZE + MSG2_SIZE);
|
||||
@ -224,6 +267,11 @@ public:
|
||||
return mClientFd;
|
||||
}
|
||||
|
||||
BluetoothSocketResultHandler* GetResultHandler() const
|
||||
{
|
||||
return mRes;
|
||||
}
|
||||
|
||||
private:
|
||||
BluetoothStatus RecvMsg1()
|
||||
{
|
||||
@ -322,6 +370,7 @@ private:
|
||||
int mClientFd;
|
||||
unsigned char mLen;
|
||||
uint8_t mBuf[MSG1_SIZE + MSG2_SIZE];
|
||||
nsRefPtr<BluetoothSocketResultHandler> mRes;
|
||||
};
|
||||
|
||||
/* |SocketMessageWatcherTask| starts a SocketMessageWatcher
|
||||
@ -373,32 +422,27 @@ class ConnectWatcher MOZ_FINAL : public SocketMessageWatcher
|
||||
{
|
||||
public:
|
||||
ConnectWatcher(int aFd, BluetoothSocketResultHandler* aRes)
|
||||
: SocketMessageWatcher(aFd)
|
||||
, mRes(aRes)
|
||||
: SocketMessageWatcher(aFd, aRes)
|
||||
{ }
|
||||
|
||||
void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
|
||||
{
|
||||
if (mRes) {
|
||||
DispatchBluetoothSocketHALResult(
|
||||
mRes, &BluetoothSocketResultHandler::Connect, GetFd(),
|
||||
GetBdAddress(), GetConnectionStatus(), aStatus);
|
||||
}
|
||||
DispatchBluetoothSocketHALResult(
|
||||
GetResultHandler(), &BluetoothSocketResultHandler::Connect,
|
||||
GetFd(), GetBdAddress(), GetConnectionStatus(), aStatus);
|
||||
|
||||
MessageLoopForIO::current()->PostTask(
|
||||
FROM_HERE, new DeleteTask<ConnectWatcher>(this));
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<BluetoothSocketResultHandler> mRes;
|
||||
};
|
||||
|
||||
void
|
||||
BluetoothSocketHALInterface::Connect(const nsAString& aBdAddr,
|
||||
BluetoothSocketType aType,
|
||||
const uint8_t aUuid[16],
|
||||
int aChannel, bool aEncrypt,
|
||||
bool aAuth,
|
||||
BluetoothSocketResultHandler* aRes)
|
||||
BluetoothSocketType aType,
|
||||
const uint8_t aUuid[16],
|
||||
int aChannel, bool aEncrypt,
|
||||
bool aAuth,
|
||||
BluetoothSocketResultHandler* aRes)
|
||||
{
|
||||
int fd;
|
||||
bt_status_t status;
|
||||
@ -425,10 +469,10 @@ BluetoothSocketHALInterface::Connect(const nsAString& aBdAddr,
|
||||
}
|
||||
}
|
||||
|
||||
/* Specializes SocketMessageWatcher for Accept operations by
|
||||
* reading the socket messages from Bluedroid and forwarding
|
||||
* the received client socket to the resource handler. The
|
||||
* first message is received immediately. When there's a new
|
||||
/* |AcceptWatcher| specializes SocketMessageWatcher for Accept
|
||||
* operations by reading the socket messages from Bluedroid and
|
||||
* forwarding the received client socket to the resource handler.
|
||||
* The first message is received immediately. When there's a new
|
||||
* connection, Bluedroid sends the 2nd message with the socket
|
||||
* info and socket file descriptor.
|
||||
*/
|
||||
@ -436,37 +480,69 @@ class AcceptWatcher MOZ_FINAL : public SocketMessageWatcher
|
||||
{
|
||||
public:
|
||||
AcceptWatcher(int aFd, BluetoothSocketResultHandler* aRes)
|
||||
: SocketMessageWatcher(aFd)
|
||||
, mRes(aRes)
|
||||
{
|
||||
/* not supplying a result handler leaks received file descriptor */
|
||||
MOZ_ASSERT(mRes);
|
||||
}
|
||||
: SocketMessageWatcher(aFd, aRes)
|
||||
{ }
|
||||
|
||||
void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
|
||||
{
|
||||
if (mRes) {
|
||||
DispatchBluetoothSocketHALResult(
|
||||
mRes, &BluetoothSocketResultHandler::Accept, GetClientFd(),
|
||||
GetBdAddress(), GetConnectionStatus(), aStatus);
|
||||
}
|
||||
DispatchBluetoothSocketHALResult(
|
||||
GetResultHandler(), &BluetoothSocketResultHandler::Accept,
|
||||
GetClientFd(), GetBdAddress(), GetConnectionStatus(), aStatus);
|
||||
|
||||
MessageLoopForIO::current()->PostTask(
|
||||
FROM_HERE, new DeleteTask<AcceptWatcher>(this));
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<BluetoothSocketResultHandler> mRes;
|
||||
};
|
||||
|
||||
void
|
||||
BluetoothSocketHALInterface::Accept(int aFd,
|
||||
BluetoothSocketResultHandler* aRes)
|
||||
BluetoothSocketResultHandler* aRes)
|
||||
{
|
||||
/* receive Bluedroid's socket-setup messages and client fd */
|
||||
Task* t = new SocketMessageWatcherTask(new AcceptWatcher(aFd, aRes));
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
|
||||
}
|
||||
|
||||
/* |DeleteSocketMessageWatcherTask| deletes a watching SocketMessageWatcher
|
||||
* on the I/O task
|
||||
*/
|
||||
class DeleteSocketMessageWatcherTask MOZ_FINAL : public Task
|
||||
{
|
||||
public:
|
||||
DeleteSocketMessageWatcherTask(BluetoothSocketResultHandler* aRes)
|
||||
: mRes(aRes)
|
||||
{
|
||||
MOZ_ASSERT(mRes);
|
||||
}
|
||||
|
||||
void Run() MOZ_OVERRIDE
|
||||
{
|
||||
// look up hash table for the watcher corresponding to |mRes|
|
||||
SocketMessageWatcherWrapper* wrapper = sWatcherHashtable.Get(mRes);
|
||||
if (!wrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
// stop the watcher if it exists
|
||||
SocketMessageWatcher* watcher = wrapper->GetSocketMessageWatcher();
|
||||
watcher->StopWatching();
|
||||
watcher->Proceed(STATUS_DONE);
|
||||
}
|
||||
|
||||
private:
|
||||
BluetoothSocketResultHandler* mRes;
|
||||
};
|
||||
|
||||
void
|
||||
BluetoothSocketHALInterface::Close(BluetoothSocketResultHandler* aRes)
|
||||
{
|
||||
MOZ_ASSERT(aRes);
|
||||
|
||||
/* stop the watcher corresponding to |aRes| */
|
||||
Task* t = new DeleteSocketMessageWatcherTask(aRes);
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
|
||||
}
|
||||
|
||||
BluetoothSocketHALInterface::BluetoothSocketHALInterface(
|
||||
const btsock_interface_t* aInterface)
|
||||
: mInterface(aInterface)
|
||||
|
@ -36,6 +36,8 @@ public:
|
||||
|
||||
void Accept(int aFd, BluetoothSocketResultHandler* aRes);
|
||||
|
||||
void Close(BluetoothSocketResultHandler* aRes);
|
||||
|
||||
protected:
|
||||
BluetoothSocketHALInterface(const btsock_interface_t* aInterface);
|
||||
~BluetoothSocketHALInterface();
|
||||
|
@ -54,6 +54,8 @@ public:
|
||||
|
||||
virtual void Accept(int aFd, BluetoothSocketResultHandler* aRes) = 0;
|
||||
|
||||
virtual void Close(BluetoothSocketResultHandler* aRes) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~BluetoothSocketInterface();
|
||||
};
|
||||
|
@ -182,7 +182,7 @@ MobileConnectionListener::Listen(bool aStart)
|
||||
NS_ENSURE_TRUE(service, false);
|
||||
|
||||
nsCOMPtr<nsIMobileConnection> connection;
|
||||
mcService->GetItemByServiceId(mClientId, getter_AddRefs(connection));
|
||||
service->GetItemByServiceId(mClientId, getter_AddRefs(connection));
|
||||
NS_ENSURE_TRUE(connection, false);
|
||||
|
||||
nsresult rv;
|
||||
|
@ -395,7 +395,10 @@ public:
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(sBluetoothSocketInterface);
|
||||
|
||||
sBluetoothSocketInterface->Accept(mFd, new AcceptResultHandler(GetIO()));
|
||||
BluetoothSocketResultHandler* res = new AcceptResultHandler(GetIO());
|
||||
GetIO()->mConsumer->SetCurrentResultHandler(res);
|
||||
|
||||
sBluetoothSocketInterface->Accept(mFd, res);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -476,6 +479,7 @@ BluetoothSocket::BluetoothSocket(BluetoothSocketObserver* aObserver,
|
||||
bool aAuth,
|
||||
bool aEncrypt)
|
||||
: mObserver(aObserver)
|
||||
, mCurrentRes(nullptr)
|
||||
, mImpl(nullptr)
|
||||
, mAuth(aAuth)
|
||||
, mEncrypt(aEncrypt)
|
||||
@ -527,13 +531,15 @@ BluetoothSocket::ConnectSocket(const nsAString& aDeviceAddress, int aChannel)
|
||||
|
||||
mImpl = new DroidSocketImpl(XRE_GetIOMessageLoop(), this);
|
||||
|
||||
BluetoothSocketResultHandler* res = new ConnectSocketResultHandler(mImpl);
|
||||
SetCurrentResultHandler(res);
|
||||
|
||||
// TODO: uuid as argument
|
||||
sBluetoothSocketInterface->Connect(
|
||||
aDeviceAddress,
|
||||
BluetoothSocketType::RFCOMM,
|
||||
UUID_OBEX_OBJECT_PUSH,
|
||||
aChannel, mEncrypt, mAuth,
|
||||
new ConnectSocketResultHandler(mImpl));
|
||||
aChannel, mEncrypt, mAuth, res);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -576,12 +582,14 @@ BluetoothSocket::ListenSocket(int aChannel)
|
||||
|
||||
mImpl = new DroidSocketImpl(XRE_GetIOMessageLoop(), this);
|
||||
|
||||
BluetoothSocketResultHandler* res = new ListenResultHandler(mImpl);
|
||||
SetCurrentResultHandler(res);
|
||||
|
||||
sBluetoothSocketInterface->Listen(
|
||||
BluetoothSocketType::RFCOMM,
|
||||
NS_LITERAL_STRING("OBEX Object Push"),
|
||||
UUID_OBEX_OBJECT_PUSH,
|
||||
aChannel, mEncrypt, mAuth,
|
||||
new ListenResultHandler(mImpl));
|
||||
aChannel, mEncrypt, mAuth, res);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -590,10 +598,16 @@ void
|
||||
BluetoothSocket::CloseSocket()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(sBluetoothSocketInterface);
|
||||
if (!mImpl) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Stop any watching |SocketMessageWatcher|
|
||||
if (mCurrentRes) {
|
||||
sBluetoothSocketInterface->Close(mCurrentRes);
|
||||
}
|
||||
|
||||
// From this point on, we consider mImpl as being deleted.
|
||||
// We sever the relationship here so any future calls to listen or connect
|
||||
// will create a new implementation.
|
||||
@ -633,6 +647,8 @@ BluetoothSocket::OnConnectSuccess()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mObserver);
|
||||
|
||||
SetCurrentResultHandler(nullptr);
|
||||
mObserver->OnSocketConnectSuccess(this);
|
||||
}
|
||||
|
||||
@ -641,6 +657,8 @@ BluetoothSocket::OnConnectError()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mObserver);
|
||||
|
||||
SetCurrentResultHandler(nullptr);
|
||||
mObserver->OnSocketConnectError(this);
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
class BluetoothSocketObserver;
|
||||
class BluetoothSocketResultHandler;
|
||||
class DroidSocketImpl;
|
||||
|
||||
class BluetoothSocket : public mozilla::ipc::SocketConsumerBase
|
||||
@ -47,8 +48,14 @@ public:
|
||||
mDeviceAddress = aDeviceAddress;
|
||||
}
|
||||
|
||||
inline void SetCurrentResultHandler(BluetoothSocketResultHandler* aRes)
|
||||
{
|
||||
mCurrentRes = aRes;
|
||||
}
|
||||
|
||||
private:
|
||||
BluetoothSocketObserver* mObserver;
|
||||
BluetoothSocketResultHandler* mCurrentRes;
|
||||
DroidSocketImpl* mImpl;
|
||||
nsString mDeviceAddress;
|
||||
bool mAuth;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include "BluetoothHALHelpers.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
@ -109,6 +110,34 @@ BluetoothSocketHALInterface::Listen(BluetoothSocketType aType,
|
||||
( ((_cmsghdr)->cmsg_level == SOL_SOCKET) && \
|
||||
((_cmsghdr)->cmsg_type == SCM_RIGHTS) )
|
||||
|
||||
class SocketMessageWatcher;
|
||||
|
||||
/* |SocketMessageWatcherWrapper| wraps SocketMessageWatcher to keep it from
|
||||
* being released by hash table's Remove() method.
|
||||
*/
|
||||
class SocketMessageWatcherWrapper
|
||||
{
|
||||
public:
|
||||
SocketMessageWatcherWrapper(SocketMessageWatcher* aSocketMessageWatcher)
|
||||
: mSocketMessageWatcher(aSocketMessageWatcher)
|
||||
{
|
||||
MOZ_ASSERT(mSocketMessageWatcher);
|
||||
}
|
||||
|
||||
SocketMessageWatcher* GetSocketMessageWatcher()
|
||||
{
|
||||
return mSocketMessageWatcher;
|
||||
}
|
||||
|
||||
private:
|
||||
SocketMessageWatcher* mSocketMessageWatcher;
|
||||
};
|
||||
|
||||
/* |sWatcherHashTable| maps result handlers to corresponding watchers */
|
||||
static nsClassHashtable<nsRefPtrHashKey<BluetoothSocketResultHandler>,
|
||||
SocketMessageWatcherWrapper>
|
||||
sWatcherHashtable;
|
||||
|
||||
/* |SocketMessageWatcher| receives Bluedroid's socket setup
|
||||
* messages on the I/O thread. You need to inherit from this
|
||||
* class to make use of it.
|
||||
@ -135,11 +164,14 @@ public:
|
||||
static const unsigned char OFF_CHANNEL2 = 12;
|
||||
static const unsigned char OFF_STATUS = 16;
|
||||
|
||||
SocketMessageWatcher(int aFd)
|
||||
SocketMessageWatcher(int aFd, BluetoothSocketResultHandler* aRes)
|
||||
: mFd(aFd)
|
||||
, mClientFd(-1)
|
||||
, mLen(0)
|
||||
{ }
|
||||
, mRes(aRes)
|
||||
{
|
||||
MOZ_ASSERT(mRes);
|
||||
}
|
||||
|
||||
virtual ~SocketMessageWatcher()
|
||||
{ }
|
||||
@ -164,7 +196,7 @@ public:
|
||||
}
|
||||
|
||||
if (IsComplete() || status != STATUS_SUCCESS) {
|
||||
mWatcher.StopWatchingFileDescriptor();
|
||||
StopWatching();
|
||||
Proceed(status);
|
||||
}
|
||||
}
|
||||
@ -174,6 +206,9 @@ public:
|
||||
|
||||
void Watch()
|
||||
{
|
||||
// add this watcher and its result handler to hash table
|
||||
sWatcherHashtable.Put(mRes, new SocketMessageWatcherWrapper(this));
|
||||
|
||||
MessageLoopForIO::current()->WatchFileDescriptor(
|
||||
mFd,
|
||||
true,
|
||||
@ -182,6 +217,14 @@ public:
|
||||
this);
|
||||
}
|
||||
|
||||
void StopWatching()
|
||||
{
|
||||
mWatcher.StopWatchingFileDescriptor();
|
||||
|
||||
// remove this watcher and its result handler from hash table
|
||||
sWatcherHashtable.Remove(mRes);
|
||||
}
|
||||
|
||||
bool IsComplete() const
|
||||
{
|
||||
return mLen == (MSG1_SIZE + MSG2_SIZE);
|
||||
@ -224,6 +267,11 @@ public:
|
||||
return mClientFd;
|
||||
}
|
||||
|
||||
BluetoothSocketResultHandler* GetResultHandler() const
|
||||
{
|
||||
return mRes;
|
||||
}
|
||||
|
||||
private:
|
||||
BluetoothStatus RecvMsg1()
|
||||
{
|
||||
@ -322,6 +370,7 @@ private:
|
||||
int mClientFd;
|
||||
unsigned char mLen;
|
||||
uint8_t mBuf[MSG1_SIZE + MSG2_SIZE];
|
||||
nsRefPtr<BluetoothSocketResultHandler> mRes;
|
||||
};
|
||||
|
||||
/* |SocketMessageWatcherTask| starts a SocketMessageWatcher
|
||||
@ -373,23 +422,18 @@ class ConnectWatcher MOZ_FINAL : public SocketMessageWatcher
|
||||
{
|
||||
public:
|
||||
ConnectWatcher(int aFd, BluetoothSocketResultHandler* aRes)
|
||||
: SocketMessageWatcher(aFd)
|
||||
, mRes(aRes)
|
||||
: SocketMessageWatcher(aFd, aRes)
|
||||
{ }
|
||||
|
||||
void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
|
||||
{
|
||||
if (mRes) {
|
||||
DispatchBluetoothSocketHALResult(
|
||||
mRes, &BluetoothSocketResultHandler::Connect, GetFd(),
|
||||
GetBdAddress(), GetConnectionStatus(), aStatus);
|
||||
}
|
||||
DispatchBluetoothSocketHALResult(
|
||||
GetResultHandler(), &BluetoothSocketResultHandler::Connect,
|
||||
GetFd(), GetBdAddress(), GetConnectionStatus(), aStatus);
|
||||
|
||||
MessageLoopForIO::current()->PostTask(
|
||||
FROM_HERE, new DeleteTask<ConnectWatcher>(this));
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<BluetoothSocketResultHandler> mRes;
|
||||
};
|
||||
|
||||
void
|
||||
@ -436,26 +480,18 @@ class AcceptWatcher MOZ_FINAL : public SocketMessageWatcher
|
||||
{
|
||||
public:
|
||||
AcceptWatcher(int aFd, BluetoothSocketResultHandler* aRes)
|
||||
: SocketMessageWatcher(aFd)
|
||||
, mRes(aRes)
|
||||
{
|
||||
/* not supplying a result handler leaks received file descriptor */
|
||||
MOZ_ASSERT(mRes);
|
||||
}
|
||||
: SocketMessageWatcher(aFd, aRes)
|
||||
{ }
|
||||
|
||||
void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
|
||||
{
|
||||
if (mRes) {
|
||||
DispatchBluetoothSocketHALResult(
|
||||
mRes, &BluetoothSocketResultHandler::Accept, GetClientFd(),
|
||||
GetBdAddress(), GetConnectionStatus(), aStatus);
|
||||
}
|
||||
DispatchBluetoothSocketHALResult(
|
||||
GetResultHandler(), &BluetoothSocketResultHandler::Accept,
|
||||
GetClientFd(), GetBdAddress(), GetConnectionStatus(), aStatus);
|
||||
|
||||
MessageLoopForIO::current()->PostTask(
|
||||
FROM_HERE, new DeleteTask<AcceptWatcher>(this));
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<BluetoothSocketResultHandler> mRes;
|
||||
};
|
||||
|
||||
void
|
||||
@ -467,6 +503,46 @@ BluetoothSocketHALInterface::Accept(int aFd,
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
|
||||
}
|
||||
|
||||
/* |DeleteSocketMessageWatcherTask| deletes a watching SocketMessageWatcher
|
||||
* on the I/O task
|
||||
*/
|
||||
class DeleteSocketMessageWatcherTask MOZ_FINAL : public Task
|
||||
{
|
||||
public:
|
||||
DeleteSocketMessageWatcherTask(BluetoothSocketResultHandler* aRes)
|
||||
: mRes(aRes)
|
||||
{
|
||||
MOZ_ASSERT(mRes);
|
||||
}
|
||||
|
||||
void Run() MOZ_OVERRIDE
|
||||
{
|
||||
// look up hash table for the watcher corresponding to |mRes|
|
||||
SocketMessageWatcherWrapper* wrapper = sWatcherHashtable.Get(mRes);
|
||||
if (!wrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
// stop the watcher if it exists
|
||||
SocketMessageWatcher* watcher = wrapper->GetSocketMessageWatcher();
|
||||
watcher->StopWatching();
|
||||
watcher->Proceed(STATUS_DONE);
|
||||
}
|
||||
|
||||
private:
|
||||
BluetoothSocketResultHandler* mRes;
|
||||
};
|
||||
|
||||
void
|
||||
BluetoothSocketHALInterface::Close(BluetoothSocketResultHandler* aRes)
|
||||
{
|
||||
MOZ_ASSERT(aRes);
|
||||
|
||||
/* stop the watcher corresponding to |aRes| */
|
||||
Task* t = new DeleteSocketMessageWatcherTask(aRes);
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
|
||||
}
|
||||
|
||||
BluetoothSocketHALInterface::BluetoothSocketHALInterface(
|
||||
const btsock_interface_t* aInterface)
|
||||
: mInterface(aInterface)
|
||||
|
@ -36,6 +36,8 @@ public:
|
||||
|
||||
void Accept(int aFd, BluetoothSocketResultHandler* aRes);
|
||||
|
||||
void Close(BluetoothSocketResultHandler* aRes);
|
||||
|
||||
protected:
|
||||
BluetoothSocketHALInterface(const btsock_interface_t* aInterface);
|
||||
~BluetoothSocketHALInterface();
|
||||
|
Loading…
Reference in New Issue
Block a user