• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 "runninglock_interface.h"
17 
18 #include <cstdint>
19 #include <memory>
20 #include <string>
21 
22 #include "power_log.h"
23 #include "power_mgr_client.h"
24 #include "runninglock_entity.h"
25 #ifdef HAS_DFX_HIVIEW_PART
26 #include "xpower_event_js.h"
27 #endif
28 
29 namespace OHOS {
30 namespace PowerMgr {
31 namespace {
32 constexpr int RESULT_SIZE = 2;
33 constexpr int RUNNINGLOCK_NAME_MAX = 512;
34 constexpr int CREATRUNNINGLOCK_ARGC = 3;
35 constexpr int ISRUNNINGLOCKTYPESUPPORTED_ARGC = 2;
36 constexpr int32_t INDEX_0 = 0;
37 constexpr int32_t INDEX_1 = 1;
38 constexpr int32_t INDEX_2 = 2;
39 static PowerMgrClient& g_powerMgrClient = PowerMgrClient::GetInstance();
40 }
41 
CreateRunningLock(napi_env env,napi_callback_info info,napi_ref & napiRunningLock)42 napi_value RunningLockInterface::CreateRunningLock(napi_env env, napi_callback_info info, napi_ref& napiRunningLock)
43 {
44     size_t argc = CREATRUNNINGLOCK_ARGC;
45     napi_value argv[CREATRUNNINGLOCK_ARGC] = {0};
46     napi_value thisArg = nullptr;
47     void* data = nullptr;
48 
49     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisArg, &data);
50     NAPI_ASSERT(env, (status == napi_ok) && (argc >= CREATRUNNINGLOCK_ARGC - 1), "Failed to get cb info");
51 
52     std::unique_ptr<RunningLockAsyncInfo> asyncInfo = std::make_unique<RunningLockAsyncInfo>();
53     if (asyncInfo == nullptr) {
54         POWER_HILOGE(FEATURE_RUNNING_LOCK, "asyncInfo is nullptr");
55         return nullptr;
56     }
57     asyncInfo->napiRunningLockIns = napiRunningLock;
58 
59     napi_valuetype valueType = napi_undefined;
60     napi_typeof(env, argv[INDEX_0], &valueType);
61     NAPI_ASSERT(env, valueType == napi_string, "The input parameter type is not string");
62     char name[RUNNINGLOCK_NAME_MAX] = {0};
63     napi_get_value_string_utf8(env, argv[INDEX_0], name, RUNNINGLOCK_NAME_MAX + 1, &asyncInfo->nameLen);
64     asyncInfo->name = name;
65 
66     napi_typeof(env, argv[INDEX_1], &valueType);
67     NAPI_ASSERT(env, valueType == napi_number, "The input parameter type is not number");
68     int32_t type = static_cast<int32_t>(RunningLockType::RUNNINGLOCK_BUTT);
69     napi_get_value_int32(env, argv[INDEX_1], &type);
70     asyncInfo->type = static_cast<RunningLockType>(type);
71 
72     if (argc == CREATRUNNINGLOCK_ARGC) {
73         napi_typeof(env, argv[INDEX_2], &valueType);
74         NAPI_ASSERT(env, valueType == napi_function, "The input parameter type is not function");
75         napi_create_reference(env, argv[INDEX_2], 1, &asyncInfo->callbackRef);
76     }
77     napi_value result = nullptr;
78     if (asyncInfo->callbackRef == nullptr) {
79         POWER_HILOGD(FEATURE_RUNNING_LOCK, "callbackRef is null");
80         napi_create_promise(env, &asyncInfo->deferred, &result);
81     } else {
82         POWER_HILOGD(FEATURE_RUNNING_LOCK, "callbackRef is not null");
83         napi_get_undefined(env, &result);
84     }
85     CreateRunningLockCallBack(env, asyncInfo);
86     return result;
87 }
88 
IsRunningLockTypeSupported(napi_env env,napi_callback_info info)89 napi_value RunningLockInterface::IsRunningLockTypeSupported(napi_env env, napi_callback_info info)
90 {
91     size_t argc = ISRUNNINGLOCKTYPESUPPORTED_ARGC;
92     napi_value argv[ISRUNNINGLOCKTYPESUPPORTED_ARGC] = {0};
93     napi_value thisArg = nullptr;
94     void* data = nullptr;
95 
96     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisArg, &data);
97     NAPI_ASSERT(env, (status == napi_ok) && (argc >= 1), "Failed to get cb info");
98 
99     std::unique_ptr<RunningLockAsyncInfo> asyncInfo = std::make_unique<RunningLockAsyncInfo>();
100     if (asyncInfo == nullptr) {
101         POWER_HILOGE(FEATURE_RUNNING_LOCK, "asyncInfo is nullptr");
102         return nullptr;
103     }
104 
105     napi_valuetype valueType = napi_undefined;
106     napi_typeof(env, argv[INDEX_0], &valueType);
107     NAPI_ASSERT(env, valueType == napi_number, "The input parameter type is not number");
108     int32_t type = static_cast<int32_t>(RunningLockType::RUNNINGLOCK_BUTT);
109     napi_get_value_int32(env, argv[INDEX_0], &type);
110     asyncInfo->type = static_cast<RunningLockType>(type);
111 
112     if (argc == ISRUNNINGLOCKTYPESUPPORTED_ARGC) {
113         napi_typeof(env, argv[INDEX_1], &valueType);
114         NAPI_ASSERT(env, valueType == napi_function, "The input parameter type is not function");
115         napi_create_reference(env, argv[INDEX_1], 1, &asyncInfo->callbackRef);
116     }
117 
118     napi_value result = nullptr;
119     if (asyncInfo->callbackRef == nullptr) {
120         POWER_HILOGD(FEATURE_RUNNING_LOCK, "callbackRef is null");
121         napi_create_promise(env, &asyncInfo->deferred, &result);
122     } else {
123         POWER_HILOGD(FEATURE_RUNNING_LOCK, "callbackRef is not null");
124         napi_get_undefined(env, &result);
125     }
126     IsRunningLockTypeSupportedCallBack(env, asyncInfo);
127     return result;
128 }
129 
Lock(napi_env env,napi_callback_info info)130 napi_value RunningLockInterface::Lock(napi_env env, napi_callback_info info)
131 {
132     size_t argc = 1;
133     napi_value args[1] = {0};
134     napi_value thisArg = nullptr;
135     void* data = nullptr;
136 
137     napi_status status = napi_get_cb_info(env, info, &argc, args, &thisArg, &data);
138     NAPI_ASSERT(env, (status == napi_ok) && (argc >= 1), "Failed to get cb info");
139     napi_valuetype type = napi_undefined;
140     NAPI_CALL(env, napi_typeof(env, args[0], &type));
141     NAPI_ASSERT(env, type == napi_number, "Wrong argument type. number expected.");
142 
143     int32_t timeOut;
144     status = napi_get_value_int32(env, args[0], &timeOut);
145     if (status != napi_ok) {
146         POWER_HILOGE(FEATURE_RUNNING_LOCK, "napi_get_value_uint32 failed");
147         return nullptr;
148     }
149     RunningLockEntity* entity = nullptr;
150     status = napi_unwrap(env, thisArg, (void**)&entity);
151     if (status != napi_ok) {
152         POWER_HILOGE(FEATURE_RUNNING_LOCK, "Cannot unwrap for pointer");
153         return nullptr;
154     }
155     if (entity == nullptr || entity->runningLock == nullptr) {
156         POWER_HILOGE(FEATURE_RUNNING_LOCK, "Entity runningLock is nullptr");
157         return nullptr;
158     }
159     entity->runningLock->Lock(timeOut);
160 #ifdef HAS_DFX_HIVIEW_PART
161     OHOS::HiviewDFX::ReportXPowerJsStackSysEvent(env, "RunningLockNapi::Lock");
162 #endif
163     return nullptr;
164 }
165 
IsUsed(napi_env env,napi_callback_info info)166 napi_value RunningLockInterface::IsUsed(napi_env env, napi_callback_info info)
167 {
168     napi_value thisArg = nullptr;
169     napi_value result = nullptr;
170     void* data = nullptr;
171 
172     napi_status status = napi_get_cb_info(env, info, nullptr, nullptr, &thisArg, &data);
173     NAPI_ASSERT(env, (status == napi_ok), "Failed to get cb info");
174     napi_get_boolean(env, false, &result);
175     RunningLockEntity* entity = nullptr;
176     status = napi_unwrap(env, thisArg, (void**)&entity);
177     if (status != napi_ok) {
178         POWER_HILOGE(FEATURE_RUNNING_LOCK, "Cannot unwrap for pointer");
179         return result;
180     }
181     if (entity == nullptr || entity->runningLock == nullptr) {
182         POWER_HILOGE(FEATURE_RUNNING_LOCK, "Entity runningLock is nullptr");
183         return result;
184     }
185     bool isUsed = entity->runningLock->IsUsed();
186     napi_get_boolean(env, isUsed, &result);
187     return result;
188 }
189 
Unlock(napi_env env,napi_callback_info info)190 napi_value RunningLockInterface::Unlock(napi_env env, napi_callback_info info)
191 {
192     napi_value thisArg = nullptr;
193     void* data = nullptr;
194 
195     napi_status status = napi_get_cb_info(env, info, nullptr, nullptr, &thisArg, &data);
196     NAPI_ASSERT(env, (status == napi_ok), "Unlock: failed to get cb info");
197 
198     RunningLockEntity* entity = nullptr;
199     status = napi_unwrap(env, thisArg, (void**)&entity);
200     if (status != napi_ok) {
201         POWER_HILOGE(FEATURE_RUNNING_LOCK, "Cannot unwrap for pointer");
202         return nullptr;
203     }
204     if (entity == nullptr || entity->runningLock == nullptr) {
205         POWER_HILOGE(FEATURE_RUNNING_LOCK, "Entity runningLock is nullptr");
206         return nullptr;
207     }
208     entity->runningLock->UnLock();
209     return nullptr;
210 }
211 
CreateInstanceForRunningLock(napi_env env,RunningLockAsyncInfo * asyncInfo)212 napi_value RunningLockInterface::CreateInstanceForRunningLock(napi_env env, RunningLockAsyncInfo* asyncInfo)
213 {
214     napi_value cons = nullptr;
215     napi_value instance = nullptr;
216     napi_status callBackStatus;
217     RunningLockEntity* entity = nullptr;
218 
219     if (asyncInfo->runningLock == nullptr) {
220         POWER_HILOGE(FEATURE_RUNNING_LOCK, "RunningLock is nullptr");
221         return nullptr;
222     }
223     callBackStatus = napi_get_reference_value(env, asyncInfo->napiRunningLockIns, &cons);
224     if (callBackStatus != napi_ok) {
225         POWER_HILOGE(FEATURE_RUNNING_LOCK, "NAPI failed to create a reference value");
226         return nullptr;
227     }
228     callBackStatus = napi_new_instance(env, cons, 0, nullptr, &instance);
229     if (callBackStatus != napi_ok || instance == nullptr) {
230         POWER_HILOGE(FEATURE_RUNNING_LOCK, "NAPI failed to create a reference");
231         return nullptr;
232     }
233     callBackStatus = napi_unwrap(env, instance, (void**)&entity);
234     if (callBackStatus != napi_ok || entity == nullptr) {
235         POWER_HILOGE(FEATURE_RUNNING_LOCK, "Cannot unwrap entity from instance");
236         return nullptr;
237     }
238     entity->runningLock = asyncInfo->runningLock;
239     return instance;
240 }
241 
CreateRunningLockCallBack(napi_env env,std::unique_ptr<RunningLockAsyncInfo> & asyncInfo)242 void RunningLockInterface::CreateRunningLockCallBack(napi_env env, std::unique_ptr<RunningLockAsyncInfo>& asyncInfo)
243 {
244     napi_value resource = nullptr;
245     napi_create_string_utf8(env, "createRunningLock", NAPI_AUTO_LENGTH, &resource);
246     napi_create_async_work(
247         env, nullptr, resource,
248         [](napi_env env, void* data) {
249             auto* asyncInfo = reinterpret_cast<RunningLockAsyncInfo*>(data);
250             if (!IsTypeSupported(asyncInfo->type)) {
251                 auto type = static_cast<uint32_t>(asyncInfo->type);
252                 POWER_HILOGW(FEATURE_RUNNING_LOCK, "type=%{public}u not supported", type);
253                 return;
254             }
255             asyncInfo->runningLock = g_powerMgrClient.CreateRunningLock(std::string(asyncInfo->name), asyncInfo->type);
256         },
257         [](napi_env env, napi_status status, void* data) {
258             auto* asyncInfo = reinterpret_cast<RunningLockAsyncInfo*>(data);
259             napi_value result[RESULT_SIZE] = {0};
260             result[1] = CreateInstanceForRunningLock(env, asyncInfo);
261             if (result[1] == nullptr) {
262                 napi_value message = nullptr;
263                 napi_create_string_utf8(env, "runningLock create failed", NAPI_AUTO_LENGTH, &message);
264                 napi_create_error(env, nullptr, message, &result[0]);
265             }
266             if (asyncInfo->deferred) {
267                 if (result[1] != nullptr) {
268                     napi_resolve_deferred(env, asyncInfo->deferred, result[1]);
269                 } else {
270                     napi_reject_deferred(env, asyncInfo->deferred, result[0]);
271                 }
272             } else {
273                 napi_value tmp = nullptr;
274                 napi_value callback = nullptr;
275                 napi_get_undefined(env, &result[0]);
276                 napi_get_reference_value(env, asyncInfo->callbackRef, &callback);
277                 napi_call_function(env, nullptr, callback, RESULT_SIZE, result, &tmp);
278                 napi_delete_reference(env, asyncInfo->callbackRef);
279             }
280             napi_delete_async_work(env, asyncInfo->asyncWork);
281             delete asyncInfo;
282         },
283         reinterpret_cast<void*>(asyncInfo.get()), &asyncInfo->asyncWork);
284     if (napi_ok == napi_queue_async_work_with_qos(env, asyncInfo->asyncWork, napi_qos_utility)) {
285         asyncInfo.release();
286     }
287 }
288 
IsRunningLockTypeSupportedCallBack(napi_env env,std::unique_ptr<RunningLockAsyncInfo> & asyncInfo)289 void RunningLockInterface::IsRunningLockTypeSupportedCallBack(
290     napi_env env, std::unique_ptr<RunningLockAsyncInfo>& asyncInfo)
291 {
292     napi_value resource = nullptr;
293     napi_create_string_utf8(env, "isRunningLockTypeSupported", NAPI_AUTO_LENGTH, &resource);
294     napi_create_async_work(
295         env, nullptr, resource,
296         [](napi_env env, void* data) {
297             auto* asyncInfo = reinterpret_cast<RunningLockAsyncInfo*>(data);
298             asyncInfo->isSupported = IsTypeSupported(asyncInfo->type);
299             POWER_HILOGD(FEATURE_RUNNING_LOCK, "type=%{public}u, isSupported=%{public}s",
300                 static_cast<uint32_t>(asyncInfo->type), asyncInfo->isSupported ? "true" : "false");
301         },
302         [](napi_env env, napi_status status, void* data) {
303             auto* asyncInfo = reinterpret_cast<RunningLockAsyncInfo*>(data);
304             napi_value result[RESULT_SIZE] = {0};
305             napi_get_boolean(env, asyncInfo->isSupported, &result[1]);
306             if (asyncInfo->deferred) {
307                 napi_resolve_deferred(env, asyncInfo->deferred, result[1]);
308             } else {
309                 napi_value tmp = nullptr;
310                 napi_value callback = nullptr;
311                 napi_get_reference_value(env, asyncInfo->callbackRef, &callback);
312                 napi_get_undefined(env, &result[0]);
313                 napi_call_function(env, nullptr, callback, RESULT_SIZE, result, &tmp);
314                 napi_delete_reference(env, asyncInfo->callbackRef);
315             }
316             napi_delete_async_work(env, asyncInfo->asyncWork);
317             delete asyncInfo;
318         },
319         reinterpret_cast<void*>(asyncInfo.get()), &asyncInfo->asyncWork);
320     if (napi_ok == napi_queue_async_work_with_qos(env, asyncInfo->asyncWork, napi_qos_utility)) {
321         asyncInfo.release();
322     }
323 }
324 
IsTypeSupported(RunningLockType type)325 bool RunningLockInterface::IsTypeSupported(RunningLockType type)
326 {
327     return type == RunningLockType::RUNNINGLOCK_BACKGROUND ||
328         type == RunningLockType::RUNNINGLOCK_PROXIMITY_SCREEN_CONTROL;
329 }
330 } // namespace PowerMgr
331 } // namespace OHOS
332