1 /*
2 * Copyright (c) 2020-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 "bundle_map.h"
17
18 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
19 #include <pthread.h>
20 #else
21 #include "cmsis_os2.h"
22 #endif
23 #include "adapter.h"
24 #include "appexecfwk_errors.h"
25 #include "bundle_info_utils.h"
26 #include "utils.h"
27
28 namespace OHOS {
29 const int32_t GET_BUNDLE_WITH_ABILITIES = 1;
30 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
31 static pthread_mutex_t g_bundleListMutex = PTHREAD_MUTEX_INITIALIZER;
32 #else
33 const int32_t BUNDLELIST_MUTEX_TIMEOUT = 2000;
34 static osMutexId_t g_bundleListMutex;
35 #endif
36
BundleMap()37 BundleMap::BundleMap()
38 {
39 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
40 pthread_mutex_init(&g_bundleListMutex, nullptr);
41 #else
42 g_bundleListMutex = osMutexNew(reinterpret_cast<osMutexAttr_t *>(NULL));
43 #endif
44 bundleInfos_ = new (std::nothrow) List<BundleInfo *>();
45 }
46
~BundleMap()47 BundleMap::~BundleMap()
48 {
49 MutexDelete(&g_bundleListMutex);
50 delete bundleInfos_;
51 bundleInfos_ = nullptr;
52 }
53
Add(BundleInfo * bundleInfo)54 void BundleMap::Add(BundleInfo *bundleInfo)
55 {
56 if ((bundleInfo == nullptr) || (bundleInfo->bundleName == nullptr)) {
57 return;
58 }
59 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
60 MutexAcquire(&g_bundleListMutex, 0);
61 #else
62 MutexAcquire(&g_bundleListMutex, BUNDLELIST_MUTEX_TIMEOUT);
63 #endif
64 for (auto node = bundleInfos_->Begin(); node != bundleInfos_->End(); node = node->next_) {
65 BundleInfo *info = node->value_;
66 if (info != nullptr && info->bundleName != nullptr && strcmp(info->bundleName, bundleInfo->bundleName) == 0) {
67 MutexRelease(&g_bundleListMutex);
68 return;
69 }
70 }
71 bundleInfos_->PushFront(bundleInfo);
72 MutexRelease(&g_bundleListMutex);
73 return;
74 }
75
Update(BundleInfo * bundleInfo)76 bool BundleMap::Update(BundleInfo *bundleInfo)
77 {
78 if ((bundleInfo == nullptr) || (bundleInfo->bundleName == nullptr)) {
79 return false;
80 }
81 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
82 MutexAcquire(&g_bundleListMutex, 0);
83 #else
84 MutexAcquire(&g_bundleListMutex, BUNDLELIST_MUTEX_TIMEOUT);
85 #endif
86 auto newNode = new (std::nothrow) Node<BundleInfo *>(bundleInfo);
87 if (newNode == nullptr) {
88 MutexRelease(&g_bundleListMutex);
89 return false;
90 }
91 for (auto oldNode = bundleInfos_->Begin(); oldNode != bundleInfos_->End(); oldNode = oldNode->next_) {
92 BundleInfo *info = oldNode->value_;
93 if ((info != nullptr) && (info->bundleName != nullptr) &&
94 (strcmp(info->bundleName, bundleInfo->bundleName) == 0)) {
95 oldNode->prev_->next_ = newNode;
96 oldNode->next_->prev_ = newNode;
97 newNode->prev_ = oldNode->prev_;
98 newNode->next_ = oldNode->next_;
99 BundleInfoUtils::FreeBundleInfo(info);
100 delete oldNode;
101 MutexRelease(&g_bundleListMutex);
102 return true;
103 }
104 }
105 delete newNode;
106 bundleInfos_->PushFront(bundleInfo);
107 MutexRelease(&g_bundleListMutex);
108 return true;
109 }
110
Get(const char * bundleName) const111 BundleInfo *BundleMap::Get(const char *bundleName) const
112 {
113 if (bundleName == nullptr) {
114 return nullptr;
115 }
116
117 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
118 MutexAcquire(&g_bundleListMutex, 0);
119 #else
120 MutexAcquire(&g_bundleListMutex, BUNDLELIST_MUTEX_TIMEOUT);
121 #endif
122 for (auto node = bundleInfos_->Begin(); node != bundleInfos_->End(); node = node->next_) {
123 BundleInfo *info = node->value_;
124 if (info != nullptr && info->bundleName != nullptr && strcmp(info->bundleName, bundleName) == 0) {
125 MutexRelease(&g_bundleListMutex);
126 return info;
127 }
128 }
129 MutexRelease(&g_bundleListMutex);
130 return nullptr;
131 }
132
GetCopyBundleInfo(uint32_t flags,const BundleInfo * bundleInfo,BundleInfo & newBundleInfo) const133 void BundleMap::GetCopyBundleInfo(uint32_t flags, const BundleInfo *bundleInfo, BundleInfo &newBundleInfo) const
134 {
135 if (bundleInfo == nullptr) {
136 return;
137 }
138 newBundleInfo.isSystemApp = bundleInfo->isSystemApp;
139 newBundleInfo.versionCode = bundleInfo->versionCode;
140 newBundleInfo.bundleName = bundleInfo->bundleName;
141 newBundleInfo.label = bundleInfo->label;
142 newBundleInfo.versionName = bundleInfo->versionName;
143 newBundleInfo.codePath = bundleInfo->codePath;
144 newBundleInfo.dataPath = bundleInfo->dataPath;
145 newBundleInfo.compatibleApi = bundleInfo->compatibleApi;
146 newBundleInfo.targetApi = bundleInfo->targetApi;
147 newBundleInfo.vendor = bundleInfo->vendor;
148 newBundleInfo.bigIconPath = bundleInfo->bigIconPath;
149 newBundleInfo.moduleInfos = bundleInfo->moduleInfos;
150 newBundleInfo.numOfModule = bundleInfo->numOfModule;
151 newBundleInfo.appId = bundleInfo->appId;
152 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
153 newBundleInfo.isKeepAlive = bundleInfo->isKeepAlive;
154 newBundleInfo.isNativeApp = bundleInfo->isNativeApp;
155 newBundleInfo.uid = bundleInfo->uid;
156 newBundleInfo.gid = bundleInfo->gid;
157 if (flags == GET_BUNDLE_WITH_ABILITIES) {
158 newBundleInfo.abilityInfos = bundleInfo->abilityInfos;
159 newBundleInfo.numOfAbility = bundleInfo->numOfAbility;
160 } else {
161 newBundleInfo.abilityInfos = nullptr;
162 newBundleInfo.numOfAbility = 0;
163 }
164 #else
165 newBundleInfo.smallIconPath = bundleInfo->smallIconPath;
166 if (flags == GET_BUNDLE_WITH_ABILITIES) {
167 newBundleInfo.abilityInfo = bundleInfo->abilityInfo;
168 } else {
169 newBundleInfo.abilityInfo = nullptr;
170 }
171 #endif
172 }
173
GetBundleInfos(int32_t flags,BundleInfo ** bundleInfos,int32_t * len) const174 uint8_t BundleMap::GetBundleInfos(int32_t flags, BundleInfo **bundleInfos, int32_t *len) const
175 {
176 if (bundleInfos == nullptr) {
177 return ERR_APPEXECFWK_QUERY_PARAMETER_ERROR;
178 }
179 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
180 MutexAcquire(&g_bundleListMutex, 0);
181 #else
182 MutexAcquire(&g_bundleListMutex, BUNDLELIST_MUTEX_TIMEOUT);
183 #endif
184 if (bundleInfos_->IsEmpty()) {
185 MutexRelease(&g_bundleListMutex);
186 return ERR_APPEXECFWK_QUERY_NO_INFOS;
187 }
188
189 BundleInfo *infos = reinterpret_cast<BundleInfo *>(AdapterMalloc(sizeof(BundleInfo) * bundleInfos_->Size()));
190 if (infos == nullptr || memset_s(infos, sizeof(BundleInfo) * bundleInfos_->Size(), 0,
191 sizeof(BundleInfo) * bundleInfos_->Size()) != EOK) {
192 AdapterFree(infos);
193 MutexRelease(&g_bundleListMutex);
194 return ERR_APPEXECFWK_QUERY_INFOS_INIT_ERROR;
195 }
196 *bundleInfos = infos;
197
198 for (auto node = bundleInfos_->Begin(); node != bundleInfos_->End(); node = node->next_) {
199 BundleInfoUtils::CopyBundleInfo(flags, infos++, *(node->value_));
200 }
201
202 *len = bundleInfos_->Size();
203 MutexRelease(&g_bundleListMutex);
204 return ERR_OK;
205 }
206
GetBundleInfosInner(List<BundleInfo * > & bundleInfos) const207 uint8_t BundleMap::GetBundleInfosInner(List<BundleInfo *> &bundleInfos) const
208 {
209 if (bundleInfos_->IsEmpty()) {
210 return ERR_APPEXECFWK_QUERY_NO_INFOS;
211 }
212 for (auto node = bundleInfos_->Begin(); node != bundleInfos_->End(); node = node->next_) {
213 bundleInfos.PushBack(node->value_);
214 }
215 return ERR_OK;
216 }
217
GetBundleInfosNoReplication(int32_t flags,BundleInfo ** bundleInfos,int32_t * len) const218 uint8_t BundleMap::GetBundleInfosNoReplication(int32_t flags, BundleInfo **bundleInfos, int32_t *len) const
219 {
220 if (bundleInfos == nullptr) {
221 return ERR_APPEXECFWK_QUERY_PARAMETER_ERROR;
222 }
223 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
224 MutexAcquire(&g_bundleListMutex, 0);
225 #else
226 MutexAcquire(&g_bundleListMutex, BUNDLELIST_MUTEX_TIMEOUT);
227 #endif
228 if (bundleInfos_->IsEmpty()) {
229 MutexRelease(&g_bundleListMutex);
230 return ERR_APPEXECFWK_QUERY_NO_INFOS;
231 }
232
233 BundleInfo *infos = reinterpret_cast<BundleInfo *>(AdapterMalloc(sizeof(BundleInfo) * bundleInfos_->Size()));
234 if (infos == nullptr || memset_s(infos, sizeof(BundleInfo) * bundleInfos_->Size(), 0,
235 sizeof(BundleInfo) * bundleInfos_->Size()) != EOK) {
236 AdapterFree(infos);
237 MutexRelease(&g_bundleListMutex);
238 return ERR_APPEXECFWK_QUERY_INFOS_INIT_ERROR;
239 }
240 *bundleInfos = infos;
241
242 for (auto node = bundleInfos_->Begin(); node != bundleInfos_->End(); node = node->next_) {
243 BundleInfoUtils::CopyBundleInfoNoReplication(flags, infos++, *(node->value_));
244 }
245
246 *len = bundleInfos_->Size();
247 MutexRelease(&g_bundleListMutex);
248 return ERR_OK;
249 }
250
GetBundleInfo(const char * bundleName,int32_t flags,BundleInfo & bundleInfo) const251 uint8_t BundleMap::GetBundleInfo(const char *bundleName, int32_t flags, BundleInfo &bundleInfo) const
252 {
253 if (bundleName == nullptr) {
254 return ERR_APPEXECFWK_QUERY_PARAMETER_ERROR;
255 }
256
257 BundleInfo *specialBundleInfo = Get(bundleName);
258 if (specialBundleInfo == nullptr) {
259 return ERR_APPEXECFWK_QUERY_NO_INFOS;
260 }
261
262 GetCopyBundleInfo(flags, specialBundleInfo, bundleInfo);
263 return ERR_OK;
264 }
265
Erase(const char * bundleName)266 void BundleMap::Erase(const char *bundleName)
267 {
268 if (bundleName == nullptr) {
269 return;
270 }
271 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
272 MutexAcquire(&g_bundleListMutex, 0);
273 #else
274 MutexAcquire(&g_bundleListMutex, BUNDLELIST_MUTEX_TIMEOUT);
275 #endif
276 for (auto node = bundleInfos_->Begin(); node != bundleInfos_->End(); node = node->next_) {
277 BundleInfo *info = node->value_;
278 if (info->bundleName != nullptr && strcmp(info->bundleName, bundleName) == 0) {
279 BundleInfoUtils::FreeBundleInfo(info);
280 bundleInfos_->Remove(node);
281 MutexRelease(&g_bundleListMutex);
282 return;
283 }
284 }
285 MutexRelease(&g_bundleListMutex);
286 }
287
EraseAll()288 void BundleMap::EraseAll()
289 {
290 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
291 MutexAcquire(&g_bundleListMutex, 0);
292 #else
293 MutexAcquire(&g_bundleListMutex, BUNDLELIST_MUTEX_TIMEOUT);
294 #endif
295 for (auto node = bundleInfos_->Begin(); node != bundleInfos_->End(); node = node->next_) {
296 BundleInfoUtils::FreeBundleInfo(node->value_);
297 }
298 bundleInfos_->RemoveAll();
299 MutexRelease(&g_bundleListMutex);
300 }
301 } // namespace OHOS
302