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 #define LOG_TAG "VtsHidlMemoryDriver"
17
18 #include "hidl_memory_driver/VtsHidlMemoryDriver.h"
19
20 #include <android-base/logging.h>
21 #include <android/hidl/allocator/1.0/IAllocator.h>
22 #include <hidlmemory/mapping.h>
23
24 using android::sp;
25 using android::hardware::hidl_memory;
26 using android::hidl::allocator::V1_0::IAllocator;
27 using android::hidl::memory::V1_0::IMemory;
28
29 using namespace std;
30
31 namespace android {
32 namespace vts {
33
VtsHidlMemoryDriver()34 VtsHidlMemoryDriver::VtsHidlMemoryDriver() {}
35
~VtsHidlMemoryDriver()36 VtsHidlMemoryDriver::~VtsHidlMemoryDriver() {
37 // clears objects in the map.
38 hidl_memory_map_.clear();
39 }
40
Allocate(size_t mem_size)41 MemoryId VtsHidlMemoryDriver::Allocate(size_t mem_size) {
42 sp<IAllocator> ashmem_allocator = IAllocator::getService("ashmem");
43 unique_ptr<MemoryInfo> mem_info = nullptr;
44 ashmem_allocator->allocate(
45 mem_size, [&](bool success, const hidl_memory& mem) {
46 if (!success) { // error
47 LOG(ERROR) << "Allocate memory failure.";
48 } else {
49 unique_ptr<hidl_memory> hidl_mem_ptr(new hidl_memory(mem));
50 sp<IMemory> mem_ptr = mapMemory(mem);
51 mem_info.reset(new MemoryInfo{move(hidl_mem_ptr), mem_ptr});
52 }
53 });
54 if (mem_info == nullptr) return -1;
55 map_mutex_.lock();
56 size_t new_mem_id = hidl_memory_map_.size();
57 hidl_memory_map_.emplace(new_mem_id, move(mem_info));
58 map_mutex_.unlock();
59 return new_mem_id;
60 }
61
RegisterHidlMemory(size_t hidl_mem_address)62 MemoryId VtsHidlMemoryDriver::RegisterHidlMemory(size_t hidl_mem_address) {
63 unique_ptr<hidl_memory> hidl_mem_ptr(
64 reinterpret_cast<hidl_memory*>(hidl_mem_address));
65 sp<IMemory> mem_ptr = mapMemory(*hidl_mem_ptr.get());
66 if (mem_ptr == nullptr) {
67 LOG(ERROR) << "Register memory failure. "
68 << "Unable to map hidl_memory to IMemory object.";
69 return -1;
70 }
71 unique_ptr<MemoryInfo> mem_info(new MemoryInfo{move(hidl_mem_ptr), mem_ptr});
72 map_mutex_.lock();
73 size_t new_mem_id = hidl_memory_map_.size();
74 hidl_memory_map_.emplace(new_mem_id, move(mem_info));
75 map_mutex_.unlock();
76 return new_mem_id;
77 }
78
Update(MemoryId mem_id)79 bool VtsHidlMemoryDriver::Update(MemoryId mem_id) {
80 MemoryInfo* mem_info = FindMemory(mem_id);
81 if (mem_info == nullptr) return false;
82 (mem_info->memory)->update();
83 return true;
84 }
85
UpdateRange(MemoryId mem_id,uint64_t start,uint64_t length)86 bool VtsHidlMemoryDriver::UpdateRange(MemoryId mem_id, uint64_t start,
87 uint64_t length) {
88 MemoryInfo* mem_info = FindMemory(mem_id);
89 if (mem_info == nullptr) return false;
90 (mem_info->memory)->updateRange(start, length);
91 return true;
92 }
93
Read(MemoryId mem_id)94 bool VtsHidlMemoryDriver::Read(MemoryId mem_id) {
95 MemoryInfo* mem_info = FindMemory(mem_id);
96 if (mem_info == nullptr) return false;
97 (mem_info->memory)->read();
98 return true;
99 }
100
ReadRange(MemoryId mem_id,uint64_t start,uint64_t length)101 bool VtsHidlMemoryDriver::ReadRange(MemoryId mem_id, uint64_t start,
102 uint64_t length) {
103 MemoryInfo* mem_info = FindMemory(mem_id);
104 if (mem_info == nullptr) return false;
105 (mem_info->memory)->readRange(start, length);
106 return true;
107 }
108
UpdateBytes(MemoryId mem_id,const char * write_data,uint64_t length,uint64_t start)109 bool VtsHidlMemoryDriver::UpdateBytes(MemoryId mem_id, const char* write_data,
110 uint64_t length, uint64_t start) {
111 MemoryInfo* mem_info = FindMemory(mem_id);
112 if (mem_info == nullptr) return false;
113 void* memory_ptr = (mem_info->memory)->getPointer();
114 char* memory_char_ptr = static_cast<char*>(memory_ptr);
115 memcpy(memory_char_ptr + start, write_data, length);
116 return true;
117 }
118
ReadBytes(MemoryId mem_id,char * read_data,uint64_t length,uint64_t start)119 bool VtsHidlMemoryDriver::ReadBytes(MemoryId mem_id, char* read_data,
120 uint64_t length, uint64_t start) {
121 MemoryInfo* mem_info = FindMemory(mem_id);
122 if (mem_info == nullptr) return false;
123 void* memory_ptr = (mem_info->memory)->getPointer();
124 char* memory_char_ptr = static_cast<char*>(memory_ptr);
125 memcpy(read_data, memory_char_ptr + start, length);
126 return true;
127 }
128
Commit(MemoryId mem_id)129 bool VtsHidlMemoryDriver::Commit(MemoryId mem_id) {
130 MemoryInfo* mem_info = FindMemory(mem_id);
131 if (mem_info == nullptr) return false;
132 (mem_info->memory)->commit();
133 return true;
134 }
135
GetSize(MemoryId mem_id,size_t * result)136 bool VtsHidlMemoryDriver::GetSize(MemoryId mem_id, size_t* result) {
137 MemoryInfo* mem_info = FindMemory(mem_id);
138 if (mem_info == nullptr) return false;
139 *result = (mem_info->memory)->getSize();
140 return true;
141 }
142
GetHidlMemoryAddress(MemoryId mem_id,size_t * result)143 bool VtsHidlMemoryDriver::GetHidlMemoryAddress(MemoryId mem_id,
144 size_t* result) {
145 MemoryInfo* mem_info = FindMemory(mem_id);
146 if (mem_info == nullptr) return false; // unable to find memory object.
147 hidl_memory* hidl_mem_ptr = (mem_info->hidl_mem_ptr).get();
148 *result = reinterpret_cast<size_t>(hidl_mem_ptr);
149 return true;
150 }
151
FindMemory(MemoryId mem_id)152 MemoryInfo* VtsHidlMemoryDriver::FindMemory(MemoryId mem_id) {
153 MemoryInfo* mem_info;
154 map_mutex_.lock();
155 auto iterator = hidl_memory_map_.find(mem_id);
156 if (iterator == hidl_memory_map_.end()) {
157 LOG(ERROR) << "Unable to find memory region associated with mem_id "
158 << mem_id;
159 map_mutex_.unlock();
160 return nullptr;
161 }
162 mem_info = (iterator->second).get();
163 map_mutex_.unlock();
164 return mem_info;
165 }
166
167 } // namespace vts
168 } // namespace android
169