1 /*
2 * Copyright (C) 2021-2022 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 REMOTE_OBSERVER_LIST_H
17 #define REMOTE_OBSERVER_LIST_H
18
19 #include <functional>
20 #include <map>
21 #include <mutex>
22 #include <tuple>
23
24 #include "refbase.h"
25 #include "iremote_broker.h"
26 #include "iremote_proxy.h"
27 #include "bluetooth_log.h"
28
29 namespace OHOS {
30 namespace Bluetooth {
31 template <typename T, typename... Args>
32 class RemoteObserverList final {
33 using DrCallbackFunc = std::function<void(const sptr<T> &observer, Args... args)>;
34 public:
35 RemoteObserverList() = default;
36 ~RemoteObserverList();
37 bool Register(const sptr<T> &observer, DrCallbackFunc func, Args... args);
38 bool Deregister(const sptr<T> &observer);
39 void ForEach(const std::function<void(sptr<T>)> &observer);
40
41 class ObserverDeathRecipient : public IRemoteObject::DeathRecipient {
42 public:
43 ObserverDeathRecipient(const sptr<T> &observer, RemoteObserverList<T, Args...> *owner);
GetObserver()44 sptr<T> GetObserver() const
45 {
46 return observer_;
47 };
48 void OnRemoteDied(const wptr<IRemoteObject> &remote) override;
49
50 private:
51 sptr<T> observer_ {};
52 RemoteObserverList<T, Args...> *owner_ {};
53 };
54 std::mutex lock_ {};
55 using ObserverMap = std::map<sptr<T>, sptr<ObserverDeathRecipient>>;
56 ObserverMap observers_ {};
57
58 struct RtOberserInfo {
59 DrCallbackFunc callbackFunc;
60 std::tuple<Args...> args;
61 };
62 using BtServerMap = std::map<sptr<T>, RtOberserInfo> ;
63 BtServerMap btServers_ {};
64
65 RemoteObserverList(const RemoteObserverList &) = delete;
66 RemoteObserverList &operator=(const RemoteObserverList &) = delete;
67
68 private:
69 bool UnregisterInternal(typename ObserverMap::iterator iter);
70 };
71
72 template <typename T, typename... Args>
~RemoteObserverList()73 RemoteObserverList<T, Args...>::~RemoteObserverList()
74 {
75 HILOGI("RemoteObserverList<T, Args...>::~RemoteObserverList() called");
76 std::lock_guard<std::mutex> lock(lock_);
77 for (auto it = observers_.begin(); it != observers_.end(); ++it) {
78 sptr<ObserverDeathRecipient> dr = it->second;
79 if (!dr->GetObserver()->AsObject()->RemoveDeathRecipient(dr)) {
80 HILOGE("Failed to unlink death recipient from observer");
81 }
82 }
83 observers_.clear();
84 btServers_.clear();
85 }
86
87 template <typename T, typename... Args>
Register(const sptr<T> & observer,DrCallbackFunc func,Args...args)88 bool RemoteObserverList<T, Args...>::Register(const sptr<T> &observer, DrCallbackFunc func, Args... args)
89 {
90 HILOGI("RemoteObserverList<T, Args...>::Register called");
91 std::lock_guard<std::mutex> lock(lock_);
92 bool isMatch = false;
93 for (const auto &it : observers_) {
94 if (it.first != nullptr && it.first->AsObject() == observer->AsObject()) {
95 HILOGW("Observer list already contains given observer");
96 isMatch = true;
97 break;
98 }
99 }
100 if (!isMatch) {
101 sptr<ObserverDeathRecipient> dr(new ObserverDeathRecipient(observer, this));
102 if (!observer->AsObject()->AddDeathRecipient(dr)) {
103 HILOGE("Failed to link death recipient to observer");
104 }
105 observers_[observer] = dr;
106 }
107
108 bool isExist = false;
109 for (const auto &it : btServers_) {
110 if (it.first != nullptr && it.first->AsObject() == observer->AsObject()) {
111 HILOGW("btServers_ list already contains given observer");
112 isExist = true;
113 break;
114 }
115 }
116 if (!isExist) {
117 struct RtOberserInfo rtInfo;
118 rtInfo.callbackFunc = func;
119 rtInfo.args = std::make_tuple(args...);
120 btServers_[observer] = rtInfo;
121 }
122
123 return true;
124 }
125
126 template <typename T, typename... Args>
Deregister(const sptr<T> & observer)127 bool RemoteObserverList<T, Args...>::Deregister(const sptr<T> &observer)
128 {
129 HILOGI("RemoteObserverList<T, Args...>::Deregister called");
130 for (auto it = observers_.begin(); it != observers_.end();) {
131 if (it->first != nullptr && it->first->AsObject() == observer->AsObject()) {
132 UnregisterInternal(it++);
133 } else {
134 it++;
135 }
136 }
137 HILOGW("Given observer not registered with this list");
138 return false;
139 }
140
141 template <typename T, typename... Args>
ForEach(const std::function<void (sptr<T>)> & observer)142 void RemoteObserverList<T, Args...>::ForEach(const std::function<void(sptr<T>)> &observer)
143 {
144 std::lock_guard<std::mutex> lock(lock_);
145 for (const auto &it : observers_) {
146 if (it.first != nullptr) {
147 observer(it.first);
148 }
149 }
150 }
151
152 template <typename T, typename... Args>
ObserverDeathRecipient(const sptr<T> & observer,RemoteObserverList<T,Args...> * owner)153 RemoteObserverList<T, Args...>::ObserverDeathRecipient::ObserverDeathRecipient(
154 const sptr<T> &observer, RemoteObserverList<T, Args...> *owner)
155 : observer_(observer), owner_(owner)
156 {
157 HILOGI("RemoteObserverList<T>::ObserverDeathRecipient::ObserverDeathRecipient called");
158 }
159
160 template <typename T, typename... Args>
OnRemoteDied(const wptr<IRemoteObject> & object)161 void RemoteObserverList<T, Args...>::ObserverDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
162 {
163 // Remove the observer but no need to call unlinkToDeath.
164 std::lock_guard<std::mutex> lock(owner_->lock_);
165 HILOGD("Enter OnRemoteDied");
166 for (auto it = owner_->btServers_.begin(); it != owner_->btServers_.end();) {
167 if (it->first != nullptr && it->first->AsObject() == object) {
168 if (it->second.callbackFunc) {
169 std::apply(it->second.callbackFunc, std::tuple_cat(std::make_tuple(it->first), it->second.args));
170 }
171 it = owner_->btServers_.erase(it);
172 } else {
173 it++;
174 }
175 }
176
177 HILOGI("Callback from dead process unregistered");
178 }
179
180 template <typename T, typename... Args>
UnregisterInternal(typename ObserverMap::iterator iter)181 bool RemoteObserverList<T, Args...>::UnregisterInternal(typename ObserverMap::iterator iter)
182 {
183 HILOGI("RemoteObserverList<T, Args...>::UnregisterInternal called");
184 sptr<ObserverDeathRecipient> dr = iter->second;
185
186 if (!dr->GetObserver()->AsObject()->RemoveDeathRecipient(dr)) {
187 HILOGE("Failed to unlink death recipient from observer");
188 }
189
190 observers_.erase(iter);
191 return true;
192 }
193 } // namespace Bluetooth
194 } // namespace OHOS
195 #endif // REMOTE_OBSERVER_LIST_H
196