195489c19Sopenharmony_ci/*
295489c19Sopenharmony_ci * Copyright (C) 2021 Huawei Device Co., Ltd.
395489c19Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
495489c19Sopenharmony_ci * you may not use this file except in compliance with the License.
595489c19Sopenharmony_ci * You may obtain a copy of the License at
695489c19Sopenharmony_ci *
795489c19Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
895489c19Sopenharmony_ci *
995489c19Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1095489c19Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1195489c19Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1295489c19Sopenharmony_ci * See the License for the specific language governing permissions and
1395489c19Sopenharmony_ci * limitations under the License.
1495489c19Sopenharmony_ci */
1595489c19Sopenharmony_ci
1695489c19Sopenharmony_ci#ifndef BLUETOOTH_OBSERVER_MAP_H
1795489c19Sopenharmony_ci#define BLUETOOTH_OBSERVER_MAP_H
1895489c19Sopenharmony_ci
1995489c19Sopenharmony_ci#include <functional>
2095489c19Sopenharmony_ci#include <map>
2195489c19Sopenharmony_ci#include <memory>
2295489c19Sopenharmony_ci#include <mutex>
2395489c19Sopenharmony_ci
2495489c19Sopenharmony_citemplate <typename T>
2595489c19Sopenharmony_ciclass BluetoothObserverMap final {
2695489c19Sopenharmony_cipublic:
2795489c19Sopenharmony_ci    BluetoothObserverMap() = default;
2895489c19Sopenharmony_ci    ~BluetoothObserverMap();
2995489c19Sopenharmony_ci
3095489c19Sopenharmony_ci    bool Register(int handle, T observer);
3195489c19Sopenharmony_ci    bool Deregister(T observer);
3295489c19Sopenharmony_ci
3395489c19Sopenharmony_ci    void ForEach(const std::function<void(uint8_t, T)> &observer, int handle);
3495489c19Sopenharmony_ci
3595489c19Sopenharmony_ci    uint8_t GetAdvertiserHandle(T observer);
3695489c19Sopenharmony_ci    T PopAdvertiserObserver(uint8_t advHandle);
3795489c19Sopenharmony_ci    T GetAdvertiserObserver(uint8_t advHandle);
3895489c19Sopenharmony_ci    bool IsExistAdvertiserCallback(T observer, int &handle);
3995489c19Sopenharmony_ci    void Clear(void);
4095489c19Sopenharmony_ci
4195489c19Sopenharmony_ciprivate:
4295489c19Sopenharmony_ci    std::mutex lock_;
4395489c19Sopenharmony_ci    std::map<int, T> observers_;
4495489c19Sopenharmony_ci
4595489c19Sopenharmony_ci    BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(BluetoothObserverMap);
4695489c19Sopenharmony_ci};
4795489c19Sopenharmony_ci
4895489c19Sopenharmony_citemplate<typename T>
4995489c19Sopenharmony_civoid BluetoothObserverMap<T>::Clear(void)
5095489c19Sopenharmony_ci{
5195489c19Sopenharmony_ci    std::lock_guard<std::mutex> lock(lock_);
5295489c19Sopenharmony_ci    observers_.clear();
5395489c19Sopenharmony_ci}
5495489c19Sopenharmony_ci
5595489c19Sopenharmony_citemplate<typename T>
5695489c19Sopenharmony_ciBluetoothObserverMap<T>::~BluetoothObserverMap()
5795489c19Sopenharmony_ci{
5895489c19Sopenharmony_ci    std::lock_guard<std::mutex> lock(lock_);
5995489c19Sopenharmony_ci    observers_.clear();
6095489c19Sopenharmony_ci}
6195489c19Sopenharmony_ci
6295489c19Sopenharmony_citemplate<typename T>
6395489c19Sopenharmony_cibool BluetoothObserverMap<T>::Register(int handle, T observer)
6495489c19Sopenharmony_ci{
6595489c19Sopenharmony_ci    std::lock_guard<std::mutex> lock(lock_);
6695489c19Sopenharmony_ci
6795489c19Sopenharmony_ci    auto it = observers_.begin();
6895489c19Sopenharmony_ci    for (; it != observers_.end();) {
6995489c19Sopenharmony_ci        if (it->first == handle) {
7095489c19Sopenharmony_ci            observers_.erase(it++);
7195489c19Sopenharmony_ci            observers_.insert(std::make_pair(handle, observer));
7295489c19Sopenharmony_ci            return true;
7395489c19Sopenharmony_ci        } else {
7495489c19Sopenharmony_ci            ++it;
7595489c19Sopenharmony_ci        }
7695489c19Sopenharmony_ci    }
7795489c19Sopenharmony_ci    if (it == observers_.end()) {
7895489c19Sopenharmony_ci        observers_.insert(std::make_pair(handle, observer));
7995489c19Sopenharmony_ci    }
8095489c19Sopenharmony_ci    return true;
8195489c19Sopenharmony_ci}
8295489c19Sopenharmony_ci
8395489c19Sopenharmony_citemplate<typename T>
8495489c19Sopenharmony_cibool BluetoothObserverMap<T>::Deregister(T observer)
8595489c19Sopenharmony_ci{
8695489c19Sopenharmony_ci    std::lock_guard<std::mutex> lock(lock_);
8795489c19Sopenharmony_ci    auto it = observers_.begin();
8895489c19Sopenharmony_ci    for (; it != observers_.end();) {
8995489c19Sopenharmony_ci        if (it->second == observer) {
9095489c19Sopenharmony_ci            observers_.erase(it++);
9195489c19Sopenharmony_ci            return true;
9295489c19Sopenharmony_ci        } else {
9395489c19Sopenharmony_ci            ++it;
9495489c19Sopenharmony_ci        }
9595489c19Sopenharmony_ci    }
9695489c19Sopenharmony_ci
9795489c19Sopenharmony_ci    return false;
9895489c19Sopenharmony_ci}
9995489c19Sopenharmony_ci
10095489c19Sopenharmony_citemplate<typename T>
10195489c19Sopenharmony_civoid BluetoothObserverMap<T>::ForEach(const std::function<void(uint8_t, T)> &observer, int handle)
10295489c19Sopenharmony_ci{
10395489c19Sopenharmony_ci    std::lock_guard<std::mutex> lock(lock_);
10495489c19Sopenharmony_ci    for (const auto &it : observers_) {
10595489c19Sopenharmony_ci        if (handle == it.first) {
10695489c19Sopenharmony_ci            observer(it.first, it.second);
10795489c19Sopenharmony_ci        }
10895489c19Sopenharmony_ci    }
10995489c19Sopenharmony_ci}
11095489c19Sopenharmony_ci
11195489c19Sopenharmony_citemplate<typename T>
11295489c19Sopenharmony_ciuint8_t BluetoothObserverMap<T>::GetAdvertiserHandle(T observer)
11395489c19Sopenharmony_ci{
11495489c19Sopenharmony_ci    std::lock_guard<std::mutex> lock(lock_);
11595489c19Sopenharmony_ci    uint8_t advHandle = OHOS::bluetooth::BLE_INVALID_ADVERTISING_HANDLE;
11695489c19Sopenharmony_ci    if (observer == nullptr) {
11795489c19Sopenharmony_ci        return advHandle;
11895489c19Sopenharmony_ci    }
11995489c19Sopenharmony_ci
12095489c19Sopenharmony_ci    auto it = observers_.begin();
12195489c19Sopenharmony_ci    for (; it != observers_.end(); it++) {
12295489c19Sopenharmony_ci        if (it->second == observer) {
12395489c19Sopenharmony_ci            advHandle = it->first;
12495489c19Sopenharmony_ci            break;
12595489c19Sopenharmony_ci        }
12695489c19Sopenharmony_ci    }
12795489c19Sopenharmony_ci
12895489c19Sopenharmony_ci    return advHandle;
12995489c19Sopenharmony_ci}
13095489c19Sopenharmony_ci
13195489c19Sopenharmony_citemplate<typename T>
13295489c19Sopenharmony_ciT BluetoothObserverMap<T>::PopAdvertiserObserver(uint8_t advHandle)
13395489c19Sopenharmony_ci{
13495489c19Sopenharmony_ci    std::lock_guard<std::mutex> lock(lock_);
13595489c19Sopenharmony_ci    T t = nullptr;
13695489c19Sopenharmony_ci    auto it = observers_.begin();
13795489c19Sopenharmony_ci    for (; it != observers_.end(); it++) {
13895489c19Sopenharmony_ci        if (it->first == advHandle) {
13995489c19Sopenharmony_ci            t = it->second;
14095489c19Sopenharmony_ci            observers_.erase(it++);
14195489c19Sopenharmony_ci            break;
14295489c19Sopenharmony_ci        }
14395489c19Sopenharmony_ci    }
14495489c19Sopenharmony_ci    return t;
14595489c19Sopenharmony_ci}
14695489c19Sopenharmony_ci
14795489c19Sopenharmony_citemplate<typename T>
14895489c19Sopenharmony_ciT BluetoothObserverMap<T>::GetAdvertiserObserver(uint8_t advHandle)
14995489c19Sopenharmony_ci{
15095489c19Sopenharmony_ci    std::lock_guard<std::mutex> lock(lock_);
15195489c19Sopenharmony_ci    auto it = observers_.begin();
15295489c19Sopenharmony_ci    for (; it != observers_.end(); it++) {
15395489c19Sopenharmony_ci        if (it->first == advHandle) {
15495489c19Sopenharmony_ci            return it->second;
15595489c19Sopenharmony_ci        }
15695489c19Sopenharmony_ci    }
15795489c19Sopenharmony_ci
15895489c19Sopenharmony_ci    return nullptr;
15995489c19Sopenharmony_ci}
16095489c19Sopenharmony_ci
16195489c19Sopenharmony_citemplate<typename T>
16295489c19Sopenharmony_cibool BluetoothObserverMap<T>::IsExistAdvertiserCallback(T observer, int &handle)
16395489c19Sopenharmony_ci{
16495489c19Sopenharmony_ci    bool isExtist = false;
16595489c19Sopenharmony_ci    if (observer == nullptr) {
16695489c19Sopenharmony_ci        return isExtist;
16795489c19Sopenharmony_ci    }
16895489c19Sopenharmony_ci
16995489c19Sopenharmony_ci    std::lock_guard<std::mutex> lock(lock_);
17095489c19Sopenharmony_ci    auto it = observers_.begin();
17195489c19Sopenharmony_ci    for (; it != observers_.end(); it++) {
17295489c19Sopenharmony_ci        if (it->second == observer) {
17395489c19Sopenharmony_ci            handle = it->first;
17495489c19Sopenharmony_ci            isExtist = true;
17595489c19Sopenharmony_ci            break;
17695489c19Sopenharmony_ci        }
17795489c19Sopenharmony_ci    }
17895489c19Sopenharmony_ci
17995489c19Sopenharmony_ci    return isExtist;
18095489c19Sopenharmony_ci}
18195489c19Sopenharmony_ci
18295489c19Sopenharmony_ci#endif  // BLUETOOTH_OBSERVER_LIST_H