• 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 "sys_event_repeat_guard.h"
17 
18 #include "calc_fingerprint.h"
19 #include "file_util.h"
20 #include "ffrt.h"
21 #include "hiview_logger.h"
22 #include "parameter_ex.h"
23 #include "setting_observer_manager.h"
24 #include "string_util.h"
25 #include "sys_event_repeat_db.h"
26 
27 namespace OHOS {
28 namespace HiviewDFX {
29 DEFINE_LOG_TAG("HiView-SysEvent-Repeat-Guard");
30 namespace {
31 constexpr time_t TIME_RANGE_COMMERCIAL = 24 * 60 * 60; // 24h
32 constexpr time_t TIME_RANGE_BETA = 1 * 60 * 60; // 1h
33 constexpr char HIVIEW_UE_SWITCH[] = "hiview_ue_switch_enable";
34 constexpr char KEY_ON[] = "1";
35 constexpr int REGISTER_RETRY_CNT = 100;
36 constexpr int REGISTER_LOOP_DURATION = 6;
37 
GetShaStr(uint8_t * eventData,std::string & hashStr)38 bool GetShaStr(uint8_t* eventData, std::string& hashStr)
39 {
40     EventRawDataInfo<EventRaw::HiSysEventHeader> eventInfo(eventData);
41     if (eventInfo.dataSize <= eventInfo.dataPos) {
42         HIVIEW_LOGE("invalid event.");
43         return false;
44     }
45     constexpr int buffLen = SHA256_DIGEST_LENGTH * 2 + 1;
46     char buff[buffLen] = {0};
47     if (CalcFingerprint::CalcBufferSha(
48         eventData + eventInfo.dataPos, eventInfo.dataSize - eventInfo.dataPos, buff, buffLen) != 0) {
49         HIVIEW_LOGE("fail to calc sha.");
50         return false;
51     }
52     hashStr = buff;
53     return true;
54 }
55 }
56 
GetMinValidTime()57 int64_t SysEventRepeatGuard::GetMinValidTime()
58 {
59     static time_t timeRange = Parameter::IsBetaVersion() ? TIME_RANGE_BETA : TIME_RANGE_COMMERCIAL;
60     time_t timeNow = time(nullptr);
61     time_t timeMin = timeNow > timeRange ? (timeNow - timeRange) : 0;
62     return timeMin;
63 }
64 
65 
Check(SysEvent & event)66 void SysEventRepeatGuard::Check(SysEvent& event)
67 {
68     if (event.GetEventType() != SysEventCreator::EventType::FAULT) {
69         return;
70     }
71     if (IsEventRepeat(event)) {
72         event.SetLog(LOG_NOT_ALLOW_PACK|LOG_REPEAT);
73         return;
74     }
75     event.SetLog(LOG_ALLOW_PACK|LOG_PACKED);
76     return;
77 }
78 
GetEventUniqueId(SysEvent & event,std::string & uniqueId)79 bool SysEventRepeatGuard::GetEventUniqueId(SysEvent& event, std::string& uniqueId)
80 {
81     uniqueId = event.GetEventValue("FINGERPRINT");
82     if (!uniqueId.empty()) {
83         return true;
84     }
85 
86     uint8_t* eventData = event.AsRawData();
87     if (eventData == nullptr) {
88         HIVIEW_LOGE("invalid eventData.");
89         return false;
90     }
91 
92     if (!GetShaStr(eventData, uniqueId) || uniqueId.empty()) {
93         HIVIEW_LOGE("GetShaStr failed.");
94         return false;
95     }
96     return true;
97 }
98 
IsEventRepeat(SysEvent & event)99 bool SysEventRepeatGuard::IsEventRepeat(SysEvent& event)
100 {
101     SysEventHashRecord sysEventHashRecord(event.domain_, event.eventName_);
102     if (!GetEventUniqueId(event, sysEventHashRecord.eventHash)) {
103         HIVIEW_LOGE("GetShaStr failed.");
104         return false;
105     }
106     auto happentime = SysEventRepeatDb::GetInstance().QueryHappentime(sysEventHashRecord);
107     int64_t minValidTime = GetMinValidTime();
108     if (happentime > minValidTime) {    // event repeat
109         SysEventRepeatDb::GetInstance().Release();
110         return true;
111     }
112 
113     sysEventHashRecord.happentime = time(nullptr);
114     if (happentime > 0) {   // > 0 means has record
115         SysEventRepeatDb::GetInstance().Update(sysEventHashRecord);
116     } else {
117         SysEventRepeatDb::GetInstance().Insert(sysEventHashRecord);
118         SysEventRepeatDb::GetInstance().CheckAndClearDb(minValidTime);
119     }
120     SysEventRepeatDb::GetInstance().Release();
121     return false;
122 }
123 
UnregisterListeningUeSwitch()124 void SysEventRepeatGuard::UnregisterListeningUeSwitch()
125 {
126     SettingObserverManager::GetInstance()->UnregisterObserver(HIVIEW_UE_SWITCH);
127 }
128 
RegisterListeningUeSwitch()129 void SysEventRepeatGuard::RegisterListeningUeSwitch()
130 {
131     ffrt::submit([] () {
132         SettingObserver::ObserverCallback callback =
133         [] (const std::string& paramKey) {
134             std::string val = SettingObserverManager::GetInstance()->GetStringValue(paramKey);
135             HIVIEW_LOGI("value of param key[%{public}s] is %{public}s", paramKey.c_str(), val.c_str());
136             if (val == KEY_ON) {
137                 int64_t curTime = time(nullptr);
138                 SysEventRepeatDb::GetInstance().Clear(curTime);
139                 SysEventRepeatDb::GetInstance().Release();
140             }
141         };
142         bool success = false;
143         int retryCount = REGISTER_RETRY_CNT;
144         while (!success && retryCount > 0) {
145             success = SettingObserverManager::GetInstance()->RegisterObserver(HIVIEW_UE_SWITCH, callback);
146             if (success) {
147                 break;
148             }
149             retryCount--;
150             ffrt::this_task::sleep_for(std::chrono::seconds(REGISTER_LOOP_DURATION));
151         }
152         if (!success) {
153             HIVIEW_LOGW("failed to regist setting db observer");
154         }
155         }, {}, {}, ffrt::task_attr().name("repeat_guard").qos(ffrt::qos_default));
156 }
157 } // HiviewDFX
158 } // OHOS