• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }