1 /*
2 * Copyright (c) 2021 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 "adapter/ohos/entrance/pa_engine/backend_delegate_impl.h"
16
17 #include <atomic>
18 #include <string>
19
20 #include "ability.h"
21 #include "ability_info.h"
22
23 #include "base/log/ace_trace.h"
24 #include "base/log/event_report.h"
25 #include "base/utils/utils.h"
26 #include "core/common/ace_application_info.h"
27 #include "core/common/platform_bridge.h"
28 #include "core/components/dialog/dialog_component.h"
29 #include "core/components/toast/toast_component.h"
30 #include "frameworks/bridge/common/manifest/manifest_parser.h"
31 #include "frameworks/bridge/common/utils/utils.h"
32
33 namespace OHOS::Ace {
34 namespace {
35 const char PA_MANIFEST_JSON[] = "manifest.json";
36 } // namespace
37
BackendDelegateImpl(const BackendDelegateImplBuilder & builder)38 BackendDelegateImpl::BackendDelegateImpl(const BackendDelegateImplBuilder& builder)
39 : loadJs_(builder.loadCallback), dispatcherCallback_(builder.transferCallback),
40 asyncEvent_(builder.asyncEventCallback), syncEvent_(builder.syncEventCallback), insert_(builder.insertCallback),
41 query_(builder.queryCallback), update_(builder.updateCallback), delete_(builder.deleteCallback),
42 batchInsert_(builder.batchInsertCallback), getType_(builder.getTypeCallback),
43 getFileTypes_(builder.getFileTypesCallback), openFile_(builder.openFileCallback),
44 openRawFile_(builder.openRawFileCallback), normalizeUri_(builder.normalizeUriCallback),
45 denormalizeUri_(builder.denormalizeUriCallback), destroyApplication_(builder.destroyApplicationCallback),
46 commandApplication_(builder.commandApplicationCallback), connectCallback_(builder.connectCallback),
47 disConnectCallback_(builder.disConnectCallback), createCallback_(builder.createFormCallback),
48 deleteCallback_(builder.deleteFormCallback), triggerEventCallback_(builder.triggerEventCallback),
49 updateCallback_(builder.updateFormCallback), castTemptoNormalCallback_(builder.castTemptoNormalCallback),
50 visibilityChangedCallback_(builder.visibilityChangedCallback),
51 acquireStateCallback_(builder.acquireStateCallback),
52 commandCallback_(builder.commandCallback),
53 manifestParser_(AceType::MakeRefPtr<Framework::ManifestParser>()),
54 type_(builder.type),
55 taskExecutor_(builder.taskExecutor)
56 {}
57
ParseManifest()58 void BackendDelegateImpl::ParseManifest()
59 {
60 std::call_once(onceFlag_, [this]() {
61 std::string jsonContent;
62 if (!GetAssetContent(PA_MANIFEST_JSON, jsonContent)) {
63 LOGE("RunPa parse manifest.json failed");
64 EventReport::SendFormException(FormExcepType::RUN_PAGE_ERR);
65 return;
66 }
67 manifestParser_->Parse(jsonContent);
68 });
69 }
70
RunPa(const std::string & url,const OHOS::AAFwk::Want & want)71 void BackendDelegateImpl::RunPa(const std::string& url, const OHOS::AAFwk::Want& want)
72 {
73 ACE_SCOPED_TRACE("BackendDelegateImpl::RunService");
74 LOGD("dDelegateImpl RunService url=%{private}s", url.c_str());
75 ParseManifest();
76 // if mutli pa in one hap should parse manifest get right url
77 LoadPa(url, want);
78 }
79
SetJsMessageDispatcher(const RefPtr<JsMessageDispatcher> & dispatcher) const80 void BackendDelegateImpl::SetJsMessageDispatcher(const RefPtr<JsMessageDispatcher>& dispatcher) const
81 {
82 taskExecutor_->PostTask([dispatcherCallback = dispatcherCallback_, dispatcher] { dispatcherCallback(dispatcher); },
83 TaskExecutor::TaskType::JS);
84 }
85
SetCallBackResult(const std::string & callBackId,const std::string & result)86 void BackendDelegateImpl::SetCallBackResult(const std::string& callBackId, const std::string& result)
87 {
88 jsCallBackResult_.try_emplace(Framework::StringToInt(callBackId), result);
89 }
90
PostJsTask(std::function<void ()> && task)91 void BackendDelegateImpl::PostJsTask(std::function<void()>&& task)
92 {
93 taskExecutor_->PostTask(task, TaskExecutor::TaskType::JS);
94 }
95
PostDelayedJsTask(std::function<void ()> && task,uint32_t delayTime)96 void BackendDelegateImpl::PostDelayedJsTask(std::function<void()>&& task, uint32_t delayTime)
97 {
98 taskExecutor_->PostDelayedTask(task, TaskExecutor::TaskType::JS, delayTime);
99 }
100
GetAssetContent(const std::string & url,std::string & content)101 bool BackendDelegateImpl::GetAssetContent(const std::string& url, std::string& content)
102 {
103 return Framework::GetAssetContentImpl(assetManager_, url, content);
104 }
105
GetAssetContent(const std::string & url,std::vector<uint8_t> & content)106 bool BackendDelegateImpl::GetAssetContent(const std::string& url, std::vector<uint8_t>& content)
107 {
108 return Framework::GetAssetContentImpl(assetManager_, url, content);
109 }
110
GetAssetPath(const std::string & url)111 std::string BackendDelegateImpl::GetAssetPath(const std::string& url)
112 {
113 return Framework::GetAssetPathImpl(assetManager_, url);
114 }
115
LoadPa(const std::string & url,const OHOS::AAFwk::Want & want)116 void BackendDelegateImpl::LoadPa(const std::string& url, const OHOS::AAFwk::Want& want)
117 {
118 LOGD("BackendDelegateImpl LoadPa: %{private}s.", url.c_str());
119
120 std::unique_lock<std::mutex> lock(LoadPaMutex_);
121 if (isStagingPageExist_) {
122 if (condition_.wait_for(lock, std::chrono::seconds(1)) == std::cv_status::timeout) {
123 LOGE("BackendDelegateImpl, load page failed, waiting for current page loading finish.");
124 return;
125 }
126 }
127
128 isStagingPageExist_ = true;
129
130 if (GetType() == BackendType::FORM) {
131 taskExecutor_->PostSyncTask(
132 [weak = AceType::WeakClaim(this), url, want] {
133 auto delegate = weak.Upgrade();
134 if (!delegate) {
135 return;
136 }
137 delegate->loadJs_(url, want);
138 },
139 TaskExecutor::TaskType::JS);
140 } else {
141 taskExecutor_->PostTask(
142 [weak = AceType::WeakClaim(this), url, want] {
143 auto delegate = weak.Upgrade();
144 if (!delegate) {
145 return;
146 }
147 delegate->loadJs_(url, want);
148 },
149 TaskExecutor::TaskType::JS);
150 }
151 }
152
TransferJsResponseData(int32_t callbackId,int32_t code,std::vector<uint8_t> && data) const153 void BackendDelegateImpl::TransferJsResponseData(int32_t callbackId, int32_t code, std::vector<uint8_t>&& data) const
154 {
155 LOGI("BackendDelegateImpl TransferJsResponseData");
156 auto weak = AceType::WeakClaim(AceType::RawPtr(groupJsBridge_));
157 taskExecutor_->PostTask(
158 [callbackId, code, data = std::move(data), weak]() mutable {
159 auto groupJsBridge = weak.Upgrade();
160 if (groupJsBridge) {
161 groupJsBridge->TriggerModuleJsCallback(callbackId, code, std::move(data));
162 }
163 },
164 TaskExecutor::TaskType::JS);
165 }
166
TransferJsPluginGetError(int32_t callbackId,int32_t errorCode,std::string && errorMessage) const167 void BackendDelegateImpl::TransferJsPluginGetError(
168 int32_t callbackId, int32_t errorCode, std::string&& errorMessage) const
169 {
170 LOGI("BackendDelegateImpl TransferJsPluginGetError");
171 auto weak = AceType::WeakClaim(AceType::RawPtr(groupJsBridge_));
172 taskExecutor_->PostTask(
173 [callbackId, errorCode, errorMessage = std::move(errorMessage), weak]() mutable {
174 auto groupJsBridge = weak.Upgrade();
175 if (groupJsBridge) {
176 groupJsBridge->TriggerModulePluginGetErrorCallback(callbackId, errorCode, std::move(errorMessage));
177 }
178 },
179 TaskExecutor::TaskType::JS);
180 }
181
TransferJsEventData(int32_t callbackId,int32_t code,std::vector<uint8_t> && data) const182 void BackendDelegateImpl::TransferJsEventData(int32_t callbackId, int32_t code, std::vector<uint8_t>&& data) const
183 {
184 LOGI("BackendDelegateImpl TransferJsEventData");
185 auto weak = AceType::WeakClaim(AceType::RawPtr(groupJsBridge_));
186 taskExecutor_->PostTask(
187 [callbackId, code, data = std::move(data), weak]() mutable {
188 auto groupJsBridge = weak.Upgrade();
189 if (groupJsBridge) {
190 groupJsBridge->TriggerEventJsCallback(callbackId, code, std::move(data));
191 }
192 },
193 TaskExecutor::TaskType::JS);
194 }
195
LoadPluginJsCode(std::string && jsCode) const196 void BackendDelegateImpl::LoadPluginJsCode(std::string&& jsCode) const
197 {
198 LOGI("BackendDelegateImpl LoadPluginJsCode");
199 auto weak = AceType::WeakClaim(AceType::RawPtr(groupJsBridge_));
200 taskExecutor_->PostTask(
201 [jsCode = std::move(jsCode), weak]() mutable {
202 auto groupJsBridge = weak.Upgrade();
203 if (groupJsBridge) {
204 groupJsBridge->LoadPluginJsCode(std::move(jsCode));
205 }
206 },
207 TaskExecutor::TaskType::JS);
208 }
209
LoadPluginJsByteCode(std::vector<uint8_t> && jsCode,std::vector<int32_t> && jsCodeLen) const210 void BackendDelegateImpl::LoadPluginJsByteCode(std::vector<uint8_t>&& jsCode, std::vector<int32_t>&& jsCodeLen) const
211 {
212 LOGI("BackendDelegateImpl LoadPluginJsByteCode");
213 auto weak = AceType::WeakClaim(AceType::RawPtr(groupJsBridge_));
214 taskExecutor_->PostTask(
215 [jsCode = std::move(jsCode), jsCodeLen = std::move(jsCodeLen), weak]() mutable {
216 auto groupJsBridge = weak.Upgrade();
217 if (groupJsBridge) {
218 groupJsBridge->LoadPluginJsByteCode(std::move(jsCode), std::move(jsCodeLen));
219 }
220 },
221 TaskExecutor::TaskType::JS);
222 }
223
GetAnimationJsTask()224 SingleTaskExecutor BackendDelegateImpl::GetAnimationJsTask()
225 {
226 return SingleTaskExecutor::Make(taskExecutor_, TaskExecutor::TaskType::JS);
227 }
228
AddTaskObserver(std::function<void ()> && task)229 void BackendDelegateImpl::AddTaskObserver(std::function<void()>&& task)
230 {
231 taskExecutor_->AddTaskObserver(std::move(task));
232 }
233
RemoveTaskObserver()234 void BackendDelegateImpl::RemoveTaskObserver()
235 {
236 taskExecutor_->RemoveTaskObserver();
237 }
238
FireAsyncEvent(const std::string & eventId,const std::string & param,const std::string & jsonArgs)239 void BackendDelegateImpl::FireAsyncEvent(
240 const std::string& eventId, const std::string& param, const std::string& jsonArgs)
241 {
242 LOGD("FireAsyncEvent eventId: %{public}s", eventId.c_str());
243 std::string args = param;
244 args.append(",null").append(",null"); // callback and dom changes
245 if (!jsonArgs.empty()) {
246 args.append(",").append(jsonArgs); // method args
247 }
248 taskExecutor_->PostTask(
249 [weak = AceType::WeakClaim(this), eventId, args = std::move(args)] {
250 auto delegate = weak.Upgrade();
251 if (delegate) {
252 delegate->asyncEvent_(eventId, args);
253 }
254 },
255 TaskExecutor::TaskType::JS);
256 }
257
FireSyncEvent(const std::string & eventId,const std::string & param,const std::string & jsonArgs)258 bool BackendDelegateImpl::FireSyncEvent(
259 const std::string& eventId, const std::string& param, const std::string& jsonArgs)
260 {
261 std::string resultStr;
262 FireSyncEvent(eventId, param, jsonArgs, resultStr);
263 return (resultStr == "true");
264 }
265
FireSyncEvent(const std::string & eventId,const std::string & param,const std::string & jsonArgs,std::string & result)266 void BackendDelegateImpl::FireSyncEvent(
267 const std::string& eventId, const std::string& param, const std::string& jsonArgs, std::string& result)
268 {
269 int32_t callbackId = callbackCnt_++;
270 std::string args = param;
271 args.append("{\"_callbackId\":\"").append(std::to_string(callbackId)).append("\"}").append(",null");
272 if (!jsonArgs.empty()) {
273 args.append(",").append(jsonArgs); // method args
274 }
275 taskExecutor_->PostSyncTask(
276 [weak = AceType::WeakClaim(this), eventId, args = std::move(args)] {
277 auto delegate = weak.Upgrade();
278 if (delegate) {
279 delegate->syncEvent_(eventId, args);
280 }
281 },
282 TaskExecutor::TaskType::JS);
283
284 result = jsCallBackResult_[callbackId];
285 LOGD("FireSyncEvent eventId: %{public}s, callbackId: %{public}d", eventId.c_str(), callbackId);
286 jsCallBackResult_.erase(callbackId);
287 }
288
OnApplicationDestroy(const std::string & packageName)289 void BackendDelegateImpl::OnApplicationDestroy(const std::string& packageName)
290 {
291 taskExecutor_->PostSyncTask(
292 [destroyApplication = destroyApplication_, packageName] { destroyApplication(packageName); },
293 TaskExecutor::TaskType::JS);
294 }
295
OnApplicationCommand(const std::string & intent,int startId)296 void BackendDelegateImpl::OnApplicationCommand(const std::string& intent, int startId)
297 {
298 taskExecutor_->PostTask(
299 [weak = AceType::WeakClaim(this), intent, startId] {
300 auto delegate = weak.Upgrade();
301 if (!delegate) {
302 return;
303 }
304 delegate->commandApplication_(intent, startId);
305 },
306 TaskExecutor::TaskType::JS);
307 }
308
MethodChannel(const std::string & methodName,std::string & jsonStr)309 void BackendDelegateImpl::MethodChannel(const std::string& methodName, std::string& jsonStr)
310 {
311 std::string resultStr;
312 FireSyncEvent("_root", std::string("\"").append(methodName).append("\","), jsonStr, resultStr);
313 jsonStr.assign(resultStr);
314 }
315
Insert(const Uri & uri,const OHOS::NativeRdb::ValuesBucket & value)316 int32_t BackendDelegateImpl::Insert(const Uri& uri, const OHOS::NativeRdb::ValuesBucket& value)
317 {
318 int32_t ret = 0;
319 taskExecutor_->PostSyncTask(
320 [insert = insert_, &ret, uri, value] { ret = insert(uri, value); }, TaskExecutor::TaskType::JS);
321 return ret;
322 }
323
Query(const Uri & uri,const std::vector<std::string> & columns,const OHOS::NativeRdb::DataAbilityPredicates & predicates)324 std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> BackendDelegateImpl::Query(
325 const Uri& uri, const std::vector<std::string>& columns, const OHOS::NativeRdb::DataAbilityPredicates& predicates)
326 {
327 std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> ret;
328 taskExecutor_->PostSyncTask(
329 [query = query_, &ret, uri, columns, predicates] { ret = query(uri, columns, predicates); },
330 TaskExecutor::TaskType::JS);
331 return ret;
332 }
333
Update(const Uri & uri,const OHOS::NativeRdb::ValuesBucket & value,const OHOS::NativeRdb::DataAbilityPredicates & predicates)334 int32_t BackendDelegateImpl::Update(const Uri& uri, const OHOS::NativeRdb::ValuesBucket& value,
335 const OHOS::NativeRdb::DataAbilityPredicates& predicates)
336 {
337 int32_t ret = 0;
338 taskExecutor_->PostSyncTask(
339 [update = update_, &ret, uri, value, predicates] { ret = update(uri, value, predicates); },
340 TaskExecutor::TaskType::JS);
341 return ret;
342 }
343
Delete(const Uri & uri,const OHOS::NativeRdb::DataAbilityPredicates & predicates)344 int32_t BackendDelegateImpl::Delete(const Uri& uri, const OHOS::NativeRdb::DataAbilityPredicates& predicates)
345 {
346 int32_t ret = 0;
347 taskExecutor_->PostSyncTask(
348 [deleteCallback = delete_, &ret, uri, predicates] { ret = deleteCallback(uri, predicates); },
349 TaskExecutor::TaskType::JS);
350 return ret;
351 }
352
BatchInsert(const Uri & uri,const std::vector<OHOS::NativeRdb::ValuesBucket> & values)353 int32_t BackendDelegateImpl::BatchInsert(const Uri& uri, const std::vector<OHOS::NativeRdb::ValuesBucket>& values)
354 {
355 int32_t ret = 0;
356 taskExecutor_->PostSyncTask([batchInsert = batchInsert_, &ret, uri, values] { ret = batchInsert(uri, values); },
357 TaskExecutor::TaskType::JS);
358 return ret;
359 }
360
GetType(const Uri & uri)361 std::string BackendDelegateImpl::GetType(const Uri& uri)
362 {
363 std::string ret;
364 taskExecutor_->PostSyncTask([getType = getType_, &ret, uri] { ret = getType(uri); }, TaskExecutor::TaskType::JS);
365 return ret;
366 }
367
GetFileTypes(const Uri & uri,const std::string & mimeTypeFilter)368 std::vector<std::string> BackendDelegateImpl::GetFileTypes(const Uri& uri, const std::string& mimeTypeFilter)
369 {
370 std::vector<std::string> ret;
371 taskExecutor_->PostSyncTask(
372 [getFileTypes = getFileTypes_, &ret, uri, mimeTypeFilter] { ret = getFileTypes(uri, mimeTypeFilter); },
373 TaskExecutor::TaskType::JS);
374 return ret;
375 }
376
OpenFile(const Uri & uri,const std::string & mode)377 int32_t BackendDelegateImpl::OpenFile(const Uri& uri, const std::string& mode)
378 {
379 int32_t ret = 0;
380 taskExecutor_->PostSyncTask(
381 [openFile = openFile_, &ret, uri, mode] { ret = openFile(uri, mode); }, TaskExecutor::TaskType::JS);
382 return ret;
383 }
384
OpenRawFile(const Uri & uri,const std::string & mode)385 int32_t BackendDelegateImpl::OpenRawFile(const Uri& uri, const std::string& mode)
386 {
387 int32_t ret = 0;
388 taskExecutor_->PostSyncTask(
389 [openRawFile = openRawFile_, &ret, uri, mode] { ret = openRawFile(uri, mode); }, TaskExecutor::TaskType::JS);
390 return ret;
391 }
392
NormalizeUri(const Uri & uri)393 Uri BackendDelegateImpl::NormalizeUri(const Uri& uri)
394 {
395 Uri ret("");
396 taskExecutor_->PostSyncTask(
397 [normalizeUri = normalizeUri_, &ret, uri] { ret = normalizeUri(uri); }, TaskExecutor::TaskType::JS);
398 return ret;
399 }
400
DenormalizeUri(const Uri & uri)401 Uri BackendDelegateImpl::DenormalizeUri(const Uri& uri)
402 {
403 Uri ret("");
404 taskExecutor_->PostSyncTask(
405 [denormalizeUri = denormalizeUri_, &ret, uri] { ret = denormalizeUri(uri); }, TaskExecutor::TaskType::JS);
406 return ret;
407 }
408
OnConnect(const OHOS::AAFwk::Want & want)409 sptr<IRemoteObject> BackendDelegateImpl::OnConnect(const OHOS::AAFwk::Want& want)
410 {
411 sptr<IRemoteObject> ret = nullptr;
412 taskExecutor_->PostSyncTask([connectCallback = connectCallback_, want, &ret]() { ret = connectCallback(want); },
413 TaskExecutor::TaskType::JS);
414 return ret;
415 }
416
OnDisConnect(const OHOS::AAFwk::Want & want)417 void BackendDelegateImpl::OnDisConnect(const OHOS::AAFwk::Want& want)
418 {
419 taskExecutor_->PostTask(
420 [disConnectCallback = disConnectCallback_, want] { disConnectCallback(want); }, TaskExecutor::TaskType::JS);
421 }
422
OnCreate(const OHOS::AAFwk::Want & want)423 void BackendDelegateImpl::OnCreate(const OHOS::AAFwk::Want& want)
424 {
425 taskExecutor_->PostSyncTask(
426 [createCallback = createCallback_, want] { createCallback(want); }, TaskExecutor::TaskType::JS);
427 }
428
OnDelete(const int64_t formId)429 void BackendDelegateImpl::OnDelete(const int64_t formId)
430 {
431 taskExecutor_->PostTask(
432 [deleteCallback = deleteCallback_, formId] { deleteCallback(formId); }, TaskExecutor::TaskType::JS);
433 }
434
OnTriggerEvent(const int64_t formId,const std::string & message)435 void BackendDelegateImpl::OnTriggerEvent(const int64_t formId, const std::string& message)
436 {
437 taskExecutor_->PostTask(
438 [triggerEventCallback = triggerEventCallback_, formId, message] { triggerEventCallback(formId, message); },
439 TaskExecutor::TaskType::JS);
440 }
441
OnUpdate(const int64_t formId)442 void BackendDelegateImpl::OnUpdate(const int64_t formId)
443 {
444 taskExecutor_->PostTask(
445 [updateCallback = updateCallback_, formId] { updateCallback(formId); }, TaskExecutor::TaskType::JS);
446 }
447
OnCastTemptoNormal(const int64_t formId)448 void BackendDelegateImpl::OnCastTemptoNormal(const int64_t formId)
449 {
450 taskExecutor_->PostTask(
451 [castTemptoNormalCallback = castTemptoNormalCallback_, formId] { castTemptoNormalCallback(formId); },
452 TaskExecutor::TaskType::JS);
453 }
454
OnVisibilityChanged(const std::map<int64_t,int32_t> & formEventsMap)455 void BackendDelegateImpl::OnVisibilityChanged(const std::map<int64_t, int32_t>& formEventsMap)
456 {
457 taskExecutor_->PostTask([visibilityChangedCallback = visibilityChangedCallback_,
458 formEventsMap] { visibilityChangedCallback(formEventsMap); },
459 TaskExecutor::TaskType::JS);
460 }
461
OnAcquireFormState(const OHOS::AAFwk::Want & want)462 int32_t BackendDelegateImpl::OnAcquireFormState(const OHOS::AAFwk::Want &want)
463 {
464 auto ret = (int32_t) AppExecFwk::FormState::UNKNOWN;
465 taskExecutor_->PostSyncTask(
466 [acquireStateCallback = acquireStateCallback_, &ret, want] { ret = acquireStateCallback(want); },
467 TaskExecutor::TaskType::JS);
468 return ret;
469 }
470
OnCommand(const OHOS::AAFwk::Want & want,int startId)471 void BackendDelegateImpl::OnCommand(const OHOS::AAFwk::Want &want, int startId)
472 {
473 taskExecutor_->PostTask([commandCallback = commandCallback_, want, startId] { commandCallback(want, startId); },
474 TaskExecutor::TaskType::JS);
475 }
476
ParseFileUri(const RefPtr<AssetManager> & assetManager,const std::string & fileUri,std::string & assetsFilePath)477 bool BackendDelegateImpl::ParseFileUri(
478 const RefPtr<AssetManager>& assetManager, const std::string& fileUri, std::string& assetsFilePath)
479 {
480 if (!assetManager || fileUri.empty() || (fileUri.length() > PATH_MAX)) {
481 return false;
482 }
483
484 std::string fileName;
485 std::string filePath;
486 size_t slashPos = fileUri.find_last_of("/");
487 if (slashPos == std::string::npos) {
488 fileName = fileUri;
489 } else {
490 fileName = fileUri.substr(slashPos + 1);
491 filePath = fileUri.substr(0, slashPos);
492 }
493
494 if (Framework::StartWith(filePath, "/")) {
495 filePath = filePath.substr(1);
496 }
497
498 std::vector<std::string> files;
499 assetManager->GetAssetList(filePath, files);
500
501 bool fileExist = false;
502 for (const auto& file : files) {
503 bool startWithSlash = Framework::StartWith(file, "/");
504 if ((startWithSlash && (file.substr(1) == fileName)) || (!startWithSlash && (file == fileName))) {
505 assetsFilePath = filePath + file;
506 fileExist = true;
507 break;
508 }
509 }
510
511 return fileExist;
512 }
513
GetResourceData(const std::string & fileUri,std::vector<uint8_t> & content,std::string & ami)514 bool BackendDelegateImpl::GetResourceData(const std::string& fileUri, std::vector<uint8_t>& content, std::string& ami)
515 {
516 std::string targetFilePath;
517 if (!ParseFileUri(assetManager_, fileUri, targetFilePath)) {
518 LOGE("GetResourceData parse file uri failed.");
519 return false;
520 }
521 ami = assetManager_->GetAssetPath(targetFilePath) + targetFilePath;
522 if (!Framework::GetAssetContentAllowEmpty(assetManager_, targetFilePath, content)) {
523 LOGE("GetResourceData GetAssetContent failed.");
524 return false;
525 }
526
527 return true;
528 }
529
530 } // namespace OHOS::Ace::Framework
531