• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "model_manager.h"
17 
18 #include <dlfcn.h>
19 
20 #include "directory_ex.h"
21 #include "file_ex.h"
22 #include "config_data_manager.h"
23 #include "security_guard_log.h"
24 #include "model_manager_impl.h"
25 #include "database_manager.h"
26 #include "security_guard_define.h"
27 
28 namespace OHOS::Security::SecurityGuard {
29 std::shared_ptr<IModelManager> ModelManager::modelManagerApi_ = std::make_shared<ModelManagerImpl>();
30 
31 namespace {
32     constexpr const char *PREFIX_MODEL_PATH = "/system/lib64/lib";
33     constexpr uint32_t AUDIT_MODEL = 3001000003;
34 }
35 
Init()36 void ModelManager::Init()
37 {
38     std::vector<uint32_t> modelIds = ConfigDataManager::GetInstance().GetAllModelIds();
39     ModelCfg cfg;
40     for (uint32_t modelId : modelIds) {
41         bool success = ConfigDataManager::GetInstance().GetModelConfig(modelId, cfg);
42         if (!success) {
43             continue;
44         }
45         SGLOGI("modelId is %{public}u, start_mode: %{public}u", modelId, cfg.startMode);
46         if (cfg.startMode != START_ON_STARTUP) {
47             continue;
48         }
49         if (cfg.modelId != AUDIT_MODEL) {
50             (void) InitModel(modelId);
51             continue;
52         }
53     }
54 }
55 
InitModel(uint32_t modelId)56 int32_t ModelManager::InitModel(uint32_t modelId)
57 {
58     std::unordered_map<uint32_t, std::unique_ptr<ModelAttrs>>::iterator iter;
59     {
60         std::lock_guard<std::mutex> lock(mutex_);
61         iter = modelIdApiMap_.find(modelId);
62         if (iter != modelIdApiMap_.end() && iter->second != nullptr && iter->second->GetModelApi() != nullptr) {
63             iter->second->GetModelApi()->Release();
64             modelIdApiMap_.erase(iter);
65         }
66     }
67 
68     ModelCfg cfg;
69     bool success = ConfigDataManager::GetInstance().GetModelConfig(modelId, cfg);
70     if (!success) {
71         SGLOGE("the model not support, modelId=%{public}u", modelId);
72         return NOT_FOUND;
73     }
74     std::string realPath;
75     if (!PathToRealPath(cfg.path, realPath) || realPath.find(PREFIX_MODEL_PATH) != 0) {
76         return FILE_ERR;
77     }
78     void *handle = dlopen(realPath.c_str(), RTLD_LAZY);
79     if (handle == nullptr) {
80         SGLOGE("modelId=%{public}u, open failed, reason:%{public}s", modelId, dlerror());
81         return FAILED;
82     }
83     std::unique_ptr<ModelAttrs> attr = std::make_unique<ModelAttrs>();
84     attr->SetHandle(handle);
85     auto getModelApi = (GetModelApi)dlsym(handle, "GetModelApi");
86     if (getModelApi == nullptr) {
87         SGLOGE("get model api func is nullptr");
88         return FAILED;
89     }
90     IModel *api = getModelApi();
91     if (api == nullptr) {
92         SGLOGE("get model api is nullptr");
93         return FAILED;
94     }
95     attr->SetModelApi(api);
96     int32_t ret = attr->GetModelApi()->Init(modelManagerApi_);
97     if (ret != SUCCESS) {
98         SGLOGE("model api init failed, ret=%{public}d", ret);
99         return ret;
100     }
101     {
102         std::lock_guard<std::mutex> lock(mutex_);
103         modelIdApiMap_[modelId] = std::move(attr);
104     }
105     SGLOGI("init model success, modelId=%{public}u", modelId);
106     return SUCCESS;
107 }
108 
GetResult(uint32_t modelId,const std::string & param)109 std::string ModelManager::GetResult(uint32_t modelId, const std::string &param)
110 {
111     std::string result = "unknown";
112     ModelCfg config;
113     bool success = ConfigDataManager::GetInstance().GetModelConfig(modelId, config);
114     if (!success) {
115         SGLOGI("GetResult GetModelConfig Failed, ModelId=%{public}u", modelId);
116         return result;
117     }
118     if (config.startMode == START_ON_DEMAND) {
119         if (InitModel(modelId) != SUCCESS) {
120             return result;
121         }
122     }
123     {
124         std::lock_guard<std::mutex> lock(mutex_);
125         auto iter = modelIdApiMap_.find(modelId);
126         if (iter == modelIdApiMap_.end() || iter->second == nullptr || iter->second->GetModelApi() == nullptr) {
127             SGLOGI("the model has not been initialized, begin init, modelId=%{public}u", modelId);
128             return result;
129         }
130         result = iter->second->GetModelApi()->GetResult(modelId, param);
131     }
132     if (config.startMode == START_ON_DEMAND) {
133         Release(modelId);
134     }
135     return result;
136 }
137 
SubscribeResult(uint32_t modelId,std::shared_ptr<IModelResultListener> listener)138 int32_t ModelManager::SubscribeResult(uint32_t modelId, std::shared_ptr<IModelResultListener> listener)
139 {
140     int32_t ret = InitModel(modelId);
141     if (ret != SUCCESS) {
142         return ret;
143     }
144 
145     std::lock_guard<std::mutex> lock(mutex_);
146     auto iter = modelIdApiMap_.find(modelId);
147     if (iter == modelIdApiMap_.end() || iter->second == nullptr || iter->second->GetModelApi() == nullptr) {
148         SGLOGI("the model has not been initialized, modelId=%{public}u", modelId);
149         return FAILED;
150     }
151 
152     return iter->second->GetModelApi()->SubscribeResult(listener);
153 }
154 
Release(uint32_t modelId)155 void ModelManager::Release(uint32_t modelId)
156 {
157     std::lock_guard<std::mutex> lock(mutex_);
158     auto iter = modelIdApiMap_.find(modelId);
159     if (iter == modelIdApiMap_.end()) {
160         SGLOGI("the model has not been initialized, modelId=%{public}u", modelId);
161         return;
162     }
163 
164     if (iter->second == nullptr || iter->second->GetModelApi() == nullptr) {
165         SGLOGI("the model attr is nullptr, modelId=%{public}u", modelId);
166         modelIdApiMap_.erase(iter);
167         return;
168     }
169 
170     iter->second->GetModelApi()->Release();
171     modelIdApiMap_.erase(iter);
172 }
173 
StartSecurityModel(uint32_t modelId,const std::string & param)174 int32_t ModelManager::StartSecurityModel(uint32_t modelId, const std::string &param)
175 {
176     int32_t ret = InitModel(modelId);
177     if (ret != SUCCESS) {
178         SGLOGE("InitModel fail, ret=%{public}d, modelId=%{public}u", ret, modelId);
179         return ret;
180     }
181 
182     std::lock_guard<std::mutex> lock(mutex_);
183     auto iter = modelIdApiMap_.find(modelId);
184     if (iter == modelIdApiMap_.end() || iter->second == nullptr || iter->second->GetModelApi() == nullptr) {
185         SGLOGE("the model has not been initialized, modelId=%{public}u", modelId);
186         return FAILED;
187     }
188 
189     return iter->second->GetModelApi()->StartSecurityModel(modelId, param);
190 }
191 } // namespace OHOS::Security::SecurityGuard
192