1 /*
2 * Copyright (c) 2022-2023 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 "property/rs_property_trace.h"
17
18 #include <climits>
19 #include <cstdarg>
20 #include <fstream>
21 #include <regex>
22 #include <securec.h>
23 #include <sys/time.h>
24 #include "directory_ex.h"
25
26 #include "rs_trace.h"
27
28 namespace OHOS {
29 namespace Rosen {
30 const std::string ANIMATION_LOG_PATH = "/etc/rosen/";
31 const std::string CONFIG_FILE_NAME = "property.config";
32 const std::string COLON_SEPARATOR = ":";
33 const std::string COMMA_SEPARATOR = ",";
34 const std::string SEMICOLON_SEPARATOR = ";";
35 const std::string NODE_ID_TAG = "ID";
36 const std::string ALL_NEED_TAG = "all";
37 static constexpr int MIN_INFO_SIZE = 2;
38 RSPropertyTrace RSPropertyTrace::instance_;
39
PropertiesDisplayByTrace(const NodeId & id,const std::shared_ptr<RSObjAbsGeometry> & boundsGeometry)40 void RSPropertyTrace::PropertiesDisplayByTrace(const NodeId& id,
41 const std::shared_ptr<RSObjAbsGeometry>& boundsGeometry)
42 {
43 if (IsNeedPropertyTrace(id)) {
44 auto rectI = boundsGeometry->GetAbsRect();
45 AddTraceFlag(std::to_string(id) + " Geometry Rect: " + rectI.ToString());
46 }
47 }
48
RefreshNodeTraceInfo()49 void RSPropertyTrace::RefreshNodeTraceInfo()
50 {
51 if (IsNeedRefreshConfig()) {
52 InitNodeAndPropertyInfo();
53 }
54 }
55
AddTraceFlag(const std::string & str)56 void RSPropertyTrace::AddTraceFlag(const std::string& str)
57 {
58 ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, str.c_str());
59 ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
60 }
61
SplitStringBySeparator(const std::string & str,const std::string & separator)62 std::vector<std::string> SplitStringBySeparator(const std::string& str,
63 const std::string& separator)
64 {
65 std::regex re(separator);
66 std::sregex_token_iterator pos(str.begin(), str.end(), re, -1);
67 std::sregex_token_iterator endPos;
68 std::vector<std::string> result;
69 while (pos != endPos) {
70 result.emplace_back(*pos++);
71 }
72 return result;
73 }
74
InitNodeAndPropertyInfo()75 void RSPropertyTrace::InitNodeAndPropertyInfo()
76 {
77 std::string configFilePath = ANIMATION_LOG_PATH + CONFIG_FILE_NAME;
78 std::string newpath;
79 if (!PathToRealPath(configFilePath, newpath)) {
80 ROSEN_LOGE("Render node trace config file is nullptr!");
81 return;
82 }
83 std::ifstream configFile(newpath);
84 if (!configFile.is_open()) {
85 ROSEN_LOGE("Open render node trace config file failed!");
86 return;
87 }
88
89 std::string info;
90 while (std::getline(configFile, info)) {
91 std::vector<std::string> infos = SplitStringBySeparator(info, SEMICOLON_SEPARATOR);
92 if (infos.empty()) {
93 continue;
94 }
95 DealConfigInputInfo(infos.front());
96 }
97 configFile.close();
98 }
99
DealConfigInputInfo(const std::string & info)100 void RSPropertyTrace::DealConfigInputInfo(const std::string& info)
101 {
102 std::vector<std::string> splitResult = SplitStringBySeparator(info, COLON_SEPARATOR);
103 if (splitResult.size() != MIN_INFO_SIZE) {
104 ROSEN_LOGE("Render node trace config file size error!");
105 return;
106 }
107
108 std::string tag = splitResult.front();
109 if (tag == NODE_ID_TAG) {
110 std::vector<std::string> nodeIds =
111 SplitStringBySeparator(splitResult.back(), COMMA_SEPARATOR);
112 for (std::string nodeId : nodeIds) {
113 if (nodeId == ALL_NEED_TAG) {
114 needWriteAllNode_ = true;
115 return;
116 }
117 auto id = atoll(nodeId.c_str());
118 nodeIdSet_.insert(id);
119 }
120 }
121 }
122
ClearNodeAndPropertyInfo()123 void RSPropertyTrace::ClearNodeAndPropertyInfo()
124 {
125 nodeIdSet_.clear();
126 }
127
IsNeedRefreshConfig()128 bool RSPropertyTrace::IsNeedRefreshConfig()
129 {
130 struct stat configFileStatus = {};
131 std::string configFilePath = ANIMATION_LOG_PATH + CONFIG_FILE_NAME;
132 if (stat(configFilePath.c_str(), &configFileStatus)) {
133 return false;
134 }
135
136 std::string curent(ctime(&configFileStatus.st_mtime));
137 if (curent != propertyFileLastModifyTime) {
138 propertyFileLastModifyTime = curent;
139 return true;
140 }
141 return false;
142 }
143
IsNeedPropertyTrace(const NodeId & id)144 bool RSPropertyTrace::IsNeedPropertyTrace(const NodeId& id)
145 {
146 auto itrn = nodeIdSet_.find(id);
147 if (itrn == nodeIdSet_.end() && !needWriteAllNode_) {
148 return false;
149 }
150 return true;
151 }
152 } // namespace Rosen
153 } // namespace OHOS
154