• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "resource_node_pool.h"
17 
18 #include <mutex>
19 #include <set>
20 #include <unordered_map>
21 
22 #include <singleton.h>
23 
24 #include "iam_check.h"
25 #include "iam_logger.h"
26 
27 #define LOG_TAG "USER_AUTH_SA"
28 
29 namespace OHOS {
30 namespace UserIam {
31 namespace UserAuth {
32 class ResourceNodePoolImpl final : public ResourceNodePool, public Singleton<ResourceNodePoolImpl> {
33 public:
34     bool Insert(const std::shared_ptr<ResourceNode> &resource) override;
35     bool Delete(uint64_t executorIndex) override;
36     void DeleteAll() override;
37     std::weak_ptr<ResourceNode> Select(uint64_t executorIndex) const override;
38     uint32_t GetPoolSize() const override;
39     void Enumerate(std::function<void(const std::weak_ptr<ResourceNode> &)> action) const override;
40     bool RegisterResourceNodePoolListener(const std::shared_ptr<ResourceNodePoolListener> &listener) override;
41     bool DeregisterResourceNodePoolListener(const std::shared_ptr<ResourceNodePoolListener> &listener) override;
42     void GetResourceNodeByTypeAndRole(AuthType authType,
43         ExecutorRole role, std::vector<std::weak_ptr<ResourceNode>> &authTypeNodes) override;
44 
45 private:
46     struct ResourceNodeParam {
47         uint32_t count = 0;
48         std::shared_ptr<ResourceNode> node = nullptr;
49     };
50     mutable std::recursive_mutex poolMutex_;
51     std::unordered_map<uint64_t, ResourceNodeParam> resourceNodeMap_;
52     std::set<std::shared_ptr<ResourceNodePoolListener>> listenerSet_;
53 };
54 
Insert(const std::shared_ptr<ResourceNode> & resource)55 bool ResourceNodePoolImpl::Insert(const std::shared_ptr<ResourceNode> &resource)
56 {
57     if (resource == nullptr) {
58         IAM_LOGE("resource is nullptr");
59         return false;
60     }
61     std::lock_guard<std::recursive_mutex> lock(poolMutex_);
62     uint64_t executorIndex = resource->GetExecutorIndex();
63 
64     ResourceNodeParam nodeParam = {1, resource};
65     auto iter = resourceNodeMap_.find(executorIndex);
66     if (iter != resourceNodeMap_.end()) {
67         if (nodeParam.count < UINT32_MAX) {
68             nodeParam.count = iter->second.count + 1;
69         }
70         if (iter->second.node != nullptr) {
71             iter->second.node->DetachFromDriver();
72         }
73     }
74 
75     auto result = resourceNodeMap_.insert_or_assign(executorIndex, nodeParam);
76     auto tempListenerSet = listenerSet_;
77     if (result.second) {
78         IAM_LOGI("insert resource node success");
79         for (const auto &listener : tempListenerSet) {
80             if (listener != nullptr) {
81                 listener->OnResourceNodePoolInsert(nodeParam.node);
82             }
83         }
84     } else {
85         IAM_LOGI("update resource node success, count: %{public}u", resourceNodeMap_[executorIndex].count);
86         for (const auto &listener : tempListenerSet) {
87             if (listener != nullptr) {
88                 listener->OnResourceNodePoolUpdate(nodeParam.node);
89             }
90         }
91     }
92     return true;
93 }
94 
Delete(uint64_t executorIndex)95 bool ResourceNodePoolImpl::Delete(uint64_t executorIndex)
96 {
97     std::lock_guard<std::recursive_mutex> lock(poolMutex_);
98     auto iter = resourceNodeMap_.find(executorIndex);
99     if (iter == resourceNodeMap_.end()) {
100         IAM_LOGE("executor not found");
101         return false;
102     }
103 
104     if (iter->second.count > 1) {
105         iter->second.count--;
106         IAM_LOGI("resource node count %{public}u, no delete", iter->second.count);
107         return true;
108     }
109     IAM_LOGI("delete resource node");
110 
111     auto tempResource = iter->second.node;
112     resourceNodeMap_.erase(iter);
113     IF_FALSE_LOGE_AND_RETURN_VAL(tempResource != nullptr, false);
114     tempResource->DeleteFromDriver();
115 
116     auto tempListenerSet = listenerSet_;
117     for (const auto &listener : tempListenerSet) {
118         if (listener != nullptr) {
119             listener->OnResourceNodePoolDelete(tempResource);
120         }
121     }
122     return true;
123 }
124 
DeleteAll()125 void ResourceNodePoolImpl::DeleteAll()
126 {
127     std::lock_guard<std::recursive_mutex> lock(poolMutex_);
128     IAM_LOGI("delete all resource node begin, node num %{public}zu", resourceNodeMap_.size());
129     for (const auto &pair : resourceNodeMap_) {
130         auto node = pair.second.node;
131         if (node != nullptr) {
132             node->DeleteFromDriver();
133         }
134     }
135     auto tempMap = resourceNodeMap_;
136     auto tempListenerSet = listenerSet_;
137     resourceNodeMap_.clear();
138     for (auto &node : tempMap) {
139         for (const auto &listener : tempListenerSet) {
140             if (listener != nullptr) {
141                 listener->OnResourceNodePoolDelete(node.second.node);
142             }
143         }
144     }
145     IAM_LOGI("delete all resource node success");
146 }
147 
Select(uint64_t executorIndex) const148 std::weak_ptr<ResourceNode> ResourceNodePoolImpl::Select(uint64_t executorIndex) const
149 {
150     std::lock_guard<std::recursive_mutex> lock(poolMutex_);
151     std::weak_ptr<ResourceNode> result;
152     auto iter = resourceNodeMap_.find(executorIndex);
153     if (iter != resourceNodeMap_.end()) {
154         result = iter->second.node;
155     }
156     return result;
157 }
158 
Enumerate(std::function<void (const std::weak_ptr<ResourceNode> &)> action) const159 void ResourceNodePoolImpl::Enumerate(std::function<void(const std::weak_ptr<ResourceNode> &)> action) const
160 {
161     if (action == nullptr) {
162         IAM_LOGE("action is nullptr");
163         return;
164     }
165     std::lock_guard<std::recursive_mutex> lock(poolMutex_);
166     for (auto &node : resourceNodeMap_) {
167         action(node.second.node);
168     }
169 }
170 
GetPoolSize() const171 uint32_t ResourceNodePoolImpl::GetPoolSize() const
172 {
173     std::lock_guard<std::recursive_mutex> lock(poolMutex_);
174     return resourceNodeMap_.size();
175 }
176 
RegisterResourceNodePoolListener(const std::shared_ptr<ResourceNodePoolListener> & listener)177 bool ResourceNodePoolImpl::RegisterResourceNodePoolListener(const std::shared_ptr<ResourceNodePoolListener> &listener)
178 {
179     if (listener == nullptr) {
180         IAM_LOGE("listener is nullptr");
181         return false;
182     }
183     std::lock_guard<std::recursive_mutex> lock(poolMutex_);
184     listenerSet_.insert(listener);
185     return true;
186 }
187 
DeregisterResourceNodePoolListener(const std::shared_ptr<ResourceNodePoolListener> & listener)188 bool ResourceNodePoolImpl::DeregisterResourceNodePoolListener(const std::shared_ptr<ResourceNodePoolListener> &listener)
189 {
190     std::lock_guard<std::recursive_mutex> lock(poolMutex_);
191     return listenerSet_.erase(listener) == 1;
192 }
193 
GetResourceNodeByTypeAndRole(AuthType authType,ExecutorRole role,std::vector<std::weak_ptr<ResourceNode>> & authTypeNodes)194 void ResourceNodePoolImpl::GetResourceNodeByTypeAndRole(AuthType authType,
195     ExecutorRole role, std::vector<std::weak_ptr<ResourceNode>> &authTypeNodes)
196 {
197     IAM_LOGI("start");
198     authTypeNodes.clear();
199     ResourceNodePool::Instance().Enumerate(
200         [&authTypeNodes, role, authType](const std::weak_ptr<ResourceNode> &weakNode) {
201             auto node = weakNode.lock();
202             if (node == nullptr) {
203                 return;
204             }
205             if (node->GetAuthType() != authType) {
206                 return;
207             }
208             if (node->GetExecutorRole() != role) {
209                 return;
210             }
211             authTypeNodes.push_back(node);
212         });
213 }
214 
Instance()215 ResourceNodePool &ResourceNodePool::Instance()
216 {
217     return ResourceNodePoolImpl::GetInstance();
218 }
219 } // namespace UserAuth
220 } // namespace UserIam
221 } // namespace OHOS
222