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