1 //
2 // Copyright 2018 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 #ifndef __VTS_RESOURCE_VTSHIDLMEMORYDRIVER_H
18 #define __VTS_RESOURCE_VTSHIDLMEMORYDRIVER_H
19 
20 #include <mutex>
21 #include <unordered_map>
22 
23 #include <android-base/logging.h>
24 #include <android/hidl/memory/1.0/IMemory.h>
25 #include <hidl/HidlSupport.h>
26 
27 using android::sp;
28 using android::hardware::hidl_memory;
29 using android::hidl::memory::V1_0::IMemory;
30 
31 using namespace std;
32 using MemoryId = int;
33 
34 namespace android {
35 namespace vts {
36 
37 // Need to store both hidl_memory pointer and IMemory pointer.
38 // Conversion from hidl_memory to IMemory is slow, and we can send hidl_memory
39 // pointer in hidl, and operate on the memory object using IMemory pointer.
40 struct MemoryInfo {
41   // Pointer to hidl_memory, which can be passed around in hidl.
42   // Need to manually manage hidl_memory as a pointer, because the returned
43   // hidl_memory reference from hidl API goes out of scope.
44   unique_ptr<hidl_memory> hidl_mem_ptr;
45   // Pointer to IMemory that allows actual memory operation.
46   sp<IMemory> memory;
47 };
48 
49 // A hidl_memory driver that manages all hidl_memory objects created
50 // on the target side. Reader and writer use their id to read from and write
51 // into the memory.
52 // Example:
53 //   VtsHidlMemoryDriver mem_driver;
54 //   // Allcate memory.
55 //   int mem_id = mem_driver.Allocate(100);
56 //
57 //   string write_data = "abcdef";
58 //   // Write into the memory.
59 //   mem_driver.Update(mem_id);
60 //   mem_driver.UpdateBytes(mem_id, write_data.c_str(),
61 //                          write_data.length());
62 //   mem_driver.Commit(mem_id);
63 //   // Read from the memory.
64 //   char read_data[write_data.length()];
65 //   mem_driver.Read(mem_id);
66 //   mem_driver.ReadBytes(mem_id, read_data, write_data.length());
67 //   mem_driver.Commit(mem_id);
68 class VtsHidlMemoryDriver {
69  public:
70   // Constructor to initialize a hidl_memory manager.
71   VtsHidlMemoryDriver();
72 
73   // Destructor to clean up the class.
74   ~VtsHidlMemoryDriver();
75 
76   // Allocate a memory region with size mem_size.
77   //
78   // @param mem_size size of the memory.
79   //
80   // @return int, id to be used to reference the memory object later.
81   //              -1 if allocation fails.
82   MemoryId Allocate(size_t mem_size);
83 
84   // Registers a memory object in the driver.
85   //
86   // @param hidl_mem_address address of hidl_memory pointer.
87   //
88   // @return id to be used to reference the memory region later.
89   //         -1 if registration fails.
90   MemoryId RegisterHidlMemory(size_t hidl_mem_address);
91 
92   // Notify that caller will possibly write to all memory region with id mem_id.
93   //
94   // @param mem_id identifies the memory object.
95   //
96   // @return true if memory object is found, false otherwise.
97   bool Update(MemoryId mem_id);
98 
99   // Notify that caller will possibly write to memory region with mem_id
100   // starting at start and ending at start + length.
101   // start + length must be < size.
102   //
103   // @param mem_id identifies the memory object.
104   // @param start  offset from the start of memory region to be modified.
105   // @param length number of bytes to be modified.
106   //
107   // @return true if memory object is found, false otherwise.
108   bool UpdateRange(MemoryId mem_id, uint64_t start, uint64_t length);
109 
110   // Notify that caller will read the entire memory.
111   //
112   // @param mem_id identifies the memory object.
113   //
114   // @return true if memory object is found, false otherwise.
115   bool Read(MemoryId mem_id);
116 
117   // Notify that caller will read memory region with mem_id starting at start
118   // and end at start + length.
119   //
120   // @param mem_id identifies the memory object.
121   // @param start  offset from the start of memory region to be modified.
122   // @param length number of bytes to be modified.
123   //
124   // @return true if memory object is found, false otherwise.
125   bool ReadRange(MemoryId mem_id, uint64_t start, uint64_t length);
126 
127   // Add this method to perform actual write operation in memory,
128   // because host side won't be able to cast c++ pointers.
129   //
130   // @param mem_id     identifies the memory object.
131   // @param write_data pointer to the start of buffer to be written into memory.
132   // @param length     number of bytes to write.
133   // @param start      offset from the start of memory region to be modified.
134   //
135   // @return true if memory object is found, false otherwise.
136   bool UpdateBytes(MemoryId mem_id, const char* write_data, uint64_t length,
137                    uint64_t start = 0);
138 
139   // Add this method to perform actual read operation in memory,
140   // because host side won't be able to cast c++ pointers.
141   //
142   // @param mem_id    identifies the memory object.
143   // @param read_data pointer to the start of buffer to be filled with
144   //                  memory content.
145   // @param length    number of bytes to be read.
146   // @param start     offset from the start of the memory region to be modified.
147   //
148   // @return true if memory object is found, false otherwise.
149   bool ReadBytes(MemoryId mem_id, char* read_data, uint64_t length,
150                  uint64_t start = 0);
151 
152   // Caller signals done with reading from or writing to memory.
153   //
154   // @param mem_id identifies the memory object.
155   //
156   // @return true if memory object is found, false otherwise.
157   bool Commit(MemoryId mem_id);
158 
159   // Get the size of the memory.
160   //
161   // @param mem_id identifies the memory object.
162   //
163   // @return true if memory object is found, false otherwise.
164   bool GetSize(MemoryId mem_id, size_t* result);
165 
166   // Get hidl_memory pointer address of memory object with mem_id.
167   //
168   // @param mem_id identifies the memory object.
169   // @param result stores the hidl_memory pointer address.
170   //
171   // @return true if memory object is found, false otherwise.
172   bool GetHidlMemoryAddress(MemoryId mem_id, size_t* result);
173 
174  private:
175   // Finds the memory object with ID mem_id.
176   // Logs error if mem_id is not found.
177   //
178   // @param mem_id identifies the memory object.
179   //
180   // @return MemoryInfo pointer, which contains both hidl_memory pointer and
181   //         IMemory pointer.
182   MemoryInfo* FindMemory(MemoryId mem_id);
183 
184   // A map to keep track of each hidl_memory information.
185   // Store MemoryInfo smart pointer, which contains both hidl_memory,
186   // and actual memory pointer.
187   unordered_map<MemoryId, unique_ptr<MemoryInfo>> hidl_memory_map_;
188 
189   // A mutex to ensure insert and lookup on hidl_memory_map_ are thread-safe.
190   mutex map_mutex_;
191 };
192 
193 }  // namespace vts
194 }  // namespace android
195 #endif  //__VTS_RESOURCE_VTSHIDLMEMORYDRIVER_H
196