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