1 /*
2  * Copyright (C) 2022 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 <bufferpool2/BufferPoolTypes.h>
20 #include <map>
21 #include <memory>
22 #include <mutex>
23 #include <vector>
24 #include <list>
25 
26 namespace aidl::android::hardware::media::bufferpool2::implementation {
27 
28 bool isMessageLater(uint32_t curMsgId, uint32_t prevMsgId);
29 
30 bool isBufferInRange(BufferId from, BufferId to, BufferId bufferId);
31 
32 /**
33  * A collection of buffer status message FMQ for a buffer pool. buffer
34  * ownership/status change messages are sent via the FMQs from the clients.
35  */
36 class BufferStatusObserver {
37 private:
38     std::map<ConnectionId, std::unique_ptr<BufferStatusQueue>>
39             mBufferStatusQueues;
40 
41 public:
42     /** Creates a buffer status message FMQ for the specified
43      * connection(client).
44      *
45      * @param connectionId  connection Id of the specified client.
46      * @param fmqDescPtr    ptr of created FMQ's descriptor.
47      *
48      * @return OK if FMQ is created successfully.
49      *         NO_MEMORY when there is no memory.
50      *         CRITICAL_ERROR otherwise.
51      */
52     BufferPoolStatus open(ConnectionId id, StatusDescriptor* _Nonnull fmqDescPtr);
53 
54     /** Closes a buffer status message FMQ for the specified
55      * connection(client).
56      *
57      * @param connectionId  connection Id of the specified client.
58      *
59      * @return OK if the specified connection is closed successfully.
60      *         CRITICAL_ERROR otherwise.
61      */
62     BufferPoolStatus close(ConnectionId id);
63 
64     /** Retrieves all pending FMQ buffer status messages from clients.
65      *
66      * @param messages  retrieved pending messages.
67      */
68     void getBufferStatusChanges(std::vector<BufferStatusMessage> &messages);
69 };
70 
71 /**
72  * A buffer status message FMQ for a buffer pool client. Buffer ownership/status
73  * change messages are sent via the fmq to the buffer pool.
74  */
75 class BufferStatusChannel {
76 private:
77     bool mValid;
78     std::unique_ptr<BufferStatusQueue> mBufferStatusQueue;
79 
80 public:
81     /**
82      * Connects to a buffer status message FMQ from a descriptor of
83      * the created FMQ.
84      *
85      * @param fmqDesc   Descriptor of the created FMQ.
86      */
87     BufferStatusChannel(const StatusDescriptor &fmqDesc);
88 
89     /** Returns whether the FMQ is connected successfully. */
90     bool isValid();
91 
92     /** Returns whether the FMQ needs to be synced from the buffer pool */
93     bool needsSync();
94 
95     /**
96      * Posts a buffer release message to the buffer pool.
97      *
98      * @param connectionId  connection Id of the client.
99      * @param pending       currently pending buffer release messages.
100      * @param posted        posted buffer release messages.
101      */
102     void postBufferRelease(
103             ConnectionId connectionId,
104             std::list<BufferId> &pending, std::list<BufferId> &posted);
105 
106     /**
107      * Posts a buffer status message regarding the specified buffer
108      * transfer transaction.
109      *
110      * @param transactionId Id of the specified transaction.
111      * @param bufferId      buffer Id of the specified transaction.
112      * @param status        new status of the buffer.
113      * @param connectionId  connection Id of the client.
114      * @param targetId      connection Id of the receiver(only when the sender
115      *                      posts a status message).
116      * @param pending       currently pending buffer release messages.
117      * @param posted        posted buffer release messages.
118      *
119      * @return {@code true} when the specified message is posted,
120      *         {@code false} otherwise.
121      */
122     bool postBufferStatusMessage(
123             TransactionId transactionId,
124             BufferId bufferId,
125             BufferStatus status,
126             ConnectionId connectionId,
127             ConnectionId targetId,
128             std::list<BufferId> &pending, std::list<BufferId> &posted);
129 
130     /**
131      * Posts a buffer invaliadation message to the buffer pool.
132      *
133      * @param connectionId  connection Id of the client.
134      * @param invalidateId  invalidation ack to the buffer pool.
135      *                      if invalidation id is zero, the ack will not be
136      *                      posted.
137      * @param invalidated   sets {@code true} only when the invalidation ack is
138      *                      posted.
139      */
140     void postBufferInvalidateAck(
141             ConnectionId connectionId,
142             uint32_t invalidateId,
143             bool* _Nonnull invalidated);
144 };
145 
146 /**
147  * A buffer invalidation FMQ for a buffer pool client. Buffer invalidation
148  * messages are received via the fmq from the buffer pool. Buffer invalidation
149  * messages are handled as soon as possible.
150  */
151 class BufferInvalidationListener {
152 private:
153     bool mValid;
154     std::unique_ptr<BufferInvalidationQueue> mBufferInvalidationQueue;
155 
156 public:
157     /**
158      * Connects to a buffer invalidation FMQ from a descriptor of the created FMQ.
159      *
160      * @param fmqDesc   Descriptor of the created FMQ.
161      */
162     BufferInvalidationListener(const InvalidationDescriptor &fmqDesc);
163 
164     /** Retrieves all pending buffer invalidation messages from the buffer pool.
165      *
166      * @param messages  retrieved pending messages.
167      */
168     void getInvalidations(std::vector<BufferInvalidationMessage> &messages);
169 
170     /** Returns whether the FMQ is connected successfully. */
171     bool isValid();
172 };
173 
174 /**
175  * A buffer invalidation FMQ for a buffer pool. A buffer pool will send buffer
176  * invalidation messages to the clients via the FMQ. The FMQ is shared among
177  * buffer pool clients.
178  */
179 class BufferInvalidationChannel {
180 private:
181     bool mValid;
182     std::unique_ptr<BufferInvalidationQueue> mBufferInvalidationQueue;
183 
184 public:
185     /**
186      * Creates a buffer invalidation FMQ for a buffer pool.
187      */
188     BufferInvalidationChannel();
189 
190     /** Returns whether the FMQ is connected successfully. */
191     bool isValid();
192 
193     /**
194      * Retrieves the descriptor of a buffer invalidation FMQ. the descriptor may
195      * be passed to the client for buffer invalidation handling.
196      *
197      * @param fmqDescPtr    ptr of created FMQ's descriptor.
198      */
199     void getDesc(InvalidationDescriptor* _Nonnull fmqDescPtr);
200 
201     /** Posts a buffer invalidation for invalidated buffers.
202      *
203      * @param msgId     Invalidation message id which is used when clients send
204      *                  acks back via BufferStatusMessage
205      * @param fromId    The start bufferid of the invalidated buffers(inclusive)
206      * @param toId      The end bufferId of the invalidated buffers(inclusive)
207      */
208     void postInvalidation(uint32_t msgId, BufferId fromId, BufferId toId);
209 };
210 
211 }  // namespace aidl::android::hardware::media::bufferpool2::implementation
212