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 #define MLOG_TAG "AccurateRefresh::DfxRefreshManager"
17
18 #include "dfx_refresh_manager.h"
19 #include "dfx_reporter.h"
20 #include "dfx_manager.h"
21 #include "photo_album_column.h"
22 #include "accurate_common_data.h"
23 #include "media_log.h"
24 #include <unordered_map>
25 #include <string>
26 #include <nlohmann/json.hpp>
27 #include "media_file_utils.h"
28 #include "parameter.h"
29 #include "parameters.h"
30
31 using namespace std;
32 using json = nlohmann::json;
33
34 namespace OHOS {
35 namespace Media::AccurateRefresh {
36
37 static const std::string KEY_HIVIEW_VERSION_TYPE = "const.logsystem.versiontype";
38
DfxRefreshManager(const std::string & targetBusiness)39 DfxRefreshManager::DfxRefreshManager(const std::string &targetBusiness): targetBusiness_(targetBusiness) {}
40
41
SetOperationTotalTime(const std::string & tableName)42 void DfxRefreshManager::SetOperationTotalTime(const std::string &tableName)
43 {
44 int32_t currentOperationTime = MediaFileUtils::UTCTimeMilliSeconds() - OperationStartTime_;
45 if (tableName == PhotoAlbumColumns::TABLE) {
46 albumOperationTotalTime_ += currentOperationTime;
47 } else {
48 photoOperationTotalTime_ += currentOperationTime;
49 }
50 }
51
SetOperationStartTime()52 void DfxRefreshManager::SetOperationStartTime()
53 {
54 int64_t timestamp = MediaFileUtils::UTCTimeMilliSeconds();
55 OperationStartTime_ = timestamp;
56 }
57
SetOptEndTimeAndSql(std::string tableName)58 void DfxRefreshManager::SetOptEndTimeAndSql(std::string tableName)
59 {
60 SetOperationTotalTime(tableName);
61 }
62
SetOptEndTimeAndSql(MediaLibraryCommand & cmd)63 void DfxRefreshManager::SetOptEndTimeAndSql(MediaLibraryCommand &cmd)
64 {
65 SetOperationTotalTime(cmd.GetTableName());
66 }
67
SetOptEndTimeAndSql(const NativeRdb::AbsRdbPredicates & predicates)68 void DfxRefreshManager::SetOptEndTimeAndSql(
69 const NativeRdb::AbsRdbPredicates &predicates)
70 {
71 SetOperationTotalTime(predicates.GetTableName());
72 }
73
SetAlbumIdAndOptTime(int32_t albumId,bool isHidden)74 void DfxRefreshManager::SetAlbumIdAndOptTime(int32_t albumId, bool isHidden)
75 {
76 int32_t currentOperationTime = MediaFileUtils::UTCTimeMilliSeconds() - OperationStartTime_;
77 albumOperationTotalTime_ += currentOperationTime;
78 if (isHidden) {
79 if (albumHiddenInfoOperationTime_.size() <= MAX_ALBUM_OPERATION_SIZE) {
80 albumHiddenInfoOperationTime_[albumId] = currentOperationTime;
81 }
82 } else {
83 if (albumOperationTime_.size() <= MAX_ALBUM_OPERATION_SIZE) {
84 albumOperationTime_[albumId] = currentOperationTime;
85 }
86 }
87 if (albumIds_.size() <= MAX_ALBUM_ID_SIZE) {
88 albumIds_.insert(albumId);
89 }
90 }
91
SetEndTotalTime()92 void DfxRefreshManager::SetEndTotalTime()
93 {
94 totalCostTime_ = endTime_ - startTime_;
95 if (totalCostTime_ > MAX_COST_TIME_REPORT) {
96 isReport_ = true;
97 }
98 if (totalCostTime_ > MAX_COST_TIME_PRINT_LOG && totalCostTime_ < MAX_COST_TIME_REPORT) {
99 isPrintLog_ = true;
100 }
101 }
102
MapToJson(const std::unordered_map<int32_t,int32_t> & map)103 std::string DfxRefreshManager::MapToJson(const std::unordered_map<int32_t, int32_t>& map)
104 {
105 json j;
106 for (const auto& pair : map) {
107 j[std::to_string(pair.first)] = pair.second;
108 }
109 return j.dump();
110 }
111
VectorToString(const std::vector<int32_t> & vec,const std::string & sep=", ")112 std::string VectorToString(const std::vector<int32_t>& vec, const std::string& sep = ", ")
113 {
114 std::stringstream ss;
115 ss << "[";
116 for (size_t i = 0; i < vec.size(); ++i) {
117 ss << vec[i];
118 if (i != vec.size() - 1) ss << sep;
119 }
120 ss << "]";
121 return ss.str();
122 }
123
DataPointToString(const AccurateRefreshDfxDataPoint & data)124 std::string DataPointToString(const AccurateRefreshDfxDataPoint& data)
125 {
126 std::stringstream ss;
127 ss << "AccurateRefreshDfxDataPoint {" << std::endl;
128 ss << " targetBusiness: \"" << data.targetBusiness << "\"," << std::endl;
129 ss << " sqlStr: \"" << data.sqlStr << "\"," << std::endl;
130 ss << " totalCostTime: " << data.totalCostTime << "," << std::endl;
131 ss << " standardCostTime: " << data.standardCostTime << "," << std::endl;
132 ss << " photoOperationTotalTime: " << data.photoOperationTotalTime << "," << std::endl;
133 ss << " albumOperationTotalTime: " << data.albumOperationTotalTime << "," << std::endl;
134 ss << " albumId: " << VectorToString(data.albumId) << "," << std::endl;
135 ss << " albumOperationTime: \"" << data.albumOperationTime << "\"," << std::endl;
136 ss << " albumHiddenInfoOperationTime: \"" << data.albumHiddenInfoOperationTime << "\"" << std::endl;
137 ss << "}";
138 return ss.str();
139 }
140
SetStartTime()141 void DfxRefreshManager::SetStartTime()
142 {
143 startTime_ = MediaFileUtils::UTCTimeMilliSeconds();
144 }
145
SetAlbumId(int32_t albumId)146 void DfxRefreshManager::SetAlbumId(int32_t albumId)
147 {
148 if (albumIds_.size() <= MAX_ALBUM_ID_SIZE) {
149 albumIds_.insert(albumId);
150 }
151 }
152
SetAlbumId(std::vector<int> albumIds)153 void DfxRefreshManager::SetAlbumId(std::vector<int> albumIds)
154 {
155 size_t remainingSpace = MAX_ALBUM_ID_SIZE - albumIds_.size();
156 if (remainingSpace > 0) {
157 // 只插入前 remainingSpace 个元素
158 auto endIt = albumIds.begin() + std::min(remainingSpace, albumIds.size());
159 albumIds_.insert(albumIds.begin(), endIt);
160 }
161 }
162
SetEndTime()163 void DfxRefreshManager::SetEndTime()
164 {
165 endTime_ = MediaFileUtils::UTCTimeMilliSeconds();
166 }
167
IsBetaVersion()168 static bool IsBetaVersion()
169 {
170 static const string versionType = system::GetParameter(KEY_HIVIEW_VERSION_TYPE, "unknown");
171 static bool isBetaVersion = versionType.find("beta") != std::string::npos;
172 return isBetaVersion;
173 }
174
DfxRefreshReport()175 void DfxRefreshManager::DfxRefreshReport()
176 {
177 SetEndTotalTime();
178 MEDIA_INFO_LOG("enter DfxRefreshReport totalCostTime_:%{public}d", static_cast<int>(totalCostTime_));
179 AccurateRefreshDfxDataPoint reportData;
180 auto albumOperationTime = albumOperationTime_;
181 auto albumHiddenInfoOperationTime = albumHiddenInfoOperationTime_;
182 reportData.totalCostTime = totalCostTime_;
183 reportData.targetBusiness = targetBusiness_;
184 reportData.standardCostTime = MAX_COST_TIME_REPORT;
185 reportData.albumId = {albumIds_.begin(), albumIds_.end()};
186 reportData.photoOperationTotalTime = photoOperationTotalTime_;
187 reportData.albumOperationTotalTime = albumOperationTotalTime_;
188 reportData.albumOperationTime = MapToJson(albumOperationTime);
189 reportData.albumHiddenInfoOperationTime = MapToJson(albumHiddenInfoOperationTime);
190 if (isReport_) {
191 DfxManager::GetInstance()->HandleAccurateRefreshTimeOut(reportData);
192 }
193 if (isPrintLog_) {
194 MEDIA_INFO_LOG("AccurateRefreshDfxDataPoint:%{public}s", DataPointToString(reportData).c_str());
195 }
196 }
197
QueryStatementReport(const std::string & targetBusiness,int32_t totalCostTime,const std::string & sqlStr)198 void DfxRefreshManager::QueryStatementReport(
199 const std::string &targetBusiness, int32_t totalCostTime, const std::string &sqlStr)
200 {
201 if (totalCostTime < MAX_COST_TIME_PRINT_LOG) {
202 return;
203 }
204 AccurateRefreshDfxDataPoint reportData;
205 reportData.totalCostTime = totalCostTime;
206 reportData.targetBusiness = targetBusiness;
207 reportData.standardCostTime = MAX_COST_TIME_REPORT;
208 if (IsBetaVersion()) {
209 if (sqlStr.size() > MAX_SQLSTR_SIZE) {
210 reportData.sqlStr = sqlStr.substr(0, MAX_SQLSTR_SIZE);
211 } else {
212 reportData.sqlStr = sqlStr;
213 }
214 }
215 if (totalCostTime > MAX_COST_TIME_PRINT_LOG && totalCostTime < MAX_COST_TIME_REPORT) {
216 MEDIA_INFO_LOG("AccurateRefreshDfxDataPoint:%{public}s", DataPointToString(reportData).c_str());
217 return;
218 }
219 DfxManager::GetInstance()->HandleAccurateRefreshTimeOut(reportData);
220 }
221
222 } // namespace Media::AccurateRefresh
223 } // namespace OHOS