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