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