• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_ENGINE_V8_V8_DECLARATIVE_GROUP_JS_BRIDGE_H
17 #define FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_ENGINE_V8_V8_DECLARATIVE_GROUP_JS_BRIDGE_H
18 
19 #include <map>
20 #include <string>
21 
22 #include "third_party/v8/include/libplatform/libplatform.h"
23 #include "third_party/v8/include/v8.h"
24 
25 #include "base/memory/ace_type.h"
26 #include "base/utils/singleton.h"
27 #include "frameworks/bridge/codec/standard_function_codec.h"
28 #include "frameworks/bridge/js_frontend/engine/common/group_js_bridge.h"
29 #include "native_engine/native_engine.h"
30 
31 namespace OHOS::Ace::Framework {
32 
33 struct PromiseCallback final {
34     v8::Persistent<v8::Value, v8::CopyablePersistentTraits<v8::Value>> resolveCallback;
35     v8::Persistent<v8::Value, v8::CopyablePersistentTraits<v8::Value>> rejectCallback;
36 };
37 
38 using EventCallbackMap = std::map<int32_t, v8::Persistent<v8::Value, v8::CopyablePersistentTraits<v8::Value>>>;
39 using ModuleCallbackMap = std::map<int32_t, PromiseCallback>;
40 using RequestIdCallbackIdMap = std::map<int32_t, int32_t>;
41 using CallbackIdIsolateMap = std::map<int32_t, v8::Isolate*>;
42 using IsolateNativeEngineMap = std::map<v8::Isolate*, NativeEngine*>;
43 
44 enum class ParseJsDataResult {
45     PARSE_JS_SUCCESS = 0,
46     PARSE_JS_ERR_UNSUPPORTED_TYPE = 101,
47     PARSE_JS_ERR_TOO_MANY_PARAM = 102,
48 };
49 
50 class V8DeclarativeGroupJsBridge : public GroupJsBridge {
51     DECLARE_ACE_TYPE(V8DeclarativeGroupJsBridge, GroupJsBridge)
52 
53 public:
54     int32_t InitializeGroupJsBridge(v8::Local<v8::Context> context);
55 
56     void TriggerModuleJsCallback(int32_t callbackId, int32_t code, std::vector<uint8_t>&& data) override;
57 
58     void TriggerModulePluginGetErrorCallback(
59         int32_t callbackId, int32_t errorCode, std::string&& errorMessage) override;
60 
61     void TriggerEventJsCallback(int32_t callbackId, int32_t code, std::vector<uint8_t>&& data) override;
62 
63     void LoadPluginJsCode(std::string&& jsCode) override;
64 
65     void LoadPluginJsByteCode(std::vector<uint8_t>&& jsCode, std::vector<int32_t>&& jsCodeLen) override;
66 
Destroy()67     void Destroy() override {};
68 
69     void Destroy(v8::Isolate* isolate, bool isWorker = false);
70 
71     // load the js source code work on v8 engine
72     int32_t CallEvalBuf(v8::Isolate* isolate, v8::Local<v8::String> src);
73 
GetJsCode()74     const std::string& GetJsCode() const
75     {
76         return jsCode_;
77     }
78 
79     static void NativeAsyncExecuteCallback(NativeEngine* engine, void* data);
80     static void NativeAsyncCompleteCallback(NativeEngine* engine, int status, void* data);
81 
82     void AddIsolateNativeEngineRelation(v8::Isolate* isolate, NativeEngine* nativeEngine);
83 
84     bool ForwardToWorker(int32_t callbackId) override;
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(v8::Isolate* isolate);
94 
95     bool SetModuleGroupCallbackFuncs(const v8::FunctionCallbackInfo<v8::Value>& args, int32_t resolveCallbackIndex,
96         int32_t rejectCallbackIndex, int32_t callbackId);
97     bool SetEventGroupCallBackFuncs(
98         v8::Isolate* isolate, v8::Local<v8::Value> localEventCallbackFunc, int32_t callbackId, int32_t requestId);
99     void RemoveEventGroupCallBackFuncs(int32_t callbackId);
100     void AddRequestIdCallbackIdRelation(int32_t callbackId, int32_t requestId);
101     void RemoveRequestIdCallbackIdRelation(int32_t requestId, bool removeEventCallback);
102     void AddCallbackIdIsolateRelation(int32_t callbackId, v8::Isolate* isolate);
103 
104     void CallModuleJsCallback(int32_t callbackId, int32_t code, v8::Local<v8::Value> callBackResult,
105         v8::Isolate* isolate);
106     void CallEventJsCallback(int32_t callbackId, std::vector<uint8_t>&& data);
107 
108     ParseJsDataResult ParseJsPara(const v8::FunctionCallbackInfo<v8::Value>& args, int32_t index, int32_t requestId,
109         std::vector<CodecData>& arguments);
110 
111     // process when parse data from js engine failed
112     static void ProcessParseJsError(ParseJsDataResult errorType, v8::Isolate* isolate, int32_t callbackId);
113 
114     static std::string SerializationObjectToString(v8::Local<v8::Context> context, v8::Local<v8::Value> val);
115 
116     // ProcessJsRequest is mapped to the JS function[SendGroupMessage]
117     // contains three parameters: groupName, message, callbackfunction
118     static void ProcessJsRequest(const v8::FunctionCallbackInfo<v8::Value>& args);
119 
120     // ProcessJsRequestSync is mapped to the JS function[sendGroupMessageSync]
121     // contains three parameters: groupName, message, params
122     static void ProcessJsRequestSync(const v8::FunctionCallbackInfo<v8::Value>& args);
123 
124     void TriggerModuleJsCallback(int32_t callbackId, int32_t code, std::string result, v8::Isolate* isolate);
125 
126     void GetCallbackId(v8::Isolate* isolate, std::set<int32_t>& callbackIdSet);
127     void DestroyModuleCallbackMap(v8::Isolate* isolate);
128     void DestroyCallbackIdIsolateMap(v8::Isolate* isolate);
129     void DestroyIsolateNativeEngineMap(v8::Isolate* isolate);
130 
131     EventCallbackMap eventCallBackFuncs_;
132     ModuleCallbackMap moduleCallBackFuncs_;
133     RequestIdCallbackIdMap requestIdCallbackIdMap_;
134     CallbackIdIsolateMap callbackIdIsolateMap_;
135     IsolateNativeEngineMap isolateNativeEngineMap_;
136     std::atomic_int pendingCallbackId_ = 1;
137 
138     v8::Isolate* isolate_ = nullptr;
139     v8::Persistent<v8::Context> context_;
140     std::string jsCode_;
141     mutable std::mutex moduleCallbackMapMutex_;
142     mutable std::mutex requestIdCallbackIdMapMutex_;
143     mutable std::mutex callbackIdIsolateMapMutex_;
144     mutable std::mutex isolateNativeEngineMapMutex_;
145 };
146 
147 struct JsCallbackData final {
JsCallbackDatafinal148     explicit JsCallbackData(int32_t callbackId, int32_t code, std::string result,
149         V8DeclarativeGroupJsBridge* groupJsBridge, v8::Isolate* isolate)
150         : callbackId(callbackId), code(code), result(result), groupJsBridge(groupJsBridge), isolate(isolate) {}
151     int32_t callbackId = -1;
152     int32_t code = -1;
153     std::string result;
154     V8DeclarativeGroupJsBridge* groupJsBridge = nullptr;
155     v8::Isolate* isolate = nullptr;
156 };
157 
158 } // namespace OHOS::Ace::Framework
159 
160 #endif // FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_ENGINE_V8_V8_DECLARATIVE_GROUP_JS_BRIDGE_H
161