зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1079649: Use a temporary (.part) file to store incoming file. (bluetooth2/bluez) r=btian
This commit is contained in:
Родитель
b99f40c9ca
Коммит
0fb740de24
|
@ -553,6 +553,7 @@ BluetoothOppManager::AfterOppDisconnected()
|
||||||
mLastCommand = 0;
|
mLastCommand = 0;
|
||||||
mPutPacketReceivedLength = 0;
|
mPutPacketReceivedLength = 0;
|
||||||
mDsFile = nullptr;
|
mDsFile = nullptr;
|
||||||
|
mDummyDsFile = nullptr;
|
||||||
|
|
||||||
// We can't reset mSuccessFlag here since this function may be called
|
// We can't reset mSuccessFlag here since this function may be called
|
||||||
// before we send system message of transfer complete
|
// before we send system message of transfer complete
|
||||||
|
@ -579,6 +580,34 @@ BluetoothOppManager::AfterOppDisconnected()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothOppManager::RecoverFileName()
|
||||||
|
{
|
||||||
|
// Remove the trailing ".part" file name from mDsFile by two steps
|
||||||
|
// 1. mDsFile->SetPath() so that the notification sent to Gaia will carry
|
||||||
|
// correct information of the file.
|
||||||
|
// 2. mDsFile->mFile->RenameTo() so that the file name would actually be
|
||||||
|
// changed in file system.
|
||||||
|
if (mDsFile && mDsFile->mFile) {
|
||||||
|
nsString path;
|
||||||
|
path.AssignLiteral(TARGET_SUBDIR);
|
||||||
|
path.Append(mFileName);
|
||||||
|
|
||||||
|
mDsFile->SetPath(path);
|
||||||
|
mDsFile->mFile->RenameTo(nullptr, mFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BluetoothOppManager::DeleteDummyFile()
|
||||||
|
{
|
||||||
|
// Remove the empty temp file
|
||||||
|
if (mDummyDsFile && mDummyDsFile->mFile) {
|
||||||
|
mDummyDsFile->mFile->Remove(false);
|
||||||
|
mDummyDsFile = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BluetoothOppManager::DeleteReceivedFile()
|
BluetoothOppManager::DeleteReceivedFile()
|
||||||
{
|
{
|
||||||
|
@ -591,6 +620,8 @@ BluetoothOppManager::DeleteReceivedFile()
|
||||||
mDsFile->mFile->Remove(false);
|
mDsFile->mFile->Remove(false);
|
||||||
mDsFile = nullptr;
|
mDsFile = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeleteDummyFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -598,25 +629,39 @@ BluetoothOppManager::CreateFile()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mPutPacketReceivedLength == mPacketLength);
|
MOZ_ASSERT(mPutPacketReceivedLength == mPacketLength);
|
||||||
|
|
||||||
|
// Create one dummy file to be a placeholder for the target file name, and
|
||||||
|
// create another file with a meaningless file extension to write the received
|
||||||
|
// data. By doing this, we can prevent applications from parsing incomplete
|
||||||
|
// data in the middle of the receiving process.
|
||||||
nsString path;
|
nsString path;
|
||||||
path.AssignLiteral(TARGET_SUBDIR);
|
path.AssignLiteral(TARGET_SUBDIR);
|
||||||
path.Append(mFileName);
|
path.Append(mFileName);
|
||||||
|
|
||||||
mDsFile = DeviceStorageFile::CreateUnique(
|
// Use an empty dummy file object to occupy the file name, so that after the
|
||||||
path, nsIFile::NORMAL_FILE_TYPE, 0644);
|
// whole file has been received successfully by using mDsFile, we could just
|
||||||
|
// remove mDummyDsFile and rename mDsFile to the file name of mDummyDsFile.
|
||||||
|
mDummyDsFile =
|
||||||
|
DeviceStorageFile::CreateUnique(path, nsIFile::NORMAL_FILE_TYPE, 0644);
|
||||||
|
NS_ENSURE_TRUE(mDummyDsFile, false);
|
||||||
|
|
||||||
|
// The function CreateUnique() may create a file with a different file
|
||||||
|
// name from the original mFileName. Therefore we have to retrieve
|
||||||
|
// the file name again.
|
||||||
|
mDummyDsFile->mFile->GetLeafName(mFileName);
|
||||||
|
|
||||||
|
BT_LOGR("mFileName: %s", NS_ConvertUTF16toUTF8(mFileName).get());
|
||||||
|
|
||||||
|
// Prepare the entire file path for the .part file
|
||||||
|
path.Truncate();
|
||||||
|
path.AssignLiteral(TARGET_SUBDIR);
|
||||||
|
path.Append(mFileName);
|
||||||
|
path.AppendLiteral(".part");
|
||||||
|
|
||||||
|
mDsFile =
|
||||||
|
DeviceStorageFile::CreateUnique(path, nsIFile::NORMAL_FILE_TYPE, 0644);
|
||||||
NS_ENSURE_TRUE(mDsFile, false);
|
NS_ENSURE_TRUE(mDsFile, false);
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> f;
|
NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), mDsFile->mFile);
|
||||||
mDsFile->mFile->Clone(getter_AddRefs(f));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The function CreateUnique() may create a file with a different file
|
|
||||||
* name from the original mFileName. Therefore we have to retrieve
|
|
||||||
* the file name again.
|
|
||||||
*/
|
|
||||||
f->GetLeafName(mFileName);
|
|
||||||
|
|
||||||
NS_NewLocalFileOutputStream(getter_AddRefs(mOutputStream), f);
|
|
||||||
NS_ENSURE_TRUE(mOutputStream, false);
|
NS_ENSURE_TRUE(mOutputStream, false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -932,6 +977,10 @@ BluetoothOppManager::ServerDataHandler(UnixSocketRawData* aMessage)
|
||||||
// Success to receive a file and notify completion
|
// Success to receive a file and notify completion
|
||||||
if (mPutFinalFlag) {
|
if (mPutFinalFlag) {
|
||||||
mSuccessFlag = true;
|
mSuccessFlag = true;
|
||||||
|
|
||||||
|
DeleteDummyFile();
|
||||||
|
RecoverFileName();
|
||||||
|
|
||||||
FileTransferComplete();
|
FileTransferComplete();
|
||||||
NotifyAboutFileChange();
|
NotifyAboutFileChange();
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,8 @@ private:
|
||||||
void ReceivingFileConfirmation();
|
void ReceivingFileConfirmation();
|
||||||
bool CreateFile();
|
bool CreateFile();
|
||||||
bool WriteToFile(const uint8_t* aData, int aDataLength);
|
bool WriteToFile(const uint8_t* aData, int aDataLength);
|
||||||
|
void RecoverFileName();
|
||||||
|
void DeleteDummyFile();
|
||||||
void DeleteReceivedFile();
|
void DeleteReceivedFile();
|
||||||
void ReplyToConnect();
|
void ReplyToConnect();
|
||||||
void ReplyToDisconnectOrAbort();
|
void ReplyToDisconnectOrAbort();
|
||||||
|
@ -209,6 +211,7 @@ private:
|
||||||
nsCOMPtr<nsIInputStream> mInputStream;
|
nsCOMPtr<nsIInputStream> mInputStream;
|
||||||
nsCOMPtr<nsIVolumeMountLock> mMountLock;
|
nsCOMPtr<nsIVolumeMountLock> mMountLock;
|
||||||
nsRefPtr<DeviceStorageFile> mDsFile;
|
nsRefPtr<DeviceStorageFile> mDsFile;
|
||||||
|
nsRefPtr<DeviceStorageFile> mDummyDsFile;
|
||||||
|
|
||||||
// If a connection has been established, mSocket will be the socket
|
// If a connection has been established, mSocket will be the socket
|
||||||
// communicating with the remote socket. We maintain the invariant that if
|
// communicating with the remote socket. We maintain the invariant that if
|
||||||
|
|
Загрузка…
Ссылка в новой задаче