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 TEXT_TRACE_H
17 #define TEXT_TRACE_H
18 
19 #ifdef OHOS_TEXT_ENABLE
20 #include "hitrace_meter.h"
21 #include "parameters.h"
22 #endif
23 
24 namespace OHOS::Rosen {
25 #ifdef OHOS_TEXT_ENABLE
26 enum class TextTraceLevel {
27     TEXT_TRACE_LEVEL_DEFAULT,
28     TEXT_TRACE_LEVEL_LOW,
29     TEXT_TRACE_LEVEL_MIDDLE,
30     TEXT_TRACE_LEVEL_HIGH
31 };
32 
33 #define TEXT_TRACE(name) OHOS::Rosen::TextOptionalTrace optionalTrace(name)
34 #define TEXT_TRACE_FUNC() OHOS::Rosen::TextOptionalTrace optionalTrace(__PRETTY_FUNCTION__)
35 #define TEXT_TRACE_LEVEL(level, name) OHOS::Rosen::TextOptionalTrace::TraceWithLevel(level, name, __PRETTY_FUNCTION__)
36 
37 class TextOptionalTrace {
38 public:
TextOptionalTrace(std::string traceStr)39     TextOptionalTrace(std::string traceStr)
40     {
41         static bool debugTraceEnable = (OHOS::system::GetIntParameter("persist.sys.graphic.openDebugTrace", 0) != 0);
42         if (debugTraceEnable) {
43             std::string name { "Text#" };
44             CutPrettyFunction(traceStr);
45             name.append(traceStr);
46             StartTrace(HITRACE_TAG_GRAPHIC_AGP | HITRACE_TAG_COMMERCIAL, name);
47         }
48     }
49 
~TextOptionalTrace()50     ~TextOptionalTrace()
51     {
52         static bool debugTraceEnable = (OHOS::system::GetIntParameter("persist.sys.graphic.openDebugTrace", 0) != 0);
53         if (debugTraceEnable) {
54             FinishTrace(HITRACE_TAG_GRAPHIC_AGP | HITRACE_TAG_COMMERCIAL);
55         }
56     }
57 
58     // Simplify __PRETTY_FUNCTION__ to only return class name and function name
59     // case: std::unique_str<XXX::XXX::Xxx> XXX::XXX::ClassName::FunctionName()
60     // retrun: ClassName::FunctionName
CutPrettyFunction(std::string& str)61     static void CutPrettyFunction(std::string& str)
62     {
63         // find last '('
64         int endIndex = str.rfind('(');
65         if (endIndex == std::string::npos) {
66             return;
67         }
68 
69         // find the third ':' before '('
70         int startIndex = 0;
71         int count = 0;
72         for (int i = endIndex; i >= 0; --i) {
73             if (str[i] == ':') {
74                 count++;
75                 if (count == 3) { // 3 means to stop iterating when reaching the third ':'
76                     startIndex = i + 1;
77                     break;
78                 }
79             }
80         }
81         str = str.substr(startIndex, endIndex - startIndex);
82     }
83 
TraceWithLevel(TextTraceLevel level, const std::string& traceStr, std::string caller)84     static void TraceWithLevel(TextTraceLevel level, const std::string& traceStr, std::string caller)
85     {
86         static int32_t systemLevel =
87             std::atoi(OHOS::system::GetParameter("persist.sys.graphic.openDebugTrace", "0").c_str());
88         if ((systemLevel != 0) && (systemLevel <= static_cast<int32_t>(level))) {
89             CutPrettyFunction(caller);
90             HITRACE_METER_FMT(HITRACE_TAG_GRAPHIC_AGP, "Text#%s %s", traceStr.c_str(), caller.c_str());
91         }
92     }
93 };
94 
95 #else
96 #define TEXT_TRACE(name)
97 #define TEXT_TRACE_FUNC()
98 #define TEXT_TRACE_LEVEL(level, name)
99 #endif
100 } // namespace OHOS::Rosen
101 #endif