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 "request_manager.h"
17
18 #include <atomic>
19
20 #include "data_ability_predicates.h"
21 #include "log.h"
22 #include "rdb_errno.h"
23 #include "rdb_helper.h"
24 #include "rdb_open_callback.h"
25 #include "rdb_predicates.h"
26 #include "rdb_store.h"
27 #include "request_sync_load_callback.h"
28 #include "result_set.h"
29 #include "system_ability_definition.h"
30
31 namespace OHOS::Request {
32 std::mutex RequestManager::instanceLock_;
33 sptr<RequestManager> RequestManager::instance_ = nullptr;
34 constexpr const int32_t RETRY_INTERVAL = 500 * 1000;
35 constexpr const int32_t RETRY_MAX_TIMES = 5;
36
RequestManager()37 RequestManager::RequestManager() : requestServiceProxy_(nullptr), deathRecipient_(nullptr), saChangeListener_(nullptr)
38 {
39 }
40
~RequestManager()41 RequestManager::~RequestManager()
42 {
43 }
44
GetInstance()45 sptr<RequestManager> RequestManager::GetInstance()
46 {
47 if (instance_ == nullptr) {
48 std::lock_guard<std::mutex> autoLock(instanceLock_);
49 if (instance_ == nullptr) {
50 instance_ = new RequestManager;
51 }
52 }
53 return instance_;
54 }
55
Create(const Config & config,int32_t & tid,sptr<NotifyInterface> listener)56 int32_t RequestManager::Create(const Config &config, int32_t &tid, sptr<NotifyInterface> listener)
57 {
58 REQUEST_HILOGD("RequestManager Create start.");
59
60 auto proxy = GetRequestServiceProxy();
61 if (proxy == nullptr) {
62 REQUEST_HILOGE("GetRequestServiceProxy fail.");
63 return E_SERVICE_ERROR;
64 }
65 int32_t ret = proxy->Create(config, tid, listener);
66 if (ret == E_UNLOADING_SA) {
67 REQUEST_HILOGE("Service ability is quitting");
68 return Retry(tid, config, ret, listener);
69 }
70 REQUEST_HILOGD("RequestManager Create end.");
71 return ret;
72 }
73
Retry(int32_t & taskId,const Config & config,int32_t errorCode,sptr<NotifyInterface> listener)74 int32_t RequestManager::Retry(int32_t &taskId, const Config &config, int32_t errorCode, sptr<NotifyInterface> listener)
75 {
76 REQUEST_HILOGD("Retry in");
77 int32_t interval = 1;
78 while (errorCode == E_UNLOADING_SA && interval <= RETRY_MAX_TIMES) {
79 if (config.action == Action::DOWNLOAD) {
80 for (auto file : config.files) {
81 std::remove(file.uri.c_str());
82 }
83 }
84
85 if (errorCode == E_UNLOADING_SA) {
86 // Waitting for system ability quit
87 usleep(RETRY_INTERVAL);
88 }
89 SetRequestServiceProxy(nullptr);
90 LoadRequestServer();
91 auto proxy = GetRequestServiceProxy();
92 if (proxy == nullptr) {
93 REQUEST_HILOGE("proxy is nullptr!");
94 continue;
95 }
96 errorCode = proxy->Create(config, taskId, listener);
97 ++interval;
98 }
99 if (errorCode != E_OK && config.action == Action::DOWNLOAD) {
100 for (auto file : config.files) {
101 std::remove(file.uri.c_str());
102 }
103 }
104 return errorCode;
105 }
106
SetRequestServiceProxy(sptr<RequestServiceInterface> proxy)107 void RequestManager::SetRequestServiceProxy(sptr<RequestServiceInterface> proxy)
108 {
109 std::lock_guard<std::mutex> lock(serviceProxyMutex_);
110 requestServiceProxy_ = proxy;
111 }
112
GetTask(const std::string & tid,const std::string & token,Config & config)113 int32_t RequestManager::GetTask(const std::string &tid, const std::string &token, Config &config)
114 {
115 REQUEST_HILOGD("GetTask in");
116 auto proxy = GetRequestServiceProxy();
117 if (proxy == nullptr) {
118 return E_SERVICE_ERROR;
119 }
120
121 return proxy->GetTask(tid, token, config);
122 }
123
Start(const std::string & tid)124 int32_t RequestManager::Start(const std::string &tid)
125 {
126 REQUEST_HILOGD("Start in");
127 auto proxy = GetRequestServiceProxy();
128 if (proxy == nullptr) {
129 return E_SERVICE_ERROR;
130 }
131
132 return proxy->Start(tid);
133 }
134
Stop(const std::string & tid)135 int32_t RequestManager::Stop(const std::string &tid)
136 {
137 REQUEST_HILOGD("Stop in");
138 auto proxy = GetRequestServiceProxy();
139 if (proxy == nullptr) {
140 return E_SERVICE_ERROR;
141 }
142
143 return proxy->Stop(tid);
144 }
145
Query(const std::string & tid,TaskInfo & info)146 int32_t RequestManager::Query(const std::string &tid, TaskInfo &info)
147 {
148 REQUEST_HILOGD("Query in");
149 auto proxy = GetRequestServiceProxy();
150 if (proxy == nullptr) {
151 return E_SERVICE_ERROR;
152 }
153
154 return proxy->Query(tid, info);
155 }
156
Touch(const std::string & tid,const std::string & token,TaskInfo & info)157 int32_t RequestManager::Touch(const std::string &tid, const std::string &token, TaskInfo &info)
158 {
159 REQUEST_HILOGD("Touch in");
160 auto proxy = GetRequestServiceProxy();
161 if (proxy == nullptr) {
162 return E_SERVICE_ERROR;
163 }
164
165 return proxy->Touch(tid, token, info);
166 }
167
Search(const Filter & filter,std::vector<std::string> & tids)168 int32_t RequestManager::Search(const Filter &filter, std::vector<std::string> &tids)
169 {
170 REQUEST_HILOGD("Search in");
171 auto proxy = GetRequestServiceProxy();
172 if (proxy == nullptr) {
173 return E_SERVICE_ERROR;
174 }
175
176 return proxy->Search(filter, tids);
177 }
178
Show(const std::string & tid,TaskInfo & info)179 int32_t RequestManager::Show(const std::string &tid, TaskInfo &info)
180 {
181 REQUEST_HILOGD("Show in");
182 auto proxy = GetRequestServiceProxy();
183 if (proxy == nullptr) {
184 return E_SERVICE_ERROR;
185 }
186
187 return proxy->Show(tid, info);
188 }
189
Pause(const std::string & tid,Version version)190 int32_t RequestManager::Pause(const std::string &tid, Version version)
191 {
192 REQUEST_HILOGD("Pause in");
193 auto proxy = GetRequestServiceProxy();
194 if (proxy == nullptr) {
195 return E_SERVICE_ERROR;
196 }
197
198 return proxy->Pause(tid, version);
199 }
200
QueryMimeType(const std::string & tid,std::string & mimeType)201 int32_t RequestManager::QueryMimeType(const std::string &tid, std::string &mimeType)
202 {
203 REQUEST_HILOGD("QueryMimeType in");
204 auto proxy = GetRequestServiceProxy();
205 if (proxy == nullptr) {
206 return E_SERVICE_ERROR;
207 }
208
209 return proxy->QueryMimeType(tid, mimeType);
210 }
211
Remove(const std::string & tid,Version version)212 int32_t RequestManager::Remove(const std::string &tid, Version version)
213 {
214 REQUEST_HILOGD("Remove in");
215 auto proxy = GetRequestServiceProxy();
216 if (proxy == nullptr) {
217 return E_SERVICE_ERROR;
218 }
219
220 return proxy->Remove(tid, version);
221 }
222
Resume(const std::string & tid)223 int32_t RequestManager::Resume(const std::string &tid)
224 {
225 REQUEST_HILOGD("Resume in");
226 auto proxy = GetRequestServiceProxy();
227 if (proxy == nullptr) {
228 return E_SERVICE_ERROR;
229 }
230
231 return proxy->Resume(tid);
232 }
233
On(const std::string & type,const std::string & tid,const sptr<NotifyInterface> & listener,Version version)234 int32_t RequestManager::On(
235 const std::string &type, const std::string &tid, const sptr<NotifyInterface> &listener, Version version)
236 {
237 REQUEST_HILOGD("On in");
238 auto proxy = GetRequestServiceProxy();
239 if (proxy == nullptr) {
240 return false;
241 }
242
243 return proxy->On(type, tid, listener, version);
244 }
245
Off(const std::string & type,const std::string & tid,Version version)246 int32_t RequestManager::Off(const std::string &type, const std::string &tid, Version version)
247 {
248 REQUEST_HILOGD("Off in");
249 auto proxy = GetRequestServiceProxy();
250 if (proxy == nullptr) {
251 return false;
252 }
253
254 return proxy->Off(type, tid, version);
255 }
256
GetRequestServiceProxy()257 sptr<RequestServiceInterface> RequestManager::GetRequestServiceProxy()
258 {
259 std::lock_guard<std::mutex> lock(serviceProxyMutex_);
260 if (requestServiceProxy_ != nullptr) {
261 return requestServiceProxy_;
262 }
263 sptr<ISystemAbilityManager> systemAbilityManager =
264 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
265 if (systemAbilityManager == nullptr) {
266 REQUEST_HILOGE("Getting SystemAbilityManager failed.");
267 return nullptr;
268 }
269 auto systemAbility = systemAbilityManager->GetSystemAbility(DOWNLOAD_SERVICE_ID, "");
270 if (systemAbility == nullptr) {
271 REQUEST_HILOGE("Get SystemAbility failed.");
272 return nullptr;
273 }
274 if (!SubscribeSA(systemAbilityManager)) {
275 REQUEST_HILOGE("Subscribe SystemAbility failed.");
276 return nullptr;
277 }
278 deathRecipient_ = new RequestSaDeathRecipient();
279 systemAbility->AddDeathRecipient(deathRecipient_);
280 requestServiceProxy_ = iface_cast<RequestServiceInterface>(systemAbility);
281 if (requestServiceProxy_ == nullptr) {
282 REQUEST_HILOGE("Get requestServiceProxy_ fail.");
283 return nullptr;
284 }
285 return requestServiceProxy_;
286 }
287
288 // Subscribe SA status changes only once
SubscribeSA(sptr<ISystemAbilityManager> systemAbilityManager)289 bool RequestManager::SubscribeSA(sptr<ISystemAbilityManager> systemAbilityManager)
290 {
291 if (saChangeListener_ != nullptr) {
292 return true;
293 }
294 saChangeListener_ = new (std::nothrow) SystemAbilityStatusChangeListener();
295 if (saChangeListener_ == nullptr) {
296 REQUEST_HILOGE("Get saChangeListener_ failed.");
297 return false;
298 }
299 if (systemAbilityManager->SubscribeSystemAbility(DOWNLOAD_SERVICE_ID, saChangeListener_) != E_OK) {
300 REQUEST_HILOGE("SubscribeSystemAbility failed.");
301 return false;
302 }
303 return true;
304 }
305
RestoreListener(void (* callback)())306 void RequestManager::RestoreListener(void (*callback)())
307 {
308 callback_ = callback;
309 }
310
SystemAbilityStatusChangeListener()311 RequestManager::SystemAbilityStatusChangeListener::SystemAbilityStatusChangeListener()
312 {
313 }
314
OnAddSystemAbility(int32_t saId,const std::string & deviceId)315 void RequestManager::SystemAbilityStatusChangeListener::OnAddSystemAbility(int32_t saId, const std::string &deviceId)
316 {
317 if (saId != DOWNLOAD_SERVICE_ID) {
318 REQUEST_HILOGE("SA ID is not DOWNLOAD_SERVICE_ID.");
319 }
320 REQUEST_HILOGD("SystemAbility Add.");
321 if (RequestManager::GetInstance()->callback_ != nullptr) {
322 RequestManager::GetInstance()->callback_();
323 }
324 }
325
OnRemoveSystemAbility(int32_t saId,const std::string & deviceId)326 void RequestManager::SystemAbilityStatusChangeListener::OnRemoveSystemAbility(int32_t saId, const std::string &deviceId)
327 {
328 if (saId != DOWNLOAD_SERVICE_ID) {
329 REQUEST_HILOGE("SA ID is not DOWNLOAD_SERVICE_ID.");
330 }
331 REQUEST_HILOGD("SystemAbility Remove.");
332 }
333
OnRemoteSaDied(const wptr<IRemoteObject> & remote)334 void RequestManager::OnRemoteSaDied(const wptr<IRemoteObject> &remote)
335 {
336 REQUEST_HILOGD(" RequestManager::OnRemoteSaDied");
337 ready_.store(false);
338 SetRequestServiceProxy(nullptr);
339 }
340
RequestSaDeathRecipient()341 RequestSaDeathRecipient::RequestSaDeathRecipient()
342 {
343 }
344
OnRemoteDied(const wptr<IRemoteObject> & object)345 void RequestSaDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
346 {
347 REQUEST_HILOGE("RequestSaDeathRecipient on remote systemAbility died.");
348 RequestManager::GetInstance()->OnRemoteSaDied(object);
349 }
350
LoadRequestServer()351 bool RequestManager::LoadRequestServer()
352 {
353 REQUEST_HILOGD("Begin load request server");
354 if (ready_.load()) {
355 REQUEST_HILOGD("GetSystemAbilityManager ready_ true");
356 return true;
357 }
358 std::lock_guard<std::mutex> lock(downloadMutex_);
359 if (ready_.load()) {
360 REQUEST_HILOGD("GetSystemAbilityManager ready_ is true");
361 return true;
362 }
363
364 auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
365 if (sm == nullptr) {
366 REQUEST_HILOGE("GetSystemAbilityManager return null");
367 return false;
368 }
369 auto systemAbility = sm->CheckSystemAbility(DOWNLOAD_SERVICE_ID);
370 if (systemAbility != nullptr) {
371 REQUEST_HILOGE("service already exists");
372 return true;
373 }
374 sptr<RequestSyncLoadCallback> loadCallback_ = new (std::nothrow) RequestSyncLoadCallback();
375 if (loadCallback_ == nullptr) {
376 REQUEST_HILOGE("new DownloadAbilityCallback fail");
377 return false;
378 }
379
380 int32_t result = sm->LoadSystemAbility(DOWNLOAD_SERVICE_ID, loadCallback_);
381 if (result != ERR_OK) {
382 REQUEST_HILOGE("LoadSystemAbility %{public}d failed, result: %{public}d", DOWNLOAD_SERVICE_ID, result);
383 return false;
384 }
385
386 {
387 std::unique_lock<std::mutex> conditionLock(conditionMutex_);
388 auto waitStatus = syncCon_.wait_for(
389 conditionLock, std::chrono::milliseconds(LOAD_SA_TIMEOUT_MS), [this]() { return ready_.load(); });
390 if (!waitStatus) {
391 REQUEST_HILOGE("download server load sa timeout");
392 return false;
393 }
394 }
395 return true;
396 }
397
IsSaReady()398 bool RequestManager::IsSaReady()
399 {
400 return ready_.load();
401 }
402
LoadServerSuccess()403 void RequestManager::LoadServerSuccess()
404 {
405 std::unique_lock<std::mutex> lock(conditionMutex_);
406 ready_.store(true);
407 syncCon_.notify_one();
408 REQUEST_HILOGE("load download server success");
409 }
410
LoadServerFail()411 void RequestManager::LoadServerFail()
412 {
413 ready_.store(false);
414 REQUEST_HILOGE("load download server fail");
415 }
416 } // namespace OHOS::Request
417