1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "cloud/assets_download_manager.h"
16
17 #include "cloud/cloud_db_constant.h"
18 #include "db_errno.h"
19 #include "log_print.h"
20 namespace DistributedDB {
AssetsDownloadManager()21 AssetsDownloadManager::AssetsDownloadManager()
22 : notificationChain_(nullptr), currentDownloadCount_(0)
23 {
24 }
25
~AssetsDownloadManager()26 AssetsDownloadManager::~AssetsDownloadManager()
27 {
28 NotificationChain *notificationChain = nullptr;
29 {
30 std::lock_guard<std::mutex> autoLock(notifyMutex_);
31 if (notificationChain_ == nullptr) {
32 return;
33 }
34 notificationChain = notificationChain_;
35 notificationChain_ = nullptr;
36 }
37 RefObject::KillAndDecObjRef(notificationChain);
38 }
39
SetAsyncDownloadAssetsConfig(const AsyncDownloadAssetsConfig & config)40 int AssetsDownloadManager::SetAsyncDownloadAssetsConfig(const AsyncDownloadAssetsConfig &config)
41 {
42 if (config.maxDownloadTask < CloudDbConstant::MIN_ASYNC_DOWNLOAD_TASK ||
43 config.maxDownloadTask > CloudDbConstant::MAX_ASYNC_DOWNLOAD_TASK) {
44 LOGE("[AssetsDownloadManager] Invalid max download task %" PRIu32, config.maxDownloadTask);
45 return -E_INVALID_ARGS;
46 }
47 if (config.maxDownloadAssetsCount < CloudDbConstant::MIN_ASYNC_DOWNLOAD_ASSETS ||
48 config.maxDownloadAssetsCount > CloudDbConstant::MAX_ASYNC_DOWNLOAD_ASSETS) {
49 LOGE("[AssetsDownloadManager] Invalid max download asset count %" PRIu32, config.maxDownloadAssetsCount);
50 return -E_INVALID_ARGS;
51 }
52 std::lock_guard<std::mutex> autoLock(dataMutex_);
53 config_ = config;
54 LOGI("[AssetsDownloadManager] Config max task %" PRIu32 " max count %" PRIu32,
55 config.maxDownloadTask, config.maxDownloadAssetsCount);
56 return E_OK;
57 }
58
BeginDownloadWithListener(const FinishAction & finishAction,const FinalizeAction & finalizeAction)59 std::pair<int, NotificationChain::Listener*> AssetsDownloadManager::BeginDownloadWithListener(
60 const FinishAction &finishAction, const FinalizeAction &finalizeAction)
61 {
62 std::lock_guard<std::mutex> autoLock(dataMutex_);
63 if (currentDownloadCount_ < config_.maxDownloadTask) {
64 currentDownloadCount_++;
65 LOGI("[AssetsDownloadManager] Begin download task now %" PRIu32, currentDownloadCount_);
66 return {E_OK, nullptr};
67 }
68 LOGW("[AssetsDownloadManager] Too muck download task now %" PRIu32, currentDownloadCount_);
69 NotificationChain *notificationChain = nullptr;
70 int errCode = E_OK;
71 {
72 std::lock_guard<std::mutex> notifyLock(notifyMutex_);
73 errCode = InitNotificationChain();
74 if (errCode != E_OK) {
75 return {errCode, nullptr};
76 }
77 notificationChain = notificationChain_;
78 RefObject::IncObjRef(notificationChain);
79 }
80 NotificationChain::Listener *listener =
81 notificationChain->RegisterListener(DOWNLOAD_FINISH_EVENT, finishAction, finalizeAction, errCode);
82 RefObject::DecObjRef(notificationChain);
83 if (errCode != E_OK) {
84 LOGW("[AssetsDownloadManager] Register listener failed %d", errCode);
85 } else {
86 errCode = -E_MAX_LIMITS;
87 }
88 return {errCode, listener};
89 }
90
FinishDownload()91 void AssetsDownloadManager::FinishDownload()
92 {
93 NotificationChain *notificationChain = nullptr;
94 {
95 std::lock_guard<std::mutex> autoLock(notifyMutex_);
96 notificationChain = notificationChain_;
97 RefObject::IncObjRef(notificationChain);
98 }
99 {
100 std::lock_guard<std::mutex> autoLock(dataMutex_);
101 currentDownloadCount_--;
102 }
103 if (notificationChain != nullptr) {
104 notificationChain->NotifyEvent(DOWNLOAD_FINISH_EVENT, nullptr);
105 }
106 RefObject::DecObjRef(notificationChain);
107 LOGI("[AssetsDownloadManager] NotifyDownloadFinish currentDownloadCount %" PRIu32, currentDownloadCount_);
108 }
109
GetCurrentDownloadCount()110 uint32_t AssetsDownloadManager::GetCurrentDownloadCount()
111 {
112 std::lock_guard<std::mutex> autoLock(dataMutex_);
113 return currentDownloadCount_;
114 }
115
GetMaxDownloadAssetsCount() const116 uint32_t AssetsDownloadManager::GetMaxDownloadAssetsCount() const
117 {
118 std::lock_guard<std::mutex> autoLock(dataMutex_);
119 return config_.maxDownloadAssetsCount;
120 }
121
CanStartNewTask() const122 bool AssetsDownloadManager::CanStartNewTask() const
123 {
124 std::lock_guard<std::mutex> autoLock(dataMutex_);
125 return config_.maxDownloadTask > currentDownloadCount_;
126 }
127
InitNotificationChain()128 int AssetsDownloadManager::InitNotificationChain()
129 {
130 if (notificationChain_ != nullptr) {
131 return E_OK;
132 }
133 notificationChain_ = new(std::nothrow) NotificationChain();
134 if (notificationChain_ == nullptr) {
135 LOGE("[AssetsDownloadManager] create notification chain failed %d", errno);
136 return -E_OUT_OF_MEMORY;
137 }
138 int errCode = notificationChain_->RegisterEventType(DOWNLOAD_FINISH_EVENT);
139 if (errCode != E_OK) {
140 LOGE("[AssetsDownloadManager] register even type failed %d", errCode);
141 RefObject::KillAndDecObjRef(notificationChain_);
142 notificationChain_ = nullptr;
143 }
144 return errCode;
145 }
146 }