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
16 #include "adapter/ohos/entrance/pa_engine/pa_backend.h"
17
18 #include "napi_remote_object.h"
19
20 #include "ability.h"
21 #include "adapter/ohos/entrance/pa_engine/engine/common/js_backend_engine_loader.h"
22 #include "base/log/dump_log.h"
23 #include "base/log/event_report.h"
24 #include "base/utils/utils.h"
25 #include "frameworks/bridge/common/utils/utils.h"
26
27 namespace OHOS::Ace {
28 namespace {
29 const char PA_MANIFEST_JSON[] = "manifest.json";
30 } // namespace
31
Create()32 RefPtr<Backend> Backend::Create()
33 {
34 return AceType::MakeRefPtr<PaBackend>();
35 }
36
~PaBackend()37 PaBackend::~PaBackend() noexcept
38 {
39 LOGI("PaBackend destructor.");
40 }
41
Initialize(BackendType type,SrcLanguage language)42 bool PaBackend::Initialize(BackendType type, SrcLanguage language)
43 {
44 LOGI("PaBackend initialize begin.");
45 type_ = type;
46 language_ = language;
47
48 CHECK_NULL_RETURN_NOLOG(jsBackendEngine_, false);
49 jsBackendEngine_->Initialize(type, language);
50
51 LOGI("PaBackend initialize end.");
52 return true;
53 }
54
LoadEngine(const char * libName,int32_t instanceId)55 void PaBackend::LoadEngine(const char* libName, int32_t instanceId)
56 {
57 auto& loader = JsBackendEngineLoader::Get(libName);
58 SetJsEngine(loader.CreateJsBackendEngine(instanceId));
59 }
60
UpdateState(Backend::State state)61 void PaBackend::UpdateState(Backend::State state)
62 {
63 LOGI("UpdateState");
64 switch (state) {
65 case Backend::State::ON_CREATE:
66 break;
67 case Backend::State::ON_DESTROY:
68 if (jsBackendEngine_) {
69 jsBackendEngine_->PostSyncTask(
70 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_)] {
71 auto jsBackendEngine = weakEngine.Upgrade();
72 CHECK_NULL_VOID_NOLOG(jsBackendEngine);
73 jsBackendEngine->DestroyApplication("pa");
74 });
75 }
76 break;
77 default:
78 LOGE("error State: %d", state);
79 }
80 }
81
OnCommand(const OHOS::AAFwk::Want & want,int startId)82 void PaBackend::OnCommand(const OHOS::AAFwk::Want& want, int startId)
83 {
84 CHECK_NULL_VOID(jsBackendEngine_);
85 jsBackendEngine_->PostTask(
86 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), want, startId] {
87 auto jsBackendEngine = weakEngine.Upgrade();
88 CHECK_NULL_VOID_NOLOG(jsBackendEngine);
89 jsBackendEngine->OnCommand(want, startId);
90 });
91 }
92
SetAssetManager(const RefPtr<AssetManager> & assetManager)93 void PaBackend::SetAssetManager(const RefPtr<AssetManager>& assetManager)
94 {
95 assetManager_ = assetManager;
96 CHECK_NULL_VOID(jsBackendEngine_);
97 jsBackendEngine_->SetAssetManager(assetManager);
98 }
99
Insert(const Uri & uri,const OHOS::NativeRdb::ValuesBucket & value)100 int32_t PaBackend::Insert(const Uri& uri, const OHOS::NativeRdb::ValuesBucket& value)
101 {
102 int32_t ret = 0;
103 CallingInfo callingInfo;
104 NAPI_RemoteObject_getCallingInfo(callingInfo);
105 LOGD("Calling token id is %{public}u.", callingInfo.callingTokenId);
106 CHECK_NULL_RETURN(jsBackendEngine_, ret);
107 jsBackendEngine_->PostSyncTask(
108 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), &ret, uri, value, callingInfo] {
109 auto jsBackendEngine = weakEngine.Upgrade();
110 if (jsBackendEngine != nullptr) {
111 ret = jsBackendEngine->Insert(uri, value, callingInfo);
112 }
113 });
114 return ret;
115 }
116
Call(const Uri & uri,const std::string & method,const std::string & arg,const AppExecFwk::PacMap & pacMap)117 std::shared_ptr<AppExecFwk::PacMap> PaBackend::Call(
118 const Uri& uri, const std::string& method, const std::string& arg, const AppExecFwk::PacMap& pacMap)
119 {
120 std::shared_ptr<AppExecFwk::PacMap> ret = nullptr;
121 CallingInfo callingInfo;
122 NAPI_RemoteObject_getCallingInfo(callingInfo);
123 LOGD("Calling token id is %{public}u.", callingInfo.callingTokenId);
124 CHECK_NULL_RETURN(jsBackendEngine_, ret);
125 jsBackendEngine_->PostSyncTask(
126 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), &ret, method, arg, pacMap, callingInfo] {
127 auto jsBackendEngine = weakEngine.Upgrade();
128 if (jsBackendEngine != nullptr) {
129 ret = jsBackendEngine->Call(method, arg, pacMap, callingInfo);
130 }
131 });
132 return ret;
133 }
134
Query(const Uri & uri,const std::vector<std::string> & columns,const OHOS::NativeRdb::DataAbilityPredicates & predicates)135 std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> PaBackend::Query(
136 const Uri& uri, const std::vector<std::string>& columns, const OHOS::NativeRdb::DataAbilityPredicates& predicates)
137 {
138 std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> ret = nullptr;
139 CallingInfo callingInfo;
140 NAPI_RemoteObject_getCallingInfo(callingInfo);
141 LOGD("Calling token id is %{public}u.", callingInfo.callingTokenId);
142 CHECK_NULL_RETURN(jsBackendEngine_, ret);
143 jsBackendEngine_->PostSyncTask(
144 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), &ret, uri, columns, predicates, callingInfo] {
145 auto jsBackendEngine = weakEngine.Upgrade();
146 if (jsBackendEngine != nullptr) {
147 ret = jsBackendEngine->Query(uri, columns, predicates, callingInfo);
148 }
149 });
150 return ret;
151 }
152
Update(const Uri & uri,const OHOS::NativeRdb::ValuesBucket & value,const OHOS::NativeRdb::DataAbilityPredicates & predicates)153 int32_t PaBackend::Update(const Uri& uri, const OHOS::NativeRdb::ValuesBucket& value,
154 const OHOS::NativeRdb::DataAbilityPredicates& predicates)
155 {
156 int32_t ret = 0;
157 CallingInfo callingInfo;
158 NAPI_RemoteObject_getCallingInfo(callingInfo);
159 LOGD("Calling token id is %{public}u.", callingInfo.callingTokenId);
160 CHECK_NULL_RETURN(jsBackendEngine_, ret);
161 jsBackendEngine_->PostSyncTask(
162 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), &ret, uri, value, predicates, callingInfo] {
163 auto jsBackendEngine = weakEngine.Upgrade();
164 if (jsBackendEngine != nullptr) {
165 ret = jsBackendEngine->Update(uri, value, predicates, callingInfo);
166 }
167 });
168 return ret;
169 }
170
Delete(const Uri & uri,const OHOS::NativeRdb::DataAbilityPredicates & predicates)171 int32_t PaBackend::Delete(const Uri& uri, const OHOS::NativeRdb::DataAbilityPredicates& predicates)
172 {
173 int32_t ret = 0;
174 CallingInfo callingInfo;
175 NAPI_RemoteObject_getCallingInfo(callingInfo);
176 LOGD("Calling token id is %{public}u.", callingInfo.callingTokenId);
177 CHECK_NULL_RETURN(jsBackendEngine_, ret);
178 jsBackendEngine_->PostSyncTask(
179 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), &ret, uri, predicates, callingInfo] {
180 auto jsBackendEngine = weakEngine.Upgrade();
181 if (jsBackendEngine != nullptr) {
182 ret = jsBackendEngine->Delete(uri, predicates, callingInfo);
183 }
184 });
185 return ret;
186 }
187
BatchInsert(const Uri & uri,const std::vector<OHOS::NativeRdb::ValuesBucket> & values)188 int32_t PaBackend::BatchInsert(const Uri& uri, const std::vector<OHOS::NativeRdb::ValuesBucket>& values)
189 {
190 int32_t ret = 0;
191 CallingInfo callingInfo;
192 NAPI_RemoteObject_getCallingInfo(callingInfo);
193 LOGD("Calling token id is %{public}u.", callingInfo.callingTokenId);
194 CHECK_NULL_RETURN(jsBackendEngine_, ret);
195 jsBackendEngine_->PostSyncTask(
196 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), &ret, uri, values, callingInfo] {
197 auto jsBackendEngine = weakEngine.Upgrade();
198 if (jsBackendEngine != nullptr) {
199 ret = jsBackendEngine->BatchInsert(uri, values, callingInfo);
200 }
201 });
202 return ret;
203 }
204
GetType(const Uri & uri)205 std::string PaBackend::GetType(const Uri& uri)
206 {
207 std::string ret;
208 CallingInfo callingInfo;
209 NAPI_RemoteObject_getCallingInfo(callingInfo);
210 LOGD("Calling token id is %{public}u.", callingInfo.callingTokenId);
211 CHECK_NULL_RETURN(jsBackendEngine_, ret);
212 jsBackendEngine_->PostSyncTask(
213 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), &ret, uri, callingInfo] {
214 auto jsBackendEngine = weakEngine.Upgrade();
215 if (jsBackendEngine != nullptr) {
216 ret = jsBackendEngine->GetType(uri, callingInfo);
217 }
218 });
219 return ret;
220 }
221
GetFileTypes(const Uri & uri,const std::string & mimeTypeFilter)222 std::vector<std::string> PaBackend::GetFileTypes(const Uri& uri, const std::string& mimeTypeFilter)
223 {
224 std::vector<std::string> ret;
225 CallingInfo callingInfo;
226 NAPI_RemoteObject_getCallingInfo(callingInfo);
227 LOGD("Calling token id is %{public}u.", callingInfo.callingTokenId);
228 CHECK_NULL_RETURN(jsBackendEngine_, ret);
229 jsBackendEngine_->PostSyncTask(
230 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), &ret, uri, mimeTypeFilter, callingInfo] {
231 auto jsBackendEngine = weakEngine.Upgrade();
232 if (jsBackendEngine != nullptr) {
233 ret = jsBackendEngine->GetFileTypes(uri, mimeTypeFilter, callingInfo);
234 }
235 });
236 return ret;
237 }
238
OpenFile(const Uri & uri,const std::string & mode)239 int32_t PaBackend::OpenFile(const Uri& uri, const std::string& mode)
240 {
241 int32_t ret = 0;
242 CallingInfo callingInfo;
243 NAPI_RemoteObject_getCallingInfo(callingInfo);
244 LOGD("Calling token id is %{public}u.", callingInfo.callingTokenId);
245 CHECK_NULL_RETURN(jsBackendEngine_, ret);
246 jsBackendEngine_->PostSyncTask(
247 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), &ret, uri, mode, callingInfo] {
248 auto jsBackendEngine = weakEngine.Upgrade();
249 if (jsBackendEngine != nullptr) {
250 ret = jsBackendEngine->OpenFile(uri, mode, callingInfo);
251 }
252 });
253 return ret;
254 }
255
OpenRawFile(const Uri & uri,const std::string & mode)256 int32_t PaBackend::OpenRawFile(const Uri& uri, const std::string& mode)
257 {
258 int32_t ret = 0;
259 CallingInfo callingInfo;
260 NAPI_RemoteObject_getCallingInfo(callingInfo);
261 LOGD("Calling token id is %{public}u.", callingInfo.callingTokenId);
262 CHECK_NULL_RETURN(jsBackendEngine_, ret);
263 jsBackendEngine_->PostSyncTask(
264 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), &ret, uri, mode, callingInfo] {
265 auto jsBackendEngine = weakEngine.Upgrade();
266 if (jsBackendEngine != nullptr) {
267 ret = jsBackendEngine->OpenRawFile(uri, mode, callingInfo);
268 }
269 });
270 return ret;
271 }
272
NormalizeUri(const Uri & uri)273 Uri PaBackend::NormalizeUri(const Uri& uri)
274 {
275 Uri ret("");
276 CallingInfo callingInfo;
277 NAPI_RemoteObject_getCallingInfo(callingInfo);
278 LOGD("Calling token id is %{public}u.", callingInfo.callingTokenId);
279 CHECK_NULL_RETURN(jsBackendEngine_, ret);
280 jsBackendEngine_->PostSyncTask(
281 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), &ret, uri, callingInfo] {
282 auto jsBackendEngine = weakEngine.Upgrade();
283 if (jsBackendEngine != nullptr) {
284 ret = jsBackendEngine->NormalizeUri(uri, callingInfo);
285 }
286 });
287 return ret;
288 }
289
DenormalizeUri(const Uri & uri)290 Uri PaBackend::DenormalizeUri(const Uri& uri)
291 {
292 Uri ret("");
293 CallingInfo callingInfo;
294 NAPI_RemoteObject_getCallingInfo(callingInfo);
295 LOGD("Calling token id is %{public}u.", callingInfo.callingTokenId);
296 CHECK_NULL_RETURN(jsBackendEngine_, ret);
297 jsBackendEngine_->PostSyncTask(
298 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), &ret, uri, callingInfo] {
299 auto jsBackendEngine = weakEngine.Upgrade();
300 if (jsBackendEngine != nullptr) {
301 ret = jsBackendEngine->DenormalizeUri(uri, callingInfo);
302 }
303 });
304 return ret;
305 }
306
ParseManifest()307 void PaBackend::ParseManifest()
308 {
309 std::call_once(onceFlag_, [this]() {
310 std::string jsonContent;
311 if (!Framework::GetAssetContentImpl(assetManager_, PA_MANIFEST_JSON, jsonContent)) {
312 LOGE("RunPa parse manifest.json failed.");
313 EventReport::SendFormException(FormExcepType::RUN_PAGE_ERR);
314 return;
315 }
316
317 if (manifestParser_ != nullptr) {
318 manifestParser_->Parse(jsonContent);
319 }
320 });
321 }
322
LoadPa(const std::string & url,const OHOS::AAFwk::Want & want)323 void PaBackend::LoadPa(const std::string& url, const OHOS::AAFwk::Want& want)
324 {
325 LOGD("LoadPa: %{private}s.", url.c_str());
326 CHECK_NULL_VOID(jsBackendEngine_);
327
328 std::unique_lock<std::mutex> lock(LoadPaMutex_);
329 if (isStagingPageExist_) {
330 if (condition_.wait_for(lock, std::chrono::seconds(1)) == std::cv_status::timeout) {
331 LOGE("Load page failed, waiting for current page loading finish.");
332 return;
333 }
334 }
335
336 isStagingPageExist_ = true;
337
338 if (type_ == BackendType::FORM) {
339 jsBackendEngine_->PostSyncTask(
340 [weak = WeakPtr<JsBackendEngine>(jsBackendEngine_), url, want] {
341 auto jsBackendEngine = weak.Upgrade();
342 CHECK_NULL_VOID_NOLOG(jsBackendEngine);
343 jsBackendEngine->LoadJs(url, want);
344 });
345 } else {
346 jsBackendEngine_->PostTask(
347 [weak = WeakPtr<JsBackendEngine>(jsBackendEngine_), url, want] {
348 auto jsBackendEngine = weak.Upgrade();
349 CHECK_NULL_VOID_NOLOG(jsBackendEngine);
350 jsBackendEngine->LoadJs(url, want);
351 });
352 }
353 }
354
RunPa(const std::string & url,const OHOS::AAFwk::Want & want)355 void PaBackend::RunPa(const std::string& url, const OHOS::AAFwk::Want& want)
356 {
357 ACE_SCOPED_TRACE("PaBackend::RunPa");
358 LOGD("RunPa url=%{private}s.", url.c_str());
359 ParseManifest();
360 // if mutli pa in one hap should parse manifest get right url
361 LoadPa(url, want);
362 }
363
OnCreate(const OHOS::AAFwk::Want & want)364 void PaBackend::OnCreate(const OHOS::AAFwk::Want& want)
365 {
366 CHECK_NULL_VOID(jsBackendEngine_);
367 jsBackendEngine_->PostSyncTask(
368 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), want] {
369 auto jsBackendEngine = weakEngine.Upgrade();
370 CHECK_NULL_VOID_NOLOG(jsBackendEngine);
371 jsBackendEngine->OnCreate(want);
372 });
373 }
374
OnDelete(const int64_t formId)375 void PaBackend::OnDelete(const int64_t formId)
376 {
377 CHECK_NULL_VOID(jsBackendEngine_);
378 jsBackendEngine_->PostTask(
379 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), formId] {
380 auto jsBackendEngine = weakEngine.Upgrade();
381 CHECK_NULL_VOID_NOLOG(jsBackendEngine);
382 jsBackendEngine->OnDelete(formId);
383 });
384 }
385
OnTriggerEvent(const int64_t formId,const std::string & message)386 void PaBackend::OnTriggerEvent(const int64_t formId, const std::string& message)
387 {
388 CHECK_NULL_VOID(jsBackendEngine_);
389 jsBackendEngine_->PostTask(
390 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), formId, message] {
391 auto jsBackendEngine = weakEngine.Upgrade();
392 CHECK_NULL_VOID_NOLOG(jsBackendEngine);
393 jsBackendEngine->OnTriggerEvent(formId, message);
394 });
395 }
396
OnUpdate(const int64_t formId)397 void PaBackend::OnUpdate(const int64_t formId)
398 {
399 CHECK_NULL_VOID(jsBackendEngine_);
400 jsBackendEngine_->PostTask(
401 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), formId] {
402 auto jsBackendEngine = weakEngine.Upgrade();
403 CHECK_NULL_VOID_NOLOG(jsBackendEngine);
404 jsBackendEngine->OnUpdate(formId);
405 });
406 }
407
OnCastTemptoNormal(const int64_t formId)408 void PaBackend::OnCastTemptoNormal(const int64_t formId)
409 {
410 CHECK_NULL_VOID(jsBackendEngine_);
411 jsBackendEngine_->PostTask(
412 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), formId] {
413 auto jsBackendEngine = weakEngine.Upgrade();
414 CHECK_NULL_VOID_NOLOG(jsBackendEngine);
415 jsBackendEngine->OnCastTemptoNormal(formId);
416 });
417 }
418
OnVisibilityChanged(const std::map<int64_t,int32_t> & formEventsMap)419 void PaBackend::OnVisibilityChanged(const std::map<int64_t, int32_t>& formEventsMap)
420 {
421 CHECK_NULL_VOID(jsBackendEngine_);
422 jsBackendEngine_->PostTask(
423 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), formEventsMap] {
424 auto jsBackendEngine = weakEngine.Upgrade();
425 CHECK_NULL_VOID_NOLOG(jsBackendEngine);
426 jsBackendEngine->OnVisibilityChanged(formEventsMap);
427 });
428 }
429
OnAcquireFormState(const OHOS::AAFwk::Want & want)430 int32_t PaBackend::OnAcquireFormState(const OHOS::AAFwk::Want& want)
431 {
432 auto ret = (int32_t)AppExecFwk::FormState::UNKNOWN;
433 CHECK_NULL_RETURN(jsBackendEngine_, ret);
434 jsBackendEngine_->PostSyncTask(
435 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), &ret, want] {
436 auto jsBackendEngine = weakEngine.Upgrade();
437 if (jsBackendEngine != nullptr) {
438 ret = jsBackendEngine->OnAcquireFormState(want);
439 }
440 });
441 return ret;
442 }
443
OnConnect(const OHOS::AAFwk::Want & want)444 sptr<IRemoteObject> PaBackend::OnConnect(const OHOS::AAFwk::Want& want)
445 {
446 sptr<IRemoteObject> ret = nullptr;
447 CHECK_NULL_RETURN(jsBackendEngine_, ret);
448 jsBackendEngine_->PostSyncTask(
449 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), &ret, want] {
450 auto jsBackendEngine = weakEngine.Upgrade();
451 if (jsBackendEngine != nullptr) {
452 ret = jsBackendEngine->OnConnectService(want);
453 }
454 });
455 return ret;
456 }
457
OnDisConnect(const OHOS::AAFwk::Want & want)458 void PaBackend::OnDisConnect(const OHOS::AAFwk::Want& want)
459 {
460 CHECK_NULL_VOID(jsBackendEngine_);
461 jsBackendEngine_->PostTask(
462 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), want] {
463 auto jsBackendEngine = weakEngine.Upgrade();
464 CHECK_NULL_VOID_NOLOG(jsBackendEngine);
465 jsBackendEngine->OnDisconnectService(want);
466 });
467 }
468
OnShare(int64_t formId,OHOS::AAFwk::WantParams & wantParams)469 bool PaBackend::OnShare(int64_t formId, OHOS::AAFwk::WantParams& wantParams)
470 {
471 bool result = false;
472 CHECK_NULL_RETURN(jsBackendEngine_, result);
473 jsBackendEngine_->PostSyncTask(
474 [weakEngine = WeakPtr<JsBackendEngine>(jsBackendEngine_), &result, formId, &wantParams] {
475 auto jsBackendEngine = weakEngine.Upgrade();
476 if (jsBackendEngine != nullptr) {
477 result = jsBackendEngine->OnShare(formId, wantParams);
478 }
479 });
480 return result;
481 }
482 } // namespace OHOS::Ace
483