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