• 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 "uds_session.h"
17 
18 #include "hisysevent.h"
19 #include "uds_socket.h"
20 
21 #undef MMI_LOG_TAG
22 #define MMI_LOG_TAG "UDSSession"
23 
24 namespace OHOS {
25 namespace MMI {
26 namespace {
27 const std::string FOUNDATION = "foundation";
28 constexpr int32_t MINUTEINMILLIS { 60000 };
29 } // namespace
30 
UDSSession(const std::string & programName,const int32_t moduleType,const int32_t fd,const int32_t uid,const int32_t pid)31 UDSSession::UDSSession(const std::string &programName, const int32_t moduleType, const int32_t fd,
32     const int32_t uid, const int32_t pid)
33     : programName_(programName),
34       moduleType_(moduleType),
35       fd_(fd),
36       uid_(uid),
37       pid_(pid)
38 {
39     UpdateDescript();
40     events_[ANR_DISPATCH] = {};
41     events_[ANR_MONITOR] = {};
42     isAnrProcess_[ANR_DISPATCH] = false;
43     isAnrProcess_[ANR_MONITOR] = false;
44 }
45 
SendMsg(const char * buf,size_t size)46 bool UDSSession::SendMsg(const char *buf, size_t size)
47 {
48     CHKPF(buf);
49     if ((size == 0) || (size > MAX_PACKET_BUF_SIZE)) {
50         MMI_HILOGE("The buf size:%{public}zu", size);
51         return false;
52     }
53     if (fd_ < 0) {
54         MMI_HILOGE("The fd is less than 0");
55         return false;
56     }
57 
58     int32_t idx = 0;
59     int32_t retryCount = 0;
60     const int32_t bufSize = static_cast<int32_t>(size);
61     int32_t remSize = bufSize;
62     int32_t socketErrorNo = 0;
63     while (remSize > 0 && retryCount < SEND_RETRY_LIMIT) {
64         retryCount += 1;
65         auto count = send(fd_, &buf[idx], remSize, MSG_DONTWAIT | MSG_NOSIGNAL);
66         if (count < 0) {
67             if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) {
68                 socketErrorNo = errno;
69                 continue;
70             }
71             if (errno == ENOTSOCK) {
72                 MMI_HILOGE("Got ENOTSOCK error, turn the socket to invalid");
73                 invalidSocket_ = true;
74             }
75             MMI_HILOGE("Send return failed,error:%{public}d fd:%{public}d, pid:%{public}d", errno, fd_, pid_);
76             return false;
77         }
78         idx += count;
79         remSize -= count;
80         if (remSize > 0) {
81             MMI_HILOGW("Remsize:%{public}d", remSize);
82             usleep(SEND_RETRY_SLEEP_TIME);
83         }
84     }
85     if (socketErrorNo == EWOULDBLOCK) {
86         ReportSocketBufferFull();
87     }
88     if (retryCount >= SEND_RETRY_LIMIT || remSize != 0) {
89         MMI_HILOGE("Send too many times:%{public}d/%{public}d,size:%{public}d/%{public}d errno:%{public}d, "
90                    "fd:%{public}d, pid:%{public}d", retryCount, SEND_RETRY_LIMIT, idx, bufSize, errno, fd_, pid_);
91         return false;
92     }
93     return true;
94 }
95 
Close()96 void UDSSession::Close()
97 {
98     CALL_DEBUG_ENTER;
99     MMI_HILOGD("Enter fd:%{public}d", fd_);
100     if (fd_ >= 0) {
101         close(fd_);
102         fd_ = -1;
103         UpdateDescript();
104     }
105 }
106 
UpdateDescript()107 void UDSSession::UpdateDescript()
108 {
109     std::ostringstream oss;
110     oss << "fd = " << fd_
111         << ", programName = " << programName_
112         << ", moduleType = " << moduleType_
113         << ((fd_ < 0) ? ", closed" : ", opened")
114         << ", uid = " << uid_
115         << ", pid = " << pid_
116         << ", tokenType = " << tokenType_
117         << std::endl;
118     descript_ = oss.str().c_str();
119 }
120 
SendMsg(NetPacket & pkt)121 bool UDSSession::SendMsg(NetPacket &pkt)
122 {
123     if (pkt.ChkRWError()) {
124         MMI_HILOGE("Read and write status is error");
125         return false;
126     }
127     StreamBuffer buf;
128     pkt.MakeData(buf);
129     return SendMsg(buf.Data(), buf.Size());
130 }
131 
ReportSocketBufferFull()132 void UDSSession::ReportSocketBufferFull()
133 {
134     int64_t now = GetSysClockTime();
135     int currentPid = pid_;
136 
137     if ((now - lastReportTime_ < MINUTEINMILLIS) && (lastReportedPid_ == currentPid)) {
138         MMI_HILOGE("Duplicate escalation within one minute and same PID");
139         return;
140     }
141 
142     int32_t ret = HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::MULTI_MODAL_INPUT,
143         "INPUT_EVENT_SOCKET_TIMEOUT",
144         OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
145         "MSG",
146         "remote client buffer full, cant send msg",
147         "PROGRAM_NAME",
148         programName_,
149         "REMOTE_PID",
150         pid_);
151     if (ret != 0) {
152         MMI_HILOGE("Save input event socket timeout failed, ret:%{public}d", ret);
153     } else {
154         lastReportTime_ = now;
155         lastReportedPid_ = currentPid;
156     }
157 }
158 
SaveANREvent(int32_t type,int32_t id,int64_t time,int32_t timerId)159 void UDSSession::SaveANREvent(int32_t type, int32_t id, int64_t time, int32_t timerId)
160 {
161     CALL_DEBUG_ENTER;
162     EventTime eventTime = { id, time, timerId };
163     auto iter = events_.find(type);
164     if (iter != events_.end()) {
165         iter->second.push_back(eventTime);
166     }
167 }
168 
GetTimerIds(int32_t type)169 std::vector<int32_t> UDSSession::GetTimerIds(int32_t type)
170 {
171     auto iter = events_.find(type);
172     if (iter == events_.end()) {
173         MMI_HILOGE("Current events have no event type:%{public}d", type);
174         return {};
175     }
176     std::vector<int32_t> timers;
177     for (auto &item : iter->second) {
178         timers.push_back(item.timerId);
179         item.timerId = -1;
180     }
181     events_[iter->first] = iter->second;
182     return timers;
183 }
184 
DelEvents(int32_t type,int32_t id)185 std::list<int32_t> UDSSession::DelEvents(int32_t type, int32_t id)
186 {
187     CALL_DEBUG_ENTER;
188     MMI_HILOGD("Delete events, anr type:%{public}d, id:%{public}d, pid:%{public}d", type, id, pid_);
189     auto iter = events_.find(type);
190     if (iter == events_.end()) {
191         MMI_HILOGE("Current events have no event type:%{public}d pid:%{public}d", type, pid_);
192         return {};
193     }
194     auto &events = iter->second;
195     int32_t canDelEventCount = 0;
196     std::list<int32_t> timerIds;
197     for (auto &item : events) {
198         if (item.id > id) {
199             break;
200         }
201         MMI_HILOGD("Delete event, anr type:%{public}d, id:%{public}d, timerId:%{public}d", type, item.id, item.timerId);
202         timerIds.push_back(item.timerId);
203         ++canDelEventCount;
204     }
205     if (canDelEventCount == 0) {
206         MMI_HILOGD("Can not find event:%{public}d pid:%{public}d type:%{public}d", id, pid_, type);
207         return timerIds;
208     }
209     events.erase(events.begin(), events.begin() + canDelEventCount);
210 
211     if (events.empty()) {
212         isAnrProcess_[type] = false;
213         return timerIds;
214     }
215     MMI_HILOGD("First event, anr type:%{public}d, id:%{public}d, timerId:%{public}d, pid:%{public}d",
216         type, events.begin()->id, events.begin()->timerId, pid_);
217     int64_t endTime = 0;
218     if (!AddInt64(events.begin()->eventTime, INPUT_UI_TIMEOUT_TIME, endTime)) {
219         MMI_HILOGE("The addition of endTime overflows");
220         return timerIds;
221     }
222     auto currentTime = GetSysClockTime();
223     if (currentTime < endTime) {
224         isAnrProcess_[type] = false;
225     }
226     return timerIds;
227 }
228 
GetEarliestEventTime(int32_t type) const229 int64_t UDSSession::GetEarliestEventTime(int32_t type) const
230 {
231     CALL_DEBUG_ENTER;
232     auto iter = events_.find(type);
233     if (iter != events_.end()) {
234         if (iter->second.empty()) {
235             MMI_HILOGD("Current events is empty");
236             return 0;
237         }
238         return iter->second.begin()->eventTime;
239     }
240     return 0;
241 }
242 
IsEventQueueEmpty(int32_t type)243 bool UDSSession::IsEventQueueEmpty(int32_t type)
244 {
245     CALL_DEBUG_ENTER;
246     auto iter = events_.find(type);
247     return (iter == events_.end() || (iter->second.empty()));
248 }
249 } // namespace MMI
250 } // namespace OHOS