1 /*
2  * Copyright (c) 2023 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 
16 #include "app_domain_verify_task_mgr.h"
17 #include <deque>
18 #include <memory>
19 #include <string>
20 #include <future>
21 #include "app_domain_verify_hilog.h"
22 
23 namespace OHOS {
24 namespace AppDomainVerify {
25 std::shared_ptr<AppDomainVerifyTaskMgr> AppDomainVerifyTaskMgr::instance_ = nullptr;
26 ffrt::mutex AppDomainVerifyTaskMgr::instanceMutex_;
27 
28 using namespace OHOS::NetStack::HttpClient;
29 
30 class AutoSeqReleaser {
31 public:
AutoSeqReleaser(SafeMap<uint32_t,std::shared_ptr<IHttpTask>> * map,uint32_t seq)32     AutoSeqReleaser(SafeMap<uint32_t, std::shared_ptr<IHttpTask>>* map, uint32_t seq) : seq_(seq), map_(map)
33     {
34         APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MODULE_COMMON, "AutoSeqReleaser() seq:%{public}u.", seq_);
35     }
~AutoSeqReleaser()36     ~AutoSeqReleaser()
37     {
38         APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MODULE_COMMON, "~AutoSeqReleaser() seq:%{public}u.", seq_);
39         if (map_ != nullptr) {
40             map_->Erase(seq_);
41         }
42     }
43 
44 private:
45     uint32_t seq_;
46     SafeMap<uint32_t, std::shared_ptr<IHttpTask>>* map_;
47 };
48 
GetInstance()49 std::shared_ptr<AppDomainVerifyTaskMgr> AppDomainVerifyTaskMgr::GetInstance()
50 {
51     if (instance_ == nullptr) {
52         std::lock_guard<ffrt::mutex> lock(instanceMutex_);
53         if (instance_ == nullptr) {
54             instance_ = std::make_shared<AppDomainVerifyTaskMgr>();
55         }
56     }
57     return instance_;
58 }
59 
DestroyInstance()60 void AppDomainVerifyTaskMgr::DestroyInstance()
61 {
62     std::lock_guard<ffrt::mutex> lock(instanceMutex_);
63     if (instance_ != nullptr) {
64         instance_.reset();
65         instance_ = nullptr;
66     }
67     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "AppDomainVerifyTaskMgr DestroyInstance!");
68 }
69 
AppDomainVerifyTaskMgr()70 AppDomainVerifyTaskMgr::AppDomainVerifyTaskMgr()
71 {
72     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "AppDomainVerifyTaskMgr new!");
73     Init();
74 }
75 
~AppDomainVerifyTaskMgr()76 AppDomainVerifyTaskMgr::~AppDomainVerifyTaskMgr()
77 {
78     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "AppDomainVerifyTaskMgr destory!");
79     {
80         std::unique_lock<ffrt::mutex> lock(mutex_);
81         this->stop_ = true;
82         cond_.notify_all();
83     }
84     // wait all workers done;
85     ffrt::wait();
86     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "AppDomainVerifyTaskMgr destory end!");
87 }
88 
Init()89 bool AppDomainVerifyTaskMgr::Init()
90 {
91     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MODULE_COMMON, "Init workers.");
92     for (int i = 0; i < poolSize_; i++) {
93         ffrt::submit_h([this]() {
94             APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "worker run.");
95             std::unique_lock<ffrt::mutex> lock(mutex_);
96             while (!this->stop_) {
97                 if (!tasks_.empty()) {
98                     auto task = std::move(tasks_.front());
99                     tasks_.pop();
100                     lock.unlock();
101                     task();
102                     lock.lock();
103                 } else {
104                     while (tasks_.empty() && !this->stop_) {
105                         cond_.wait(lock);
106                     }
107                 }
108             }
109             APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "worker done.");
110         });
111     }
112     return true;
113 }
GetTaskWrapper(const std::shared_ptr<IHttpTask> & httpTask)114 std::function<void()> AppDomainVerifyTaskMgr::GetTaskWrapper(const std::shared_ptr<IHttpTask>& httpTask)
115 {
116     return [taskMap = &taskMap_, httpTask]() {
117         APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "task in");
118         auto seq = httpTask->GetTaskId();
119         auto clientTask = httpTask->CreateHttpClientTask();
120         if (clientTask == nullptr) {
121             AutoSeqReleaser releaser(taskMap, seq);
122             HttpClientRequest request;
123             HttpClientResponse response;
124             response.SetResult("creat http client task failed");
125             HttpClientError error;
126             httpTask->OnFail(request, response, error);
127             APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "clientTask null");
128             return;
129         }
130         std::promise<void> promise;
131         std::future future = promise.get_future();
132         clientTask->OnSuccess(
133             [&taskMap, &httpTask, &promise, seq](const HttpClientRequest& request, const HttpClientResponse& response) {
134                 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "OnSuccess");
135                 httpTask->OnSuccess(request, response);
136                 AutoSeqReleaser releaser(taskMap, seq);
137                 promise.set_value();
138             });
139         clientTask->OnFail([&taskMap, httpTask, &promise, seq](const HttpClientRequest& request,
140                                const HttpClientResponse& response, const HttpClientError& error) {
141             APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "OnFail");
142             httpTask->OnFail(request, response, error);
143             AutoSeqReleaser releaser(taskMap, seq);
144             promise.set_value();
145         });
146         clientTask->OnCancel(
147             [&taskMap, &httpTask, &promise, seq](const HttpClientRequest& request, const HttpClientResponse& response) {
148                 APP_DOMAIN_VERIFY_HILOGW(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "OnCancel");
149                 httpTask->OnCancel(request, response);
150                 AutoSeqReleaser releaser(taskMap, seq);
151                 promise.set_value();
152             });
153         clientTask->OnDataReceive(
154             [&clientTask, &httpTask](const HttpClientRequest& request, const uint8_t* data, size_t length) {
155                 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "OnDataReceive");
156                 httpTask->OnDataReceive(clientTask, request, data, length);
157             });
158         clientTask->Start();
159         future.wait();
160         APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "task out");
161     };
162 }
AddTask(const std::shared_ptr<IHttpTask> & task)163 bool AppDomainVerifyTaskMgr::AddTask(const std::shared_ptr<IHttpTask>& task)
164 {
165     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MODULE_COMMON, "AddTask.");
166     if (task == nullptr) {
167         APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MODULE_COMMON, "AddTask task null.");
168         return false;
169     }
170     std::function<void()> taskWrapper = GetTaskWrapper(task);
171     std::unique_lock<ffrt::mutex> lock(mutex_);
172     taskMap_.EnsureInsert(task->GetTaskId(), task);
173     tasks_.push(std::move(taskWrapper));
174     cond_.notify_one();
175     return true;
176 }
IsIdle()177 bool AppDomainVerifyTaskMgr::IsIdle()
178 {
179     APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MODULE_COMMON, "IsIdle.");
180     return taskMap_.IsEmpty();
181 }
182 }
183 }
184