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