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_event.h"
17 
18 #include "constant.h"
19 #include "js_initialize.h"
20 #include "log.h"
21 #include "request_manager.h"
22 
23 namespace OHOS::Request {
24 constexpr const std::int32_t DECIMALISM = 10;
25 static constexpr const char *EVENT_COMPLETED = "completed";
26 static constexpr const char *EVENT_FAILED = "failed";
27 static constexpr const char *EVENT_PAUSE = "pause";
28 static constexpr const char *EVENT_RESUME = "resume";
29 static constexpr const char *EVENT_REMOVE = "remove";
30 static constexpr const char *EVENT_PROGRESS = "progress";
31 static constexpr const char *EVENT_HEADERRECEIVE = "headerReceive";
32 static constexpr const char *EVENT_FAIL = "fail";
33 static constexpr const char *EVENT_COMPLETE = "complete";
34 static constexpr const char *EVENT_RESPONSE = "response";
35 
36 std::map<std::string, SubscribeType> RequestEvent::supportEventsV9_ = {
37     { EVENT_COMPLETE, SubscribeType::COMPLETED },
38     { EVENT_PAUSE, SubscribeType::PAUSE },
39     { EVENT_REMOVE, SubscribeType::REMOVE },
40     { EVENT_PROGRESS, SubscribeType::PROGRESS },
41     { EVENT_HEADERRECEIVE, SubscribeType::HEADER_RECEIVE },
42     { EVENT_FAIL, SubscribeType::FAILED },
43 };
44 
45 std::map<std::string, SubscribeType> RequestEvent::supportEventsV10_ = {
46     { EVENT_PROGRESS, SubscribeType::PROGRESS },
47     { EVENT_COMPLETED, SubscribeType::COMPLETED },
48     { EVENT_FAILED, SubscribeType::FAILED },
49     { EVENT_PAUSE, SubscribeType::PAUSE },
50     { EVENT_RESUME, SubscribeType::RESUME },
51     { EVENT_REMOVE, SubscribeType::REMOVE },
52     { EVENT_RESPONSE, SubscribeType::RESPONSE },
53 };
54 
55 std::map<std::string, RequestEvent::Event> RequestEvent::requestEvent_ = {
56     { FUNCTION_PAUSE, RequestEvent::PauseExec },
57     { FUNCTION_QUERY, RequestEvent::QueryExec },
58     { FUNCTION_QUERY_MIME_TYPE, RequestEvent::QueryMimeTypeExec },
59     { FUNCTION_REMOVE, RequestEvent::RemoveExec },
60     { FUNCTION_RESUME, RequestEvent::ResumeExec },
61     { FUNCTION_START, RequestEvent::StartExec },
62     { FUNCTION_STOP, RequestEvent::StopExec },
63 };
64 
65 std::map<std::string, uint32_t> RequestEvent::resMap_ = {
66     { FUNCTION_PAUSE, BOOL_RES },
67     { FUNCTION_QUERY, INFO_RES },
68     { FUNCTION_QUERY_MIME_TYPE, STR_RES },
69     { FUNCTION_REMOVE, BOOL_RES },
70     { FUNCTION_RESUME, BOOL_RES },
71     { FUNCTION_START, BOOL_RES },
72     { FUNCTION_STOP, BOOL_RES },
73 };
74 
75 std::map<State, DownloadStatus> RequestEvent::stateMap_ = {
76     { State::INITIALIZED, SESSION_PENDING },
77     { State::WAITING, SESSION_PAUSED },
78     { State::RUNNING, SESSION_RUNNING },
79     { State::RETRYING, SESSION_RUNNING },
80     { State::PAUSED, SESSION_PAUSED },
81     { State::COMPLETED, SESSION_SUCCESS },
82     { State::STOPPED, SESSION_FAILED },
83     { State::FAILED, SESSION_FAILED },
84 };
85 
86 std::map<Reason, DownloadErrorCode> RequestEvent::failMap_ = {
87     { REASON_OK, ERROR_FILE_ALREADY_EXISTS },
88     { IO_ERROR, ERROR_FILE_ERROR },
89     { INSUFFICIENT_SPACE, ERROR_INSUFFICIENT_SPACE },
90     { REDIRECT_ERROR, ERROR_TOO_MANY_REDIRECTS },
91     { OTHERS_ERROR, ERROR_UNKNOWN },
92     { NETWORK_OFFLINE, ERROR_OFFLINE },
93     { UNSUPPORTED_NETWORK_TYPE, ERROR_UNSUPPORTED_NETWORK_TYPE },
94     { UNSUPPORT_RANGE_REQUEST, ERROR_UNKNOWN },
95 };
96 
Pause(napi_env env,napi_callback_info info)97 napi_value RequestEvent::Pause(napi_env env, napi_callback_info info)
98 {
99     return Exec(env, info, FUNCTION_PAUSE);
100 }
101 
Query(napi_env env,napi_callback_info info)102 napi_value RequestEvent::Query(napi_env env, napi_callback_info info)
103 {
104     return Exec(env, info, FUNCTION_QUERY);
105 }
106 
QueryMimeType(napi_env env,napi_callback_info info)107 napi_value RequestEvent::QueryMimeType(napi_env env, napi_callback_info info)
108 {
109     return Exec(env, info, FUNCTION_QUERY_MIME_TYPE);
110 }
111 
Remove(napi_env env,napi_callback_info info)112 napi_value RequestEvent::Remove(napi_env env, napi_callback_info info)
113 {
114     return Exec(env, info, FUNCTION_REMOVE);
115 }
116 
Resume(napi_env env,napi_callback_info info)117 napi_value RequestEvent::Resume(napi_env env, napi_callback_info info)
118 {
119     return Exec(env, info, FUNCTION_RESUME);
120 }
121 
Start(napi_env env,napi_callback_info info)122 napi_value RequestEvent::Start(napi_env env, napi_callback_info info)
123 {
124     return Exec(env, info, FUNCTION_START);
125 }
126 
Stop(napi_env env,napi_callback_info info)127 napi_value RequestEvent::Stop(napi_env env, napi_callback_info info)
128 {
129     return Exec(env, info, FUNCTION_STOP);
130 }
131 
On(napi_env env,napi_callback_info info)132 napi_value RequestEvent::On(napi_env env, napi_callback_info info)
133 {
134     int32_t seq = RequestManager::GetInstance()->GetNextSeq();
135     REQUEST_HILOGD("Begin task on, seq: %{public}d", seq);
136     JsParam jsParam;
137     ExceptionError err = ParseOnOffParameters(env, info, true, jsParam);
138     if (err.code != E_OK) {
139         bool withErrCode = jsParam.task->config_.version == Version::API10;
140         REQUEST_HILOGE("End task on, seq: %{public}d, failed: %{public}d", seq, err.code);
141         NapiUtils::ThrowError(env, err.code, err.errInfo, withErrCode);
142         return nullptr;
143     }
144 
145     if (jsParam.subscribeType == SubscribeType::RESPONSE) {
146         jsParam.task->listenerMutex_.lock();
147         if (jsParam.task->responseListener_ == nullptr) {
148             jsParam.task->responseListener_ = std::make_shared<JSResponseListener>(env, jsParam.task->GetTid());
149         }
150         jsParam.task->listenerMutex_.unlock();
151         napi_status ret = jsParam.task->responseListener_->AddListener(jsParam.callback);
152         if (ret != napi_ok) {
153             REQUEST_HILOGE("End task on, seq: %{public}d, failed: AddListener fail code %{public}d", seq, ret);
154             return nullptr;
155         }
156     } else {
157         jsParam.task->listenerMutex_.lock();
158         auto listener = jsParam.task->notifyDataListenerMap_.find(jsParam.subscribeType);
159         if (listener == jsParam.task->notifyDataListenerMap_.end()) {
160             jsParam.task->notifyDataListenerMap_[jsParam.subscribeType] =
161                 std::make_shared<JSNotifyDataListener>(env, jsParam.task->GetTid(), jsParam.subscribeType);
162         }
163         jsParam.task->listenerMutex_.unlock();
164         napi_status ret = jsParam.task->notifyDataListenerMap_[jsParam.subscribeType]->AddListener(jsParam.callback);
165         if (ret != napi_ok) {
166             REQUEST_HILOGE("End task on, seq: %{public}d, failed: AddListener fail code %{public}d", seq, ret);
167             return nullptr;
168         }
169     }
170 
171     REQUEST_HILOGI(
172         "End task %{public}s on %{public}s seq %{public}d", jsParam.task->GetTid().c_str(), jsParam.type.c_str(), seq);
173     return nullptr;
174 }
175 
Off(napi_env env,napi_callback_info info)176 napi_value RequestEvent::Off(napi_env env, napi_callback_info info)
177 {
178     int32_t seq = RequestManager::GetInstance()->GetNextSeq();
179     REQUEST_HILOGD("Begin task off, seq %{public}d", seq);
180     JsParam jsParam;
181     ExceptionError err = ParseOnOffParameters(env, info, false, jsParam);
182     if (err.code != E_OK) {
183         bool withErrCode = jsParam.task->config_.version == Version::API10;
184         REQUEST_HILOGE("End task off, seq: %{public}d, failed: %{public}d", seq, err.code);
185         NapiUtils::ThrowError(env, err.code, err.errInfo, withErrCode);
186         return nullptr;
187     }
188 
189     if (jsParam.subscribeType == SubscribeType::RESPONSE) {
190         jsParam.task->listenerMutex_.lock();
191         if (jsParam.task->responseListener_ == nullptr) {
192             jsParam.task->responseListener_ = std::make_shared<JSResponseListener>(env, jsParam.task->GetTid());
193         }
194         jsParam.task->listenerMutex_.unlock();
195         napi_status ret = jsParam.task->responseListener_->RemoveListener(jsParam.callback);
196         if (ret != napi_ok) {
197             REQUEST_HILOGE("End task off, seq: %{public}d, failed: RemoveListener fail code %{public}d", seq, ret);
198             return nullptr;
199         }
200     } else {
201         jsParam.task->listenerMutex_.lock();
202         auto listener = jsParam.task->notifyDataListenerMap_.find(jsParam.subscribeType);
203         if (listener == jsParam.task->notifyDataListenerMap_.end()) {
204             jsParam.task->notifyDataListenerMap_[jsParam.subscribeType] =
205                 std::make_shared<JSNotifyDataListener>(env, jsParam.task->GetTid(), jsParam.subscribeType);
206         }
207         jsParam.task->listenerMutex_.unlock();
208         napi_status ret = jsParam.task->notifyDataListenerMap_[jsParam.subscribeType]->RemoveListener(jsParam.callback);
209         if (ret != napi_ok) {
210             REQUEST_HILOGE("End task off, seq: %{public}d, failed: RemoveListener fail code %{public}d", seq, ret);
211             return nullptr;
212         }
213     }
214 
215     REQUEST_HILOGD("End task off %{public}s ok, seq %{public}d tid %{public}s", jsParam.type.c_str(), seq,
216         jsParam.task->GetTid().c_str());
217     return nullptr;
218 }
219 
StringToSubscribeType(const std::string & type,Version version)220 SubscribeType RequestEvent::StringToSubscribeType(const std::string &type, Version version)
221 {
222     if (version == Version::API10) {
223         if (supportEventsV10_.find(type) != supportEventsV10_.end()) {
224             return supportEventsV10_[type];
225         }
226     } else {
227         if (supportEventsV9_.find(type) != supportEventsV9_.end()) {
228             return supportEventsV9_[type];
229         }
230     }
231     return SubscribeType::BUTT;
232 }
233 
BuildNotifyData(const std::shared_ptr<TaskInfo> & taskInfo)234 NotifyData RequestEvent::BuildNotifyData(const std::shared_ptr<TaskInfo> &taskInfo)
235 {
236     NotifyData notifyData;
237     notifyData.progress = taskInfo->progress;
238     notifyData.action = taskInfo->action;
239     notifyData.version = taskInfo->version;
240     notifyData.mode = taskInfo->mode;
241     notifyData.taskStates = taskInfo->taskStates;
242     return notifyData;
243 }
244 
ParseOnOffParameters(napi_env env,napi_callback_info info,bool IsRequiredParam,JsParam & jsParam)245 ExceptionError RequestEvent::ParseOnOffParameters(
246     napi_env env, napi_callback_info info, bool IsRequiredParam, JsParam &jsParam)
247 {
248     ExceptionError err = { .code = E_OK };
249     size_t argc = NapiUtils::MAX_ARGC;
250     napi_value argv[NapiUtils::MAX_ARGC] = { nullptr };
251     napi_status status = napi_get_cb_info(env, info, &argc, argv, &jsParam.self, nullptr);
252     if (status != napi_ok) {
253         err.code = E_PARAMETER_CHECK;
254         err.errInfo = "Parameter verification failed, Failed to obtain parameters";
255         return err;
256     }
257     napi_unwrap(env, jsParam.self, reinterpret_cast<void **>(&jsParam.task));
258     if (jsParam.task == nullptr) {
259         err.code = E_PARAMETER_CHECK;
260         err.errInfo = "Parameter verification failed, Failed to obtain the current object";
261         return err;
262     }
263 
264     if ((IsRequiredParam && argc < NapiUtils::TWO_ARG) || (!IsRequiredParam && argc < NapiUtils::ONE_ARG)) {
265         err.code = E_PARAMETER_CHECK;
266         err.errInfo = "Missing mandatory parameters, Wrong number of arguments";
267         return err;
268     }
269     napi_valuetype valuetype;
270     napi_typeof(env, argv[NapiUtils::FIRST_ARGV], &valuetype);
271     if (valuetype != napi_string) {
272         err.code = E_PARAMETER_CHECK;
273         err.errInfo = "Incorrect parameter type, event is not of string type";
274         return err;
275     }
276     jsParam.type = NapiUtils::Convert2String(env, argv[NapiUtils::FIRST_ARGV]);
277     jsParam.subscribeType = StringToSubscribeType(jsParam.type, jsParam.task->config_.version);
278     if (jsParam.subscribeType == SubscribeType::BUTT) {
279         err.code = E_PARAMETER_CHECK;
280         err.errInfo = "Parameter verification failed, event parse error";
281         return err;
282     }
283     if (argc == NapiUtils::ONE_ARG) {
284         return err;
285     }
286     valuetype = napi_undefined;
287     napi_typeof(env, argv[NapiUtils::SECOND_ARGV], &valuetype);
288     if (valuetype != napi_function) {
289         err.code = E_PARAMETER_CHECK;
290         err.errInfo = "Incorrect parameter type, callback is not of function type";
291         return err;
292     }
293     jsParam.callback = argv[NapiUtils::SECOND_ARGV];
294     return err;
295 }
296 
Exec(napi_env env,napi_callback_info info,const std::string & execType)297 napi_value RequestEvent::Exec(napi_env env, napi_callback_info info, const std::string &execType)
298 {
299     int32_t seq = RequestManager::GetInstance()->GetNextSeq();
300     REQUEST_HILOGI("Begin task %{public}s seq %{public}d", execType.c_str(), seq);
301     auto context = std::make_shared<ExecContext>();
302     auto input = [context](size_t argc, napi_value *argv, napi_value self) -> napi_status {
303         return ParseInputParameters(context->env_, argc, self, context);
304     };
305     auto output = [context, execType, seq](napi_value *result) -> napi_status {
306         if (context->innerCode_ != E_OK) {
307             REQUEST_HILOGE("End task %{public}s in AsyncCall output, seq: %{public}d, failed: %{public}d",
308                 execType.c_str(), seq, context->innerCode_);
309             return napi_generic_failure;
310         }
311 
312         napi_status status = GetResult(context->env_, context, execType, *result);
313         if (status != napi_ok) {
314             REQUEST_HILOGE("End task %{public}s in AsyncCall output, seq: %{public}d, failed: %{public}d",
315                 execType.c_str(), seq, status);
316         } else {
317             REQUEST_HILOGI("End task %{public}s ok seq %{public}d", execType.c_str(), seq);
318         }
319         return status;
320     };
321     auto exec = [context, execType]() {
322         auto handle = requestEvent_.find(execType);
323         if (handle != requestEvent_.end()) {
324             context->innerCode_ = handle->second(context);
325         }
326     };
327 
328     context->SetInput(input).SetOutput(output).SetExec(exec);
329     AsyncCall asyncCall(env, info, context);
330     return asyncCall.Call(context, execType);
331 }
332 
ParseInputParameters(napi_env env,size_t argc,napi_value self,const std::shared_ptr<ExecContext> & context)333 napi_status RequestEvent::ParseInputParameters(
334     napi_env env, size_t argc, napi_value self, const std::shared_ptr<ExecContext> &context)
335 {
336     NAPI_ASSERT_BASE(env, self != nullptr, "self is nullptr", napi_invalid_arg);
337     NAPI_CALL_BASE(env, napi_unwrap(env, self, reinterpret_cast<void **>(&context->task)), napi_invalid_arg);
338     NAPI_ASSERT_BASE(env, context->task != nullptr, "there is no native task", napi_invalid_arg);
339     context->version_ = context->task->config_.version;
340     context->withErrCode_ = context->version_ != Version::API8;
341     return napi_ok;
342 }
343 
GetResult(napi_env env,const std::shared_ptr<ExecContext> & context,const std::string & execType,napi_value & result)344 napi_status RequestEvent::GetResult(
345     napi_env env, const std::shared_ptr<ExecContext> &context, const std::string &execType, napi_value &result)
346 {
347     auto res = resMap_.find(execType);
348     if (res == resMap_.end()) {
349         return napi_generic_failure;
350     }
351     if (res->second == BOOL_RES) {
352         return NapiUtils::Convert2JSValue(env, context->boolRes, result);
353     }
354     if (res->second == STR_RES) {
355         return NapiUtils::Convert2JSValue(env, context->strRes, result);
356     }
357     if (res->second == INFO_RES) {
358         return NapiUtils::Convert2JSValue(env, context->infoRes, result);
359     }
360     return napi_generic_failure;
361 }
362 
StartExec(const std::shared_ptr<ExecContext> & context)363 int32_t RequestEvent::StartExec(const std::shared_ptr<ExecContext> &context)
364 {
365     REQUEST_HILOGD("RequestEvent::StartExec in");
366     JsTask *task = context->task;
367     Config config = task->config_;
368 
369     // Rechecks file path.
370     if (config.files.size() == 0) {
371         return E_FILE_IO;
372     }
373     FileSpec file = config.files[0];
374     if (JsInitialize::FindDir(file.uri) && config.action == Action::DOWNLOAD && !task->isGetPermission) {
375         REQUEST_HILOGD("Found the downloaded file: %{public}s.", file.uri.c_str());
376         if (chmod(file.uri.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) != 0) {
377             REQUEST_HILOGD("File add OTH access Failed.");
378         }
379         if (!JsTask::SetPathPermission(file.uri)) {
380             REQUEST_HILOGE("Set path permission fail.");
381             return E_FILE_IO;
382         }
383     }
384     std::string tid = context->task->GetTid();
385     {
386         std::lock_guard<std::mutex> lockGuard(JsTask::taskMutex_);
387         const auto it = JsTask::taskMap_.find(tid);
388         if (it == JsTask::taskMap_.end()) {
389             REQUEST_HILOGE("Can not find task in JsTask::taskMap_ by tid: %{public}s.", tid.c_str());
390             // In JS d.ts, only can throw 201/13400003/21900007(E_TASK_STATE)
391             return E_TASK_STATE;
392         }
393     }
394 
395     int32_t ret = RequestManager::GetInstance()->Start(tid);
396     if (ret == E_OK) {
397         context->boolRes = true;
398     }
399     return ret;
400 }
401 
StopExec(const std::shared_ptr<ExecContext> & context)402 int32_t RequestEvent::StopExec(const std::shared_ptr<ExecContext> &context)
403 {
404     int32_t ret = RequestManager::GetInstance()->Stop(context->task->GetTid());
405     if (ret == E_OK) {
406         context->boolRes = true;
407     }
408     return ret;
409 }
410 
PauseExec(const std::shared_ptr<ExecContext> & context)411 int32_t RequestEvent::PauseExec(const std::shared_ptr<ExecContext> &context)
412 {
413     int32_t ret = RequestManager::GetInstance()->Pause(context->task->GetTid(), context->version_);
414     if (ret == E_OK) {
415         context->boolRes = true;
416     }
417     if (context->version_ != Version::API10 && ret != E_PERMISSION) {
418         return E_OK;
419     }
420     return ret;
421 }
422 
QueryExec(const std::shared_ptr<ExecContext> & context)423 int32_t RequestEvent::QueryExec(const std::shared_ptr<ExecContext> &context)
424 {
425     TaskInfo infoRes;
426     int32_t ret = E_OK;
427     if (!RequestManager::GetInstance()->LoadRequestServer()) {
428         ret = E_SERVICE_ERROR;
429         return ret;
430     }
431     ret = RequestManager::GetInstance()->Show(context->task->GetTid(), infoRes);
432     if (context->version_ != Version::API10 && ret != E_PERMISSION) {
433         ret = E_OK;
434     }
435     GetDownloadInfo(infoRes, context->infoRes);
436     return ret;
437 }
438 
QueryMimeTypeExec(const std::shared_ptr<ExecContext> & context)439 int32_t RequestEvent::QueryMimeTypeExec(const std::shared_ptr<ExecContext> &context)
440 {
441     int32_t ret = E_OK;
442     if (!RequestManager::GetInstance()->LoadRequestServer()) {
443         ret = E_SERVICE_ERROR;
444         return ret;
445     }
446     ret = RequestManager::GetInstance()->QueryMimeType(context->task->GetTid(), context->strRes);
447     if (context->version_ != Version::API10 && ret != E_PERMISSION) {
448         ret = E_OK;
449     }
450     return ret;
451 }
452 
GetDownloadInfo(const TaskInfo & infoRes,DownloadInfo & info)453 void RequestEvent::GetDownloadInfo(const TaskInfo &infoRes, DownloadInfo &info)
454 {
455     info.downloadId = strtoul(infoRes.tid.c_str(), NULL, DECIMALISM);
456     if (infoRes.progress.state == State::FAILED) {
457         auto it = failMap_.find(infoRes.code);
458         if (it != failMap_.end()) {
459             info.failedReason = it->second;
460         } else {
461             info.failedReason = ERROR_UNKNOWN;
462         }
463     }
464     if (infoRes.progress.state == State::WAITING
465         && (infoRes.code == NETWORK_OFFLINE || infoRes.code == UNSUPPORTED_NETWORK_TYPE)) {
466         info.pausedReason = PAUSED_WAITING_FOR_NETWORK;
467     }
468     if (infoRes.progress.state == State::PAUSED) {
469         if (infoRes.code == USER_OPERATION) {
470             info.pausedReason = PAUSED_BY_USER;
471         }
472     }
473     if (!infoRes.files.empty()) {
474         info.fileName = infoRes.files[0].filename;
475         info.filePath = infoRes.files[0].uri;
476     }
477     auto it = stateMap_.find(infoRes.progress.state);
478     if (it != stateMap_.end()) {
479         info.status = it->second;
480     }
481     info.url = infoRes.url;
482     info.downloadTitle = infoRes.title;
483     if (!infoRes.progress.sizes.empty()) {
484         info.downloadTotalBytes = infoRes.progress.sizes[0];
485     }
486     info.description = infoRes.description;
487     info.downloadedBytes = infoRes.progress.processed;
488 }
489 
RemoveExec(const std::shared_ptr<ExecContext> & context)490 int32_t RequestEvent::RemoveExec(const std::shared_ptr<ExecContext> &context)
491 {
492     int32_t ret = RequestManager::GetInstance()->Remove(context->task->GetTid(), context->version_);
493     if (context->version_ != Version::API10 && ret != E_PERMISSION) {
494         ret = E_OK;
495     }
496     if (ret == E_OK) {
497         context->boolRes = true;
498     }
499     return ret;
500 }
501 
ResumeExec(const std::shared_ptr<ExecContext> & context)502 int32_t RequestEvent::ResumeExec(const std::shared_ptr<ExecContext> &context)
503 {
504     int32_t ret = E_OK;
505     if (!RequestManager::GetInstance()->LoadRequestServer()) {
506         ret = E_SERVICE_ERROR;
507         return ret;
508     }
509     ret = RequestManager::GetInstance()->Resume(context->task->GetTid());
510     if (context->version_ != Version::API10 && ret != E_PERMISSION) {
511         ret = E_OK;
512     }
513     if (ret == E_OK) {
514         context->boolRes = true;
515     }
516     return ret;
517 }
518 } // namespace OHOS::Request
519