mirror of
https://github.com/openharmony/miscservices_request.git
synced 2026-07-20 22:58:08 -04:00
1. fix file access permission, 2. add network monitor
Signed-off-by: liulinna <liulinna4@huawei.com>
This commit is contained in:
@@ -40,6 +40,10 @@ public:
|
||||
|
||||
void SetTitle(const std::string &title);
|
||||
|
||||
void SetFD(int32_t fd);
|
||||
|
||||
void SetFDError(int32_t fdError);
|
||||
|
||||
[[nodiscard]] const std::string &GetUrl() const;
|
||||
|
||||
[[nodiscard]] const std::map<std::string, std::string> &GetHeader() const;
|
||||
@@ -56,6 +60,10 @@ public:
|
||||
|
||||
[[nodiscard]] const std::string &GetTitle() const;
|
||||
|
||||
int32_t GetFD() const;
|
||||
|
||||
int32_t GetFDError() const;
|
||||
|
||||
void Dump(bool isFull = true) const;
|
||||
|
||||
private:
|
||||
@@ -74,6 +82,10 @@ private:
|
||||
std::string filePath_;
|
||||
|
||||
std::string title_;
|
||||
|
||||
int32_t fd_;
|
||||
|
||||
int32_t fdError_;
|
||||
};
|
||||
} // namespace OHOS::Request::Download
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
namespace OHOS::Request::Download {
|
||||
DownloadConfig::DownloadConfig()
|
||||
: url_(""), enableMetered_(false), enableRoaming_(false), description_(""), networkType_(0),
|
||||
filePath_(""), title_("") {
|
||||
filePath_(""), title_(""), fd_(-1), fdError_(0) {
|
||||
}
|
||||
|
||||
void DownloadConfig::SetUrl(const std::string &url)
|
||||
@@ -63,6 +63,16 @@ void DownloadConfig::SetTitle(const std::string &title)
|
||||
title_ = title;
|
||||
}
|
||||
|
||||
void DownloadConfig::SetFD(int32_t fd)
|
||||
{
|
||||
fd_ = fd;
|
||||
}
|
||||
|
||||
void DownloadConfig::SetFDError(int32_t fdError)
|
||||
{
|
||||
fdError_ = fdError;
|
||||
}
|
||||
|
||||
const std::string &DownloadConfig::GetUrl() const
|
||||
{
|
||||
return url_;
|
||||
@@ -103,8 +113,20 @@ const std::string &DownloadConfig::GetTitle() const
|
||||
return title_;
|
||||
}
|
||||
|
||||
int32_t DownloadConfig::GetFD() const
|
||||
{
|
||||
return fd_;
|
||||
}
|
||||
|
||||
int32_t DownloadConfig::GetFDError() const
|
||||
{
|
||||
return fdError_;
|
||||
}
|
||||
|
||||
void DownloadConfig::Dump(bool isFull) const
|
||||
{
|
||||
DOWNLOAD_HILOGD("fd: %{public}d", fd_);
|
||||
DOWNLOAD_HILOGD("fd errno: %{public}s", strerror(fdError_));
|
||||
DOWNLOAD_HILOGD("URL: %{public}s", url_.c_str());
|
||||
DOWNLOAD_HILOGD("enableMetered: %{public}s", enableMetered_ ? "true" : "false");
|
||||
DOWNLOAD_HILOGD("enableRoaming: %{public}s", enableRoaming_ ? "true" : "false");
|
||||
|
||||
@@ -13,9 +13,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "download_service_proxy.h"
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "iremote_broker.h"
|
||||
|
||||
#include "log.h"
|
||||
#include "download_common.h"
|
||||
|
||||
@@ -32,6 +35,26 @@ uint32_t DownloadServiceProxy::Request(const DownloadConfig &config)
|
||||
MessageParcel data, reply;
|
||||
MessageOption option;
|
||||
data.WriteInterfaceToken(GetDescriptor());
|
||||
|
||||
int32_t fd = -1;
|
||||
int32_t err = 0;
|
||||
fd = open(config.GetFilePath().c_str(), O_RDWR);
|
||||
if (fd > 0) {
|
||||
DOWNLOAD_HILOGD("File [%{public}s] already exists", config.GetFilePath().c_str());
|
||||
fd = -1;
|
||||
} else {
|
||||
fd = open(config.GetFilePath().c_str(), O_CREAT | O_RDWR, 0644);
|
||||
if (fd < 0) {
|
||||
DOWNLOAD_HILOGD("Failed to open file [%{public}s], errno [%{public}s]",
|
||||
config.GetFilePath().c_str(), strerror(errno));
|
||||
err = errno;
|
||||
}
|
||||
}
|
||||
|
||||
DOWNLOAD_HILOGI("Succeed to open file [%{public}s, fd [%{public}d]]", config.GetFilePath().c_str(), fd);
|
||||
data.WriteFileDescriptor(fd);
|
||||
data.WriteInt32(err);
|
||||
close(fd);
|
||||
data.WriteString(config.GetUrl());
|
||||
data.WriteBool(config.GetMetered());
|
||||
data.WriteBool(config.GetRoaming());
|
||||
|
||||
@@ -156,7 +156,8 @@ bool DownloadTaskNapi::ParseConfig(napi_env env, napi_value configValue, Downloa
|
||||
bool DownloadTaskNapi::ParseHeader(napi_env env, napi_value configValue, DownloadConfig &config)
|
||||
{
|
||||
if (!NapiUtils::HasNamedProperty(env, configValue, PARAM_KEY_HEADER)) {
|
||||
return false;
|
||||
DOWNLOAD_HILOGD("No header present, ignore it");
|
||||
return true;
|
||||
}
|
||||
napi_value header = NapiUtils::GetNamedProperty(env, configValue, PARAM_KEY_HEADER);
|
||||
if (NapiUtils::GetValueType(env, header) != napi_object) {
|
||||
@@ -164,6 +165,7 @@ bool DownloadTaskNapi::ParseHeader(napi_env env, napi_value configValue, Downloa
|
||||
}
|
||||
auto names = NapiUtils::GetPropertyNames(env, header);
|
||||
std::vector<std::string>::iterator iter;
|
||||
DOWNLOAD_HILOGD("current name list size = %{public}d", names.size());
|
||||
for (iter = names.begin(); iter != names.end(); ++iter)
|
||||
{
|
||||
auto value = NapiUtils::GetStringPropertyUtf8(env, header, *iter);
|
||||
|
||||
@@ -56,7 +56,6 @@ private:
|
||||
NONE_QUEUE,
|
||||
PENDING_QUEUE,
|
||||
PAUSED_QUEUE,
|
||||
COMPLETED_QUEUE,
|
||||
};
|
||||
|
||||
uint32_t GetCurrentTaskId();
|
||||
@@ -65,12 +64,15 @@ private:
|
||||
void PushQueue(std::queue<uint32_t> &queue, uint32_t taskId);
|
||||
void RemoveFromQueue(std::queue<uint32_t> &queue, uint32_t taskId);
|
||||
|
||||
bool GetNetworkStatus();
|
||||
void ResumeTaskByNetwork();
|
||||
static void MonitorNetwork(DownloadServiceManager *thisVal);
|
||||
|
||||
private:
|
||||
bool initialized_;
|
||||
std::recursive_mutex mutex_;
|
||||
std::map<uint32_t, std::shared_ptr<DownloadServiceTask>> taskMap_;
|
||||
std::queue<uint32_t> pendingQueue_;
|
||||
std::queue<uint32_t> completedQueue_;
|
||||
std::queue<uint32_t> pausedQueue_;
|
||||
std::vector<std::shared_ptr<DownloadThread>> threadList_;
|
||||
|
||||
@@ -79,6 +81,8 @@ private:
|
||||
uint32_t threadNum_;
|
||||
uint32_t timeoutRetry_;
|
||||
|
||||
std::shared_ptr<std::thread> networkThread_;
|
||||
|
||||
static uint32_t taskId;
|
||||
static std::recursive_mutex instanceLock_;
|
||||
static std::shared_ptr<DownloadServiceManager> instance_;
|
||||
|
||||
@@ -26,9 +26,9 @@ public:
|
||||
int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
|
||||
|
||||
private:
|
||||
bool OnRequest(Parcel &data, Parcel &reply);
|
||||
bool OnPause(Parcel &data, Parcel &reply);
|
||||
bool OnQuery(Parcel &data, Parcel &reply);
|
||||
bool OnRequest(MessageParcel &data, MessageParcel &reply);
|
||||
bool OnPause(MessageParcel &data, MessageParcel &reply);
|
||||
bool OnQuery(MessageParcel &data, MessageParcel &reply);
|
||||
bool OnQueryMimeType(MessageParcel &data, MessageParcel &reply);
|
||||
bool OnRemove(MessageParcel &data, MessageParcel &reply);
|
||||
bool OnResume(MessageParcel &data, MessageParcel &reply);
|
||||
|
||||
@@ -45,6 +45,7 @@ public:
|
||||
void GetRunResult(DownloadStatus &status, ErrorCode &code, PausedReason &reason);
|
||||
|
||||
void SetRetryTime(uint32_t retryTime);
|
||||
void SetNetworkStatus(bool isOnline);
|
||||
|
||||
private:
|
||||
void SetStatus(DownloadStatus status, ErrorCode code, PausedReason reason);
|
||||
@@ -57,6 +58,7 @@ private:
|
||||
void DumpPausedReason();
|
||||
|
||||
bool ExecHttp();
|
||||
bool SetFileSizeOption(CURL *curl, struct curl_slist *requestHeader);
|
||||
bool SetOption(CURL *curl, struct curl_slist *requestHeader);
|
||||
struct curl_slist *MakeHeaders(const std::vector<std::string> &vec);
|
||||
|
||||
@@ -73,6 +75,7 @@ private:
|
||||
|
||||
bool CheckResumeCondition();
|
||||
void ForceStopRunning();
|
||||
bool HandleFileError();
|
||||
|
||||
private:
|
||||
uint32_t taskId_;
|
||||
@@ -93,6 +96,9 @@ private:
|
||||
|
||||
DownloadTaskCallback eventCb_;
|
||||
std::recursive_mutex mutex_;
|
||||
bool hasFileSize_;
|
||||
bool isOnline_;
|
||||
uint32_t prevSize_;
|
||||
};
|
||||
} // namespace OHOS::Request::Download
|
||||
#endif // DOWNLOAD_TASK_H
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
static constexpr uint32_t THREAD_POOL_NUM = 4;
|
||||
static constexpr uint32_t TASK_SLEEP_INTERVAL = 1;
|
||||
static constexpr uint32_t MAX_RETRY_TIMES = 10;
|
||||
static constexpr uint32_t MAX_RETRY_TIMES = 3;
|
||||
|
||||
namespace OHOS::Request::Download {
|
||||
uint32_t DownloadServiceManager::taskId = 1000;
|
||||
@@ -28,7 +28,8 @@ std::recursive_mutex DownloadServiceManager::instanceLock_;
|
||||
std::shared_ptr<DownloadServiceManager> DownloadServiceManager::instance_ = nullptr;
|
||||
|
||||
DownloadServiceManager::DownloadServiceManager()
|
||||
: initialized_(false), interval_(TASK_SLEEP_INTERVAL), threadNum_(THREAD_POOL_NUM), timeoutRetry_(MAX_RETRY_TIMES)
|
||||
: initialized_(false), interval_(TASK_SLEEP_INTERVAL), threadNum_(THREAD_POOL_NUM), timeoutRetry_(MAX_RETRY_TIMES),
|
||||
networkThread_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -66,14 +67,18 @@ bool DownloadServiceManager::Create(uint32_t threadNum)
|
||||
DOWNLOAD_HILOGD("Failed to initialize 'curl'");
|
||||
return false;
|
||||
}
|
||||
networkThread_ = std::make_shared<std::thread>(MonitorNetwork, this);
|
||||
|
||||
initialized_ = true;
|
||||
return initialized_;
|
||||
return initialized_;
|
||||
}
|
||||
|
||||
void DownloadServiceManager::Destroy()
|
||||
{
|
||||
std::for_each(threadList_.begin(), threadList_.end(), [](std::shared_ptr<DownloadThread> t) { t->Stop(); });
|
||||
std::for_each(threadList_.begin(), threadList_.end(), [](auto t) { t->Stop(); });
|
||||
threadList_.clear();
|
||||
initialized_ = false;
|
||||
networkThread_->join();
|
||||
}
|
||||
|
||||
uint32_t DownloadServiceManager::AddTask(const DownloadConfig& config)
|
||||
@@ -121,7 +126,9 @@ bool DownloadServiceManager::ProcessTask()
|
||||
if (pendingQueue_.size() > 0) {
|
||||
taskId = pendingQueue_.front();
|
||||
pendingQueue_.pop();
|
||||
return taskMap_[taskId];
|
||||
if (taskMap_.find(taskId) != taskMap_.end()) {
|
||||
return taskMap_[taskId];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
@@ -142,10 +149,12 @@ bool DownloadServiceManager::Pause(uint32_t taskId)
|
||||
if (!initialized_) {
|
||||
return false;
|
||||
}
|
||||
DOWNLOAD_HILOGD("Pause Task[%{public}d]", taskId);
|
||||
auto it = taskMap_.find(taskId);
|
||||
if (it == taskMap_.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (it->second->Pause()) {
|
||||
MoveTaskToQueue(taskId, it->second);
|
||||
return true;
|
||||
@@ -158,10 +167,12 @@ bool DownloadServiceManager::Resume(uint32_t taskId)
|
||||
if (!initialized_) {
|
||||
return false;
|
||||
}
|
||||
DOWNLOAD_HILOGD("Resume Task[%{public}d]", taskId);
|
||||
auto it = taskMap_.find(taskId);
|
||||
if (it == taskMap_.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (it->second->Resume()) {
|
||||
MoveTaskToQueue(taskId, it->second);
|
||||
return true;
|
||||
@@ -174,17 +185,18 @@ bool DownloadServiceManager::Remove(uint32_t taskId)
|
||||
if (!initialized_) {
|
||||
return false;
|
||||
}
|
||||
DOWNLOAD_HILOGD("Remove Task[%{public}d]", taskId);
|
||||
auto it = taskMap_.find(taskId);
|
||||
if (it == taskMap_.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = it->second->Remove();
|
||||
if (result) {
|
||||
std::lock_guard<std::recursive_mutex> autoLock(mutex_);
|
||||
RemoveFromQueue(pendingQueue_, taskId);
|
||||
RemoveFromQueue(pausedQueue_, taskId);
|
||||
RemoveFromQueue(completedQueue_, taskId);
|
||||
taskMap_.erase(it);
|
||||
RemoveFromQueue(pendingQueue_, taskId);
|
||||
RemoveFromQueue(pausedQueue_, taskId);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -222,24 +234,20 @@ uint32_t DownloadServiceManager::GetCurrentTaskId()
|
||||
DownloadServiceManager::QueueType DownloadServiceManager::DecideQueueType(DownloadStatus status)
|
||||
{
|
||||
switch (status) {
|
||||
case SESSION_PENDING:
|
||||
case SESSION_RUNNING:
|
||||
return QueueType::NONE_QUEUE;
|
||||
|
||||
case SESSION_SUCCESS:
|
||||
return QueueType::COMPLETED_QUEUE;
|
||||
|
||||
case SESSION_PAUSED:
|
||||
return QueueType::PAUSED_QUEUE;
|
||||
|
||||
case SESSION_FAILED:
|
||||
case SESSION_UNKNOWN:
|
||||
return QueueType::PENDING_QUEUE;
|
||||
|
||||
|
||||
case SESSION_PENDING:
|
||||
case SESSION_RUNNING:
|
||||
case SESSION_SUCCESS:
|
||||
case SESSION_FAILED:
|
||||
default:
|
||||
return QueueType::PENDING_QUEUE;
|
||||
return QueueType::NONE_QUEUE;
|
||||
}
|
||||
return QueueType::PENDING_QUEUE;
|
||||
return QueueType::NONE_QUEUE;
|
||||
}
|
||||
|
||||
void DownloadServiceManager::MoveTaskToQueue(uint32_t taskId, std::shared_ptr<DownloadServiceTask> task)
|
||||
@@ -248,28 +256,20 @@ void DownloadServiceManager::MoveTaskToQueue(uint32_t taskId, std::shared_ptr<Do
|
||||
ErrorCode code;
|
||||
PausedReason reason;
|
||||
task->GetRunResult(status, code, reason);
|
||||
DOWNLOAD_HILOGD("Status [%{public}d], Code [%{public}d], Reason [%{public}d]", status, code, reason);
|
||||
switch (DecideQueueType(status)) {
|
||||
case QueueType::PENDING_QUEUE: {
|
||||
std::lock_guard<std::recursive_mutex> autoLock(mutex_);
|
||||
RemoveFromQueue(pausedQueue_, taskId);
|
||||
RemoveFromQueue(completedQueue_, taskId);
|
||||
PushQueue(pendingQueue_, taskId);
|
||||
break;
|
||||
}
|
||||
case QueueType::PAUSED_QUEUE: {
|
||||
std::lock_guard<std::recursive_mutex> autoLock(mutex_);
|
||||
RemoveFromQueue(pendingQueue_, taskId);
|
||||
RemoveFromQueue(completedQueue_, taskId);
|
||||
PushQueue(pausedQueue_, taskId);
|
||||
break;
|
||||
}
|
||||
case QueueType::COMPLETED_QUEUE: {
|
||||
std::lock_guard<std::recursive_mutex> autoLock(mutex_);
|
||||
RemoveFromQueue(pendingQueue_, taskId);
|
||||
RemoveFromQueue(pausedQueue_, taskId);
|
||||
PushQueue(completedQueue_, taskId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
case QueueType::NONE_QUEUE:
|
||||
default:
|
||||
break;
|
||||
@@ -279,6 +279,10 @@ void DownloadServiceManager::MoveTaskToQueue(uint32_t taskId, std::shared_ptr<Do
|
||||
void DownloadServiceManager::PushQueue(std::queue<uint32_t> &queue, uint32_t taskId)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> autoLock(mutex_);
|
||||
if (taskMap_.find(taskId) == taskMap_.end()) {
|
||||
DOWNLOAD_HILOGD("invalid task id [%{public}d]", taskId);
|
||||
return;
|
||||
}
|
||||
bool foundIt = false;
|
||||
if (queue.size() > 0) {
|
||||
uint32_t indicatorId = queue.front();
|
||||
@@ -318,4 +322,74 @@ uint32_t DownloadServiceManager::GetInterval() const
|
||||
{
|
||||
return interval_;
|
||||
}
|
||||
|
||||
bool DownloadServiceManager::GetNetworkStatus()
|
||||
{
|
||||
bool isOnline = false;
|
||||
std::unique_ptr<CURL, decltype(&curl_easy_cleanup)> handle(curl_easy_init(), curl_easy_cleanup);
|
||||
|
||||
if (!handle) {
|
||||
DOWNLOAD_HILOGD("Failed to create network monitor task");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string example = "www.example.com";
|
||||
curl_easy_setopt(handle.get(), CURLOPT_URL, example.c_str());
|
||||
CURLcode code = curl_easy_perform(handle.get());
|
||||
if (code == CURLE_OK) {
|
||||
DOWNLOAD_HILOGD("Network status is online");
|
||||
isOnline = true;
|
||||
}
|
||||
return isOnline;
|
||||
}
|
||||
|
||||
void DownloadServiceManager::ResumeTaskByNetwork()
|
||||
{
|
||||
int taskCount = 0;
|
||||
std::lock_guard<std::recursive_mutex> autoLock(mutex_);
|
||||
if (pausedQueue_.size() > 0) {
|
||||
size_t size = pausedQueue_.size();
|
||||
while (size-- > 0) {
|
||||
uint32_t taskId = pausedQueue_.front();
|
||||
if (taskMap_.find(taskId) != taskMap_.end()) {
|
||||
pausedQueue_.pop();
|
||||
|
||||
auto task = taskMap_[taskId];
|
||||
DownloadStatus status;
|
||||
ErrorCode code;
|
||||
PausedReason reason;
|
||||
task->GetRunResult(status, code, reason);
|
||||
|
||||
if (reason != PAUSED_BY_USER) {
|
||||
task->Resume();
|
||||
PushQueue(pendingQueue_, taskId);
|
||||
taskCount++;
|
||||
} else {
|
||||
pausedQueue_.push(taskId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DOWNLOAD_HILOGD("[%{public}d] task has been resumed by network status changed", taskCount);
|
||||
}
|
||||
|
||||
void DownloadServiceManager::MonitorNetwork(DownloadServiceManager *thisVal)
|
||||
{
|
||||
bool isOnline = true;
|
||||
bool currentStatus = true;
|
||||
|
||||
while (thisVal->initialized_) {
|
||||
currentStatus = thisVal->GetNetworkStatus();
|
||||
if (!isOnline && currentStatus) {
|
||||
// offline --> online
|
||||
if (thisVal) {
|
||||
thisVal->ResumeTaskByNetwork();
|
||||
}
|
||||
}
|
||||
isOnline = currentStatus;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
std::this_thread::yield();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OHOS::Request::Download
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#include "download_service_stub.h"
|
||||
#include "ipc_skeleton.h"
|
||||
#include "parcel.h"
|
||||
#include "message_parcel.h"
|
||||
#include "download_common.h"
|
||||
#include "download_service_interface.h"
|
||||
#include "log.h"
|
||||
@@ -62,10 +62,14 @@ int32_t DownloadServiceStub::OnRemoteRequest(
|
||||
return E_DOWNLOAD_OK;
|
||||
}
|
||||
|
||||
bool DownloadServiceStub::OnRequest(Parcel &data, Parcel &reply)
|
||||
bool DownloadServiceStub::OnRequest(MessageParcel &data, MessageParcel &reply)
|
||||
{
|
||||
DOWNLOAD_HILOGD("Receive request");
|
||||
DownloadConfig config;
|
||||
int32_t fd = data.ReadFileDescriptor();
|
||||
DOWNLOAD_HILOGI("Get FD from client, fd [%{public}d]", fd);
|
||||
config.SetFD(fd);
|
||||
config.SetFDError(data.ReadInt32());
|
||||
config.SetUrl(data.ReadString());
|
||||
config.SetMetered(data.ReadBool());
|
||||
config.SetRoaming(data.ReadBool());
|
||||
@@ -88,7 +92,7 @@ bool DownloadServiceStub::OnRequest(Parcel &data, Parcel &reply)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DownloadServiceStub::OnPause(Parcel &data, Parcel &reply)
|
||||
bool DownloadServiceStub::OnPause(MessageParcel &data, MessageParcel &reply)
|
||||
{
|
||||
bool result = Pause(data.ReadUint32());
|
||||
if (!reply.WriteBool(result)) {
|
||||
@@ -98,7 +102,7 @@ bool DownloadServiceStub::OnPause(Parcel &data, Parcel &reply)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DownloadServiceStub::OnQuery(Parcel &data, Parcel &reply)
|
||||
bool DownloadServiceStub::OnQuery(MessageParcel &data, MessageParcel &reply)
|
||||
{
|
||||
DownloadInfo info;
|
||||
bool result = Query(data.ReadUint32(), info);
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
#include "download_service_task.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include "constant.h"
|
||||
#include "log.h"
|
||||
|
||||
@@ -23,7 +26,7 @@ namespace OHOS::Request::Download {
|
||||
DownloadServiceTask::DownloadServiceTask(uint32_t taskId, const DownloadConfig &config)
|
||||
: taskId_(taskId), config_(config), status_(SESSION_UNKNOWN), code_(ERROR_UNKNOWN), reason_(PAUSED_UNKNOWN),
|
||||
mimeType_(""), file_(nullptr), totalSize_(0), downloadSize_(0), isPartialMode_(false), forceStop_(false),
|
||||
isRemoved_(false), retryTime_(10), eventCb_(nullptr) {
|
||||
isRemoved_(false), retryTime_(10), eventCb_(nullptr), hasFileSize_(false), isOnline_(true), prevSize_(0) {
|
||||
}
|
||||
|
||||
DownloadServiceTask::~DownloadServiceTask(void)
|
||||
@@ -33,6 +36,10 @@ DownloadServiceTask::~DownloadServiceTask(void)
|
||||
fflush(file_);
|
||||
fclose(file_);
|
||||
}
|
||||
if (config_.GetFD() > 0) {
|
||||
close(config_.GetFD());
|
||||
config_.SetFD(-1);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t DownloadServiceTask::GetId() const
|
||||
@@ -43,59 +50,70 @@ uint32_t DownloadServiceTask::GetId() const
|
||||
bool DownloadServiceTask::Run()
|
||||
{
|
||||
DOWNLOAD_HILOGD("Task[%{public}d] start.", taskId_);
|
||||
std::lock_guard<std::recursive_mutex> autoLock(mutex_);
|
||||
if (!GetFileSize(totalSize_)) {
|
||||
SetStatus(SESSION_PENDING, ERROR_UNKNOWN, reason_);
|
||||
if (HandleFileError()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t retryTime = 0;
|
||||
bool result = true;
|
||||
bool enableTimeout;
|
||||
bool result = false;
|
||||
bool enableTimeout = false;
|
||||
SetStatus(SESSION_RUNNING);
|
||||
|
||||
do {
|
||||
enableTimeout = false;
|
||||
SetStatus(SESSION_RUNNING);
|
||||
result = ExecHttp();
|
||||
if (status_ != SESSION_RUNNING && status_ != SESSION_PENDING) {
|
||||
break;
|
||||
}
|
||||
if (GetFileSize(totalSize_)) {
|
||||
result = ExecHttp();
|
||||
}
|
||||
DumpStatus();
|
||||
DumpErrorCode();
|
||||
DumpPausedReason();
|
||||
|
||||
// HTTP timeout occurs, retry
|
||||
if (status_ == SESSION_PENDING) {
|
||||
enableTimeout = true;
|
||||
retryTime++;
|
||||
}
|
||||
} while (!result && enableTimeout && retryTime < retryTime_);
|
||||
if (retryTime >= retryTime_) {
|
||||
SetStatus(SESSION_PAUSED, ERROR_UNKNOWN, PAUSED_WAITING_TO_RETRY);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DownloadServiceTask::Pause()
|
||||
{
|
||||
DOWNLOAD_HILOGD("Pause Task[%{public}d], current status is %{public}d\n", taskId_, status_);
|
||||
DOWNLOAD_HILOGD("Status [%{public}d], Code [%{public}d], Reason [%{public}d]", status_, code_, reason_);
|
||||
if (status_ != SESSION_RUNNING && status_ != SESSION_PENDING) {
|
||||
return false;
|
||||
}
|
||||
ForceStopRunning();
|
||||
|
||||
SetStatus(SESSION_PAUSED);
|
||||
SetStatus(SESSION_PAUSED, ERROR_UNKNOWN, PAUSED_BY_USER);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DownloadServiceTask::Resume()
|
||||
{
|
||||
DOWNLOAD_HILOGD("Resume Task[%{public}d], current status is %{public}d\n", taskId_, status_);
|
||||
if (status_ != SESSION_PAUSED) {
|
||||
return false;
|
||||
}
|
||||
ForceStopRunning();
|
||||
if (!CheckResumeCondition()) {
|
||||
SetStatus(SESSION_FAILED, ERROR_CANNOT_RESUME, reason_);
|
||||
DOWNLOAD_HILOGD("Status [%{public}d], Code [%{public}d], Reason [%{public}d]", status_, code_, reason_);
|
||||
if (status_ == SESSION_PAUSED || (status_ == SESSION_FAILED && code_ == ERROR_CANNOT_RESUME)) {
|
||||
forceStop_ = false;
|
||||
if (!CheckResumeCondition()) {
|
||||
SetStatus(SESSION_FAILED, ERROR_CANNOT_RESUME, PAUSED_UNKNOWN);
|
||||
} else {
|
||||
// reset status
|
||||
SetStatus(SESSION_UNKNOWN, ERROR_UNKNOWN, PAUSED_UNKNOWN);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
SetStatus(SESSION_UNKNOWN, code_, reason_);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DownloadServiceTask::Remove()
|
||||
{
|
||||
DOWNLOAD_HILOGD("Remove Task[%{public}d], current status is %{public}d\n", taskId_, status_);
|
||||
DOWNLOAD_HILOGD("Status [%{public}d], Code [%{public}d], Reason [%{public}d]", status_, code_, reason_);
|
||||
isRemoved_ = true;
|
||||
ForceStopRunning();
|
||||
if (eventCb_ != nullptr) {
|
||||
@@ -147,11 +165,19 @@ void DownloadServiceTask::SetRetryTime(uint32_t retryTime)
|
||||
retryTime_ = retryTime;
|
||||
}
|
||||
|
||||
void DownloadServiceTask::SetNetworkStatus(bool isOnline)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> autoLock(mutex_);
|
||||
isOnline_ = isOnline;
|
||||
if (status_ == SESSION_PAUSED && reason_ == PAUSED_WAITING_TO_RETRY && !isOnline_) {
|
||||
reason_ = PAUSED_WAITING_FOR_NETWORK;
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadServiceTask::SetStatus(DownloadStatus status, ErrorCode code, PausedReason reason)
|
||||
{
|
||||
auto stateChange = [this](DownloadStatus status, ErrorCode code, PausedReason reason) -> bool {
|
||||
std::lock_guard<std::recursive_mutex> autoLock(mutex_);
|
||||
this->forceStop_ = false;
|
||||
bool isChanged = false;
|
||||
if (status != this->status_) {
|
||||
this->status_ = status;
|
||||
@@ -161,16 +187,24 @@ void DownloadServiceTask::SetStatus(DownloadStatus status, ErrorCode code, Pause
|
||||
this->code_ = code;
|
||||
isChanged = true;
|
||||
}
|
||||
if (reason != this->reason_) {
|
||||
this->reason_ = reason;
|
||||
isChanged = true;
|
||||
if (this->reason_ != PAUSED_BY_USER) {
|
||||
if (!isOnline_ && reason == PAUSED_WAITING_TO_RETRY) {
|
||||
reason = PAUSED_WAITING_FOR_NETWORK;
|
||||
}
|
||||
if (reason != this->reason_) {
|
||||
this->reason_ = reason;
|
||||
isChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
DOWNLOAD_HILOGD("Status [%{public}d], Code [%{public}d], Reason [%{public}d]", status, code, reason);
|
||||
if (!stateChange(status, code, reason)) {
|
||||
return;
|
||||
}
|
||||
if (eventCb_ != nullptr) {
|
||||
std::lock_guard<std::recursive_mutex> autoLock(mutex_);
|
||||
switch (status_) {
|
||||
case SESSION_SUCCESS:
|
||||
eventCb_("complete", taskId_, 0, 0);
|
||||
@@ -194,7 +228,6 @@ void DownloadServiceTask::SetStatus(DownloadStatus status)
|
||||
{
|
||||
auto stateChange = [this](DownloadStatus status) -> bool {
|
||||
std::lock_guard<std::recursive_mutex> autoLock(mutex_);
|
||||
this->forceStop_ = false;
|
||||
if (status == this->status_) {
|
||||
DOWNLOAD_HILOGD("ignore same status");
|
||||
return false;
|
||||
@@ -202,10 +235,12 @@ void DownloadServiceTask::SetStatus(DownloadStatus status)
|
||||
this->status_ = status;
|
||||
return true;
|
||||
};
|
||||
DOWNLOAD_HILOGD("Status [%{public}d]", status);
|
||||
if (!stateChange(status)) {
|
||||
return;
|
||||
}
|
||||
if (eventCb_ != nullptr) {
|
||||
std::lock_guard<std::recursive_mutex> autoLock(mutex_);
|
||||
switch (status_) {
|
||||
case SESSION_SUCCESS:
|
||||
eventCb_("complete", taskId_, 0, 0);
|
||||
@@ -227,8 +262,8 @@ void DownloadServiceTask::SetStatus(DownloadStatus status)
|
||||
|
||||
void DownloadServiceTask::SetError(ErrorCode code)
|
||||
{
|
||||
DOWNLOAD_HILOGD("Code [%{public}d]", code);
|
||||
std::lock_guard<std::recursive_mutex> autoLock(mutex_);
|
||||
this->forceStop_ = false;
|
||||
if (code == code_) {
|
||||
DOWNLOAD_HILOGD("ignore same error code");
|
||||
return;
|
||||
@@ -238,13 +273,19 @@ void DownloadServiceTask::SetError(ErrorCode code)
|
||||
|
||||
void DownloadServiceTask::SetReason(PausedReason reason)
|
||||
{
|
||||
DOWNLOAD_HILOGD("Reason [%{public}d]", reason);
|
||||
std::lock_guard<std::recursive_mutex> autoLock(mutex_);
|
||||
this->forceStop_ = false;
|
||||
if (reason == reason_) {
|
||||
DOWNLOAD_HILOGD("ignore same paused reason");
|
||||
return;
|
||||
}
|
||||
reason_ = reason;
|
||||
|
||||
if (reason_ != PAUSED_BY_USER) {
|
||||
if (!isOnline_ && reason == PAUSED_WAITING_TO_RETRY) {
|
||||
reason = PAUSED_WAITING_FOR_NETWORK;
|
||||
}
|
||||
if (reason == reason_) {
|
||||
DOWNLOAD_HILOGD("ignore same paused reason");
|
||||
return;
|
||||
}
|
||||
reason_ = reason;
|
||||
}
|
||||
}
|
||||
|
||||
void DownloadServiceTask::DumpStatus()
|
||||
@@ -358,8 +399,11 @@ size_t DownloadServiceTask::WriteCallback(void *buffer, size_t size, size_t num,
|
||||
{
|
||||
size_t result = 0;
|
||||
DownloadServiceTask *this_ = static_cast<DownloadServiceTask *>(param);
|
||||
if (this_ != nullptr && this_->file_) {
|
||||
result = fwrite(buffer, size, num, this_->file_);
|
||||
if (this_ != nullptr && this_->config_.GetFD() > 0) {
|
||||
result = write(this_->config_.GetFD(), buffer, size * num);
|
||||
if (result < size * num) {
|
||||
DOWNLOAD_HILOGE("origin size = %{pulic}d, write size = %{pulic}d", size * num, result);
|
||||
}
|
||||
this_->downloadSize_ += static_cast<uint32_t>(result);
|
||||
}
|
||||
return result;
|
||||
@@ -384,12 +428,18 @@ int DownloadServiceTask::ProgressCallback(void *pParam, double dltotal, double d
|
||||
if (this_->isRemoved_) {
|
||||
DOWNLOAD_HILOGD("download task has been removed\n");
|
||||
}
|
||||
if (this_->eventCb_ != nullptr && !this_->isRemoved_) {
|
||||
this_->eventCb_("progress", this_->taskId_, this_->downloadSize_, this_->totalSize_);
|
||||
}
|
||||
if (this_->forceStop_) {
|
||||
DOWNLOAD_HILOGD("Pause issued by user\n");
|
||||
return HTTP_FORCE_STOP;
|
||||
}
|
||||
if (this_->eventCb_ != nullptr && !this_->isRemoved_) {
|
||||
if (this_->prevSize_ != this_->downloadSize_) {
|
||||
std::lock_guard<std::recursive_mutex> autoLock(this_->mutex_);
|
||||
if (this_->status_ != SESSION_PAUSED) {
|
||||
this_->eventCb_("progress", this_->taskId_, this_->downloadSize_, this_->totalSize_);
|
||||
this_->prevSize_ = this_->downloadSize_;
|
||||
}
|
||||
}
|
||||
}
|
||||
// calc the download speed
|
||||
}
|
||||
@@ -418,29 +468,29 @@ bool DownloadServiceTask::ExecHttp()
|
||||
DOWNLOAD_HILOGD("set option failed");
|
||||
return false;
|
||||
}
|
||||
std::string tmpFileName = GetTmpPath().c_str();
|
||||
file_ = fopen(tmpFileName.c_str(), "ab");
|
||||
if (file_ != nullptr) {
|
||||
DOWNLOAD_HILOGD("Succeed to open %{public}s", tmpFileName.c_str());
|
||||
fseek(file_, 0, SEEK_END);
|
||||
uint32_t pos = ftell(file_);
|
||||
|
||||
if (config_.GetFD() > 0) {
|
||||
DOWNLOAD_HILOGD("Succeed to open %{public}s", config_.GetFilePath().c_str());
|
||||
uint64_t pos = lseek(config_.GetFD(), 0, SEEK_END);
|
||||
downloadSize_ = 0;
|
||||
if (pos > 0) {
|
||||
if (pos < totalSize_) {
|
||||
isPartialMode_ = true;
|
||||
downloadSize_ = static_cast<uint32_t>(pos);
|
||||
SetResumeFromLarge(handle.get(), pos);
|
||||
} else if (pos == totalSize_) {
|
||||
} else if (pos >= totalSize_) {
|
||||
downloadSize_ = totalSize_;
|
||||
DOWNLOAD_HILOGD("Download task has already completed");
|
||||
SetStatus(SESSION_SUCCESS);
|
||||
return true;
|
||||
} else {
|
||||
DOWNLOAD_HILOGD("Download size exceed the file size, re-download it");
|
||||
fclose(file_);
|
||||
file_ = fopen(tmpFileName.c_str(), "wb");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
prevSize_ = downloadSize_;
|
||||
} else {
|
||||
DOWNLOAD_HILOGD("Failed to open %{public}s", tmpFileName.c_str());
|
||||
DOWNLOAD_HILOGD("Failed to open %{public}s", config_.GetFilePath().c_str());
|
||||
}
|
||||
|
||||
CURLcode code = curl_easy_perform(handle.get());
|
||||
@@ -456,6 +506,51 @@ bool DownloadServiceTask::ExecHttp()
|
||||
return code == CURLE_OK;
|
||||
}
|
||||
|
||||
bool DownloadServiceTask::SetFileSizeOption(CURL *curl, struct curl_slist *requestHeader)
|
||||
{
|
||||
curl_easy_setopt(curl, CURLOPT_URL, config_.GetUrl().c_str());
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, HeaderCallback);
|
||||
curl_easy_setopt(curl, CURLOPT_HEADERDATA, this);
|
||||
|
||||
if (requestHeader != nullptr) {
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, requestHeader);
|
||||
}
|
||||
// Some servers don't like requests that are made without a user-agent field, so we provide one
|
||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, HTTP_DEFAULT_USER_AGENT);
|
||||
#if 1
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
|
||||
/* first #undef CURL_DISABLE_COOKIES in curl config */
|
||||
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "");
|
||||
|
||||
#ifdef DOWNLOAD_USE_PROXY
|
||||
curl_easy_setopt(curl, CURLOPT_PROXY, HTTP_PROXY_URL_PORT);
|
||||
curl_easy_setopt(curl, CURLOPT_PROXYTYPE, HTTP_PROXY_TYPE);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, 1L);
|
||||
#ifdef DOWNLOAD_PROXY_PASS
|
||||
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, HTTP_PROXY_PASS);
|
||||
#endif // DOWNLOAD_PROXY_PASS
|
||||
#endif // DOWNLOAD_USE_PROXY
|
||||
|
||||
#ifdef DOWNLOAD_SSL_CERTIFICATION
|
||||
curl_easy_setopt(curl, CURLOPT_CAINFO, HTTP_DEFAULT_CA_PATH);
|
||||
#else
|
||||
// NO_SSL_CERTIFICATION
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
#endif
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
|
||||
#if HTTP_CURL_PRINT_VERBOSE
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L, context);
|
||||
#endif
|
||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, DEFAULT_READ_TIMEOUT);
|
||||
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, DEFAULT_CONNECT_TIMEOUT);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DownloadServiceTask::SetOption(CURL *curl, struct curl_slist *requestHeader)
|
||||
{
|
||||
curl_easy_setopt(curl, CURLOPT_URL, config_.GetUrl().c_str());
|
||||
@@ -525,7 +620,7 @@ void DownloadServiceTask::SetResumeFromLarge(CURL *curl, long long pos)
|
||||
|
||||
bool DownloadServiceTask::GetFileSize(uint32_t &result)
|
||||
{
|
||||
if (totalSize_) {
|
||||
if (hasFileSize_) {
|
||||
DOWNLOAD_HILOGD("Already get file size");
|
||||
return true;
|
||||
}
|
||||
@@ -544,23 +639,30 @@ bool DownloadServiceTask::GetFileSize(uint32_t &result)
|
||||
});
|
||||
std::unique_ptr<struct curl_slist, decltype(&curl_slist_free_all)> header(MakeHeaders(vec), curl_slist_free_all);
|
||||
|
||||
if (!SetOption(handle.get(), header.get())) {
|
||||
if (!SetFileSizeOption(handle.get(), header.get())) {
|
||||
DOWNLOAD_HILOGD("set option failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
curl_easy_setopt(handle.get(), CURLOPT_NOBODY, 1L);
|
||||
CURLcode res;
|
||||
curl_easy_perform(handle.get());
|
||||
res = curl_easy_getinfo(handle.get(), CURLINFO_CONTENT_LENGTH_DOWNLOAD, &size);
|
||||
if (res == CURLE_OK) {
|
||||
CURLcode code = curl_easy_perform(handle.get());
|
||||
curl_easy_getinfo(handle.get(), CURLINFO_CONTENT_LENGTH_DOWNLOAD, &size);
|
||||
|
||||
if (code == CURLE_OK) {
|
||||
result = static_cast<long long>(size);
|
||||
if (result == static_cast<uint32_t>(-1)) {
|
||||
result = 0;
|
||||
}
|
||||
hasFileSize_ = true;
|
||||
DOWNLOAD_HILOGD("Has got file size");
|
||||
} else {
|
||||
if (status_ == SESSION_RUNNING || status_ == SESSION_PENDING) {
|
||||
SetStatus(SESSION_PENDING, ERROR_UNKNOWN, PAUSED_UNKNOWN);
|
||||
}
|
||||
}
|
||||
if (result == -1) {
|
||||
result = 0;
|
||||
}
|
||||
|
||||
DOWNLOAD_HILOGD("fetch file size %{public}d", result);
|
||||
return true;
|
||||
return hasFileSize_;
|
||||
}
|
||||
|
||||
std::string DownloadServiceTask::GetTmpPath()
|
||||
@@ -574,22 +676,41 @@ void DownloadServiceTask::HandleResponseCode(CURLcode code, int32_t httpCode)
|
||||
DOWNLOAD_HILOGD("download task has been removed");
|
||||
return;
|
||||
}
|
||||
DOWNLOAD_HILOGD("Current CURLcode is %{public}d, httpCode is %{public}d\n", code, httpCode);
|
||||
if (status_ == SESSION_PAUSED && reason_ == PAUSED_BY_USER) {
|
||||
DOWNLOAD_HILOGD("Pause By User:ignore status changed caused by libcurl");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (code) {
|
||||
case CURLE_OK:
|
||||
if (httpCode == HTTP_OK || (isPartialMode_ && httpCode == HTTP_PARIAL_FILE)) {
|
||||
SetStatus(SESSION_SUCCESS);
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CURLE_ABORTED_BY_CALLBACK:
|
||||
if (httpCode == HTTP_OK || (isPartialMode_ && httpCode == HTTP_PARIAL_FILE)) {
|
||||
SetStatus(SESSION_PAUSED, code_, PAUSED_BY_USER);
|
||||
SetStatus(SESSION_PAUSED, ERROR_UNKNOWN, PAUSED_BY_USER);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case CURLE_WRITE_ERROR:
|
||||
if (httpCode == HTTP_OK || (isPartialMode_ && httpCode == HTTP_PARIAL_FILE)) {
|
||||
SetStatus(SESSION_FAILED, ERROR_HTTP_DATA_ERROR, PAUSED_UNKNOWN);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case CURLE_TOO_MANY_REDIRECTS:
|
||||
SetStatus(SESSION_FAILED, ERROR_TOO_MANY_REDIRECTS, reason_);
|
||||
SetStatus(SESSION_FAILED, ERROR_TOO_MANY_REDIRECTS, PAUSED_UNKNOWN);
|
||||
return;
|
||||
|
||||
case CURLE_COULDNT_RESOLVE_PROXY:
|
||||
case CURLE_COULDNT_RESOLVE_HOST:
|
||||
case CURLE_COULDNT_CONNECT:
|
||||
case CURLE_OPERATION_TIMEDOUT:
|
||||
SetStatus(SESSION_PENDING);
|
||||
return;
|
||||
@@ -597,13 +718,14 @@ void DownloadServiceTask::HandleResponseCode(CURLcode code, int32_t httpCode)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
DOWNLOAD_HILOGD("Current CURLcode is %{public}d, httpCode is %{public}d\n", code, httpCode);
|
||||
SetStatus(SESSION_FAILED, ERROR_UNHANDLED_HTTP_CODE, reason_);
|
||||
SetStatus(SESSION_FAILED, ERROR_UNHANDLED_HTTP_CODE, PAUSED_UNKNOWN);
|
||||
}
|
||||
|
||||
bool DownloadServiceTask::CheckResumeCondition()
|
||||
{
|
||||
// current paused issued by user
|
||||
if (!isOnline_) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -611,12 +733,16 @@ void DownloadServiceTask::ForceStopRunning()
|
||||
{
|
||||
forceStop_ = true;
|
||||
}
|
||||
|
||||
void DownloadServiceTask::HandleCleanup(DownloadStatus status)
|
||||
{
|
||||
switch (status) {
|
||||
case SESSION_SUCCESS:
|
||||
// rename download to target file name
|
||||
rename(GetTmpPath().c_str(), config_.GetFilePath().c_str());
|
||||
if (config_.GetFD() > 0) {
|
||||
close(config_.GetFD());
|
||||
config_.SetFD(-1);
|
||||
}
|
||||
break;
|
||||
|
||||
case SESSION_FAILED:
|
||||
@@ -626,4 +752,30 @@ void DownloadServiceTask::HandleCleanup(DownloadStatus status)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool DownloadServiceTask::HandleFileError()
|
||||
{
|
||||
|
||||
ErrorCode code = ERROR_UNKNOWN;
|
||||
|
||||
if (config_.GetFD() < 0) {
|
||||
switch (config_.GetFDError()) {
|
||||
case 0:
|
||||
DOWNLOAD_HILOGD("File [%{public}s] already exists", config_.GetFilePath().c_str());
|
||||
code = ERROR_FILE_ALREADY_EXISTS;
|
||||
break;
|
||||
|
||||
case ENODEV:
|
||||
code = ERROR_DEVICE_NOT_FOUND;
|
||||
break;
|
||||
|
||||
default:
|
||||
code = ERROR_FILE_ERROR;
|
||||
break;
|
||||
}
|
||||
SetStatus(SESSION_FAILED, code, PAUSED_UNKNOWN);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace OHOS::Request::Download
|
||||
|
||||
@@ -40,6 +40,7 @@ static napi_value paused_queue_wifi = nullptr;
|
||||
static napi_value paused_for_network = nullptr;
|
||||
static napi_value paused_to_retry = nullptr;
|
||||
static napi_value paused_by_user = nullptr;
|
||||
static napi_value paused_unknown = nullptr;
|
||||
static napi_value session_success = nullptr;
|
||||
static napi_value session_running = nullptr;
|
||||
static napi_value session_pending = nullptr;
|
||||
@@ -68,6 +69,7 @@ static napi_value Init(napi_env env, napi_value exports)
|
||||
napi_create_int32(env, static_cast<int32_t>(PAUSED_WAITING_FOR_NETWORK), &paused_for_network);
|
||||
napi_create_int32(env, static_cast<int32_t>(PAUSED_WAITING_TO_RETRY), &paused_to_retry);
|
||||
napi_create_int32(env, static_cast<int32_t>(PAUSED_BY_USER), &paused_by_user);
|
||||
napi_create_int32(env, static_cast<int32_t>(PAUSED_UNKNOWN), &paused_unknown);
|
||||
|
||||
/* Create session status Const */
|
||||
napi_create_int32(env, static_cast<int32_t>(SESSION_SUCCESS), &session_success);
|
||||
@@ -94,8 +96,9 @@ static napi_value Init(napi_env env, napi_value exports)
|
||||
DECLARE_NAPI_STATIC_PROPERTY("PAUSED_WAITING_FOR_NETWORK", paused_for_network),
|
||||
DECLARE_NAPI_STATIC_PROPERTY("PAUSED_WAITING_TO_RETRY", paused_to_retry),
|
||||
DECLARE_NAPI_STATIC_PROPERTY("PAUSED_BY_USER", paused_by_user),
|
||||
DECLARE_NAPI_STATIC_PROPERTY("PAUSED_UNKNOWN", paused_unknown),
|
||||
|
||||
DECLARE_NAPI_STATIC_PROPERTY("SESSION_SUCCESS", session_success),
|
||||
DECLARE_NAPI_STATIC_PROPERTY("SESSION_SUCCESSFUL", session_success),
|
||||
DECLARE_NAPI_STATIC_PROPERTY("SESSION_RUNNING", session_running),
|
||||
DECLARE_NAPI_STATIC_PROPERTY("SESSION_PENDING", session_pending),
|
||||
DECLARE_NAPI_STATIC_PROPERTY("SESSION_PAUSED", session_paused),
|
||||
|
||||
Reference in New Issue
Block a user