• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 #define LOG_TAG "HidlMemoryCache"
18 #include "HidlMemoryCache.h"
19 #include <android/hidl/memory/1.0/IMemory.h>
20 #include <android/hidl/memory/token/1.0/IMemoryToken.h>
21 #include <hidlmemory/mapping.h>
22 #include <sys/mman.h>
23 #include <utils/Log.h>
24 
25 namespace android {
26 namespace hardware {
27 
28 using IMemoryToken = ::android::hidl::memory::token::V1_0::IMemoryToken;
29 using IMemory = ::android::hidl::memory::V1_0::IMemory;
30 
31 class MemoryDecorator : public virtual IMemory {
32    public:
MemoryDecorator(const sp<IMemory> & heap)33     MemoryDecorator(const sp<IMemory>& heap) : mHeap(heap) {}
~MemoryDecorator()34     virtual ~MemoryDecorator() {}
update()35     Return<void> update() override { return mHeap->update(); }
read()36     Return<void> read() override { return mHeap->read(); }
updateRange(uint64_t start,uint64_t length)37     Return<void> updateRange(uint64_t start, uint64_t length) override {
38         return mHeap->updateRange(start, length);
39     }
readRange(uint64_t start,uint64_t length)40     Return<void> readRange(uint64_t start, uint64_t length) override {
41         return mHeap->readRange(start, length);
42     }
commit()43     Return<void> commit() override { return mHeap->commit(); }
44 
getPointer()45     Return<void*> getPointer() override { return mHeap->getPointer(); }
getSize()46     Return<uint64_t> getSize() override { return mHeap->getSize(); }
47 
48    protected:
49     sp<IMemory> mHeap;
50 };
51 
52 class MemoryCacheable : public virtual MemoryDecorator {
53    public:
MemoryCacheable(const sp<IMemory> & heap,sp<IMemoryToken> key)54     MemoryCacheable(const sp<IMemory>& heap, sp<IMemoryToken> key)
55         : MemoryDecorator(heap), mKey(key) {}
~MemoryCacheable()56     virtual ~MemoryCacheable() { HidlMemoryCache::getInstance()->flush(mKey); }
57 
58    protected:
59     sp<IMemoryToken> mKey;
60 };
61 
62 class MemoryBlockImpl : public virtual IMemory {
63    public:
MemoryBlockImpl(const sp<IMemory> & heap,uint64_t size,uint64_t offset)64     MemoryBlockImpl(const sp<IMemory>& heap, uint64_t size, uint64_t offset)
65         : mHeap(heap), mSize(size), mOffset(offset), mHeapSize(heap->getSize()) {}
validRange(uint64_t start,uint64_t length)66     bool validRange(uint64_t start, uint64_t length) {
67         return (start + length <= mSize) && (start + length >= start) &&
68                (mOffset + mSize <= mHeapSize);
69     }
readRange(uint64_t start,uint64_t length)70     Return<void> readRange(uint64_t start, uint64_t length) override {
71         if (!validRange(start, length)) {
72             ALOGE("IMemoryBlock::readRange: out of range");
73             return Void();
74         }
75         return mHeap->readRange(mOffset + start, length);
76     }
updateRange(uint64_t start,uint64_t length)77     Return<void> updateRange(uint64_t start, uint64_t length) override {
78         if (!validRange(start, length)) {
79             ALOGE("IMemoryBlock::updateRange: out of range");
80             return Void();
81         }
82         return mHeap->updateRange(mOffset + start, length);
83     }
read()84     Return<void> read() override { return this->readRange(0, mSize); }
update()85     Return<void> update() override { return this->updateRange(0, mSize); }
commit()86     Return<void> commit() override { return mHeap->commit(); }
getSize()87     Return<uint64_t> getSize() override { return mSize; }
getPointer()88     Return<void*> getPointer() override {
89         void* p = mHeap->getPointer();
90         return (static_cast<char*>(p) + mOffset);
91     }
92 
93    protected:
94     sp<IMemory> mHeap;
95     uint64_t mSize;
96     uint64_t mOffset;
97     uint64_t mHeapSize;
98 };
99 
getInstance()100 sp<HidlMemoryCache> HidlMemoryCache::getInstance() {
101     static sp<HidlMemoryCache> instance = new HidlMemoryCache();
102     return instance;
103 }
104 
fillLocked(const sp<IMemoryToken> & key)105 sp<IMemory> HidlMemoryCache::fillLocked(const sp<IMemoryToken>& key) {
106     sp<IMemory> memory = nullptr;
107     Return<void> ret = key->get(
108         [&](const hidl_memory& mem) { memory = new MemoryCacheable(mapMemory(mem), key); });
109     if (!ret.isOk()) {
110         ALOGE("HidlMemoryCache::fill: cannot IMemoryToken::get.");
111         return nullptr;
112     }
113     mCached[key] = memory;
114     return memory;
115 }
116 
map(const MemoryBlock & memblk)117 sp<IMemory> HidlMemoryCache::map(const MemoryBlock& memblk) {
118     sp<IMemoryToken> token = memblk.token;
119     sp<IMemory> heap = fetch(token);
120     if (heap == nullptr) {
121         return nullptr;
122     }
123     return new MemoryBlockImpl(heap, memblk.size, memblk.offset);
124 }
125 
126 }  // namespace hardware
127 }  // namespace android
128