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 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 23 bool ChannelParcelable::IsValid() const { 24 return !!data_fd_ && !!pollin_event_fd_ && !!pollhup_event_fd_; 25 } 26 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 38 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 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