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