1 /*
2  * Copyright (c) 2021-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 #ifndef BASE_EVENTHANDLER_FRAMEWORKS_EVENTHANDLER_INCLUDE_HITRACE_METER_H
16 #define BASE_EVENTHANDLER_FRAMEWORKS_EVENTHANDLER_INCLUDE_HITRACE_METER_H
17 
18 #ifdef EH_HITRACE_METER_ENABLE
19 #include <dlfcn.h>
20 #include "inner_event.h"
21 
22 #define LOCAL_API __attribute__((visibility ("hidden")))
23 namespace OHOS {
24 namespace AppExecFwk {
25 constexpr uint64_t HITRACE_TAG_NOTIFICATION = (1ULL << 40); // Notification module tag.
26 bool IsTagEnabled(uint64_t tag);
27 void StartTrace(uint64_t label, const std::string& value, float limit = -1);
28 void FinishTrace(uint64_t label);
29 using IsTagEnabledType = decltype(IsTagEnabled)*;
30 using StartTraceType = decltype(StartTrace)*;
31 using FinishTraceType = decltype(FinishTrace)*;
32 
33 #if (defined(__aarch64__) || defined(__x86_64__))
34 static const std::string TRACE_LIB_PATH = "/system/lib64/chipset-pub-sdk/libhitrace_meter.so";
35 #else
36 static const std::string TRACE_LIB_PATH = "/system/lib/chipset-pub-sdk/libhitrace_meter.so";
37 #endif
38 
39 class TraceAdapter {
40 public:
TraceAdapter()41     TraceAdapter()
42     {
43         Load();
44     }
45 
~TraceAdapter()46     ~TraceAdapter()
47     {
48     }
49 
Instance()50     static TraceAdapter* Instance()
51     {
52         static TraceAdapter instance;
53         return &instance;
54     }
55 
56     IsTagEnabledType IsTagEnabled = nullptr;
57     StartTraceType StartTrace = nullptr;
58     FinishTraceType FinishTrace = nullptr;
59 private:
Load()60     LOCAL_API void Load()
61     {
62         if (handle != nullptr) {
63             HILOGD("%{public}s is already dlopened.", TRACE_LIB_PATH.c_str());
64             return;
65         }
66 
67         handle = dlopen(TRACE_LIB_PATH.c_str(), RTLD_NOW | RTLD_LOCAL);
68         if (handle == nullptr) {
69             HILOGE("dlopen %{public}s failed.", TRACE_LIB_PATH.c_str());
70             return;
71         }
72 
73         IsTagEnabled = reinterpret_cast<IsTagEnabledType>(dlsym(handle, "IsTagEnabled"));
74         if (IsTagEnabled == nullptr) {
75             HILOGE("get symbol IsTagEnabled failed.");
76             return;
77         }
78 
79         StartTrace = reinterpret_cast<StartTraceType>(dlsym(handle, "StartTrace"));
80         if (StartTrace == nullptr) {
81             HILOGE("get symbol StartTrace failed.");
82             return;
83         }
84 
85         FinishTrace = reinterpret_cast<FinishTraceType>(dlsym(handle, "FinishTrace"));
86         if (FinishTrace == nullptr) {
87             HILOGE("get symbol FinishTrace failed.");
88             return;
89         }
90     }
91 
92     DEFINE_EH_HILOG_LABEL("EventHiTraceAdapter");
93     void* handle = nullptr;
94 };
95 
StartTraceAdapter(const InnerEvent::Pointer & event)96 LOCAL_API static inline void StartTraceAdapter(const InnerEvent::Pointer &event)
97 {
98     if (TraceAdapter::Instance()->IsTagEnabled && TraceAdapter::Instance()->StartTrace) {
99         if (TraceAdapter::Instance()->IsTagEnabled(HITRACE_TAG_NOTIFICATION)) {
100             TraceAdapter::Instance()->StartTrace(HITRACE_TAG_NOTIFICATION, event->TraceInfo(), -1);
101         }
102     }
103 }
StartTraceObserver(ObserverTrace & observer)104 LOCAL_API static inline void StartTraceObserver(ObserverTrace &observer)
105 {
106     if (TraceAdapter::Instance()->IsTagEnabled && TraceAdapter::Instance()->StartTrace) {
107         if (TraceAdapter::Instance()->IsTagEnabled(HITRACE_TAG_NOTIFICATION)) {
108             TraceAdapter::Instance()->StartTrace(HITRACE_TAG_NOTIFICATION, observer.getTraceInfo(), -1);
109         }
110     }
111 }
FinishTraceAdapter()112 LOCAL_API static inline void FinishTraceAdapter()
113 {
114     if (TraceAdapter::Instance()->FinishTrace) {
115         TraceAdapter::Instance()->FinishTrace(HITRACE_TAG_NOTIFICATION);
116     }
117 }
118 }}
119 #else
120 namespace OHOS {
121 namespace AppExecFwk {
StartTraceAdapter(const InnerEvent::Pointer & event)122 static inline void StartTraceAdapter(const InnerEvent::Pointer &event)
123 {
124 }
StartTraceObserver(ObserverTrace & observer)125 static inline void StartTraceObserver(ObserverTrace &observer)
126 {
127 }
FinishTraceAdapter()128 static inline void FinishTraceAdapter()
129 {
130 }
131 }}
132 #endif
133 #endif // BASE_EVENTHANDLER_FRAMEWORKS_EVENTHANDLER_INCLUDE_HITRACE_METER_H
134