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