1 /*
2  * Copyright (c) 2021-2023 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 #ifndef FOUNDATION_ACE_ADAPTER_PREVIEW_ACE_CONTAINER_H
17 #define FOUNDATION_ACE_ADAPTER_PREVIEW_ACE_CONTAINER_H
18 
19 #include <memory>
20 #include <mutex>
21 #include <string>
22 #include <vector>
23 
24 #include "adapter/preview/entrance/ace_run_args.h"
25 #include "adapter/preview/entrance/ace_view_preview.h"
26 #include "adapter/preview/external/ability/stage/stage_pkg_context_info.h"
27 #include "adapter/preview/osal/fetch_manager.h"
28 #include "base/resource/asset_manager.h"
29 #include "base/thread/task_executor.h"
30 #include "base/utils/noncopyable.h"
31 #include "core/common/ace_view.h"
32 #include "core/common/container.h"
33 #include "core/common/js_message_dispatcher.h"
34 #include "core/common/platform_bridge.h"
35 #include "frameworks/bridge/js_frontend/engine/common/js_engine.h"
36 
37 
38 #include <refbase.h>
39 
40 namespace OHOS::Rosen {
41     class Window;
42 }
43 
44 namespace OHOS::Ace::Platform {
45 
46 namespace {
47 // Different with mobile, we don't support multi-instances in Windows, because we only want
48 // preview UI effect, it doesn't make sense to create multi ability in one process.
49 constexpr int32_t ACE_INSTANCE_ID = 0;
50 } // namespace
51 
52 using UIEnvCallback = std::function<void(const OHOS::Ace::RefPtr<PipelineContext>& context)>;
53 using OnRouterChangeCallback = bool (*)(const std::string currentRouterPath);
54 
55 // AceContainer is the instance have its own pipeline and thread models, it can contains multiple pages.
56 class AceContainer : public Container, public JsMessageDispatcher {
57     DECLARE_ACE_TYPE(AceContainer, Container, JsMessageDispatcher);
58 
59 public:
60     static void CreateContainer(
61         int32_t instanceId, FrontendType type, bool useNewPipeline, bool useCurrentEventRunner = false);
62     static void DestroyContainer(int32_t instanceId);
63 
64     static void AddAssetPath(int32_t instanceId, const std::string& packagePath, const std::vector<std::string>& paths);
65     static void SetResourcesPathAndThemeStyle(int32_t instanceId, const std::string& systemResourcesPath,
66         const std::string& hmsResourcesPath, const std::string& appResourcesPath, const int32_t& themeId,
67         const ColorMode& colorMode);
68 
69 #ifndef ENABLE_ROSEN_BACKEND
70     static void SetView(AceViewPreview* view, double density, int32_t width, int32_t height);
71 #else
72     static void SetView(AceViewPreview* view, sptr<Rosen::Window> rsWindow, double density, int32_t width,
73         int32_t height, UIEnvCallback callback);
74 #endif
75 
76     static UIContentErrorCode RunPage(int32_t instanceId, const std::string& url, const std::string& params);
77     static RefPtr<AceContainer> GetContainerInstance(int32_t instanceId);
78     static void AddRouterChangeCallback(int32_t instanceId, const OnRouterChangeCallback& onRouterChangeCallback);
79     static void NativeOnConfigurationUpdated(int32_t instanceId);
80 
81     AceContainer(int32_t instanceId, FrontendType type, bool useNewPipeline, bool useCurrentEventRunner = false);
82     ~AceContainer() override = default;
83 
84     void Initialize() override;
85 
86     void Destroy() override;
87 
88     void DestroyView() override;
89 
GetInstanceId()90     int32_t GetInstanceId() const override
91     {
92         return instanceId_;
93     }
94 
GetHostClassName()95     std::string GetHostClassName() const override
96     {
97         return "";
98     }
99 
GetFrontend()100     RefPtr<Frontend> GetFrontend() const override
101     {
102         return frontend_;
103     }
104 
GetMessageBridge()105     RefPtr<PlatformBridge> GetMessageBridge() const
106     {
107         return messageBridge_;
108     }
109 
GetTaskExecutor()110     RefPtr<TaskExecutor> GetTaskExecutor() const override
111     {
112         return taskExecutor_;
113     }
114 
GetAssetManager()115     RefPtr<AssetManager> GetAssetManager() const override
116     {
117         return assetManager_;
118     }
119 
GetPlatformResRegister()120     RefPtr<PlatformResRegister> GetPlatformResRegister() const override
121     {
122         return resRegister_;
123     }
124 
GetPipelineContext()125     RefPtr<PipelineBase> GetPipelineContext() const override
126     {
127         return pipelineContext_;
128     }
129 
GetViewWidth()130     int32_t GetViewWidth() const override
131     {
132         return aceView_ ? aceView_->GetWidth() : 0;
133     }
134 
GetViewHeight()135     int32_t GetViewHeight() const override
136     {
137         return aceView_ ? aceView_->GetHeight() : 0;
138     }
139 
GetViewPosX()140     int32_t GetViewPosX() const override
141     {
142         return 0;
143     }
144 
GetViewPosY()145     int32_t GetViewPosY() const override
146     {
147         return 0;
148     }
149 
GetWindowId()150     uint32_t GetWindowId() const override
151     {
152         return 0;
153     }
154 
SetWindowId(uint32_t windowId)155     void SetWindowId(uint32_t windowId) override {}
156 
WindowIsShow()157     bool WindowIsShow() const override
158     {
159         return true;
160     }
161 
GetAceView()162     RefPtr<AceView> GetAceView() const override
163     {
164         return aceView_;
165     }
166 
GetView()167     void* GetView() const override
168     {
169         return static_cast<void*>(AceType::RawPtr(aceView_));
170     }
171 
SetWindowModal(WindowModal windowModal)172     void SetWindowModal(WindowModal windowModal)
173     {
174         windowModal_ = windowModal;
175     }
176 
SetColorScheme(ColorScheme colorScheme)177     void SetColorScheme(ColorScheme colorScheme)
178     {
179         colorScheme_ = colorScheme;
180     }
181 
GetType()182     FrontendType GetType() const
183     {
184         return type_;
185     }
186 
GetResourceConfiguration()187     ResourceConfiguration GetResourceConfiguration() const override
188     {
189         return resourceInfo_.GetResourceConfiguration();
190     }
191 
SetResourceConfiguration(const ResourceConfiguration & config)192     void SetResourceConfiguration(const ResourceConfiguration& config)
193     {
194         resourceInfo_.SetResourceConfiguration(config);
195     }
196 
197     void UpdateResourceConfiguration(const std::string& jsonStr) override;
198 
199     void FetchResponse(const ResponseData responseData, const int32_t callbackId) const;
200 
201     void CallCurlFunction(const RequestData requestData, const int32_t callbackId) const override;
202 
203     void Dispatch(
204         const std::string& group, std::vector<uint8_t>&& data, int32_t id, bool replyToComponent) const override;
205 
DispatchSync(const std::string & group,std::vector<uint8_t> && data,uint8_t ** resData,int64_t & position)206     void DispatchSync(
207         const std::string& group, std::vector<uint8_t>&& data, uint8_t** resData, int64_t& position) const override
208     {}
209 
210     void DispatchPluginError(int32_t callbackId, int32_t errorCode, std::string&& errorMessage) const override;
211 
212     void UpdateDeviceConfig(const DeviceConfig& deviceConfig);
213 
214     void LoadDocument(const std::string& url, const std::string& componentName);
215 
216     void RunNativeEngineLoop();
217 
218     void SetStageCardConfig(const std::string& pageProfile, const std::string& selectUrl);
219 
220     void SetPkgContextInfo(const RefPtr<StagePkgContextInfo>& PkgContextInfo);
221 
SetPageProfile(const std::string & pageProfile)222     void SetPageProfile(const std::string& pageProfile)
223     {
224         pageProfile_ = pageProfile;
225     }
226 
227     void InitializeAppConfig(const std::string& assetPath, const std::string& bundleName,
228         const std::string& moduleName, const std::string& compileMode);
229 
SetCardFrontend(WeakPtr<Frontend> frontend,int64_t cardId)230     void SetCardFrontend(WeakPtr<Frontend> frontend, int64_t cardId) override
231     {
232         std::lock_guard<std::mutex> lock(cardFrontMutex_);
233         cardFrontendMap_.try_emplace(cardId, frontend);
234     }
235 
GetCardFrontend(int64_t cardId)236     WeakPtr<Frontend> GetCardFrontend(int64_t cardId) const override
237     {
238         std::lock_guard<std::mutex> lock(cardFrontMutex_);
239         auto it = cardFrontendMap_.find(cardId);
240         if (it != cardFrontendMap_.end()) {
241             return it->second;
242         }
243         return nullptr;
244     }
245 
GetCardFrontendMap(std::unordered_map<int64_t,WeakPtr<Frontend>> & cardFrontendMap)246     void GetCardFrontendMap(std::unordered_map<int64_t, WeakPtr<Frontend>>& cardFrontendMap) const override
247     {
248         cardFrontendMap = cardFrontendMap_;
249     }
250 
SetCardPipeline(WeakPtr<PipelineBase> pipeline,int64_t cardId)251     void SetCardPipeline(WeakPtr<PipelineBase> pipeline, int64_t cardId) override
252     {
253         std::lock_guard<std::mutex> lock(cardPipelineMutex_);
254         cardPipelineMap_.try_emplace(cardId, pipeline);
255     }
256 
GetCardPipeline(int64_t cardId)257     WeakPtr<PipelineBase> GetCardPipeline(int64_t cardId) const override
258     {
259         std::lock_guard<std::mutex> lock(cardPipelineMutex_);
260         auto it = cardPipelineMap_.find(cardId);
261         if (it == cardPipelineMap_.end()) {
262             return nullptr;
263         }
264         return it->second;
265     }
266 
267     static std::string GetContentInfo(int32_t instanceId, ContentInfoType type);
SetSharedRuntime(void * runtime)268     void SetSharedRuntime(void* runtime) override
269     {
270         sharedRuntime_ = runtime;
271     }
SetInstallationFree(bool installationFree)272     void SetInstallationFree(bool installationFree)
273     {
274         installationFree_ = installationFree;
275     }
276 
SetLabelId(int32_t labelId)277     void SetLabelId(int32_t labelId)
278     {
279         labelId_ = labelId;
280     }
SetComponentModeFlag(bool isComponentMode)281     static void SetComponentModeFlag(bool isComponentMode)
282     {
283         isComponentMode_ = isComponentMode;
284     }
285 
SetContainerSdkPath(const std::string & containerSdkPath)286     void SetContainerSdkPath(const std::string& containerSdkPath)
287     {
288         containerSdkPath_ = containerSdkPath;
289     }
290 
291     void NotifyConfigurationChange(bool, const ConfigurationChange& configurationChange) override;
292 
293     // Support to execute the ets code mocked by developer
SetMockModuleList(const std::map<std::string,std::string> & mockJsonInfo)294     void SetMockModuleList(const std::map<std::string, std::string>& mockJsonInfo)
295     {
296         mockJsonInfo_ = mockJsonInfo;
297     }
298 
SetBundleName(const std::string & bundleName)299     void SetBundleName(const std::string& bundleName)
300     {
301         bundleName_ = bundleName;
302     }
303 
SetModuleName(const std::string & moduleName)304     void SetModuleName(const std::string& moduleName)
305     {
306         moduleName_ = moduleName;
307     }
308 
309 private:
310     void InitializeFrontend();
311     void InitializeCallback();
312     void SetHspBufferTrackerCallback();
313     // Support to execute the ets code mocked by developer
314     void SetMockModuleListToJsEngine();
315 
316 #ifndef ENABLE_ROSEN_BACKEND
317     void AttachView(
318         std::shared_ptr<Window> window, AceViewPreview* view, double density, int32_t width, int32_t height);
319 #else
320     void AttachView(std::shared_ptr<Window> window, AceViewPreview* view, double density, int32_t width, int32_t height,
321         UIEnvCallback callback);
322 #endif
323 
324     RefPtr<AceViewPreview> aceView_ = nullptr;
325     int32_t instanceId_;
326     RefPtr<TaskExecutor> taskExecutor_;
327     RefPtr<AssetManager> assetManager_;
328     RefPtr<PlatformResRegister> resRegister_;
329     RefPtr<PipelineBase> pipelineContext_;
330     RefPtr<Frontend> frontend_;
331     RefPtr<PlatformBridge> messageBridge_;
332     FrontendType type_ { FrontendType::JSON };
333     WindowModal windowModal_ { WindowModal::NORMAL };
334     ColorScheme colorScheme_ { ColorScheme::SCHEME_LIGHT };
335     ResourceInfo resourceInfo_;
336     static std::once_flag onceFlag_;
337     std::string pageProfile_;
338     std::unordered_map<int64_t, WeakPtr<Frontend>> cardFrontendMap_;
339     std::unordered_map<int64_t, WeakPtr<PipelineBase>> cardPipelineMap_;
340     mutable std::mutex cardFrontMutex_;
341     mutable std::mutex cardPipelineMutex_;
342     void* sharedRuntime_ = nullptr;
343     std::string bundleName_;
344     std::string moduleName_;
345     RefPtr<StagePkgContextInfo> PkgContextInfo_;
346 
347     // Support to execute the ets code mocked by developer
348     std::map<std::string, std::string> mockJsonInfo_;
349 
350     // app bar to use
351     bool installationFree_ = false;
352     int32_t labelId_;
353     static bool isComponentMode_;
354     std::string containerSdkPath_;
355 
356     ACE_DISALLOW_COPY_AND_MOVE(AceContainer);
357 };
358 
359 } // namespace OHOS::Ace::Platform
360 
361 #endif // FOUNDATION_ACE_ADAPTER_PREVIEW_ACE_CONTAINER_H
362