1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <utility>
20 
21 #include "base/callback_list.h"
22 #include "os/handler.h"
23 
24 /* This file contains CallbackList implementation that will execute callback on provided Handler thread
25 
26 Example usage inside your class:
27 
28 private:
29   common::CallbackList<void(int)> callbacks_list_;
30 public:
31   std::unique_ptr<common::CallbackList<void(int)>::Subscription> RegisterCallback(
32       const base::RepeatingCallback<void(int)>& cb, os::Handler* handler) {
33     return callbacks_list_.Add({cb, handler});
34   }
35 
36   void NotifyAllCallbacks(int value) {
37     callbacks_list_.Notify(value);
38   }
39 */
40 
41 namespace bluetooth {
42 namespace common {
43 
44 namespace {
45 template <typename CallbackType>
46 struct CallbackWithHandler {
CallbackWithHandlerCallbackWithHandler47   CallbackWithHandler(base::RepeatingCallback<CallbackType> callback, os::Handler* handler)
48       : callback(callback), handler(handler) {}
49 
is_nullCallbackWithHandler50   bool is_null() const {
51     return callback.is_null();
52   }
53 
ResetCallbackWithHandler54   void Reset() {
55     callback.Reset();
56   }
57 
58   base::RepeatingCallback<CallbackType> callback;
59   os::Handler* handler;
60 };
61 
62 }  // namespace
63 
64 template <typename Sig>
65 class CallbackList;
66 template <typename... Args>
67 class CallbackList<void(Args...)> : public base::internal::CallbackListBase<CallbackWithHandler<void(Args...)>> {
68  public:
69   using CallbackType = CallbackWithHandler<void(Args...)>;
70   CallbackList() = default;
71   template <typename... RunArgs>
Notify(RunArgs &&...args)72   void Notify(RunArgs&&... args) {
73     auto it = this->GetIterator();
74     CallbackType* cb;
75     while ((cb = it.GetNext()) != nullptr) {
76       cb->handler->Post(base::Bind(cb->callback, args...));
77     }
78   }
79 
80  private:
81   DISALLOW_COPY_AND_ASSIGN(CallbackList);
82 };
83 
84 }  // namespace common
85 }  // namespace bluetooth
86