1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "pdx/service.h"
2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <fcntl.h>
44fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko#include <log/log.h>
5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <utils/misc.h>
6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <algorithm>
8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <cstdint>
9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/trace.h>
11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android {
13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace pdx {
14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::shared_ptr<Channel> Channel::GetFromMessageInfo(const MessageInfo& info) {
16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return info.channel ? info.channel->shared_from_this()
17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                      : std::shared_ptr<Channel>();
18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoMessage::Message() : replied_(true) {}
21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoMessage::Message(const MessageInfo& info)
23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    : service_{Service::GetFromMessageInfo(info)},
24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      channel_{Channel::GetFromMessageInfo(info)},
25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      info_{info},
26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      replied_{IsImpulse()} {
27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto svc = service_.lock();
28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (svc)
29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    state_ = svc->endpoint()->AllocateMessageState();
30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// C++11 specifies the move semantics for shared_ptr but not weak_ptr. This
33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// means we have to manually implement the desired move semantics for Message.
34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoMessage::Message(Message&& other) { *this = std::move(other); }
35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoMessage& Message::operator=(Message&& other) {
37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  Destroy();
38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto base = reinterpret_cast<std::uint8_t*>(&info_);
39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::fill(&base[0], &base[sizeof(info_)], 0);
40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  replied_ = true;
41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::swap(service_, other.service_);
42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::swap(channel_, other.channel_);
43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::swap(info_, other.info_);
44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::swap(state_, other.state_);
45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::swap(replied_, other.replied_);
46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return *this;
47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoMessage::~Message() { Destroy(); }
50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid Message::Destroy() {
52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto svc = service_.lock();
53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (svc) {
54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (!replied_) {
55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      ALOGE(
56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          "ERROR: Service \"%s\" failed to reply to message: op=%d pid=%d "
57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          "cid=%d\n",
58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          svc->name_.c_str(), info_.op, info_.pid, info_.cid);
59f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      svc->DefaultHandleMessage(*this);
60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    }
61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    svc->endpoint()->FreeMessageState(state_);
62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  state_ = nullptr;
64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  service_.reset();
65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  channel_.reset();
66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoconst std::uint8_t* Message::ImpulseBegin() const {
69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return reinterpret_cast<const std::uint8_t*>(info_.impulse);
70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoconst std::uint8_t* Message::ImpulseEnd() const {
73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return ImpulseBegin() + (IsImpulse() ? GetSendLength() : 0);
74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
76f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<size_t> Message::ReadVector(const struct iovec* vector,
77f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko                                   size_t vector_length) {
78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::ReadVector");
79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (auto svc = service_.lock()) {
80f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return svc->endpoint()->ReadMessageData(this, vector, vector_length);
81f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  } else {
82f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{ESHUTDOWN};
83f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  }
84f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko}
85f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko
86f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Message::ReadVectorAll(const struct iovec* vector,
87f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko                                    size_t vector_length) {
88f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  PDX_TRACE_NAME("Message::ReadVectorAll");
89f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  if (auto svc = service_.lock()) {
90f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    const auto status =
91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        svc->endpoint()->ReadMessageData(this, vector, vector_length);
92f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    if (!status)
93f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      return status.error_status();
94f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    size_t size_to_read = 0;
95f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    for (size_t i = 0; i < vector_length; i++)
96f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      size_to_read += vector[i].iov_len;
97f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    if (status.get() < size_to_read)
98f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      return ErrorStatus{EIO};
99f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return {};
100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
101f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{ESHUTDOWN};
102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
105f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<size_t> Message::Read(void* buffer, size_t length) {
106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::Read");
107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (auto svc = service_.lock()) {
108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const struct iovec vector = {buffer, length};
109f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return svc->endpoint()->ReadMessageData(this, &vector, 1);
110f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  } else {
111f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{ESHUTDOWN};
112f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  }
113f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko}
114f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko
115f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<size_t> Message::WriteVector(const struct iovec* vector,
116f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko                                    size_t vector_length) {
117f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  PDX_TRACE_NAME("Message::WriteVector");
118f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  if (auto svc = service_.lock()) {
119f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return svc->endpoint()->WriteMessageData(this, vector, vector_length);
120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
121f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{ESHUTDOWN};
122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
125f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Message::WriteVectorAll(const struct iovec* vector,
126f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko                                     size_t vector_length) {
127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::WriteVector");
128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (auto svc = service_.lock()) {
129f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    const auto status =
130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        svc->endpoint()->WriteMessageData(this, vector, vector_length);
131f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    if (!status)
132f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      return status.error_status();
133f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    size_t size_to_write = 0;
134f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    for (size_t i = 0; i < vector_length; i++)
135f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      size_to_write += vector[i].iov_len;
136f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    if (status.get() < size_to_write)
137f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      return ErrorStatus{EIO};
138f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return {};
139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
140f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{ESHUTDOWN};
141e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
144f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<size_t> Message::Write(const void* buffer, size_t length) {
145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::Write");
146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (auto svc = service_.lock()) {
147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const struct iovec vector = {const_cast<void*>(buffer), length};
148f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return svc->endpoint()->WriteMessageData(this, &vector, 1);
149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
150f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{ESHUTDOWN};
151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
154f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<FileReference> Message::PushFileHandle(const LocalHandle& handle) {
155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::PushFileHandle");
156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (auto svc = service_.lock()) {
157f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return svc->endpoint()->PushFileHandle(this, handle);
158e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
159f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{ESHUTDOWN};
160e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
162e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
163f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<FileReference> Message::PushFileHandle(const BorrowedHandle& handle) {
164e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::PushFileHandle");
165e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (auto svc = service_.lock()) {
166f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return svc->endpoint()->PushFileHandle(this, handle);
167e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
168f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{ESHUTDOWN};
169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
172f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<FileReference> Message::PushFileHandle(const RemoteHandle& handle) {
173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::PushFileHandle");
174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (auto svc = service_.lock()) {
175f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return svc->endpoint()->PushFileHandle(this, handle);
176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
177f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{ESHUTDOWN};
178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
181f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<ChannelReference> Message::PushChannelHandle(
182f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    const LocalChannelHandle& handle) {
183e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::PushChannelHandle");
184e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (auto svc = service_.lock()) {
185f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return svc->endpoint()->PushChannelHandle(this, handle);
186e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
187f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{ESHUTDOWN};
188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
190e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
191f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<ChannelReference> Message::PushChannelHandle(
192e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const BorrowedChannelHandle& handle) {
193e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::PushChannelHandle");
194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (auto svc = service_.lock()) {
195f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return svc->endpoint()->PushChannelHandle(this, handle);
196e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
197f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{ESHUTDOWN};
198e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
199e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
200e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
201f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<ChannelReference> Message::PushChannelHandle(
202f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    const RemoteChannelHandle& handle) {
203e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::PushChannelHandle");
204e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (auto svc = service_.lock()) {
205f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return svc->endpoint()->PushChannelHandle(this, handle);
206e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
207f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{ESHUTDOWN};
208e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
209e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
210e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
211e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool Message::GetFileHandle(FileReference ref, LocalHandle* handle) {
212e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::GetFileHandle");
213e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto svc = service_.lock();
214e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (!svc)
215e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return false;
216e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
217e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (ref >= 0) {
218e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    *handle = svc->endpoint()->GetFileHandle(this, ref);
219e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (!handle->IsValid())
220e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return false;
221e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
222e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    *handle = LocalHandle{ref};
223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
224e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return true;
225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
227e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool Message::GetChannelHandle(ChannelReference ref,
228e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                               LocalChannelHandle* handle) {
229e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::GetChannelHandle");
230e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto svc = service_.lock();
231e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (!svc)
232e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return false;
233e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
234e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (ref >= 0) {
235e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    *handle = svc->endpoint()->GetChannelHandle(this, ref);
236e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (!handle->valid())
237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return false;
238e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
239e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    *handle = LocalChannelHandle{nullptr, ref};
240e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
241e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return true;
242e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
243e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
244f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Message::Reply(int return_code) {
245e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::Reply");
246e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto svc = service_.lock();
247e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (!replied_ && svc) {
248f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    const auto ret = svc->endpoint()->MessageReply(this, return_code);
249f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    replied_ = ret.ok();
250f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ret;
251e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
252f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{EINVAL};
253e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
254e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
255e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
256f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Message::ReplyFileDescriptor(unsigned int fd) {
257e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::ReplyFileDescriptor");
258e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto svc = service_.lock();
259e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (!replied_ && svc) {
260f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    const auto ret = svc->endpoint()->MessageReplyFd(this, fd);
261f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    replied_ = ret.ok();
262f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ret;
263e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
264f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{EINVAL};
265e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
266e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
267e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
268f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Message::ReplyError(unsigned int error) {
269e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::ReplyError");
270e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto svc = service_.lock();
271e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (!replied_ && svc) {
272f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    const auto ret =
273f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko        svc->endpoint()->MessageReply(this, -static_cast<int>(error));
274f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    replied_ = ret.ok();
275f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ret;
276e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
277f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{EINVAL};
278e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
279e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
280e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
281f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Message::Reply(const LocalHandle& handle) {
282e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::ReplyFileHandle");
283e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto svc = service_.lock();
284e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (!replied_ && svc) {
285f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    Status<void> ret;
286e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
287e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (handle)
288e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      ret = svc->endpoint()->MessageReplyFd(this, handle.Get());
289e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    else
290e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      ret = svc->endpoint()->MessageReply(this, handle.Get());
291e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
292f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    replied_ = ret.ok();
293f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ret;
294e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
295f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{EINVAL};
296e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
297e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
298e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
299f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Message::Reply(const BorrowedHandle& handle) {
300e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::ReplyFileHandle");
301e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto svc = service_.lock();
302e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (!replied_ && svc) {
303f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    Status<void> ret;
304e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
305e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (handle)
306e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      ret = svc->endpoint()->MessageReplyFd(this, handle.Get());
307e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    else
308e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      ret = svc->endpoint()->MessageReply(this, handle.Get());
309e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
310f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    replied_ = ret.ok();
311f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ret;
312e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
313f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{EINVAL};
314e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
315e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
316e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
317f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Message::Reply(const RemoteHandle& handle) {
318e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::ReplyFileHandle");
319e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto svc = service_.lock();
320e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (!replied_ && svc) {
321f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    Status<void> ret;
322f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko
323f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    if (handle)
324f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      ret = svc->endpoint()->MessageReply(this, handle.Get());
325f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    else
326f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      ret = svc->endpoint()->MessageReply(this, handle.Get());
327f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko
328f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    replied_ = ret.ok();
329f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ret;
330e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
331f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{EINVAL};
332e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
333e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
334e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
335f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Message::Reply(const LocalChannelHandle& handle) {
336e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto svc = service_.lock();
337e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (!replied_ && svc) {
338f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    const auto ret = svc->endpoint()->MessageReplyChannelHandle(this, handle);
339f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    replied_ = ret.ok();
340f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ret;
341e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
342f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{EINVAL};
343e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
344e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
345e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
346f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Message::Reply(const BorrowedChannelHandle& handle) {
347e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto svc = service_.lock();
348e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (!replied_ && svc) {
349f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    const auto ret = svc->endpoint()->MessageReplyChannelHandle(this, handle);
350f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    replied_ = ret.ok();
351f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ret;
352e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
353f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{EINVAL};
354e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
355e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
356e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
357f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Message::Reply(const RemoteChannelHandle& handle) {
358e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto svc = service_.lock();
359e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (!replied_ && svc) {
360f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    const auto ret = svc->endpoint()->MessageReplyChannelHandle(this, handle);
361f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    replied_ = ret.ok();
362f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ret;
363e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
364f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{EINVAL};
365e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
366e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
367e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
368f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Message::ModifyChannelEvents(int clear_mask, int set_mask) {
369e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::ModifyChannelEvents");
370e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (auto svc = service_.lock()) {
371f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return svc->endpoint()->ModifyChannelEvents(info_.cid, clear_mask,
372f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko                                                set_mask);
373e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
374f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{ESHUTDOWN};
375e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
376e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
377e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
378e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<RemoteChannelHandle> Message::PushChannel(
379e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    int flags, const std::shared_ptr<Channel>& channel, int* channel_id) {
380e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::PushChannel");
381e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (auto svc = service_.lock()) {
382e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return svc->PushChannel(this, flags, channel, channel_id);
383e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
384e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorStatus(ESHUTDOWN);
385e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
386e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
387e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
388e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<RemoteChannelHandle> Message::PushChannel(
389e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    Service* service, int flags, const std::shared_ptr<Channel>& channel,
390e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    int* channel_id) {
391e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::PushChannel");
392e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return service->PushChannel(this, flags, channel, channel_id);
393e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
394e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
395e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<int> Message::CheckChannel(ChannelReference ref,
396e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                  std::shared_ptr<Channel>* channel) const {
397e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::CheckChannel");
398e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (auto svc = service_.lock()) {
399e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return svc->CheckChannel(this, ref, channel);
400e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
401e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ErrorStatus(ESHUTDOWN);
402e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
403e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
404e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
405e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<int> Message::CheckChannel(const Service* service, ChannelReference ref,
406e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                  std::shared_ptr<Channel>* channel) const {
407e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Message::CheckChannel");
408e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return service->CheckChannel(this, ref, channel);
409e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
410e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
411e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkopid_t Message::GetProcessId() const { return info_.pid; }
412e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
413e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkopid_t Message::GetThreadId() const { return info_.tid; }
414e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
415e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkouid_t Message::GetEffectiveUserId() const { return info_.euid; }
416e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
417e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkogid_t Message::GetEffectiveGroupId() const { return info_.egid; }
418e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
419e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Message::GetChannelId() const { return info_.cid; }
420e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
421e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Message::GetMessageId() const { return info_.mid; }
422e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
423e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Message::GetOp() const { return info_.op; }
424e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
425e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Message::GetFlags() const { return info_.flags; }
426e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
427e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkosize_t Message::GetSendLength() const { return info_.send_len; }
428e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
429e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkosize_t Message::GetReceiveLength() const { return info_.recv_len; }
430e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
431e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkosize_t Message::GetFileDescriptorCount() const { return info_.fd_count; }
432e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
433e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::shared_ptr<Channel> Message::GetChannel() const { return channel_.lock(); }
434e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
435f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Message::SetChannel(const std::shared_ptr<Channel>& chan) {
436e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  channel_ = chan;
437f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  Status<void> status;
438e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (auto svc = service_.lock())
439f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    status = svc->SetChannel(info_.cid, chan);
440f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  return status;
441e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
442e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
443e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::shared_ptr<Service> Message::GetService() const { return service_.lock(); }
444e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
445e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoconst MessageInfo& Message::GetInfo() const { return info_; }
446e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
447e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoService::Service(const std::string& name, std::unique_ptr<Endpoint> endpoint)
448e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    : name_(name), endpoint_{std::move(endpoint)} {
449e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (!endpoint_)
450e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return;
451e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
452f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  const auto status = endpoint_->SetService(this);
453f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  ALOGE_IF(!status, "Failed to set service context because: %s",
454f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko           status.GetErrorMessage().c_str());
455e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
456e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
457e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoService::~Service() {
458e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (endpoint_) {
459f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    const auto status = endpoint_->SetService(nullptr);
460f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    ALOGE_IF(!status, "Failed to clear service context because: %s",
461f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko             status.GetErrorMessage().c_str());
462e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
463e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
464e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
465e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::shared_ptr<Service> Service::GetFromMessageInfo(const MessageInfo& info) {
466e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return info.service ? info.service->shared_from_this()
467e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                      : std::shared_ptr<Service>();
468e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
469e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
470e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool Service::IsInitialized() const { return endpoint_.get() != nullptr; }
471e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
472e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::shared_ptr<Channel> Service::OnChannelOpen(Message& /*message*/) {
473e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return nullptr;
474e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
475e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
476e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid Service::OnChannelClose(Message& /*message*/,
477e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                             const std::shared_ptr<Channel>& /*channel*/) {}
478e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
479f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Service::SetChannel(int channel_id,
480f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko                                 const std::shared_ptr<Channel>& channel) {
481e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Service::SetChannel");
482e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::lock_guard<std::mutex> autolock(channels_mutex_);
483e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
484f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  const auto status = endpoint_->SetChannel(channel_id, channel.get());
485f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  if (!status) {
486e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    ALOGE("%s::SetChannel: Failed to set channel context: %s\n", name_.c_str(),
487f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko          status.GetErrorMessage().c_str());
488e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
489e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // It's possible someone mucked with things behind our back by calling the C
490e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // API directly. Since we know the channel id isn't valid, make sure we
491e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // don't have it in the channels map.
492f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    if (status.error() == ENOENT)
493f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      channels_.erase(channel_id);
494f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  } else {
495f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    if (channel != nullptr)
496f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      channels_[channel_id] = channel;
497f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    else
498e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      channels_.erase(channel_id);
499e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
500f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  return status;
501e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
502e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
503e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::shared_ptr<Channel> Service::GetChannel(int channel_id) const {
504e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Service::GetChannel");
505e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::lock_guard<std::mutex> autolock(channels_mutex_);
506e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
507e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto search = channels_.find(channel_id);
508e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (search != channels_.end())
509e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return search->second;
510e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  else
511e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return nullptr;
512e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
513e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
514f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Service::CloseChannel(int channel_id) {
515e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Service::CloseChannel");
516e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::lock_guard<std::mutex> autolock(channels_mutex_);
517e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
518f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  const auto status = endpoint_->CloseChannel(channel_id);
519e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
520e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Always erase the map entry, in case someone mucked with things behind our
521e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // back using the C API directly.
522e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  channels_.erase(channel_id);
523e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
524f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  return status;
525e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
526e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
527f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Service::ModifyChannelEvents(int channel_id, int clear_mask,
528f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko                                          int set_mask) {
529e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Service::ModifyChannelEvents");
530e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return endpoint_->ModifyChannelEvents(channel_id, clear_mask, set_mask);
531e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
532e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
533e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<RemoteChannelHandle> Service::PushChannel(
534e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    Message* message, int flags, const std::shared_ptr<Channel>& channel,
535e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    int* channel_id) {
536e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Service::PushChannel");
537e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
538e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::lock_guard<std::mutex> autolock(channels_mutex_);
539e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
540e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int channel_id_temp = -1;
541e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  Status<RemoteChannelHandle> ret =
542e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      endpoint_->PushChannel(message, flags, channel.get(), &channel_id_temp);
543e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ALOGE_IF(!ret.ok(), "%s::PushChannel: Failed to push channel: %s",
544e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko           name_.c_str(), strerror(ret.error()));
545e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
546e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (channel && channel_id_temp != -1)
547e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    channels_[channel_id_temp] = channel;
548e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (channel_id)
549e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    *channel_id = channel_id_temp;
550e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
551e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return ret;
552e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
553e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
554e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<int> Service::CheckChannel(const Message* message, ChannelReference ref,
555e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                  std::shared_ptr<Channel>* channel) const {
556e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_TRACE_NAME("Service::CheckChannel");
557e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
558e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Synchronization to maintain consistency between the kernel's channel
559e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // context pointer and the userspace channels_ map. Other threads may attempt
560e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // to modify the map at the same time, which could cause the channel context
561e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // pointer returned by the kernel to be invalid.
562e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::lock_guard<std::mutex> autolock(channels_mutex_);
563e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
564e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  Channel* channel_context = nullptr;
565e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  Status<int> ret = endpoint_->CheckChannel(
566e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      message, ref, channel ? &channel_context : nullptr);
567e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (ret && channel) {
568e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (channel_context)
569e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      *channel = channel_context->shared_from_this();
570e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    else
571e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      *channel = nullptr;
572e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
573e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
574e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return ret;
575e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
576e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
577e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::string Service::DumpState(size_t /*max_length*/) { return ""; }
578e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
579f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Service::HandleMessage(Message& message) {
580e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  return DefaultHandleMessage(message);
581e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
582e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
583e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid Service::HandleImpulse(Message& /*impulse*/) {}
584e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
585f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Service::HandleSystemMessage(Message& message) {
586e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const MessageInfo& info = message.GetInfo();
587e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
588e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  switch (info.op) {
589e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    case opcodes::CHANNEL_OPEN: {
590e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      ALOGD("%s::OnChannelOpen: pid=%d cid=%d\n", name_.c_str(), info.pid,
591e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            info.cid);
592e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      message.SetChannel(OnChannelOpen(message));
593f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      return message.Reply(0);
594e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    }
595e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
596e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    case opcodes::CHANNEL_CLOSE: {
597e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      ALOGD("%s::OnChannelClose: pid=%d cid=%d\n", name_.c_str(), info.pid,
598e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            info.cid);
599e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      OnChannelClose(message, Channel::GetFromMessageInfo(info));
600e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      message.SetChannel(nullptr);
601f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      return message.Reply(0);
602e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    }
603e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
604e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    case opcodes::REPORT_SYSPROP_CHANGE:
605e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      ALOGD("%s:REPORT_SYSPROP_CHANGE: pid=%d cid=%d\n", name_.c_str(),
606e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            info.pid, info.cid);
607e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      OnSysPropChange();
608e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      android::report_sysprop_change();
609f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      return message.Reply(0);
610e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
611e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    case opcodes::DUMP_STATE: {
612e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      ALOGD("%s:DUMP_STATE: pid=%d cid=%d\n", name_.c_str(), info.pid,
613e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            info.cid);
614e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      auto response = DumpState(message.GetReceiveLength());
615e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      const size_t response_size = response.size() < message.GetReceiveLength()
616e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                       ? response.size()
617e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                       : message.GetReceiveLength();
618f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      const Status<size_t> status =
619e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko          message.Write(response.data(), response_size);
620f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      if (status && status.get() < response_size)
621f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko        return message.ReplyError(EIO);
622e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      else
623f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko        return message.Reply(status);
624e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    }
625e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
626e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    default:
627f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      return ErrorStatus{EOPNOTSUPP};
628e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
629e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
630e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
631f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Service::DefaultHandleMessage(Message& message) {
632e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const MessageInfo& info = message.GetInfo();
633e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
634e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ALOGD_IF(TRACE, "Service::DefaultHandleMessage: pid=%d cid=%d op=%d\n",
635e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko           info.pid, info.cid, info.op);
636e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
637e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  switch (info.op) {
638e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    case opcodes::CHANNEL_OPEN:
639e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    case opcodes::CHANNEL_CLOSE:
640e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    case opcodes::REPORT_SYSPROP_CHANGE:
641e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    case opcodes::DUMP_STATE:
642f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      return HandleSystemMessage(message);
643e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
644e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    default:
645f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      return message.ReplyError(EOPNOTSUPP);
646e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
647e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
648e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
649e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid Service::OnSysPropChange() {}
650e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
651f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Service::ReceiveAndDispatch() {
652e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  Message message;
653f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  const auto status = endpoint_->MessageReceive(&message);
654f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  if (!status) {
655f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    ALOGE("Failed to receive message: %s\n", status.GetErrorMessage().c_str());
656f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return status;
657e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
658e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
659e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::shared_ptr<Service> service = message.GetService();
660e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
661e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (!service) {
662e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    ALOGE("Service::ReceiveAndDispatch: service context is NULL!!!\n");
663e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // Don't block the sender indefinitely in this error case.
664e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    endpoint_->MessageReply(&message, -EINVAL);
665f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return ErrorStatus{EINVAL};
666e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
667e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
668e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  if (message.IsImpulse()) {
669e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    service->HandleImpulse(message);
670f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return {};
671e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else if (service->HandleSystemMessage(message)) {
672f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko    return {};
673e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  } else {
674e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return service->HandleMessage(message);
675e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
676e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
677e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
678f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<void> Service::Cancel() { return endpoint_->Cancel(); }
679e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
680e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace pdx
681e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // namespace android
682