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 "hitrace_dump.h"
16 #include "hiview_logger.h"
17 #include "telemetry_state_machine.h"
18 #include "time_util.h"
19
20 namespace OHOS::HiviewDFX::Telemetry {
21 namespace {
22 DEFINE_LOG_TAG("TeleMetryStateMachine");
23 }
24
IsTraceOn()25 bool InitState::IsTraceOn()
26 {
27 return false;
28 }
29
TraceOn()30 TraceRet InitState::TraceOn()
31 {
32 auto ptr = stateMachine_.lock();
33 if (ptr == nullptr) {
34 HIVIEW_LOGE(":%{public}s, stateMachine_ null", GetTag().c_str());
35 return TraceRet(TraceStateCode::FAIL);
36 }
37 if (auto ret = ptr->TransToTraceOnState(1, 0); !ret.IsSuccess()) {
38 HIVIEW_LOGI("set traceOn fail");
39 return ret;
40 }
41 if (ptr->stateCallback_ != nullptr) {
42 ptr->stateCallback_->OnTelemetryTraceOn();
43 }
44 return {};
45 }
46
TraceOff()47 TraceRet InitState::TraceOff()
48 {
49 HIVIEW_LOGW(":%{public}s, already trace off", GetTag().c_str());
50 return {};
51 }
52
PostOn(uint64_t time)53 TraceRet InitState::PostOn(uint64_t time)
54 {
55 auto ptr = stateMachine_.lock();
56 if (ptr == nullptr) {
57 HIVIEW_LOGE(":%{public}s, stateMachine_ null", GetTag().c_str());
58 return TraceRet(TraceStateCode::FAIL);
59 }
60 auto postEndTime = TimeUtil::GetBootTimeMs() + time;
61 if (auto ret = ptr->TransToTraceOnState(0, postEndTime); !ret.IsSuccess()) {
62 HIVIEW_LOGI("set traceOn fail");
63 return ret;
64 }
65 if (ptr->stateCallback_ != nullptr) {
66 ptr->stateCallback_->OnTelemetryTraceOn();
67 }
68 HIVIEW_LOGI("state:%{public}s time:%{public}" PRId64 "", GetTag().c_str(), time);
69 return TraceRet(TraceStateCode::UPDATE_TIME);
70 }
71
TimeOut()72 TraceRet InitState::TimeOut()
73 {
74 HIVIEW_LOGI(":%{public}s, do nothing", GetTag().c_str());
75 return {};
76 }
77
GetTag()78 std::string InitState::GetTag()
79 {
80 return "InitState";
81 }
82
IsTraceOn()83 bool TraceOnState::IsTraceOn()
84 {
85 return true;
86 }
87
TraceOn()88 TraceRet TraceOnState::TraceOn()
89 {
90 traceOnCount_++;
91 HIVIEW_LOGI("state:%{public}s, traceOnCount_:%{public}d", GetTag().c_str(), traceOnCount_);
92 return {};
93 }
94
TraceOff()95 TraceRet TraceOnState::TraceOff()
96 {
97 auto ptr = stateMachine_.lock();
98 if (ptr == nullptr) {
99 HIVIEW_LOGE(":%{public}s, stateMachine_ null", GetTag().c_str());
100 return TraceRet(TraceStateCode::FAIL);
101 }
102 if (postEndTime_ > 0 || traceOnCount_ > 1) {
103 if (traceOnCount_ > 1) {
104 traceOnCount_--;
105 }
106 HIVIEW_LOGE(":%{public}s, post on running, still trace on", GetTag().c_str());
107 return TraceRet(TraceStateCode::NO_TRIGGER);
108 }
109 if (auto ret = ptr->TransToInitState(); !ret.IsSuccess()) {
110 HIVIEW_LOGE("set traceOff fail");
111 return ret;
112 }
113 HIVIEW_LOGI(":%{public}s, close trace", GetTag().c_str());
114 if (stateMachine_.lock()->stateCallback_ != nullptr) {
115 stateMachine_.lock()->stateCallback_->OnTelemetryTraceOff();
116 }
117 return {};
118 }
119
PostOn(uint64_t time)120 TraceRet TraceOnState::PostOn(uint64_t time)
121 {
122 auto postEndTime = TimeUtil::GetBootTimeMs() + time;
123 if (postEndTime < postEndTime_) {
124 HIVIEW_LOGW("already post on, no need to update time out");
125 return {};
126 }
127 postEndTime_ = postEndTime;
128 HIVIEW_LOGI("state:%{public}s time:%{public}" PRId64 "", GetTag().c_str(), time);
129 return TraceRet(TraceStateCode::UPDATE_TIME);
130 }
131
TimeOut()132 TraceRet TraceOnState::TimeOut()
133 {
134 auto ptr = stateMachine_.lock();
135 if (ptr == nullptr) {
136 HIVIEW_LOGE(":%{public}s, stateMachine_ null", GetTag().c_str());
137 return TraceRet(TraceStateCode::FAIL);
138 }
139 auto now = TimeUtil::GetBootTimeMs();
140 if (now < postEndTime_) {
141 HIVIEW_LOGW(":%{public}s do nothing, time out invalid", GetTag().c_str());
142 return TraceRet(TraceStateCode::NO_TRIGGER);
143 }
144 postEndTime_ = 0;
145 if (traceOnCount_ > 0) {
146 HIVIEW_LOGW(":%{public}s trace on running count:%{public}d still trace on", GetTag().c_str(), traceOnCount_);
147 return TraceRet(TraceStateCode::NO_TRIGGER);
148 }
149 if (auto ret = ptr->TransToInitState(); !ret.IsSuccess()) {
150 HIVIEW_LOGI("set traceOff fail");
151 return ret;
152 }
153 if (stateMachine_.lock()->stateCallback_ != nullptr) {
154 stateMachine_.lock()->stateCallback_->OnTelemetryTraceOff();
155 }
156 return {};
157 }
158
GetTag()159 std::string TraceOnState::GetTag()
160 {
161 return "TraceOnState";
162 }
163
TransToInitState()164 TraceRet TeleMetryStateMachine::TransToInitState()
165 {
166 auto ret = SetTraceStatus(false);
167 if (ret != TraceErrorCode::SUCCESS) {
168 HIVIEW_LOGE("SetTraceStatus true, result:%{public}d", ret);
169 return TraceRet(ret);
170 }
171 HIVIEW_LOGI("init success");
172 currentState_ = initStateState_;
173 return {};
174 }
175
TransToTraceOnState(uint32_t traceOnCount,uint64_t postEndTime)176 TraceRet TeleMetryStateMachine::TransToTraceOnState(uint32_t traceOnCount, uint64_t postEndTime)
177 {
178 auto ret = Hitrace::SetTraceStatus(true);
179 if (ret != TraceErrorCode::SUCCESS) {
180 HIVIEW_LOGE("SetTraceStatus true, result:%{public}d", ret);
181 return TraceRet(ret);
182 }
183 HIVIEW_LOGI("traceOnCount:%{public}d", traceOnCount);
184 traceOnState_->SetTraceOnCount(traceOnCount);
185 traceOnState_->SetPostEndTime(postEndTime);
186 currentState_ = traceOnState_;
187 return {};
188 }
189 }
190