1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
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  */
15 
16 #include "remote_connect_listener_manager.h"
17 
18 #include "iam_check.h"
19 #include "iam_logger.h"
20 
21 #define LOG_TAG "USER_AUTH_SA"
22 namespace OHOS {
23 namespace UserIam {
24 namespace UserAuth {
25 namespace {
26 const char *GLOBAL_CONNECTION_NAME = "GLOBAL";
27 }
operator ==(const ListenerInfo & other) const28 bool RemoteConnectListenerManager::ListenerInfo::operator==(const ListenerInfo &other) const
29 {
30     bool compareRet = endPointName == other.endPointName &&
31         (connectionName == other.connectionName || connectionName == GLOBAL_CONNECTION_NAME);
32     return compareRet;
33 }
34 
GetInstance()35 RemoteConnectListenerManager &RemoteConnectListenerManager::GetInstance()
36 {
37     static RemoteConnectListenerManager instance;
38     return instance;
39 }
40 
RegisterListener(const std::string & connectionName,const std::string & endPointName,const std::shared_ptr<ConnectionListener> & listener)41 ResultCode RemoteConnectListenerManager::RegisterListener(const std::string &connectionName,
42     const std::string &endPointName, const std::shared_ptr<ConnectionListener> &listener)
43 {
44     std::lock_guard<std::recursive_mutex> lock(listenerMutex_);
45     IF_FALSE_LOGE_AND_RETURN_VAL(listener != nullptr, GENERAL_ERROR);
46     IAM_LOGI("RegisterListener connectionName:%{public}s, endPointName:%{public}s", connectionName.c_str(),
47         endPointName.c_str());
48 
49     ListenerInfo info = { connectionName, endPointName, listener };
50     auto it = std::find(listeners_.begin(), listeners_.end(), info);
51     if (it != listeners_.end()) {
52         IAM_LOGE("listener already exist");
53         return GENERAL_ERROR;
54     }
55 
56     listeners_.push_back(info);
57     return SUCCESS;
58 }
59 
RegisterListener(const std::string & endPointName,const std::shared_ptr<ConnectionListener> & listener)60 ResultCode RemoteConnectListenerManager::RegisterListener(const std::string &endPointName,
61     const std::shared_ptr<ConnectionListener> &listener)
62 {
63     std::lock_guard<std::recursive_mutex> lock(listenerMutex_);
64     return RegisterListener(GLOBAL_CONNECTION_NAME, endPointName, listener);
65 }
66 
UnregisterListener(const std::string & connectionName,const std::string & endPointName)67 ResultCode RemoteConnectListenerManager::UnregisterListener(const std::string &connectionName,
68     const std::string &endPointName)
69 {
70     std::lock_guard<std::recursive_mutex> lock(listenerMutex_);
71     IAM_LOGI("UnregisterListener connectionName:%{public}s, endPointName:%{public}s", connectionName.c_str(),
72         endPointName.c_str());
73     ListenerInfo info = { connectionName, endPointName };
74     auto it = std::find(listeners_.begin(), listeners_.end(), info);
75     if (it == listeners_.end()) {
76         IAM_LOGE("listener not exist");
77         return GENERAL_ERROR;
78     }
79 
80     listeners_.erase(it);
81     return SUCCESS;
82 }
83 
UnregisterListener(const std::string & endPointName)84 ResultCode RemoteConnectListenerManager::UnregisterListener(const std::string &endPointName)
85 {
86     std::lock_guard<std::recursive_mutex> lock(listenerMutex_);
87     return UnregisterListener(GLOBAL_CONNECTION_NAME, endPointName);
88 }
89 
FindListener(const std::string & connectionName,const std::string & endPointName)90 std::shared_ptr<ConnectionListener> RemoteConnectListenerManager::FindListener(const std::string &connectionName,
91     const std::string &endPointName)
92 {
93     std::lock_guard<std::recursive_mutex> lock(listenerMutex_);
94     ListenerInfo info = { connectionName, endPointName };
95     auto it = std::find(listeners_.begin(), listeners_.end(), info);
96     if (it == listeners_.end()) {
97         IAM_LOGE("connectionName:%{public}s, endPointName:%{public}s, listener not exist", connectionName.c_str(),
98             endPointName.c_str());
99         return nullptr;
100     }
101     return it->listener;
102 }
103 
OnConnectionDown(const std::string & connectionName)104 void RemoteConnectListenerManager::OnConnectionDown(const std::string &connectionName)
105 {
106     std::lock_guard<std::recursive_mutex> lock(listenerMutex_);
107     IAM_LOGI("OnConnectionDown connectionName:%{public}s", connectionName.c_str());
108     for (auto it = listeners_.begin(); it != listeners_.end(); ++it) {
109         if (it->listener == nullptr) {
110             IAM_LOGE("it->listener is null");
111             continue;
112         }
113         if (it->connectionName == connectionName) {
114             IAM_LOGI("notify listener endPointName:%{public}s", it->endPointName.c_str());
115             it->listener->OnConnectStatus(connectionName, ConnectStatus::DISCONNECTED);
116         }
117     }
118     listeners_.erase(std::remove_if(listeners_.begin(), listeners_.end(),
119         [&](ListenerInfo item) { return item.connectionName == connectionName; }),
120         listeners_.end());
121     IAM_LOGI("OnConnectionDown end");
122 }
123 
OnConnectionUp(const std::string & connectionName)124 void RemoteConnectListenerManager::OnConnectionUp(const std::string &connectionName)
125 {
126     std::lock_guard<std::recursive_mutex> lock(listenerMutex_);
127     IAM_LOGI("OnConnectionUp connectionName:%{public}s", connectionName.c_str());
128     for (auto it = listeners_.begin(); it != listeners_.end(); ++it) {
129         if (it->connectionName == connectionName) {
130             if (it->listener == nullptr) {
131                 IAM_LOGE("it->listener is null");
132                 continue;
133             }
134             IAM_LOGI("notify listener endPointName:%{public}s", it->endPointName.c_str());
135             it->listener->OnConnectStatus(connectionName, ConnectStatus::CONNECTED);
136         }
137     }
138     IAM_LOGI("OnConnectionUp end");
139 }
140 } // namespace UserAuth
141 } // namespace UserIam
142 } // namespace OHOS