blob: 37691623441c4ad1c38c63e6a5080d5299536359 [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#include "pdx/service.h"
2
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08003#include <fcntl.h>
Alex Vakulenko4fe60582017-02-02 11:35:59 -08004#include <log/log.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08005#include <utils/misc.h>
6
7#include <algorithm>
8#include <cstdint>
9
10#include <pdx/trace.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080011
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080012namespace android {
13namespace pdx {
14
15std::shared_ptr<Channel> Channel::GetFromMessageInfo(const MessageInfo& info) {
16 return info.channel ? info.channel->shared_from_this()
17 : std::shared_ptr<Channel>();
18}
19
20Message::Message() : replied_(true) {}
21
22Message::Message(const MessageInfo& info)
23 : service_{Service::GetFromMessageInfo(info)},
24 channel_{Channel::GetFromMessageInfo(info)},
25 info_{info},
26 replied_{IsImpulse()} {
27 auto svc = service_.lock();
28 if (svc)
29 state_ = svc->endpoint()->AllocateMessageState();
30}
31
32// C++11 specifies the move semantics for shared_ptr but not weak_ptr. This
33// means we have to manually implement the desired move semantics for Message.
Chih-Hung Hsieh5bc849f2018-09-25 14:21:50 -070034Message::Message(Message&& other) noexcept { *this = std::move(other); }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080035
Chih-Hung Hsieh5bc849f2018-09-25 14:21:50 -070036Message& Message::operator=(Message&& other) noexcept {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080037 Destroy();
38 auto base = reinterpret_cast<std::uint8_t*>(&info_);
39 std::fill(&base[0], &base[sizeof(info_)], 0);
40 replied_ = true;
41 std::swap(service_, other.service_);
42 std::swap(channel_, other.channel_);
43 std::swap(info_, other.info_);
44 std::swap(state_, other.state_);
45 std::swap(replied_, other.replied_);
46 return *this;
47}
48
49Message::~Message() { Destroy(); }
50
51void Message::Destroy() {
52 auto svc = service_.lock();
53 if (svc) {
54 if (!replied_) {
55 ALOGE(
56 "ERROR: Service \"%s\" failed to reply to message: op=%d pid=%d "
57 "cid=%d\n",
58 svc->name_.c_str(), info_.op, info_.pid, info_.cid);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -070059 svc->DefaultHandleMessage(*this);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080060 }
61 svc->endpoint()->FreeMessageState(state_);
62 }
63 state_ = nullptr;
64 service_.reset();
65 channel_.reset();
66}
67
68const std::uint8_t* Message::ImpulseBegin() const {
69 return reinterpret_cast<const std::uint8_t*>(info_.impulse);
70}
71
72const std::uint8_t* Message::ImpulseEnd() const {
73 return ImpulseBegin() + (IsImpulse() ? GetSendLength() : 0);
74}
75
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -070076Status<size_t> Message::ReadVector(const struct iovec* vector,
77 size_t vector_length) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080078 PDX_TRACE_NAME("Message::ReadVector");
79 if (auto svc = service_.lock()) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -070080 return svc->endpoint()->ReadMessageData(this, vector, vector_length);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080081 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -070082 return ErrorStatus{ESHUTDOWN};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080083 }
84}
85
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -070086Status<void> Message::ReadVectorAll(const struct iovec* vector,
87 size_t vector_length) {
88 PDX_TRACE_NAME("Message::ReadVectorAll");
89 if (auto svc = service_.lock()) {
90 const auto status =
91 svc->endpoint()->ReadMessageData(this, vector, vector_length);
92 if (!status)
93 return status.error_status();
94 size_t size_to_read = 0;
95 for (size_t i = 0; i < vector_length; i++)
96 size_to_read += vector[i].iov_len;
97 if (status.get() < size_to_read)
98 return ErrorStatus{EIO};
99 return {};
100 } else {
101 return ErrorStatus{ESHUTDOWN};
102 }
103}
104
105Status<size_t> Message::Read(void* buffer, size_t length) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800106 PDX_TRACE_NAME("Message::Read");
107 if (auto svc = service_.lock()) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800108 const struct iovec vector = {buffer, length};
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700109 return svc->endpoint()->ReadMessageData(this, &vector, 1);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800110 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700111 return ErrorStatus{ESHUTDOWN};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800112 }
113}
114
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700115Status<size_t> Message::WriteVector(const struct iovec* vector,
116 size_t vector_length) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800117 PDX_TRACE_NAME("Message::WriteVector");
118 if (auto svc = service_.lock()) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700119 return svc->endpoint()->WriteMessageData(this, vector, vector_length);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800120 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700121 return ErrorStatus{ESHUTDOWN};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800122 }
123}
124
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700125Status<void> Message::WriteVectorAll(const struct iovec* vector,
126 size_t vector_length) {
127 PDX_TRACE_NAME("Message::WriteVector");
128 if (auto svc = service_.lock()) {
129 const auto status =
130 svc->endpoint()->WriteMessageData(this, vector, vector_length);
131 if (!status)
132 return status.error_status();
133 size_t size_to_write = 0;
134 for (size_t i = 0; i < vector_length; i++)
135 size_to_write += vector[i].iov_len;
136 if (status.get() < size_to_write)
137 return ErrorStatus{EIO};
138 return {};
139 } else {
140 return ErrorStatus{ESHUTDOWN};
141 }
142}
143
144Status<size_t> Message::Write(const void* buffer, size_t length) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800145 PDX_TRACE_NAME("Message::Write");
146 if (auto svc = service_.lock()) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800147 const struct iovec vector = {const_cast<void*>(buffer), length};
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700148 return svc->endpoint()->WriteMessageData(this, &vector, 1);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800149 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700150 return ErrorStatus{ESHUTDOWN};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800151 }
152}
153
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700154Status<FileReference> Message::PushFileHandle(const LocalHandle& handle) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800155 PDX_TRACE_NAME("Message::PushFileHandle");
156 if (auto svc = service_.lock()) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700157 return svc->endpoint()->PushFileHandle(this, handle);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800158 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700159 return ErrorStatus{ESHUTDOWN};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800160 }
161}
162
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700163Status<FileReference> Message::PushFileHandle(const BorrowedHandle& handle) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800164 PDX_TRACE_NAME("Message::PushFileHandle");
165 if (auto svc = service_.lock()) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700166 return svc->endpoint()->PushFileHandle(this, handle);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800167 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700168 return ErrorStatus{ESHUTDOWN};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800169 }
170}
171
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700172Status<FileReference> Message::PushFileHandle(const RemoteHandle& handle) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800173 PDX_TRACE_NAME("Message::PushFileHandle");
174 if (auto svc = service_.lock()) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700175 return svc->endpoint()->PushFileHandle(this, handle);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800176 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700177 return ErrorStatus{ESHUTDOWN};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800178 }
179}
180
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700181Status<ChannelReference> Message::PushChannelHandle(
182 const LocalChannelHandle& handle) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800183 PDX_TRACE_NAME("Message::PushChannelHandle");
184 if (auto svc = service_.lock()) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700185 return svc->endpoint()->PushChannelHandle(this, handle);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800186 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700187 return ErrorStatus{ESHUTDOWN};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800188 }
189}
190
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700191Status<ChannelReference> Message::PushChannelHandle(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800192 const BorrowedChannelHandle& handle) {
193 PDX_TRACE_NAME("Message::PushChannelHandle");
194 if (auto svc = service_.lock()) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700195 return svc->endpoint()->PushChannelHandle(this, handle);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800196 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700197 return ErrorStatus{ESHUTDOWN};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800198 }
199}
200
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700201Status<ChannelReference> Message::PushChannelHandle(
202 const RemoteChannelHandle& handle) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800203 PDX_TRACE_NAME("Message::PushChannelHandle");
204 if (auto svc = service_.lock()) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700205 return svc->endpoint()->PushChannelHandle(this, handle);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800206 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700207 return ErrorStatus{ESHUTDOWN};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800208 }
209}
210
211bool Message::GetFileHandle(FileReference ref, LocalHandle* handle) {
212 PDX_TRACE_NAME("Message::GetFileHandle");
213 auto svc = service_.lock();
214 if (!svc)
215 return false;
216
217 if (ref >= 0) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800218 *handle = svc->endpoint()->GetFileHandle(this, ref);
219 if (!handle->IsValid())
220 return false;
221 } else {
222 *handle = LocalHandle{ref};
223 }
224 return true;
225}
226
227bool Message::GetChannelHandle(ChannelReference ref,
228 LocalChannelHandle* handle) {
229 PDX_TRACE_NAME("Message::GetChannelHandle");
230 auto svc = service_.lock();
231 if (!svc)
232 return false;
233
234 if (ref >= 0) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800235 *handle = svc->endpoint()->GetChannelHandle(this, ref);
236 if (!handle->valid())
237 return false;
238 } else {
239 *handle = LocalChannelHandle{nullptr, ref};
240 }
241 return true;
242}
243
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700244Status<void> Message::Reply(int return_code) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800245 PDX_TRACE_NAME("Message::Reply");
246 auto svc = service_.lock();
247 if (!replied_ && svc) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700248 const auto ret = svc->endpoint()->MessageReply(this, return_code);
249 replied_ = ret.ok();
250 return ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800251 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700252 return ErrorStatus{EINVAL};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800253 }
254}
255
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700256Status<void> Message::ReplyFileDescriptor(unsigned int fd) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800257 PDX_TRACE_NAME("Message::ReplyFileDescriptor");
258 auto svc = service_.lock();
259 if (!replied_ && svc) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700260 const auto ret = svc->endpoint()->MessageReplyFd(this, fd);
261 replied_ = ret.ok();
262 return ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800263 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700264 return ErrorStatus{EINVAL};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800265 }
266}
267
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700268Status<void> Message::ReplyError(unsigned int error) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800269 PDX_TRACE_NAME("Message::ReplyError");
270 auto svc = service_.lock();
271 if (!replied_ && svc) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700272 const auto ret =
273 svc->endpoint()->MessageReply(this, -static_cast<int>(error));
274 replied_ = ret.ok();
275 return ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800276 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700277 return ErrorStatus{EINVAL};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800278 }
279}
280
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700281Status<void> Message::Reply(const LocalHandle& handle) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800282 PDX_TRACE_NAME("Message::ReplyFileHandle");
283 auto svc = service_.lock();
284 if (!replied_ && svc) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700285 Status<void> ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800286
287 if (handle)
288 ret = svc->endpoint()->MessageReplyFd(this, handle.Get());
289 else
290 ret = svc->endpoint()->MessageReply(this, handle.Get());
291
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700292 replied_ = ret.ok();
293 return ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800294 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700295 return ErrorStatus{EINVAL};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800296 }
297}
298
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700299Status<void> Message::Reply(const BorrowedHandle& handle) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800300 PDX_TRACE_NAME("Message::ReplyFileHandle");
301 auto svc = service_.lock();
302 if (!replied_ && svc) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700303 Status<void> ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800304
305 if (handle)
306 ret = svc->endpoint()->MessageReplyFd(this, handle.Get());
307 else
308 ret = svc->endpoint()->MessageReply(this, handle.Get());
309
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700310 replied_ = ret.ok();
311 return ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800312 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700313 return ErrorStatus{EINVAL};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800314 }
315}
316
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700317Status<void> Message::Reply(const RemoteHandle& handle) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800318 PDX_TRACE_NAME("Message::ReplyFileHandle");
319 auto svc = service_.lock();
320 if (!replied_ && svc) {
Greg Kaiserfa1f4202018-11-12 12:33:13 -0800321 Status<void> ret = svc->endpoint()->MessageReply(this, handle.Get());
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700322 replied_ = ret.ok();
323 return ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800324 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700325 return ErrorStatus{EINVAL};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800326 }
327}
328
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700329Status<void> Message::Reply(const LocalChannelHandle& handle) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800330 auto svc = service_.lock();
331 if (!replied_ && svc) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700332 const auto ret = svc->endpoint()->MessageReplyChannelHandle(this, handle);
333 replied_ = ret.ok();
334 return ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800335 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700336 return ErrorStatus{EINVAL};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800337 }
338}
339
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700340Status<void> Message::Reply(const BorrowedChannelHandle& handle) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800341 auto svc = service_.lock();
342 if (!replied_ && svc) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700343 const auto ret = svc->endpoint()->MessageReplyChannelHandle(this, handle);
344 replied_ = ret.ok();
345 return ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800346 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700347 return ErrorStatus{EINVAL};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800348 }
349}
350
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700351Status<void> Message::Reply(const RemoteChannelHandle& handle) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800352 auto svc = service_.lock();
353 if (!replied_ && svc) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700354 const auto ret = svc->endpoint()->MessageReplyChannelHandle(this, handle);
355 replied_ = ret.ok();
356 return ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800357 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700358 return ErrorStatus{EINVAL};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800359 }
360}
361
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700362Status<void> Message::ModifyChannelEvents(int clear_mask, int set_mask) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800363 PDX_TRACE_NAME("Message::ModifyChannelEvents");
364 if (auto svc = service_.lock()) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700365 return svc->endpoint()->ModifyChannelEvents(info_.cid, clear_mask,
366 set_mask);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800367 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700368 return ErrorStatus{ESHUTDOWN};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800369 }
370}
371
372Status<RemoteChannelHandle> Message::PushChannel(
373 int flags, const std::shared_ptr<Channel>& channel, int* channel_id) {
374 PDX_TRACE_NAME("Message::PushChannel");
375 if (auto svc = service_.lock()) {
376 return svc->PushChannel(this, flags, channel, channel_id);
377 } else {
378 return ErrorStatus(ESHUTDOWN);
379 }
380}
381
382Status<RemoteChannelHandle> Message::PushChannel(
383 Service* service, int flags, const std::shared_ptr<Channel>& channel,
384 int* channel_id) {
385 PDX_TRACE_NAME("Message::PushChannel");
386 return service->PushChannel(this, flags, channel, channel_id);
387}
388
389Status<int> Message::CheckChannel(ChannelReference ref,
390 std::shared_ptr<Channel>* channel) const {
391 PDX_TRACE_NAME("Message::CheckChannel");
392 if (auto svc = service_.lock()) {
393 return svc->CheckChannel(this, ref, channel);
394 } else {
395 return ErrorStatus(ESHUTDOWN);
396 }
397}
398
399Status<int> Message::CheckChannel(const Service* service, ChannelReference ref,
400 std::shared_ptr<Channel>* channel) const {
401 PDX_TRACE_NAME("Message::CheckChannel");
402 return service->CheckChannel(this, ref, channel);
403}
404
405pid_t Message::GetProcessId() const { return info_.pid; }
406
407pid_t Message::GetThreadId() const { return info_.tid; }
408
409uid_t Message::GetEffectiveUserId() const { return info_.euid; }
410
411gid_t Message::GetEffectiveGroupId() const { return info_.egid; }
412
413int Message::GetChannelId() const { return info_.cid; }
414
415int Message::GetMessageId() const { return info_.mid; }
416
417int Message::GetOp() const { return info_.op; }
418
419int Message::GetFlags() const { return info_.flags; }
420
421size_t Message::GetSendLength() const { return info_.send_len; }
422
423size_t Message::GetReceiveLength() const { return info_.recv_len; }
424
425size_t Message::GetFileDescriptorCount() const { return info_.fd_count; }
426
427std::shared_ptr<Channel> Message::GetChannel() const { return channel_.lock(); }
428
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700429Status<void> Message::SetChannel(const std::shared_ptr<Channel>& chan) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800430 channel_ = chan;
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700431 Status<void> status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800432 if (auto svc = service_.lock())
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700433 status = svc->SetChannel(info_.cid, chan);
434 return status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800435}
436
437std::shared_ptr<Service> Message::GetService() const { return service_.lock(); }
438
439const MessageInfo& Message::GetInfo() const { return info_; }
440
441Service::Service(const std::string& name, std::unique_ptr<Endpoint> endpoint)
442 : name_(name), endpoint_{std::move(endpoint)} {
443 if (!endpoint_)
444 return;
445
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700446 const auto status = endpoint_->SetService(this);
447 ALOGE_IF(!status, "Failed to set service context because: %s",
448 status.GetErrorMessage().c_str());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800449}
450
451Service::~Service() {
452 if (endpoint_) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700453 const auto status = endpoint_->SetService(nullptr);
454 ALOGE_IF(!status, "Failed to clear service context because: %s",
455 status.GetErrorMessage().c_str());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800456 }
457}
458
459std::shared_ptr<Service> Service::GetFromMessageInfo(const MessageInfo& info) {
460 return info.service ? info.service->shared_from_this()
461 : std::shared_ptr<Service>();
462}
463
464bool Service::IsInitialized() const { return endpoint_.get() != nullptr; }
465
466std::shared_ptr<Channel> Service::OnChannelOpen(Message& /*message*/) {
467 return nullptr;
468}
469
470void Service::OnChannelClose(Message& /*message*/,
471 const std::shared_ptr<Channel>& /*channel*/) {}
472
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700473Status<void> Service::SetChannel(int channel_id,
474 const std::shared_ptr<Channel>& channel) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800475 PDX_TRACE_NAME("Service::SetChannel");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800476 std::lock_guard<std::mutex> autolock(channels_mutex_);
477
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700478 const auto status = endpoint_->SetChannel(channel_id, channel.get());
479 if (!status) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800480 ALOGE("%s::SetChannel: Failed to set channel context: %s\n", name_.c_str(),
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700481 status.GetErrorMessage().c_str());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800482
483 // It's possible someone mucked with things behind our back by calling the C
484 // API directly. Since we know the channel id isn't valid, make sure we
485 // don't have it in the channels map.
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700486 if (status.error() == ENOENT)
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800487 channels_.erase(channel_id);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700488 } else {
489 if (channel != nullptr)
490 channels_[channel_id] = channel;
491 else
492 channels_.erase(channel_id);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800493 }
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700494 return status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800495}
496
497std::shared_ptr<Channel> Service::GetChannel(int channel_id) const {
498 PDX_TRACE_NAME("Service::GetChannel");
499 std::lock_guard<std::mutex> autolock(channels_mutex_);
500
501 auto search = channels_.find(channel_id);
502 if (search != channels_.end())
503 return search->second;
504 else
505 return nullptr;
506}
507
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700508Status<void> Service::CloseChannel(int channel_id) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800509 PDX_TRACE_NAME("Service::CloseChannel");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800510 std::lock_guard<std::mutex> autolock(channels_mutex_);
511
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700512 const auto status = endpoint_->CloseChannel(channel_id);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800513
514 // Always erase the map entry, in case someone mucked with things behind our
515 // back using the C API directly.
516 channels_.erase(channel_id);
517
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700518 return status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800519}
520
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700521Status<void> Service::ModifyChannelEvents(int channel_id, int clear_mask,
522 int set_mask) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800523 PDX_TRACE_NAME("Service::ModifyChannelEvents");
524 return endpoint_->ModifyChannelEvents(channel_id, clear_mask, set_mask);
525}
526
527Status<RemoteChannelHandle> Service::PushChannel(
528 Message* message, int flags, const std::shared_ptr<Channel>& channel,
529 int* channel_id) {
530 PDX_TRACE_NAME("Service::PushChannel");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800531
532 std::lock_guard<std::mutex> autolock(channels_mutex_);
533
534 int channel_id_temp = -1;
535 Status<RemoteChannelHandle> ret =
536 endpoint_->PushChannel(message, flags, channel.get(), &channel_id_temp);
537 ALOGE_IF(!ret.ok(), "%s::PushChannel: Failed to push channel: %s",
538 name_.c_str(), strerror(ret.error()));
539
540 if (channel && channel_id_temp != -1)
541 channels_[channel_id_temp] = channel;
542 if (channel_id)
543 *channel_id = channel_id_temp;
544
545 return ret;
546}
547
548Status<int> Service::CheckChannel(const Message* message, ChannelReference ref,
549 std::shared_ptr<Channel>* channel) const {
550 PDX_TRACE_NAME("Service::CheckChannel");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800551
552 // Synchronization to maintain consistency between the kernel's channel
553 // context pointer and the userspace channels_ map. Other threads may attempt
554 // to modify the map at the same time, which could cause the channel context
555 // pointer returned by the kernel to be invalid.
556 std::lock_guard<std::mutex> autolock(channels_mutex_);
557
558 Channel* channel_context = nullptr;
559 Status<int> ret = endpoint_->CheckChannel(
560 message, ref, channel ? &channel_context : nullptr);
561 if (ret && channel) {
562 if (channel_context)
563 *channel = channel_context->shared_from_this();
564 else
565 *channel = nullptr;
566 }
567
568 return ret;
569}
570
571std::string Service::DumpState(size_t /*max_length*/) { return ""; }
572
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700573Status<void> Service::HandleMessage(Message& message) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800574 return DefaultHandleMessage(message);
575}
576
577void Service::HandleImpulse(Message& /*impulse*/) {}
578
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700579Status<void> Service::HandleSystemMessage(Message& message) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800580 const MessageInfo& info = message.GetInfo();
581
582 switch (info.op) {
583 case opcodes::CHANNEL_OPEN: {
584 ALOGD("%s::OnChannelOpen: pid=%d cid=%d\n", name_.c_str(), info.pid,
585 info.cid);
586 message.SetChannel(OnChannelOpen(message));
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700587 return message.Reply(0);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800588 }
589
590 case opcodes::CHANNEL_CLOSE: {
591 ALOGD("%s::OnChannelClose: pid=%d cid=%d\n", name_.c_str(), info.pid,
592 info.cid);
593 OnChannelClose(message, Channel::GetFromMessageInfo(info));
594 message.SetChannel(nullptr);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700595 return message.Reply(0);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800596 }
597
598 case opcodes::REPORT_SYSPROP_CHANGE:
599 ALOGD("%s:REPORT_SYSPROP_CHANGE: pid=%d cid=%d\n", name_.c_str(),
600 info.pid, info.cid);
601 OnSysPropChange();
602 android::report_sysprop_change();
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700603 return message.Reply(0);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800604
605 case opcodes::DUMP_STATE: {
606 ALOGD("%s:DUMP_STATE: pid=%d cid=%d\n", name_.c_str(), info.pid,
607 info.cid);
608 auto response = DumpState(message.GetReceiveLength());
609 const size_t response_size = response.size() < message.GetReceiveLength()
610 ? response.size()
611 : message.GetReceiveLength();
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700612 const Status<size_t> status =
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800613 message.Write(response.data(), response_size);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700614 if (status && status.get() < response_size)
615 return message.ReplyError(EIO);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800616 else
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700617 return message.Reply(status);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800618 }
619
620 default:
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700621 return ErrorStatus{EOPNOTSUPP};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800622 }
623}
624
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700625Status<void> Service::DefaultHandleMessage(Message& message) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800626 const MessageInfo& info = message.GetInfo();
627
628 ALOGD_IF(TRACE, "Service::DefaultHandleMessage: pid=%d cid=%d op=%d\n",
629 info.pid, info.cid, info.op);
630
631 switch (info.op) {
632 case opcodes::CHANNEL_OPEN:
633 case opcodes::CHANNEL_CLOSE:
634 case opcodes::REPORT_SYSPROP_CHANGE:
635 case opcodes::DUMP_STATE:
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700636 return HandleSystemMessage(message);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800637
638 default:
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700639 return message.ReplyError(EOPNOTSUPP);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800640 }
641}
642
643void Service::OnSysPropChange() {}
644
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700645Status<void> Service::ReceiveAndDispatch() {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800646 Message message;
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700647 const auto status = endpoint_->MessageReceive(&message);
648 if (!status) {
649 ALOGE("Failed to receive message: %s\n", status.GetErrorMessage().c_str());
650 return status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800651 }
652
653 std::shared_ptr<Service> service = message.GetService();
654
655 if (!service) {
656 ALOGE("Service::ReceiveAndDispatch: service context is NULL!!!\n");
657 // Don't block the sender indefinitely in this error case.
658 endpoint_->MessageReply(&message, -EINVAL);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700659 return ErrorStatus{EINVAL};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800660 }
661
662 if (message.IsImpulse()) {
663 service->HandleImpulse(message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700664 return {};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800665 } else if (service->HandleSystemMessage(message)) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700666 return {};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800667 } else {
668 return service->HandleMessage(message);
669 }
670}
671
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700672Status<void> Service::Cancel() { return endpoint_->Cancel(); }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800673
674} // namespace pdx
675} // namespace android