• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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