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