• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "mmi_client.h"
16 
17 #include <cinttypes>
18 #include <condition_variable>
19 
20 #include "mmi_log.h"
21 #include "proto.h"
22 #include "util.h"
23 
24 #include "input_manager_impl.h"
25 #include "mmi_fd_listener.h"
26 #include "multimodal_event_handler.h"
27 #include "multimodal_input_connect_manager.h"
28 
29 namespace OHOS {
30 namespace MMI {
31 namespace {
32 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "MMIClient" };
33 const std::string THREAD_NAME = "mmi_EventHdr";
34 } // namespace
35 
36 using namespace AppExecFwk;
~MMIClient()37 MMIClient::~MMIClient()
38 {
39     CALL_DEBUG_ENTER;
40     Stop();
41 }
42 
SetEventHandler(EventHandlerPtr eventHandler)43 void MMIClient::SetEventHandler(EventHandlerPtr eventHandler)
44 {
45     CHKPV(eventHandler);
46     eventHandler_ = eventHandler;
47 }
48 
MarkIsEventHandlerChanged(EventHandlerPtr eventHandler)49 void MMIClient::MarkIsEventHandlerChanged(EventHandlerPtr eventHandler)
50 {
51     CHKPV(eventHandler);
52     CHKPV(eventHandler_);
53     auto currentRunner = eventHandler_->GetEventRunner();
54     CHKPV(currentRunner);
55     auto newRunner = eventHandler->GetEventRunner();
56     CHKPV(newRunner);
57     isEventHandlerChanged_ = false;
58     if (currentRunner->GetRunnerThreadName() != newRunner->GetRunnerThreadName()) {
59         isEventHandlerChanged_ = true;
60         MMI_HILOGD("Event handler changed");
61     }
62     MMI_HILOGD("Current handler name:%{public}s, New handler name:%{public}s",
63         currentRunner->GetRunnerThreadName().c_str(), newRunner->GetRunnerThreadName().c_str());
64 }
65 
SendMessage(const NetPacket & pkt) const66 bool MMIClient::SendMessage(const NetPacket &pkt) const
67 {
68     return SendMsg(pkt);
69 }
70 
GetCurrentConnectedStatus() const71 bool MMIClient::GetCurrentConnectedStatus() const
72 {
73     return GetConnectedStatus();
74 }
75 
GetSharedPtr()76 MMIClientPtr MMIClient::GetSharedPtr()
77 {
78     return shared_from_this();
79 }
80 
Start()81 bool MMIClient::Start()
82 {
83     CALL_DEBUG_ENTER;
84     msgHandler_.Init();
85     auto callback = std::bind(&ClientMsgHandler::OnMsgHandler, &msgHandler_,
86         std::placeholders::_1, std::placeholders::_2);
87     if (!StartClient(callback)) {
88         MMI_HILOGE("Client startup failed");
89         Stop();
90         return false;
91     }
92     if (!StartEventRunner()) {
93         MMI_HILOGE("Start runner failed");
94         Stop();
95         return false;
96     }
97     MMI_HILOGD("Client started successfully");
98     return true;
99 }
100 
StartEventRunner()101 bool MMIClient::StartEventRunner()
102 {
103     CALL_DEBUG_ENTER;
104     CHK_PID_AND_TID();
105     if (eventHandler_ == nullptr) {
106         auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
107         eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
108         MMI_HILOGI("Create event handler, thread name:%{public}s", runner->GetRunnerThreadName().c_str());
109     }
110 
111     if (isConnected_ && fd_ >= 0) {
112         if (isListening_) {
113             MMI_HILOGI("File fd is in listening");
114             return true;
115         }
116         if (!AddFdListener(fd_)) {
117             MMI_HILOGE("Add fd listener failed");
118             return false;
119         }
120     } else {
121         if (!eventHandler_->PostTask(std::bind(&MMIClient::OnReconnect, this), CLIENT_RECONNECT_COOLING_TIME)) {
122             MMI_HILOGE("Send reconnect event failed");
123             return false;
124         }
125     }
126     return true;
127 }
128 
AddFdListener(int32_t fd)129 bool MMIClient::AddFdListener(int32_t fd)
130 {
131     CALL_DEBUG_ENTER;
132     if (fd < 0) {
133         MMI_HILOGE("Invalid fd:%{public}d", fd);
134         return false;
135     }
136     CHKPF(eventHandler_);
137     auto fdListener = std::make_shared<MMIFdListener>(GetSharedPtr());
138     auto errCode = eventHandler_->AddFileDescriptorListener(fd, FILE_DESCRIPTOR_INPUT_EVENT, fdListener);
139     if (errCode != ERR_OK) {
140         MMI_HILOGE("Add fd listener failed,fd:%{public}d code:%{public}u str:%{public}s", fd, errCode,
141             GetErrorStr(errCode).c_str());
142         return false;
143     }
144     isRunning_ = true;
145     MMI_HILOGI("serverFd:%{public}d was listening,mask:%{public}u pid:%{public}d threadId:%{public}" PRIu64,
146         fd, FILE_DESCRIPTOR_INPUT_EVENT, GetPid(), GetThisThreadId());
147     return true;
148 }
149 
DelFdListener(int32_t fd)150 bool MMIClient::DelFdListener(int32_t fd)
151 {
152     CALL_DEBUG_ENTER;
153     CHKPF(eventHandler_);
154     if (fd >= 0) {
155         eventHandler_->RemoveFileDescriptorListener(fd);
156     } else {
157         MMI_HILOGE("Invalid fd:%{public}d", fd);
158     }
159     auto runner = eventHandler_->GetEventRunner();
160     CHKPF(runner);
161     if (runner->GetRunnerThreadName() == THREAD_NAME) {
162         eventHandler_->RemoveAllEvents();
163     }
164     isRunning_ = false;
165     return true;
166 }
167 
OnPacket(NetPacket & pkt)168 void MMIClient::OnPacket(NetPacket& pkt)
169 {
170     recvFun_(*this, pkt);
171 }
172 
OnRecvMsg(const char * buf,size_t size)173 void MMIClient::OnRecvMsg(const char *buf, size_t size)
174 {
175     CHKPV(buf);
176     if (size == 0 || size > MAX_PACKET_BUF_SIZE) {
177         MMI_HILOGE("Invalid input param size. size:%{public}zu", size);
178         return;
179     }
180     if (!circBuf_.Write(buf, size)) {
181         MMI_HILOGW("Write data failed. size:%{public}zu", size);
182     }
183     OnReadPackets(circBuf_, std::bind(&MMIClient::OnPacket, this, std::placeholders::_1));
184 }
185 
Reconnect()186 int32_t MMIClient::Reconnect()
187 {
188     return ConnectTo();
189 }
190 
OnReconnect()191 void MMIClient::OnReconnect()
192 {
193     if (Reconnect() == RET_OK) {
194         MMI_HILOGI("Reconnect ok");
195         return;
196     }
197     CHKPV(eventHandler_);
198     if (!eventHandler_->PostTask(std::bind(&MMIClient::OnReconnect, this), CLIENT_RECONNECT_COOLING_TIME)) {
199         MMI_HILOGE("Post reconnect event failed");
200     }
201 }
202 
OnDisconnect()203 void MMIClient::OnDisconnect()
204 {
205     OnDisconnected();
206 }
207 
RegisterConnectedFunction(ConnectCallback fun)208 void MMIClient::RegisterConnectedFunction(ConnectCallback fun)
209 {
210     funConnected_ = fun;
211 }
212 
RegisterDisconnectedFunction(ConnectCallback fun)213 void MMIClient::RegisterDisconnectedFunction(ConnectCallback fun)
214 {
215     funDisconnected_ = fun;
216 }
217 
OnDisconnected()218 void MMIClient::OnDisconnected()
219 {
220     CALL_DEBUG_ENTER;
221     MMI_HILOGI("Disconnected from server, fd:%{public}d", fd_);
222     isConnected_ = false;
223     isListening_ = false;
224     if (funDisconnected_) {
225         funDisconnected_(*this);
226     }
227     if (!DelFdListener(fd_)) {
228         MMI_HILOGE("Delete fd listener failed");
229     }
230     Close();
231     if (!isExit && eventHandler_ != nullptr) {
232         if (!eventHandler_->PostTask(std::bind(&MMIClient::OnReconnect, this), CLIENT_RECONNECT_COOLING_TIME)) {
233             MMI_HILOGE("Send reconnect event task failed");
234         }
235     }
236 }
237 
OnConnected()238 void MMIClient::OnConnected()
239 {
240     CALL_DEBUG_ENTER;
241     MMI_HILOGI("Connection to server succeeded, fd:%{public}d", GetFd());
242     isConnected_ = true;
243     msgHandler_.InitProcessedCallback();
244     if (funConnected_) {
245         funConnected_(*this);
246     }
247     if (!isExit && !isRunning_ && fd_ >= 0 && eventHandler_ != nullptr) {
248         if (!AddFdListener(fd_)) {
249             MMI_HILOGE("Add fd listener failed");
250             return;
251         }
252         isListening_ = true;
253     }
254 }
255 
Socket()256 int32_t MMIClient::Socket()
257 {
258     CALL_DEBUG_ENTER;
259     int32_t ret = MultimodalInputConnMgr->AllocSocketPair(IMultimodalInputConnect::CONNECT_MODULE_TYPE_MMI_CLIENT);
260     if (ret != RET_OK) {
261         MMI_HILOGE("Call AllocSocketPair return %{public}d", ret);
262         return RET_ERR;
263     }
264     fd_ = MultimodalInputConnMgr->GetClientSocketFdOfAllocedSocketPair();
265     if (fd_ == IMultimodalInputConnect::INVALID_SOCKET_FD) {
266         MMI_HILOGE("Call GetClientSocketFdOfAllocedSocketPair return invalid fd");
267     } else {
268         MMI_HILOGD("Call GetClientSocketFdOfAllocedSocketPair return fd:%{public}d", fd_);
269     }
270     return fd_;
271 }
272 
Stop()273 void MMIClient::Stop()
274 {
275     CALL_DEBUG_ENTER;
276     UDSClient::Stop();
277     if (eventHandler_ != nullptr) {
278         auto runner = eventHandler_->GetEventRunner();
279         CHKPV(runner);
280         if (runner->GetRunnerThreadName() == THREAD_NAME) {
281             runner->Stop();
282             eventHandler_->RemoveAllEvents();
283             eventHandler_->RemoveAllFileDescriptorListeners();
284         }
285     }
286 }
287 
GetErrorStr(ErrCode code) const288 const std::string& MMIClient::GetErrorStr(ErrCode code) const
289 {
290     const static std::string defErrString = "Unknown event handler error!";
291     const static std::map<ErrCode, std::string> mapStrings = {
292         {ERR_OK, "ERR_OK."},
293         {EVENT_HANDLER_ERR_INVALID_PARAM, "Invalid parameters"},
294         {EVENT_HANDLER_ERR_NO_EVENT_RUNNER, "Have not set event runner yet"},
295         {EVENT_HANDLER_ERR_FD_NOT_SUPPORT, "Not support to listen file descriptors"},
296         {EVENT_HANDLER_ERR_FD_ALREADY, "File descriptor is already in listening"},
297         {EVENT_HANDLER_ERR_FD_FAILED, "Failed to listen file descriptor"},
298         {EVENT_HANDLER_ERR_RUNNER_NO_PERMIT, "No permit to start or stop deposited event runner"},
299         {EVENT_HANDLER_ERR_RUNNER_ALREADY, "Event runner is already running"}
300     };
301     auto it = mapStrings.find(code);
302     if (it != mapStrings.end()) {
303         return it->second;
304     }
305     return defErrString;
306 }
307 } // namespace MMI
308 } // namespace OHOS
309