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