1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <android-base/unique_fd.h>
20 #include <binder/Parcelable.h>
21 #include <utils/Errors.h>
22 
23 namespace android {
24 
25 class Parcel;
26 
27 namespace gui {
28 
29 class BitTube : public Parcelable {
30 public:
31     // creates an uninitialized BitTube (to unparcel into)
32     BitTube() = default;
33 
34     // creates a BitTube with a a specified send and receive buffer size
35     explicit BitTube(size_t bufsize);
36 
37     // creates a BitTube with a default (4KB) send buffer
38     struct DefaultSizeType {};
39     static constexpr DefaultSizeType DefaultSize{};
40     explicit BitTube(DefaultSizeType);
41 
42     explicit BitTube(const Parcel& data);
43 
44     virtual ~BitTube() = default;
45 
46     // check state after construction
47     status_t initCheck() const;
48 
49     // get receive file-descriptor
50     int getFd() const;
51 
52     // get the send file-descriptor.
53     int getSendFd() const;
54 
55     // moves the receive file descriptor out of this BitTube
56     base::unique_fd moveReceiveFd();
57 
58     // resets this BitTube's receive file descriptor to receiveFd
59     void setReceiveFd(base::unique_fd&& receiveFd);
60 
61     // send objects (sized blobs). All objects are guaranteed to be written or the call fails.
62     template <typename T>
sendObjects(BitTube * tube,T const * events,size_t count)63     static ssize_t sendObjects(BitTube* tube, T const* events, size_t count) {
64         return sendObjects(tube, events, count, sizeof(T));
65     }
66 
67     // receive objects (sized blobs). If the receiving buffer isn't large enough, excess messages
68     // are silently discarded.
69     template <typename T>
recvObjects(BitTube * tube,T * events,size_t count)70     static ssize_t recvObjects(BitTube* tube, T* events, size_t count) {
71         return recvObjects(tube, events, count, sizeof(T));
72     }
73 
74     // implement the Parcelable protocol. Only parcels the receive file descriptor
75     status_t writeToParcel(Parcel* reply) const;
76     status_t readFromParcel(const Parcel* parcel);
77 
78 private:
79     void init(size_t rcvbuf, size_t sndbuf);
80 
81     // send a message. The write is guaranteed to send the whole message or fail.
82     ssize_t write(void const* vaddr, size_t size);
83 
84     // receive a message. the passed buffer must be at least as large as the write call used to send
85     // the message, excess data is silently discarded.
86     ssize_t read(void* vaddr, size_t size);
87 
88     base::unique_fd mSendFd;
89     mutable base::unique_fd mReceiveFd;
90 
91     static ssize_t sendObjects(BitTube* tube, void const* events, size_t count, size_t objSize);
92 
93     static ssize_t recvObjects(BitTube* tube, void* events, size_t count, size_t objSize);
94 };
95 
96 } // namespace gui
97 } // namespace android
98