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