1 /*
2  * Copyright (c) 2023-2024 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 "device_control_addon.h"
17 #include "operate_device_param.h"
18 #ifdef OS_ACCOUNT_EDM_ENABLE
19 #include "os_account_manager.h"
20 #endif
21 #include "edm_log.h"
22 
23 using namespace OHOS::EDM;
24 
Init(napi_env env,napi_value exports)25 napi_value DeviceControlAddon::Init(napi_env env, napi_value exports)
26 {
27     napi_property_descriptor property[] = {
28         DECLARE_NAPI_FUNCTION("resetFactory", ResetFactory),
29         DECLARE_NAPI_FUNCTION("shutdown", Shutdown),
30         DECLARE_NAPI_FUNCTION("reboot", Reboot),
31         DECLARE_NAPI_FUNCTION("lockScreen", LockScreen),
32         DECLARE_NAPI_FUNCTION("operateDevice", OperateDevice),
33     };
34     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(property) / sizeof(property[0]), property));
35     return exports;
36 }
37 
ResetFactory(napi_env env,napi_callback_info info)38 napi_value DeviceControlAddon::ResetFactory(napi_env env, napi_callback_info info)
39 {
40     EDMLOGI("NAPI_resetFactory called");
41     size_t argc = ARGS_SIZE_TWO;
42     napi_value argv[ARGS_SIZE_TWO] = {nullptr};
43     napi_value thisArg = nullptr;
44     void *data = nullptr;
45     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
46     ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_ONE, "parameter count error");
47     bool matchFlag = MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object);
48     if (argc > ARGS_SIZE_ONE) {
49         matchFlag = matchFlag && MatchValueType(env, argv[ARR_INDEX_ONE], napi_function);
50     }
51     ASSERT_AND_THROW_PARAM_ERROR(env, matchFlag, "parameter type error");
52     auto asyncCallbackInfo = new (std::nothrow) AsyncDeviceControlCallbackInfo();
53     if (asyncCallbackInfo == nullptr) {
54         return nullptr;
55     }
56     std::unique_ptr<AsyncDeviceControlCallbackInfo> callbackPtr {asyncCallbackInfo};
57     bool ret = ParseElementName(env, asyncCallbackInfo->elementName, argv[ARR_INDEX_ZERO]);
58     ASSERT_AND_THROW_PARAM_ERROR(env, ret, "element name param error");
59     EDMLOGD("resetFactory: asyncCallbackInfo->elementName.bundlename %{public}s, "
60         "asyncCallbackInfo->abilityname:%{public}s",
61         asyncCallbackInfo->elementName.GetBundleName().c_str(),
62         asyncCallbackInfo->elementName.GetAbilityName().c_str());
63     if (argc > ARGS_SIZE_ONE) {
64         EDMLOGD("NAPI_resetFactory argc == ARGS_SIZE_TWO");
65         napi_create_reference(env, argv[ARR_INDEX_ONE], NAPI_RETURN_ONE, &asyncCallbackInfo->callback);
66     }
67     napi_value asyncWorkReturn = HandleAsyncWork(env, asyncCallbackInfo, "ResetFactory",
68         NativeResetFactory, NativeVoidCallbackComplete);
69     callbackPtr.release();
70     return asyncWorkReturn;
71 }
72 
LockScreen(napi_env env,napi_callback_info info)73 napi_value DeviceControlAddon::LockScreen(napi_env env, napi_callback_info info)
74 {
75     EDMLOGI("NAPI_lockScreen called");
76     size_t argc = ARGS_SIZE_TWO;
77     napi_value argv[ARGS_SIZE_TWO] = {nullptr};
78     napi_value thisArg = nullptr;
79     void *data = nullptr;
80     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
81     ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_ONE, "parameter count error");
82     bool matchFlag = MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object);
83     ASSERT_AND_THROW_PARAM_ERROR(env, matchFlag, "parameter type error");
84     OHOS::AppExecFwk::ElementName elementName;
85     bool ret = ParseElementName(env, elementName, argv[ARR_INDEX_ZERO]);
86     ASSERT_AND_THROW_PARAM_ERROR(env, ret, "element name param error");
87     EDMLOGD("lockScreen: asyncCallbackInfo->elementName.bundlename %{public}s, "
88         "asyncCallbackInfo->abilityname:%{public}s",
89         elementName.GetBundleName().c_str(),
90         elementName.GetAbilityName().c_str());
91     int32_t userId = 0;
92 #ifdef OS_ACCOUNT_EDM_ENABLE
93     AccountSA::OsAccountManager::GetOsAccountLocalIdFromProcess(userId);
94     EDMLOGI("NAPI_lockScreen called userId :%{public}d", userId);
95 #else
96     EDMLOGI("NAPI_lockScreen don't call userId");
97 #endif
98     int32_t result = DeviceControlProxy::GetDeviceControlProxy()->LockScreen(elementName, userId);
99     if (FAILED(result)) {
100         napi_throw(env, CreateError(env, result));
101     }
102     return nullptr;
103 }
104 
Shutdown(napi_env env,napi_callback_info info)105 napi_value DeviceControlAddon::Shutdown(napi_env env, napi_callback_info info)
106 {
107     EDMLOGI("NAPI_shutdown called");
108     size_t argc = ARGS_SIZE_TWO;
109     napi_value argv[ARGS_SIZE_TWO] = {nullptr};
110     napi_value thisArg = nullptr;
111     void *data = nullptr;
112     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
113     ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_ONE, "parameter count error");
114     bool matchFlag = MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object);
115     ASSERT_AND_THROW_PARAM_ERROR(env, matchFlag, "parameter type error");
116     OHOS::AppExecFwk::ElementName elementName;
117     bool ret = ParseElementName(env, elementName, argv[ARR_INDEX_ZERO]);
118     ASSERT_AND_THROW_PARAM_ERROR(env, ret, "element name param error");
119     EDMLOGD("lockScreen: asyncCallbackInfo->elementName.bundlename %{public}s, "
120         "asyncCallbackInfo->abilityname:%{public}s",
121         elementName.GetBundleName().c_str(),
122         elementName.GetAbilityName().c_str());
123     int32_t result = DeviceControlProxy::GetDeviceControlProxy()->Shutdown(elementName);
124     if (FAILED(result)) {
125         napi_throw(env, CreateError(env, result));
126     }
127     return nullptr;
128 }
129 
Reboot(napi_env env,napi_callback_info info)130 napi_value DeviceControlAddon::Reboot(napi_env env, napi_callback_info info)
131 {
132     EDMLOGI("NAPI_reboot called");
133     size_t argc = ARGS_SIZE_TWO;
134     napi_value argv[ARGS_SIZE_TWO] = {nullptr};
135     napi_value thisArg = nullptr;
136     void *data = nullptr;
137     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
138     ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_ONE, "parameter count error");
139     bool matchFlag = MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object);
140     ASSERT_AND_THROW_PARAM_ERROR(env, matchFlag, "parameter type error");
141     OHOS::AppExecFwk::ElementName elementName;
142     bool ret = ParseElementName(env, elementName, argv[ARR_INDEX_ZERO]);
143     ASSERT_AND_THROW_PARAM_ERROR(env, ret, "element name param error");
144     EDMLOGD("lockScreen: asyncCallbackInfo->elementName.bundlename %{public}s, "
145         "asyncCallbackInfo->abilityname:%{public}s",
146         elementName.GetBundleName().c_str(),
147         elementName.GetAbilityName().c_str());
148     int32_t result = DeviceControlProxy::GetDeviceControlProxy()->Reboot(elementName);
149     if (FAILED(result)) {
150         napi_throw(env, CreateError(env, result));
151     }
152     return nullptr;
153 }
154 
NativeResetFactory(napi_env env,void * data)155 void DeviceControlAddon::NativeResetFactory(napi_env env, void *data)
156 {
157     EDMLOGI("NAPI_NativeResetFactory called");
158     if (data == nullptr) {
159         EDMLOGE("data is nullptr");
160         return;
161     }
162     AsyncDeviceControlCallbackInfo *asyncCallbackInfo = static_cast<AsyncDeviceControlCallbackInfo *>(data);
163     if (DeviceControlProxy::GetDeviceControlProxy() == nullptr) {
164         EDMLOGE("can not get GetDeviceControlProxy");
165         return;
166     }
167     asyncCallbackInfo->ret =
168         DeviceControlProxy::GetDeviceControlProxy()->ResetFactory(asyncCallbackInfo->elementName);
169 }
170 
OperateDevice(napi_env env,napi_callback_info info)171 napi_value DeviceControlAddon::OperateDevice(napi_env env, napi_callback_info info)
172 {
173     EDMLOGI("NAPI_OperateDevice called");
174     size_t argc = ARGS_SIZE_THREE;
175     napi_value argv[ARGS_SIZE_THREE] = {nullptr};
176     napi_value thisArg = nullptr;
177     void *data = nullptr;
178     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
179     ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_TWO, "parameter count error");
180     bool matchFlag = MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object) &&
181         MatchValueType(env, argv[ARR_INDEX_ONE], napi_string);
182     if (argc > ARGS_SIZE_TWO) {
183         matchFlag = matchFlag && MatchValueType(env, argv[ARR_INDEX_TWO], napi_string);
184     }
185     ASSERT_AND_THROW_PARAM_ERROR(env, matchFlag, "parameter type error");
186 
187     AppExecFwk::ElementName elementName;
188     ASSERT_AND_THROW_PARAM_ERROR(
189         env, ParseElementName(env, elementName, argv[ARR_INDEX_ZERO]), "element name param error");
190     EDMLOGD("resetFactory: elementName.bundlename %{public}s, abilityname:%{public}s",
191         elementName.GetBundleName().c_str(), elementName.GetAbilityName().c_str());
192     OperateDeviceParam param;
193     ASSERT_AND_THROW_PARAM_ERROR(env, ParseString(env, param.operate, argv[ARR_INDEX_ONE]), "operate param error");
194     if (argc > ARGS_SIZE_TWO) {
195         ASSERT_AND_THROW_PARAM_ERROR(env, ParseString(env, param.addition, argv[ARR_INDEX_TWO]),
196             "addition param error");
197     }
198 #ifdef OS_ACCOUNT_EDM_ENABLE
199     AccountSA::OsAccountManager::GetOsAccountLocalIdFromProcess(param.userId);
200     EDMLOGI("NAPI_lockScreen called userId :%{public}d", param.userId);
201 #else
202     EDMLOGI("NAPI_lockScreen don't call userId");
203 #endif
204     int32_t ret = DeviceControlProxy::GetDeviceControlProxy()->OperateDevice(elementName, param);
205     if (FAILED(ret)) {
206         napi_throw(env, CreateError(env, ret));
207     }
208     return nullptr;
209 }
210 
211 static napi_module g_deviceControlModule = {
212     .nm_version = 1,
213     .nm_flags = 0,
214     .nm_filename = nullptr,
215     .nm_register_func = DeviceControlAddon::Init,
216     .nm_modname = "enterprise.deviceControl",
217     .nm_priv = ((void *)0),
218     .reserved = { 0 },
219 };
220 
DeviceControlManagerRegister()221 extern "C" __attribute__((constructor)) void DeviceControlManagerRegister()
222 {
223     napi_module_register(&g_deviceControlModule);
224 }
225