• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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_napi.h"
17 
18 #include <memory>
19 
20 #include "napi_errors.h"
21 #include "napi_utils.h"
22 #include "power_common.h"
23 #include "power_log.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 uint32_t CREATE_PROMISE_MAX_ARGC = 2;
33 constexpr uint32_t CREATE_CALLBACK_MAX_ARGC = 3;
34 constexpr uint32_t ISSUPPORTED_MAX_ARGC = 1;
35 constexpr uint32_t HOLD_MAX_ARGC = 1;
36 constexpr int32_t INDEX_0 = 0;
37 constexpr int32_t INDEX_1 = 1;
38 constexpr int32_t INDEX_2 = 2;
39 }
40 
Create(napi_env & env,napi_callback_info & info,napi_ref & napiRunningLockIns)41 napi_value RunningLockNapi::Create(napi_env& env, napi_callback_info& info, napi_ref& napiRunningLockIns)
42 {
43     size_t argc = CREATE_CALLBACK_MAX_ARGC;
44     napi_value argv[argc];
45     NapiUtils::GetCallbackInfo(env, info, argc, argv);
46 
47     NapiErrors error;
48     if (argc != CREATE_CALLBACK_MAX_ARGC && argc != CREATE_PROMISE_MAX_ARGC) {
49         return error.ThrowError(env, PowerErrors::ERR_PARAM_INVALID);
50     }
51 
52     std::unique_ptr<AsyncCallbackInfo> asyncInfo = std::make_unique<AsyncCallbackInfo>();
53     RETURN_IF_WITH_RET(asyncInfo == nullptr, nullptr);
54     asyncInfo->GetData().SetRunningLockInstance(napiRunningLockIns);
55     // callback
56     if (argc == CREATE_CALLBACK_MAX_ARGC) {
57         return CreateAsyncCallback(env, argv, asyncInfo);
58     }
59 
60     // promise
61     return CreatePromise(env, argv, asyncInfo);
62 }
63 
IsSupported(napi_env env,napi_callback_info info)64 napi_value RunningLockNapi::IsSupported(napi_env env, napi_callback_info info)
65 {
66     size_t argc = ISSUPPORTED_MAX_ARGC;
67     napi_value argv[argc];
68     NapiUtils::GetCallbackInfo(env, info, argc, argv);
69 
70     NapiErrors error;
71     if (argc != ISSUPPORTED_MAX_ARGC || !NapiUtils::CheckValueType(env, argv[INDEX_0], napi_number)) {
72         return error.ThrowError(env, PowerErrors::ERR_PARAM_INVALID);
73     }
74 
75     int32_t numType;
76     napi_get_value_int32(env, argv[INDEX_0], &numType);
77     RunningLockType type = static_cast<RunningLockType>(numType);
78 
79     bool isSupported = (type == RunningLockType::RUNNINGLOCK_BACKGROUND) ||
80         (type == RunningLockType::RUNNINGLOCK_PROXIMITY_SCREEN_CONTROL);
81 
82     napi_value result;
83     napi_get_boolean(env, isSupported, &result);
84     return result;
85 }
86 
Hold(napi_env env,napi_callback_info info)87 napi_value RunningLockNapi::Hold(napi_env env, napi_callback_info info)
88 {
89     size_t argc = HOLD_MAX_ARGC;
90     napi_value argv[argc];
91     napi_value thisArg = NapiUtils::GetCallbackInfo(env, info, argc, argv);
92     NapiErrors error;
93     if (argc != HOLD_MAX_ARGC || !NapiUtils::CheckValueType(env, argv[INDEX_0], napi_number)) {
94         return error.ThrowError(env, PowerErrors::ERR_PARAM_INVALID);
95     }
96 
97     int32_t timeOut;
98     if (napi_ok != napi_get_value_int32(env, argv[INDEX_0], &timeOut)) {
99         POWER_HILOGE(FEATURE_RUNNING_LOCK, "napi_get_value_uint32 failed");
100         return nullptr;
101     }
102     auto runningLock = UnwrapRunningLock(env, thisArg);
103     RETURN_IF_WITH_RET(runningLock == nullptr, nullptr);
104     ErrCode code = runningLock->Lock(timeOut);
105     if (code == E_PERMISSION_DENIED) {
106         return error.ThrowError(env, PowerErrors::ERR_PERMISSION_DENIED);
107     }
108 #ifdef HAS_DFX_HIVIEW_PART
109     OHOS::HiviewDFX::ReportXPowerJsStackSysEvent(env, "RunningLockNapi::Hold");
110 #endif
111     return nullptr;
112 }
113 
IsHolding(napi_env env,napi_callback_info info)114 napi_value RunningLockNapi::IsHolding(napi_env env, napi_callback_info info)
115 {
116     size_t argc = 0;
117     napi_value thisArg = NapiUtils::GetCallbackInfo(env, info, argc, nullptr);
118     auto runningLock = UnwrapRunningLock(env, thisArg);
119     RETURN_IF_WITH_RET(runningLock == nullptr, nullptr);
120     bool isUsed = runningLock->IsUsed();
121     napi_value result;
122     napi_get_boolean(env, isUsed, &result);
123     return result;
124 }
125 
UnHold(napi_env env,napi_callback_info info)126 napi_value RunningLockNapi::UnHold(napi_env env, napi_callback_info info)
127 {
128     size_t argc = 0;
129     napi_value thisArg = NapiUtils::GetCallbackInfo(env, info, argc, nullptr);
130     auto runningLock = UnwrapRunningLock(env, thisArg);
131     RETURN_IF_WITH_RET(runningLock == nullptr, nullptr);
132     ErrCode code = runningLock->UnLock();
133     NapiErrors error;
134     if (code == E_PERMISSION_DENIED) {
135         return error.ThrowError(env, PowerErrors::ERR_PERMISSION_DENIED);
136     }
137     return nullptr;
138 }
139 
CreateAsyncCallback(napi_env & env,napi_value argv[],std::unique_ptr<AsyncCallbackInfo> & asyncInfo)140 napi_value RunningLockNapi::CreateAsyncCallback(
141     napi_env& env, napi_value argv[], std::unique_ptr<AsyncCallbackInfo>& asyncInfo)
142 {
143     bool isStr = NapiUtils::CheckValueType(env, argv[INDEX_0], napi_string);
144     bool isNum = NapiUtils::CheckValueType(env, argv[INDEX_1], napi_number);
145     bool isFunc = NapiUtils::CheckValueType(env, argv[INDEX_2], napi_function);
146     if (!isStr || !isNum || !isFunc) {
147         POWER_HILOGD(
148             FEATURE_RUNNING_LOCK, "isStr: %{public}d, isNum: %{public}d, isFunc: %{public}d", isStr, isNum, isFunc);
149         return asyncInfo->GetError().ThrowError(env, PowerErrors::ERR_PARAM_INVALID);
150     }
151     asyncInfo->GetData().SetName(env, argv[INDEX_0]);
152     asyncInfo->GetData().SetType(env, argv[INDEX_1]);
153     asyncInfo->CreateCallback(env, argv[INDEX_2]);
154 
155     AsyncWork(
156         env, asyncInfo, "CreateAsyncCallback",
157         [](napi_env env, void* data) {
158             AsyncCallbackInfo* asyncInfo = reinterpret_cast<AsyncCallbackInfo*>(data);
159             RETURN_IF(asyncInfo == nullptr);
160             auto error = asyncInfo->GetData().CreateRunningLock();
161             asyncInfo->GetError().Error(error);
162         },
163         [](napi_env env, napi_status status, void* data) {
164             AsyncCallbackInfo* asyncInfo = reinterpret_cast<AsyncCallbackInfo*>(data);
165             RETURN_IF(asyncInfo == nullptr);
166             napi_value result = asyncInfo->GetData().CreateInstanceForRunningLock(env);
167             asyncInfo->CallFunction(env, result);
168             asyncInfo->Release(env);
169             delete asyncInfo;
170         });
171     return nullptr;
172 }
173 
CreatePromise(napi_env & env,napi_value argv[],std::unique_ptr<AsyncCallbackInfo> & asyncInfo)174 napi_value RunningLockNapi::CreatePromise(
175     napi_env& env, napi_value argv[], std::unique_ptr<AsyncCallbackInfo>& asyncInfo)
176 {
177     bool isStr = NapiUtils::CheckValueType(env, argv[INDEX_0], napi_string);
178     bool isNum = NapiUtils::CheckValueType(env, argv[INDEX_1], napi_number);
179     if (!isStr || !isNum) {
180         POWER_HILOGW(FEATURE_RUNNING_LOCK, "isStr: %{public}d, isNum: %{public}d", isStr, isNum);
181         return asyncInfo->GetError().ThrowError(env, PowerErrors::ERR_PARAM_INVALID);
182     }
183 
184     napi_value promise;
185     asyncInfo->CreatePromise(env, promise);
186     RETURN_IF_WITH_RET(promise == nullptr, nullptr);
187     asyncInfo->GetData().SetName(env, argv[INDEX_0]);
188     asyncInfo->GetData().SetType(env, argv[INDEX_1]);
189 
190     AsyncWork(
191         env, asyncInfo, "CreatePromise",
192         [](napi_env env, void* data) {
193             AsyncCallbackInfo* asyncInfo = reinterpret_cast<AsyncCallbackInfo*>(data);
194             RETURN_IF(asyncInfo == nullptr);
195             auto error = asyncInfo->GetData().CreateRunningLock();
196             asyncInfo->GetError().Error(error);
197         },
198         [](napi_env env, napi_status status, void* data) {
199             AsyncCallbackInfo* asyncInfo = reinterpret_cast<AsyncCallbackInfo*>(data);
200             RETURN_IF(asyncInfo == nullptr);
201             if (asyncInfo->GetError().IsError()) {
202                 napi_reject_deferred(env, asyncInfo->GetDeferred(), asyncInfo->GetError().GetNapiError(env));
203             } else {
204                 napi_value result = asyncInfo->GetData().CreateInstanceForRunningLock(env);
205                 napi_resolve_deferred(env, asyncInfo->GetDeferred(), result);
206             }
207             asyncInfo->Release(env);
208             delete asyncInfo;
209         });
210     return promise;
211 }
212 
AsyncWork(napi_env & env,std::unique_ptr<AsyncCallbackInfo> & asyncInfo,const std::string & resourceName,napi_async_execute_callback execute,napi_async_complete_callback complete)213 void RunningLockNapi::AsyncWork(napi_env& env, std::unique_ptr<AsyncCallbackInfo>& asyncInfo,
214     const std::string& resourceName, napi_async_execute_callback execute, napi_async_complete_callback complete)
215 {
216     napi_value resource = nullptr;
217     napi_create_string_utf8(env, resourceName.c_str(), NAPI_AUTO_LENGTH, &resource);
218     napi_create_async_work(env, nullptr, resource, execute, complete,
219         reinterpret_cast<void*>(asyncInfo.get()), &asyncInfo->GetAsyncWork());
220     NAPI_CALL_RETURN_VOID(env, napi_queue_async_work_with_qos(env, asyncInfo->GetAsyncWork(), napi_qos_utility));
221     asyncInfo.release();
222 }
223 
UnwrapRunningLock(napi_env & env,napi_value & thisArg)224 std::shared_ptr<RunningLock> RunningLockNapi::UnwrapRunningLock(napi_env& env, napi_value& thisArg)
225 {
226     RunningLockEntity* entity = nullptr;
227     if (napi_ok != napi_unwrap(env, thisArg, (void**)&entity)) {
228         POWER_HILOGE(FEATURE_RUNNING_LOCK, "Cannot unwrap for pointer");
229         return nullptr;
230     }
231     if (entity == nullptr || entity->runningLock == nullptr) {
232         POWER_HILOGE(FEATURE_RUNNING_LOCK, "Entity runningLock is nullptr");
233         return nullptr;
234     }
235     return entity->runningLock;
236 }
237 } // namespace PowerMgr
238 } // namespace OHOS
239