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 #include "trace_state_machine.h"
16
17 #include "trace_command_state.h"
18 #include "trace_common_state.h"
19 #include "trace_telemetry_state.h"
20 #include "trace_dynamic_state.h"
21 #include "hiview_logger.h"
22 #include "unistd.h"
23
24 namespace OHOS::HiviewDFX {
25 namespace {
26 DEFINE_LOG_TAG("TraceStateMachine");
27 const std::vector<std::string> TAG_GROUPS = {"scene_performance"};
28 }
29
TraceStateMachine()30 TraceStateMachine::TraceStateMachine()
31 {
32 currentState_ = std::make_shared<CloseState>();
33 }
34
OpenDynamicTrace(int32_t appid)35 TraceRet TraceStateMachine::OpenDynamicTrace(int32_t appid)
36 {
37 std::lock_guard<std::mutex> lock(traceMutex_);
38 return currentState_->OpenAppTrace(appid);
39 }
40
OpenTelemetryTrace(const std::string & args,TelemetryPolicy policy)41 TraceRet TraceStateMachine::OpenTelemetryTrace(const std::string &args, TelemetryPolicy policy)
42 {
43 std::lock_guard<std::mutex> lock(traceMutex_);
44 return currentState_->OpenTelemetryTrace(args, policy);
45 }
46
DumpTrace(TraceScenario scenario,uint32_t maxDuration,uint64_t happenTime,TraceRetInfo & info)47 TraceRet TraceStateMachine::DumpTrace(TraceScenario scenario, uint32_t maxDuration, uint64_t happenTime,
48 TraceRetInfo &info)
49 {
50 std::lock_guard<std::mutex> lock(traceMutex_);
51 auto ret = currentState_->DumpTrace(scenario, maxDuration, happenTime, info);
52 if (ret.GetCodeError() == TraceErrorCode::TRACE_IS_OCCUPIED ||
53 ret.GetCodeError() == TraceErrorCode::WRONG_TRACE_MODE) {
54 RecoverState();
55 }
56 return ret;
57 }
58
DumpTraceAsync(const DumpTraceArgs & args,int64_t fileSizeLimit,TraceRetInfo & info,DumpTraceCallback callback)59 TraceRet TraceStateMachine::DumpTraceAsync(const DumpTraceArgs &args, int64_t fileSizeLimit,
60 TraceRetInfo &info, DumpTraceCallback callback)
61 {
62 std::lock_guard<std::mutex> lock(traceMutex_);
63 auto ret = currentState_->DumpTraceAsync(args, fileSizeLimit, info, callback);
64 if (ret.GetCodeError() == TraceErrorCode::TRACE_IS_OCCUPIED ||
65 ret.GetCodeError() == TraceErrorCode::WRONG_TRACE_MODE) {
66 RecoverState();
67 }
68 return ret;
69 }
70
DumpTraceWithFilter(uint32_t maxDuration,uint64_t happenTime,TraceRetInfo & info)71 TraceRet TraceStateMachine::DumpTraceWithFilter(uint32_t maxDuration, uint64_t happenTime, TraceRetInfo &info)
72 {
73 std::lock_guard<std::mutex> lock(traceMutex_);
74 return currentState_->DumpTraceWithFilter(maxDuration, happenTime, info);
75 }
76
OpenTrace(TraceScenario scenario,const std::vector<std::string> & tagGroups)77 TraceRet TraceStateMachine::OpenTrace(TraceScenario scenario, const std::vector<std::string> &tagGroups)
78 {
79 HIVIEW_LOGI("TraceStateMachine OpenTrace scenario:%{public}d", static_cast<int>(scenario));
80 std::lock_guard<std::mutex> lock(traceMutex_);
81 return currentState_->OpenTrace(scenario, tagGroups);
82 }
83
OpenTrace(TraceScenario scenario,const std::string & args)84 TraceRet TraceStateMachine::OpenTrace(TraceScenario scenario, const std::string &args)
85 {
86 std::lock_guard<std::mutex> lock(traceMutex_);
87 HIVIEW_LOGI("TraceStateMachine OpenTrace scenario:%{public}d", static_cast<int>(scenario));
88 return currentState_->OpenTrace(scenario, args);
89 }
90
TraceDropOn(TraceScenario scenario)91 TraceRet TraceStateMachine::TraceDropOn(TraceScenario scenario)
92 {
93 std::lock_guard<std::mutex> lock(traceMutex_);
94 return currentState_->TraceDropOn(scenario);
95 }
96
TraceDropOff(TraceScenario scenario,TraceRetInfo & info)97 TraceRet TraceStateMachine::TraceDropOff(TraceScenario scenario, TraceRetInfo &info)
98 {
99 std::lock_guard<std::mutex> lock(traceMutex_);
100 return currentState_->TraceDropOff(scenario, info);
101 }
102
TraceTelemetryOn()103 TraceRet TraceStateMachine::TraceTelemetryOn()
104 {
105 std::lock_guard<std::mutex> lock(traceMutex_);
106 return currentState_->TraceTelemetryOn();
107 }
108
TraceTelemetryOff()109 TraceRet TraceStateMachine::TraceTelemetryOff()
110 {
111 std::lock_guard<std::mutex> lock(traceMutex_);
112 return currentState_->TraceTelemetryOff();
113 }
114
CloseTrace(TraceScenario scenario)115 TraceRet TraceStateMachine::CloseTrace(TraceScenario scenario)
116 {
117 std::lock_guard<std::mutex> lock(traceMutex_);
118 if (auto ret = currentState_->CloseTrace(scenario); !ret.IsSuccess()) {
119 HIVIEW_LOGW("fail stateError:%{public}d, codeError%{public}d", static_cast<int >(ret.stateError_),
120 ret.codeError_);
121 return ret;
122 }
123 return RecoverState();
124 }
125
TransToDynamicState(int32_t appPid)126 void TraceStateMachine::TransToDynamicState(int32_t appPid)
127 {
128 HIVIEW_LOGI("to app state");
129 currentState_ = std::make_shared<DynamicState>(appPid);
130 }
131
TransToCommonState()132 void TraceStateMachine::TransToCommonState()
133 {
134 HIVIEW_LOGI("to common state");
135 currentState_ = std::make_shared<CommonState>(isCachSwitchOn_, cacheSizeLimit_, cacheSliceSpan_);
136 }
137
TransToCommonDropState()138 void TraceStateMachine::TransToCommonDropState()
139 {
140 HIVIEW_LOGI("to common drop state");
141 currentState_ = std::make_shared<CommonDropState>();
142 }
143
144
TransToTeleMetryState(TelemetryPolicy policy)145 void TraceStateMachine::TransToTeleMetryState(TelemetryPolicy policy)
146 {
147 HIVIEW_LOGI("to telemetry state");
148 currentState_ = std::make_shared<TelemetryState>(policy);
149 }
150
TransToCloseState()151 void TraceStateMachine::TransToCloseState()
152 {
153 HIVIEW_LOGI("to close state");
154 currentState_ = std::make_shared<CloseState>();
155 }
156
TransToCommandState()157 void TraceStateMachine::TransToCommandState()
158 {
159 HIVIEW_LOGI("to command state");
160 SetCommandState(true);
161 currentState_ = std::make_shared<CommandState>();
162 }
163
TransToCommandDropState()164 void TraceStateMachine::TransToCommandDropState()
165 {
166 HIVIEW_LOGI("to command drop state");
167 currentState_ = std::make_shared<CommandDropState>();
168 }
169
InitCommonDropState()170 TraceRet TraceStateMachine::InitCommonDropState()
171 {
172 if (auto ret = Hitrace::OpenTrace(TAG_GROUPS); ret != TraceErrorCode::SUCCESS) {
173 HIVIEW_LOGE("OpenTrace error:%{public}d", ret);
174 return TraceRet(ret);
175 }
176 if (auto retTraceOn = Hitrace::RecordTraceOn(); retTraceOn != TraceErrorCode::SUCCESS) {
177 HIVIEW_LOGE("DumpTraceOn error:%{public}d", retTraceOn);
178 return TraceRet(retTraceOn);
179 }
180 TransToCommonDropState();
181 return {};
182 }
183
InitCommonState()184 TraceRet TraceStateMachine::InitCommonState()
185 {
186 if (auto ret = Hitrace::OpenTrace(TAG_GROUPS); ret != TraceErrorCode::SUCCESS) {
187 HIVIEW_LOGE("OpenTrace error:%{public}d", ret);
188 return TraceRet(ret);
189 }
190 TransToCommonState();
191 return {};
192 }
193
TraceCacheOn()194 TraceRet TraceStateMachine::TraceCacheOn()
195 {
196 std::lock_guard<std::mutex> lock(traceMutex_);
197 isCachSwitchOn_ = true;
198 return currentState_->TraceCacheOn();
199 }
200
TraceCacheOff()201 TraceRet TraceStateMachine::TraceCacheOff()
202 {
203 std::lock_guard<std::mutex> lock(traceMutex_);
204 isCachSwitchOn_ = false;
205 return currentState_->TraceCacheOff();
206 }
207
SetAppFilterInfo(const std::string & bundleName)208 int32_t TraceStateMachine::SetAppFilterInfo(const std::string &bundleName)
209 {
210 return currentState_->SetAppFilterInfo(bundleName);
211 }
212
SetFilterPidInfo(pid_t pid)213 int32_t TraceStateMachine::SetFilterPidInfo(pid_t pid)
214 {
215 return currentState_->SetFilterPidInfo(pid);
216 }
217
PowerTelemetryOn()218 TraceRet TraceStateMachine::PowerTelemetryOn()
219 {
220 std::lock_guard<std::mutex> lock(traceMutex_);
221 return currentState_->PowerTelemetryOn();
222 }
223
PowerTelemetryOff()224 TraceRet TraceStateMachine::PowerTelemetryOff()
225 {
226 std::lock_guard<std::mutex> lock(traceMutex_);
227 return currentState_->PowerTelemetryOff();
228 }
229
RecoverState()230 TraceRet TraceStateMachine::RecoverState()
231 {
232 if (Hitrace::GetTraceMode() != Hitrace::TraceMode::CLOSE) {
233 if (auto ret = Hitrace::CloseTrace(); ret != TraceErrorCode::SUCCESS) {
234 HIVIEW_LOGE("Hitrace close error:%{public}d", ret);
235 return TraceRet(ret);
236 }
237 }
238
239 // All switch is closed
240 if (traceSwitchState_ == 0) {
241 HIVIEW_LOGI("commercial version and all switch is closed, trans to CloseState");
242 TransToCloseState();
243 return {};
244 }
245
246 // If trace recording switch is open
247 if ((traceSwitchState_ & 1) == 1) {
248 return InitCommonDropState();
249 }
250
251 // trace froze or UCollection switch is open or isBetaVersion
252 return InitCommonState();
253 }
254
RegisterTelemetryCallback(std::shared_ptr<TelemetryCallback> stateCallback)255 bool TraceStateMachine::RegisterTelemetryCallback(std::shared_ptr<TelemetryCallback> stateCallback)
256 {
257 std::lock_guard<std::mutex> lock(traceMutex_);
258 return currentState_->RegisterTelemetryCallback(stateCallback);
259 }
260
PostTelemetryOn(uint64_t time)261 TraceRet TraceStateMachine::PostTelemetryOn(uint64_t time)
262 {
263 std::lock_guard<std::mutex> lock(traceMutex_);
264 return currentState_->PostTelemetryOn(time);
265 }
266
PostTelemetryTimeOut()267 TraceRet TraceStateMachine::PostTelemetryTimeOut()
268 {
269 std::lock_guard<std::mutex> lock(traceMutex_);
270 return currentState_->PostTelemetryTimeOut();
271 }
272
InitTelemetryStatus(bool isStatusOn)273 void TraceStateMachine::InitTelemetryStatus(bool isStatusOn)
274 {
275 HIVIEW_LOGI("isStatusOn %{public}d", isStatusOn);
276 currentState_->InitTelemetryStatus(isStatusOn);
277 }
278 }
279