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