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#ifndef OHOS_ROSEN_SCREEN_EVENT_TRACKER_H 17#define OHOS_ROSEN_SCREEN_EVENT_TRACKER_H 18 19#include <iomanip> 20#include <vector> 21#include <mutex> 22#include <sstream> 23#include <string> 24 25#include "window_manager_hilog.h" 26 27namespace OHOS { 28namespace Rosen { 29const int32_t OUTPUT_FREQ = 1; // 1Hz 30 31struct TrackInfo { 32 std::string info; 33 std::chrono::system_clock::time_point timestamp; 34}; 35 36class EventTracker { 37public: 38 void RecordEvent(std::string info = "") 39 { 40 std::lock_guard<std::mutex> lock(mutex_); 41 recordInfos_.push_back({info, std::chrono::system_clock::now()}); 42 } 43 44 void ClearAllRecordedEvents() 45 { 46 std::lock_guard<std::mutex> lock(mutex_); 47 recordInfos_.clear(); 48 } 49 50 void LogWarningAllInfos() const 51 { 52 auto now = std::chrono::system_clock::now(); 53 if (std::chrono::duration_cast<std::chrono::seconds>(now - lastOutputTime_).count() < OUTPUT_FREQ) { 54 return ; // Output too frequent. Try again later. 55 } 56 lastOutputTime_ = now; 57 58 std::lock_guard<std::mutex> lock(mutex_); 59 for (const auto& info : recordInfos_) { 60 TLOGW(WmsLogTag::DMS, "[%{public}s]: %{public}s", 61 formatTimestamp(info.timestamp).c_str(), info.info.c_str()); 62 } 63 } 64 65 std::string formatTimestamp(const std::chrono::system_clock::time_point& timePoint) const 66 { 67 const int32_t WIDTH_TIME = 2; 68 const int32_t WIDTH_TIME_MS = 3; 69 const int32_t TIME_CONVERT_MS = 1000; 70 const char DEFAULT_CHAR = '0'; 71 auto time = std::chrono::system_clock::to_time_t(timePoint); 72 std::tm localTime; 73 localtime_r(&time, &localTime); 74 auto timeMs = std::chrono::duration_cast<std::chrono::milliseconds>( 75 timePoint.time_since_epoch()) % TIME_CONVERT_MS; 76 77 std::ostringstream oss; 78 oss << std::setfill(DEFAULT_CHAR) 79 << std::setw(WIDTH_TIME) << (localTime.tm_mon + 1) << '-' 80 << std::setw(WIDTH_TIME) << localTime.tm_mday << ' ' 81 << std::setw(WIDTH_TIME) << localTime.tm_hour << ':' 82 << std::setw(WIDTH_TIME) << localTime.tm_min << ':' 83 << std::setw(WIDTH_TIME) << localTime.tm_sec << '.' 84 << std::setw(WIDTH_TIME_MS) << timeMs.count(); 85 return oss.str(); 86 } 87 88 const std::vector<TrackInfo>& GetRecordInfos() const 89 { 90 std::lock_guard<std::mutex> lock(mutex_); 91 return recordInfos_; 92 } 93 94private: 95 mutable std::mutex mutex_; 96 mutable std::chrono::system_clock::time_point lastOutputTime_; 97 std::vector<TrackInfo> recordInfos_; 98}; 99 100 101} // Rosen 102} // OHOS 103#endif // OHOS_ROSEN_SCREEN_EVENT_TRACKER_H