1 /*
2 * Copyright (c) 2025 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 "insight_intent_sys_event_receiver.h"
17
18 #include "extract_insight_intent_profile.h"
19 #include "common_event_support.h"
20 #include "hilog_tag_wrapper.h"
21 #include "task_handler_wrap.h"
22 #include "os_account_manager_wrapper.h"
23 #include "in_process_call_wrapper.h"
24 #include "ability_util.h"
25 #include "bundle_mgr_helper.h"
26 #include "insight_intent_db_cache.h"
27 #include "ffrt.h"
28
29 namespace OHOS {
30 namespace AbilityRuntime {
31 constexpr const char* INSIGHT_INTENT_SYS_EVENT_RECERVER = "InsightIntentSysEventReceiver";
32 const int32_t MAIN_USER_ID = 100;
33
InsightIntentSysEventReceiver(const EventFwk::CommonEventSubscribeInfo & subscribeInfo)34 InsightIntentSysEventReceiver::InsightIntentSysEventReceiver(const EventFwk::CommonEventSubscribeInfo &subscribeInfo)
35 : EventFwk::CommonEventSubscriber(subscribeInfo)
36 {
37 }
38
SaveInsightIntentInfos(const std::string & bundleName,const std::string & moduleName,int32_t userId)39 void InsightIntentSysEventReceiver::SaveInsightIntentInfos(const std::string &bundleName, const std::string &moduleName,
40 int32_t userId)
41 {
42 std::vector<std::string> moduleNameVec;
43 std::string profile;
44 AbilityRuntime::ExtractInsightIntentProfileInfoVec infos = {};
45 TAG_LOGI(AAFwkTag::INTENT, "save insight intent infos, bundle:%{public}s module:%{public}s",
46 bundleName.c_str(), moduleName.c_str());
47 ErrCode ret;
48 auto bundleMgrHelper = DelayedSingleton<AppExecFwk::BundleMgrHelper>::GetInstance();
49 if (bundleMgrHelper == nullptr) {
50 TAG_LOGE(AAFwkTag::INTENT, "null bundleMgrHelper");
51 return;
52 }
53
54 OHOS::SplitStr(moduleName, ",", moduleNameVec);
55 for (std::string moduleNameLocal : moduleNameVec) {
56 // Get json profile firstly
57 ret = IN_PROCESS_CALL(bundleMgrHelper->GetJsonProfile(AppExecFwk::INTENT_PROFILE, bundleName,
58 moduleNameLocal, profile, userId));
59 if (ret != ERR_OK) {
60 TAG_LOGE(AAFwkTag::INTENT, "GetJsonProfile failed, code: %{public}d", ret);
61 continue;
62 }
63
64 // Transform json string
65 if (!AbilityRuntime::ExtractInsightIntentProfile::TransformTo(profile, infos) ||
66 infos.insightIntents.size() == 0) {
67 TAG_LOGE(AAFwkTag::INTENT, "transform profile failed, profile:%{public}s", profile.c_str());
68 continue;
69 }
70
71 // save database
72 ret = DelayedSingleton<AbilityRuntime::InsightIntentDbCache>::GetInstance()->SaveInsightIntentTotalInfo(
73 bundleName, moduleNameLocal, userId, infos);
74 if (ret != ERR_OK) {
75 TAG_LOGE(AAFwkTag::INTENT, "save intent info failed, bundleName: %{public}s, moduleName: %{public}s, "
76 "userId: %{public}d", bundleName.c_str(), moduleNameLocal.c_str(), userId);
77 continue;
78 }
79
80 TAG_LOGI(AAFwkTag::INTENT, "save intent info success, bundleName: %{public}s, moduleName: %{public}s, "
81 "userId: %{public}d", bundleName.c_str(), moduleNameLocal.c_str(), userId);
82 }
83 }
84
LoadInsightIntentInfos(int32_t userId)85 void InsightIntentSysEventReceiver::LoadInsightIntentInfos(int32_t userId)
86 {
87 std::lock_guard<std::mutex> lock(userIdMutex_);
88 if (userId == -1) {
89 userId = AppExecFwk::OsAccountManagerWrapper::GetCurrentActiveAccountId();
90 if (userId == 0) {
91 TAG_LOGI(AAFwkTag::INTENT, "use MAIN_USER_ID(%{public}d) instead of current userId: (%{public}d)",
92 MAIN_USER_ID, userId);
93 userId = MAIN_USER_ID;
94 }
95 }
96
97 TAG_LOGI(AAFwkTag::INTENT, "init insight intent cache start, userId: %{public}d", userId);
98 DelayedSingleton<AbilityRuntime::InsightIntentDbCache>::GetInstance()->InitInsightIntentCache(userId);
99 TAG_LOGI(AAFwkTag::INTENT, "init insight intent cache end, userId: %{public}d", userId);
100
101 auto bundleMgrHelper = DelayedSingleton<AppExecFwk::BundleMgrHelper>::GetInstance();
102 if (bundleMgrHelper == nullptr) {
103 TAG_LOGE(AAFwkTag::INTENT, "null bundleMgrHelper");
104 return;
105 }
106
107 std::vector<AppExecFwk::BundleInfo> bundleInfos {};
108 if (!IN_PROCESS_CALL(bundleMgrHelper->GetBundleInfos(AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES, bundleInfos,
109 userId))) {
110 TAG_LOGE(AAFwkTag::INTENT, "get bundle info failed");
111 return;
112 }
113
114 TAG_LOGI(AAFwkTag::INTENT, "bundleInfos size: %{public}zu", bundleInfos.size());
115 for (auto &bundleInfo : bundleInfos) {
116 for (const auto &hapInfo : bundleInfo.hapModuleInfos) {
117 if (!hapInfo.hasIntent) {
118 continue;
119 }
120 SaveInsightIntentInfos(bundleInfo.name, hapInfo.moduleName, userId);
121 }
122 }
123 }
124
DeleteInsightIntentInfoByUserId(int32_t userId)125 void InsightIntentSysEventReceiver::DeleteInsightIntentInfoByUserId(int32_t userId)
126 {
127 int32_t ret = DelayedSingleton<AbilityRuntime::InsightIntentDbCache>::GetInstance()->DeleteInsightIntentByUserId(
128 userId);
129 if (ret != ERR_OK) {
130 TAG_LOGE(AAFwkTag::INTENT, "delete insight intent by userId failed, userId: %{public}d, ret: %{public}d",
131 userId, ret);
132 return;
133 }
134 }
135
HandleBundleScanFinished()136 void InsightIntentSysEventReceiver::HandleBundleScanFinished()
137 {
138 auto task = [self = shared_from_this()]() { self->LoadInsightIntentInfos(); };
139 ffrt::submit(task);
140 }
141
HandleUserSwitched(const EventFwk::CommonEventData & data)142 void InsightIntentSysEventReceiver::HandleUserSwitched(const EventFwk::CommonEventData &data)
143 {
144 int32_t userId = data.GetCode();
145 if (userId < 0) {
146 TAG_LOGE(AAFwkTag::INTENT, "invalid switched userId: %{public}d", userId);
147 }
148
149 std::lock_guard<std::mutex> lock(userIdMutex_);
150 if (userId == lastUserId_) {
151 TAG_LOGE(AAFwkTag::INTENT, "same userId: %{public}d", lastUserId_);
152 return;
153 }
154
155 TAG_LOGI(AAFwkTag::INTENT, "userId: %{public}d switch to current userId: %{public}d", lastUserId_, userId);
156 lastUserId_ = userId;
157
158 auto task = [self = shared_from_this(), userId]() { self->LoadInsightIntentInfos(userId); };
159 ffrt::submit(task);
160 }
161
HandleUserRemove(const EventFwk::CommonEventData & data)162 void InsightIntentSysEventReceiver::HandleUserRemove(const EventFwk::CommonEventData &data)
163 {
164 int32_t userId = data.GetCode();
165 if (userId < 0) {
166 TAG_LOGE(AAFwkTag::INTENT, "invalid switched userId: %{public}d", userId);
167 }
168
169 std::lock_guard<std::mutex> lock(userIdMutex_);
170 if (userId == lastUserId_) {
171 TAG_LOGW(AAFwkTag::INTENT, "not allow remove current userId: %{public}d", userId);
172 return;
173 }
174
175 auto task = [self = shared_from_this(), userId]() { self->DeleteInsightIntentInfoByUserId(userId); };
176 ffrt::submit(task);
177 }
178
OnReceiveEvent(const EventFwk::CommonEventData & data)179 void InsightIntentSysEventReceiver::OnReceiveEvent(const EventFwk::CommonEventData &data)
180 {
181 const AAFwk::Want &want = data.GetWant();
182 std::string action = want.GetAction();
183 TAG_LOGI(AAFwkTag::INTENT, "the action: %{public}s", action.c_str());
184
185 if (action == EventFwk::CommonEventSupport::COMMON_EVENT_BUNDLE_SCAN_FINISHED) {
186 HandleBundleScanFinished();
187 } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED) {
188 HandleUserSwitched(data);
189 } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_USER_REMOVED) {
190 HandleUserRemove(data);
191 } else {
192 TAG_LOGW(AAFwkTag::INTENT, "invalid action");
193 }
194 }
195 } // namespace AbilityRuntime
196 } // namespace OHOS