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 "thermal_napi_context.h"
17
18 #include "thermal_common.h"
19
20 using namespace OHOS::PowerMgr;
21
22 namespace {
23 static const int32_t CALLBACK_ARG_0 = 0;
24 static const int32_t CALLBACK_ARG_1 = 1;
25 static const int32_t CALLBACK_ARGS_COUNT = 2;
26 }
27
ThermalNapiContext(napi_env env,napi_value * args,uint32_t argc,int32_t callbackArg,napi_value object)28 ThermalNapiContext::ThermalNapiContext(napi_env env, napi_value* args, uint32_t argc,
29 int32_t callbackArg, napi_value object) : env_(env),
30 object_(object),
31 deferred_(nullptr),
32 callbackRef_(nullptr),
33 asyncWork_(nullptr),
34 status_(AsyncStatus::PENDING)
35 {
36 THERMAL_HILOGD(COMP_FWK, "Enter");
37 if (callbackArg >= 0 && callbackArg < static_cast<int32_t>(argc)) {
38 napi_valuetype valueType = napi_undefined;
39 napi_typeof(env, args[callbackArg], &valueType);
40 if (valueType == napi_function) {
41 napi_create_reference(env, args[callbackArg], 1, &callbackRef_);
42 }
43 }
44
45 if (callbackRef_ == nullptr) {
46 napi_create_promise(env, &deferred_, &promise_);
47 } else {
48 napi_get_undefined(env, &promise_);
49 }
50
51 if (object_ == nullptr) {
52 napi_get_global(env, &object_);
53 }
54 napi_get_undefined(env_, &outValue_);
55 napi_get_undefined(env_, &outError_);
56 Init(args, argc);
57 }
58
~ThermalNapiContext()59 ThermalNapiContext::~ThermalNapiContext()
60 {
61 if (deferred_) {
62 deferred_ = NULL;
63 }
64
65 if (asyncWork_) {
66 napi_delete_async_work(env_, asyncWork_);
67 }
68 }
69
StartAsyncWork(const char * workName,ExecuteFunc exeFunc,FreeFunc freeFunc)70 bool ThermalNapiContext::StartAsyncWork(const char* workName, ExecuteFunc exeFunc, FreeFunc freeFunc)
71 {
72 napi_status status;
73
74 napi_value resourceName;
75 napi_create_string_latin1(this->env_, workName, NAPI_AUTO_LENGTH, &resourceName);
76
77 exeFunc_ = exeFunc;
78 freeFunc_ = freeFunc;
79
80 status = napi_create_async_work(
81 this->env_,
82 nullptr,
83 resourceName,
84 ExecuteAsyncWork,
85 CompleteAsyncWork,
86 (void *)this,
87 &asyncWork_);
88 if (status != napi_ok) {
89 THERMAL_HILOGE(COMP_FWK, "CreateAsyncWork failed: %d", status);
90 return false;
91 }
92 napi_queue_async_work(this->env_, asyncWork_);
93
94 return true;
95 }
96
ExecuteAsyncWork(napi_env env,void * data)97 void ThermalNapiContext::ExecuteAsyncWork(napi_env env, void *data)
98 {
99 ThermalNapiContext* context = (ThermalNapiContext*)data;
100 if (context->exeFunc_) {
101 bool ret = context->exeFunc_();
102 THERMAL_HILOGD(COMP_FWK, "execute work: %d", ret);
103 if (ret) {
104 context->status_ = AsyncStatus::RESOLVED;
105 } else {
106 context->status_ = AsyncStatus::REJECTED;
107 }
108 } else {
109 THERMAL_HILOGW(COMP_FWK, "execute work: no exeFunc");
110 context->status_ = AsyncStatus::REJECTED;
111 }
112 }
113
CompleteAsyncWork(napi_env env,napi_status status,void * data)114 void ThermalNapiContext::CompleteAsyncWork(napi_env env, napi_status status, void *data)
115 {
116 ThermalNapiContext* context = (ThermalNapiContext*)data;
117
118 if (context->deferred_) {
119 if (context->status_ == AsyncStatus::RESOLVED) {
120 THERMAL_HILOGD(COMP_FWK, "work complete: resolved");
121 napi_resolve_deferred(env, context->deferred_, context->GetValue());
122 } else {
123 THERMAL_HILOGD(COMP_FWK, "work complete: rejected");
124 napi_reject_deferred(env, context->deferred_, context->GetError());
125 }
126 context->deferred_ = nullptr;
127 } else if (context->callbackRef_) {
128 THERMAL_HILOGD(COMP_FWK, "work complete: callback");
129 napi_value result = 0;
130 napi_value callback = nullptr;
131 napi_get_reference_value(env, context->callbackRef_, &callback);
132 napi_value values[CALLBACK_ARGS_COUNT];
133
134 values[CALLBACK_ARG_0] = context->GetError();
135 values[CALLBACK_ARG_1] = context->GetValue();
136
137 napi_call_function(env, context->object_, callback, context->cbParamCount_, values, &result);
138 napi_delete_reference(env, context->callbackRef_);
139 context->callbackRef_ = nullptr;
140 } else {
141 THERMAL_HILOGE(COMP_FWK, "work complete: nothing");
142 }
143 napi_delete_async_work(env, context->asyncWork_);
144 context->asyncWork_ = nullptr;
145 if (context->freeFunc_) {
146 context->freeFunc_(context);
147 }
148 }
149
Init(napi_value * args,uint32_t argc)150 void ThermalNapiContext::Init(napi_value* args, uint32_t argc)
151 {
152 // do nothing in context class
153 }
154
GetValue()155 napi_value ThermalNapiContext::GetValue()
156 {
157 return outValue_;
158 }
159
GetError()160 napi_value ThermalNapiContext::GetError()
161 {
162 return outError_;
163 }
164