1 /*
2 * Copyright (c) 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 "ima_hisysevent_reporter.h"
17
18 #include <chrono>
19
20 namespace OHOS {
21 namespace MiscServices {
22 using namespace std::chrono;
23 const std::vector<std::pair<int32_t, int32_t>> ImaHiSysEventReporter::BASE_TEXT_OPERATION_TIME_INTERVAL = { { 0, 4 },
24 { 4, 8 }, { 8, 16 }, { 16, 24 }, { 24, 500 } }; // 0-4ms 4-8ms 8-16ms 16-24ms 24ms+
25 const std::vector<std::pair<int32_t, int32_t>> ImaHiSysEventReporter::IME_CB_TIME_INTERVAL = { { 0, 10 }, { 10, 50 },
26 { 50, 100 }, { 100, 500 }, { 500, 1000 }, { 1000, 2000 } }; // 0-10ms 10-50ms 50-100 100-500 500-500 1000+
GetInstance()27 ImaHiSysEventReporter &ImaHiSysEventReporter::GetInstance()
28 {
29 static ImaHiSysEventReporter instance;
30 return instance;
31 }
32
ImaHiSysEventReporter()33 ImaHiSysEventReporter::ImaHiSysEventReporter()
34 : imeStartInputAllInfo_(ImeStartInputAllInfo(
35 COUNT_STATISTICS_INTERVAL_NUM, COUNT_STATISTICS_INTERVAL_NUM, IME_CB_TIME_INTERVAL.size())),
36 baseTextOperationAllInfo_(
37 BaseTextOperationAllInfo(BASE_TEXT_OPERATION_TIME_INTERVAL.size(), COUNT_STATISTICS_INTERVAL_NUM))
38 {
39 }
40
~ImaHiSysEventReporter()41 ImaHiSysEventReporter::~ImaHiSysEventReporter()
42 {
43 }
44
IsValidErrCode(int32_t errCode)45 bool MiscServices::ImaHiSysEventReporter::IsValidErrCode(int32_t errCode)
46 {
47 return !((ErrorCode::ERROR_IMC_BEGIN < errCode && errCode < ErrorCode::ERROR_IMC_END)
48 || (ErrorCode::ERROR_IMSA_BEGIN < errCode && errCode < ErrorCode::ERROR_IMSA_END));
49 }
50
IsFault(int32_t errCode)51 bool ImaHiSysEventReporter::IsFault(int32_t errCode)
52 {
53 return IsValidErrCode(errCode);
54 }
55
RecordStatisticsEvent(ImfStatisticsEvent event,const HiSysOriginalInfo & info)56 void ImaHiSysEventReporter::RecordStatisticsEvent(ImfStatisticsEvent event, const HiSysOriginalInfo &info)
57 {
58 std::lock_guard<std::mutex> lock(statisticsEventLock_);
59 switch (event) {
60 case ImfStatisticsEvent::IME_START_INPUT_STATISTICS: {
61 RecordImeStartInputStatistics(info);
62 break;
63 }
64 case ImfStatisticsEvent::BASE_TEXT_OPERATION_STATISTICS: {
65 RecordBaseTextOperationStatistics(info);
66 break;
67 }
68 default:
69 break;
70 }
71 }
72
ReportStatisticsEvent()73 void ImaHiSysEventReporter::ReportStatisticsEvent()
74 {
75 ImeStartInputAllInfo imeStartInputInfo(
76 COUNT_STATISTICS_INTERVAL_NUM, COUNT_STATISTICS_INTERVAL_NUM, IME_CB_TIME_INTERVAL.size());
77 BaseTextOperationAllInfo baseTextOperationInfo(
78 BASE_TEXT_OPERATION_TIME_INTERVAL.size(), COUNT_STATISTICS_INTERVAL_NUM);
79 {
80 std::lock_guard<std::mutex> lock(statisticsEventLock_);
81 auto time = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
82 ResetTimerStartTime(time);
83 imeStartInputInfo = imeStartInputAllInfo_;
84 baseTextOperationInfo = baseTextOperationAllInfo_;
85 imeStartInputAllInfo_ = ImeStartInputAllInfo(
86 COUNT_STATISTICS_INTERVAL_NUM, COUNT_STATISTICS_INTERVAL_NUM, IME_CB_TIME_INTERVAL.size());
87 baseTextOperationAllInfo_ =
88 BaseTextOperationAllInfo(BASE_TEXT_OPERATION_TIME_INTERVAL.size(), COUNT_STATISTICS_INTERVAL_NUM);
89 }
90 if (!imeStartInputInfo.appNames.empty()) {
91 std::string imeStartInputStatistics;
92 imeStartInputInfo.Marshall(imeStartInputStatistics);
93 ImfHiSysEventUtil::ReportStatisticsEvent(GET_NAME(IME_START_INPUT_STATISTICS), GetSelfName(),
94 imeStartInputInfo.appNames, { imeStartInputStatistics });
95 }
96 if (!baseTextOperationInfo.appNames.empty()) {
97 std::string baseTextOperationStatistics;
98 baseTextOperationInfo.succeedRateInfo.Marshall(baseTextOperationStatistics);
99 ImfHiSysEventUtil::ReportStatisticsEvent(GET_NAME(BASE_TEXT_OPERATION_STATISTICS), GetSelfName(),
100 baseTextOperationInfo.appNames, { baseTextOperationStatistics });
101 }
102 }
103
RecordImeStartInputStatistics(const HiSysOriginalInfo & info)104 void ImaHiSysEventReporter::RecordImeStartInputStatistics(const HiSysOriginalInfo &info)
105 {
106 std::string appName = "*"; // for security reasons, the package name is not printed at this time
107 auto appIndex = ImfHiSysEventUtil::AddIfAbsent(appName, imeStartInputAllInfo_.appNames);
108 ModImeCbTimeConsumeInfo(info.imeCbTime);
109 auto intervalIndex = GetStatisticalIntervalIndex();
110 std::string key(appIndex);
111 if (info.errCode == ErrorCode::NO_ERROR) {
112 key.append("/").append(std::to_string(info.isShowKeyboard));
113 imeStartInputAllInfo_.succeedRateInfo.succeedInfo.ModCountDistributions(intervalIndex, key);
114 return;
115 }
116 key.append("/").append(std::to_string(info.eventCode)).append("/").append(std::to_string(info.errCode));
117 imeStartInputAllInfo_.succeedRateInfo.failedInfo.ModCountDistributions(intervalIndex, key);
118 }
119
ModImeCbTimeConsumeInfo(int32_t imeCbTime)120 void ImaHiSysEventReporter::ModImeCbTimeConsumeInfo(int32_t imeCbTime)
121 {
122 if (imeCbTime < 0) {
123 return;
124 }
125 auto index = IME_CB_TIME_INTERVAL.size() - 1;
126 for (size_t i = 0; i < IME_CB_TIME_INTERVAL.size() - 1; i++) {
127 if (IME_CB_TIME_INTERVAL[i].first <= imeCbTime && imeCbTime <= IME_CB_TIME_INTERVAL[i].second) {
128 index = i;
129 break;
130 }
131 }
132 imeStartInputAllInfo_.imeCbTimeConsumeInfo.ModCountDistributions(index);
133 }
134
RecordBaseTextOperationStatistics(const HiSysOriginalInfo & info)135 void ImaHiSysEventReporter::RecordBaseTextOperationStatistics(const HiSysOriginalInfo &info)
136 {
137 std::string appName = "*";
138 auto appIndex = ImfHiSysEventUtil::AddIfAbsent(appName, baseTextOperationAllInfo_.appNames);
139 std::string key(appIndex);
140 if (info.errCode == ErrorCode::NO_ERROR) {
141 key.append("/").append(std::to_string(info.eventCode));
142 baseTextOperationAllInfo_.succeedRateInfo.succeedInfo.ModCountDistributions(
143 GetBaseTextOperationSucceedIntervalIndex(info.baseTextOperationTime), key);
144 return;
145 }
146 key.append("/")
147 .append(std::to_string(info.clientType))
148 .append("/")
149 .append(std::to_string(info.eventCode))
150 .append("/")
151 .append(std::to_string(info.errCode));
152 baseTextOperationAllInfo_.succeedRateInfo.failedInfo.ModCountDistributions(GetStatisticalIntervalIndex(), key);
153 }
154
GetBaseTextOperationSucceedIntervalIndex(int32_t baseTextOperationTime)155 uint32_t ImaHiSysEventReporter::GetBaseTextOperationSucceedIntervalIndex(int32_t baseTextOperationTime)
156 {
157 if (baseTextOperationTime < 0) {
158 return 0;
159 }
160 auto index = BASE_TEXT_OPERATION_TIME_INTERVAL.size() - 1;
161 for (size_t i = 0; i < BASE_TEXT_OPERATION_TIME_INTERVAL.size() - 1; i++) {
162 if (BASE_TEXT_OPERATION_TIME_INTERVAL[i].first <= baseTextOperationTime
163 && baseTextOperationTime <= BASE_TEXT_OPERATION_TIME_INTERVAL[i].second) {
164 index = i;
165 break;
166 }
167 }
168 return index;
169 }
170 } // namespace MiscServices
171 } // namespace OHOS