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