• 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 <cinttypes>
19 #include <sstream>
20 
21 #include <fcntl.h>
22 #include <sys/types.h>
23 #include <sys/un.h>
24 #include <unistd.h>
25 
26 #include "uds_socket.h"
27 #include "proto.h"
28 
29 namespace OHOS {
30 namespace MMI {
31 namespace {
32 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "UDSSession" };
33 constexpr int64_t INPUT_UI_TIMEOUT_TIME = 5 * 1000000;
34 const std::string FOUNDATION = "foundation";
35 } // namespace
36 
UDSSession(const std::string & programName,const int32_t moduleType,const int32_t fd,const int32_t uid,const int32_t pid)37 UDSSession::UDSSession(const std::string &programName, const int32_t moduleType, const int32_t fd,
38     const int32_t uid, const int32_t pid)
39     : programName_(programName),
40       moduleType_(moduleType),
41       fd_(fd),
42       uid_(uid),
43       pid_(pid)
44 {
45     UpdateDescript();
46     events_[ANR_DISPATCH] = {};
47     events_[ANR_MONITOR] = {};
48     isAnrProcess_[ANR_DISPATCH] = false;
49     isAnrProcess_[ANR_MONITOR] = false;
50 }
51 
SendMsg(const char * buf,size_t size) const52 bool UDSSession::SendMsg(const char *buf, size_t size) const
53 {
54     CHKPF(buf);
55     if ((size == 0) || (size > MAX_PACKET_BUF_SIZE)) {
56         MMI_HILOGE("buf size:%{public}zu", size);
57         return false;
58     }
59     if (fd_ < 0) {
60         MMI_HILOGE("The fd_ is less than 0");
61         return false;
62     }
63 
64     int32_t idx = 0;
65     int32_t retryCount = 0;
66     const int32_t bufSize = static_cast<int32_t>(size);
67     int32_t remSize = bufSize;
68     while (remSize > 0 && retryCount < SEND_RETRY_LIMIT) {
69         retryCount += 1;
70         auto count = send(fd_, &buf[idx], remSize, MSG_DONTWAIT | MSG_NOSIGNAL);
71         if (count < 0) {
72             if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) {
73                 MMI_HILOGW("Continue for errno EAGAIN|EINTR|EWOULDBLOCK, errno:%{public}d", errno);
74                 continue;
75             }
76             MMI_HILOGE("Send return failed,error:%{public}d fd:%{public}d", errno, fd_);
77             return false;
78         }
79         idx += count;
80         remSize -= count;
81         if (remSize > 0) {
82             MMI_HILOGW("Remsize:%{public}d", remSize);
83             usleep(SEND_RETRY_SLEEP_TIME);
84         }
85     }
86     if (retryCount >= SEND_RETRY_LIMIT || remSize != 0) {
87         MMI_HILOGE("Send too many times:%{public}d/%{public}d,size:%{public}d/%{public}d fd:%{public}d",
88             retryCount, SEND_RETRY_LIMIT, idx, bufSize, fd_);
89         return false;
90     }
91     return true;
92 }
93 
Close()94 void UDSSession::Close()
95 {
96     CALL_DEBUG_ENTER;
97     MMI_HILOGD("Enter fd_:%{public}d.", fd_);
98     if (fd_ >= 0) {
99         close(fd_);
100         fd_ = -1;
101         UpdateDescript();
102     }
103 }
104 
UpdateDescript()105 void UDSSession::UpdateDescript()
106 {
107     std::ostringstream oss;
108     oss << "fd = " << fd_
109         << ", programName = " << programName_
110         << ", moduleType = " << moduleType_
111         << ((fd_ < 0) ? ", closed" : ", opened")
112         << ", uid = " << uid_
113         << ", pid = " << pid_
114         << ", tokenType = " << tokenType_
115         << std::endl;
116     descript_ = oss.str().c_str();
117 }
118 
SendMsg(NetPacket & pkt) const119 bool UDSSession::SendMsg(NetPacket &pkt) const
120 {
121     if (pkt.ChkRWError()) {
122         MMI_HILOGE("Read and write status is error");
123         return false;
124     }
125     StreamBuffer buf;
126     pkt.MakeData(buf);
127     return SendMsg(buf.Data(), buf.Size());
128 }
129 
SaveANREvent(int32_t type,int32_t id,int64_t time,int32_t timerId)130 void UDSSession::SaveANREvent(int32_t type, int32_t id, int64_t time, int32_t timerId)
131 {
132     CALL_DEBUG_ENTER;
133     EventTime eventTime = { id, time, timerId };
134     auto iter = events_.find(type);
135     if (iter != events_.end()) {
136         iter->second.push_back(eventTime);
137     }
138 }
139 
GetTimerIds(int32_t type)140 std::vector<int32_t> UDSSession::GetTimerIds(int32_t type)
141 {
142     auto iter = events_.find(type);
143     if (iter == events_.end()) {
144         MMI_HILOGE("Current events have no event type:%{public}d", type);
145         return {};
146     }
147     std::vector<int32_t> timers;
148     for (auto &item : iter->second) {
149         timers.push_back(item.timerId);
150         item.timerId = -1;
151     }
152     events_[iter->first] = iter->second;
153     return timers;
154 }
155 
DelEvents(int32_t type,int32_t id)156 std::list<int32_t> UDSSession::DelEvents(int32_t type, int32_t id)
157 {
158     CALL_DEBUG_ENTER;
159     MMI_HILOGD("Delete events, anr type:%{public}d, id:%{public}d", type, id);
160     auto iter = events_.find(type);
161     if (iter == events_.end()) {
162         MMI_HILOGE("Current events have no event type:%{public}d", type);
163         return {};
164     }
165     auto &events = iter->second;
166     int32_t canDelEventCount = 0;
167     std::list<int32_t> timerIds;
168     for (auto &item : events) {
169         if (item.id > id) {
170             break;
171         }
172         MMI_HILOGD("Delete event, anr type:%{public}d, id:%{public}d, timerId:%{public}d", type, item.id, item.timerId);
173         timerIds.push_back(item.timerId);
174         ++canDelEventCount;
175     }
176     if (canDelEventCount == 0) {
177         MMI_HILOGW("Can not find event:%{public}d", id);
178         return timerIds;
179     }
180     events.erase(events.begin(), events.begin() + canDelEventCount);
181 
182     if (events.empty()) {
183         isAnrProcess_[type] = false;
184         return timerIds;
185     }
186     MMI_HILOGD("First event, anr type:%{public}d, id:%{public}d, timerId:%{public}d", type,
187         events.begin()->id, events.begin()->timerId);
188     int64_t endTime = 0;
189     if (!AddInt64(events.begin()->eventTime, INPUT_UI_TIMEOUT_TIME, endTime)) {
190         MMI_HILOGE("The addition of endTime overflows");
191         return timerIds;
192     }
193     auto currentTime = GetSysClockTime();
194     if (currentTime < endTime) {
195         isAnrProcess_[type] = false;
196     }
197     return timerIds;
198 }
199 
GetEarliestEventTime(int32_t type) const200 int64_t UDSSession::GetEarliestEventTime(int32_t type) const
201 {
202     CALL_DEBUG_ENTER;
203     auto iter = events_.find(type);
204     if (iter != events_.end()) {
205         if (iter->second.empty()) {
206             MMI_HILOGD("Current events is empty");
207             return 0;
208         }
209         return iter->second.begin()->eventTime;
210     }
211     return 0;
212 }
213 
IsEventQueueEmpty(int32_t type)214 bool UDSSession::IsEventQueueEmpty(int32_t type)
215 {
216     CALL_DEBUG_ENTER;
217     auto iter = events_.find(type);
218     return (iter == events_.end() || (iter->second.empty()));
219 }
220 } // namespace MMI
221 } // namespace OHOS