• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "event_statistic.h"
17 #include "util_ex.h"
18 
19 #undef MMI_LOG_DOMAIN
20 #define MMI_LOG_DOMAIN MMI_LOG_HANDLER
21 #undef MMI_LOG_TAG
22 #define MMI_LOG_TAG "EventStatistic"
23 
24 namespace OHOS {
25 namespace MMI {
26 namespace {
27 const char* EVENT_FILE_NAME = "/data/service/el1/public/multimodalinput/multimodal_event.dmp";
28 const char* EVENT_FILE_NAME_HISTORY = "/data/service/el1/public/multimodalinput/multimodal_event_history.dmp";
29 constexpr int32_t FILE_MAX_SIZE = 100 * 1024 * 1024;
30 constexpr int32_t EVENT_OUT_SIZE = 30;
31 constexpr int32_t FUNC_EXE_OK = 0;
32 constexpr int32_t STRING_WIDTH = 3;
33 }
34 
35 std::queue<std::string> EventStatistic::eventQueue_;
36 std::list<std::string> EventStatistic::dumperEventList_;
37 std::mutex EventStatistic::queueMutex_;
38 std::condition_variable EventStatistic::queueCondition_;
39 bool EventStatistic::writeFileEnabled_ = false;
40 
ConvertEventToStr(const std::shared_ptr<InputEvent> eventPtr)41 std::string EventStatistic::ConvertEventToStr(const std::shared_ptr<InputEvent> eventPtr)
42 {
43     auto nowTime = std::chrono::system_clock::now();
44     std::time_t timeT = std::chrono::system_clock::to_time_t(nowTime);
45     auto milsecsCount = std::chrono::duration_cast<std::chrono::milliseconds>(nowTime.time_since_epoch()).count();
46     std::string handleTime = ConvertTimeToStr(static_cast<int64_t>(timeT));
47     int32_t milsec = milsecsCount % 1000;
48     std::stringstream strStream;
49     strStream << std::left << std::setw(STRING_WIDTH) << milsec;
50     std::string milsecStr(strStream.str());
51     handleTime += "." + milsecStr;
52     std::string eventStr = "{" + handleTime + "," + eventPtr->ToString() + "}";
53     return eventStr;
54 }
55 
ConvertTimeToStr(int64_t timestamp)56 std::string EventStatistic::ConvertTimeToStr(int64_t timestamp)
57 {
58     std::string timeStr = std::to_string(timestamp);
59     std::time_t timeT = timestamp;
60     std::tm tmInfo;
61     localtime_r(&timeT, &tmInfo);
62     char buffer[32] = {0};
63     if (std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tmInfo) > 0) {
64         timeStr = buffer;
65     }
66     return timeStr;
67 }
68 
PushPointerEvent(std::shared_ptr<PointerEvent> eventPtr)69 void EventStatistic::PushPointerEvent(std::shared_ptr<PointerEvent> eventPtr)
70 {
71     CHKPV(eventPtr);
72     int32_t pointerAction = eventPtr->GetPointerAction();
73     if (pointerAction == PointerEvent::POINTER_ACTION_MOVE ||
74         eventPtr->HasFlag(InputEvent::EVENT_FLAG_PRIVACY_MODE)) {
75         MMI_HILOGD("PointEvent is filtered");
76         return;
77     }
78     PushEvent(eventPtr);
79 }
80 
PushEvent(std::shared_ptr<InputEvent> eventPtr)81 void EventStatistic::PushEvent(std::shared_ptr<InputEvent> eventPtr)
82 {
83     std::lock_guard<std::mutex> lock(queueMutex_);
84     CHKPV(eventPtr);
85     std::string eventStr = ConvertEventToStr(eventPtr);
86     dumperEventList_.push_back(eventStr);
87     if (dumperEventList_.size() > EVENT_OUT_SIZE) {
88         dumperEventList_.pop_front();
89     }
90     if (writeFileEnabled_) {
91         eventQueue_.push(eventStr);
92         queueCondition_.notify_all();
93     }
94 }
95 
PopEvent()96 std::string EventStatistic::PopEvent()
97 {
98     std::unique_lock<std::mutex> lock(queueMutex_);
99     if (eventQueue_.empty()) {
100         queueCondition_.wait(lock, []() { return !eventQueue_.empty(); });
101     }
102     std::string eventStr = eventQueue_.front();
103     eventQueue_.pop();
104     return eventStr;
105 }
106 
WriteEventFile()107 void EventStatistic::WriteEventFile()
108 {
109     while (writeFileEnabled_) {
110         std::string eventStr = PopEvent();
111         struct stat statbuf;
112         int32_t fileSize = 0;
113         if (stat(EVENT_FILE_NAME, &statbuf) == FUNC_EXE_OK) {
114             fileSize = static_cast<int32_t>(statbuf.st_size);
115         }
116         if (fileSize >= FILE_MAX_SIZE) {
117             if (access(EVENT_FILE_NAME_HISTORY, F_OK) == FUNC_EXE_OK &&
118                 remove(EVENT_FILE_NAME_HISTORY) != FUNC_EXE_OK) {
119                 MMI_HILOGE("Remove history file failed");
120             }
121             if (rename(EVENT_FILE_NAME, EVENT_FILE_NAME_HISTORY) != FUNC_EXE_OK) {
122                 MMI_HILOGE("Rename file failed");
123             }
124         }
125         std::ofstream file(EVENT_FILE_NAME, std::ios::app);
126         if (file.is_open()) {
127             file << eventStr << std::endl;
128             file.close();
129         } else {
130             MMI_HILOGE("Open file failed");
131         }
132     }
133 }
134 
Dump(int32_t fd,const std::vector<std::string> & args)135 void EventStatistic::Dump(int32_t fd, const std::vector<std::string> &args)
136 {
137     std::lock_guard<std::mutex> lock(queueMutex_);
138     for (auto it = dumperEventList_.begin(); it != dumperEventList_.end(); ++it) {
139         mprintf(fd, (*it).c_str());
140     }
141 }
142 } // namespace MMI
143 } // namespace OHOS