author | Eric Chou <echou@mozilla.com> |
Thu, 04 Apr 2013 17:53:08 -0700 | |
changeset 127743 | a7a3e3a4e53450fc2c98983368fbf98650cacbc7 |
parent 127742 | fc1c1298bd85163181a984dd4061c61dc595a799 |
child 127744 | 4530d1c784f36d12cb9de3e0631d56eb4c1bd243 |
push id | 24512 |
push user | ryanvm@gmail.com |
push date | Fri, 05 Apr 2013 20:13:49 +0000 |
treeherder | mozilla-central@139b6ba547fa [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mrbkap |
bugs | 851046 |
milestone | 23.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
dom/bluetooth/BluetoothOppManager.cpp | file | annotate | diff | comparison | revisions | |
dom/bluetooth/BluetoothOppManager.h | file | annotate | diff | comparison | revisions |
--- a/dom/bluetooth/BluetoothOppManager.cpp +++ b/dom/bluetooth/BluetoothOppManager.cpp @@ -4,16 +4,17 @@ * 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 "base/basictypes.h" #include "BluetoothOppManager.h" #include "BluetoothReplyRunnable.h" #include "BluetoothService.h" +#include "BluetoothSocket.h" #include "BluetoothUtils.h" #include "BluetoothUuid.h" #include "ObexBase.h" #include "mozilla/dom/bluetooth/BluetoothTypes.h" #include "mozilla/RefPtr.h" #include "mozilla/Services.h" #include "mozilla/StaticPtr.h" @@ -79,17 +80,17 @@ namespace { static const uint32_t kUpdateProgressBase = 50 * 1024; /* * The format of the header of an PUT request is * [opcode:1][packet length:2][headerId:1][header length:2] */ static const uint32_t kPutRequestHeaderSize = 6; -StaticRefPtr<BluetoothOppManager> sInstance; +StaticAutoPtr<BluetoothOppManager> sInstance; StaticRefPtr<BluetoothOppManagerObserver> sOppObserver; /* * FIXME / Bug 806749 * * Currently Bluetooth*Manager inherits mozilla::ipc::UnixSocketConsumer, * which means that each Bluetooth*Manager can handle only one socket * connection at a time. We need to support concurrent multiple socket @@ -189,28 +190,33 @@ public: private: nsCOMPtr<nsIInputStream> mInputStream; uint32_t mAvailablePacketSize; }; class CloseSocketTask : public Task { public: + CloseSocketTask(BluetoothSocket* aSocket) : mSocket(aSocket) + { + MOZ_ASSERT(aSocket); + } + void Run() MOZ_OVERRIDE { - if (!sInstance) { - NS_WARNING("BluetoothOppManager no longer exists, cannot close socket!"); - return; - } + MOZ_ASSERT(NS_IsMainThread()); - if (sInstance->GetConnectionStatus() == - SocketConnectionStatus::SOCKET_CONNECTED) { - sInstance->CloseSocket(); + if (mSocket->GetConnectionStatus() == + SocketConnectionStatus::SOCKET_CONNECTED) { + mSocket->Disconnect(); } } + +private: + nsRefPtr<BluetoothSocket> mSocket; }; BluetoothOppManager::BluetoothOppManager() : mConnected(false) , mRemoteObexVersion(0) , mRemoteConnectionFlags(0) , mRemoteMaxPacketLength(0) , mLastCommand(0) , mPacketLeftLength(0) @@ -218,50 +224,57 @@ BluetoothOppManager::BluetoothOppManager , mReceivedDataBufferOffset(0) , mAbortFlag(false) , mNewFileFlag(false) , mPutFinalFlag(false) , mSendTransferCompleteFlag(false) , mSuccessFlag(false) , mWaitingForConfirmationFlag(false) { - mConnectedDeviceAddress.AssignLiteral("00:00:00:00:00:00"); - mSocketStatus = GetConnectionStatus(); + mConnectedDeviceAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE); + + mSocket = new BluetoothSocket(this, + BluetoothSocketType::RFCOMM, + true, + true); + mSocketStatus = mSocket->GetConnectionStatus(); } BluetoothOppManager::~BluetoothOppManager() { } //static BluetoothOppManager* BluetoothOppManager::Get() { MOZ_ASSERT(NS_IsMainThread()); - if (sInstance == nullptr) { + if (!sInstance) { sInstance = new BluetoothOppManager(); } return sInstance; } bool BluetoothOppManager::Connect(const nsAString& aDeviceObjectPath, BluetoothReplyRunnable* aRunnable) { MOZ_ASSERT(NS_IsMainThread()); - if (GetConnectionStatus() == SocketConnectionStatus::SOCKET_CONNECTED || - GetConnectionStatus() == SocketConnectionStatus::SOCKET_CONNECTING) { + SocketConnectionStatus s = mSocket->GetConnectionStatus(); + + if (s == SocketConnectionStatus::SOCKET_CONNECTED || + s == SocketConnectionStatus::SOCKET_CONNECTING) { NS_WARNING("BluetoothOppManager has been already connected"); return false; } - CloseSocket(); + Disconnect(); BluetoothService* bs = BluetoothService::Get(); if (!bs) { NS_WARNING("BluetoothService not available!"); return false; } nsString uuid; @@ -269,70 +282,58 @@ BluetoothOppManager::Connect(const nsASt mRunnable = aRunnable; nsresult rv = bs->GetSocketViaService(aDeviceObjectPath, uuid, BluetoothSocketType::RFCOMM, true, true, - this, + mSocket, mRunnable); return NS_FAILED(rv) ? false : true; } void BluetoothOppManager::Disconnect() { - if (GetConnectionStatus() == SocketConnectionStatus::SOCKET_DISCONNECTED) { - NS_WARNING("BluetoothOppManager has been disconnected!"); - return; - } - - CloseSocket(); + mSocket->Disconnect(); } nsresult BluetoothOppManager::HandleShutdown() { MOZ_ASSERT(NS_IsMainThread()); sInShutdown = true; - CloseSocket(); + Disconnect(); sInstance = nullptr; return NS_OK; } bool BluetoothOppManager::Listen() { MOZ_ASSERT(NS_IsMainThread()); - if (GetConnectionStatus() == SocketConnectionStatus::SOCKET_LISTENING) { + if (mSocket->GetConnectionStatus() == + SocketConnectionStatus::SOCKET_LISTENING) { NS_WARNING("BluetoothOppManager has been already listening"); return true; } - CloseSocket(); + Disconnect(); - BluetoothService* bs = BluetoothService::Get(); - if (!bs) { - NS_WARNING("BluetoothService not available!"); + if (!mSocket->Listen(BluetoothReservedChannels::CHANNEL_OPUSH)) { + NS_WARNING("[OPP] Can't listen on socket!"); return false; } - nsresult rv = - bs->ListenSocketViaService(BluetoothReservedChannels::CHANNEL_OPUSH, - BluetoothSocketType::RFCOMM, - true, - true, - this); - mSocketStatus = GetConnectionStatus(); - - return NS_FAILED(rv) ? false : true; + mSocketStatus = mSocket->GetConnectionStatus(); + return true; } bool BluetoothOppManager::SendFile(BlobParent* aActor) { if (mBlob) { // Means there's a sending process. Reply error. return false; @@ -686,17 +687,18 @@ BluetoothOppManager::ServerDataHandler(U packetLength = mPacketLeftLength; } else { opCode = aMessage->mData[0]; packetLength = (((int)aMessage->mData[1]) << 8) | aMessage->mData[2]; // When there's a Put packet right after a PutFinal packet, // which means it's the start point of a new file. if (mPutFinalFlag && - (opCode == ObexRequestCode::Put || opCode == ObexRequestCode::PutFinal)) { + (opCode == ObexRequestCode::Put || + opCode == ObexRequestCode::PutFinal)) { mNewFileFlag = true; AfterFirstPut(); } } ObexHeaderSet pktHeaders(opCode); if (opCode == ObexRequestCode::Connect) { // Section 3.3.1 "Connect", IrOBEX 1.2 @@ -859,17 +861,17 @@ BluetoothOppManager::ClientDataHandler(U SendDisconnectRequest(); FileTransferComplete(); } else if (mLastCommand == ObexRequestCode::Disconnect) { AfterOppDisconnected(); // Most devices will directly terminate connection after receiving // Disconnect request, so we make a delay here. If the socket hasn't been // disconnected, we will close it. MessageLoop::current()-> - PostDelayedTask(FROM_HERE, new CloseSocketTask(), 1000); + PostDelayedTask(FROM_HERE, new CloseSocketTask(mSocket), 1000); } else if (mLastCommand == ObexRequestCode::Connect) { MOZ_ASSERT(!sFileName.IsEmpty()); MOZ_ASSERT(mBlob); AfterOppConnected(); // Keep remote information mRemoteObexVersion = aMessage->mData[3]; @@ -952,17 +954,17 @@ BluetoothOppManager::SendConnectRequest( req[5] = BluetoothOppManager::MAX_PACKET_LENGTH >> 8; req[6] = (uint8_t)BluetoothOppManager::MAX_PACKET_LENGTH; SetObexPacketInfo(req, ObexRequestCode::Connect, index); mLastCommand = ObexRequestCode::Connect; UnixSocketRawData* s = new UnixSocketRawData(index); memcpy(s->mData, req, s->mSize); - SendSocketData(s); + mSocket->SendSocketData(s); } void BluetoothOppManager::SendPutHeaderRequest(const nsAString& aFileName, int aFileSize) { uint8_t* req = new uint8_t[mRemoteMaxPacketLength]; @@ -982,17 +984,17 @@ BluetoothOppManager::SendPutHeaderReques index += AppendHeaderName(&req[index], (char*)fileName, (len + 1) * 2); index += AppendHeaderLength(&req[index], aFileSize); SetObexPacketInfo(req, ObexRequestCode::Put, index); mLastCommand = ObexRequestCode::Put; UnixSocketRawData* s = new UnixSocketRawData(index); memcpy(s->mData, req, s->mSize); - SendSocketData(s); + mSocket->SendSocketData(s); delete [] fileName; delete [] req; } void BluetoothOppManager::SendPutRequest(uint8_t* aFileBody, int aFileBodyLength) @@ -1012,17 +1014,17 @@ BluetoothOppManager::SendPutRequest(uint int index = 3; index += AppendHeaderBody(&req[index], aFileBody, aFileBodyLength); SetObexPacketInfo(req, ObexRequestCode::Put, index); mLastCommand = ObexRequestCode::Put; UnixSocketRawData* s = new UnixSocketRawData(index); memcpy(s->mData, req, s->mSize); - SendSocketData(s); + mSocket->SendSocketData(s); delete [] req; } void BluetoothOppManager::SendPutFinalRequest() { if (!mConnected) return; @@ -1038,17 +1040,17 @@ BluetoothOppManager::SendPutFinalRequest int index = 3; uint8_t* req = new uint8_t[mRemoteMaxPacketLength]; index += AppendHeaderEndOfBody(&req[index]); SetObexPacketInfo(req, ObexRequestCode::PutFinal, index); mLastCommand = ObexRequestCode::PutFinal; UnixSocketRawData* s = new UnixSocketRawData(index); memcpy(s->mData, req, s->mSize); - SendSocketData(s); + mSocket->SendSocketData(s); sWaitingToSendPutFinal = false; delete [] req; } void BluetoothOppManager::SendDisconnectRequest() @@ -1058,33 +1060,33 @@ BluetoothOppManager::SendDisconnectReque uint8_t req[255]; int index = 3; SetObexPacketInfo(req, ObexRequestCode::Disconnect, index); mLastCommand = ObexRequestCode::Disconnect; UnixSocketRawData* s = new UnixSocketRawData(index); memcpy(s->mData, req, s->mSize); - SendSocketData(s); + mSocket->SendSocketData(s); } void BluetoothOppManager::SendAbortRequest() { // Section 3.3.5 "Abort", IrOBEX 1.2 // [opcode:1][length:2][Headers:var] uint8_t req[255]; int index = 3; SetObexPacketInfo(req, ObexRequestCode::Abort, index); mLastCommand = ObexRequestCode::Abort; UnixSocketRawData* s = new UnixSocketRawData(index); memcpy(s->mData, req, s->mSize); - SendSocketData(s); + mSocket->SendSocketData(s); } bool BluetoothOppManager::IsTransferring() { return (mConnected && !mSendTransferCompleteFlag); } @@ -1104,17 +1106,17 @@ BluetoothOppManager::ReplyToConnect() req[4] = 0x00; // flag=0x00 req[5] = BluetoothOppManager::MAX_PACKET_LENGTH >> 8; req[6] = (uint8_t)BluetoothOppManager::MAX_PACKET_LENGTH; SetObexPacketInfo(req, ObexResponseCode::Success, index); UnixSocketRawData* s = new UnixSocketRawData(index); memcpy(s->mData, req, s->mSize); - SendSocketData(s); + mSocket->SendSocketData(s); } void BluetoothOppManager::ReplyToDisconnect() { if (!mConnected) return; mConnected = false; @@ -1122,17 +1124,17 @@ BluetoothOppManager::ReplyToDisconnect() // [opcode:1][length:2][Headers:var] uint8_t req[255]; int index = 3; SetObexPacketInfo(req, ObexResponseCode::Success, index); UnixSocketRawData* s = new UnixSocketRawData(index); memcpy(s->mData, req, s->mSize); - SendSocketData(s); + mSocket->SendSocketData(s); } void BluetoothOppManager::ReplyToPut(bool aFinal, bool aContinue) { if (!mConnected) return; // Section 3.3.2 "Disconnect", IrOBEX 1.2 @@ -1153,17 +1155,17 @@ BluetoothOppManager::ReplyToPut(bool aFi SetObexPacketInfo(req, ObexResponseCode::Unauthorized & (~FINAL_BIT), index); } } UnixSocketRawData* s = new UnixSocketRawData(index); memcpy(s->mData, req, s->mSize); - SendSocketData(s); + mSocket->SendSocketData(s); } void BluetoothOppManager::FileTransferComplete() { if (mSendTransferCompleteFlag) { return; } @@ -1308,37 +1310,36 @@ BluetoothOppManager::OnConnectSuccess() if (NS_FAILED(NS_DispatchToMainThread(mRunnable))) { NS_WARNING("Failed to dispatch to main thread!"); } mRunnable.forget(); } // Cache device address since we can't get socket address when a remote // device disconnect with us. - GetSocketAddr(mConnectedDeviceAddress); - - mSocketStatus = GetConnectionStatus(); + mSocket->GetAddress(mConnectedDeviceAddress); + mSocketStatus = mSocket->GetConnectionStatus(); } void BluetoothOppManager::OnConnectError() { if (mRunnable) { nsString errorStr; errorStr.AssignLiteral("Failed to connect with a bluetooth opp manager!"); BluetoothReply* reply = new BluetoothReply(BluetoothReplyError(errorStr)); mRunnable->SetReply(reply); if (NS_FAILED(NS_DispatchToMainThread(mRunnable))) { NS_WARNING("Failed to dispatch to main thread!"); } mRunnable.forget(); } - CloseSocket(); - mSocketStatus = GetConnectionStatus(); + mSocket->Disconnect(); + mSocketStatus = mSocket->GetConnectionStatus(); Listen(); } void BluetoothOppManager::OnDisconnect() { /** * It is valid for a bluetooth device which is transfering file via OPP @@ -1350,28 +1351,29 @@ BluetoothOppManager::OnDisconnect() if (mSocketStatus == SocketConnectionStatus::SOCKET_CONNECTED) { if (mTransferMode) { if (!mSuccessFlag) { DeleteReceivedFile(); } else if (mDsFile) { nsString data; CopyASCIItoUTF16("modified", data); - nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); + nsCOMPtr<nsIObserverService> obs = + mozilla::services::GetObserverService(); if (obs) { obs->NotifyObservers(mDsFile, "file-watcher-notify", data.get()); } } } if (!mSuccessFlag) { FileTransferComplete(); } Listen(); } else if (mSocketStatus == SocketConnectionStatus::SOCKET_CONNECTING) { NS_WARNING("BluetoothOppManager got unexpected socket status!"); } AfterOppDisconnected(); - mConnectedDeviceAddress.AssignLiteral("00:00:00:00:00:00"); + mConnectedDeviceAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE); mSuccessFlag = false; }
--- a/dom/bluetooth/BluetoothOppManager.h +++ b/dom/bluetooth/BluetoothOppManager.h @@ -3,43 +3,43 @@ /* 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/. */ #ifndef mozilla_dom_bluetooth_bluetoothoppmanager_h__ #define mozilla_dom_bluetooth_bluetoothoppmanager_h__ #include "BluetoothCommon.h" +#include "BluetoothSocketObserver.h" #include "mozilla/dom/ipc/Blob.h" #include "mozilla/ipc/UnixSocket.h" #include "DeviceStorage.h" class nsIOutputStream; class nsIInputStream; BEGIN_BLUETOOTH_NAMESPACE class BluetoothReplyRunnable; +class BluetoothSocket; class ObexHeaderSet; -class BluetoothOppManager : public mozilla::ipc::UnixSocketConsumer +class BluetoothOppManager : public BluetoothSocketObserver { public: /* * Channel of reserved services are fixed values, please check * function add_reserved_service_records() in * external/bluetooth/bluez/src/adapter.c for more information. */ static const int DEFAULT_OPP_CHANNEL = 10; static const int MAX_PACKET_LENGTH = 0xFFFE; ~BluetoothOppManager(); static BluetoothOppManager* Get(); - void ReceiveSocketData(nsAutoPtr<mozilla::ipc::UnixSocketRawData>& aMessage) - MOZ_OVERRIDE; void ClientDataHandler(mozilla::ipc::UnixSocketRawData* aMessage); void ServerDataHandler(mozilla::ipc::UnixSocketRawData* aMessage); /* * If a application wnats to send a file, first, it needs to * call Connect() to create a valid RFCOMM connection. After * that, call SendFile()/StopSendingFile() to control file-sharing * process. During the file transfering process, the application @@ -67,16 +67,24 @@ public: void ExtractPacketHeaders(const ObexHeaderSet& aHeader); bool ExtractBlobHeaders(); nsresult HandleShutdown(); // Return true if there is an ongoing file-transfer session, please see // Bug 827267 for more information. bool IsTransferring(); + + // Implement interface BluetoothSocketObserver + void ReceiveSocketData(nsAutoPtr<mozilla::ipc::UnixSocketRawData>& aMessage) + MOZ_OVERRIDE; + void OnConnectSuccess() MOZ_OVERRIDE; + void OnConnectError() MOZ_OVERRIDE; + void OnDisconnect() MOZ_OVERRIDE; + private: BluetoothOppManager(); void StartFileTransfer(); void FileTransferComplete(); void UpdateProgress(); void ReceivingFileConfirmation(); bool CreateFile(); bool WriteToFile(const uint8_t* aData, int aDataLength); @@ -85,20 +93,16 @@ private: void ReplyToDisconnect(); void ReplyToPut(bool aFinal, bool aContinue); void AfterOppConnected(); void AfterFirstPut(); void AfterOppDisconnected(); void ValidateFileName(); bool IsReservedChar(PRUnichar c); - virtual void OnConnectSuccess() MOZ_OVERRIDE; - virtual void OnConnectError() MOZ_OVERRIDE; - virtual void OnDisconnect() MOZ_OVERRIDE; - /** * RFCOMM socket status. */ enum mozilla::ipc::SocketConnectionStatus mSocketStatus; /** * OBEX session status. * Set when OBEX session is established. @@ -168,13 +172,14 @@ private: nsCOMPtr<nsIDOMBlob> mBlob; nsCOMPtr<nsIThread> mReadFileThread; nsCOMPtr<nsIOutputStream> mOutputStream; nsCOMPtr<nsIInputStream> mInputStream; nsRefPtr<BluetoothReplyRunnable> mRunnable; nsRefPtr<DeviceStorageFile> mDsFile; + nsRefPtr<BluetoothSocket> mSocket; }; END_BLUETOOTH_NAMESPACE #endif