• 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 #include "js_runtime_utils.h"
17 
18 #include "hilog_wrapper.h"
19 #include "js_runtime.h"
20 namespace OHOS {
21 namespace AbilityRuntime {
22 namespace {
CreateAsyncTaskWithLastParam(NativeEngine & engine,NativeValue * lastParam,std::unique_ptr<AsyncTask::ExecuteCallback> && execute,std::unique_ptr<AsyncTask::CompleteCallback> && complete,NativeValue ** result)23 std::unique_ptr<AsyncTask> CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam,
24     std::unique_ptr<AsyncTask::ExecuteCallback>&& execute, std::unique_ptr<AsyncTask::CompleteCallback>&& complete,
25     NativeValue** result)
26 {
27     if (lastParam == nullptr || lastParam->TypeOf() != NATIVE_FUNCTION) {
28         NativeDeferred* nativeDeferred = nullptr;
29         *result = engine.CreatePromise(&nativeDeferred);
30         return std::make_unique<AsyncTask>(nativeDeferred, std::move(execute), std::move(complete));
31     } else {
32         *result = engine.CreateUndefined();
33         NativeReference* callbackRef = engine.CreateReference(lastParam, 1);
34         return std::make_unique<AsyncTask>(callbackRef, std::move(execute), std::move(complete));
35     }
36 }
37 } // namespace
38 
39 // Help Functions
CreateJsError(NativeEngine & engine,int32_t errCode,const std::string & message)40 NativeValue* CreateJsError(NativeEngine& engine, int32_t errCode, const std::string& message)
41 {
42     return engine.CreateError(CreateJsValue(engine, errCode), CreateJsValue(engine, message));
43 }
44 
BindNativeFunction(NativeEngine & engine,NativeObject & object,const char * name,const char * moduleName,NativeCallback func)45 void BindNativeFunction(NativeEngine& engine, NativeObject& object, const char* name,
46     const char* moduleName, NativeCallback func)
47 {
48     std::string fullName(moduleName);
49     fullName += ".";
50     fullName += name;
51     object.SetProperty(name, engine.CreateFunction(fullName.c_str(), fullName.length(), func, nullptr));
52 }
53 
BindNativeProperty(NativeObject & object,const char * name,NativeCallback getter)54 void BindNativeProperty(NativeObject& object, const char* name, NativeCallback getter)
55 {
56     NativePropertyDescriptor property;
57     property.utf8name = name;
58     property.name = nullptr;
59     property.method = nullptr;
60     property.getter = getter;
61     property.setter = nullptr;
62     property.value = nullptr;
63     property.attributes = napi_default;
64     property.data = nullptr;
65     object.DefineProperty(property);
66 }
67 
GetNativePointerFromCallbackInfo(const NativeEngine * engine,NativeCallbackInfo * info,const char * name)68 void* GetNativePointerFromCallbackInfo(const NativeEngine* engine, NativeCallbackInfo* info, const char* name)
69 {
70     if (engine == nullptr || info == nullptr) {
71         return nullptr;
72     }
73 
74     NativeObject* object = ConvertNativeValueTo<NativeObject>(info->thisVar);
75     if (object != nullptr && name != nullptr) {
76         object = ConvertNativeValueTo<NativeObject>(object->GetProperty(name));
77     }
78     return (object != nullptr) ? object->GetNativePointer() : nullptr;
79 }
80 
SetNamedNativePointer(NativeEngine & engine,NativeObject & object,const char * name,void * ptr,NativeFinalize func)81 void SetNamedNativePointer(NativeEngine& engine, NativeObject& object, const char* name, void* ptr, NativeFinalize func)
82 {
83     NativeValue* value = engine.CreateObject();
84     NativeObject* newObject = ConvertNativeValueTo<NativeObject>(value);
85     if (newObject == nullptr) {
86         return;
87     }
88     newObject->SetNativePointer(ptr, func, nullptr);
89     object.SetProperty(name, value);
90 }
91 
GetNamedNativePointer(NativeEngine & engine,NativeObject & object,const char * name)92 void* GetNamedNativePointer(NativeEngine& engine, NativeObject& object, const char* name)
93 {
94     NativeObject* namedObj = ConvertNativeValueTo<NativeObject>(object.GetProperty(name));
95     return (namedObj != nullptr) ? namedObj->GetNativePointer() : nullptr;
96 }
97 
98 // Handle Scope
HandleScope(JsRuntime & jsRuntime)99 HandleScope::HandleScope(JsRuntime& jsRuntime)
100 {
101     scopeManager_ = jsRuntime.GetNativeEngine().GetScopeManager();
102     if (scopeManager_ != nullptr) {
103         nativeScope_ = scopeManager_->Open();
104     }
105 }
106 
HandleScope(NativeEngine & engine)107 HandleScope::HandleScope(NativeEngine& engine)
108 {
109     scopeManager_ = engine.GetScopeManager();
110     if (scopeManager_ != nullptr) {
111         nativeScope_ = scopeManager_->Open();
112     }
113 }
114 
~HandleScope()115 HandleScope::~HandleScope()
116 {
117     if (nativeScope_ != nullptr) {
118         scopeManager_->Close(nativeScope_);
119         nativeScope_ = nullptr;
120     }
121     scopeManager_ = nullptr;
122 }
123 
124 // Handle Escape
HandleEscape(JsRuntime & jsRuntime)125 HandleEscape::HandleEscape(JsRuntime& jsRuntime)
126 {
127     scopeManager_ = jsRuntime.GetNativeEngine().GetScopeManager();
128     if (scopeManager_ != nullptr) {
129         nativeScope_ = scopeManager_->OpenEscape();
130     }
131 }
132 
HandleEscape(NativeEngine & engine)133 HandleEscape::HandleEscape(NativeEngine& engine)
134 {
135     scopeManager_ = engine.GetScopeManager();
136     if (scopeManager_ != nullptr) {
137         nativeScope_ = scopeManager_->OpenEscape();
138     }
139 }
140 
~HandleEscape()141 HandleEscape::~HandleEscape()
142 {
143     if (nativeScope_ != nullptr) {
144         scopeManager_->CloseEscape(nativeScope_);
145         nativeScope_ = nullptr;
146     }
147     scopeManager_ = nullptr;
148 }
149 
Escape(NativeValue * value)150 NativeValue* HandleEscape::Escape(NativeValue* value)
151 {
152     if (nativeScope_ != nullptr) {
153         scopeManager_->Escape(nativeScope_, value);
154     }
155     return value;
156 }
157 
158 // Async Task
AsyncTask(NativeDeferred * deferred,std::unique_ptr<AsyncTask::ExecuteCallback> && execute,std::unique_ptr<AsyncTask::CompleteCallback> && complete)159 AsyncTask::AsyncTask(NativeDeferred* deferred, std::unique_ptr<AsyncTask::ExecuteCallback>&& execute,
160     std::unique_ptr<AsyncTask::CompleteCallback>&& complete)
161     : deferred_(deferred), execute_(std::move(execute)), complete_(std::move(complete))
162 {}
163 
AsyncTask(NativeReference * callbackRef,std::unique_ptr<AsyncTask::ExecuteCallback> && execute,std::unique_ptr<AsyncTask::CompleteCallback> && complete)164 AsyncTask::AsyncTask(NativeReference* callbackRef, std::unique_ptr<AsyncTask::ExecuteCallback>&& execute,
165     std::unique_ptr<AsyncTask::CompleteCallback>&& complete)
166     : callbackRef_(callbackRef), execute_(std::move(execute)), complete_(std::move(complete))
167 {}
168 
169 AsyncTask::~AsyncTask() = default;
170 
Schedule(const std::string & name,NativeEngine & engine,std::unique_ptr<AsyncTask> && task)171 void AsyncTask::Schedule(const std::string &name, NativeEngine& engine, std::unique_ptr<AsyncTask>&& task)
172 {
173     if (task && task->Start(name, engine)) {
174         task.release();
175     }
176 }
177 
Resolve(NativeEngine & engine,NativeValue * value)178 void AsyncTask::Resolve(NativeEngine& engine, NativeValue* value)
179 {
180     HILOG_DEBUG("AsyncTask::Resolve is called");
181     if (deferred_) {
182         deferred_->Resolve(value);
183         deferred_.reset();
184     }
185     if (callbackRef_) {
186         NativeValue* argv[] = {
187             CreateJsError(engine, 0),
188             value,
189         };
190         engine.CallFunction(engine.CreateUndefined(), callbackRef_->Get(), argv, ArraySize(argv));
191         callbackRef_.reset();
192     }
193     HILOG_DEBUG("AsyncTask::Resolve is called end.");
194 }
195 
ResolveWithNoError(NativeEngine & engine,NativeValue * value)196 void AsyncTask::ResolveWithNoError(NativeEngine& engine, NativeValue* value)
197 {
198     HILOG_DEBUG("AsyncTask::Resolve is called");
199     if (deferred_) {
200         deferred_->Resolve(value);
201         deferred_.reset();
202     }
203     if (callbackRef_) {
204         NativeValue* argv[] = {
205             engine.CreateNull(),
206             value,
207         };
208         engine.CallFunction(engine.CreateUndefined(), callbackRef_->Get(), argv, ArraySize(argv));
209         callbackRef_.reset();
210     }
211     HILOG_DEBUG("AsyncTask::Resolve is called end.");
212 }
213 
Reject(NativeEngine & engine,NativeValue * error)214 void AsyncTask::Reject(NativeEngine& engine, NativeValue* error)
215 {
216     if (deferred_) {
217         deferred_->Reject(error);
218         deferred_.reset();
219     }
220     if (callbackRef_) {
221         NativeValue* argv[] = {
222             error,
223             engine.CreateUndefined(),
224         };
225         engine.CallFunction(engine.CreateUndefined(), callbackRef_->Get(), argv, ArraySize(argv));
226         callbackRef_.reset();
227     }
228 }
229 
Execute(NativeEngine * engine,void * data)230 void AsyncTask::Execute(NativeEngine* engine, void* data)
231 {
232     if (engine == nullptr || data == nullptr) {
233         return;
234     }
235     auto me = static_cast<AsyncTask*>(data);
236     if (me->execute_ && *(me->execute_)) {
237         (*me->execute_)();
238     }
239 }
240 
Complete(NativeEngine * engine,int32_t status,void * data)241 void AsyncTask::Complete(NativeEngine* engine, int32_t status, void* data)
242 {
243     if (engine == nullptr || data == nullptr) {
244         return;
245     }
246     std::unique_ptr<AsyncTask> me(static_cast<AsyncTask*>(data));
247     if (me->complete_ && *(me->complete_)) {
248         HandleScope handleScope(*engine);
249         (*me->complete_)(*engine, *me, status);
250     }
251 }
252 
Start(const std::string & name,NativeEngine & engine)253 bool AsyncTask::Start(const std::string &name, NativeEngine& engine)
254 {
255     work_.reset(engine.CreateAsyncWork(name, Execute, Complete, this));
256     return work_->Queue();
257 }
258 
CreateAsyncTaskWithLastParam(NativeEngine & engine,NativeValue * lastParam,AsyncTask::ExecuteCallback && execute,AsyncTask::CompleteCallback && complete,NativeValue ** result)259 std::unique_ptr<AsyncTask> CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam,
260     AsyncTask::ExecuteCallback&& execute, AsyncTask::CompleteCallback&& complete, NativeValue** result)
261 {
262     return CreateAsyncTaskWithLastParam(engine, lastParam,
263         std::make_unique<AsyncTask::ExecuteCallback>(std::move(execute)),
264         std::make_unique<AsyncTask::CompleteCallback>(std::move(complete)), result);
265 }
266 
CreateAsyncTaskWithLastParam(NativeEngine & engine,NativeValue * lastParam,AsyncTask::ExecuteCallback && execute,nullptr_t,NativeValue ** result)267 std::unique_ptr<AsyncTask> CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam,
268     AsyncTask::ExecuteCallback&& execute, nullptr_t, NativeValue** result)
269 {
270     return CreateAsyncTaskWithLastParam(
271         engine, lastParam, std::make_unique<AsyncTask::ExecuteCallback>(std::move(execute)), nullptr, result);
272 }
273 
CreateAsyncTaskWithLastParam(NativeEngine & engine,NativeValue * lastParam,nullptr_t,AsyncTask::CompleteCallback && complete,NativeValue ** result)274 std::unique_ptr<AsyncTask> CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam,
275     nullptr_t, AsyncTask::CompleteCallback&& complete, NativeValue** result)
276 {
277     return CreateAsyncTaskWithLastParam(
278         engine, lastParam, nullptr, std::make_unique<AsyncTask::CompleteCallback>(std::move(complete)), result);
279 }
280 
CreateAsyncTaskWithLastParam(NativeEngine & engine,NativeValue * lastParam,nullptr_t,nullptr_t,NativeValue ** result)281 std::unique_ptr<AsyncTask> CreateAsyncTaskWithLastParam(NativeEngine& engine, NativeValue* lastParam,
282     nullptr_t, nullptr_t, NativeValue** result)
283 {
284     return CreateAsyncTaskWithLastParam(engine, lastParam, std::unique_ptr<AsyncTask::ExecuteCallback>(),
285         std::unique_ptr<AsyncTask::CompleteCallback>(), result);
286 }
287 }  // namespace AbilityRuntime
288 }  // namespace OHOS
289