blob: fab4770b7f64c7541085e2447d14b461d58b57c1 [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#define LOG_TAG "ServiceFramework"
2#include "pdx/service.h"
3
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08004#include <fcntl.h>
Alex Vakulenko4fe60582017-02-02 11:35:59 -08005#include <log/log.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08006#include <utils/misc.h>
7
8#include <algorithm>
9#include <cstdint>
10
11#include <pdx/trace.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080012
13#define TRACE 0
14
15namespace android {
16namespace pdx {
17
18std::shared_ptr<Channel> Channel::GetFromMessageInfo(const MessageInfo& info) {
19 return info.channel ? info.channel->shared_from_this()
20 : std::shared_ptr<Channel>();
21}
22
23Message::Message() : replied_(true) {}
24
25Message::Message(const MessageInfo& info)
26 : service_{Service::GetFromMessageInfo(info)},
27 channel_{Channel::GetFromMessageInfo(info)},
28 info_{info},
29 replied_{IsImpulse()} {
30 auto svc = service_.lock();
31 if (svc)
32 state_ = svc->endpoint()->AllocateMessageState();
33}
34
35// C++11 specifies the move semantics for shared_ptr but not weak_ptr. This
36// means we have to manually implement the desired move semantics for Message.
37Message::Message(Message&& other) { *this = std::move(other); }
38
39Message& Message::operator=(Message&& other) {
40 Destroy();
41 auto base = reinterpret_cast<std::uint8_t*>(&info_);
42 std::fill(&base[0], &base[sizeof(info_)], 0);
43 replied_ = true;
44 std::swap(service_, other.service_);
45 std::swap(channel_, other.channel_);
46 std::swap(info_, other.info_);
47 std::swap(state_, other.state_);
48 std::swap(replied_, other.replied_);
49 return *this;
50}
51
52Message::~Message() { Destroy(); }
53
54void Message::Destroy() {
55 auto svc = service_.lock();
56 if (svc) {
57 if (!replied_) {
58 ALOGE(
59 "ERROR: Service \"%s\" failed to reply to message: op=%d pid=%d "
60 "cid=%d\n",
61 svc->name_.c_str(), info_.op, info_.pid, info_.cid);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -070062 svc->DefaultHandleMessage(*this);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080063 }
64 svc->endpoint()->FreeMessageState(state_);
65 }
66 state_ = nullptr;
67 service_.reset();
68 channel_.reset();
69}
70
71const std::uint8_t* Message::ImpulseBegin() const {
72 return reinterpret_cast<const std::uint8_t*>(info_.impulse);
73}
74
75const std::uint8_t* Message::ImpulseEnd() const {
76 return ImpulseBegin() + (IsImpulse() ? GetSendLength() : 0);
77}
78
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -070079Status<size_t> Message::ReadVector(const struct iovec* vector,
80 size_t vector_length) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080081 PDX_TRACE_NAME("Message::ReadVector");
82 if (auto svc = service_.lock()) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -070083 return svc->endpoint()->ReadMessageData(this, vector, vector_length);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080084 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -070085 return ErrorStatus{ESHUTDOWN};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080086 }
87}
88
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -070089Status<void> Message::ReadVectorAll(const struct iovec* vector,
90 size_t vector_length) {
91 PDX_TRACE_NAME("Message::ReadVectorAll");
92 if (auto svc = service_.lock()) {
93 const auto status =
94 svc->endpoint()->ReadMessageData(this, vector, vector_length);
95 if (!status)
96 return status.error_status();
97 size_t size_to_read = 0;
98 for (size_t i = 0; i < vector_length; i++)
99 size_to_read += vector[i].iov_len;
100 if (status.get() < size_to_read)
101 return ErrorStatus{EIO};
102 return {};
103 } else {
104 return ErrorStatus{ESHUTDOWN};
105 }
106}
107
108Status<size_t> Message::Read(void* buffer, size_t length) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800109 PDX_TRACE_NAME("Message::Read");
110 if (auto svc = service_.lock()) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800111 const struct iovec vector = {buffer, length};
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700112 return svc->endpoint()->ReadMessageData(this, &vector, 1);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800113 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700114 return ErrorStatus{ESHUTDOWN};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800115 }
116}
117
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700118Status<size_t> Message::WriteVector(const struct iovec* vector,
119 size_t vector_length) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800120 PDX_TRACE_NAME("Message::WriteVector");
121 if (auto svc = service_.lock()) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700122 return svc->endpoint()->WriteMessageData(this, vector, vector_length);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800123 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700124 return ErrorStatus{ESHUTDOWN};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800125 }
126}
127
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700128Status<void> Message::WriteVectorAll(const struct iovec* vector,
129 size_t vector_length) {
130 PDX_TRACE_NAME("Message::WriteVector");
131 if (auto svc = service_.lock()) {
132 const auto status =
133 svc->endpoint()->WriteMessageData(this, vector, vector_length);
134 if (!status)
135 return status.error_status();
136 size_t size_to_write = 0;
137 for (size_t i = 0; i < vector_length; i++)
138 size_to_write += vector[i].iov_len;
139 if (status.get() < size_to_write)
140 return ErrorStatus{EIO};
141 return {};
142 } else {
143 return ErrorStatus{ESHUTDOWN};
144 }
145}
146
147Status<size_t> Message::Write(const void* buffer, size_t length) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800148 PDX_TRACE_NAME("Message::Write");
149 if (auto svc = service_.lock()) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800150 const struct iovec vector = {const_cast<void*>(buffer), length};
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700151 return svc->endpoint()->WriteMessageData(this, &vector, 1);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800152 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700153 return ErrorStatus{ESHUTDOWN};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800154 }
155}
156
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700157Status<FileReference> Message::PushFileHandle(const LocalHandle& handle) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800158 PDX_TRACE_NAME("Message::PushFileHandle");
159 if (auto svc = service_.lock()) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700160 return svc->endpoint()->PushFileHandle(this, handle);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800161 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700162 return ErrorStatus{ESHUTDOWN};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800163 }
164}
165
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700166Status<FileReference> Message::PushFileHandle(const BorrowedHandle& handle) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800167 PDX_TRACE_NAME("Message::PushFileHandle");
168 if (auto svc = service_.lock()) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700169 return svc->endpoint()->PushFileHandle(this, handle);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800170 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700171 return ErrorStatus{ESHUTDOWN};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800172 }
173}
174
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700175Status<FileReference> Message::PushFileHandle(const RemoteHandle& handle) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800176 PDX_TRACE_NAME("Message::PushFileHandle");
177 if (auto svc = service_.lock()) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700178 return svc->endpoint()->PushFileHandle(this, handle);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800179 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700180 return ErrorStatus{ESHUTDOWN};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800181 }
182}
183
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700184Status<ChannelReference> Message::PushChannelHandle(
185 const LocalChannelHandle& handle) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800186 PDX_TRACE_NAME("Message::PushChannelHandle");
187 if (auto svc = service_.lock()) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700188 return svc->endpoint()->PushChannelHandle(this, handle);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800189 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700190 return ErrorStatus{ESHUTDOWN};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800191 }
192}
193
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700194Status<ChannelReference> Message::PushChannelHandle(
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800195 const BorrowedChannelHandle& handle) {
196 PDX_TRACE_NAME("Message::PushChannelHandle");
197 if (auto svc = service_.lock()) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700198 return svc->endpoint()->PushChannelHandle(this, handle);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800199 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700200 return ErrorStatus{ESHUTDOWN};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800201 }
202}
203
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700204Status<ChannelReference> Message::PushChannelHandle(
205 const RemoteChannelHandle& handle) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800206 PDX_TRACE_NAME("Message::PushChannelHandle");
207 if (auto svc = service_.lock()) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700208 return svc->endpoint()->PushChannelHandle(this, handle);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800209 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700210 return ErrorStatus{ESHUTDOWN};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800211 }
212}
213
214bool Message::GetFileHandle(FileReference ref, LocalHandle* handle) {
215 PDX_TRACE_NAME("Message::GetFileHandle");
216 auto svc = service_.lock();
217 if (!svc)
218 return false;
219
220 if (ref >= 0) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800221 *handle = svc->endpoint()->GetFileHandle(this, ref);
222 if (!handle->IsValid())
223 return false;
224 } else {
225 *handle = LocalHandle{ref};
226 }
227 return true;
228}
229
230bool Message::GetChannelHandle(ChannelReference ref,
231 LocalChannelHandle* handle) {
232 PDX_TRACE_NAME("Message::GetChannelHandle");
233 auto svc = service_.lock();
234 if (!svc)
235 return false;
236
237 if (ref >= 0) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800238 *handle = svc->endpoint()->GetChannelHandle(this, ref);
239 if (!handle->valid())
240 return false;
241 } else {
242 *handle = LocalChannelHandle{nullptr, ref};
243 }
244 return true;
245}
246
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700247Status<void> Message::Reply(int return_code) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800248 PDX_TRACE_NAME("Message::Reply");
249 auto svc = service_.lock();
250 if (!replied_ && svc) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700251 const auto ret = svc->endpoint()->MessageReply(this, return_code);
252 replied_ = ret.ok();
253 return ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800254 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700255 return ErrorStatus{EINVAL};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800256 }
257}
258
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700259Status<void> Message::ReplyFileDescriptor(unsigned int fd) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800260 PDX_TRACE_NAME("Message::ReplyFileDescriptor");
261 auto svc = service_.lock();
262 if (!replied_ && svc) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700263 const auto ret = svc->endpoint()->MessageReplyFd(this, fd);
264 replied_ = ret.ok();
265 return ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800266 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700267 return ErrorStatus{EINVAL};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800268 }
269}
270
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700271Status<void> Message::ReplyError(unsigned int error) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800272 PDX_TRACE_NAME("Message::ReplyError");
273 auto svc = service_.lock();
274 if (!replied_ && svc) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700275 const auto ret =
276 svc->endpoint()->MessageReply(this, -static_cast<int>(error));
277 replied_ = ret.ok();
278 return ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800279 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700280 return ErrorStatus{EINVAL};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800281 }
282}
283
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700284Status<void> Message::Reply(const LocalHandle& handle) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800285 PDX_TRACE_NAME("Message::ReplyFileHandle");
286 auto svc = service_.lock();
287 if (!replied_ && svc) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700288 Status<void> ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800289
290 if (handle)
291 ret = svc->endpoint()->MessageReplyFd(this, handle.Get());
292 else
293 ret = svc->endpoint()->MessageReply(this, handle.Get());
294
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700295 replied_ = ret.ok();
296 return ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800297 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700298 return ErrorStatus{EINVAL};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800299 }
300}
301
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700302Status<void> Message::Reply(const BorrowedHandle& handle) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800303 PDX_TRACE_NAME("Message::ReplyFileHandle");
304 auto svc = service_.lock();
305 if (!replied_ && svc) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700306 Status<void> ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800307
308 if (handle)
309 ret = svc->endpoint()->MessageReplyFd(this, handle.Get());
310 else
311 ret = svc->endpoint()->MessageReply(this, handle.Get());
312
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700313 replied_ = ret.ok();
314 return ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800315 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700316 return ErrorStatus{EINVAL};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800317 }
318}
319
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700320Status<void> Message::Reply(const RemoteHandle& handle) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800321 PDX_TRACE_NAME("Message::ReplyFileHandle");
322 auto svc = service_.lock();
323 if (!replied_ && svc) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700324 Status<void> ret;
325
326 if (handle)
327 ret = svc->endpoint()->MessageReply(this, handle.Get());
328 else
329 ret = svc->endpoint()->MessageReply(this, handle.Get());
330
331 replied_ = ret.ok();
332 return ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800333 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700334 return ErrorStatus{EINVAL};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800335 }
336}
337
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700338Status<void> Message::Reply(const LocalChannelHandle& handle) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800339 auto svc = service_.lock();
340 if (!replied_ && svc) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700341 const auto ret = svc->endpoint()->MessageReplyChannelHandle(this, handle);
342 replied_ = ret.ok();
343 return ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800344 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700345 return ErrorStatus{EINVAL};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800346 }
347}
348
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700349Status<void> Message::Reply(const BorrowedChannelHandle& handle) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800350 auto svc = service_.lock();
351 if (!replied_ && svc) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700352 const auto ret = svc->endpoint()->MessageReplyChannelHandle(this, handle);
353 replied_ = ret.ok();
354 return ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800355 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700356 return ErrorStatus{EINVAL};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800357 }
358}
359
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700360Status<void> Message::Reply(const RemoteChannelHandle& handle) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800361 auto svc = service_.lock();
362 if (!replied_ && svc) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700363 const auto ret = svc->endpoint()->MessageReplyChannelHandle(this, handle);
364 replied_ = ret.ok();
365 return ret;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800366 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700367 return ErrorStatus{EINVAL};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800368 }
369}
370
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700371Status<void> Message::ModifyChannelEvents(int clear_mask, int set_mask) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800372 PDX_TRACE_NAME("Message::ModifyChannelEvents");
373 if (auto svc = service_.lock()) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700374 return svc->endpoint()->ModifyChannelEvents(info_.cid, clear_mask,
375 set_mask);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800376 } else {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700377 return ErrorStatus{ESHUTDOWN};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800378 }
379}
380
381Status<RemoteChannelHandle> Message::PushChannel(
382 int flags, const std::shared_ptr<Channel>& channel, int* channel_id) {
383 PDX_TRACE_NAME("Message::PushChannel");
384 if (auto svc = service_.lock()) {
385 return svc->PushChannel(this, flags, channel, channel_id);
386 } else {
387 return ErrorStatus(ESHUTDOWN);
388 }
389}
390
391Status<RemoteChannelHandle> Message::PushChannel(
392 Service* service, int flags, const std::shared_ptr<Channel>& channel,
393 int* channel_id) {
394 PDX_TRACE_NAME("Message::PushChannel");
395 return service->PushChannel(this, flags, channel, channel_id);
396}
397
398Status<int> Message::CheckChannel(ChannelReference ref,
399 std::shared_ptr<Channel>* channel) const {
400 PDX_TRACE_NAME("Message::CheckChannel");
401 if (auto svc = service_.lock()) {
402 return svc->CheckChannel(this, ref, channel);
403 } else {
404 return ErrorStatus(ESHUTDOWN);
405 }
406}
407
408Status<int> Message::CheckChannel(const Service* service, ChannelReference ref,
409 std::shared_ptr<Channel>* channel) const {
410 PDX_TRACE_NAME("Message::CheckChannel");
411 return service->CheckChannel(this, ref, channel);
412}
413
414pid_t Message::GetProcessId() const { return info_.pid; }
415
416pid_t Message::GetThreadId() const { return info_.tid; }
417
418uid_t Message::GetEffectiveUserId() const { return info_.euid; }
419
420gid_t Message::GetEffectiveGroupId() const { return info_.egid; }
421
422int Message::GetChannelId() const { return info_.cid; }
423
424int Message::GetMessageId() const { return info_.mid; }
425
426int Message::GetOp() const { return info_.op; }
427
428int Message::GetFlags() const { return info_.flags; }
429
430size_t Message::GetSendLength() const { return info_.send_len; }
431
432size_t Message::GetReceiveLength() const { return info_.recv_len; }
433
434size_t Message::GetFileDescriptorCount() const { return info_.fd_count; }
435
436std::shared_ptr<Channel> Message::GetChannel() const { return channel_.lock(); }
437
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700438Status<void> Message::SetChannel(const std::shared_ptr<Channel>& chan) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800439 channel_ = chan;
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700440 Status<void> status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800441 if (auto svc = service_.lock())
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700442 status = svc->SetChannel(info_.cid, chan);
443 return status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800444}
445
446std::shared_ptr<Service> Message::GetService() const { return service_.lock(); }
447
448const MessageInfo& Message::GetInfo() const { return info_; }
449
450Service::Service(const std::string& name, std::unique_ptr<Endpoint> endpoint)
451 : name_(name), endpoint_{std::move(endpoint)} {
452 if (!endpoint_)
453 return;
454
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700455 const auto status = endpoint_->SetService(this);
456 ALOGE_IF(!status, "Failed to set service context because: %s",
457 status.GetErrorMessage().c_str());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800458}
459
460Service::~Service() {
461 if (endpoint_) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700462 const auto status = endpoint_->SetService(nullptr);
463 ALOGE_IF(!status, "Failed to clear service context because: %s",
464 status.GetErrorMessage().c_str());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800465 }
466}
467
468std::shared_ptr<Service> Service::GetFromMessageInfo(const MessageInfo& info) {
469 return info.service ? info.service->shared_from_this()
470 : std::shared_ptr<Service>();
471}
472
473bool Service::IsInitialized() const { return endpoint_.get() != nullptr; }
474
475std::shared_ptr<Channel> Service::OnChannelOpen(Message& /*message*/) {
476 return nullptr;
477}
478
479void Service::OnChannelClose(Message& /*message*/,
480 const std::shared_ptr<Channel>& /*channel*/) {}
481
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700482Status<void> Service::SetChannel(int channel_id,
483 const std::shared_ptr<Channel>& channel) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800484 PDX_TRACE_NAME("Service::SetChannel");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800485 std::lock_guard<std::mutex> autolock(channels_mutex_);
486
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700487 const auto status = endpoint_->SetChannel(channel_id, channel.get());
488 if (!status) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800489 ALOGE("%s::SetChannel: Failed to set channel context: %s\n", name_.c_str(),
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700490 status.GetErrorMessage().c_str());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800491
492 // It's possible someone mucked with things behind our back by calling the C
493 // API directly. Since we know the channel id isn't valid, make sure we
494 // don't have it in the channels map.
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700495 if (status.error() == ENOENT)
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800496 channels_.erase(channel_id);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700497 } else {
498 if (channel != nullptr)
499 channels_[channel_id] = channel;
500 else
501 channels_.erase(channel_id);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800502 }
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700503 return status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800504}
505
506std::shared_ptr<Channel> Service::GetChannel(int channel_id) const {
507 PDX_TRACE_NAME("Service::GetChannel");
508 std::lock_guard<std::mutex> autolock(channels_mutex_);
509
510 auto search = channels_.find(channel_id);
511 if (search != channels_.end())
512 return search->second;
513 else
514 return nullptr;
515}
516
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700517Status<void> Service::CloseChannel(int channel_id) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800518 PDX_TRACE_NAME("Service::CloseChannel");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800519 std::lock_guard<std::mutex> autolock(channels_mutex_);
520
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700521 const auto status = endpoint_->CloseChannel(channel_id);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800522
523 // Always erase the map entry, in case someone mucked with things behind our
524 // back using the C API directly.
525 channels_.erase(channel_id);
526
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700527 return status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800528}
529
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700530Status<void> Service::ModifyChannelEvents(int channel_id, int clear_mask,
531 int set_mask) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800532 PDX_TRACE_NAME("Service::ModifyChannelEvents");
533 return endpoint_->ModifyChannelEvents(channel_id, clear_mask, set_mask);
534}
535
536Status<RemoteChannelHandle> Service::PushChannel(
537 Message* message, int flags, const std::shared_ptr<Channel>& channel,
538 int* channel_id) {
539 PDX_TRACE_NAME("Service::PushChannel");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800540
541 std::lock_guard<std::mutex> autolock(channels_mutex_);
542
543 int channel_id_temp = -1;
544 Status<RemoteChannelHandle> ret =
545 endpoint_->PushChannel(message, flags, channel.get(), &channel_id_temp);
546 ALOGE_IF(!ret.ok(), "%s::PushChannel: Failed to push channel: %s",
547 name_.c_str(), strerror(ret.error()));
548
549 if (channel && channel_id_temp != -1)
550 channels_[channel_id_temp] = channel;
551 if (channel_id)
552 *channel_id = channel_id_temp;
553
554 return ret;
555}
556
557Status<int> Service::CheckChannel(const Message* message, ChannelReference ref,
558 std::shared_ptr<Channel>* channel) const {
559 PDX_TRACE_NAME("Service::CheckChannel");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800560
561 // Synchronization to maintain consistency between the kernel's channel
562 // context pointer and the userspace channels_ map. Other threads may attempt
563 // to modify the map at the same time, which could cause the channel context
564 // pointer returned by the kernel to be invalid.
565 std::lock_guard<std::mutex> autolock(channels_mutex_);
566
567 Channel* channel_context = nullptr;
568 Status<int> ret = endpoint_->CheckChannel(
569 message, ref, channel ? &channel_context : nullptr);
570 if (ret && channel) {
571 if (channel_context)
572 *channel = channel_context->shared_from_this();
573 else
574 *channel = nullptr;
575 }
576
577 return ret;
578}
579
580std::string Service::DumpState(size_t /*max_length*/) { return ""; }
581
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700582Status<void> Service::HandleMessage(Message& message) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800583 return DefaultHandleMessage(message);
584}
585
586void Service::HandleImpulse(Message& /*impulse*/) {}
587
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700588Status<void> Service::HandleSystemMessage(Message& message) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800589 const MessageInfo& info = message.GetInfo();
590
591 switch (info.op) {
592 case opcodes::CHANNEL_OPEN: {
593 ALOGD("%s::OnChannelOpen: pid=%d cid=%d\n", name_.c_str(), info.pid,
594 info.cid);
595 message.SetChannel(OnChannelOpen(message));
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700596 return message.Reply(0);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800597 }
598
599 case opcodes::CHANNEL_CLOSE: {
600 ALOGD("%s::OnChannelClose: pid=%d cid=%d\n", name_.c_str(), info.pid,
601 info.cid);
602 OnChannelClose(message, Channel::GetFromMessageInfo(info));
603 message.SetChannel(nullptr);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700604 return message.Reply(0);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800605 }
606
607 case opcodes::REPORT_SYSPROP_CHANGE:
608 ALOGD("%s:REPORT_SYSPROP_CHANGE: pid=%d cid=%d\n", name_.c_str(),
609 info.pid, info.cid);
610 OnSysPropChange();
611 android::report_sysprop_change();
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700612 return message.Reply(0);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800613
614 case opcodes::DUMP_STATE: {
615 ALOGD("%s:DUMP_STATE: pid=%d cid=%d\n", name_.c_str(), info.pid,
616 info.cid);
617 auto response = DumpState(message.GetReceiveLength());
618 const size_t response_size = response.size() < message.GetReceiveLength()
619 ? response.size()
620 : message.GetReceiveLength();
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700621 const Status<size_t> status =
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800622 message.Write(response.data(), response_size);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700623 if (status && status.get() < response_size)
624 return message.ReplyError(EIO);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800625 else
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700626 return message.Reply(status);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800627 }
628
629 default:
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700630 return ErrorStatus{EOPNOTSUPP};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800631 }
632}
633
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700634Status<void> Service::DefaultHandleMessage(Message& message) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800635 const MessageInfo& info = message.GetInfo();
636
637 ALOGD_IF(TRACE, "Service::DefaultHandleMessage: pid=%d cid=%d op=%d\n",
638 info.pid, info.cid, info.op);
639
640 switch (info.op) {
641 case opcodes::CHANNEL_OPEN:
642 case opcodes::CHANNEL_CLOSE:
643 case opcodes::REPORT_SYSPROP_CHANGE:
644 case opcodes::DUMP_STATE:
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700645 return HandleSystemMessage(message);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800646
647 default:
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700648 return message.ReplyError(EOPNOTSUPP);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800649 }
650}
651
652void Service::OnSysPropChange() {}
653
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700654Status<void> Service::ReceiveAndDispatch() {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800655 Message message;
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700656 const auto status = endpoint_->MessageReceive(&message);
657 if (!status) {
658 ALOGE("Failed to receive message: %s\n", status.GetErrorMessage().c_str());
659 return status;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800660 }
661
662 std::shared_ptr<Service> service = message.GetService();
663
664 if (!service) {
665 ALOGE("Service::ReceiveAndDispatch: service context is NULL!!!\n");
666 // Don't block the sender indefinitely in this error case.
667 endpoint_->MessageReply(&message, -EINVAL);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700668 return ErrorStatus{EINVAL};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800669 }
670
671 if (message.IsImpulse()) {
672 service->HandleImpulse(message);
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700673 return {};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800674 } else if (service->HandleSystemMessage(message)) {
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700675 return {};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800676 } else {
677 return service->HandleMessage(message);
678 }
679}
680
Alex Vakulenkof0a7bd02017-03-31 18:06:19 -0700681Status<void> Service::Cancel() { return endpoint_->Cancel(); }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800682
683} // namespace pdx
684} // namespace android