1 /*
2 * Copyright (c) 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 "power_napi.h"
17
18 #include "napi_errors.h"
19 #include "napi_utils.h"
20 #include "power_common.h"
21 #include "power_log.h"
22 #include "power_mgr_client.h"
23
24 namespace OHOS {
25 namespace PowerMgr {
26 namespace {
27 constexpr uint32_t REBOOT_SHUTDOWN_MAX_ARGC = 1;
28 constexpr uint32_t WAKEUP_MAX_ARGC = 1;
29 constexpr uint32_t SET_MODE_CALLBACK_MAX_ARGC = 2;
30 constexpr uint32_t SET_MODE_PROMISE_MAX_ARGC = 1;
31 constexpr uint32_t SUSPEND_MAX_ARGC = 1;
32 constexpr int32_t INDEX_0 = 0;
33 constexpr int32_t INDEX_1 = 1;
34 static PowerMgrClient& g_powerMgrClient = PowerMgrClient::GetInstance();
35 } // namespace
Shutdown(napi_env env,napi_callback_info info)36 napi_value PowerNapi::Shutdown(napi_env env, napi_callback_info info)
37 {
38 return RebootOrShutdown(env, info, false);
39 }
40
Reboot(napi_env env,napi_callback_info info)41 napi_value PowerNapi::Reboot(napi_env env, napi_callback_info info)
42 {
43 return RebootOrShutdown(env, info, true);
44 }
45
IsActive(napi_env env,napi_callback_info info)46 napi_value PowerNapi::IsActive(napi_env env, napi_callback_info info)
47 {
48 bool isScreen = g_powerMgrClient.IsScreenOn();
49 napi_value napiValue;
50 NAPI_CALL(env, napi_get_boolean(env, isScreen, &napiValue));
51 return napiValue;
52 }
53
Wakeup(napi_env env,napi_callback_info info)54 napi_value PowerNapi::Wakeup(napi_env env, napi_callback_info info)
55 {
56 size_t argc = WAKEUP_MAX_ARGC;
57 napi_value argv[argc];
58 NapiUtils::GetCallbackInfo(env, info, argc, argv);
59
60 NapiErrors error;
61 if (argc != WAKEUP_MAX_ARGC || !NapiUtils::CheckValueType(env, argv[INDEX_0], napi_string)) {
62 return error.ThrowError(env, PowerErrors::ERR_PARAM_INVALID);
63 }
64
65 std::string detail = NapiUtils::GetStringFromNapi(env, argv[INDEX_0]);
66 POWER_HILOGD(FEATURE_WAKEUP, "Wakeup type: APPLICATION, reason: %{public}s", detail.c_str());
67 PowerErrors code = g_powerMgrClient.WakeupDevice(WakeupDeviceType::WAKEUP_DEVICE_APPLICATION, detail);
68 if (code != PowerErrors::ERR_OK) {
69 error.ThrowError(env, code);
70 }
71 return nullptr;
72 }
73
Suspend(napi_env env,napi_callback_info info)74 napi_value PowerNapi::Suspend(napi_env env, napi_callback_info info)
75 {
76 size_t argc = SUSPEND_MAX_ARGC;
77 napi_value argv[argc];
78 NapiUtils::GetCallbackInfo(env, info, argc, argv);
79
80 NapiErrors error;
81 if (argc != SUSPEND_MAX_ARGC || !NapiUtils::CheckValueType(env, argv[INDEX_0], napi_boolean)) {
82 if (!NapiUtils::CheckValueType(env, argv[INDEX_0], napi_undefined)) {
83 std::string detail = NapiUtils::GetStringFromNapi(env, argv[INDEX_0]);
84 if (!detail.empty()) {
85 return error.ThrowError(env, PowerErrors::ERR_PARAM_INVALID);
86 }
87 }
88 }
89 bool isForce = false;
90 napi_get_value_bool(env, argv[0], &isForce);
91
92 if (isForce) {
93 bool ret = g_powerMgrClient.ForceSuspendDevice();
94 if (!ret) {
95 POWER_HILOGE(FEATURE_WAKEUP, "Forcesuspend Device fail");
96 }
97 } else {
98 PowerErrors code = g_powerMgrClient.SuspendDevice();
99 if (code != PowerErrors::ERR_OK) {
100 error.ThrowError(env, code);
101 }
102 }
103 return nullptr;
104 }
105
SetPowerMode(napi_env env,napi_callback_info info)106 napi_value PowerNapi::SetPowerMode(napi_env env, napi_callback_info info)
107 {
108 size_t argc = SET_MODE_CALLBACK_MAX_ARGC;
109 napi_value argv[argc];
110 NapiUtils::GetCallbackInfo(env, info, argc, argv);
111
112 NapiErrors error;
113 if (argc != SET_MODE_CALLBACK_MAX_ARGC && argc != SET_MODE_PROMISE_MAX_ARGC) {
114 return error.ThrowError(env, PowerErrors::ERR_PARAM_INVALID);
115 }
116
117 std::unique_ptr<AsyncCallbackInfo> asyncInfo = std::make_unique<AsyncCallbackInfo>();
118 RETURN_IF_WITH_RET(asyncInfo == nullptr, nullptr);
119 // callback
120 if (argc == SET_MODE_CALLBACK_MAX_ARGC) {
121 POWER_HILOGD(FEATURE_POWER_MODE, "Call setPowerMode callback");
122 return SetPowerModeCallback(env, argv, asyncInfo);
123 }
124
125 // promise
126 POWER_HILOGD(FEATURE_POWER_MODE, "Call setPowerMode promise");
127 return SetPowerModePromise(env, argv, asyncInfo);
128 }
129
GetPowerMode(napi_env env,napi_callback_info info)130 napi_value PowerNapi::GetPowerMode(napi_env env, napi_callback_info info)
131 {
132 PowerMode mode = g_powerMgrClient.GetDeviceMode();
133 napi_value napiValue;
134 NAPI_CALL(env, napi_create_uint32(env, static_cast<uint32_t>(mode), &napiValue));
135 return napiValue;
136 }
137
RebootOrShutdown(napi_env env,napi_callback_info info,bool isReboot)138 napi_value PowerNapi::RebootOrShutdown(napi_env env, napi_callback_info info, bool isReboot)
139 {
140 size_t argc = REBOOT_SHUTDOWN_MAX_ARGC;
141 napi_value argv[argc];
142 NapiUtils::GetCallbackInfo(env, info, argc, argv);
143
144 NapiErrors error;
145 if (argc != REBOOT_SHUTDOWN_MAX_ARGC || !NapiUtils::CheckValueType(env, argv[INDEX_0], napi_string)) {
146 return error.ThrowError(env, PowerErrors::ERR_PARAM_INVALID);
147 }
148
149 std::string reason = NapiUtils::GetStringFromNapi(env, argv[INDEX_0]);
150 POWER_HILOGD(FEATURE_SHUTDOWN, "reboot: %{public}d, reason: %{public}s", isReboot, reason.c_str());
151
152 PowerErrors code;
153 if (isReboot) {
154 code = g_powerMgrClient.RebootDevice(reason);
155 } else {
156 code = g_powerMgrClient.ShutDownDevice(reason);
157 }
158 if (code != PowerErrors::ERR_OK) {
159 error.ThrowError(env, code);
160 }
161
162 return nullptr;
163 }
164
SetPowerModeCallback(napi_env & env,napi_value argv[],std::unique_ptr<AsyncCallbackInfo> & asyncInfo)165 napi_value PowerNapi::SetPowerModeCallback(
166 napi_env& env, napi_value argv[], std::unique_ptr<AsyncCallbackInfo>& asyncInfo)
167 {
168 bool isNum = NapiUtils::CheckValueType(env, argv[INDEX_0], napi_number);
169 bool isFunc = NapiUtils::CheckValueType(env, argv[INDEX_1], napi_function);
170 if (!isNum || !isFunc) {
171 POWER_HILOGW(FEATURE_POWER_MODE, "isNum: %{public}d, isFunc: %{public}d", isNum, isFunc);
172 return asyncInfo->GetError().ThrowError(env, PowerErrors::ERR_PARAM_INVALID);
173 }
174
175 asyncInfo->GetData().SetMode(env, argv[INDEX_0]);
176 asyncInfo->CreateCallback(env, argv[INDEX_1]);
177
178 AsyncWork(
179 env, asyncInfo, "SetPowerModeCallback",
180 [](napi_env env, void* data) {
181 AsyncCallbackInfo* asyncInfo = reinterpret_cast<AsyncCallbackInfo*>(data);
182 RETURN_IF(asyncInfo == nullptr);
183 PowerErrors error = g_powerMgrClient.SetDeviceMode(asyncInfo->GetData().GetMode());
184 asyncInfo->GetError().Error(error);
185 },
186 [](napi_env env, napi_status status, void* data) {
187 AsyncCallbackInfo* asyncInfo = reinterpret_cast<AsyncCallbackInfo*>(data);
188 RETURN_IF(asyncInfo == nullptr);
189 asyncInfo->CallFunction(env, nullptr);
190 asyncInfo->Release(env);
191 delete asyncInfo;
192 });
193 return nullptr;
194 }
195
SetPowerModePromise(napi_env & env,napi_value argv[],std::unique_ptr<AsyncCallbackInfo> & asyncInfo)196 napi_value PowerNapi::SetPowerModePromise(
197 napi_env& env, napi_value argv[], std::unique_ptr<AsyncCallbackInfo>& asyncInfo)
198 {
199 bool isNum = NapiUtils::CheckValueType(env, argv[INDEX_0], napi_number);
200 if (!isNum) {
201 POWER_HILOGW(FEATURE_POWER_MODE, "isNum: %{public}d", isNum);
202 return asyncInfo->GetError().ThrowError(env, PowerErrors::ERR_PARAM_INVALID);
203 }
204 napi_value promise;
205 asyncInfo->CreatePromise(env, promise);
206 RETURN_IF_WITH_RET(promise == nullptr, nullptr);
207 asyncInfo->GetData().SetMode(env, argv[INDEX_0]);
208
209 AsyncWork(
210 env, asyncInfo, "SetPowerModePromise",
211 [](napi_env env, void* data) {
212 AsyncCallbackInfo* asyncInfo = reinterpret_cast<AsyncCallbackInfo*>(data);
213 RETURN_IF(asyncInfo == nullptr);
214 PowerErrors error = g_powerMgrClient.SetDeviceMode(asyncInfo->GetData().GetMode());
215 asyncInfo->GetError().Error(error);
216 },
217 [](napi_env env, napi_status status, void* data) {
218 AsyncCallbackInfo* asyncInfo = reinterpret_cast<AsyncCallbackInfo*>(data);
219 RETURN_IF(asyncInfo == nullptr);
220 if (asyncInfo->GetError().IsError()) {
221 napi_reject_deferred(env, asyncInfo->GetDeferred(), asyncInfo->GetError().GetNapiError(env));
222 } else {
223 napi_value undefined;
224 napi_get_undefined(env, &undefined);
225 napi_resolve_deferred(env, asyncInfo->GetDeferred(), undefined);
226 }
227 asyncInfo->Release(env);
228 delete asyncInfo;
229 });
230 return promise;
231 }
232
AsyncWork(napi_env & env,std::unique_ptr<AsyncCallbackInfo> & asyncInfo,const std::string & resourceName,napi_async_execute_callback execute,napi_async_complete_callback complete)233 void PowerNapi::AsyncWork(napi_env& env, std::unique_ptr<AsyncCallbackInfo>& asyncInfo, const std::string& resourceName,
234 napi_async_execute_callback execute, napi_async_complete_callback complete)
235 {
236 napi_value resource = nullptr;
237 napi_create_string_utf8(env, resourceName.c_str(), NAPI_AUTO_LENGTH, &resource);
238 napi_create_async_work(env, nullptr, resource, execute, complete,
239 reinterpret_cast<void*>(asyncInfo.get()), &(asyncInfo->GetAsyncWork()));
240 NAPI_CALL_RETURN_VOID(env, napi_queue_async_work_with_qos(env, asyncInfo->GetAsyncWork(), napi_qos_utility));
241 asyncInfo.release();
242 }
243
IsStandby(napi_env env,napi_callback_info info)244 napi_value PowerNapi::IsStandby(napi_env env, napi_callback_info info)
245 {
246 bool isStandby = false;
247 PowerErrors code = g_powerMgrClient.IsStandby(isStandby);
248 if (code == PowerErrors::ERR_OK) {
249 napi_value napiValue;
250 NAPI_CALL(env, napi_get_boolean(env, isStandby, &napiValue));
251 return napiValue;
252 }
253 NapiErrors error;
254 return error.ThrowError(env, code);
255 }
256 } // namespace PowerMgr
257 } // namespace OHOS
258