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_container.h"
17
18#include "adapter/ohos/entrance/file_asset_provider_impl.h"
19#include "adapter/ohos/entrance/hap_asset_provider_impl.h"
20#include "adapter/ohos/entrance/pa_engine/engine/common/js_backend_engine_loader.h"
21#include "adapter/ohos/entrance/pa_engine/pa_backend.h"
22#include "base/log/ace_trace.h"
23#include "base/log/event_report.h"
24#include "base/log/log.h"
25#include "base/subwindow/subwindow_manager.h"
26#include "base/utils/system_properties.h"
27#include "base/utils/utils.h"
28#include "core/common/ace_engine.h"
29#include "core/common/asset_manager_impl.h"
30#include "core/common/platform_window.h"
31
32namespace OHOS::Ace::Platform {
33namespace {
34
35constexpr char ARK_PA_ENGINE_SHARED_LIB[] = "libace_engine_pa_ark.z.so";
36
37const char* GetPaEngineSharedLibrary()
38{
39    return ARK_PA_ENGINE_SHARED_LIB;
40}
41
42} // namespace
43
44PaContainer::PaContainer(int32_t instanceId, void* paAbility, const PaContainerOptions& options,
45    std::unique_ptr<PlatformEventCallback> callback)
46    : instanceId_(instanceId), paAbility_(paAbility)
47{
48    ACE_DCHECK(callback);
49    type_ = options.type;
50    hapPath_ = options.hapPath;
51    workerPath_ =  options.workerPath;
52    InitializeBackend(options.language);
53    platformEventCallback_ = std::move(callback);
54}
55
56void PaContainer::InitializeBackend(SrcLanguage language)
57{
58    // create backend
59    backend_ = Backend::Create();
60    auto paBackend = AceType::DynamicCast<PaBackend>(backend_);
61    CHECK_NULL_VOID(paBackend);
62
63    // set JS engine, init in JS thread
64    auto& loader = JsBackendEngineLoader::Get(GetPaEngineSharedLibrary());
65    auto jsEngine = loader.CreateJsBackendEngine(instanceId_);
66    jsEngine->AddExtraNativeObject("ability", paAbility_);
67    jsEngine->SetNeedDebugBreakPoint(AceApplicationInfo::GetInstance().IsNeedDebugBreakPoint());
68    jsEngine->SetDebugVersion(AceApplicationInfo::GetInstance().IsDebugVersion());
69    jsEngine->SetHapPath(hapPath_);
70    jsEngine->SetWorkerPath(workerPath_);
71    paBackend->SetJsEngine(jsEngine);
72
73    ACE_DCHECK(backend_);
74    backend_->Initialize(type_, language);
75}
76
77RefPtr<PaContainer> PaContainer::GetContainer(int32_t instanceId)
78{
79    auto container = AceEngine::Get().GetContainer(instanceId);
80    return AceType::DynamicCast<PaContainer>(container);
81}
82
83void PaContainer::CreateContainer(int32_t instanceId, void* paAbility, const PaContainerOptions& options,
84    std::unique_ptr<PlatformEventCallback> callback)
85{
86    auto aceContainer = AceType::MakeRefPtr<PaContainer>(instanceId, paAbility, options, std::move(callback));
87    AceEngine::Get().AddContainer(instanceId, aceContainer);
88
89    auto back = aceContainer->GetBackend();
90    CHECK_NULL_VOID(back);
91    back->UpdateState(Backend::State::ON_CREATE);
92}
93
94bool PaContainer::RunPa(int32_t instanceId, const std::string& content, const OHOS::AAFwk::Want& want)
95{
96    LOGI("PA: PaContainer RunPa start");
97    auto container = AceEngine::Get().GetContainer(instanceId);
98    CHECK_NULL_RETURN(container, false);
99    ContainerScope scope(instanceId);
100    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
101    CHECK_NULL_RETURN(aceContainer, false);
102    auto paBackend = AceType::DynamicCast<PaBackend>(aceContainer->GetBackend());
103    CHECK_NULL_RETURN(paBackend, false);
104    paBackend->RunPa(content, want);
105    return true;
106}
107
108bool PaContainer::OnCreate(int32_t instanceId, const OHOS::AAFwk::Want& want)
109{
110    LOGI("PA: PaContainer OnCreate start");
111    auto container = AceEngine::Get().GetContainer(instanceId);
112    CHECK_NULL_RETURN(container, false);
113    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
114    CHECK_NULL_RETURN(aceContainer, false);
115    auto paBackend = AceType::DynamicCast<PaBackend>(aceContainer->GetBackend());
116    CHECK_NULL_RETURN(paBackend, false);
117    paBackend->OnCreate(want);
118    return true;
119}
120
121bool PaContainer::OnDelete(int32_t instanceId, int64_t formId)
122{
123    LOGI("PA: PaContainer OnDelete start");
124    auto container = AceEngine::Get().GetContainer(instanceId);
125    CHECK_NULL_RETURN(container, false);
126    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
127    CHECK_NULL_RETURN(aceContainer, false);
128    auto paBackend = AceType::DynamicCast<PaBackend>(aceContainer->GetBackend());
129    CHECK_NULL_RETURN(paBackend, false);
130    paBackend->OnDelete(formId);
131    return true;
132}
133
134bool PaContainer::OnTriggerEvent(int32_t instanceId, int64_t formId, const std::string& message)
135{
136    LOGI("PA: PaContainer OnTriggerEvent start");
137    auto container = AceEngine::Get().GetContainer(instanceId);
138    CHECK_NULL_RETURN(container, false);
139    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
140    CHECK_NULL_RETURN(aceContainer, false);
141    auto paBackend = AceType::DynamicCast<PaBackend>(aceContainer->GetBackend());
142    CHECK_NULL_RETURN(paBackend, false);
143    paBackend->OnTriggerEvent(formId, message);
144    return true;
145}
146
147int32_t PaContainer::OnAcquireFormState(int32_t instanceId, const OHOS::AAFwk::Want& want)
148{
149    LOGI("PA: PaContainer OnAcquireFormState start");
150    auto container = AceEngine::Get().GetContainer(instanceId);
151    CHECK_NULL_RETURN(container, -1);
152    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
153    CHECK_NULL_RETURN(aceContainer, -1);
154    auto paBackend = AceType::DynamicCast<PaBackend>(aceContainer->GetBackend());
155    CHECK_NULL_RETURN(paBackend, -1);
156    int32_t formState = paBackend->OnAcquireFormState(want);
157    return formState;
158}
159
160bool PaContainer::OnUpdate(int32_t instanceId, int64_t formId)
161{
162    LOGI("PA: PaContainer OnUpdate start");
163    auto container = AceEngine::Get().GetContainer(instanceId);
164    CHECK_NULL_RETURN(container, false);
165    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
166    CHECK_NULL_RETURN(aceContainer, false);
167    auto paBackend = AceType::DynamicCast<PaBackend>(aceContainer->GetBackend());
168    CHECK_NULL_RETURN(paBackend, false);
169    paBackend->OnUpdate(formId);
170    return true;
171}
172
173bool PaContainer::OnCastTemptoNormal(int32_t instanceId, int64_t formId)
174{
175    LOGI("PA: PaContainer OnCastTemptoNormal start");
176    auto container = AceEngine::Get().GetContainer(instanceId);
177    CHECK_NULL_RETURN(container, false);
178    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
179    CHECK_NULL_RETURN(aceContainer, false);
180    auto paBackend = AceType::DynamicCast<PaBackend>(aceContainer->GetBackend());
181    CHECK_NULL_RETURN(paBackend, false);
182    paBackend->OnCastTemptoNormal(formId);
183    return true;
184}
185
186bool PaContainer::OnVisibilityChanged(int32_t instanceId, const std::map<int64_t, int32_t>& formEventsMap)
187{
188    LOGI("PA: PaContainer OnVisibilityChanged start");
189    auto container = AceEngine::Get().GetContainer(instanceId);
190    CHECK_NULL_RETURN(container, false);
191    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
192    CHECK_NULL_RETURN(aceContainer, false);
193    auto paBackend = AceType::DynamicCast<PaBackend>(aceContainer->GetBackend());
194    CHECK_NULL_RETURN(paBackend, false);
195    paBackend->OnVisibilityChanged(formEventsMap);
196    return true;
197}
198
199AppExecFwk::FormProviderData PaContainer::GetFormData(int32_t instanceId)
200{
201    LOGI("PA: PaContainer GetFormData start");
202    auto container = AceEngine::Get().GetContainer(instanceId);
203    CHECK_NULL_RETURN(container, AppExecFwk::FormProviderData());
204    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
205    CHECK_NULL_RETURN(aceContainer, AppExecFwk::FormProviderData());
206    auto paBackend = AceType::DynamicCast<PaBackend>(aceContainer->GetBackend());
207    CHECK_NULL_RETURN(paBackend, AppExecFwk::FormProviderData());
208    return paBackend->GetFormData();
209}
210
211void PaContainer::Destroy()
212{
213    RefPtr<Backend> backend;
214    backend_.Swap(backend);
215    CHECK_NULL_VOID(backend);
216    backend->UpdateState(Backend::State::ON_DESTROY);
217}
218
219void PaContainer::DestroyContainer(int32_t instanceId)
220{
221    LOGI("DestroyContainer with id %{private}d", instanceId);
222    SubwindowManager::GetInstance()->CloseDialog(instanceId);
223    auto container = AceEngine::Get().GetContainer(instanceId);
224    CHECK_NULL_VOID(container);
225    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
226    CHECK_NULL_VOID(aceContainer);
227    aceContainer->Destroy();
228}
229
230void PaContainer::AddAssetPath(int32_t instanceId, const std::string& packagePath, const std::string& hapPath,
231    const std::vector<std::string>& paths)
232{
233    auto container = AceType::DynamicCast<PaContainer>(AceEngine::Get().GetContainer(instanceId));
234    CHECK_NULL_VOID(container);
235    RefPtr<AssetManagerImpl> assetManagerImpl;
236    if (container->assetManager_) {
237        assetManagerImpl = AceType::DynamicCast<AssetManagerImpl>(container->assetManager_);
238    } else {
239        assetManagerImpl = Referenced::MakeRefPtr<AssetManagerImpl>();
240        container->assetManager_ = assetManagerImpl;
241        AceType::DynamicCast<PaBackend>(container->GetBackend())->SetAssetManager(assetManagerImpl);
242    }
243    CHECK_NULL_VOID(assetManagerImpl);
244    if (!hapPath.empty()) {
245        auto assetProvider = AceType::MakeRefPtr<HapAssetProviderImpl>();
246        if (assetProvider->Initialize(hapPath, paths)) {
247            LOGI("Push AssetProvider to queue.");
248            assetManagerImpl->PushBack(std::move(assetProvider));
249        }
250    }
251    if (!packagePath.empty()) {
252        auto assetProvider = AceType::MakeRefPtr<FileAssetProviderImpl>();
253        if (assetProvider->Initialize(packagePath, paths)) {
254            LOGI("Push AssetProvider to queue.");
255            assetManagerImpl->PushBack(std::move(assetProvider));
256        }
257    }
258}
259
260void PaContainer::AddLibPath(int32_t instanceId, const std::vector<std::string>& libPath)
261{
262    auto container = AceType::DynamicCast<PaContainer>(AceEngine::Get().GetContainer(instanceId));
263    CHECK_NULL_VOID(container);
264    RefPtr<AssetManager> assetManagerImpl;
265    if (container->assetManager_) {
266        assetManagerImpl = AceType::DynamicCast<AssetManagerImpl>(container->assetManager_);
267    } else {
268        assetManagerImpl = Referenced::MakeRefPtr<AssetManagerImpl>();
269        container->assetManager_ = assetManagerImpl;
270        AceType::DynamicCast<PaBackend>(container->GetBackend())->SetAssetManager(assetManagerImpl);
271    }
272    CHECK_NULL_VOID(assetManagerImpl);
273    assetManagerImpl->SetLibPath("default", libPath);
274}
275
276int32_t PaContainer::Insert(int32_t instanceId, const Uri& uri, const OHOS::NativeRdb::ValuesBucket& value)
277{
278    LOGI("Insert with id %{public}d", instanceId);
279    int32_t ret = 0;
280    auto container = AceEngine::Get().GetContainer(instanceId);
281    CHECK_NULL_RETURN(container, ret);
282    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
283    auto back = AceType::DynamicCast<PaBackend>(aceContainer->GetBackend());
284    CHECK_NULL_RETURN(back, ret);
285    ret = back->Insert(uri, value);
286    return ret;
287}
288
289std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> PaContainer::Query(int32_t instanceId, const Uri& uri,
290    const std::vector<std::string>& columns, const OHOS::NativeRdb::DataAbilityPredicates& predicates)
291{
292    LOGI("Query with id %{public}d", instanceId);
293    std::shared_ptr<OHOS::NativeRdb::AbsSharedResultSet> ret;
294    auto container = AceEngine::Get().GetContainer(instanceId);
295    CHECK_NULL_RETURN(container, ret);
296    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
297    auto back = AceType::DynamicCast<PaBackend>(aceContainer->GetBackend());
298    CHECK_NULL_RETURN(back, ret);
299    ret = back->Query(uri, columns, predicates);
300    return ret;
301}
302
303int32_t PaContainer::Update(int32_t instanceId, const Uri& uri, const OHOS::NativeRdb::ValuesBucket& value,
304    const OHOS::NativeRdb::DataAbilityPredicates& predicates)
305{
306    LOGI("Update with id %{public}d", instanceId);
307    int32_t ret = 0;
308    auto container = AceEngine::Get().GetContainer(instanceId);
309    CHECK_NULL_RETURN(container, ret);
310    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
311    auto back = AceType::DynamicCast<PaBackend>(aceContainer->GetBackend());
312    CHECK_NULL_RETURN(back, ret);
313    ret = back->Update(uri, value, predicates);
314    return ret;
315}
316
317int32_t PaContainer::Delete(
318    int32_t instanceId, const Uri& uri, const OHOS::NativeRdb::DataAbilityPredicates& predicates)
319{
320    LOGI("Delete with id %{public}d", instanceId);
321    int32_t ret = 0;
322    auto container = AceEngine::Get().GetContainer(instanceId);
323    CHECK_NULL_RETURN(container, ret);
324    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
325    auto back = AceType::DynamicCast<PaBackend>(aceContainer->GetBackend());
326    CHECK_NULL_RETURN(back, ret);
327    ret = back->Delete(uri, predicates);
328    return ret;
329}
330
331int32_t PaContainer::BatchInsert(
332    int32_t instanceId, const Uri& uri, const std::vector<OHOS::NativeRdb::ValuesBucket>& values)
333{
334    LOGI("BatchInsert with id %{public}d", instanceId);
335    int32_t ret = 0;
336    auto container = AceEngine::Get().GetContainer(instanceId);
337    CHECK_NULL_RETURN(container, ret);
338    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
339    auto back = AceType::DynamicCast<PaBackend>(aceContainer->GetBackend());
340    CHECK_NULL_RETURN(back, ret);
341    ret = back->BatchInsert(uri, values);
342    return ret;
343}
344
345std::string PaContainer::GetType(int32_t instanceId, const Uri& uri)
346{
347    LOGI("GetType with id %{public}d", instanceId);
348    std::string ret;
349    auto container = AceEngine::Get().GetContainer(instanceId);
350    CHECK_NULL_RETURN(container, ret);
351    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
352    auto back = AceType::DynamicCast<PaBackend>(aceContainer->GetBackend());
353    CHECK_NULL_RETURN(back, ret);
354    ret = back->GetType(uri);
355    return ret;
356}
357
358std::vector<std::string> PaContainer::GetFileTypes(
359    int32_t instanceId, const Uri& uri, const std::string& mimeTypeFilter)
360{
361    LOGI("GetFileTypes with id %{public}d", instanceId);
362    std::vector<std::string> ret;
363    auto container = AceEngine::Get().GetContainer(instanceId);
364    CHECK_NULL_RETURN(container, ret);
365    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
366    auto back = AceType::DynamicCast<PaBackend>(aceContainer->GetBackend());
367    CHECK_NULL_RETURN(back, ret);
368    ret = back->GetFileTypes(uri, mimeTypeFilter);
369    return ret;
370}
371
372int32_t PaContainer::OpenFile(int32_t instanceId, const Uri& uri, const std::string& mode)
373{
374    LOGI("OpenFile with id %{public}d", instanceId);
375    int32_t ret = 0;
376    auto container = AceEngine::Get().GetContainer(instanceId);
377    CHECK_NULL_RETURN(container, ret);
378    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
379    auto back = AceType::DynamicCast<PaBackend>(aceContainer->GetBackend());
380    CHECK_NULL_RETURN(back, ret);
381    ret = back->OpenFile(uri, mode);
382    return ret;
383}
384
385int32_t PaContainer::OpenRawFile(int32_t instanceId, const Uri& uri, const std::string& mode)
386{
387    LOGI("OpenRawFile with id %{public}d", instanceId);
388    int32_t ret = 0;
389    auto container = AceEngine::Get().GetContainer(instanceId);
390    CHECK_NULL_RETURN(container, ret);
391    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
392    auto back = AceType::DynamicCast<PaBackend>(aceContainer->GetBackend());
393    CHECK_NULL_RETURN(back, ret);
394    ret = back->OpenRawFile(uri, mode);
395    return ret;
396}
397
398Uri PaContainer::NormalizeUri(int32_t instanceId, const Uri& uri)
399{
400    LOGI("NormalizeUri with id %{public}d", instanceId);
401    Uri ret("");
402    auto container = AceEngine::Get().GetContainer(instanceId);
403    CHECK_NULL_RETURN(container, ret);
404    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
405    auto back = AceType::DynamicCast<PaBackend>(aceContainer->GetBackend());
406    CHECK_NULL_RETURN(back, ret);
407    ret = back->NormalizeUri(uri);
408    return ret;
409}
410
411Uri PaContainer::DenormalizeUri(int32_t instanceId, const Uri& uri)
412{
413    LOGI("DenormalizeUri with id %{public}d", instanceId);
414    Uri ret("");
415    auto container = AceEngine::Get().GetContainer(instanceId);
416    CHECK_NULL_RETURN(container, ret);
417    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
418    auto back = AceType::DynamicCast<PaBackend>(aceContainer->GetBackend());
419    CHECK_NULL_RETURN(back, ret);
420    ret = back->DenormalizeUri(uri);
421    return ret;
422}
423
424sptr<IRemoteObject> PaContainer::OnConnect(int32_t instanceId, const OHOS::AAFwk::Want& want)
425{
426    LOGI("OnConnect with id %{private}d", instanceId);
427    auto container = AceEngine::Get().GetContainer(instanceId);
428    CHECK_NULL_RETURN(container, nullptr);
429    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
430    auto back = aceContainer->GetBackend();
431    CHECK_NULL_RETURN(back, nullptr);
432    auto paBackend = AceType::DynamicCast<PaBackend>(back);
433    CHECK_NULL_RETURN(paBackend, nullptr);
434    return paBackend->OnConnect(want);
435    return nullptr;
436}
437
438void PaContainer::OnDisConnect(int32_t instanceId, const OHOS::AAFwk::Want& want)
439{
440    LOGI("OnDisConnect with id %{private}d", instanceId);
441    auto container = AceEngine::Get().GetContainer(instanceId);
442    CHECK_NULL_VOID(container);
443    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
444    auto back = aceContainer->GetBackend();
445    CHECK_NULL_VOID(back);
446    auto paBackend = AceType::DynamicCast<PaBackend>(back);
447    CHECK_NULL_VOID(paBackend);
448    paBackend->OnDisConnect(want);
449}
450
451void PaContainer::OnCommand(const OHOS::AAFwk::Want &want, int startId, int32_t instanceId)
452{
453    LOGI("OnCommand with id %{private}d", instanceId);
454    auto container = AceEngine::Get().GetContainer(instanceId);
455    CHECK_NULL_VOID(container);
456    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
457    auto back = aceContainer->GetBackend();
458    CHECK_NULL_VOID(back);
459    auto paBackend = AceType::DynamicCast<PaBackend>(back);
460    CHECK_NULL_VOID(paBackend);
461    paBackend->OnCommand(want, startId);
462}
463
464bool PaContainer::OnShare(int32_t instanceId, int64_t formId, OHOS::AAFwk::WantParams &wantParams)
465{
466    auto container = AceEngine::Get().GetContainer(instanceId);
467    CHECK_NULL_RETURN(container, false);
468    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
469    CHECK_NULL_RETURN(aceContainer, false);
470    auto paBackend = AceType::DynamicCast<PaBackend>(aceContainer->GetBackend());
471    CHECK_NULL_RETURN(paBackend, false);
472    return paBackend->OnShare(formId, wantParams);
473}
474
475std::shared_ptr<AppExecFwk::PacMap> PaContainer::Call(int32_t instanceId, const Uri& uri,
476    const std::string& method, const std::string& arg, const AppExecFwk::PacMap& pacMap)
477{
478    std::shared_ptr<AppExecFwk::PacMap> ret = nullptr;
479    auto container = AceEngine::Get().GetContainer(instanceId);
480    CHECK_NULL_RETURN(container, ret);
481    auto aceContainer = AceType::DynamicCast<PaContainer>(container);
482    auto back = AceType::DynamicCast<PaBackend>(aceContainer->GetBackend());
483    CHECK_NULL_RETURN(back, ret);
484    ret = back->Call(uri, method, arg, pacMap);
485    return ret;
486}
487} // namespace OHOS::Ace::Platform
488