• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2023 Unionman Technology 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 <cstdio>
16 #include <cstring>
17 #include "iremote_proxy.h"
18 #include "iremote_object.h"
19 #include "if_system_ability_manager.h"
20 #include "iservice_registry.h"
21 #include "system_ability_definition.h"
22 #include "system_ability_definition.h"
23 #include "napi/native_api.h"
24 #include "napi/native_node_api.h"
25 #include "hilog/log.h"
26 
27 #define ZLOGE(LOG_LABEL, fmt, args...)                                                                                 \
28     (void)OHOS::HiviewDFX::HiLog::Error(LOG_LABEL, "%{public}d: " fmt, __LINE__, ##args)
29 #define ZLOGW(LOG_LABEL, fmt, args...)                                                                                 \
30     (void)OHOS::HiviewDFX::HiLog::Warn(LOG_LABEL, "%{public}d: " fmt, __LINE__, ##args)
31 #define ZLOGI(LOG_LABEL, fmt, args...)                                                                                 \
32     (void)OHOS::HiviewDFX::HiLog::Info(LOG_LABEL, "%{public}d: " fmt, __LINE__, ##args)
33 #define ZLOGD(LOG_LABEL, fmt, args...)                                                                                 \
34     (void)OHOS::HiviewDFX::HiLog::Debug(LOG_LABEL, "%{public}d: " fmt, __LINE__, ##args)
35 
36 using namespace OHOS;
37 // 定义消息码
38 const int ABILITY_SHELL = 4;
39 static HiviewDFX::HiLogLabel LABEL = {LOG_APP, 0x0002, "ShellServer"};
40 class IShellAbility : public IRemoteBroker {
41 public:
42     // DECLARE_INTERFACE_DESCRIPTOR是必需的,入参需使用std::u16string;
43     DECLARE_INTERFACE_DESCRIPTOR(u"shell.Ability");
44     virtual std::string executeCommand(const std::string &dummy) = 0; // 定义业务函数
45 };
46 
47 class ShellAbilityProxy : public IRemoteProxy<IShellAbility> {
48 public:
49     explicit ShellAbilityProxy(const sptr<IRemoteObject> &impl);
50     std::string executeCommand(const std::string &dummy) override;
51 
52 private:
53     static inline BrokerDelegator<ShellAbilityProxy> delegator_; // 方便后续使用iface_cast宏
54 };
55 
ShellAbilityProxy(const sptr<IRemoteObject> & impl)56 ShellAbilityProxy::ShellAbilityProxy(const sptr<IRemoteObject> &impl) : IRemoteProxy<IShellAbility>(impl)
57 {
58 }
59 
executeCommand(const std::string & dummy)60 std::string ShellAbilityProxy::executeCommand(const std::string &dummy)
61 {
62     MessageOption option;
63     MessageParcel dataParcel, replyParcel;
64     dataParcel.WriteString(dummy);
65     int error = Remote()->SendRequest(ABILITY_SHELL, dataParcel, replyParcel, option);
66     std::string result = (error == ERR_NONE) ? replyParcel.ReadString() : "-1";
67 
68     return result;
69 }
70 
EexecuteCommand(const std::string data)71 static std::string EexecuteCommand(const std::string data)
72 {
73     int ServerId = 1602;
74     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
75     if (samgr == nullptr) {
76         ZLOGW(LABEL, "erro samgr");
77         return "erro samgr";
78     } else {
79         ZLOGW(LABEL, "samgr  got");
80     }
81     sptr<IRemoteObject> remoteObject = samgr->GetSystemAbility(ServerId);
82     if (remoteObject != nullptr) {
83         ZLOGW(LABEL, "Got Shell Service object");
84     } else {
85         ZLOGW(LABEL, "Got Shell Service object error");
86         return "Got Shell Service object error";
87     }
88     sptr<IShellAbility> ShellAbility = iface_cast<IShellAbility>(remoteObject); // 使用iface_cast宏转换成具体类型
89 
90     std::string result = ShellAbility->executeCommand(data.c_str());
91     ZLOGW(LABEL, "client ipc shell serevr %{pubilc}s", result.c_str());
92     return result;
93 }
94 
95 #ifdef __cplusplus
96 extern "C" {
97 #endif
98 
EexecuteCommandnapi(napi_env env,napi_callback_info info)99 static napi_value EexecuteCommandnapi(napi_env env, napi_callback_info info)
100 {
101     // 期望从 ArkTS 侧获取的参数的数量,这里只接受一个参数
102     size_t argc = 1;
103     napi_value args[1] = {nullptr};
104     // 从 info 中获取从 ArkTS 侧传递过来的参数
105     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
106     // 将获取的 ArkTS 参数转换为 native 信息,这里将其转换为字符串类型
107     size_t strSize = 0;
108     napi_status status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &strSize);
109     char *strValue = new char[strSize + 1];
110     napi_status status1;
111     size_t strSize1 = 0;
112     status1 = napi_get_value_string_utf8(env, args[0], strValue, strSize + 1, &strSize1);
113     std::string path = std::string(strValue);
114     std::string result = EexecuteCommand(path.c_str());
115     napi_value ret;
116     napi_create_string_utf8(env, result.c_str(), result.length(), &ret);
117     return ret;
118 }
119 struct LedAddOnData {
120     napi_async_work asyncWork = nullptr; // 异步工作项
121     napi_deferred deferred = nullptr;    // 用于Promise的resolve、reject处理
122     napi_ref callback = nullptr;         // 回调函数
123     char *args[1] = {nullptr};
124     char *arr;    // 2个输入参数
125     char *result; // 业务逻辑处理结果(返回值)
126 };
127 // 业务逻辑处理函数。
completeCBForPromise(napi_env env,napi_status status,void * data)128 static void completeCBForPromise(napi_env env, napi_status status, void *data)
129 {
130     LedAddOnData *addOnData = (LedAddOnData *)data;
131     napi_value result = nullptr;
132     napi_create_string_utf8(env, addOnData->result, strlen(addOnData->result), &result);
133     napi_resolve_deferred(env, addOnData->deferred, result);
134     free(addOnData->args[0]);
135     free(addOnData->result);
136     // 删除napi_ref对象
137     if (addOnData->callback != nullptr) {
138         napi_delete_reference(env, addOnData->callback);
139     }
140     // 删除异步工作项
141     napi_delete_async_work(env, addOnData->asyncWork);
142     delete addOnData;
143 }
144 // 业务逻辑处理函数,由worker线程池调度执行。
ShellExecuteCB(napi_env env,void * data)145 static void ShellExecuteCB(napi_env env, void *data)
146 {
147     LedAddOnData *addOnData = (LedAddOnData *)data;
148     std::string result = EexecuteCommand(addOnData->args[0]);
149     addOnData->result = strdup(result.c_str()); // 使用 strdup 分配并复制字符串
150 }
EexecuteCommandNapiWithPromise(napi_env env,napi_callback_info info)151 static napi_value EexecuteCommandNapiWithPromise(napi_env env, napi_callback_info info)
152 {
153     // 期望从 ArkTS 侧获取的参数的数量,这里只接受一个参数
154     size_t argc = 1;
155     napi_value args[1] = {nullptr};
156     // 从 info 中获取从 ArkTS 侧传递过来的参数
157     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
158     // 将获取的 ArkTS 参数转换为 native 信息,这里将其转换为字符串类型
159     ZLOGW(LABEL, "EexecuteCommandNapiWithPromise got");
160     // 创建promise
161     napi_value promise = nullptr;
162     napi_deferred deferred = nullptr;
163     NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
164 
165     // 异步工作项上下文用户数据,传递到异步工作项的execute、complete之间传递数据
166     auto addonData = new LedAddOnData {
167         .asyncWork = nullptr,
168         .deferred = deferred,
169     };
170 
171     // 将被收到的参数传入
172     size_t strSize = 0;
173     napi_status status5 = napi_get_value_string_utf8(env, args[0], nullptr, 0, &strSize);
174     char *strValue = new char[strSize + 1];
175     napi_status status1;
176     size_t strSize1 = 0;
177     status1 = napi_get_value_string_utf8(env, args[0], strValue, strSize + 1, &strSize1);
178     addonData->args[0] = (char *)malloc(strlen(strValue) + 1);
179     addonData->args[0] = strdup(strValue); // 使用 strdup 分配并复制字符串
180     // 创建async work,创建成功后通过最后一个参数(addonData->asyncWork)返回asyncwork的handle
181     napi_value resourceName = nullptr;
182     napi_create_string_utf8(env, "ShellExecuteCB", NAPI_AUTO_LENGTH, &resourceName);
183     ZLOGW(LABEL, "EexecuteCommandNapiWithPromise working");
184     napi_create_async_work(env, nullptr, resourceName, ShellExecuteCB, completeCBForPromise, (void *)addonData,
185                            &addonData->asyncWork);
186     // 将刚创建的async work加到队列,由底层去调度执行
187     napi_queue_async_work(env, addonData->asyncWork);
188     // 返回promise
189     return promise;
190 }
191 /* 以上为实现异步计算接下来10s内温度,可设置为传参类型 */
192 
193 /*
194  * 注册接口
195  */
registerdeviceinfoApis(napi_env env,napi_value exports)196 static napi_value registerdeviceinfoApis(napi_env env, napi_value exports)
197 {
198     napi_property_descriptor desc[] = {
199         DECLARE_NAPI_FUNCTION("EexecuteCommandnapi", EexecuteCommandnapi),
200         DECLARE_NAPI_FUNCTION("EexecuteCommandNapiWithPromise", EexecuteCommandNapiWithPromise),
201     };
202     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
203     return exports;
204 }
205 /*
206  * 模块定义
207  */
208 static napi_module writeShellnapiModule = {
209     .nm_version = 1,
210     .nm_flags = 0,
211     .nm_filename = nullptr,
212     .nm_register_func = registerdeviceinfoApis,
213     .nm_modname = "ipcnapi", // 模块名
214     .nm_priv = ((void *)0),
215     .reserved = {0},
216 };
217 #ifdef __cplusplus
218 }
219 #endif
220 /*
221  * 注册模块
222  */
RegisterModule(void)223 extern "C" __attribute__((constructor)) void RegisterModule(void)
224 {
225     napi_module_register(&writeShellnapiModule); // 接口注册函数
226 }