1 /* 2 * Copyright (c) 2024-2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef CAMERA_LISTENER_MANAGER_H 17 #define CAMERA_LISTENER_MANAGER_H 18 19 #include <cstdint> 20 #include <functional> 21 #include <memory> 22 #include <mutex> 23 #include <vector> 24 25 #include "camera_thread_utils.h" 26 #include "refbase.h" 27 28 namespace OHOS { 29 namespace CameraStandard { 30 template<typename T> 31 class CameraListenerManager { 32 public: 33 CameraListenerManager() = default; 34 ~CameraListenerManager() = default; AddListener(std::shared_ptr<T> listener)35 bool AddListener(std::shared_ptr<T> listener) 36 { 37 std::lock_guard<std::recursive_mutex> lock(listenerMutex_); 38 if (!isTriggering_) { 39 return AddListenerNoLock(listener, listeners_); 40 } 41 return AddListenerNoLock(listener, triggerAddListeners_); 42 } 43 RemoveListener(std::shared_ptr<T> listener)44 void RemoveListener(std::shared_ptr<T> listener) 45 { 46 std::lock_guard<std::recursive_mutex> lock(listenerMutex_); 47 if (!isTriggering_) { 48 return RemoveListenerNoLock(listener, listeners_); 49 } 50 // Add this listener to remove-list. 51 AddListenerNoLock(listener, triggerRemoveListeners_); 52 } 53 ClearListeners()54 void ClearListeners() 55 { 56 std::lock_guard<std::recursive_mutex> lock(listenerMutex_); 57 listeners_.clear(); 58 } 59 TriggerListener(std::function<void (T *)> fun)60 void TriggerListener(std::function<void(T*)> fun) 61 { 62 std::lock_guard<std::recursive_mutex> lock(listenerMutex_); 63 isTriggering_ = true; 64 triggerAddListeners_.clear(); 65 triggerRemoveListeners_.clear(); 66 for (std::shared_ptr<T>& listener : listeners_) { 67 fun(listener.get()); 68 } 69 for (auto& removeListener : triggerRemoveListeners_) { 70 for (auto it = triggerAddListeners_.begin(); it != triggerAddListeners_.end(); it++) { 71 if (removeListener == *it) { 72 triggerAddListeners_.erase(it); 73 break; 74 } 75 } 76 } 77 for (auto& listener : triggerRemoveListeners_) { 78 RemoveListenerNoLock(listener, listeners_); 79 } 80 81 for (auto& listener : triggerAddListeners_) { 82 AddListenerNoLock(listener, listeners_); 83 } 84 isTriggering_ = false; 85 } 86 TriggerTargetListenerAsync(std::shared_ptr<T> & listener,const std::function<void (std::shared_ptr<T>)> fun)87 void TriggerTargetListenerAsync(std::shared_ptr<T>& listener, const std::function<void(std::shared_ptr<T>)> fun) 88 { 89 if (listener == nullptr || !IsListenerExist(listener)) { 90 return; 91 } 92 CameraThreadUtils::StartAsyncTask([listener, fun]() { fun(listener); }); 93 } 94 GetListenerCount()95 size_t GetListenerCount() 96 { 97 std::lock_guard<std::recursive_mutex> lock(listenerMutex_); 98 return listeners_.size(); 99 } 100 IsListenerExist(std::shared_ptr<T> listener)101 bool IsListenerExist(std::shared_ptr<T> listener) 102 { 103 std::lock_guard<std::recursive_mutex> lock(listenerMutex_); 104 for (auto& listListener : listeners_) { 105 if (listener == listListener) { 106 return true; 107 } 108 } 109 return false; 110 } 111 112 private: AddListenerNoLock(std::shared_ptr<T> & listener,std::vector<std::shared_ptr<T>> & listeners)113 bool AddListenerNoLock(std::shared_ptr<T>& listener, std::vector<std::shared_ptr<T>>& listeners) const 114 { 115 if (listener == nullptr) { 116 return false; 117 } 118 for (auto& itListener : listeners) { 119 if (itListener == listener) { 120 return false; 121 } 122 } 123 listeners.emplace_back(listener); 124 return true; 125 } 126 RemoveListenerNoLock(std::shared_ptr<T> & listener,std::vector<std::shared_ptr<T>> & listeners)127 void RemoveListenerNoLock(std::shared_ptr<T>& listener, std::vector<std::shared_ptr<T>>& listeners) const 128 { 129 if (listener == nullptr) { 130 return; 131 } 132 for (auto it = listeners_.begin(); it != listeners.end(); it++) { 133 if (*it == listener) { 134 listeners.erase(it); 135 return; 136 } 137 } 138 } 139 140 mutable std::recursive_mutex listenerMutex_; 141 bool isTriggering_ = false; 142 std::vector<std::shared_ptr<T>> listeners_; 143 std::vector<std::shared_ptr<T>> triggerAddListeners_; 144 std::vector<std::shared_ptr<T>> triggerRemoveListeners_; 145 }; 146 } // namespace CameraStandard 147 } // namespace OHOS 148 149 #endif