1 /*
2  * Copyright (c) 2022 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_common_event_mgr.h"
17 
18 #include "account_helper.h"
19 #include "app_log_tag_wrapper.h"
20 #include "bundle_common_event.h"
21 #include "bundle_util.h"
22 #include "common_event_manager.h"
23 #include "common_event_support.h"
24 #include "ipc_skeleton.h"
25 
26 namespace OHOS {
27 namespace AppExecFwk {
28 namespace {
29 constexpr const char* ACCESS_TOKEN_ID = "accessTokenId";
30 constexpr const char* IS_AGING_UNINSTALL = "isAgingUninstall";
31 constexpr const char* APP_ID = "appId";
32 constexpr const char* IS_MODULE_UPDATE = "isModuleUpdate";
33 constexpr const char* IS_ENABLE_DYNAMIC_ICON = "isEnableDynamicIcon";
34 constexpr const char* APP_IDENTIFIER = "appIdentifier";
35 constexpr const char* APP_DISTRIBUTION_TYPE = "appDistributionType";
36 constexpr const char* APP_INDEX = "appIndex";
37 const std::string BUNDLE_RESOURCES_CHANGED = "usual.event.BUNDLE_RESOURCES_CHANGED";
38 constexpr const char* UID = "uid";
39 constexpr const char* SANDBOX_APP_INDEX = "sandbox_app_index";
40 constexpr const char* BUNDLE_TYPE = "bundleType";
41 constexpr const char* ATOMIC_SERVICE_MODULE_UPGRADE = "atomicServiceModuleUpgrade";
42 constexpr const char* BUNDLE_RESOURCE_CHANGE_TYPE = "bundleResourceChangeType";
43 constexpr const char* TYPE = "type";
44 constexpr const char* RESULT_CODE = "resultCode";
45 constexpr const char* PERMISSION_GET_DISPOSED_STATUS = "ohos.permission.GET_DISPOSED_APP_STATUS";
46 }
47 
BundleCommonEventMgr()48 BundleCommonEventMgr::BundleCommonEventMgr()
49 {
50     APP_LOGI("enter BundleCommonEventMgr");
51     Init();
52 }
53 
Init()54 void BundleCommonEventMgr::Init()
55 {
56     commonEventMap_ = {
57         { NotifyType::INSTALL, EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED },
58         { NotifyType::UNINSTALL_BUNDLE, EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED },
59         { NotifyType::UNINSTALL_MODULE, EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED },
60         { NotifyType::UPDATE, EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED },
61         { NotifyType::ABILITY_ENABLE, EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED },
62         { NotifyType::APPLICATION_ENABLE, EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED },
63         { NotifyType::BUNDLE_DATA_CLEARED, EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_DATA_CLEARED },
64         { NotifyType::BUNDLE_CACHE_CLEARED, EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CACHE_CLEARED },
65         { NotifyType::OVERLAY_INSTALL, OVERLAY_ADD_ACTION},
66         { NotifyType::OVERLAY_UPDATE, OVERLAY_CHANGED_ACTION},
67         { NotifyType::DISPOSED_RULE_ADDED, DISPOSED_RULE_ADDED},
68         { NotifyType::DISPOSED_RULE_DELETED, DISPOSED_RULE_DELETED},
69         { NotifyType::START_INSTALL, EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_INSTALLATION_STARTED },
70     };
71 }
72 
NotifyBundleStatus(const NotifyBundleEvents & installResult,const std::shared_ptr<BundleDataMgr> & dataMgr)73 void BundleCommonEventMgr::NotifyBundleStatus(const NotifyBundleEvents &installResult,
74     const std::shared_ptr<BundleDataMgr> &dataMgr)
75 {
76     APP_LOGD("notify type %{public}d with %{public}d for %{public}s-%{public}s in %{public}s",
77         static_cast<int32_t>(installResult.type), installResult.resultCode, installResult.modulePackage.c_str(),
78         installResult.abilityName.c_str(), installResult.bundleName.c_str());
79     OHOS::AAFwk::Want want;
80     SetNotifyWant(want, installResult);
81     EventFwk::CommonEventData commonData { want };
82     // trigger BundleEventCallback first
83     if (dataMgr != nullptr && !(want.GetAction() == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED &&
84         installResult.resultCode != ERR_OK)) {
85         LOG_I(BMS_TAG_DEFAULT, "eventBack begin");
86         dataMgr->NotifyBundleEventCallback(commonData);
87         LOG_I(BMS_TAG_DEFAULT, "eventBack end");
88     }
89 
90     uint8_t installType = ((installResult.type == NotifyType::UNINSTALL_BUNDLE) ||
91             (installResult.type == NotifyType::UNINSTALL_MODULE)) ?
92             static_cast<uint8_t>(InstallType::UNINSTALL_CALLBACK) :
93             static_cast<uint8_t>(InstallType::INSTALL_CALLBACK);
94     int32_t bundleUserId = BundleUtil::GetUserIdByUid(installResult.uid);
95     int32_t publishUserId = (bundleUserId == Constants::DEFAULT_USERID) ?
96         AccountHelper::GetCurrentActiveUserId() : bundleUserId;
97 
98     // trigger the status callback for status listening
99     if ((dataMgr != nullptr) && (installResult.type != NotifyType::START_INSTALL)) {
100         auto &callbackMutex = dataMgr->GetStatusCallbackMutex();
101         std::shared_lock<std::shared_mutex> lock(callbackMutex);
102         auto callbackList = dataMgr->GetCallBackList();
103         for (const auto& callback : callbackList) {
104             int32_t callbackUserId = callback->GetUserId();
105             if (callbackUserId != Constants::UNSPECIFIED_USERID && callbackUserId != publishUserId) {
106                 LOG_W(BMS_TAG_DEFAULT, "not callback userId %{public}d incorrect", callbackUserId);
107                 continue;
108             }
109             if (callback->GetBundleName() == installResult.bundleName) {
110                 // if the msg needed, it could convert in the proxy node
111                 callback->OnBundleStateChanged(installType, installResult.resultCode, Constants::EMPTY_STRING,
112                     installResult.bundleName);
113             }
114         }
115     }
116 
117     if (installResult.resultCode != ERR_OK || installResult.isBmsExtensionUninstalled) {
118         APP_LOGI("install ret: %{public}d, extension: %{public}d",
119             installResult.resultCode, installResult.isBmsExtensionUninstalled);
120         return;
121     }
122 
123     std::string identity = IPCSkeleton::ResetCallingIdentity();
124     if (!EventFwk::CommonEventManager::PublishCommonEventAsUser(commonData, publishUserId)) {
125         APP_LOGE("PublishCommonEventAsUser failed");
126     }
127     IPCSkeleton::SetCallingIdentity(identity);
128 }
129 
SetNotifyWant(OHOS::AAFwk::Want & want,const NotifyBundleEvents & installResult)130 void BundleCommonEventMgr::SetNotifyWant(OHOS::AAFwk::Want& want, const NotifyBundleEvents &installResult)
131 {
132     std::string eventData = GetCommonEventData(installResult.type);
133     APP_LOGD("will send event data %{public}s", eventData.c_str());
134     want.SetAction(eventData);
135     ElementName element;
136     element.SetBundleName(installResult.bundleName);
137     element.SetModuleName(installResult.modulePackage);
138     element.SetAbilityName(installResult.abilityName);
139     want.SetElement(element);
140     want.SetParam(UID, installResult.uid);
141     want.SetParam(Constants::USER_ID, BundleUtil::GetUserIdByUid(installResult.uid));
142     want.SetParam(Constants::ABILITY_NAME, installResult.abilityName);
143     want.SetParam(ACCESS_TOKEN_ID, static_cast<int32_t>(installResult.accessTokenId));
144     want.SetParam(IS_AGING_UNINSTALL, installResult.isAgingUninstall);
145     want.SetParam(APP_ID, installResult.appId);
146     want.SetParam(IS_MODULE_UPDATE, installResult.isModuleUpdate);
147     want.SetParam(APP_IDENTIFIER, installResult.appIdentifier);
148     want.SetParam(APP_DISTRIBUTION_TYPE, installResult.appDistributionType);
149     want.SetParam(APP_INDEX, installResult.appIndex);
150     want.SetParam(BUNDLE_TYPE, installResult.bundleType);
151     want.SetParam(ATOMIC_SERVICE_MODULE_UPGRADE, installResult.atomicServiceModuleUpgrade);
152     want.SetParam(TYPE, static_cast<int32_t>(installResult.type));
153     want.SetParam(RESULT_CODE, installResult.resultCode);
154 }
155 
NotifySandboxAppStatus(const InnerBundleInfo & info,int32_t uid,int32_t userId,const SandboxInstallType & type)156 ErrCode BundleCommonEventMgr::NotifySandboxAppStatus(const InnerBundleInfo &info, int32_t uid, int32_t userId,
157     const SandboxInstallType &type)
158 {
159     OHOS::AAFwk::Want want;
160     if (type == SandboxInstallType::INSTALL) {
161         want.SetAction(COMMON_EVENT_SANDBOX_PACKAGE_ADDED);
162     } else if (type == SandboxInstallType::UNINSTALL) {
163         want.SetAction(COMMON_EVENT_SANDBOX_PACKAGE_REMOVED);
164     } else {
165         return ERR_APPEXECFWK_SANDBOX_INSTALL_UNKNOWN_INSTALL_TYPE;
166     }
167     ElementName element;
168     element.SetBundleName(info.GetBundleName());
169     element.SetAbilityName(info.GetMainAbility());
170     want.SetElement(element);
171     want.SetParam(UID, uid);
172     want.SetParam(Constants::USER_ID, userId);
173     want.SetParam(Constants::ABILITY_NAME, info.GetMainAbility());
174     want.SetParam(SANDBOX_APP_INDEX, info.GetAppIndex());
175     want.SetParam(ACCESS_TOKEN_ID, static_cast<int32_t>(info.GetAccessTokenId(userId)));
176     want.SetParam(APP_ID, info.GetAppId());
177     EventFwk::CommonEventData commonData { want };
178     EventFwk::CommonEventPublishInfo publishInfo;
179     std::vector<std::string> permissionVec { Constants::LISTEN_BUNDLE_CHANGE };
180     publishInfo.SetSubscriberPermissions(permissionVec);
181     std::string identity = IPCSkeleton::ResetCallingIdentity();
182     if (!EventFwk::CommonEventManager::PublishCommonEvent(commonData, publishInfo)) {
183         APP_LOGE("PublishCommonEvent failed");
184     }
185     IPCSkeleton::SetCallingIdentity(identity);
186     return ERR_OK;
187 }
188 
NotifyOverlayModuleStateStatus(const std::string & bundleName,const std::string & moduleName,bool isEnabled,int32_t userId,int32_t uid)189 void BundleCommonEventMgr::NotifyOverlayModuleStateStatus(const std::string &bundleName,
190     const std::string &moduleName, bool isEnabled, int32_t userId, int32_t uid)
191 {
192     OHOS::AAFwk::Want want;
193     want.SetAction(OVERLAY_STATE_CHANGED);
194     ElementName element;
195     element.SetBundleName(bundleName);
196     element.SetModuleName(moduleName);
197     want.SetElement(element);
198     want.SetParam(UID, uid);
199     want.SetParam(Constants::USER_ID, userId);
200     want.SetParam(Constants::OVERLAY_STATE, isEnabled);
201     EventFwk::CommonEventData commonData { want };
202     EventFwk::CommonEventPublishInfo publishInfo;
203     std::vector<std::string> permissionVec { Constants::LISTEN_BUNDLE_CHANGE };
204     publishInfo.SetSubscriberPermissions(permissionVec);
205     std::string identity = IPCSkeleton::ResetCallingIdentity();
206     if (!EventFwk::CommonEventManager::PublishCommonEvent(commonData, publishInfo)) {
207         APP_LOGE("PublishCommonEvent failed");
208     }
209     IPCSkeleton::SetCallingIdentity(identity);
210 }
211 
GetCommonEventData(const NotifyType & type)212 std::string BundleCommonEventMgr::GetCommonEventData(const NotifyType &type)
213 {
214     auto iter = commonEventMap_.find(type);
215     if (iter == commonEventMap_.end()) {
216         APP_LOGW("event type error");
217         return EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED;
218     }
219     return iter->second;
220 }
221 
NotifySetDiposedRule(const std::string & appId,int32_t userId,const std::string & data,int32_t appIndex)222 void BundleCommonEventMgr::NotifySetDiposedRule(
223     const std::string &appId, int32_t userId, const std::string &data, int32_t appIndex)
224 {
225     OHOS::AAFwk::Want want;
226     want.SetAction(DISPOSED_RULE_ADDED);
227     want.SetParam(Constants::USER_ID, userId);
228     want.SetParam(APP_ID, appId);
229     want.SetParam(APP_INDEX, appIndex);
230     EventFwk::CommonEventData commonData { want };
231     commonData.SetData(data);
232     EventFwk::CommonEventPublishInfo publishInfo;
233     std::vector<std::string> permissionVec { PERMISSION_GET_DISPOSED_STATUS };
234     publishInfo.SetSubscriberPermissions(permissionVec);
235     std::string identity = IPCSkeleton::ResetCallingIdentity();
236     if (!EventFwk::CommonEventManager::PublishCommonEvent(commonData, publishInfo)) {
237         APP_LOGE("PublishCommonEvent failed");
238     }
239     IPCSkeleton::SetCallingIdentity(identity);
240 }
241 
NotifyDeleteDiposedRule(const std::string & appId,int32_t userId,int32_t appIndex)242 void BundleCommonEventMgr::NotifyDeleteDiposedRule(const std::string &appId, int32_t userId, int32_t appIndex)
243 {
244     OHOS::AAFwk::Want want;
245     want.SetAction(DISPOSED_RULE_DELETED);
246     want.SetParam(Constants::USER_ID, userId);
247     want.SetParam(APP_ID, appId);
248     want.SetParam(APP_INDEX, appIndex);
249     EventFwk::CommonEventData commonData { want };
250     EventFwk::CommonEventPublishInfo publishInfo;
251     std::vector<std::string> permissionVec { PERMISSION_GET_DISPOSED_STATUS };
252     publishInfo.SetSubscriberPermissions(permissionVec);
253     std::string identity = IPCSkeleton::ResetCallingIdentity();
254     if (!EventFwk::CommonEventManager::PublishCommonEvent(commonData, publishInfo)) {
255         APP_LOGE("PublishCommonEvent failed");
256     }
257     IPCSkeleton::SetCallingIdentity(identity);
258 }
259 
NotifyDynamicIconEvent(const std::string & bundleName,bool isEnableDynamicIcon)260 void BundleCommonEventMgr::NotifyDynamicIconEvent(
261     const std::string &bundleName, bool isEnableDynamicIcon)
262 {
263     APP_LOGI("NotifyDynamicIconEvent bundleName: %{public}s, %{public}d",
264         bundleName.c_str(), isEnableDynamicIcon);
265     OHOS::AAFwk::Want want;
266     want.SetAction(DYNAMIC_ICON_CHANGED);
267     ElementName element;
268     element.SetBundleName(bundleName);
269     want.SetElement(element);
270     want.SetParam(IS_ENABLE_DYNAMIC_ICON, isEnableDynamicIcon);
271     EventFwk::CommonEventData commonData { want };
272     EventFwk::CommonEventPublishInfo publishInfo;
273     std::string identity = IPCSkeleton::ResetCallingIdentity();
274     if (!EventFwk::CommonEventManager::PublishCommonEvent(commonData, publishInfo)) {
275         APP_LOGE("PublishCommonEvent failed");
276     }
277     IPCSkeleton::SetCallingIdentity(identity);
278 }
279 
NotifyBundleResourcesChanged(const int32_t userId,const uint32_t type)280 void BundleCommonEventMgr::NotifyBundleResourcesChanged(const int32_t userId, const uint32_t type)
281 {
282     OHOS::AAFwk::Want want;
283     want.SetAction(BUNDLE_RESOURCES_CHANGED);
284     want.SetParam(Constants::USER_ID, userId);
285     want.SetParam(BUNDLE_RESOURCE_CHANGE_TYPE, static_cast<int32_t>(type));
286     EventFwk::CommonEventData commonData { want };
287     EventFwk::CommonEventPublishInfo publishInfo;
288     std::vector<std::string> permissionVec { ServiceConstants::PERMISSION_GET_BUNDLE_RESOURCES };
289     publishInfo.SetSubscriberPermissions(permissionVec);
290     std::string identity = IPCSkeleton::ResetCallingIdentity();
291     if (!EventFwk::CommonEventManager::PublishCommonEvent(commonData, publishInfo)) {
292         APP_LOGE("PublishCommonEvent failed");
293     }
294     IPCSkeleton::SetCallingIdentity(identity);
295 }
296 } // AppExecFwk
297 } // OHOS