1 /*
2 * Copyright (c) 2021-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_manager_helper.h"
17
18 #include "if_system_ability_manager.h"
19 #include "iservice_registry.h"
20 #include "os_account_manager.h"
21 #include "system_ability_definition.h"
22
23 #include "ans_const_define.h"
24 #include "ans_log_wrapper.h"
25 #include "notification_analytics_util.h"
26 #include "os_account_manager_helper.h"
27
28 namespace OHOS {
29 namespace Notification {
BundleManagerHelper()30 BundleManagerHelper::BundleManagerHelper()
31 {
32 deathRecipient_ = new (std::nothrow)
33 RemoteDeathRecipient(std::bind(&BundleManagerHelper::OnRemoteDied, this, std::placeholders::_1));
34 if (deathRecipient_ == nullptr) {
35 ANS_LOGE("Failed to create RemoteDeathRecipient instance");
36 }
37 }
38
~BundleManagerHelper()39 BundleManagerHelper::~BundleManagerHelper()
40 {
41 std::lock_guard<ffrt::mutex> lock(connectionMutex_);
42 Disconnect();
43 }
44
OnRemoteDied(const wptr<IRemoteObject> & object)45 void BundleManagerHelper::OnRemoteDied(const wptr<IRemoteObject> &object)
46 {
47 std::lock_guard<ffrt::mutex> lock(connectionMutex_);
48 Disconnect();
49 }
50
GetBundleNameByUid(int32_t uid)51 std::string BundleManagerHelper::GetBundleNameByUid(int32_t uid)
52 {
53 std::string bundle;
54
55 std::lock_guard<ffrt::mutex> lock(connectionMutex_);
56
57 Connect();
58
59 if (bundleMgr_ != nullptr) {
60 std::string identity = IPCSkeleton::ResetCallingIdentity();
61 bundleMgr_->GetNameForUid(uid, bundle);
62 IPCSkeleton::SetCallingIdentity(identity);
63 }
64
65 return bundle;
66 }
IsSystemApp(int32_t uid)67 bool BundleManagerHelper::IsSystemApp(int32_t uid)
68 {
69 bool isSystemApp = false;
70
71 std::lock_guard<ffrt::mutex> lock(connectionMutex_);
72
73 Connect();
74
75 if (bundleMgr_ != nullptr) {
76 isSystemApp = bundleMgr_->CheckIsSystemAppByUid(uid);
77 }
78
79 return isSystemApp;
80 }
81
CheckApiCompatibility(const sptr<NotificationBundleOption> & bundleOption)82 bool BundleManagerHelper::CheckApiCompatibility(const sptr<NotificationBundleOption> &bundleOption)
83 {
84 if (bundleOption == nullptr) {
85 ANS_LOGE("bundleOption is nullptr");
86 return false;
87 }
88 return CheckApiCompatibility(bundleOption->GetBundleName(), bundleOption->GetUid());
89 }
90
CheckApiCompatibility(const std::string & bundleName,const int32_t & uid)91 bool BundleManagerHelper::CheckApiCompatibility(const std::string &bundleName, const int32_t &uid)
92 {
93 #ifdef ANS_DISABLE_FA_MODEL
94 return false;
95 #endif
96 AppExecFwk::BundleInfo bundleInfo;
97 int32_t callingUserId;
98 AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(uid, callingUserId);
99 if (!GetBundleInfoByBundleName(bundleName, callingUserId, bundleInfo)) {
100 ANS_LOGE("Failed to GetBundleInfoByBundleName, bundlename = %{public}s",
101 bundleName.c_str());
102 return false;
103 }
104
105 for (auto abilityInfo : bundleInfo.abilityInfos) {
106 if (abilityInfo.isStageBasedModel) {
107 return false;
108 }
109 }
110 return true;
111 }
112
GetBundleInfoByBundleName(const std::string bundle,const int32_t userId,AppExecFwk::BundleInfo & bundleInfo)113 bool BundleManagerHelper::GetBundleInfoByBundleName(
114 const std::string bundle, const int32_t userId, AppExecFwk::BundleInfo &bundleInfo)
115 {
116 std::lock_guard<ffrt::mutex> lock(connectionMutex_);
117 Connect();
118
119 if (bundleMgr_ == nullptr) {
120 return false;
121 }
122 bool ret = false;
123 std::string identity = IPCSkeleton::ResetCallingIdentity();
124 ret = bundleMgr_->GetBundleInfo(bundle, AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES, bundleInfo, userId);
125 IPCSkeleton::SetCallingIdentity(identity);
126 return ret;
127 }
128
Connect()129 void BundleManagerHelper::Connect()
130 {
131 if (bundleMgr_ != nullptr) {
132 return;
133 }
134
135 sptr<ISystemAbilityManager> systemAbilityManager =
136 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
137 if (systemAbilityManager == nullptr) {
138 return;
139 }
140
141 sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
142 if (remoteObject == nullptr) {
143 return;
144 }
145
146 bundleMgr_ = iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
147 if (bundleMgr_ != nullptr) {
148 bundleMgr_->AsObject()->AddDeathRecipient(deathRecipient_);
149 }
150 }
151
Disconnect()152 void BundleManagerHelper::Disconnect()
153 {
154 if (bundleMgr_ != nullptr) {
155 bundleMgr_->AsObject()->RemoveDeathRecipient(deathRecipient_);
156 bundleMgr_ = nullptr;
157 }
158 }
159
GetDefaultUidByBundleName(const std::string & bundle,const int32_t userId)160 int32_t BundleManagerHelper::GetDefaultUidByBundleName(const std::string &bundle, const int32_t userId)
161 {
162 int32_t uid = -1;
163
164 std::lock_guard<ffrt::mutex> lock(connectionMutex_);
165
166 Connect();
167
168 if (bundleMgr_ != nullptr) {
169 std::string identity = IPCSkeleton::ResetCallingIdentity();
170 uid = bundleMgr_->GetUidByBundleName(bundle, userId);
171 if (uid < 0) {
172 ANS_LOGW("get invalid uid of bundle %{public}s in userId %{public}d", bundle.c_str(), userId);
173 }
174 IPCSkeleton::SetCallingIdentity(identity);
175 }
176
177 return uid;
178 }
179
180 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
GetDistributedNotificationEnabled(const std::string & bundleName,const int32_t userId)181 bool BundleManagerHelper::GetDistributedNotificationEnabled(const std::string &bundleName, const int32_t userId)
182 {
183 std::lock_guard<ffrt::mutex> lock(connectionMutex_);
184
185 Connect();
186
187 if (bundleMgr_ != nullptr) {
188 AppExecFwk::ApplicationInfo appInfo;
189 if (bundleMgr_->GetApplicationInfo(
190 bundleName, AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO, userId, appInfo)) {
191 ANS_LOGD("APPLICATION_INFO distributed enabled %{public}d", appInfo.distributedNotificationEnabled);
192 return appInfo.distributedNotificationEnabled;
193 }
194 }
195
196 ANS_LOGD("APPLICATION_INFO distributed enabled is default");
197 return DEFAULT_DISTRIBUTED_ENABLE_IN_APPLICATION_INFO;
198 }
199 #endif
200
GetBundleInfo(const std::string & bundleName,const AppExecFwk::BundleFlag flag,int32_t userId,AppExecFwk::BundleInfo & bundleInfo)201 bool BundleManagerHelper::GetBundleInfo(const std::string &bundleName, const AppExecFwk::BundleFlag flag,
202 int32_t userId, AppExecFwk::BundleInfo &bundleInfo)
203 {
204 std::lock_guard<ffrt::mutex> lock(connectionMutex_);
205
206 Connect();
207
208 if (bundleMgr_ == nullptr) {
209 return false;
210 }
211 int32_t callingUserId;
212 AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(userId, callingUserId);
213 std::string identity = IPCSkeleton::ResetCallingIdentity();
214 bool ret = bundleMgr_->GetBundleInfo(bundleName, flag, bundleInfo, callingUserId);
215 IPCSkeleton::SetCallingIdentity(identity);
216 return ret;
217 }
218
GetBundleInfos(const AppExecFwk::BundleFlag flag,std::vector<AppExecFwk::BundleInfo> & bundleInfos,int32_t userId)219 bool BundleManagerHelper::GetBundleInfos(
220 const AppExecFwk::BundleFlag flag, std::vector<AppExecFwk::BundleInfo> &bundleInfos, int32_t userId)
221 {
222 std::lock_guard<ffrt::mutex> lock(connectionMutex_);
223 Connect();
224
225 if (bundleMgr_ == nullptr) {
226 return false;
227 }
228
229 std::string identity = IPCSkeleton::ResetCallingIdentity();
230 bool ret = bundleMgr_->GetBundleInfos(flag, bundleInfos, userId);
231 IPCSkeleton::SetCallingIdentity(identity);
232 return ret;
233 }
234
GetAppIndexByUid(const int32_t uid)235 int32_t BundleManagerHelper::GetAppIndexByUid(const int32_t uid)
236 {
237 int32_t appIndex = 0;
238 std::lock_guard<ffrt::mutex> lock(connectionMutex_);
239 Connect();
240 if (nullptr == bundleMgr_) {
241 return appIndex;
242 }
243 std::string bundleName;
244 std::string identity = IPCSkeleton::ResetCallingIdentity();
245 bundleMgr_->GetNameAndIndexForUid(uid, bundleName, appIndex);
246 IPCSkeleton::SetCallingIdentity(identity);
247 return appIndex;
248 }
249
GetDefaultUidByBundleName(const std::string & bundle,const int32_t userId,const int32_t appIndex)250 int32_t BundleManagerHelper::GetDefaultUidByBundleName(const std::string &bundle, const int32_t userId,
251 const int32_t appIndex)
252 {
253 int32_t uid = -1;
254 std::lock_guard<ffrt::mutex> lock(connectionMutex_);
255 Connect();
256 if (bundleMgr_ != nullptr) {
257 std::string identity = IPCSkeleton::ResetCallingIdentity();
258 uid = bundleMgr_->GetUidByBundleName(bundle, userId, appIndex);
259 if (uid < 0) {
260 ANS_LOGW("get invalid uid of bundle %{public}s in userId %{public}d", bundle.c_str(), userId);
261 }
262 IPCSkeleton::SetCallingIdentity(identity);
263 }
264 return uid;
265 }
266
GetBundleInfoV9(const std::string bundle,const int32_t flag,AppExecFwk::BundleInfo & bundleInfo,const int32_t userId)267 bool BundleManagerHelper::GetBundleInfoV9(
268 const std::string bundle, const int32_t flag,
269 AppExecFwk::BundleInfo &bundleInfo, const int32_t userId)
270 {
271 std::lock_guard<ffrt::mutex> lock(connectionMutex_);
272 Connect();
273
274 if (bundleMgr_ == nullptr) {
275 return false;
276 }
277 std::string identity = IPCSkeleton::ResetCallingIdentity();
278 int32_t ret = bundleMgr_->GetBundleInfoV9(bundle, flag, bundleInfo, userId);
279 IPCSkeleton::SetCallingIdentity(identity);
280 if (ret != ERR_OK) {
281 ANS_LOGE("Bundle failed %{public}s %{public}d %{public}d %{public}d.", bundle.c_str(),
282 flag, userId, ret);
283 return false;
284 }
285 return true;
286 }
287
GetApplicationInfo(const std::string & bundleName,int32_t flags,int32_t userId,AppExecFwk::ApplicationInfo & appInfo)288 ErrCode BundleManagerHelper::GetApplicationInfo(const std::string &bundleName, int32_t flags, int32_t userId,
289 AppExecFwk::ApplicationInfo &appInfo)
290 {
291 ErrCode result = 0;
292 std::lock_guard<ffrt::mutex> lock(connectionMutex_);
293 Connect();
294 if (bundleMgr_ == nullptr) {
295 ANS_LOGE("GetBundleInfo bundle proxy failed.");
296 return -1;
297 }
298
299 std::string identity = IPCSkeleton::ResetCallingIdentity();
300 result = bundleMgr_->GetApplicationInfoV9(bundleName, flags, userId, appInfo);
301 IPCSkeleton::SetCallingIdentity(identity);
302 return result;
303 }
304
CheckSystemApp(const std::string & bundleName,int32_t userId)305 bool BundleManagerHelper::CheckSystemApp(const std::string& bundleName, int32_t userId)
306 {
307 if (userId == SUBSCRIBE_USER_INIT) {
308 OsAccountManagerHelper::GetInstance().GetCurrentActiveUserId(userId);
309 }
310 AppExecFwk::BundleInfo bundleInfo;
311 int32_t flags = static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION);
312 if (!GetBundleInfoV9(bundleName, flags, bundleInfo, userId)) {
313 ANS_LOGE("Get installed bundle failed.");
314 return false;
315 }
316
317 ANS_LOGI("Get installed bundle %{public}s %{public}d.", bundleName.c_str(),
318 bundleInfo.applicationInfo.isSystemApp);
319 return bundleInfo.applicationInfo.isSystemApp;
320 }
321
GetBundleResourceInfo(const std::string & bundleName,AppExecFwk::BundleResourceInfo & bundleResourceInfo,const int32_t appIndex)322 ErrCode BundleManagerHelper::GetBundleResourceInfo(const std::string &bundleName,
323 AppExecFwk::BundleResourceInfo &bundleResourceInfo, const int32_t appIndex)
324 {
325 ErrCode result = 0;
326 std::lock_guard<ffrt::mutex> lock(connectionMutex_);
327 Connect();
328 if (bundleMgr_ == nullptr) {
329 ANS_LOGE("GetBundleInfo bundle proxy failed.");
330 return -1;
331 }
332 sptr<AppExecFwk::IBundleResource> bundleResourceProxy = bundleMgr_->GetBundleResourceProxy();
333 if (!bundleResourceProxy) {
334 ANS_LOGE("GetBundleInfo, get bundle resource proxy failed.");
335 return -1;
336 }
337
338 std::string identity = IPCSkeleton::ResetCallingIdentity();
339 int32_t flag = static_cast<int32_t>(AppExecFwk::ResourceFlag::GET_RESOURCE_INFO_ALL);
340 result = bundleResourceProxy->GetBundleResourceInfo(bundleName, flag, bundleResourceInfo, appIndex);
341 IPCSkeleton::SetCallingIdentity(identity);
342 return result;
343 }
344 } // namespace Notification
345 } // namespace OHOS
346