Bug 796329 - implemented StopSendingFile() and fixed potential memory problem, r=qdot

This commit is contained in:
Eric Chou 2012-10-03 15:09:27 +08:00
Родитель 9418188a43
Коммит b04a37f44f
11 изменённых файлов: 128 добавлений и 8 удалений

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

@ -849,7 +849,29 @@ NS_IMETHODIMP
BluetoothAdapter::StopSendingFile(const nsAString& aDeviceAddress,
nsIDOMDOMRequest** aRequest)
{
// Will implement in another patch
BluetoothService* bs = BluetoothService::Get();
if (!bs) {
NS_WARNING("BluetoothService not available!");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDOMRequestService> rs = do_GetService("@mozilla.org/dom/dom-request-service;1");
if (!rs) {
NS_WARNING("No DOMRequest Service!");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDOMDOMRequest> req;
nsresult rv = rs->CreateRequest(GetOwner(), getter_AddRefs(req));
if (NS_FAILED(rv)) {
NS_WARNING("Can't create DOMRequest!");
return NS_ERROR_FAILURE;
}
nsRefPtr<BluetoothVoidReplyRunnable> result = new BluetoothVoidReplyRunnable(req);
bs->StopSendingFile(aDeviceAddress, result);
req.forget(aRequest);
return NS_OK;
}

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

@ -91,6 +91,8 @@ BluetoothOppManager::BluetoothOppManager() : mConnected(false)
, mRemoteObexVersion(0)
, mRemoteConnectionFlags(0)
, mRemoteMaxPacketLength(0)
, mAbortFlag(false)
, mReadFileThread(nullptr)
{
}
@ -171,7 +173,12 @@ BluetoothOppManager::SendFile(BlobParent* aActor,
bool
BluetoothOppManager::StopSendingFile(BluetoothReplyRunnable* aRunnable)
{
// will implement in another patch.
if (!mBlob) {
return false;
}
mAbortFlag = true;
return true;
}
@ -216,7 +223,14 @@ BluetoothOppManager::ReceiveSocketData(UnixSocketRawData* aMessage)
return;
}
if (NS_FAILED(NS_NewThread(getter_AddRefs(mReadFileThread)))) {
NS_WARNING("Can't create thread");
SendDisconnectRequest();
return;
}
sSentFileSize = 0;
mAbortFlag = false;
sInstance->SendPutHeaderRequest(fileName, fileSize);
}
}
@ -227,19 +241,21 @@ BluetoothOppManager::ReceiveSocketData(UnixSocketRawData* aMessage)
} else {
mConnected = false;
mBlob = nullptr;
mReadFileThread = nullptr;
}
} else if (mLastCommand == ObexRequestCode::Put) {
if (responseCode != ObexResponseCode::Continue) {
// FIXME: Needs error handling here
NS_WARNING("[OPP] Put failed");
} else {
nsCOMPtr<nsIThread> t;
NS_NewThread(getter_AddRefs(t));
if (mAbortFlag || mReadFileThread == nullptr) {
SendAbortRequest();
} else {
nsRefPtr<ReadFileTask> task = new ReadFileTask(mBlob);
nsRefPtr<ReadFileTask> task = new ReadFileTask(mBlob);
if (NS_FAILED(t->Dispatch(task, NS_DISPATCH_NORMAL))) {
NS_WARNING("Cannot dispatch ring task!");
if (NS_FAILED(mReadFileThread->Dispatch(task, NS_DISPATCH_NORMAL))) {
NS_WARNING("Cannot dispatch ring task!");
}
}
}
} else if (mLastCommand == ObexRequestCode::PutFinal) {
@ -249,6 +265,12 @@ BluetoothOppManager::ReceiveSocketData(UnixSocketRawData* aMessage)
} else {
SendDisconnectRequest();
}
} else if (mLastCommand == ObexRequestCode::Abort) {
if (responseCode != ObexResponseCode::Success) {
NS_WARNING("[OPP] Abort failed");
}
SendDisconnectRequest();
}
}
@ -359,3 +381,19 @@ BluetoothOppManager::SendDisconnectRequest()
memcpy(s->mData, req, s->mSize);
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);
}

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

