1 #include "include/private/dvr/buffer_hub_queue_parcelable.h"
2 
3 #include <binder/Parcel.h>
4 #include <pdx/default_transport/channel_parcelable.h>
5 
6 namespace android {
7 namespace dvr {
8 
9 template <BufferHubQueueParcelableMagic Magic>
IsValid() const10 bool BufferHubQueueParcelable<Magic>::IsValid() const {
11   return !!channel_parcelable_ && channel_parcelable_->IsValid();
12 }
13 
14 template <BufferHubQueueParcelableMagic Magic>
TakeChannelHandle()15 pdx::LocalChannelHandle BufferHubQueueParcelable<Magic>::TakeChannelHandle() {
16   if (!IsValid()) {
17     ALOGE(
18         "BufferHubQueueParcelable::TakeChannelHandle: Invalid channel parcel.");
19     return {};  // Returns an empty channel handle.
20   }
21 
22   // Take channel handle out of the parcelable and reset the parcelable.
23   pdx::LocalChannelHandle handle = channel_parcelable_->TakeChannelHandle();
24   // Now channel_parcelable_ should already be invalid, but reset it to release
25   // the invalid parcelable object from unique_ptr.
26   channel_parcelable_ = nullptr;
27   return handle;
28 }
29 
30 template <BufferHubQueueParcelableMagic Magic>
writeToParcel(Parcel * parcel) const31 status_t BufferHubQueueParcelable<Magic>::writeToParcel(Parcel* parcel) const {
32   if (!IsValid()) {
33     ALOGE("BufferHubQueueParcelable::writeToParcel: Invalid channel.");
34     return -EINVAL;
35   }
36 
37   status_t res = parcel->writeUint32(Magic);
38   if (res != OK) {
39     ALOGE("BufferHubQueueParcelable::writeToParcel: Cannot write magic.");
40     return res;
41   }
42 
43   return channel_parcelable_->writeToParcel(parcel);
44 }
45 
46 template <BufferHubQueueParcelableMagic Magic>
readFromParcel(const Parcel * parcel)47 status_t BufferHubQueueParcelable<Magic>::readFromParcel(const Parcel* parcel) {
48   if (IsValid()) {
49     ALOGE(
50         "BufferHubQueueParcelable::readFromParcel: This parcelable object has "
51         "been initialized already.");
52     return -EINVAL;
53   }
54 
55   uint32_t out_magic = 0;
56   status_t res = OK;
57 
58   res = parcel->readUint32(&out_magic);
59   if (res != OK)
60     return res;
61 
62   if (out_magic != Magic) {
63     ALOGE(
64         "BufferHubQueueParcelable::readFromParcel: Unexpected magic: 0x%x, "
65         "epxected: 0x%x",
66         out_magic, Magic);
67     return -EINVAL;
68   }
69 
70   // (Re)Alocate channel parcelable object.
71   channel_parcelable_ =
72       std::make_unique<pdx::default_transport::ChannelParcelable>();
73   return channel_parcelable_->readFromParcel(parcel);
74 }
75 
76 template class BufferHubQueueParcelable<
77     BufferHubQueueParcelableMagic::Producer>;
78 template class BufferHubQueueParcelable<
79     BufferHubQueueParcelableMagic::Consumer>;
80 
81 }  // namespace dvr
82 }  // namespace android
83