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 FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_JS_XCOMPONENT_H
17 #define FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_JS_XCOMPONENT_H
18 
19 #include "core/common/container.h"
20 #include "frameworks/bridge/declarative_frontend/engine/functions/js_function.h"
21 #include "frameworks/bridge/declarative_frontend/engine/js_ref_ptr.h"
22 #include "frameworks/bridge/declarative_frontend/jsview/js_container_base.h"
23 #include "frameworks/bridge/declarative_frontend/jsview/js_utils.h"
24 #include "frameworks/bridge/declarative_frontend/jsview/js_xcomponent_controller.h"
25 
26 namespace OHOS::Ace::Framework {
27 
28 struct XComponentParams {
29     int32_t elmtId = -1;
30     int32_t xcomponentType = 0;
31     int32_t renderType = 0;
32     int32_t width = 0;
33     int32_t height = 0;
34     std::string xcomponentId;
35     std::string surfaceId;
36     std::string libraryName;
37     JSXComponentController* controller = nullptr;
38 };
39 
40 class XComponentClient {
41 public:
42     using GetJSValCallback = std::function<bool(JSRef<JSVal>& param)>;
43     using DeleteCallback = std::function<void()>;
44     XComponentClient& operator=(const XComponentClient&) = delete;
45     XComponentClient(const XComponentClient&) = delete;
46     ~XComponentClient() = default;
47 
GetInstance()48     static XComponentClient& GetInstance()
49     {
50         static XComponentClient instance;
51         return instance;
52     }
53 
GetControllerFromJSXComponentControllersMap(const std::string & xcomponentId)54     RefPtr<JSXComponentController> GetControllerFromJSXComponentControllersMap(const std::string& xcomponentId)
55     {
56         auto idWithContainerId = xcomponentId + std::to_string(Container::CurrentId());
57         auto iter = jsXComponentControllersMap_.find(idWithContainerId);
58         if (iter == jsXComponentControllersMap_.end()) {
59             return nullptr;
60         }
61         return iter->second;
62     }
63 
GetNativeXComponentFromXcomponentsMap(const std::string & xcomponentId)64     std::pair<RefPtr<OHOS::Ace::NativeXComponentImpl>, OH_NativeXComponent*> GetNativeXComponentFromXcomponentsMap(
65         const std::string& xcomponentId)
66     {
67         auto idWithContainerId = xcomponentId + std::to_string(Container::CurrentId());
68         auto it = nativeXcomponentsMap_.find(idWithContainerId);
69         if (it != nativeXcomponentsMap_.end()) {
70             return it->second;
71         } else {
72             auto nativeXComponentImpl = AceType::MakeRefPtr<NativeXComponentImpl>();
73             auto nativeXComponent = new OH_NativeXComponent(AceType::RawPtr(nativeXComponentImpl));
74             nativeXcomponentsMap_[idWithContainerId] = std::make_pair(nativeXComponentImpl, nativeXComponent);
75             return nativeXcomponentsMap_[idWithContainerId];
76         }
77     }
78 
AddControllerToJSXComponentControllersMap(const std::string & xcomponentId,JSXComponentController * & controller)79     void AddControllerToJSXComponentControllersMap(const std::string& xcomponentId, JSXComponentController*& controller)
80     {
81         auto idWithContainerId = xcomponentId + std::to_string(Container::CurrentId());
82         jsXComponentControllersMap_[idWithContainerId] = controller;
83     }
84 
DeleteControllerFromJSXComponentControllersMap(const std::string & xcomponentId)85     void DeleteControllerFromJSXComponentControllersMap(const std::string& xcomponentId)
86     {
87         auto idWithContainerId = xcomponentId + std::to_string(Container::CurrentId());
88         jsXComponentControllersMap_.erase(idWithContainerId);
89     }
90 
DeleteFromNativeXcomponentsMapById(const std::string & xcomponentId)91     void DeleteFromNativeXcomponentsMapById(const std::string& xcomponentId)
92     {
93         auto idWithContainerId = xcomponentId + std::to_string(Container::CurrentId());
94         auto it = nativeXcomponentsMap_.find(idWithContainerId);
95         if (it == nativeXcomponentsMap_.end()) {
96             return;
97         }
98         if (it->second.second) {
99             delete it->second.second;
100             it->second.second = nullptr;
101         }
102         nativeXcomponentsMap_.erase(it);
103     }
104 
AddJsValToJsValMap(const std::string & xcomponentId,const JSRef<JSVal> & jsVal)105     void AddJsValToJsValMap(const std::string& xcomponentId, const JSRef<JSVal>& jsVal)
106     {
107         auto idWithContainerId = xcomponentId + std::to_string(Container::CurrentId());
108         auto result = jsValMap_.try_emplace(idWithContainerId, jsVal);
109         if (!result.second) {
110             result.first->second = jsVal;
111         }
112     }
113 
DeleteFromJsValMapById(const std::string & xcomponentId)114     void DeleteFromJsValMapById(const std::string& xcomponentId)
115     {
116         auto idWithContainerId = xcomponentId + std::to_string(Container::CurrentId());
117         auto it = jsValMap_.find(idWithContainerId);
118         if (it == jsValMap_.end()) {
119             return;
120         }
121         jsValMap_.erase(it);
122     }
123 
GetJSVal(const std::string & xcomponentId,JSRef<JSVal> & jsVal)124     bool GetJSVal(const std::string& xcomponentId, JSRef<JSVal>& jsVal)
125     {
126         auto idWithContainerId = xcomponentId + std::to_string(Container::CurrentId());
127         auto iter = jsValMap_.find(idWithContainerId);
128         if (iter != jsValMap_.end()) {
129             jsVal = iter->second;
130             jsValMap_.erase(iter);
131             return true;
132         }
133         return false;
134     }
135 
136 private:
137     XComponentClient() = default;
138     std::unordered_map<std::string, RefPtr<JSXComponentController>> jsXComponentControllersMap_;
139     std::unordered_map<std::string, std::pair<RefPtr<OHOS::Ace::NativeXComponentImpl>, OH_NativeXComponent*>>
140         nativeXcomponentsMap_;
141     std::unordered_map<std::string, JSRef<JSVal>> jsValMap_;
142 };
143 
144 class ACE_EXPORT JSXComponent : public JSContainerBase {
145 public:
146     static void JSBind(BindingTarget globalObj);
147     static void Create(const JSCallbackInfo& info);
148     static void JsOnLoad(const JSCallbackInfo& args);
149     static void JsOnDestroy(const JSCallbackInfo& args);
150     static void JsOnAppear(const JSCallbackInfo& args);
151     static void JsOnDisAppear(const JSCallbackInfo& args);
152     static void JsOnAttach(const JSCallbackInfo& args);
153     static void JsOnDetach(const JSCallbackInfo& args);
154 
155     static void JsOnTouch(const JSCallbackInfo& args);
156     static void JsOnClick(const JSCallbackInfo& args);
157     static void JsOnKeyEvent(const JSCallbackInfo& args);
158     static void JsOnMouse(const JSCallbackInfo& args);
159     static void JsOnHover(const JSCallbackInfo& args);
160     static void JsOnFocus(const JSCallbackInfo& args);
161     static void JsOnBlur(const JSCallbackInfo& args);
162 
163     static void JsBackgroundColor(const JSCallbackInfo& args);
164     static void JsBackgroundImage(const JSCallbackInfo& args);
165     static void JsBackgroundImageSize(const JSCallbackInfo& args);
166     static void JsBackgroundImagePosition(const JSCallbackInfo& args);
167     static void JsOpacity(const JSCallbackInfo& args);
168     static void JsBlur(const JSCallbackInfo& args);
169     static void JsBackdropBlur(const JSCallbackInfo& args);
170     static void JsGrayscale(const JSCallbackInfo& args);
171     static void JsBrightness(const JSCallbackInfo& args);
172     static void JsSaturate(const JSCallbackInfo& args);
173     static void JsContrast(const JSCallbackInfo& args);
174     static void JsInvert(const JSCallbackInfo& args);
175     static void JsSepia(const JSCallbackInfo& args);
176     static void JsHueRotate(const JSCallbackInfo& args);
177     static void JsColorBlend(const JSCallbackInfo& args);
178     static void JsSphericalEffect(const JSCallbackInfo& args);
179     static void JsLightUpEffect(const JSCallbackInfo& args);
180     static void JsPixelStretchEffect(const JSCallbackInfo& args);
181     static void JsLinearGradientBlur(const JSCallbackInfo& args);
182     static void JsEnableAnalyzer(bool enable);
183     static void JsRenderFit(const JSCallbackInfo& args);
184     static void JsEnableSecure(const JSCallbackInfo& args);
185 
186     // For xcomponent node
187     static void* Create(const XComponentParams& params);
188 
189     void RegisterOnCreate(const JsiExecutionContext& execCtx, const Local<JSValueRef>& func);
190     void RegisterOnDestroy(const JsiExecutionContext& execCtx, const Local<JSValueRef>& func);
SetFrameNode(RefPtr<AceType> frameNode)191     void SetFrameNode(RefPtr<AceType> frameNode)
192     {
193         frameNode_ = frameNode;
194     }
GetFrameNode()195     RefPtr<AceType> GetFrameNode() const
196     {
197         return frameNode_;
198     }
199     bool ChangeRenderType(int32_t renderType);
200 
201 private:
202     static void ParseImageAIOptions(const JSRef<JSVal>& jsValue);
203     RefPtr<AceType> frameNode_;
204 };
205 } // namespace OHOS::Ace::Framework
206 #endif // FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_JS_XCOMPONENT_H
207