• 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 "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