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