service.cpp 20 KB

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