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
Init(const std::shared_ptr<BundleActiveCore> & bundleActiveCore)30 void BundleActiveReportHandler::Init(const std::shared_ptr<BundleActiveCore>& bundleActiveCore)
31 {
32 bundleActiveCore_ = bundleActiveCore;
33 ffrtQueue_ = std::make_shared<ffrt::queue>(DEVICE_USAGE_REPORT_HANDLE_QUEUE.c_str(),
34 ffrt::queue_attr().qos(ffrt::qos_default));
35 if (ffrtQueue_ == nullptr) {
36 BUNDLE_ACTIVE_LOGE("BundleActiveReportHandler, ffrtQueue create failed");
37 return;
38 }
39 isInited_ = true;
40 }
41
SendEvent(const int32_t & eventId,const std::shared_ptr<BundleActiveReportHandlerObject> & handlerobj,const int64_t & delayTime)42 void BundleActiveReportHandler::SendEvent(const int32_t& eventId,
43 const std::shared_ptr<BundleActiveReportHandlerObject>& handlerobj, const int64_t& delayTime)
44 {
45 if (!isInited_) {
46 BUNDLE_ACTIVE_LOGE("init failed");
47 return;
48 }
49 auto reportHandler = shared_from_this();
50 int64_t ffrtDelayTime = BundleActiveUtil::GetFFRTDelayTime(delayTime);
51 std::lock_guard<ffrt::mutex> lock(taskHandlerMutex_);
52 if (taskHandlerMap_.find(eventId) == taskHandlerMap_.end()) {
53 taskHandlerMap_[eventId] = std::queue<ffrt::task_handle>();
54 }
55 ffrt::task_handle taskHandle = ffrtQueue_->submit_h([reportHandler, eventId, handlerobj]() {
56 reportHandler->ProcessEvent(eventId, handlerobj);
57 std::lock_guard<ffrt::mutex> lock(reportHandler->taskHandlerMutex_);
58 if (reportHandler->taskHandlerMap_.find(eventId) == reportHandler->taskHandlerMap_.end()) {
59 return;
60 }
61 if (!reportHandler->taskHandlerMap_[eventId].empty()) {
62 reportHandler->taskHandlerMap_[eventId].pop();
63 }
64 }, ffrt::task_attr().delay(ffrtDelayTime));
65 taskHandlerMap_[eventId].push(std::move(taskHandle));
66 }
67
RemoveEvent(const int32_t & eventId)68 void BundleActiveReportHandler::RemoveEvent(const int32_t& eventId)
69 {
70 if (!isInited_) {
71 BUNDLE_ACTIVE_LOGE("init failed");
72 return;
73 }
74 std::lock_guard<ffrt::mutex> lock(taskHandlerMutex_);
75 if (taskHandlerMap_.find(eventId) == taskHandlerMap_.end()) {
76 return;
77 }
78 while (!taskHandlerMap_[eventId].empty()) {
79 ffrtQueue_->cancel(taskHandlerMap_[eventId].front());
80 taskHandlerMap_[eventId].pop();
81 }
82 taskHandlerMap_.erase(eventId);
83 }
84
HasEvent(const int32_t & eventId)85 bool BundleActiveReportHandler::HasEvent(const int32_t& eventId)
86 {
87 if (!isInited_) {
88 BUNDLE_ACTIVE_LOGE("init failed");
89 return false;
90 }
91 std::lock_guard<ffrt::mutex> lock(taskHandlerMutex_);
92 if (taskHandlerMap_.find(eventId) != taskHandlerMap_.end()) {
93 return true;
94 }
95 return false;
96 }
97
ProcessEvent(const int32_t & eventId,const std::shared_ptr<BundleActiveReportHandlerObject> & handlerobj)98 void BundleActiveReportHandler::ProcessEvent(const int32_t& eventId,
99 const std::shared_ptr<BundleActiveReportHandlerObject>& handlerobj)
100 {
101 if (handlerobj == nullptr) {
102 BUNDLE_ACTIVE_LOGE("handlerobj is null, exit ProcessEvent");
103 return;
104 }
105 BundleActiveReportHandlerObject tmpHandlerobj = *handlerobj;
106 switch (eventId) {
107 case MSG_REPORT_EVENT: {
108 BUNDLE_ACTIVE_LOGD("MSG_REPORT_EVENT CALLED");
109 bundleActiveCore_->ReportEvent(tmpHandlerobj.event_, tmpHandlerobj.userId_);
110 break;
111 }
112 case MSG_FLUSH_TO_DISK: {
113 BUNDLE_ACTIVE_LOGI("FLUSH TO DISK HANDLE");
114 if (tmpHandlerobj.userId_ != bundleActiveCore_->currentUsedUser_) {
115 BUNDLE_ACTIVE_LOGE("flush user is %{public}d, not last user %{public}d, return",
116 tmpHandlerobj.userId_, bundleActiveCore_->currentUsedUser_);
117 RemoveEvent(BundleActiveReportHandler::MSG_FLUSH_TO_DISK);
118 return;
119 }
120 bundleActiveCore_->RestoreToDatabase(tmpHandlerobj.userId_);
121 break;
122 }
123 case MSG_REMOVE_USER: {
124 bundleActiveCore_->OnUserRemoved(tmpHandlerobj.userId_);
125 break;
126 }
127 case MSG_BUNDLE_UNINSTALLED: {
128 BUNDLE_ACTIVE_LOGI("MSG_BUNDLE_UNINSTALLED CALLED");
129 bundleActiveCore_->OnBundleUninstalled(tmpHandlerobj.userId_, tmpHandlerobj.bundleName_,
130 tmpHandlerobj.uid_, tmpHandlerobj.appIndex_);
131 break;
132 }
133 case MSG_SWITCH_USER: {
134 BUNDLE_ACTIVE_LOGI("MSG_SWITCH_USER CALLED");
135 bundleActiveCore_->OnUserSwitched(tmpHandlerobj.userId_);
136 break;
137 }
138 default: {
139 break;
140 }
141 }
142 }
143 } // namespace DeviceUsageStats
144 } // namespace OHOS
145
146