1 // Copyright (C) 2021 The Android Open Source Project 2 // 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 #pragma once 15 16 #include <functional> // for function 17 #include <mutex> // for mutex, lock_guard 18 #include <utility> // for move 19 #include <vector> // for vector 20 21 namespace android { 22 namespace base { 23 24 // An EventNotificationSupport class can be used to add simple notification 25 // support to your class. 26 // 27 // You basically specify an EventObject type, subclass from the support class 28 // and simply call fireEvent when an event needs to be delivered. 29 template <class EventObject> 30 class EventNotificationSupport { 31 using EventListener = std::function<void(const EventObject evt)>; 32 33 public: 34 EventNotificationSupport() = default; 35 36 // A listener that can be registered that cannot be removed. 37 // This listener will live for the lifetime of the object. registerOnce(EventListener listener)38 void registerOnce(EventListener listener) { 39 std::lock_guard<std::mutex> lock(mStreamLock); 40 mNonRemovableListeners.push_back(listener); 41 } 42 addListener(EventListener * listener)43 void addListener(EventListener* listener) { 44 std::lock_guard<std::mutex> lock(mStreamLock); 45 mListeners.push_back(listener); 46 } 47 removeListener(EventListener * listener)48 void removeListener(EventListener* listener) { 49 std::lock_guard<std::mutex> lock(mStreamLock); 50 for (auto it = mListeners.begin(); it != mListeners.end();) { 51 if (*it == listener) { 52 it = mListeners.erase(it); 53 } else { 54 ++it; 55 } 56 } 57 } 58 59 protected: fireEvent(EventObject evt)60 void fireEvent(EventObject evt) { 61 std::lock_guard<std::mutex> lock(mStreamLock); 62 for (const auto& listener : mListeners) { 63 (*listener)(evt); 64 } 65 for (const auto& listener : mNonRemovableListeners) { 66 listener(evt); 67 } 68 } 69 70 private: 71 std::vector<EventListener*> mListeners; 72 std::vector<EventListener> mNonRemovableListeners; 73 std::mutex mStreamLock; 74 }; 75 76 // A RaiiEventListener is an event listener that will register and unregister 77 // the provided callback when this object goes out of scope. 78 template <class Source, class EventObject> 79 class RaiiEventListener { 80 public: 81 using EventListener = std::function<void(const EventObject evt)>; 82 RaiiEventListener(Source * src,EventListener listener)83 RaiiEventListener(Source* src, EventListener listener) 84 : mSource(src), mListener(std::move(listener)) { 85 mSource->addListener(&mListener); 86 } 87 ~RaiiEventListener()88 ~RaiiEventListener() { mSource->removeListener(&mListener); } 89 90 private: 91 Source* mSource; 92 EventListener mListener; 93 }; 94 } // namespace base 95 } // namespace android 96