@ -57,6 +57,7 @@ public:
void SendPutRequest(uint8_t* aFileBody, int aFileBodyLength,
bool aFinal);
void SendDisconnectRequest();
void SendAbortRequest();
private:
BluetoothOppManager();
@ -67,8 +68,10 @@ private:
uint8_t mRemoteObexVersion;
uint8_t mRemoteConnectionFlags;
int mRemoteMaxPacketLength;
bool mAbortFlag;
nsCOMPtr<nsIDOMBlob> mBlob;
nsCOMPtr<nsIThread> mReadFileThread;
};
END_BLUETOOTH_NAMESPACE

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

@ -286,6 +286,10 @@ public:
BlobChild* aBlobChild,
BluetoothReplyRunnable* aRunnable) = 0;
virtual bool
StopSendingFile(const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable) = 0;
virtual nsresult
ListenSocketViaService(int aChannel,
BluetoothSocketType aType,

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

@ -223,6 +223,8 @@ BluetoothParent::RecvPBluetoothRequestConstructor(
return actor->DoRequest(aRequest.get_DisconnectObjectPushRequest());
case Request::TSendFileRequest:
return actor->DoRequest(aRequest.get_SendFileRequest());
case Request::TStopSendingFileRequest:
return actor->DoRequest(aRequest.get_StopSendingFileRequest());
default:
MOZ_NOT_REACHED("Unknown type!");
return false;
@ -552,3 +554,13 @@ BluetoothRequestParent::DoRequest(const SendFileRequest& aRequest)
(BlobChild*)aRequest.blobChild(),
mReplyRunnable.get());
}
bool
BluetoothRequestParent::DoRequest(const StopSendingFileRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TStopSendingFileRequest);
return mService->StopSendingFile(aRequest.devicePath(),
mReplyRunnable.get());
}

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

@ -180,6 +180,9 @@ protected:
bool
DoRequest(const SendFileRequest& aRequest);
bool
DoRequest(const StopSendingFileRequest& aRequest);
};
END_BLUETOOTH_NAMESPACE

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

@ -351,6 +351,16 @@ BluetoothServiceChildProcess::SendFile(
return true;
}
bool
BluetoothServiceChildProcess::StopSendingFile(
const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable,
StopSendingFileRequest(nsString(aDeviceAddress)));
return true;
}
nsresult
BluetoothServiceChildProcess::HandleStartup()
{

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

@ -151,6 +151,10 @@ public:
BlobChild* aBlobChild,
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
virtual bool
StopSendingFile(const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
protected:
BluetoothServiceChildProcess();
virtual ~BluetoothServiceChildProcess();

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

@ -122,6 +122,11 @@ struct SendFileRequest
PBlob blob;
};
struct StopSendingFileRequest
{
nsString devicePath;
};
union Request
{
DefaultAdapterPathRequest;
@ -143,6 +148,7 @@ union Request
DisconnectHeadsetRequest;
DisconnectObjectPushRequest;
SendFileRequest;
StopSendingFileRequest;
};
protocol PBluetooth

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

@ -2423,6 +2423,20 @@ BluetoothDBusService::SendFile(const nsAString& aDeviceAddress,
return true;
}
bool
BluetoothDBusService::StopSendingFile(const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable)
{
// Currently we only support one device sending one file at a time,
// so we don't need aDeviceAddress here because the target device
// has been determined when calling 'Connect()'. Nevertheless, keep
// it for future use.
BluetoothOppManager* opp = BluetoothOppManager::Get();
opp->StopSendingFile(aRunnable);
return true;
}
class ListenBluetoothSocketRunnable : public nsRunnable
{
public:

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

@ -155,6 +155,10 @@ public:
BlobChild* aBlobChild,
BluetoothReplyRunnable* aRunnable);
virtual bool
StopSendingFile(const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable);
private:
nsresult SendGetPropertyMessage(const nsAString& aPath,
const char* aInterface,