• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 <string>
16 #include <dlfcn.h>
17 #include "msdp_manager.h"
18 #include "message_parcel.h"
19 #include "extension_ability_manager.cpp"
20 
21 namespace OHOS {
22 namespace Accessibility {
23 constexpr uint32_t FEATURE_USER_PREFERENCE_APP = 10;
24 constexpr uint32_t FEATURE_USER_FACE_ANGLE = 11;
25 constexpr uint32_t FEATURE_TIME_TUNNEL = 14;
26 constexpr uint32_t FEATURE_ENV_SOUND = 17;
27 constexpr int32_t MAX_APP_SIZE = 50;
28 const char* USER_STATUS_SO_NAME = "libuser_status_client.z.so";
29 const char* MSDP_SUBSCRIBE_CALLBACK_FUNC_NAME = "SubscribeCallback";
30 const char* MSDP_SUBSCRIBE_FUNC_NAME = "Subscribe";
31 const char* MSDP_UNSUBSCRIBE_FUNC_NAME = "Unsubscribe";
32 const std::string KEY_USER_STATUS_PREFERENCE_APP = "userStatusPreferenceApp";
33 const std::string KEY_FACE_ANGLE_STATUS = "userFaceAngleStatus";
34 const std::string TIME_TUNNEL_STATUS = "timeTunnelStatus";
35 
36 typedef int32_t (*SubscribeCallbackFunc)(uint32_t feature, UserStatusDataCallbackFunc &callback);
37 typedef void (*SubscribeFunc)(uint32_t feature);
38 typedef void (*UnsubscribeFunc)(uint32_t feature);
39 
UserStatusData()40 UserStatusData::UserStatusData() {}
41 
~UserStatusData()42 UserStatusData::~UserStatusData() {}
43 
GetFeature() const44 uint32_t UserStatusData::GetFeature() const
45 {
46     return feature_;
47 }
48 
SetFeature(uint32_t feature)49 void UserStatusData::SetFeature(uint32_t feature)
50 {
51     feature_ = feature;
52 }
53 
GetStatus() const54 std::string UserStatusData::GetStatus() const
55 {
56     return status_;
57 }
58 
SetStatus(const std::string & status)59 void UserStatusData::SetStatus(const std::string &status)
60 {
61     status_ = status;
62 }
63 
GetResult() const64 int32_t UserStatusData::GetResult() const
65 {
66     return result_;
67 }
68 
SetResult(int32_t result)69 void UserStatusData::SetResult(int32_t result)
70 {
71     result_ = result;
72 }
73 
GetErrorCode() const74 int32_t UserStatusData::GetErrorCode() const
75 {
76     return errorCode_;
77 }
78 
SetErrorCode(int32_t errorCode)79 void UserStatusData::SetErrorCode(int32_t errorCode)
80 {
81     errorCode_ = errorCode;
82 }
83 
GetResultApps() const84 std::vector<std::string> UserStatusData::GetResultApps() const
85 {
86     return resultApps_;
87 }
88 
SetResultApps(const std::vector<std::string> resultApps)89 void UserStatusData::SetResultApps(const std::vector<std::string> resultApps)
90 {
91     resultApps_ = resultApps;
92 }
93 
GetHpeDeviceId() const94 std::string UserStatusData::GetHpeDeviceId() const
95 {
96     return hpeDeviceId_;
97 }
98 
SetHpeDeviceId(const std::string & hpeDeviceId)99 void UserStatusData::SetHpeDeviceId(const std::string &hpeDeviceId)
100 {
101     hpeDeviceId_ = hpeDeviceId;
102 }
103 
GetCoordinateX() const104 int32_t UserStatusData::GetCoordinateX() const
105 {
106     return coordinateX_;
107 }
108 
SetCoordinateX(int32_t coordinateX)109 void UserStatusData::SetCoordinateX(int32_t coordinateX)
110 {
111     coordinateX_ = coordinateX;
112 }
113 
GetCoordinateY() const114 int32_t UserStatusData::GetCoordinateY() const
115 {
116     return coordinateY_;
117 }
118 
SetCoordinateY(int32_t coordinateY)119 void UserStatusData::SetCoordinateY(int32_t coordinateY)
120 {
121     coordinateY_ = coordinateY;
122 }
123 
GetPointerAction() const124 int32_t UserStatusData::GetPointerAction() const
125 {
126     return pointerAction_;
127 }
128 
SetPointerAction(int32_t pointerAction)129 void UserStatusData::SetPointerAction(int32_t pointerAction)
130 {
131     pointerAction_ = pointerAction;
132 }
133 
GetOrientation() const134 int32_t UserStatusData::GetOrientation() const
135 {
136     return orientation_;
137 }
138 
SetOrientation(int32_t orientation)139 void UserStatusData::SetOrientation(int32_t orientation)
140 {
141     orientation_ = orientation;
142 }
143 
Dump()144 std::string UserStatusData::Dump()
145 {
146     std::string dumpInfo = DumpBaseData();
147 
148     if (feature_ == FEATURE_USER_PREFERENCE_APP) {
149         dumpInfo.append(", resultApps_=");
150         dumpInfo.append(std::to_string(resultApps_.size()));
151         for (const auto& app : resultApps_) {
152             dumpInfo.append(", ");
153             dumpInfo.append(app.c_str());
154         }
155     }
156     return dumpInfo;
157 }
158 
DumpBaseData()159 std::string UserStatusData::DumpBaseData()
160 {
161     std::ostringstream dumpInfo;
162     dumpInfo << "feature=" << static_cast<uint32_t>(feature_)
163              << ", status=" << status_
164              << ", result=" << result_
165              << ", errorCode_=" << errorCode_;
166     if (feature_ == FEATURE_TIME_TUNNEL) {
167         dumpInfo << ", coordinateX=" << coordinateX_
168                  << ", coordinateY=" << coordinateY_
169                  << ", pointerAction=" << pointerAction_
170                  << ", orientation=" << orientation_;
171     }
172     return dumpInfo.str();
173 }
174 
Unmarshalling(Parcel & parcel)175 std::shared_ptr<UserStatusData> UserStatusData::Unmarshalling(Parcel &parcel)
176 {
177     auto statusData = std::make_shared<UserStatusData>();
178     if (!statusData->ReadFromParcel(parcel)) {
179         HILOG_ERROR("read from parcel failed");
180         return nullptr;
181     }
182     return statusData;
183 }
184 
UnMarshallingFeature(Parcel & parcel)185 int32_t UserStatusData::UnMarshallingFeature(Parcel &parcel)
186 {
187     MessageParcel& msgParcel = static_cast<MessageParcel&>(parcel);
188     msgParcel.PrintBuffer(__FUNCTION__, __LINE__);
189     return parcel.ReadUint32();
190 }
191 
Marshalling(Parcel & parcel) const192 bool UserStatusData::Marshalling(Parcel &parcel) const
193 {
194     if (!parcel.WriteUint32(feature_)) {
195         HILOG_ERROR("write features_ is failed");
196         return false;
197     }
198     if (!parcel.WriteInt32(result_)) {
199         HILOG_ERROR("write result_ is failed");
200         return false;
201     }
202     if (!parcel.WriteInt32(errorCode_)) {
203         HILOG_ERROR("write errorCode_ is failed");
204         return false;
205     }
206     if (!parcel.WriteString(status_)) {
207         HILOG_ERROR("write status_ is failed");
208         return false;
209     }
210 
211     if (feature_ == FEATURE_USER_PREFERENCE_APP) {
212         int32_t appSize = static_cast<int32_t>(resultApps_.size());
213         if (appSize > MAX_APP_SIZE) {
214             appSize = MAX_APP_SIZE;
215         }
216         if (!parcel.WriteInt32(appSize)) {
217             HILOG_ERROR("write resultApps_ size is failed");
218             return false;
219         }
220         for (int32_t i = 0; i < appSize; ++i) {
221             if (!parcel.WriteString(resultApps_[i])) {
222                 HILOG_ERROR("write resultApps_ item is failed");
223                 return false;
224             }
225         }
226     }
227     if (feature_ == FEATURE_USER_FACE_ANGLE) {
228         if (!parcel.WriteString(hpeDeviceId_)) {
229             HILOG_ERROR("write hpeDeviceId_ is failed");
230             return false;
231         }
232     }
233     if (feature_ == FEATURE_TIME_TUNNEL) {
234         if (!WriteTimeTunnelData(parcel)) {
235             return false;
236         }
237     }
238     return true;
239 }
240 
WriteTimeTunnelData(Parcel & parcel) const241 bool UserStatusData::WriteTimeTunnelData(Parcel &parcel) const
242 {
243     if (!parcel.WriteInt32(coordinateX_)) {
244         HILOG_ERROR("write coordinateX_ is failed");
245         return false;
246     }
247     if (!parcel.WriteInt32(coordinateY_)) {
248         HILOG_ERROR("write coordinateY_ is failed");
249         return false;
250     }
251     if (!parcel.WriteInt32(pointerAction_)) {
252         HILOG_ERROR("write pointerAction_ is failed");
253         return false;
254     }
255     if (!parcel.WriteInt32(orientation_)) {
256         HILOG_ERROR("write orientation_ is failed");
257         return false;
258     }
259 
260     return true;
261 }
262 
ReadFromParcel(Parcel & parcel)263 bool UserStatusData::ReadFromParcel(Parcel &parcel)
264 {
265     result_ = parcel.ReadInt32();
266     errorCode_ = parcel.ReadInt32();
267     status_ = parcel.ReadString();
268     if (status_.empty()) {
269         HILOG_ERROR("Read status_ failed");
270         return false;
271     }
272 
273     if (status_ == KEY_USER_STATUS_PREFERENCE_APP) {
274         int32_t size = parcel.ReadInt32();
275         if (size > MAX_APP_SIZE || size < 0) {
276             HILOG_ERROR("Invalid app size: %{public}d", size);
277             return false;
278         }
279         std::string bundleName;
280         for (int32_t i = 0; i < size; ++i) {
281             bundleName = parcel.ReadString();
282             if (bundleName.empty()) {
283                 HILOG_ERROR("Read bundle name failed, feature: %{public}d, result: %{public}d, errorCode: %{public}d",
284                     feature_, result_, errorCode_);
285                 return false;
286             }
287             resultApps_.push_back(bundleName);
288         }
289     }
290     if (status_ == KEY_FACE_ANGLE_STATUS) {
291         hpeDeviceId_ = parcel.ReadString();
292     }
293     if (status_ == TIME_TUNNEL_STATUS) {
294         coordinateX_ = parcel.ReadInt32();
295         coordinateY_ = parcel.ReadInt32();
296         pointerAction_ = parcel.ReadInt32();
297         orientation_ = parcel.ReadInt32();
298     }
299     return true;
300 }
301 
MsdpManager()302 MsdpManager::MsdpManager()
303 {
304     handle_ = dlopen(USER_STATUS_SO_NAME, RTLD_NOW);
305     if (handle_ == nullptr) {
306         HILOG_ERROR("user status dlopen failed : %{public}s", dlerror());
307     }
308 }
309 
~MsdpManager()310 MsdpManager::~MsdpManager()
311 {
312     if (handle_ != nullptr) {
313         dlclose(handle_);
314     }
315 }
316 
GetInstance()317 MsdpManager& MsdpManager::GetInstance()
318 {
319     static MsdpManager instance;
320     return instance;
321 }
322 
323 
SubscribeVoiceRecognition()324 int32_t MsdpManager::SubscribeVoiceRecognition()
325 {
326     HILOG_INFO();
327     if (handle_ == nullptr) {
328         HILOG_ERROR("user status dlopen failed : %{public}s", dlerror());
329         return ERR_INVALID_STATE;
330     }
331     SubscribeCallbackFunc subscribeCallbackFunc = reinterpret_cast<SubscribeCallbackFunc>(dlsym(handle_,
332         MSDP_SUBSCRIBE_CALLBACK_FUNC_NAME));
333     if (subscribeCallbackFunc == nullptr) {
334         HILOG_ERROR("dlsym subscribeCallbackFunc failed : %{public}s", dlerror());
335         return ERR_INVALID_STATE;
336     }
337     SubscribeFunc subscribeFunc = reinterpret_cast<SubscribeFunc>(dlsym(handle_, MSDP_SUBSCRIBE_FUNC_NAME));
338     if (subscribeFunc == nullptr) {
339         HILOG_ERROR("dlsym subscribeFunc failed : %{public}s", dlerror());
340         return ERR_INVALID_STATE;
341     }
342     std::function<void(int32_t, std::shared_ptr<UserStatusData>)> func = [ = ](
343         int32_t callbackId, std::shared_ptr<UserStatusData> userStatusData) {
344         HILOG_INFO("voice recognition callback, Id: %{public}d, GetFeature: %{public}d, GetResult: %{public}d",
345             callbackId, userStatusData->GetFeature(), userStatusData->GetResult());
346 
347         ExtensionAbilityManager::GetInstance().VoiceRecognize(userStatusData->GetResult());
348     };
349     int32_t ret = subscribeCallbackFunc(FEATURE_ENV_SOUND, func);
350     subscribeFunc(FEATURE_ENV_SOUND);
351     HILOG_INFO("userstatusClient.SubscribeCallback RET: %{public}d", ret);
352     return ret;
353 }
354 
UnSubscribeVoiceRecognition()355 void MsdpManager::UnSubscribeVoiceRecognition()
356 {
357     HILOG_INFO();
358     if (handle_ == nullptr) {
359         HILOG_ERROR("user status dlopen failed : %{public}s", dlerror());
360         return;
361     }
362     UnsubscribeFunc unsubscribeFunc = reinterpret_cast<UnsubscribeFunc>(dlsym(handle_, MSDP_UNSUBSCRIBE_FUNC_NAME));
363     if (unsubscribeFunc == nullptr) {
364         HILOG_ERROR("dlsym unsubscribeFunc failed : %{public}s", dlerror());
365         return;
366     }
367     unsubscribeFunc(FEATURE_ENV_SOUND);
368     HILOG_INFO("userstatusClient.unsubscribeFunc");
369 }
370 } // namespace Accessibility
371 } // namespace OHOS
372