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