1*be431cd8SAndroid Build Coastguard Worker /* 2*be431cd8SAndroid Build Coastguard Worker * Copyright (C) 2020 The Android Open Source Project 3*be431cd8SAndroid Build Coastguard Worker * 4*be431cd8SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*be431cd8SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*be431cd8SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*be431cd8SAndroid Build Coastguard Worker * 8*be431cd8SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*be431cd8SAndroid Build Coastguard Worker * 10*be431cd8SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*be431cd8SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*be431cd8SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*be431cd8SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*be431cd8SAndroid Build Coastguard Worker * limitations under the License. 15*be431cd8SAndroid Build Coastguard Worker */ 16*be431cd8SAndroid Build Coastguard Worker #pragma once 17*be431cd8SAndroid Build Coastguard Worker #include <aidl/android/hardware/common/fmq/MQDescriptor.h> 18*be431cd8SAndroid Build Coastguard Worker #include <aidl/android/hardware/common/fmq/SynchronizedReadWrite.h> 19*be431cd8SAndroid Build Coastguard Worker #include <aidl/android/hardware/common/fmq/UnsynchronizedWrite.h> 20*be431cd8SAndroid Build Coastguard Worker #include "AidlMQDescriptorShim.h" 21*be431cd8SAndroid Build Coastguard Worker #include "AidlMessageQueueBase.h" 22*be431cd8SAndroid Build Coastguard Worker 23*be431cd8SAndroid Build Coastguard Worker namespace android { 24*be431cd8SAndroid Build Coastguard Worker using aidl::android::hardware::common::fmq::MQDescriptor; 25*be431cd8SAndroid Build Coastguard Worker using aidl::android::hardware::common::fmq::SynchronizedReadWrite; 26*be431cd8SAndroid Build Coastguard Worker using aidl::android::hardware::common::fmq::UnsynchronizedWrite; 27*be431cd8SAndroid Build Coastguard Worker using android::details::AidlMQDescriptorShim; 28*be431cd8SAndroid Build Coastguard Worker using android::hardware::MQFlavor; 29*be431cd8SAndroid Build Coastguard Worker 30*be431cd8SAndroid Build Coastguard Worker template <> 31*be431cd8SAndroid Build Coastguard Worker struct FlavorTypeToValue<aidl::android::hardware::common::fmq::SynchronizedReadWrite> { 32*be431cd8SAndroid Build Coastguard Worker static constexpr MQFlavor value = hardware::kSynchronizedReadWrite; 33*be431cd8SAndroid Build Coastguard Worker }; 34*be431cd8SAndroid Build Coastguard Worker 35*be431cd8SAndroid Build Coastguard Worker template <> 36*be431cd8SAndroid Build Coastguard Worker struct FlavorTypeToValue<aidl::android::hardware::common::fmq::UnsynchronizedWrite> { 37*be431cd8SAndroid Build Coastguard Worker static constexpr MQFlavor value = hardware::kUnsynchronizedWrite; 38*be431cd8SAndroid Build Coastguard Worker }; 39*be431cd8SAndroid Build Coastguard Worker 40*be431cd8SAndroid Build Coastguard Worker struct BackendTypesStore { 41*be431cd8SAndroid Build Coastguard Worker template <typename T, MQFlavor flavor> 42*be431cd8SAndroid Build Coastguard Worker using AidlMQDescriptorShimType = android::details::AidlMQDescriptorShim<T, flavor>; 43*be431cd8SAndroid Build Coastguard Worker using GrantorDescriptorType = aidl::android::hardware::common::fmq::GrantorDescriptor; 44*be431cd8SAndroid Build Coastguard Worker template <typename T, typename flavor> 45*be431cd8SAndroid Build Coastguard Worker using MQDescriptorType = aidl::android::hardware::common::fmq::MQDescriptor<T, flavor>; 46*be431cd8SAndroid Build Coastguard Worker using FileDescriptorType = ndk::ScopedFileDescriptor; 47*be431cd8SAndroid Build Coastguard Worker static FileDescriptorType createFromInt(int fd) { return FileDescriptorType(fd); } 48*be431cd8SAndroid Build Coastguard Worker }; 49*be431cd8SAndroid Build Coastguard Worker 50*be431cd8SAndroid Build Coastguard Worker template <typename T, typename U> 51*be431cd8SAndroid Build Coastguard Worker struct AidlMessageQueue final : public AidlMessageQueueBase<T, U, BackendTypesStore> { 52*be431cd8SAndroid Build Coastguard Worker AidlMessageQueue(const MQDescriptor<T, U>& desc, bool resetPointers = true); 53*be431cd8SAndroid Build Coastguard Worker ~AidlMessageQueue() = default; 54*be431cd8SAndroid Build Coastguard Worker 55*be431cd8SAndroid Build Coastguard Worker /** 56*be431cd8SAndroid Build Coastguard Worker * This constructor uses Ashmem shared memory to create an FMQ 57*be431cd8SAndroid Build Coastguard Worker * that can contain a maximum of 'numElementsInQueue' elements of type T. 58*be431cd8SAndroid Build Coastguard Worker * 59*be431cd8SAndroid Build Coastguard Worker * @param numElementsInQueue Capacity of the AidlMessageQueue in terms of T. 60*be431cd8SAndroid Build Coastguard Worker * @param configureEventFlagWord Boolean that specifies if memory should 61*be431cd8SAndroid Build Coastguard Worker * also be allocated and mapped for an EventFlag word. 62*be431cd8SAndroid Build Coastguard Worker * @param bufferFd User-supplied file descriptor to map the memory for the ringbuffer 63*be431cd8SAndroid Build Coastguard Worker * By default, bufferFd=-1 means library will allocate ashmem region for ringbuffer. 64*be431cd8SAndroid Build Coastguard Worker * MessageQueue takes ownership of the file descriptor. 65*be431cd8SAndroid Build Coastguard Worker * @param bufferSize size of buffer in bytes that bufferFd represents. This 66*be431cd8SAndroid Build Coastguard Worker * size must be larger than or equal to (numElementsInQueue * sizeof(T)). 67*be431cd8SAndroid Build Coastguard Worker * Otherwise, operations will cause out-of-bounds memory access. 68*be431cd8SAndroid Build Coastguard Worker */ 69*be431cd8SAndroid Build Coastguard Worker AidlMessageQueue(size_t numElementsInQueue, bool configureEventFlagWord, 70*be431cd8SAndroid Build Coastguard Worker android::base::unique_fd bufferFd, size_t bufferSize); 71*be431cd8SAndroid Build Coastguard Worker 72*be431cd8SAndroid Build Coastguard Worker AidlMessageQueue(size_t numElementsInQueue, bool configureEventFlagWord = false) 73*be431cd8SAndroid Build Coastguard Worker : AidlMessageQueue(numElementsInQueue, configureEventFlagWord, android::base::unique_fd(), 74*be431cd8SAndroid Build Coastguard Worker 0) {} 75*be431cd8SAndroid Build Coastguard Worker 76*be431cd8SAndroid Build Coastguard Worker template <typename V = T> 77*be431cd8SAndroid Build Coastguard Worker AidlMessageQueue(size_t numElementsInQueue, bool configureEventFlagWord = false, 78*be431cd8SAndroid Build Coastguard Worker std::enable_if_t<std::is_same_v<V, MQErased>, size_t> quantum = sizeof(T)) 79*be431cd8SAndroid Build Coastguard Worker : AidlMessageQueue(numElementsInQueue, configureEventFlagWord, android::base::unique_fd(), 80*be431cd8SAndroid Build Coastguard Worker 0, quantum) {} 81*be431cd8SAndroid Build Coastguard Worker 82*be431cd8SAndroid Build Coastguard Worker template <typename V = T> 83*be431cd8SAndroid Build Coastguard Worker AidlMessageQueue(size_t numElementsInQueue, bool configureEventFlagWord, 84*be431cd8SAndroid Build Coastguard Worker android::base::unique_fd bufferFd, size_t bufferSize, 85*be431cd8SAndroid Build Coastguard Worker std::enable_if_t<std::is_same_v<V, MQErased>, size_t> quantum); 86*be431cd8SAndroid Build Coastguard Worker }; 87*be431cd8SAndroid Build Coastguard Worker 88*be431cd8SAndroid Build Coastguard Worker template <typename T, typename U> 89*be431cd8SAndroid Build Coastguard Worker AidlMessageQueue<T, U>::AidlMessageQueue(const MQDescriptor<T, U>& desc, bool resetPointers) 90*be431cd8SAndroid Build Coastguard Worker : AidlMessageQueueBase<T, U, BackendTypesStore>(desc, resetPointers) {} 91*be431cd8SAndroid Build Coastguard Worker 92*be431cd8SAndroid Build Coastguard Worker template <typename T, typename U> 93*be431cd8SAndroid Build Coastguard Worker AidlMessageQueue<T, U>::AidlMessageQueue(size_t numElementsInQueue, bool configureEventFlagWord, 94*be431cd8SAndroid Build Coastguard Worker android::base::unique_fd bufferFd, size_t bufferSize) 95*be431cd8SAndroid Build Coastguard Worker : AidlMessageQueueBase<T, U, BackendTypesStore>(numElementsInQueue, configureEventFlagWord, 96*be431cd8SAndroid Build Coastguard Worker std::move(bufferFd), bufferSize) {} 97*be431cd8SAndroid Build Coastguard Worker 98*be431cd8SAndroid Build Coastguard Worker template <typename T, typename U> 99*be431cd8SAndroid Build Coastguard Worker template <typename V> 100*be431cd8SAndroid Build Coastguard Worker AidlMessageQueue<T, U>::AidlMessageQueue( 101*be431cd8SAndroid Build Coastguard Worker size_t numElementsInQueue, bool configureEventFlagWord, android::base::unique_fd bufferFd, 102*be431cd8SAndroid Build Coastguard Worker size_t bufferSize, std::enable_if_t<std::is_same_v<V, MQErased>, size_t> quantum) 103*be431cd8SAndroid Build Coastguard Worker : AidlMessageQueueBase<T, U, BackendTypesStore>(numElementsInQueue, configureEventFlagWord, 104*be431cd8SAndroid Build Coastguard Worker std::move(bufferFd), bufferSize, quantum) {} 105*be431cd8SAndroid Build Coastguard Worker 106*be431cd8SAndroid Build Coastguard Worker } // namespace android 107