xref: /aosp_15_r20/system/libfmq/include/fmq/AidlMessageQueueCpp.h (revision be431cd81a9a2349eaea34eb56fcf6d1608da596)
1 /*
2  * Copyright (C) 2024 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 #include <android/hardware/common/fmq/MQDescriptor.h>
19 #include <android/hardware/common/fmq/SynchronizedReadWrite.h>
20 #include <android/hardware/common/fmq/UnsynchronizedWrite.h>
21 #include <fmq/MQDescriptorBase.h>
22 #include "AidlMQDescriptorShimCpp.h"
23 #include "AidlMessageQueueBase.h"
24 namespace android {
25 
26 template <>
27 struct FlavorTypeToValue<android::hardware::common::fmq::SynchronizedReadWrite> {
28     static constexpr MQFlavor value = hardware::kSynchronizedReadWrite;
29 };
30 
31 template <>
32 struct FlavorTypeToValue<android::hardware::common::fmq::UnsynchronizedWrite> {
33     static constexpr MQFlavor value = hardware::kUnsynchronizedWrite;
34 };
35 
36 struct BackendTypesStoreCpp {
37     template <typename T, MQFlavor flavor>
38     using AidlMQDescriptorShimType = android::details::AidlMQDescriptorShimCpp<T, flavor>;
39     using GrantorDescriptorType = android::hardware::common::fmq::GrantorDescriptor;
40     template <typename T, typename flavor>
41     using MQDescriptorType = android::hardware::common::fmq::MQDescriptor<T, flavor>;
42     using FileDescriptorType = os::ParcelFileDescriptor;
43     static FileDescriptorType createFromInt(int fd) {
44         return FileDescriptorType(binder::unique_fd(fd));
45     }
46 };
47 
48 template <typename T, typename U>
49 struct AidlMessageQueueCpp final : public AidlMessageQueueBase<T, U, BackendTypesStoreCpp> {
50     AidlMessageQueueCpp(const android::hardware::common::fmq::MQDescriptor<T, U>& desc,
51                         bool resetPointers = true);
52     ~AidlMessageQueueCpp() = default;
53 
54     /**
55      * This constructor uses Ashmem shared memory to create an FMQ
56      * that can contain a maximum of 'numElementsInQueue' elements of type T.
57      *
58      * @param numElementsInQueue Capacity of the AidlMessageQueueCpp in terms of T.
59      * @param configureEventFlagWord Boolean that specifies if memory should
60      * also be allocated and mapped for an EventFlag word.
61      * @param bufferFd User-supplied file descriptor to map the memory for the ringbuffer
62      * By default, bufferFd=-1 means library will allocate ashmem region for ringbuffer.
63      * MessageQueue takes ownership of the file descriptor.
64      * @param bufferSize size of buffer in bytes that bufferFd represents. This
65      * size must be larger than or equal to (numElementsInQueue * sizeof(T)).
66      * Otherwise, operations will cause out-of-bounds memory access.
67      */
68     AidlMessageQueueCpp(size_t numElementsInQueue, bool configureEventFlagWord,
69                         android::base::unique_fd bufferFd, size_t bufferSize);
70 
71     AidlMessageQueueCpp(size_t numElementsInQueue, bool configureEventFlagWord = false)
72         : AidlMessageQueueCpp(numElementsInQueue, configureEventFlagWord,
73                               android::base::unique_fd(), 0) {}
74 
75     template <typename V = T>
76     AidlMessageQueueCpp(size_t numElementsInQueue, bool configureEventFlagWord = false,
77                         std::enable_if_t<std::is_same_v<V, MQErased>, size_t> quantum = sizeof(T))
78         : AidlMessageQueueCpp(numElementsInQueue, configureEventFlagWord,
79                               android::base::unique_fd(), 0, quantum) {}
80 
81     template <typename V = T>
82     AidlMessageQueueCpp(size_t numElementsInQueue, bool configureEventFlagWord,
83                         android::base::unique_fd bufferFd, size_t bufferSize,
84                         std::enable_if_t<std::is_same_v<V, MQErased>, size_t> quantum);
85 };
86 
87 template <typename T, typename U>
88 AidlMessageQueueCpp<T, U>::AidlMessageQueueCpp(
89         const android::hardware::common::fmq::MQDescriptor<T, U>& desc, bool resetPointers)
90     : AidlMessageQueueBase<T, U, BackendTypesStoreCpp>(desc, resetPointers) {}
91 
92 template <typename T, typename U>
93 AidlMessageQueueCpp<T, U>::AidlMessageQueueCpp(size_t numElementsInQueue,
94                                                bool configureEventFlagWord,
95                                                android::base::unique_fd bufferFd, size_t bufferSize)
96     : AidlMessageQueueBase<T, U, BackendTypesStoreCpp>(numElementsInQueue, configureEventFlagWord,
97                                                        std::move(bufferFd), bufferSize) {}
98 
99 template <typename T, typename U>
100 template <typename V>
101 AidlMessageQueueCpp<T, U>::AidlMessageQueueCpp(
102         size_t numElementsInQueue, bool configureEventFlagWord, android::base::unique_fd bufferFd,
103         size_t bufferSize, std::enable_if_t<std::is_same_v<V, MQErased>, size_t> quantum)
104     : AidlMessageQueueBase<T, U, BackendTypesStoreCpp>(numElementsInQueue, configureEventFlagWord,
105                                                        std::move(bufferFd), bufferSize, quantum) {}
106 
107 }  // namespace android