1 /*
2 * Copyright (c) 2022-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 "bundle_active_log.h"
17 #include "bundle_active_report_handler.h"
18 #include "bundle_active_event.h"
19 #include "bundle_active_util.h"
20 #include "bundle_active_report_controller.h"
21
22 namespace OHOS {
23 namespace DeviceUsageStats {
24 const std::string DEVICE_USAGE_REPORT_HANDLE_QUEUE = "DeviceUsageReportHandleQueue";
25 const int32_t BundleActiveReportHandler::MSG_REPORT_EVENT = 0;
26 const int32_t BundleActiveReportHandler::MSG_FLUSH_TO_DISK = 1;
27 const int32_t BundleActiveReportHandler::MSG_REMOVE_USER = 2;
28 const int32_t BundleActiveReportHandler::MSG_BUNDLE_UNINSTALLED = 3;
29 const int32_t BundleActiveReportHandler::MSG_SWITCH_USER = 4;
30 const int32_t BundleActiveReportHandler::MSG_BUNDLE_INSTALLED = 5;
31
Init(const std::shared_ptr<BundleActiveCore> & bundleActiveCore)32 void BundleActiveReportHandler::Init(const std::shared_ptr<BundleActiveCore>& bundleActiveCore)
33 {
34 bundleActiveCore_ = bundleActiveCore;
35 ffrtQueue_ = std::make_shared<ffrt::queue>(DEVICE_USAGE_REPORT_HANDLE_QUEUE.c_str(),
36 ffrt::queue_attr().qos(ffrt::qos_default));
37 if (ffrtQueue_ == nullptr) {
38 BUNDLE_ACTIVE_LOGE("BundleActiveReportHandler, ffrtQueue create failed");
39 return;
40 }
41 isInited_ = true;
42 }
43
DeInit()44 void BundleActiveReportHandler::DeInit()
45 {
46 isInited_ = false;
47 for (auto& iter : taskHandlerMap_) {
48 auto& queue = iter.second;
49 while (!queue.empty()) {
50 ffrtQueue_->cancel(queue.front());
51 queue.pop();
52 }
53 }
54 taskHandlerMap_.clear();
55 }
56
SendEvent(const int32_t & eventId,const std::shared_ptr<BundleActiveReportHandlerObject> & handlerobj,const int64_t & delayTime)57 void BundleActiveReportHandler::SendEvent(const int32_t& eventId,
58 const std::shared_ptr<BundleActiveReportHandlerObject>& handlerobj, const int64_t& delayTime)
59 {
60 if (!isInited_) {
61 BUNDLE_ACTIVE_LOGE("init failed");
62 return;
63 }
64 int64_t ffrtDelayTime = BundleActiveUtil::GetFFRTDelayTime(delayTime);
65 std::lock_guard<ffrt::mutex> lock(taskHandlerMutex_);
66 if (taskHandlerMap_.find(eventId) == taskHandlerMap_.end()) {
67 taskHandlerMap_[eventId] = std::queue<ffrt::task_handle>();
68 }
69 ffrt::task_handle taskHandle = ffrtQueue_->submit_h([eventId, handlerobj]() {
70 auto reportHandler = BundleActiveReportController::GetInstance().GetBundleReportHandler();
71 if (reportHandler == nullptr) {
72 return;
73 }
74 if (!reportHandler->isInited_) {
75 BUNDLE_ACTIVE_LOGE("init failed");
76 return;
77 }
78 reportHandler->ProcessEvent(eventId, handlerobj);
79 std::lock_guard<ffrt::mutex> lock(reportHandler->taskHandlerMutex_);
80 if (reportHandler->taskHandlerMap_.find(eventId) == reportHandler->taskHandlerMap_.end()) {
81 return;
82 }
83 if (!reportHandler->taskHandlerMap_[eventId].empty()) {
84 reportHandler->taskHandlerMap_[eventId].pop();
85 }
86 }, ffrt::task_attr().delay(ffrtDelayTime));
87 taskHandlerMap_[eventId].push(std::move(taskHandle));
88 }
89
RemoveEvent(const int32_t & eventId)90 void BundleActiveReportHandler::RemoveEvent(const int32_t& eventId)
91 {
92 if (!isInited_) {
93 BUNDLE_ACTIVE_LOGE("init failed");
94 return;
95 }
96 std::lock_guard<ffrt::mutex> lock(taskHandlerMutex_);
97 if (taskHandlerMap_.find(eventId) == taskHandlerMap_.end()) {
98 return;
99 }
100 while (!taskHandlerMap_[eventId].empty()) {
101 ffrtQueue_->cancel(taskHandlerMap_[eventId].front());
102 taskHandlerMap_[eventId].pop();
103 }
104 taskHandlerMap_.erase(eventId);
105 }
106
HasEvent(const int32_t & eventId)107 bool BundleActiveReportHandler::HasEvent(const int32_t& eventId)
108 {
109 if (!isInited_) {
110 BUNDLE_ACTIVE_LOGE("init failed");
111 return false;
112 }
113 std::lock_guard<ffrt::mutex> lock(taskHandlerMutex_);
114 if (taskHandlerMap_.find(eventId) != taskHandlerMap_.end()) {
115 return true;
116 }
117 return false;
118 }
119
ProcessEvent(const int32_t & eventId,const std::shared_ptr<BundleActiveReportHandlerObject> & handlerobj)120 void BundleActiveReportHandler::ProcessEvent(const int32_t& eventId,
121 const std::shared_ptr<BundleActiveReportHandlerObject>& handlerobj)
122 {
123 if (!isInited_) {
124 BUNDLE_ACTIVE_LOGE("init failed");
125 return;
126 }
127 if (handlerobj == nullptr) {
128 BUNDLE_ACTIVE_LOGE("handlerobj is null, exit ProcessEvent");
129 return;
130 }
131 BundleActiveReportHandlerObject tmpHandlerobj = *handlerobj;
132 switch (eventId) {
133 case MSG_REPORT_EVENT: {
134 ProcessReportEvent(tmpHandlerobj);
135 break;
136 }
137 case MSG_FLUSH_TO_DISK: {
138 ProcessFlushToDiskEvent(tmpHandlerobj);
139 break;
140 }
141 case MSG_REMOVE_USER: {
142 ProcessRmoveUserEvent(tmpHandlerobj);
143 break;
144 }
145 case MSG_SWITCH_USER: {
146 ProcessUserSwitchEvent(tmpHandlerobj);
147 break;
148 }
149 case MSG_BUNDLE_UNINSTALLED: {
150 ProcessBundleUninstallEvent(tmpHandlerobj);
151 break;
152 }
153 case MSG_BUNDLE_INSTALLED: {
154 ProcessBundleInstallEvent(tmpHandlerobj);
155 break;
156 }
157 default: {
158 break;
159 }
160 }
161 }
162
ProcessReportEvent(BundleActiveReportHandlerObject & tmpHandlerobj)163 void BundleActiveReportHandler::ProcessReportEvent(BundleActiveReportHandlerObject& tmpHandlerobj)
164 {
165 BUNDLE_ACTIVE_LOGD("MSG_REPORT_EVENT CALLED");
166 if (BundleActiveEvent::IsAppStateEvent(tmpHandlerobj.event_.eventId_) &&
167 bundleActiveCore_->isUninstalledApp(tmpHandlerobj.event_.uid_)) {
168 BUNDLE_ACTIVE_LOGE("not report uninstall app event");
169 return;
170 }
171 bundleActiveCore_->ReportEvent(tmpHandlerobj.event_, tmpHandlerobj.userId_);
172 }
173
ProcessFlushToDiskEvent(const BundleActiveReportHandlerObject & tmpHandlerobj)174 void BundleActiveReportHandler::ProcessFlushToDiskEvent(const BundleActiveReportHandlerObject& tmpHandlerobj)
175 {
176 BUNDLE_ACTIVE_LOGI("FLUSH TO DISK HANDLE");
177 if (tmpHandlerobj.userId_ != bundleActiveCore_->currentUsedUser_) {
178 BUNDLE_ACTIVE_LOGE("flush user is %{public}d, not last user %{public}d, return",
179 tmpHandlerobj.userId_, bundleActiveCore_->currentUsedUser_);
180 RemoveEvent(BundleActiveReportHandler::MSG_FLUSH_TO_DISK);
181 return;
182 }
183 bundleActiveCore_->RestoreToDatabase(tmpHandlerobj.userId_);
184 }
185
ProcessRmoveUserEvent(const BundleActiveReportHandlerObject & tmpHandlerobj)186 void BundleActiveReportHandler::ProcessRmoveUserEvent(const BundleActiveReportHandlerObject& tmpHandlerobj)
187 {
188 BUNDLE_ACTIVE_LOGI("Remove user");
189 bundleActiveCore_->OnUserRemoved(tmpHandlerobj.userId_);
190 }
191
ProcessUserSwitchEvent(const BundleActiveReportHandlerObject & tmpHandlerobj)192 void BundleActiveReportHandler::ProcessUserSwitchEvent(const BundleActiveReportHandlerObject& tmpHandlerobj)
193 {
194 BUNDLE_ACTIVE_LOGI("MSG_SWITCH_USER CALLED");
195 bundleActiveCore_->OnUserSwitched(tmpHandlerobj.userId_);
196 }
197
ProcessBundleUninstallEvent(const BundleActiveReportHandlerObject & tmpHandlerobj)198 void BundleActiveReportHandler::ProcessBundleUninstallEvent(const BundleActiveReportHandlerObject& tmpHandlerobj)
199 {
200 BUNDLE_ACTIVE_LOGI("MSG_BUNDLE_UNINSTALLED CALLED");
201 bundleActiveCore_->OnBundleUninstalled(tmpHandlerobj.userId_, tmpHandlerobj.bundleName_,
202 tmpHandlerobj.uid_, tmpHandlerobj.appIndex_);
203 }
204
ProcessBundleInstallEvent(const BundleActiveReportHandlerObject & tmpHandlerobj)205 void BundleActiveReportHandler::ProcessBundleInstallEvent(const BundleActiveReportHandlerObject& tmpHandlerobj)
206 {
207 BUNDLE_ACTIVE_LOGI("MSG_BUNDLE_INSTALLED CALLED");
208 bundleActiveCore_->OnBundleInstalled(tmpHandlerobj.userId_, tmpHandlerobj.bundleName_,
209 tmpHandlerobj.uid_, tmpHandlerobj.appIndex_);
210 }
211
212 } // namespace DeviceUsageStats
213 } // namespace OHOS
214
215