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_YOLO = 5;
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 yolo5s(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 yolo5s(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
yolo5s(const std::string & dummy)60 std::string ShellAbilityProxy::yolo5s(const std::string &dummy)
61 {
62 MessageOption option;
63 MessageParcel dataParcel;
64 MessageParcel replyParcel;
65 dataParcel.WriteString(dummy);
66 int error = Remote()->SendRequest(ABILITY_YOLO, dataParcel, replyParcel, option);
67 std::string result = (error == ERR_NONE) ? replyParcel.ReadString() : "-1";
68 return result;
69 }
70
Yolo5s(const std::string data)71 static std::string Yolo5s(const std::string data)
72 {
73 int serverId = 1602L;
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->yolo5s(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
99 struct LedAddOnData {
100 napi_async_work asyncWork = nullptr; // 异步工作项
101 napi_deferred deferred = nullptr; // 用于Promise的resolve、reject处理
102 napi_ref callback = nullptr; // 回调函数
103 char *args[1] = {nullptr};
104 char *arr; // 2个输入参数
105 char *result; // 业务逻辑处理结果(返回值)
106 };
107 // 业务逻辑处理函数。
completeCBForPromise(napi_env env,napi_status status,void * data)108 static void completeCBForPromise(napi_env env, napi_status status, void *data)
109 {
110 LedAddOnData *addOnData = (LedAddOnData *)data;
111 napi_value result = nullptr;
112 napi_create_string_utf8(env, addOnData->result, strlen(addOnData->result), &result);
113 napi_resolve_deferred(env, addOnData->deferred, result);
114 free(addOnData->args[0]);
115 free(addOnData->result);
116 // 删除napi_ref对象
117 if (addOnData->callback != nullptr) {
118 napi_delete_reference(env, addOnData->callback);
119 }
120 // 删除异步工作项
121 napi_delete_async_work(env, addOnData->asyncWork);
122 delete addOnData;
123 }
124 // 业务逻辑处理函数,由worker线程池调度执行。
ShellExecuteCB(napi_env env,void * data)125 static void ShellExecuteCB(napi_env env, void *data)
126 {
127 LedAddOnData *addOnData = (LedAddOnData *)data;
128 std::string result = Yolo5s(addOnData->args[0]);
129 addOnData->result = strdup(result.c_str()); // 使用 strdup 分配并复制字符串
130 }
Yolo5sWithPromise(napi_env env,napi_callback_info info)131 static napi_value Yolo5sWithPromise(napi_env env, napi_callback_info info)
132 {
133 // 期望从 ArkTS 侧获取的参数的数量,这里只接受一个参数
134 size_t argc = 1;
135 napi_value args[1] = {nullptr};
136 // 从 info 中获取从 ArkTS 侧传递过来的参数
137 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
138 // 将获取的 ArkTS 参数转换为 native 信息,这里将其转换为字符串类型
139 ZLOGW(LABEL, "Yolo5sWithPromise got");
140 // 创建promise
141 napi_value promise = nullptr;
142 napi_deferred deferred = nullptr;
143 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
144
145 // 异步工作项上下文用户数据,传递到异步工作项的execute、complete之间传递数据
146 auto addonData = new LedAddOnData {
147 .asyncWork = nullptr,
148 .deferred = deferred,
149 };
150
151 // 将被收到的参数传入
152 size_t strSize = 0;
153 napi_get_value_string_utf8(env, args[0], nullptr, 0, &strSize);
154 char *strValue = new char[strSize + 1];
155 napi_status status1;
156 size_t strSize1 = 0;
157 status1 = napi_get_value_string_utf8(env, args[0], strValue, strSize + 1, &strSize1);
158 addonData->args[0] = (char *)malloc(strlen(strValue) + 1);
159 addonData->args[0] = strdup(strValue); // 使用 strdup 分配并复制字符串
160 // 创建async work,创建成功后通过最后一个参数(addonData->asyncWork)返回asyncwork的handle
161 napi_value resourceName = nullptr;
162 napi_create_string_utf8(env, "ShellExecuteCB", NAPI_AUTO_LENGTH, &resourceName);
163 ZLOGW(LABEL, "Yolo5sWithPromise working");
164 napi_create_async_work(env, nullptr, resourceName, ShellExecuteCB, completeCBForPromise, (void *)addonData,
165 &addonData->asyncWork);
166 // 将刚创建的async work加到队列,由底层去调度执行
167 napi_queue_async_work(env, addonData->asyncWork);
168 // 返回promise
169 return promise;
170 }
171 /* 以上为实现异步计算接下来10s内温度,可设置为传参类型 */
172
173 /*
174 * 注册接口
175 */
registerdeviceinfoApis(napi_env env,napi_value exports)176 static napi_value registerdeviceinfoApis(napi_env env, napi_value exports)
177 {
178 napi_property_descriptor desc[] = {
179 DECLARE_NAPI_FUNCTION("Yolo5sWithPromise", Yolo5sWithPromise),
180 };
181 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
182 return exports;
183 }
184 /*
185 * 模块定义
186 */
187 static napi_module writeShellnapiModule = {
188 .nm_version = 1,
189 .nm_flags = 0,
190 .nm_filename = nullptr,
191 .nm_register_func = registerdeviceinfoApis,
192 .nm_modname = "yolo5snapi", // 模块名
193 .nm_priv = ((void *)0),
194 .reserved = {0},
195 };
196 #ifdef __cplusplus
197 }
198 #endif
199 /*
200 * 注册模块
201 */
RegisterModule(void)202 extern "C" __attribute__((constructor)) void RegisterModule(void)
203 {
204 napi_module_register(&writeShellnapiModule); // 接口注册函数
205 }
206