1 /* 2 * Copyright (C) 2022 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 #pragma once 18 19 #include <algorithm> 20 #include <memory> 21 #include <unordered_map> 22 23 #include <android-base/logging.h> 24 #include <android-base/thread_annotations.h> 25 26 #include "BundleContext.h" 27 #include "BundleTypes.h" 28 29 namespace aidl::android::hardware::audio::effect { 30 31 /** 32 * @brief Maintain all effect bundle sessions. 33 * 34 * Sessions are identified with the session ID, maximum of MAX_BUNDLE_SESSIONS is supported by the 35 * bundle implementation. 36 */ 37 class GlobalSession { 38 public: getGlobalSession()39 static GlobalSession& getGlobalSession() { 40 static GlobalSession instance; 41 return instance; 42 } 43 isSessionIdExist(int sessionId)44 bool isSessionIdExist(int sessionId) { 45 std::lock_guard lg(mMutex); 46 return mSessionMap.count(sessionId); 47 } 48 49 static bool findBundleTypeInList(std::vector<std::shared_ptr<BundleContext>>& list, 50 const lvm::BundleEffectType& type, bool remove = false) { 51 auto itor = std::find_if(list.begin(), list.end(), 52 [type](const std::shared_ptr<BundleContext>& bundle) { 53 return bundle ? bundle->getBundleType() == type : false; 54 }); 55 if (itor == list.end()) { 56 return false; 57 } 58 if (remove && *itor) { 59 (*itor)->deInit(); 60 list.erase(itor); 61 } 62 return true; 63 } 64 65 /** 66 * Create a certain type of BundleContext in shared_ptr container, each session must not have 67 * more than one session for each type. 68 */ createSession(const lvm::BundleEffectType & type,int statusDepth,const Parameter::Common & common)69 std::shared_ptr<BundleContext> createSession(const lvm::BundleEffectType& type, int statusDepth, 70 const Parameter::Common& common) { 71 int sessionId = common.session; 72 LOG(DEBUG) << __func__ << type << " with sessionId " << sessionId; 73 std::lock_guard lg(mMutex); 74 if (mSessionMap.count(sessionId) == 0 && mSessionMap.size() >= MAX_BUNDLE_SESSIONS) { 75 LOG(ERROR) << __func__ << " exceed max bundle session"; 76 return nullptr; 77 } 78 79 if (mSessionMap.count(sessionId)) { 80 if (findBundleTypeInList(mSessionMap[sessionId], type)) { 81 LOG(ERROR) << __func__ << type << " already exist in session " << sessionId; 82 return nullptr; 83 } 84 } 85 86 auto& list = mSessionMap[sessionId]; 87 auto context = std::make_shared<BundleContext>(statusDepth, common, type); 88 RETURN_VALUE_IF(!context, nullptr, "failedToCreateContext"); 89 90 RetCode ret = context->init(); 91 if (RetCode::SUCCESS != ret) { 92 LOG(ERROR) << __func__ << " context init ret " << ret; 93 return nullptr; 94 } 95 list.push_back(context); 96 return context; 97 } 98 releaseSession(const lvm::BundleEffectType & type,int sessionId)99 void releaseSession(const lvm::BundleEffectType& type, int sessionId) { 100 LOG(DEBUG) << __func__ << type << " sessionId " << sessionId; 101 std::lock_guard lg(mMutex); 102 if (mSessionMap.count(sessionId)) { 103 auto& list = mSessionMap[sessionId]; 104 if (!findBundleTypeInList(list, type, true /* remove */)) { 105 LOG(ERROR) << __func__ << " can't find " << type << "in session " << sessionId; 106 return; 107 } 108 if (list.size() == 0) { 109 mSessionMap.erase(sessionId); 110 } 111 } 112 } 113 114 private: 115 // Lock for mSessionMap access. 116 std::mutex mMutex; 117 // Max session number supported. 118 static constexpr int MAX_BUNDLE_SESSIONS = 32; 119 std::unordered_map<int /* session ID */, std::vector<std::shared_ptr<BundleContext>>> 120 mSessionMap GUARDED_BY(mMutex); 121 }; 122 } // namespace aidl::android::hardware::audio::effect 123