1 /*
2 * Copyright (c) 2021-2024 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 "launcher_service.h"
17
18 #include "bundle_mgr_proxy.h"
19 #include "bundle_mgr_service_death_recipient.h"
20 #include "common_event_subscribe_info.h"
21 #include "common_event_support.h"
22 #include "hitrace_meter.h"
23 #include "matching_skills.h"
24 #include "operation_builder.h"
25
26 namespace OHOS {
27 namespace AppExecFwk {
28 OHOS::sptr<OHOS::AppExecFwk::IBundleMgr> LauncherService::bundleMgr_ = nullptr;
29 OHOS::sptr<IRemoteObject::DeathRecipient> LauncherService::deathRecipient_(
30 new (std::nothrow) LauncherServiceDeathRecipient());
31 std::mutex LauncherService::bundleMgrMutex_;
32 const char* EMPTY_STRING = "";
33
34 void LauncherService::LauncherServiceDeathRecipient::OnRemoteDied([[maybe_unused]] const wptr<IRemoteObject>& remote)
35 {
36 APP_LOGD("BundleManagerService dead");
37 std::lock_guard<std::mutex> lock(bundleMgrMutex_);
38 bundleMgr_ = nullptr;
39 };
40
LauncherService()41 LauncherService::LauncherService()
42 {
43 init();
44 }
45
init()46 void LauncherService::init()
47 {
48 EventFwk::MatchingSkills matchingSkills;
49 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED);
50 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED);
51 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED);
52 EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
53 bundleMonitor_ = std::make_shared<BundleMonitor>(subscribeInfo);
54 }
55
~LauncherService()56 LauncherService::~LauncherService()
57 {
58 APP_LOGD("destroy LauncherService");
59 if (bundleMgr_ != nullptr && deathRecipient_ != nullptr) {
60 bundleMgr_->AsObject()->RemoveDeathRecipient(deathRecipient_);
61 }
62 }
63
GetBundleMgr()64 OHOS::sptr<OHOS::AppExecFwk::IBundleMgr> LauncherService::GetBundleMgr()
65 {
66 if (bundleMgr_ == nullptr) {
67 std::lock_guard<std::mutex> lock(bundleMgrMutex_);
68 if (bundleMgr_ == nullptr) {
69 auto systemAbilityManager = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
70 if (systemAbilityManager == nullptr) {
71 APP_LOGE("GetBundleMgr GetSystemAbilityManager is null");
72 return nullptr;
73 }
74 auto bundleMgrSa = systemAbilityManager->GetSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
75 if (bundleMgrSa == nullptr) {
76 APP_LOGE("GetBundleMgr GetSystemAbility is null");
77 return nullptr;
78 }
79 auto bundleMgr = OHOS::iface_cast<IBundleMgr>(bundleMgrSa);
80 if (bundleMgr == nullptr) {
81 APP_LOGE("GetBundleMgr iface_cast get null");
82 return nullptr;
83 }
84 bundleMgr_ = bundleMgr;
85 bundleMgr_->AsObject()->AddDeathRecipient(deathRecipient_);
86 }
87 }
88 return bundleMgr_;
89 }
90
RegisterCallback(const sptr<IBundleStatusCallback> & callback)91 bool LauncherService::RegisterCallback(const sptr<IBundleStatusCallback> &callback)
92 {
93 APP_LOGD("RegisterCallback called");
94 if (bundleMonitor_ == nullptr) {
95 APP_LOGE("failed to register callback, bundleMonitor is null");
96 return false;
97 }
98
99 // check permission
100 auto iBundleMgr = GetBundleMgr();
101 if (iBundleMgr == nullptr) {
102 APP_LOGE("can not get iBundleMgr");
103 return false;
104 }
105 if (!iBundleMgr->VerifySystemApi(Constants::INVALID_API_VERSION)) {
106 APP_LOGE("non-system app calling system api");
107 return false;
108 }
109 if (!iBundleMgr->VerifyCallingPermission(Constants::LISTEN_BUNDLE_CHANGE)) {
110 APP_LOGE("register bundle status callback failed due to lack of permission");
111 return false;
112 }
113 return bundleMonitor_->Subscribe(callback);
114 }
115
UnRegisterCallback()116 bool LauncherService::UnRegisterCallback()
117 {
118 APP_LOGD("UnRegisterCallback called");
119 if (bundleMonitor_ == nullptr) {
120 APP_LOGE("failed to unregister callback, bundleMonitor is null");
121 return false;
122 }
123
124 // check permission
125 auto iBundleMgr = GetBundleMgr();
126 if (iBundleMgr == nullptr) {
127 APP_LOGE("can not get iBundleMgr");
128 return false;
129 }
130 if (!iBundleMgr->VerifySystemApi(Constants::INVALID_API_VERSION)) {
131 APP_LOGE("non-system app calling system api");
132 return false;
133 }
134 if (!iBundleMgr->VerifyCallingPermission(Constants::LISTEN_BUNDLE_CHANGE)) {
135 APP_LOGE("register bundle status callback failed due to lack of permission");
136 return false;
137 }
138 return bundleMonitor_->UnSubscribe();
139 }
140
GetAbilityList(const std::string & bundleName,const int userId,std::vector<LauncherAbilityInfo> & launcherAbilityInfos)141 bool LauncherService::GetAbilityList(
142 const std::string &bundleName, const int userId, std::vector<LauncherAbilityInfo> &launcherAbilityInfos)
143 {
144 APP_LOGD("GetAbilityList called");
145 auto iBundleMgr = GetBundleMgr();
146 if ((iBundleMgr == nullptr) || (bundleName.empty())) {
147 APP_LOGE("can not get iBundleMgr");
148 return false;
149 }
150 if (!iBundleMgr->VerifySystemApi(Constants::INVALID_API_VERSION)) {
151 APP_LOGE("non-system app calling system api");
152 return false;
153 }
154 std::vector<std::string> entities;
155 entities.push_back(Want::ENTITY_HOME);
156 Want want;
157 want.SetAction(Want::ACTION_HOME);
158 want.AddEntity(Want::ENTITY_HOME);
159 ElementName elementName;
160 elementName.SetBundleName(bundleName);
161 want.SetElement(elementName);
162 std::vector<AbilityInfo> abilityInfos;
163 if (!iBundleMgr->QueryAllAbilityInfos(want, userId, abilityInfos)) {
164 APP_LOGE("Query ability info failed");
165 return false;
166 }
167
168 for (auto &ability : abilityInfos) {
169 if (ability.bundleName != bundleName || !ability.enabled) {
170 continue;
171 }
172
173 LauncherAbilityInfo info;
174 info.applicationInfo = ability.applicationInfo;
175 info.labelId = ability.labelId;
176 info.iconId = ability.iconId;
177 ElementName abilityElementName;
178 abilityElementName.SetBundleName(ability.bundleName);
179 abilityElementName.SetModuleName(ability.moduleName);
180 abilityElementName.SetAbilityName(ability.name);
181 abilityElementName.SetDeviceID(ability.deviceId);
182 info.elementName = abilityElementName;
183 info.userId = userId;
184 info.installTime = ability.installTime;
185 launcherAbilityInfos.emplace_back(info);
186 }
187
188 return true;
189 }
190
GetAllLauncherAbilityInfos(int32_t userId,std::vector<LauncherAbilityInfo> & launcherAbilityInfos)191 bool LauncherService::GetAllLauncherAbilityInfos(int32_t userId, std::vector<LauncherAbilityInfo> &launcherAbilityInfos)
192 {
193 APP_LOGI("start");
194 auto iBundleMgr = GetBundleMgr();
195 if (iBundleMgr == nullptr) {
196 APP_LOGE("can not get iBundleMgr");
197 return false;
198 }
199 if (!iBundleMgr->VerifySystemApi(Constants::INVALID_API_VERSION)) {
200 APP_LOGE("non-system app calling system api");
201 return false;
202 }
203 Want want;
204 want.SetAction(Want::ACTION_HOME);
205 want.AddEntity(Want::ENTITY_HOME);
206
207 std::vector<AbilityInfo> abilityInfos;
208 if (!iBundleMgr->QueryAllAbilityInfos(want, userId, abilityInfos)) {
209 APP_LOGE("Query ability info failed");
210 return false;
211 }
212
213 for (const auto& ability : abilityInfos) {
214 if (ability.applicationInfo.isLauncherApp || !ability.enabled) {
215 continue;
216 }
217
218 if (ability.applicationInfo.hideDesktopIcon) {
219 APP_LOGD("Bundle(%{public}s) hide desktop icon", ability.bundleName.c_str());
220 continue;
221 }
222
223 LauncherAbilityInfo info;
224 info.installTime = ability.installTime;
225 info.applicationInfo = ability.applicationInfo;
226 info.labelId = ability.labelId;
227 info.iconId = ability.iconId;
228 info.userId = userId;
229 ElementName elementName;
230 elementName.SetBundleName(ability.bundleName);
231 elementName.SetModuleName(ability.moduleName);
232 elementName.SetAbilityName(ability.name);
233 elementName.SetDeviceID(ability.deviceId);
234 info.elementName = elementName;
235 launcherAbilityInfos.emplace_back(info);
236 }
237
238 if (launcherAbilityInfos.empty()) {
239 APP_LOGW("success, but launcherAbilityInfos is empty");
240 } else {
241 APP_LOGI("success");
242 }
243
244 return true;
245 }
246
GetShortcutInfos(const std::string & bundleName,std::vector<ShortcutInfo> & shortcutInfos)247 ErrCode LauncherService::GetShortcutInfos(
248 const std::string &bundleName, std::vector<ShortcutInfo> &shortcutInfos)
249 {
250 APP_LOGD("GetShortcutInfos called");
251 if (bundleName.empty()) {
252 APP_LOGE("bundleName is empty");
253 return ERR_BUNDLE_MANAGER_INVALID_PARAMETER;
254 }
255 auto iBundleMgr = GetBundleMgr();
256 if (iBundleMgr == nullptr) {
257 APP_LOGE("iBundleMgr is empty");
258 return ERR_BUNDLE_MANAGER_INTERNAL_ERROR;
259 }
260 if (!iBundleMgr->VerifySystemApi(Constants::INVALID_API_VERSION)) {
261 return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
262 }
263
264 std::vector<ShortcutInfo> infos;
265 if (!iBundleMgr->GetShortcutInfos(bundleName, infos)) {
266 APP_LOGE("GetShortcutInfos is empty");
267 return ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST;
268 }
269 if (infos.size() == 0) {
270 APP_LOGE("infos size is empty");
271 return ERR_BUNDLE_MANAGER_PROFILE_NOT_EXIST;
272 }
273
274 for (ShortcutInfo shortcutInfo : infos) {
275 if (bundleName == shortcutInfo.bundleName) {
276 shortcutInfos.emplace_back(shortcutInfo);
277 }
278 }
279 return ERR_OK;
280 }
281
InitWant(Want & want,const std::string & bundleName)282 void LauncherService::InitWant(Want &want, const std::string &bundleName)
283 {
284 want.SetAction(Want::ACTION_HOME);
285 want.AddEntity(Want::ENTITY_HOME);
286 if (!bundleName.empty()) {
287 ElementName elementName;
288 elementName.SetBundleName(bundleName);
289 want.SetElement(elementName);
290 }
291 }
292
ConvertAbilityToLauncherAbility(const AbilityInfo & ability,LauncherAbilityInfo & launcherAbility,const int32_t userId)293 void LauncherService::ConvertAbilityToLauncherAbility(const AbilityInfo &ability, LauncherAbilityInfo &launcherAbility,
294 const int32_t userId)
295 {
296 launcherAbility.applicationInfo = ability.applicationInfo;
297 launcherAbility.labelId = ability.labelId;
298 launcherAbility.iconId = ability.iconId;
299 ElementName elementName;
300 elementName.SetBundleName(ability.bundleName);
301 elementName.SetModuleName(ability.moduleName);
302 elementName.SetAbilityName(ability.name);
303 elementName.SetDeviceID(ability.deviceId);
304 launcherAbility.elementName = elementName;
305 launcherAbility.userId = userId;
306 launcherAbility.installTime = ability.installTime;
307 }
308
GetLauncherAbilityByBundleName(const std::string & bundleName,const int32_t userId,std::vector<LauncherAbilityInfo> & launcherAbilityInfos)309 ErrCode LauncherService::GetLauncherAbilityByBundleName(const std::string &bundleName, const int32_t userId,
310 std::vector<LauncherAbilityInfo> &launcherAbilityInfos)
311 {
312 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
313 APP_LOGD("GetLauncherAbilityByBundleName called");
314 if (bundleName.empty()) {
315 APP_LOGE("no bundleName %{public}s found", bundleName.c_str());
316 return ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST;
317 }
318 auto iBundleMgr = GetBundleMgr();
319 if (iBundleMgr == nullptr) {
320 APP_LOGE("can not get iBundleMgr");
321 return ERR_APPEXECFWK_SERVICE_NOT_READY;
322 }
323
324 Want want;
325 InitWant(want, bundleName);
326 std::vector<AbilityInfo> abilityInfos;
327 ErrCode err = iBundleMgr->QueryLauncherAbilityInfos(want, userId, abilityInfos);
328 if (err != ERR_OK) {
329 APP_LOGE("QueryLauncherAbilityInfos failed");
330 return err;
331 }
332 for (const auto &ability : abilityInfos) {
333 if (ability.bundleName != bundleName || !ability.enabled) {
334 continue;
335 }
336 LauncherAbilityInfo info;
337 ConvertAbilityToLauncherAbility(ability, info, userId);
338 launcherAbilityInfos.push_back(info);
339 }
340 return ERR_OK;
341 }
342
GetAllLauncherAbility(const int32_t userId,std::vector<LauncherAbilityInfo> & launcherAbilityInfos)343 ErrCode LauncherService::GetAllLauncherAbility(const int32_t userId,
344 std::vector<LauncherAbilityInfo> &launcherAbilityInfos)
345 {
346 APP_LOGD("GetAllLauncherAbility called");
347 auto iBundleMgr = GetBundleMgr();
348 if (iBundleMgr == nullptr) {
349 APP_LOGE("can not get iBundleMgr");
350 return ERR_APPEXECFWK_SERVICE_NOT_READY;
351 }
352
353 Want want;
354 InitWant(want, EMPTY_STRING);
355 std::vector<AbilityInfo> abilityInfos;
356 ErrCode err = iBundleMgr->QueryLauncherAbilityInfos(want, userId, abilityInfos);
357 if (err != ERR_OK) {
358 APP_LOGE("QueryLauncherAbilityInfos failed");
359 return err;
360 }
361 for (const auto &ability : abilityInfos) {
362 if (!ability.enabled || ability.applicationInfo.hideDesktopIcon) {
363 continue;
364 }
365 LauncherAbilityInfo info;
366 ConvertAbilityToLauncherAbility(ability, info, userId);
367 launcherAbilityInfos.push_back(info);
368 }
369 return ERR_OK;
370 }
371
GetShortcutInfoV9(const std::string & bundleName,std::vector<ShortcutInfo> & shortcutInfos,int32_t userId)372 ErrCode LauncherService::GetShortcutInfoV9(
373 const std::string &bundleName, std::vector<ShortcutInfo> &shortcutInfos, int32_t userId)
374 {
375 auto iBundleMgr = GetBundleMgr();
376 if (iBundleMgr == nullptr) {
377 APP_LOGE("can not get iBundleMgr");
378 return ERR_APPEXECFWK_SERVICE_NOT_READY;
379 }
380 std::vector<ShortcutInfo> infos;
381 ErrCode errCode = iBundleMgr->GetShortcutInfoV9(bundleName, infos, userId);
382 if (errCode != ERR_OK) {
383 APP_LOGE("GetShortcutInfoV9 is failed");
384 return errCode;
385 }
386 if (infos.empty()) {
387 APP_LOGD("ShortcutInfo is not exist for this bundle");
388 return ERR_OK;
389 }
390
391 for (ShortcutInfo shortcutInfo : infos) {
392 if (bundleName == shortcutInfo.bundleName) {
393 shortcutInfos.emplace_back(shortcutInfo);
394 }
395 }
396 return ERR_OK;
397 }
398
OnDeath()399 void LauncherService::OnDeath()
400 {
401 APP_LOGD("BundleManagerService dead");
402 std::lock_guard<std::mutex> lock(bundleMgrMutex_);
403 bundleMgr_ = nullptr;
404 }
405 } // namespace AppExecFwk
406 } // namespace OHOS