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 #ifndef FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_ENGINE_JSI_JSI_GROUP_JS_BRIDGE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_ENGINE_JSI_JSI_GROUP_JS_BRIDGE_H
18 
19 #include <map>
20 #include <string>
21 
22 #if defined(PREVIEW)
23 #include "adapter/preview/osal/request_data.h"
24 #include "adapter/preview/osal/response_data.h"
25 #include "frameworks/base/utils/linear_map.h"
26 #endif
27 #include "base/memory/ace_type.h"
28 #include "base/utils/singleton.h"
29 #include "frameworks/bridge/codec/standard_function_codec.h"
30 #include "frameworks/bridge/js_frontend/engine/common/group_js_bridge.h"
31 #include "frameworks/bridge/js_frontend/engine/jsi/js_runtime.h"
32 #include "frameworks/bridge/js_frontend/engine/jsi/js_value.h"
33 
34 namespace OHOS::Ace::Framework {
35 using std::shared_ptr;
36 
37 struct PromiseCallback final {
38     shared_ptr<JsValue> resolveCallback;
39     shared_ptr<JsValue> rejectCallback;
40 };
41 
42 using EventCallbackMap = std::map<int32_t, shared_ptr<JsValue>>;
43 using ModuleCallbackMap = std::map<int32_t, PromiseCallback>;
44 using RequestIdCallbackIdMap = std::map<int32_t, int32_t>;
45 
46 enum class ParseJsDataResult {
47     PARSE_JS_SUCCESS = 0,
48     PARSE_JS_ERR_UNSUPPORTED_TYPE = 101,
49     PARSE_JS_ERR_TOO_MANY_PARAM = 102,
50 };
51 
52 class JsiGroupJsBridge : public GroupJsBridge {
53     DECLARE_ACE_TYPE(JsiGroupJsBridge, GroupJsBridge)
54 
55     enum GroupType {
56         MODULE_GROUP = 0,
57         EVENT_GROUP = 1,
58     };
59 
60 public:
61     JsiGroupJsBridge() = default;
62     ~JsiGroupJsBridge() override = default;
63 
64     int32_t InitializeGroupJsBridge(const shared_ptr<JsRuntime>& runtime);
65 
66     void TriggerModuleJsCallback(int32_t callbackId, int32_t code, std::vector<uint8_t>&& messageData) override;
67 
68     void TriggerModulePluginGetErrorCallback(
69         int32_t callbackId, int32_t errorCode, std::string&& errorMessage) override;
70 
71     void TriggerEventJsCallback(int32_t callbackId, int32_t code, std::vector<uint8_t>&& eventData) override;
72 
73     void LoadPluginJsCode(std::string&& jsCode) override;
74 
75     void LoadPluginJsByteCode(std::vector<uint8_t>&& jsCode, std::vector<int32_t>&& jsCodeLen) override;
76 
77     void Destroy() override;
78 
79 #if defined(PREVIEW)
80     void TriggerModuleJsCallbackPreview(
81         int32_t callbackId, int32_t code, OHOS::Ace::ResponseData responseData) override;
82     void GetRequestData(const shared_ptr<JsValue>& valObject, OHOS::Ace::RequestData& requestData);
83     ParseJsDataResult ParseRequestData(
84         int32_t argc, const std::vector<shared_ptr<JsValue>>& argv,
85         OHOS::Ace::RequestData& requestData, int32_t requestId);
86 #endif
87 
88 private:
GetPendingCallbackIdAndIncrement()89     int32_t GetPendingCallbackIdAndIncrement()
90     {
91         return pendingCallbackId_++;
92     }
93 
94     // Js bridge functions are used for the mapping between the Js and CPP functions.
95     int32_t LoadJsBridgeFunction();
96 
97     bool SetModuleGroupCallbackFuncs(const std::vector<shared_ptr<JsValue>>& argv, int32_t resolveCallbackIndex,
98         int32_t rejectCallbackIndex, int32_t callbackId);
99     bool SetEventGroupCallBackFuncs(const shared_ptr<JsRuntime>& runtime,
100         const shared_ptr<JsValue>& localEventCallbackFunc, int32_t callbackId, int32_t requestId);
101 
102     void RemoveEventGroupCallBackFuncs(int32_t callbackId);
103     void AddRequestIdCallbackIdRelation(int32_t callbackId, int32_t requestId);
104     void RemoveRequestIdCallbackIdRelation(int32_t requestId, bool removeEventCallback);
105 
106     void CallModuleJsCallback(int32_t callbackId, int32_t code, const shared_ptr<JsValue>& callBackResult);
107     void CallEventJsCallback(int32_t callbackId, std::vector<uint8_t>&& data);
108 
109     ParseJsDataResult ParseJsPara(const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv,
110         int32_t beginIndex, int32_t requestId, std::vector<CodecData>& arguments);
111 
112     // process when parse data from js engine failed
113     static void ProcessParseJsError(
114         ParseJsDataResult errorType, const shared_ptr<JsRuntime>& runtime, int32_t callbackId);
115 
116     static std::string SerializationObjectToString(
117         const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& val);
118 
119     // JsSendGroupMessage is mapped to the Js function[SendGroupMessage]
120     // contains three parameters: groupName, message, callback function
121     static shared_ptr<JsValue> ProcessJsRequest(const shared_ptr<JsRuntime>& runtime,
122         const shared_ptr<JsValue>& thisObj, const std::vector<shared_ptr<JsValue>>& argv, int32_t argc);
123 
124     // JsSendGroupMessage is mapped to the Js function[SendGroupMessageSync]
125     // contains three parameters: groupName, message, params
126     static shared_ptr<JsValue> ProcessJsRequestSync(const shared_ptr<JsRuntime>& runtime,
127         const shared_ptr<JsValue>& thisObj, const std::vector<shared_ptr<JsValue>>& argv, int32_t argc);
128 
129     EventCallbackMap eventCallBackFuncs_;
130     ModuleCallbackMap moduleCallBackFuncs_;
131     RequestIdCallbackIdMap requestIdCallbackIdMap_;
132     std::atomic_int pendingCallbackId_;
133 
134     shared_ptr<JsRuntime> runtime_;
135 #if defined(PREVIEW)
136     static const LinearMapNode<void (*)(const char*, RequestData&)> fetchRequestDataMap1[];
137     static const LinearMapNode<void (*)(shared_ptr<JsRuntime>,
138         const shared_ptr<JsValue>&, RequestData&)> fetchRequestDataMap2[];
139 #endif
140 };
141 
142 } // namespace OHOS::Ace::Framework
143 
144 #endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_ENGINE_JSI_JSI_GROUP_JS_BRIDGE_H
145