blob: eaef087d26516d3d40e1341eb5dbcb01253ac610 [file] [log] [blame]
Devin Moore133cb5e2020-07-07 16:31:22 -07001/*
2 * Copyright (C) 2020 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 <aidl/android/hardware/common/MQDescriptor.h>
Devin Moore1b2d0a62020-09-22 17:20:54 +000020#include <aidl/android/hardware/common/SynchronizedReadWrite.h>
21#include <aidl/android/hardware/common/UnsynchronizedWrite.h>
Devin Moore133cb5e2020-07-07 16:31:22 -070022#include <cutils/native_handle.h>
23#include <fmq/AidlMQDescriptorShim.h>
24#include <fmq/MessageQueueBase.h>
25#include <utils/Log.h>
Devin Moore1b2d0a62020-09-22 17:20:54 +000026#include <type_traits>
Devin Moore133cb5e2020-07-07 16:31:22 -070027
Devin Moore7c04cfe2020-08-17 14:37:13 -070028namespace android {
29
Devin Moore133cb5e2020-07-07 16:31:22 -070030using aidl::android::hardware::common::MQDescriptor;
Devin Moore1b2d0a62020-09-22 17:20:54 +000031using aidl::android::hardware::common::SynchronizedReadWrite;
32using aidl::android::hardware::common::UnsynchronizedWrite;
Devin Moore133cb5e2020-07-07 16:31:22 -070033using android::details::AidlMQDescriptorShim;
34using android::hardware::MQFlavor;
35
Devin Moore1b2d0a62020-09-22 17:20:54 +000036template <typename T>
37struct FlavorTypeToValue;
38
39template <>
40struct FlavorTypeToValue<SynchronizedReadWrite> {
41 static constexpr MQFlavor value = hardware::kSynchronizedReadWrite;
42};
43
44template <>
45struct FlavorTypeToValue<UnsynchronizedWrite> {
46 static constexpr MQFlavor value = hardware::kUnsynchronizedWrite;
47};
48
Devin Moore133cb5e2020-07-07 16:31:22 -070049typedef uint64_t RingBufferPosition;
50
Devin Moore1b2d0a62020-09-22 17:20:54 +000051template <typename T, typename U>
52struct AidlMessageQueue final
53 : public MessageQueueBase<AidlMQDescriptorShim, T, FlavorTypeToValue<U>::value> {
54 typedef AidlMQDescriptorShim<T, FlavorTypeToValue<U>::value> Descriptor;
Devin Moore133cb5e2020-07-07 16:31:22 -070055 /**
56 * This constructor uses the external descriptor used with AIDL interfaces.
57 * It will create an FMQ based on the descriptor that was obtained from
58 * another FMQ instance for communication.
59 *
60 * @param desc Descriptor from another FMQ that contains all of the
61 * information required to create a new instance of that queue.
62 * @param resetPointers Boolean indicating whether the read/write pointers
63 * should be reset or not.
64 */
Devin Moore1b2d0a62020-09-22 17:20:54 +000065 AidlMessageQueue(const MQDescriptor<T, U>& desc, bool resetPointers = true);
Devin Moore133cb5e2020-07-07 16:31:22 -070066 ~AidlMessageQueue() = default;
67
68 /**
69 * This constructor uses Ashmem shared memory to create an FMQ
70 * that can contain a maximum of 'numElementsInQueue' elements of type T.
71 *
72 * @param numElementsInQueue Capacity of the AidlMessageQueue in terms of T.
73 * @param configureEventFlagWord Boolean that specifies if memory should
74 * also be allocated and mapped for an EventFlag word.
75 */
76 AidlMessageQueue(size_t numElementsInQueue, bool configureEventFlagWord = false);
Devin Moore1b2d0a62020-09-22 17:20:54 +000077 MQDescriptor<T, U> dupeDesc();
Devin Moore133cb5e2020-07-07 16:31:22 -070078
79 private:
80 AidlMessageQueue(const AidlMessageQueue& other) = delete;
81 AidlMessageQueue& operator=(const AidlMessageQueue& other) = delete;
82 AidlMessageQueue() = delete;
83};
84
Devin Moore1b2d0a62020-09-22 17:20:54 +000085template <typename T, typename U>
86AidlMessageQueue<T, U>::AidlMessageQueue(const MQDescriptor<T, U>& desc, bool resetPointers)
87 : MessageQueueBase<AidlMQDescriptorShim, T, FlavorTypeToValue<U>::value>(Descriptor(desc),
88 resetPointers) {}
Devin Moore133cb5e2020-07-07 16:31:22 -070089
Devin Moore1b2d0a62020-09-22 17:20:54 +000090template <typename T, typename U>
91AidlMessageQueue<T, U>::AidlMessageQueue(size_t numElementsInQueue, bool configureEventFlagWord)
92 : MessageQueueBase<AidlMQDescriptorShim, T, FlavorTypeToValue<U>::value>(
93 numElementsInQueue, configureEventFlagWord) {}
Devin Moore133cb5e2020-07-07 16:31:22 -070094
Devin Moore1b2d0a62020-09-22 17:20:54 +000095template <typename T, typename U>
96MQDescriptor<T, U> AidlMessageQueue<T, U>::dupeDesc() {
97 auto* shim = MessageQueueBase<AidlMQDescriptorShim, T, FlavorTypeToValue<U>::value>::getDesc();
Devin Moore133cb5e2020-07-07 16:31:22 -070098 if (shim) {
Devin Moore7c04cfe2020-08-17 14:37:13 -070099 std::vector<aidl::android::hardware::common::GrantorDescriptor> grantors;
100 for (const auto& grantor : shim->grantors()) {
101 grantors.push_back(aidl::android::hardware::common::GrantorDescriptor{
102 .offset = static_cast<int32_t>(grantor.offset),
103 .extent = static_cast<int64_t>(grantor.extent)});
104 }
Devin Moore1b2d0a62020-09-22 17:20:54 +0000105 return MQDescriptor<T, U>{
Devin Moore133cb5e2020-07-07 16:31:22 -0700106 .quantum = static_cast<int32_t>(shim->getQuantum()),
Devin Moore7c04cfe2020-08-17 14:37:13 -0700107 .grantors = grantors,
108 .flags = static_cast<int32_t>(shim->getFlags()),
Devin Moore133cb5e2020-07-07 16:31:22 -0700109 .fileDescriptor = ndk::ScopedFileDescriptor(dup(shim->handle()->data[0])),
110 };
111 } else {
Devin Moore1b2d0a62020-09-22 17:20:54 +0000112 return MQDescriptor<T, U>();
Devin Moore133cb5e2020-07-07 16:31:22 -0700113 }
114}
115
116} // namespace android