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 JsiDeclarativeGroupJsBridge : public GroupJsBridge {
53     DECLARE_ACE_TYPE(JsiDeclarativeGroupJsBridge, GroupJsBridge)
54 
55     enum GroupType {
56         MODULE_GROUP = 0,
57         EVENT_GROUP = 1,
58     };
59 
60 public:
61     JsiDeclarativeGroupJsBridge() = default;
62     ~JsiDeclarativeGroupJsBridge() 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(int32_t callbackId, int32_t code, ResponseData responseData) override;
81     void GetRequestData(const shared_ptr<JsValue>& valObject, OHOS::Ace::RequestData& requestData);
82     ParseJsDataResult ParseRequestData(
83     int32_t argc, const std::vector<shared_ptr<JsValue>>& argv, OHOS::Ace::RequestData& requestData, int32_t requestId);
84 #endif
85 
86 private:
GetPendingCallbackIdAndIncrement()87     int32_t GetPendingCallbackIdAndIncrement()
88     {
89         return pendingCallbackId_++;
90     }
91 
92     // Js bridge functions are used for the mapping between the Js and CPP functions.
93     int32_t LoadJsBridgeFunction();
94 
95     bool SetModuleGroupCallbackFuncs(const std::vector<shared_ptr<JsValue>>& argv, int32_t resolveCallbackIndex,
96         int32_t rejectCallbackIndex, int32_t callbackId);
97     bool SetEventGroupCallBackFuncs(const shared_ptr<JsRuntime>& runtime,
98         const shared_ptr<JsValue>& localEventCallbackFunc, int32_t callbackId, int32_t requestId);
99 
100     void RemoveEventGroupCallBackFuncs(int32_t callbackId);
101     void AddRequestIdCallbackIdRelation(int32_t callbackId, int32_t requestId);
102     void RemoveRequestIdCallbackIdRelation(int32_t requestId, bool removeEventCallback);
103 
104     void CallModuleJsCallback(int32_t callbackId, int32_t code, const shared_ptr<JsValue>& callBackResult);
105     void CallEventJsCallback(int32_t callbackId, std::vector<uint8_t>&& data);
106 
107     ParseJsDataResult ParseJsPara(const shared_ptr<JsRuntime>& runtime, const std::vector<shared_ptr<JsValue>>& argv,
108         int32_t beginIndex, int32_t requestId, std::vector<CodecData>& arguments);
109 
110     // process when parse data from js engine failed
111     static void ProcessParseJsError(
112         ParseJsDataResult errorType, const shared_ptr<JsRuntime>& runtime, int32_t callbackId);
113 
114     // JsSendGroupMessage is mapped to the Js function[SendGroupMessage]
115     // contains three parameters: groupName, message, callback function
116     static shared_ptr<JsValue> ProcessJsRequest(const shared_ptr<JsRuntime>& runtime,
117         const shared_ptr<JsValue>& thisObj, const std::vector<shared_ptr<JsValue>>& argv, int32_t argc);
118 
119     // JsSendGroupMessage is mapped to the Js function[SendGroupMessageSync]
120     // contains three parameters: groupName, message, params
121     static shared_ptr<JsValue> ProcessJsRequestSync(const shared_ptr<JsRuntime>& runtime,
122         const shared_ptr<JsValue>& thisObj, const std::vector<shared_ptr<JsValue>>& argv, int32_t argc);
123 
124     static std::string SerializationObjectToString(
125         const shared_ptr<JsRuntime>& runtime, const shared_ptr<JsValue>& val);
126 
127     EventCallbackMap eventCallBackFuncs_;
128     ModuleCallbackMap moduleCallBackFuncs_;
129     RequestIdCallbackIdMap requestIdCallbackIdMap_;
130     std::atomic_int pendingCallbackId_;
131 
132     shared_ptr<JsRuntime> runtime_;
133 #if defined(PREVIEW)
134     static const LinearMapNode<void (*)(const char*, RequestData&)> fetchRequestDataMap1[];
135     static const LinearMapNode<void (*)(shared_ptr<JsRuntime>,
136         const shared_ptr<JsValue>&, RequestData&)> fetchRequestDataMap2[];
137 #endif
138 };
139 
140 } // namespace OHOS::Ace::Framework
141 
142 #endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_ENGINE_JSI_JSI_GROUP_JS_BRIDGE_H
143