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