• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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