1 /*
2  * Copyright (c) 2022-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 #include "device_info_addon.h"
16 
17 #include "edm_ipc_interface_code.h"
18 #include "edm_log.h"
19 
20 using namespace OHOS::EDM;
21 
Init(napi_env env,napi_value exports)22 napi_value DeviceInfoAddon::Init(napi_env env, napi_value exports)
23 {
24     napi_property_descriptor property[] = {
25         DECLARE_NAPI_FUNCTION("getDeviceSerial", GetDeviceSerial),
26         DECLARE_NAPI_FUNCTION("getDisplayVersion", GetDisplayVersion),
27         DECLARE_NAPI_FUNCTION("getDeviceName", GetDeviceName),
28         DECLARE_NAPI_FUNCTION("getDeviceInfo", GetDeviceInfoSync),
29     };
30     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(property) / sizeof(property[0]), property));
31     return exports;
32 }
33 
GetDeviceSerial(napi_env env,napi_callback_info info)34 napi_value DeviceInfoAddon::GetDeviceSerial(napi_env env, napi_callback_info info)
35 {
36     EDMLOGI("NAPI_GetDeviceSerial called");
37     return GetDeviceInfo(env, info, EdmInterfaceCode::GET_DEVICE_SERIAL);
38 }
39 
GetDisplayVersion(napi_env env,napi_callback_info info)40 napi_value DeviceInfoAddon::GetDisplayVersion(napi_env env, napi_callback_info info)
41 {
42     EDMLOGI("NAPI_GetDisplayVersion called");
43     return GetDeviceInfo(env, info, EdmInterfaceCode::GET_DISPLAY_VERSION);
44 }
45 
GetDeviceName(napi_env env,napi_callback_info info)46 napi_value DeviceInfoAddon::GetDeviceName(napi_env env, napi_callback_info info)
47 {
48     EDMLOGI("NAPI_GetDeviceName called");
49     return GetDeviceInfo(env, info, EdmInterfaceCode::GET_DEVICE_NAME);
50 }
51 
GetDeviceInfoSync(napi_env env,napi_callback_info info)52 napi_value DeviceInfoAddon::GetDeviceInfoSync(napi_env env, napi_callback_info info)
53 {
54     EDMLOGI("NAPI_GetDeviceInfoSync called");
55     size_t argc = ARGS_SIZE_TWO;
56     napi_value argv[ARGS_SIZE_TWO] = {nullptr};
57     napi_value thisArg = nullptr;
58     void *data = nullptr;
59     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
60     ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_TWO, "parameter count error");
61     bool matchFlag = MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object) &&
62         MatchValueType(env, argv[ARR_INDEX_ONE], napi_string);
63     ASSERT_AND_THROW_PARAM_ERROR(env, matchFlag, "parameter type error");
64 
65     AppExecFwk::ElementName elementName;
66     ASSERT_AND_THROW_PARAM_ERROR(env, ParseElementName(env, elementName, argv[ARR_INDEX_ZERO]),
67         "element name param error");
68     EDMLOGD(
69         "GetDeviceInfo: elementName.bundlename %{public}s, abilityname:%{public}s",
70         elementName.GetBundleName().c_str(), elementName.GetAbilityName().c_str());
71     std::string label;
72     ASSERT_AND_THROW_PARAM_ERROR(env, ParseString(env, label, argv[ARR_INDEX_ONE]), "label param error");
73 
74     std::string deviceInfo;
75     int32_t ret = DeviceInfoProxy::GetDeviceInfoProxy()->GetDeviceInfoSync(elementName, label, deviceInfo);
76     if (FAILED(ret)) {
77         napi_throw(env, CreateError(env, ret));
78         return nullptr;
79     }
80     napi_value napiInfo;
81     napi_create_string_utf8(env, deviceInfo.c_str(), NAPI_AUTO_LENGTH, &napiInfo);
82     return napiInfo;
83 }
84 
GetDeviceInfo(napi_env env,napi_callback_info info,int code)85 napi_value DeviceInfoAddon::GetDeviceInfo(napi_env env, napi_callback_info info, int code)
86 {
87     size_t argc = ARGS_SIZE_TWO;
88     napi_value argv[ARGS_SIZE_TWO] = {nullptr};
89     napi_value thisArg = nullptr;
90     void *data = nullptr;
91     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
92     ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_ONE, "parameter count error");
93     bool matchFlag = MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object);
94     if (argc > ARGS_SIZE_ONE) {
95         matchFlag = matchFlag && MatchValueType(env, argv[ARR_INDEX_ONE], napi_function);
96     }
97     ASSERT_AND_THROW_PARAM_ERROR(env, matchFlag, "parameter type error");
98     auto asyncCallbackInfo = new (std::nothrow) AsyncGetDeviceInfoCallbackInfo();
99     if (asyncCallbackInfo == nullptr) {
100         return nullptr;
101     }
102     std::unique_ptr<AsyncGetDeviceInfoCallbackInfo> callbackPtr{asyncCallbackInfo};
103     bool ret = ParseElementName(env, asyncCallbackInfo->elementName, argv[ARR_INDEX_ZERO]);
104     ASSERT_AND_THROW_PARAM_ERROR(env, ret, "element name param error");
105     EDMLOGD(
106         "GetDeviceInfo: asyncCallbackInfo->elementName.bundlename %{public}s, "
107         "asyncCallbackInfo->abilityname:%{public}s",
108         asyncCallbackInfo->elementName.GetBundleName().c_str(),
109         asyncCallbackInfo->elementName.GetAbilityName().c_str());
110     if (argc > ARGS_SIZE_ONE) {
111         EDMLOGD("NAPI_GetDeviceInfo argc == ARGS_SIZE_TWO");
112         napi_create_reference(env, argv[ARR_INDEX_ONE], NAPI_RETURN_ONE, &asyncCallbackInfo->callback);
113     }
114     asyncCallbackInfo->policyCode = code;
115     napi_value asyncWorkReturn =
116         HandleAsyncWork(env, asyncCallbackInfo, "GetDeviceInfo", NativeGetDeviceInfo, NativeStringCallbackComplete);
117     callbackPtr.release();
118     return asyncWorkReturn;
119 }
120 
NativeGetDeviceInfo(napi_env env,void * data)121 void DeviceInfoAddon::NativeGetDeviceInfo(napi_env env, void *data)
122 {
123     EDMLOGI("NAPI_NativeGetDeviceInfo called");
124     if (data == nullptr) {
125         EDMLOGE("data is nullptr");
126         return;
127     }
128     AsyncGetDeviceInfoCallbackInfo *asyncCallbackInfo = static_cast<AsyncGetDeviceInfoCallbackInfo *>(data);
129     auto deviceInfoProxy = DeviceInfoProxy::GetDeviceInfoProxy();
130     if (deviceInfoProxy == nullptr) {
131         EDMLOGE("can not get DeviceInfoProxy");
132         return;
133     }
134     switch (asyncCallbackInfo->policyCode) {
135         case static_cast<int32_t>(EdmInterfaceCode::GET_DEVICE_SERIAL):
136             asyncCallbackInfo->ret =
137                 deviceInfoProxy->GetDeviceSerial(asyncCallbackInfo->elementName, asyncCallbackInfo->stringRet);
138             break;
139         case static_cast<int32_t>(EdmInterfaceCode::GET_DISPLAY_VERSION):
140             asyncCallbackInfo->ret =
141                 deviceInfoProxy->GetDisplayVersion(asyncCallbackInfo->elementName, asyncCallbackInfo->stringRet);
142             break;
143         case static_cast<int32_t>(EdmInterfaceCode::GET_DEVICE_NAME):
144             asyncCallbackInfo->ret =
145                 deviceInfoProxy->GetDeviceName(asyncCallbackInfo->elementName, asyncCallbackInfo->stringRet);
146             break;
147         default:
148             asyncCallbackInfo->ret = EdmReturnErrCode::INTERFACE_UNSUPPORTED;
149             EDMLOGE("NAPI_GetDeviceInfo failed");
150             return;
151     }
152 }
153 
154 static napi_module g_deviceInfoModule = {
155     .nm_version = 1,
156     .nm_flags = 0,
157     .nm_filename = nullptr,
158     .nm_register_func = DeviceInfoAddon::Init,
159     .nm_modname = "enterprise.deviceInfo",
160     .nm_priv = ((void *)0),
161     .reserved = {0},
162 };
163 
DeviceInfoRegister()164 extern "C" __attribute__((constructor)) void DeviceInfoRegister()
165 {
166     napi_module_register(&g_deviceInfoModule);
167 }