• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 <cstdio>
17 #include <cstdlib>
18 #include <string>
19 #include "hilog_wrapper.h"
20 #include "napi/native_api.h"
21 #include "napi/native_node_api.h"
22 #include "power_mgr_client.h"
23 
24 using namespace OHOS::PowerMgr;
25 
26 namespace {
27 constexpr int REASON_MAX = 512;
28 constexpr int RESULT_SIZE = 2;
29 }
30 
31 struct PowerAsyncCallbackInfo {
32     napi_env env;
33     napi_async_work asyncWork = nullptr;
34     napi_ref callbackRef = nullptr;
35     napi_deferred deferred = nullptr;
36     bool screenOn = false;
37 };
38 
39 static PowerMgrClient &g_powerMgrClient = PowerMgrClient::GetInstance();
40 
RebootOrShutdown(napi_env env,napi_callback_info info,bool isReboot)41 static napi_value RebootOrShutdown(napi_env env, napi_callback_info info, bool isReboot)
42 {
43     POWER_HILOGD(MODULE_JS_NAPI, "%{public}s: enter, %{public}s", __func__, isReboot ? "reboot" : "shutdown");
44     size_t argc = 1;
45     napi_value args[1] = { 0 };
46     napi_value jsthis;
47     void *data = nullptr;
48 
49     napi_status status = napi_get_cb_info(env, info, &argc, args, &jsthis, &data);
50     NAPI_ASSERT(env, (status == napi_ok) && (argc >= 1), "failed to get cb info");
51     napi_valuetype type = napi_undefined;
52     NAPI_CALL(env, napi_typeof(env, args[0], &type));
53     NAPI_ASSERT(env, type == napi_string, "wrong argument type. string expected.");
54 
55     char reason[REASON_MAX] = { 0 };
56     size_t reasonLen = 0;
57     status = napi_get_value_string_utf8(env, args[0], reason, REASON_MAX - 1, &reasonLen);
58     if (status != napi_ok) {
59         POWER_HILOGE(MODULE_JS_NAPI, "%{public}s: get reason failed", __func__);
60         return nullptr;
61     }
62     if (isReboot) {
63         g_powerMgrClient.RebootDevice(std::string(reason));
64     } else {
65         g_powerMgrClient.ShutDownDevice(std::string(reason));
66     }
67     POWER_HILOGD(MODULE_JS_NAPI, "%{public}s: reason %{public}s, exit", __func__, reason);
68     return nullptr;
69 }
70 
ShutdownDevice(napi_env env,napi_callback_info info)71 static napi_value ShutdownDevice(napi_env env, napi_callback_info info)
72 {
73     return RebootOrShutdown(env, info, false);
74 }
75 
RebootDevice(napi_env env,napi_callback_info info)76 static napi_value RebootDevice(napi_env env, napi_callback_info info)
77 {
78     return RebootOrShutdown(env, info, true);
79 }
80 
IsScreenOnCallBack(napi_env env,PowerAsyncCallbackInfo * asyncCallbackInfo)81 static void IsScreenOnCallBack(napi_env env, PowerAsyncCallbackInfo *asyncCallbackInfo)
82 {
83     napi_value resource = nullptr;
84     napi_create_string_utf8(env, "IsScreenOn", NAPI_AUTO_LENGTH, &resource);
85     napi_create_async_work(
86         env,
87         nullptr,
88         resource,
89         [](napi_env env, void *data) {
90             PowerAsyncCallbackInfo *asyncCallbackInfo = (PowerAsyncCallbackInfo *)data;
91             asyncCallbackInfo->screenOn = g_powerMgrClient.IsScreenOn();
92             POWER_HILOGD(MODULE_JS_NAPI, "%{public}s: screen is %{public}s ", __func__,
93                 asyncCallbackInfo->screenOn ? "on" : "off");
94         },
95         [](napi_env env, napi_status status, void *data) {
96             PowerAsyncCallbackInfo *asyncCallbackInfo = (PowerAsyncCallbackInfo *)data;
97             napi_value result[RESULT_SIZE] = { 0 };
98             napi_get_boolean(env, asyncCallbackInfo->screenOn, &result[1]);
99             if (asyncCallbackInfo->deferred) {
100                 napi_resolve_deferred(env, asyncCallbackInfo->deferred, result[1]);
101             } else {
102                 napi_value tmp = nullptr;
103                 napi_value callback = nullptr;
104                 napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
105                 napi_get_undefined(env, &result[0]);
106                 napi_call_function(env, nullptr, callback, RESULT_SIZE, result, &tmp);
107                 napi_delete_reference(env, asyncCallbackInfo->callbackRef);
108             }
109             napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
110             delete asyncCallbackInfo;
111         },
112         (void *)asyncCallbackInfo,
113         &asyncCallbackInfo->asyncWork);
114     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
115 }
116 
IsScreenOn(napi_env env,napi_callback_info info)117 static napi_value IsScreenOn(napi_env env, napi_callback_info info)
118 {
119     POWER_HILOGD(MODULE_JS_NAPI, "%{public}s: enter", __func__);
120     size_t argc = 1;
121     napi_value args[1] = { 0 };
122     napi_value jsthis;
123     void *data = nullptr;
124 
125     napi_status status = napi_get_cb_info(env, info, &argc, args, &jsthis, &data);
126     NAPI_ASSERT(env, (status == napi_ok), "IsScreenOn: failed to get cb info");
127 
128     auto asyncCallbackInfo = new PowerAsyncCallbackInfo();
129     if (asyncCallbackInfo == nullptr) {
130         POWER_HILOGE(MODULE_JS_NAPI, "%{public}s: new asyncCallbackInfo failed", __func__);
131         return nullptr;
132     }
133     asyncCallbackInfo->env = env;
134 
135     napi_valuetype type;
136     if (argc == 1) {
137         NAPI_CALL(env, napi_typeof(env, args[0], &type));
138         if (type != napi_function) {
139             POWER_HILOGE(MODULE_JS_NAPI, "%{public}s: wrong argument type. napi_function expected", __func__);
140             delete asyncCallbackInfo;
141             return nullptr;
142         }
143         napi_create_reference(env, args[0], 1, &asyncCallbackInfo->callbackRef);
144     }
145     napi_value result = nullptr;
146     if (asyncCallbackInfo->callbackRef == nullptr) {
147         POWER_HILOGD(MODULE_JS_NAPI, "%{public}s: callbackRef is null", __func__);
148         napi_create_promise(env, &asyncCallbackInfo->deferred, &result);
149     } else {
150         POWER_HILOGD(MODULE_JS_NAPI, "%{public}s: callbackRef is not null", __func__);
151         napi_get_undefined(env, &result);
152     }
153     IsScreenOnCallBack(env, asyncCallbackInfo);
154     POWER_HILOGD(MODULE_JS_NAPI, "%{public}s: exit", __func__);
155     return result;
156 }
157 
158 EXTERN_C_START
159 /*
160  * function for module exports
161  */
PowerInit(napi_env env,napi_value exports)162 static napi_value PowerInit(napi_env env, napi_value exports)
163 {
164     POWER_HILOGD(MODULE_JS_NAPI, "%{public}s: enter", __func__);
165     napi_property_descriptor desc[] = {
166         DECLARE_NAPI_FUNCTION("shutdownDevice", ShutdownDevice),
167         DECLARE_NAPI_FUNCTION("rebootDevice", RebootDevice),
168         DECLARE_NAPI_FUNCTION("isScreenOn", IsScreenOn),
169     };
170     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
171     POWER_HILOGD(MODULE_JS_NAPI, "%{public}s: exit", __func__);
172 
173     return exports;
174 }
175 EXTERN_C_END
176 
177 /*
178  * Module definition
179  */
180 static napi_module g_module = {
181     .nm_version = 1,
182     .nm_flags = 0,
183     .nm_filename = "power",
184     .nm_register_func = PowerInit,
185     .nm_modname = "power",
186     .nm_priv = ((void *)0),
187     .reserved = {0}
188 };
189 
190 /*
191  * Module registration
192  */
RegisterPowerModule(void)193 extern "C" __attribute__((constructor)) void RegisterPowerModule(void)
194 {
195     napi_module_register(&g_module);
196 }