1020a203aSopenharmony_ci/* 2020a203aSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 3020a203aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4020a203aSopenharmony_ci * you may not use this file except in compliance with the License. 5020a203aSopenharmony_ci * You may obtain a copy of the License at 6020a203aSopenharmony_ci * 7020a203aSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8020a203aSopenharmony_ci * 9020a203aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10020a203aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11020a203aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12020a203aSopenharmony_ci * See the License for the specific language governing permissions and 13020a203aSopenharmony_ci * limitations under the License. 14020a203aSopenharmony_ci */ 15020a203aSopenharmony_ci 16020a203aSopenharmony_ci#include "resolver.h" 17020a203aSopenharmony_ci 18020a203aSopenharmony_ci#include <sys/time.h> 19020a203aSopenharmony_ci 20020a203aSopenharmony_ci#include "file_util.h" 21020a203aSopenharmony_ci#include "hiview_event_report.h" 22020a203aSopenharmony_ci#include "hiview_logger.h" 23020a203aSopenharmony_ci#include "string_util.h" 24020a203aSopenharmony_ci#include "sys_event.h" 25020a203aSopenharmony_ci#include "sys_event_dao.h" 26020a203aSopenharmony_ci 27020a203aSopenharmony_cinamespace OHOS { 28020a203aSopenharmony_cinamespace HiviewDFX { 29020a203aSopenharmony_cinamespace { 30020a203aSopenharmony_ci static const int DEFAULT_TIME_WINDOW = 30; 31020a203aSopenharmony_ci static const int MINUTES_IN_HOUR = 60; 32020a203aSopenharmony_ci static const int MIN_MATCH_NUM = 2; 33020a203aSopenharmony_ci static const int DEFAULT_HOURS = 10; 34020a203aSopenharmony_ci} 35020a203aSopenharmony_ci 36020a203aSopenharmony_ciDEFINE_LOG_LABEL(0xD002D01, "FreezeDetector"); 37020a203aSopenharmony_cibool FreezeResolver::Init() 38020a203aSopenharmony_ci{ 39020a203aSopenharmony_ci if (freezeCommon_ == nullptr) { 40020a203aSopenharmony_ci return false; 41020a203aSopenharmony_ci } 42020a203aSopenharmony_ci freezeRuleCluster_ = freezeCommon_->GetFreezeRuleCluster(); 43020a203aSopenharmony_ci if (freezeRuleCluster_ == nullptr) { 44020a203aSopenharmony_ci return false; 45020a203aSopenharmony_ci } 46020a203aSopenharmony_ci dBHelper_ = std::make_unique<DBHelper>(freezeCommon_); 47020a203aSopenharmony_ci vendor_ = std::make_unique<Vendor>(freezeCommon_); 48020a203aSopenharmony_ci return vendor_->Init(); 49020a203aSopenharmony_ci} 50020a203aSopenharmony_ci 51020a203aSopenharmony_cibool FreezeResolver::ResolveEvent(const WatchPoint& watchPoint, 52020a203aSopenharmony_ci std::vector<WatchPoint>& list, std::vector<FreezeResult>& result) const 53020a203aSopenharmony_ci{ 54020a203aSopenharmony_ci if (freezeRuleCluster_ == nullptr || !freezeRuleCluster_->GetResult(watchPoint, result)) { 55020a203aSopenharmony_ci return false; 56020a203aSopenharmony_ci } 57020a203aSopenharmony_ci unsigned long long timestamp = watchPoint.GetTimestamp(); 58020a203aSopenharmony_ci long pid = watchPoint.GetPid(); 59020a203aSopenharmony_ci std::string packageName = watchPoint.GetPackageName().empty() ? 60020a203aSopenharmony_ci watchPoint.GetProcessName() : watchPoint.GetPackageName(); 61020a203aSopenharmony_ci DBHelper::WatchParams params = {pid, packageName}; 62020a203aSopenharmony_ci for (auto& i : result) { 63020a203aSopenharmony_ci long window = i.GetWindow(); 64020a203aSopenharmony_ci if (window == 0) { 65020a203aSopenharmony_ci list.push_back(watchPoint); 66020a203aSopenharmony_ci } else if (dBHelper_ != nullptr) { 67020a203aSopenharmony_ci unsigned long long timeInterval = static_cast<unsigned long long>(std::abs(window) * MILLISECOND); 68020a203aSopenharmony_ci unsigned long long start = window > 0 ? timestamp : timestamp - timeInterval; 69020a203aSopenharmony_ci unsigned long long end = window > 0 ? timestamp + timeInterval : timestamp; 70020a203aSopenharmony_ci dBHelper_->SelectEventFromDB(start, end, list, params, i); 71020a203aSopenharmony_ci } 72020a203aSopenharmony_ci } 73020a203aSopenharmony_ci 74020a203aSopenharmony_ci HIVIEW_LOGI("list size %{public}zu", list.size()); 75020a203aSopenharmony_ci return true; 76020a203aSopenharmony_ci} 77020a203aSopenharmony_ci 78020a203aSopenharmony_cibool FreezeResolver::JudgmentResult(const WatchPoint& watchPoint, 79020a203aSopenharmony_ci const std::vector<WatchPoint>& list, const std::vector<FreezeResult>& result) const 80020a203aSopenharmony_ci{ 81020a203aSopenharmony_ci if (watchPoint.GetDomain() == "ACE" && watchPoint.GetStringId() == "UI_BLOCK_6S") { 82020a203aSopenharmony_ci if (list.size() == result.size()) { 83020a203aSopenharmony_ci HIVIEW_LOGI("ACE UI_BLOCK has UI_BLOCK_3S UI_BLOCK_6S UI_BLOCK_RECOVERED as UI_JANK"); 84020a203aSopenharmony_ci return false; 85020a203aSopenharmony_ci } 86020a203aSopenharmony_ci 87020a203aSopenharmony_ci if (list.size() != (result.size() - 1)) { 88020a203aSopenharmony_ci return false; 89020a203aSopenharmony_ci } 90020a203aSopenharmony_ci 91020a203aSopenharmony_ci for (auto& i : list) { 92020a203aSopenharmony_ci if (i.GetStringId() == "UI_BLOCK_RECOVERED") { 93020a203aSopenharmony_ci return false; 94020a203aSopenharmony_ci } 95020a203aSopenharmony_ci } 96020a203aSopenharmony_ci return true; 97020a203aSopenharmony_ci } 98020a203aSopenharmony_ci 99020a203aSopenharmony_ci if (std::any_of(result.begin(), result.end(), [&list](auto& res) { 100020a203aSopenharmony_ci return res.GetAction() == "or"; 101020a203aSopenharmony_ci })) { 102020a203aSopenharmony_ci return list.size() >= MIN_MATCH_NUM; 103020a203aSopenharmony_ci } 104020a203aSopenharmony_ci 105020a203aSopenharmony_ci if (list.size() == result.size()) { 106020a203aSopenharmony_ci return true; 107020a203aSopenharmony_ci } 108020a203aSopenharmony_ci return false; 109020a203aSopenharmony_ci} 110020a203aSopenharmony_ci 111020a203aSopenharmony_ciint FreezeResolver::ProcessEvent(const WatchPoint &watchPoint) const 112020a203aSopenharmony_ci{ 113020a203aSopenharmony_ci HIVIEW_LOGI("process event [%{public}s, %{public}s]", 114020a203aSopenharmony_ci watchPoint.GetDomain().c_str(), watchPoint.GetStringId().c_str()); 115020a203aSopenharmony_ci if (vendor_ == nullptr) { 116020a203aSopenharmony_ci return -1; 117020a203aSopenharmony_ci } 118020a203aSopenharmony_ci std::vector<WatchPoint> list; 119020a203aSopenharmony_ci std::vector<FreezeResult> result; 120020a203aSopenharmony_ci if (!ResolveEvent(watchPoint, list, result)) { 121020a203aSopenharmony_ci HIVIEW_LOGW("no rule for event [%{public}s, %{public}s]", 122020a203aSopenharmony_ci watchPoint.GetDomain().c_str(), watchPoint.GetStringId().c_str()); 123020a203aSopenharmony_ci return -1; 124020a203aSopenharmony_ci } 125020a203aSopenharmony_ci 126020a203aSopenharmony_ci if (!JudgmentResult(watchPoint, list, result)) { 127020a203aSopenharmony_ci HIVIEW_LOGW("no match event for event [%{public}s, %{public}s]", 128020a203aSopenharmony_ci watchPoint.GetDomain().c_str(), watchPoint.GetStringId().c_str()); 129020a203aSopenharmony_ci return -1; 130020a203aSopenharmony_ci } 131020a203aSopenharmony_ci 132020a203aSopenharmony_ci vendor_->MergeEventLog(watchPoint, list, result); 133020a203aSopenharmony_ci return 0; 134020a203aSopenharmony_ci} 135020a203aSopenharmony_ci 136020a203aSopenharmony_cistd::string FreezeResolver::GetTimeZone() const 137020a203aSopenharmony_ci{ 138020a203aSopenharmony_ci std::string timeZone = ""; 139020a203aSopenharmony_ci struct timeval tv; 140020a203aSopenharmony_ci struct timezone tz; 141020a203aSopenharmony_ci if (gettimeofday(&tv, &tz) != 0) { 142020a203aSopenharmony_ci HIVIEW_LOGE("failed to gettimeofday"); 143020a203aSopenharmony_ci return timeZone; 144020a203aSopenharmony_ci } 145020a203aSopenharmony_ci 146020a203aSopenharmony_ci int hour = (-tz.tz_minuteswest) / MINUTES_IN_HOUR; 147020a203aSopenharmony_ci timeZone = (hour >= 0) ? "+" : "-"; 148020a203aSopenharmony_ci 149020a203aSopenharmony_ci int absHour = std::abs(hour); 150020a203aSopenharmony_ci if (absHour < DEFAULT_HOURS) { 151020a203aSopenharmony_ci timeZone.append("0"); 152020a203aSopenharmony_ci } 153020a203aSopenharmony_ci timeZone.append(std::to_string(absHour)); 154020a203aSopenharmony_ci 155020a203aSopenharmony_ci int minute = (-tz.tz_minuteswest) % MINUTES_IN_HOUR; 156020a203aSopenharmony_ci int absMinute = std::abs(minute); 157020a203aSopenharmony_ci if (absMinute < DEFAULT_HOURS) { 158020a203aSopenharmony_ci timeZone.append("0"); 159020a203aSopenharmony_ci } 160020a203aSopenharmony_ci timeZone.append(std::to_string(absMinute)); 161020a203aSopenharmony_ci 162020a203aSopenharmony_ci return timeZone; 163020a203aSopenharmony_ci} 164020a203aSopenharmony_ci} // namespace HiviewDFX 165020a203aSopenharmony_ci} // namespace OHOS 166