1 #include "uds/channel_parcelable.h"
2
3 #include <binder/Parcel.h>
4 #include <uds/channel_manager.h>
5
6 namespace android {
7 namespace pdx {
8 namespace uds {
9
10 namespace {
11
12 static constexpr uint32_t kUdsMagicParcelHeader = 0x7564736d; // 'udsm'.
13
14 } // namespace
15
ChannelParcelable(LocalHandle data_fd,LocalHandle pollin_event_fd,LocalHandle pollhup_event_fd)16 ChannelParcelable::ChannelParcelable(LocalHandle data_fd,
17 LocalHandle pollin_event_fd,
18 LocalHandle pollhup_event_fd)
19 : data_fd_{std::move(data_fd)},
20 pollin_event_fd_{std::move(pollin_event_fd)},
21 pollhup_event_fd_{std::move(pollhup_event_fd)} {}
22
IsValid() const23 bool ChannelParcelable::IsValid() const {
24 return !!data_fd_ && !!pollin_event_fd_ && !!pollhup_event_fd_;
25 }
26
TakeChannelHandle()27 LocalChannelHandle ChannelParcelable::TakeChannelHandle() {
28 if (!IsValid()) {
29 ALOGE("ChannelParcelable::TakeChannelHandle: Invalid channel parcel.");
30 return {}; // Returns an empty channel handle.
31 }
32
33 return ChannelManager::Get().CreateHandle(std::move(data_fd_),
34 std::move(pollin_event_fd_),
35 std::move(pollhup_event_fd_));
36 }
37
writeToParcel(Parcel * parcel) const38 status_t ChannelParcelable::writeToParcel(Parcel* parcel) const {
39 status_t res = OK;
40
41 if (!IsValid()) {
42 ALOGE("ChannelParcelable::writeToParcel: Invalid channel parcel.");
43 return BAD_VALUE;
44 }
45
46 res = parcel->writeUint32(kUdsMagicParcelHeader);
47 if (res != OK) {
48 ALOGE("ChannelParcelable::writeToParcel: Cannot write magic: res=%d.", res);
49 return res;
50 }
51
52 res = parcel->writeFileDescriptor(data_fd_.Get());
53 if (res != OK) {
54 ALOGE("ChannelParcelable::writeToParcel: Cannot write data fd: res=%d.",
55 res);
56 return res;
57 }
58
59 res = parcel->writeFileDescriptor(pollin_event_fd_.Get());
60 if (res != OK) {
61 ALOGE(
62 "ChannelParcelable::writeToParcel: Cannot write pollin event fd: "
63 "res=%d.",
64 res);
65 return res;
66 }
67
68 res = parcel->writeFileDescriptor(pollhup_event_fd_.Get());
69 if (res != OK) {
70 ALOGE(
71 "ChannelParcelable::writeToParcel: Cannot write pollhup event fd: "
72 "res=%d.",
73 res);
74 return res;
75 }
76
77 return res;
78 }
79
readFromParcel(const Parcel * parcel)80 status_t ChannelParcelable::readFromParcel(const Parcel* parcel) {
81 uint32_t magic = 0;
82 status_t res = OK;
83
84 if (IsValid()) {
85 ALOGE(
86 "ChannelParcelable::readFromParcel: This channel parcel is already "
87 "initailzied.");
88 return ALREADY_EXISTS;
89 }
90
91 res = parcel->readUint32(&magic);
92 if (res != OK) {
93 ALOGE("ChannelParcelable::readFromParcel: Failed to read magic: res=%d.",
94 res);
95 return res;
96 }
97
98 if (magic != kUdsMagicParcelHeader) {
99 ALOGE(
100 "ChannelParcelable::readFromParcel: Unknown magic: 0x%x, epxected: "
101 "0x%x",
102 magic, kUdsMagicParcelHeader);
103 return BAD_VALUE;
104 }
105
106 // TODO(b/69010509): We have to dup() the FD from android::Parcel as it
107 // doesn't support taking out the FD's ownership. We can remove the dup() here
108 // once android::Parcel support such operation.
109 data_fd_.Reset(dup(parcel->readFileDescriptor()));
110 pollin_event_fd_.Reset(dup(parcel->readFileDescriptor()));
111 pollhup_event_fd_.Reset(dup(parcel->readFileDescriptor()));
112 if (!IsValid()) {
113 ALOGE(
114 "ChannelParcelable::readFromParcel: Cannot read fd from parcel: "
115 "data_fd=%d, pollin_event_fd=%d, pollhup_event_fd=%d.",
116 data_fd_.Get(), pollin_event_fd_.Get(), pollhup_event_fd_.Get());
117 return DEAD_OBJECT;
118 }
119
120 return res;
121 }
122
123 } // namespace uds
124 } // namespace pdx
125 } // namespace android
126