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 OHOS_ABILITY_RUNTIME_JS_RUNTIME_UTILS_H
17 #define OHOS_ABILITY_RUNTIME_JS_RUNTIME_UTILS_H
18
19 #include <cstdint>
20 #include <memory>
21 #include <sstream>
22 #include <type_traits>
23
24 #include "native_engine/native_engine.h"
25
26 #include "js_runtime.h"
27
28 namespace OHOS {
29 namespace AbilityRuntime {
30 template<class T>
ConvertNativeValueTo(NativeValue * value)31 inline T* ConvertNativeValueTo(NativeValue* value)
32 {
33 return (value != nullptr) ? static_cast<T*>(value->GetInterface(T::INTERFACE_ID)) : nullptr;
34 }
35
36 template<typename T, size_t N>
ArraySize(T (&)[N])37 inline constexpr size_t ArraySize(T (&)[N]) noexcept
38 {
39 return N;
40 }
41
42 template<class T>
CreateJsValue(NativeEngine & engine,const T & value)43 inline NativeValue* CreateJsValue(NativeEngine& engine, const T& value)
44 {
45 using ValueType = std::remove_cv_t<std::remove_reference_t<T>>;
46 if constexpr (std::is_same_v<ValueType, bool>) {
47 return engine.CreateBoolean(value);
48 } else if constexpr (std::is_arithmetic_v<ValueType>) {
49 return engine.CreateNumber(value);
50 } else if constexpr (std::is_same_v<ValueType, std::string>) {
51 return engine.CreateString(value.c_str(), value.length());
52 } else if constexpr (std::is_enum_v<ValueType>) {
53 return engine.CreateNumber(static_cast<std::make_signed_t<ValueType>>(value));
54 } else if constexpr (std::is_same_v<ValueType, const char*>) {
55 return (value != nullptr) ? engine.CreateString(value, strlen(value)) : engine.CreateUndefined();
56 }
57 return engine.CreateUndefined();
58 }
59
60 template<class T>
ConvertFromJsValue(NativeEngine & engine,NativeValue * jsValue,T & value)61 inline bool ConvertFromJsValue(NativeEngine& engine, NativeValue* jsValue, T& value)
62 {
63 if (jsValue == nullptr) {
64 return false;
65 }
66
67 using ValueType = std::remove_cv_t<std::remove_reference_t<T>>;
68 if constexpr (std::is_same_v<ValueType, bool>) {
69 auto boolValue = ConvertNativeValueTo<NativeBoolean>(jsValue);
70 if (boolValue == nullptr) {
71 return false;
72 }
73 value = *boolValue;
74 return true;
75 } else if constexpr (std::is_arithmetic_v<ValueType>) {
76 auto numberValue = ConvertNativeValueTo<NativeNumber>(jsValue);
77 if (numberValue == nullptr) {
78 return false;
79 }
80 value = *numberValue;
81 return true;
82 } else if constexpr (std::is_same_v<ValueType, std::string>) {
83 auto stringValue = ConvertNativeValueTo<NativeString>(jsValue);
84 if (stringValue == nullptr) {
85 return false;
86 }
87 size_t len = stringValue->GetLength() + 1;
88 auto buffer = std::make_unique<char[]>(len);
89 size_t strLength = 0;
90 stringValue->GetCString(buffer.get(), len, &strLength);
91 value = buffer.get();
92 return true;
93 } else if constexpr (std::is_enum_v<ValueType>) {
94 auto numberValue = ConvertNativeValueTo<NativeNumber>(jsValue);
95 if (numberValue == nullptr) {
96 return false;
97 }
98 value = static_cast<ValueType>(static_cast<std::make_signed_t<ValueType>>(*numberValue));
99 return true;
100 }
101 }
102
103 template<class T>
CreateNativeArray(NativeEngine & engine,const std::vector<T> & data)104 NativeValue* CreateNativeArray(NativeEngine& engine, const std::vector<T>& data)
105 {
106 NativeValue* arrayValue = engine.CreateArray(data.size());
107 NativeArray* array = ConvertNativeValueTo<NativeArray>(arrayValue);
108 uint32_t index = 0;
109 for (const T& item : data) {
110 array->SetElement(index++, CreateJsValue(engine, item));
111 }
112 return arrayValue;
113 }
114
115 NativeValue* CreateJsError(NativeEngine& engine, int32_t errCode, const std::string& message = std::string());
116 void BindNativeFunction(NativeEngine& engine, NativeObject& object, const char* name,
117 const char* moduleName, NativeCallback func);
118 void BindNativeProperty(NativeObject& object, const char* name, NativeCallback getter);
119 void* GetNativePointerFromCallbackInfo(const NativeEngine* engine, NativeCallbackInfo* info, const char* name);
120
121 void SetNamedNativePointer(
122 NativeEngine& engine, NativeObject& object, const char* name, void* ptr, NativeFinalize func);
123 void* GetNamedNativePointer(NativeEngine& engine, NativeObject& object, const char* name);
124
125 template<class T>
126 T* CheckParamsAndGetThis(NativeEngine* engine, NativeCallbackInfo* info, const char* name = nullptr)
127 {
128 return static_cast<T*>(GetNativePointerFromCallbackInfo(engine, info, name));
129 }
130
131 class HandleScope final {
132 public:
133 explicit HandleScope(JsRuntime& jsRuntime);
134 explicit HandleScope(NativeEngine& engine);
135 ~HandleScope();
136
137 HandleScope(const HandleScope&) = delete;
138 HandleScope(HandleScope&&) = delete;
139 HandleScope& operator=(const HandleScope&) = delete;
140 HandleScope& operator=(HandleScope&&) = delete;
141
142 private:
143 NativeScopeManager* scopeManager_ = nullptr;
144 NativeScope* nativeScope_ = nullptr;
145 };
146
147 class HandleEscape final {
148 public:
149 explicit HandleEscape(JsRuntime& jsRuntime);
150 explicit HandleEscape(NativeEngine& engine);
151 ~HandleEscape();
152
153 NativeValue* Escape(NativeValue* value);
154
155 HandleEscape(const HandleEscape&) = delete;
156 HandleEscape(HandleEscape&&) = delete;
157 HandleEscape& operator=(const HandleEscape&) = delete;
158 HandleEscape& operator=(HandleEscape&&) = delete;
159
160 private:
161 NativeScopeManager* scopeManager_ = nullptr;
162 NativeScope* nativeScope_ = nullptr;
163 };
164
165 class AsyncTask final {
166 public:
167 using ExecuteCallback = std::function<void()>;
168 using CompleteCallback = std::function<void(NativeEngine&, AsyncTask&, int32_t)>;
169
170 static void Schedule(const std::string& name, NativeEngine& engine, std::unique_ptr<AsyncTask>&& task);
171 static void ScheduleWithDefaultQos(const std::string &name, NativeEngine& engine,
172 std::unique_ptr<AsyncTask>&& task);
173 static void ScheduleHighQos(const std::string& name, NativeEngine& engine, std::unique_ptr<AsyncTask>&& task);
174 static void ScheduleLowQos(const std::string& name, NativeEngine& engine, std::unique_ptr<AsyncTask>&& task);
175 bool StartWithDefaultQos(const std::string &name, NativeEngine& engine);
176
177 AsyncTask(NativeDeferred* deferred, std::unique_ptr<ExecuteCallback>&& execute,
178 std::unique_ptr<CompleteCallback>&& complete);
179 AsyncTask(NativeReference* callbackRef, std::unique_ptr<ExecuteCallback>&& execute,
180 std::unique_ptr<CompleteCallback>&& complete);
181 ~AsyncTask();
182
183 void Resolve(NativeEngine& engine, NativeValue* value);
184 void Reject(NativeEngine& engine, NativeValue* error);
185 void ResolveWithNoError(NativeEngine& engine, NativeValue* value);
186 void ResolveWithCustomize(NativeEngine& engine, NativeValue* error, NativeValue* value);
187 void RejectWithCustomize(NativeEngine& engine, NativeValue* error, NativeValue* value);
188
189 private:
190 static void Execute(NativeEngine* engine, void* data);
191 static void Complete(NativeEngine* engine, int32_t status, void* data);
192
193 bool Start(const std::string &name, NativeEngine& engine);
194 bool StartHighQos(const std::string &name, NativeEngine& engine);
195 bool StartLowQos(const std::string &name, NativeEngine& engine);
196
197 std::unique_ptr<NativeDeferred> deferred_;
198 std::unique_ptr<NativeReference> callbackRef_;
199 std::unique_ptr<NativeAsyncWork> work_;
200 std::unique_ptr<ExecuteCallback> execute_;
201 std::unique_ptr<CompleteCallback> complete_;
202 };
203
204 std::unique_ptr<AsyncTask> CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam,
205 AsyncTask::ExecuteCallback&& execute, AsyncTask::CompleteCallback&& complete, NativeValue** result);
206
207 std::unique_ptr<AsyncTask> CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam,
208 AsyncTask::ExecuteCallback&& execute, nullptr_t, NativeValue** result);
209
210 std::unique_ptr<AsyncTask> CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam,
211 nullptr_t, AsyncTask::CompleteCallback&& complete, NativeValue** result);
212
213 std::unique_ptr<AsyncTask> CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam,
214 nullptr_t, nullptr_t, NativeValue** result);
215 } // namespace AbilityRuntime
216 } // namespace OHOS
217
218 #endif // OHOS_ABILITY_RUNTIME_JS_RUNTIME_UTILS_H
219