1 /*
2  * Copyright (c) 2021-2022 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_FRAMEWORKS_CORE_COMMON_FRONTEND_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMMON_FRONTEND_H
18 
19 #include <string>
20 #include <utility>
21 
22 #include "base/memory/ace_type.h"
23 #include "base/utils/macros.h"
24 #include "base/utils/resource_configuration.h"
25 #include "bridge/common/utils/source_map.h"
26 #include "core/accessibility/accessibility_manager.h"
27 #include "core/common/ace_page.h"
28 #include "core/common/js_message_dispatcher.h"
29 #include "core/common/router_recover_record.h"
30 #include "core/event/ace_event_handler.h"
31 #include "core/pipeline/pipeline_base.h"
32 #include "interfaces/inner_api/ace/constants.h"
33 
34 using FrontendDialogCallback = std::function<void(const std::string& event, const std::string& param)>;
35 
36 typedef struct napi_value__* napi_value;
37 
38 namespace OHOS::Ace {
39 
40 enum class ContentInfoType;
41 
42 #ifndef WEARABLE_PRODUCT
43 constexpr int32_t DEFAULT_DESIGN_WIDTH = 720;
44 #else
45 constexpr int32_t DEFAULT_DESIGN_WIDTH = 454;
46 #endif
47 
48 // Window config of frontend.
49 struct WindowConfig {
50     // NOT runtime real design width, this is config value set by user.
51     // Runtime design width should be considered together with autoDesignWidth.
52     int32_t designWidth = DEFAULT_DESIGN_WIDTH;
53     bool autoDesignWidth = false;
54     bool boxWrap = false;
55     double designWidthScale = 0.0;
56 
GetDesignWidthScaleWindowConfig57     double GetDesignWidthScale(const double viewWidth)
58     {
59         if (NearEqual(designWidthScale, 0.0)) {
60             if (designWidth <= 0) {
61                 LOGI("designWidth <= 0");
62                 designWidth = DEFAULT_DESIGN_WIDTH;
63             }
64             return viewWidth / designWidth;
65         }
66         return designWidthScale;
67     }
68 
UpdateDesignWidthScaleWindowConfig69     void UpdateDesignWidthScale(const double viewWidth)
70     {
71         if (designWidth <= 0) {
72             LOGI("designWidth <= 0");
73             designWidth = DEFAULT_DESIGN_WIDTH;
74         }
75         designWidthScale = viewWidth / designWidth;
76     }
77 };
78 
79 enum class FrontendType { JSON, JS, JS_CARD, DECLARATIVE_JS, JS_PLUGIN, ETS_CARD, DECLARATIVE_CJ };
80 struct PageTarget;
81 
82 class ACE_FORCE_EXPORT Frontend : public AceType {
83     DECLARE_ACE_TYPE(Frontend, AceType);
84 
85 public:
86     Frontend() = default;
87     ~Frontend() override;
88 
89     enum State : uint8_t { ON_CREATE = 0, ON_DESTROY, ON_SHOW, ON_HIDE, ON_ACTIVE, ON_INACTIVE, UNDEFINE };
90     static std::string stateToString(int state);
91 
92     static RefPtr<Frontend> Create();
93     static RefPtr<Frontend> CreateDefault();
94 
95     virtual bool Initialize(FrontendType type, const RefPtr<TaskExecutor>& taskExecutor) = 0;
96 
97     virtual void Destroy() = 0;
98 
99     virtual void AttachPipelineContext(const RefPtr<PipelineBase>& context) = 0;
100 
101     virtual void SetAssetManager(const RefPtr<AssetManager>& assetManager) = 0;
102 
103     virtual void AddPage(const RefPtr<AcePage>& page) = 0;
104 
105     virtual RefPtr<AcePage> GetPage(int32_t pageId) const = 0;
106 
107     // Get the currently running JS page information in NG structure.
GetCurrentPageUrl()108     virtual std::string GetCurrentPageUrl() const
109     {
110         return "";
111     }
112 
113     // Get the currently running JS page information in NG structure.
GetCurrentPageSourceMap()114     virtual RefPtr<Framework::RevSourceMap> GetCurrentPageSourceMap() const
115     {
116         return nullptr;
117     }
118 
119     // Get the currently running JS page information in NG structure.
GetFaAppSourceMap()120     virtual RefPtr<Framework::RevSourceMap> GetFaAppSourceMap() const
121     {
122         return nullptr;
123     }
124 
125     // Get the stage mode sourceMap.
GetStageSourceMap(std::unordered_map<std::string,RefPtr<Framework::RevSourceMap>> & sourceMap)126     virtual void GetStageSourceMap(std::unordered_map<std::string, RefPtr<Framework::RevSourceMap>>& sourceMap) const {}
127 
RunPage(const std::string & content,const std::string & params)128     virtual UIContentErrorCode RunPage(const std::string& content, const std::string& params)
129     {
130         return UIContentErrorCode::NO_ERRORS;
131     }
RunPage(const std::shared_ptr<std::vector<uint8_t>> & content,const std::string & params)132     virtual UIContentErrorCode RunPage(const std::shared_ptr<std::vector<uint8_t>>& content, const std::string& params)
133     {
134         return UIContentErrorCode::NO_ERRORS;
135     }
RunDynamicPage(const std::string & content,const std::string & params,const std::string & entryPoint)136     virtual UIContentErrorCode RunDynamicPage(
137         const std::string& content, const std::string& params, const std::string& entryPoint)
138     {
139         return UIContentErrorCode::NO_ERRORS;
140     }
141 
RunPageByNamedRouter(const std::string & name,const std::string & params)142     virtual UIContentErrorCode RunPageByNamedRouter(const std::string& name, const std::string& params)
143     {
144         return UIContentErrorCode::NO_ERRORS;
145     }
146 
147     virtual void ReplacePage(const std::string& url, const std::string& params) = 0;
148 
149     virtual void PushPage(const std::string& url, const std::string& params) = 0;
150 
151     // Gets front-end event handler to handle ace event.
152     virtual RefPtr<AceEventHandler> GetEventHandler() = 0;
153 
154     // Get window config of front end, which is used to calculate the pixel ratio of the real device.
155     virtual WindowConfig& GetWindowConfig() = 0;
156 
GetLock()157     std::unique_lock<std::recursive_mutex> GetLock() const
158     {
159         return std::unique_lock<std::recursive_mutex>(mutex_);
160     }
161 
GetType()162     FrontendType GetType() const
163     {
164         return type_;
165     }
166 
GetTaskExecutor()167     RefPtr<TaskExecutor> GetTaskExecutor() const
168     {
169         return taskExecutor_;
170     }
171 
172     // inform the frontend that onCreate or onDestroy
173     virtual void UpdateState(State) = 0;
174 
175     // dump frontend info
176     virtual void DumpFrontend() const = 0;
177 
178     virtual std::string GetPagePath() const = 0;
179 
180     // send the message by js callback
181     virtual void SendCallbackMessage(const std::string& callbackId, const std::string& data) const = 0;
182 
183     // set the message transfer to js instance
184     virtual void SetJsMessageDispatcher(const RefPtr<JsMessageDispatcher>& transfer) const = 0;
185 
186     // transfer data back from platform side to component side
187     virtual void TransferComponentResponseData(int32_t callbackId, int32_t code, std::vector<uint8_t>&& data) const = 0;
188 
189     // transfer data back from platform side to js side
190     virtual void TransferJsResponseData(int32_t callbackId, int32_t code, std::vector<uint8_t>&& data) const = 0;
191 
192     // transfer error message get in plugin from platform side to js side
193     virtual void TransferJsPluginGetError(int32_t callbackId, int32_t errorCode, std::string&& errorMessage) const = 0;
194 
195     // transfer event data from platform side to js side
196     virtual void TransferJsEventData(int32_t callbackId, int32_t code, std::vector<uint8_t>&& data) const = 0;
197 
198     // get system plugin used in application
GetPluginsUsed(std::string & data)199     virtual void GetPluginsUsed(std::string& data) {}
200 
201     // get js code from plugin and load in js engine
202     virtual void LoadPluginJsCode(std::string&& jsCode) const = 0;
203 
204     virtual void LoadPluginJsByteCode(std::vector<uint8_t>&& jsCode, std::vector<int32_t>&& jsCodeLen) const = 0;
205 
206     // when this is foreground frontend
207     virtual bool IsForeground() = 0;
208 
209     // get accessibility manager handler.
210     virtual RefPtr<AccessibilityManager> GetAccessibilityManager() const = 0;
211 
212     // when back pressed
213     virtual bool OnBackPressed() = 0;
214 
215     // when interface show up
216     virtual void OnShow() = 0;
217 
218     // when interface hide
219     virtual void OnHide() = 0;
220 
221     // when configuration update
OnConfigurationUpdated(const std::string & data)222     virtual void OnConfigurationUpdated(const std::string& data) {}
223 
224     virtual void OnSaveAbilityState(std::string& data) = 0;
225 
226     virtual void OnMemoryLevel(int32_t level) = 0;
227 
228     virtual void OnRestoreAbilityState(const std::string& data) = 0;
229 
230     // when front on active
231     virtual void OnActive() = 0;
232 
233     // when front on inactive
234     virtual void OnInactive() = 0;
235 
236     // when front on asks a user whether to start the migration
237     virtual bool OnStartContinuation() = 0;
238 
239     // when front on a local ability migration is complete
240     virtual void OnCompleteContinuation(int32_t code) = 0;
241 
242     // interface to save the user data
243     virtual void OnSaveData(std::string& data) = 0;
244 
245     // interface to restores the user data on the remote device
246     virtual bool OnRestoreData(const std::string& data) = 0;
247 
248     virtual void OnRemoteTerminated() = 0;
249 
250     // start the ability when it's running
251     virtual void OnNewRequest(const std::string& data) = 0;
252 
253     virtual void OnNewWant(const std::string& data) = 0;
254 
255     // call router back
256     virtual void CallRouterBack() = 0;
257 
258     virtual void OnSurfaceChanged(int32_t width, int32_t height) = 0;
259 
260     virtual void OnLayoutCompleted(const std::string& componentId) = 0;
261     virtual void OnDrawCompleted(const std::string& componentId) = 0;
262 
TriggerGarbageCollection()263     virtual void TriggerGarbageCollection() {}
264 
DumpHeapSnapshot(bool isPrivate)265     virtual void DumpHeapSnapshot(bool isPrivate) {}
266 
DestroyHeapProfiler()267     virtual void DestroyHeapProfiler() {}
268 
ForceFullGC()269     virtual void ForceFullGC() {}
270 
NotifyUIIdle()271     virtual void NotifyUIIdle() {}
272 
RebuildAllPages()273     virtual void RebuildAllPages() {}
274 
SetColorMode(ColorMode colorMode)275     virtual void SetColorMode(ColorMode colorMode) {}
276 
277     // navigator component call router
NavigatePage(uint8_t type,const PageTarget & target,const std::string & params)278     virtual void NavigatePage(uint8_t type, const PageTarget& target, const std::string& params) {}
279 
280     // restore
RestoreRouterStack(const std::string & contentInfo,ContentInfoType type)281     virtual std::pair<RouterRecoverRecord, UIContentErrorCode> RestoreRouterStack(
282         const std::string& contentInfo, ContentInfoType type)
283     {
284         return std::make_pair(RouterRecoverRecord(), UIContentErrorCode::NO_ERRORS);
285     }
286 
GetContentInfo(ContentInfoType type)287     virtual std::string GetContentInfo(ContentInfoType type) const
288     {
289         return "";
290     }
291 
292     // only declarative frontend need to support
GetRouterSize()293     virtual int32_t GetRouterSize() const
294     {
295         return -1;
296     }
297 
NotifyAppStorage(const std::string & key,const std::string & value)298     virtual void NotifyAppStorage(const std::string& key, const std::string& value) {}
299 
GetContextValue()300     virtual napi_value GetContextValue()
301     {
302         napi_value value = nullptr;
303         return value;
304     }
305 
GetFrameNodeValueByNodeId(int32_t nodeId)306     virtual napi_value GetFrameNodeValueByNodeId(int32_t nodeId)
307     {
308         return nullptr;
309     }
310 #ifdef PREVIEW
RunNativeEngineLoop()311     virtual void RunNativeEngineLoop() {}
312 #endif
313 
314     // Disallow pop last page
DisallowPopLastPage()315     void DisallowPopLastPage()
316     {
317         disallowPopLastPage_ = true;
318     }
319 
SetDialogCallback(FrontendDialogCallback callback)320     virtual void SetDialogCallback(FrontendDialogCallback callback)
321     {
322         dialogCallback_ = std::move(callback);
323     }
324 
FlushReload()325     virtual void FlushReload() {}
326     // flush frontend for HotReload feature in NG
HotReload()327     virtual void HotReload() {}
328 
GetState()329     State GetState() const
330     {
331         return state_;
332     }
333 
SetErrorEventHandler(std::function<void (const std::string &,const std::string &)> && errorCallback)334     virtual void SetErrorEventHandler(std::function<void(const std::string&, const std::string&)>&& errorCallback) {}
335 
336 protected:
337     virtual bool MaybeRelease() override;
338     FrontendType type_ = FrontendType::JS;
339     RefPtr<TaskExecutor> taskExecutor_;
340     bool disallowPopLastPage_ = false;
341     FrontendDialogCallback dialogCallback_ = nullptr;
342     State state_ = State::UNDEFINE;
343     mutable std::recursive_mutex mutex_;
344     mutable std::mutex destructMutex_;
345 };
346 
347 } // namespace OHOS::Ace
348 
349 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMMON_FRONTEND_H
350