1 /*
2  * Copyright (C) 2017 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 #include <atomic>
18 
19 #include <hidlmemory/mapping.h>
20 
21 #include "AudioBufferManager.h"
22 
23 namespace android {
24 
25 ANDROID_SINGLETON_STATIC_INSTANCE(AudioBufferManager);
26 
wrap(const AudioBuffer & buffer,sp<AudioBufferWrapper> * wrapper)27 bool AudioBufferManager::wrap(const AudioBuffer& buffer, sp<AudioBufferWrapper>* wrapper) {
28     // Check if we have this buffer already
29     std::lock_guard<std::mutex> lock(mLock);
30     ssize_t idx = mBuffers.indexOfKey(buffer.id);
31     if (idx >= 0) {
32         *wrapper = mBuffers[idx].promote();
33         if (*wrapper != nullptr) {
34             (*wrapper)->getHalBuffer()->frameCount = buffer.frameCount;
35             return true;
36         }
37         mBuffers.removeItemsAt(idx);
38     }
39     // Need to create and init a new AudioBufferWrapper.
40     sp<AudioBufferWrapper> tempBuffer(new AudioBufferWrapper(buffer));
41     if (!tempBuffer->init()) return false;
42     *wrapper = tempBuffer;
43     mBuffers.add(buffer.id, *wrapper);
44     return true;
45 }
46 
removeEntry(uint64_t id)47 void AudioBufferManager::removeEntry(uint64_t id) {
48     std::lock_guard<std::mutex> lock(mLock);
49     ssize_t idx = mBuffers.indexOfKey(id);
50     if (idx >= 0) mBuffers.removeItemsAt(idx);
51 }
52 
53 namespace hardware {
54 namespace audio {
55 namespace effect {
56 namespace V2_0 {
57 namespace implementation {
58 
AudioBufferWrapper(const AudioBuffer & buffer)59 AudioBufferWrapper::AudioBufferWrapper(const AudioBuffer& buffer) :
60         mHidlBuffer(buffer), mHalBuffer{ 0, { nullptr } } {
61 }
62 
~AudioBufferWrapper()63 AudioBufferWrapper::~AudioBufferWrapper() {
64     AudioBufferManager::getInstance().removeEntry(mHidlBuffer.id);
65 }
66 
init()67 bool AudioBufferWrapper::init() {
68     if (mHalBuffer.raw != nullptr) {
69         ALOGE("An attempt to init AudioBufferWrapper twice");
70         return false;
71     }
72     mHidlMemory = mapMemory(mHidlBuffer.data);
73     if (mHidlMemory == nullptr) {
74         ALOGE("Could not map HIDL memory to IMemory");
75         return false;
76     }
77     mHalBuffer.raw = static_cast<void*>(mHidlMemory->getPointer());
78     if (mHalBuffer.raw == nullptr) {
79         ALOGE("IMemory buffer pointer is null");
80         return false;
81     }
82     mHalBuffer.frameCount = mHidlBuffer.frameCount;
83     return true;
84 }
85 
86 }  // namespace implementation
87 }  // namespace V2_0
88 }  // namespace effect
89 }  // namespace audio
90 }  // namespace hardware
91 }  // namespace android
92