• 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 "context_pool.h"
17 
18 #include <mutex>
19 #include <set>
20 #include <singleton.h>
21 #include <unordered_map>
22 
23 #include <openssl/rand.h>
24 
25 #include "iam_logger.h"
26 
27 #define LOG_LABEL UserIam::Common::LABEL_USER_AUTH_SA
28 
29 namespace OHOS {
30 namespace UserIam {
31 namespace UserAuth {
32 class ContextPoolImpl final : public ContextPool, public Singleton<ContextPoolImpl> {
33 public:
34     bool Insert(const std::shared_ptr<Context> &context) override;
35     bool Delete(uint64_t contextId) override;
36     std::weak_ptr<Context> Select(uint64_t contextId) const override;
37     std::vector<std::weak_ptr<Context>> Select(ContextType contextType) const override;
38     std::shared_ptr<ScheduleNode> SelectScheduleNodeByScheduleId(uint64_t scheduleId) override;
39     bool RegisterContextPoolListener(const std::shared_ptr<ContextPoolListener> &listener) override;
40     bool DeregisterContextPoolListener(const std::shared_ptr<ContextPoolListener> &listener) override;
41 
42 private:
43     mutable std::mutex poolMutex_;
44     std::unordered_map<uint64_t, std::shared_ptr<Context>> contextMap_;
45     std::set<std::shared_ptr<ContextPoolListener>> listenerSet_;
46 };
47 
Insert(const std::shared_ptr<Context> & context)48 bool ContextPoolImpl::Insert(const std::shared_ptr<Context> &context)
49 {
50     if (context == nullptr) {
51         IAM_LOGE("context is nullptr");
52         return false;
53     }
54     std::lock_guard<std::mutex> lock(poolMutex_);
55     uint64_t contextId = context->GetContextId();
56     auto result = contextMap_.try_emplace(contextId, context);
57     if (!result.second) {
58         return false;
59     }
60     for (const auto &listener : listenerSet_) {
61         if (listener != nullptr) {
62             listener->OnContextPoolInsert(context);
63         }
64     }
65     return true;
66 }
67 
Delete(uint64_t contextId)68 bool ContextPoolImpl::Delete(uint64_t contextId)
69 {
70     std::lock_guard<std::mutex> lock(poolMutex_);
71     auto iter = contextMap_.find(contextId);
72     if (iter == contextMap_.end()) {
73         IAM_LOGE("context not found");
74         return false;
75     }
76     auto tempContext = iter->second;
77     contextMap_.erase(iter);
78     for (const auto &listener : listenerSet_) {
79         if (listener != nullptr) {
80             listener->OnContextPoolDelete(tempContext);
81         }
82     }
83     return true;
84 }
85 
Select(uint64_t contextId) const86 std::weak_ptr<Context> ContextPoolImpl::Select(uint64_t contextId) const
87 {
88     std::lock_guard<std::mutex> lock(poolMutex_);
89     std::weak_ptr<Context> result;
90     auto iter = contextMap_.find(contextId);
91     if (iter != contextMap_.end()) {
92         result = iter->second;
93     }
94     return result;
95 }
96 
Select(ContextType contextType) const97 std::vector<std::weak_ptr<Context>> ContextPoolImpl::Select(ContextType contextType) const
98 {
99     std::lock_guard<std::mutex> lock(poolMutex_);
100     std::vector<std::weak_ptr<Context>> result;
101     for (const auto &context : contextMap_) {
102         if (context.second == nullptr) {
103             continue;
104         }
105         if (context.second->GetContextType() == contextType) {
106             result.emplace_back(context.second);
107         }
108     }
109     return result;
110 }
111 
SelectScheduleNodeByScheduleId(uint64_t scheduleId)112 std::shared_ptr<ScheduleNode> ContextPoolImpl::SelectScheduleNodeByScheduleId(uint64_t scheduleId)
113 {
114     std::lock_guard<std::mutex> lock(poolMutex_);
115     for (const auto &context : contextMap_) {
116         if (context.second == nullptr) {
117             continue;
118         }
119         auto node = context.second->GetScheduleNode(scheduleId);
120         if (node != nullptr) {
121             return node;
122         }
123     }
124     return nullptr;
125 }
126 
RegisterContextPoolListener(const std::shared_ptr<ContextPoolListener> & listener)127 bool ContextPoolImpl::RegisterContextPoolListener(const std::shared_ptr<ContextPoolListener> &listener)
128 {
129     if (listener == nullptr) {
130         IAM_LOGE("listener is nullptr");
131         return false;
132     }
133     std::lock_guard<std::mutex> lock(poolMutex_);
134     listenerSet_.insert(listener);
135     return true;
136 }
137 
DeregisterContextPoolListener(const std::shared_ptr<ContextPoolListener> & listener)138 bool ContextPoolImpl::DeregisterContextPoolListener(const std::shared_ptr<ContextPoolListener> &listener)
139 {
140     std::lock_guard<std::mutex> lock(poolMutex_);
141     return listenerSet_.erase(listener) == 1;
142 }
143 
Instance()144 ContextPool &ContextPool::Instance()
145 {
146     return ContextPoolImpl::GetInstance();
147 }
148 
GetNewContextId()149 uint64_t ContextPool::GetNewContextId()
150 {
151     static constexpr uint32_t MAX_TRY_TIMES = 10;
152     static std::mutex mutex;
153     std::lock_guard<std::mutex> lock(mutex);
154     uint64_t contextId = 0;
155     unsigned char *contextIdPtr = static_cast<unsigned char *>(static_cast<void *>(&contextId));
156     for (uint32_t i = 0; i < MAX_TRY_TIMES; i++) {
157         RAND_bytes(contextIdPtr, sizeof(uint64_t));
158         if (contextId == 0 || ContextPool::Instance().Select(contextId).lock() != nullptr) {
159             IAM_LOGE("invalid or duplicate context id");
160             continue;
161         }
162     }
163     return contextId;
164 }
165 } // namespace UserAuth
166 } // namespace UserIam
167 } // namespace OHOS
168