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 <array>
20 
21 #include "common/bind.h"
22 #include "common/callback.h"
23 #include "os/log.h"
24 
25 namespace bluetooth {
26 namespace common {
27 
28 // Tracks an observer registration on client (observer) code. Register() returns a wrapped callback object which can
29 // be passed to server's register API. Unregister() invalidates the wrapped callback so all callbacks that are posted
30 // to the client handler after the client called Unregister() call and before the server processed the Unregister()
31 // call on its handler, are dropped.
32 // Note: Register() invalidates the previous registration.
33 class SingleObserverRegistry {
34  public:
35   template <typename R, typename... T>
decltype(auto)36   decltype(auto) Register(Callback<R(T...)> callback) {
37     session_++;
38     return Bind(&SingleObserverRegistry::callback_wrapper<R, T...>, Unretained(this), session_, callback);
39   }
40 
Unregister()41   void Unregister() {
42     session_++;
43   }
44 
45  private:
46   template <typename R, typename... T>
callback_wrapper(int session,Callback<R (T...)> callback,T...t)47   void callback_wrapper(int session, Callback<R(T...)> callback, T... t) {
48     if (session == session_) {
49       callback.Run(std::forward<T>(t)...);
50     }
51   }
52 
53   uint8_t session_ = 0;
54 };
55 
56 // Tracks observer registration for multiple event type. Each event type is represented as an integer in [0, Capacity).
57 template <int Capacity = 10>
58 class MultipleObserverRegistry {
59  public:
60   template <typename R, typename... T>
decltype(auto)61   decltype(auto) Register(int event_type, Callback<R(T...)> callback) {
62     ASSERT(event_type < Capacity);
63     return registry_[event_type].Register(callback);
64   }
65 
Unregister(int event_type)66   void Unregister(int event_type) {
67     ASSERT(event_type < Capacity);
68     registry_[event_type].Unregister();
69   }
70 
71   std::array<SingleObserverRegistry, Capacity> registry_;
72 };
73 
74 }  // namespace common
75 }  // namespace bluetooth
76