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
27 namespace OHOS {
28 namespace Notification {
BundleManagerHelper()29 BundleManagerHelper::BundleManagerHelper()
30 {
31 deathRecipient_ = new (std::nothrow)
32 RemoteDeathRecipient(std::bind(&BundleManagerHelper::OnRemoteDied, this, std::placeholders::_1));
33 if (deathRecipient_ == nullptr) {
34 ANS_LOGE("Failed to create RemoteDeathRecipient instance");
35 }
36 }
37
~BundleManagerHelper()38 BundleManagerHelper::~BundleManagerHelper()
39 {
40 std::lock_guard<std::mutex> lock(connectionMutex_);
41 Disconnect();
42 }
43
OnRemoteDied(const wptr<IRemoteObject> & object)44 void BundleManagerHelper::OnRemoteDied(const wptr<IRemoteObject> &object)
45 {
46 std::lock_guard<std::mutex> lock(connectionMutex_);
47 Disconnect();
48 }
49
GetBundleNameByUid(int32_t uid)50 std::string BundleManagerHelper::GetBundleNameByUid(int32_t uid)
51 {
52 std::string bundle;
53
54 std::lock_guard<std::mutex> lock(connectionMutex_);
55
56 Connect();
57
58 if (bundleMgr_ != nullptr) {
59 std::string identity = IPCSkeleton::ResetCallingIdentity();
60 bundleMgr_->GetNameForUid(uid, bundle);
61 IPCSkeleton::SetCallingIdentity(identity);
62 }
63
64 return bundle;
65 }
IsSystemApp(int32_t uid)66 bool BundleManagerHelper::IsSystemApp(int32_t uid)
67 {
68 bool isSystemApp = false;
69
70 std::lock_guard<std::mutex> lock(connectionMutex_);
71
72 Connect();
73
74 if (bundleMgr_ != nullptr) {
75 isSystemApp = bundleMgr_->CheckIsSystemAppByUid(uid);
76 }
77
78 return isSystemApp;
79 }
80
CheckApiCompatibility(const sptr<NotificationBundleOption> & bundleOption)81 bool BundleManagerHelper::CheckApiCompatibility(const sptr<NotificationBundleOption> &bundleOption)
82 {
83 if (bundleOption == nullptr) {
84 ANS_LOGE("bundleOption is nullptr");
85 return false;
86 }
87 return CheckApiCompatibility(bundleOption->GetBundleName(), bundleOption->GetUid());
88 }
89
CheckApiCompatibility(const std::string & bundleName,const int32_t & uid)90 bool BundleManagerHelper::CheckApiCompatibility(const std::string &bundleName, const int32_t &uid)
91 {
92 AppExecFwk::BundleInfo bundleInfo;
93 int32_t callingUserId;
94 AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(uid, callingUserId);
95 if (!GetBundleInfoByBundleName(bundleName, callingUserId, bundleInfo)) {
96 ANS_LOGW("Failed to GetBundleInfoByBundleName, bundlename = %{public}s",
97 bundleName.c_str());
98 return false;
99 }
100
101 for (auto abilityInfo : bundleInfo.abilityInfos) {
102 if (abilityInfo.isStageBasedModel) {
103 return false;
104 }
105 }
106 return true;
107 }
108
GetBundleInfoByBundleName(const std::string bundle,const int32_t userId,AppExecFwk::BundleInfo & bundleInfo)109 bool BundleManagerHelper::GetBundleInfoByBundleName(
110 const std::string bundle, const int32_t userId, AppExecFwk::BundleInfo &bundleInfo)
111 {
112 std::lock_guard<std::mutex> lock(connectionMutex_);
113 Connect();
114
115 if (bundleMgr_ == nullptr) {
116 return false;
117 }
118 bool ret = false;
119 std::string identity = IPCSkeleton::ResetCallingIdentity();
120 ret = bundleMgr_->GetBundleInfo(bundle, AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES, bundleInfo, userId);
121 IPCSkeleton::SetCallingIdentity(identity);
122 return ret;
123 }
124
Connect()125 void BundleManagerHelper::Connect()
126 {
127 if (bundleMgr_ != nullptr) {
128 return;
129 }
130
131 sptr<ISystemAbilityManager> systemAbilityManager =
132 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
133 if (systemAbilityManager == nullptr) {
134 return;
135 }
136
137 sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
138 if (remoteObject == nullptr) {
139 return;
140 }
141
142 bundleMgr_ = iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
143 if (bundleMgr_ != nullptr) {
144 bundleMgr_->AsObject()->AddDeathRecipient(deathRecipient_);
145 }
146 }
147
Disconnect()148 void BundleManagerHelper::Disconnect()
149 {
150 if (bundleMgr_ != nullptr) {
151 bundleMgr_->AsObject()->RemoveDeathRecipient(deathRecipient_);
152 bundleMgr_ = nullptr;
153 }
154 }
155
GetDefaultUidByBundleName(const std::string & bundle,const int32_t userId)156 int32_t BundleManagerHelper::GetDefaultUidByBundleName(const std::string &bundle, const int32_t userId)
157 {
158 int32_t uid = -1;
159
160 std::lock_guard<std::mutex> lock(connectionMutex_);
161
162 Connect();
163
164 if (bundleMgr_ != nullptr) {
165 std::string identity = IPCSkeleton::ResetCallingIdentity();
166 uid = bundleMgr_->GetUidByBundleName(bundle, userId);
167 if (uid < 0) {
168 ANS_LOGW("get invalid uid of bundle %{public}s in userId %{public}d", bundle.c_str(), userId);
169 }
170 IPCSkeleton::SetCallingIdentity(identity);
171 }
172
173 return uid;
174 }
175
176 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
GetDistributedNotificationEnabled(const std::string & bundleName,const int32_t userId)177 bool BundleManagerHelper::GetDistributedNotificationEnabled(const std::string &bundleName, const int32_t userId)
178 {
179 std::lock_guard<std::mutex> lock(connectionMutex_);
180
181 Connect();
182
183 if (bundleMgr_ != nullptr) {
184 AppExecFwk::ApplicationInfo appInfo;
185 if (bundleMgr_->GetApplicationInfo(
186 bundleName, AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO, userId, appInfo)) {
187 ANS_LOGD("APPLICATION_INFO distributed enabled %{public}d", appInfo.distributedNotificationEnabled);
188 return appInfo.distributedNotificationEnabled;
189 }
190 }
191
192 ANS_LOGD("APPLICATION_INFO distributed enabled is default");
193 return DEFAULT_DISTRIBUTED_ENABLE_IN_APPLICATION_INFO;
194 }
195 #endif
196
GetBundleInfo(const std::string & bundleName,const AppExecFwk::BundleFlag flag,int32_t userId,AppExecFwk::BundleInfo & bundleInfo)197 bool BundleManagerHelper::GetBundleInfo(const std::string &bundleName, const AppExecFwk::BundleFlag flag,
198 int32_t userId, AppExecFwk::BundleInfo &bundleInfo)
199 {
200 std::lock_guard<std::mutex> lock(connectionMutex_);
201
202 Connect();
203
204 if (bundleMgr_ == nullptr) {
205 return false;
206 }
207 int32_t callingUserId;
208 AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(userId, callingUserId);
209 std::string identity = IPCSkeleton::ResetCallingIdentity();
210 bool ret = bundleMgr_->GetBundleInfo(bundleName, flag, bundleInfo, callingUserId);
211 IPCSkeleton::SetCallingIdentity(identity);
212 return ret;
213 }
214
GetBundleInfos(const AppExecFwk::BundleFlag flag,std::vector<AppExecFwk::BundleInfo> & bundleInfos,int32_t userId)215 bool BundleManagerHelper::GetBundleInfos(
216 const AppExecFwk::BundleFlag flag, std::vector<AppExecFwk::BundleInfo> &bundleInfos, int32_t userId)
217 {
218 std::lock_guard<std::mutex> lock(connectionMutex_);
219 Connect();
220
221 if (bundleMgr_ == nullptr) {
222 return false;
223 }
224
225 std::string identity = IPCSkeleton::ResetCallingIdentity();
226 bool ret = bundleMgr_->GetBundleInfos(flag, bundleInfos, userId);
227 IPCSkeleton::SetCallingIdentity(identity);
228 return ret;
229 }
230
GetAppIndexByUid(const int32_t uid)231 int32_t BundleManagerHelper::GetAppIndexByUid(const int32_t uid)
232 {
233 int32_t appIndex = 0;
234 std::lock_guard<std::mutex> lock(connectionMutex_);
235 Connect();
236 if (nullptr == bundleMgr_) {
237 return appIndex;
238 }
239 std::string bundleName;
240 std::string identity = IPCSkeleton::ResetCallingIdentity();
241 bundleMgr_->GetNameAndIndexForUid(uid, bundleName, appIndex);
242 IPCSkeleton::SetCallingIdentity(identity);
243 return appIndex;
244 }
245
GetDefaultUidByBundleName(const std::string & bundle,const int32_t userId,const int32_t appIndex)246 int32_t BundleManagerHelper::GetDefaultUidByBundleName(const std::string &bundle, const int32_t userId,
247 const int32_t appIndex)
248 {
249 int32_t uid = -1;
250 std::lock_guard<std::mutex> lock(connectionMutex_);
251 Connect();
252 if (bundleMgr_ != nullptr) {
253 std::string identity = IPCSkeleton::ResetCallingIdentity();
254 uid = bundleMgr_->GetUidByBundleName(bundle, userId, appIndex);
255 if (uid < 0) {
256 ANS_LOGW("get invalid uid of bundle %{public}s in userId %{public}d", bundle.c_str(), userId);
257 }
258 IPCSkeleton::SetCallingIdentity(identity);
259 }
260 return uid;
261 }
262
GetBundleInfoV9(const std::string bundle,const int32_t flag,AppExecFwk::BundleInfo & bundleInfo,const int32_t userId)263 bool BundleManagerHelper::GetBundleInfoV9(
264 const std::string bundle, const int32_t flag,
265 AppExecFwk::BundleInfo &bundleInfo, const int32_t userId)
266 {
267 std::lock_guard<std::mutex> lock(connectionMutex_);
268 Connect();
269
270 if (bundleMgr_ == nullptr) {
271 return false;
272 }
273 bool ret = false;
274 std::string identity = IPCSkeleton::ResetCallingIdentity();
275 ret = bundleMgr_->GetBundleInfoV9(bundle, flag, bundleInfo, userId);
276 IPCSkeleton::SetCallingIdentity(identity);
277 return ret;
278 }
279 } // namespace Notification
280 } // namespace OHOS
281