• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "app_start_filter.h"
17 
18 namespace SysTuning {
19 namespace TraceStreamer {
20 constexpr uint32_t INVAILD_DATA = 2;
21 constexpr uint32_t MIN_VECTOR_SIZE = 2;
22 constexpr uint32_t VAILD_DATA_COUNT = 6;
APPStartupFilter(TraceDataCache * dataCache,const TraceStreamerFilters * filter)23 APPStartupFilter::APPStartupFilter(TraceDataCache* dataCache, const TraceStreamerFilters* filter)
24     : FilterBase(dataCache, filter), mAPPStartupData_(0)
25 {
26 }
27 
28 APPStartupFilter::~APPStartupFilter() = default;
29 
FilterAllAPPStartupData()30 void APPStartupFilter::FilterAllAPPStartupData()
31 {
32     ParserAppStartup();
33     ParserSoInitalization();
34 }
35 
CaclRsDataByPid(appMap & mAPPStartupData)36 bool APPStartupFilter::CaclRsDataByPid(appMap& mAPPStartupData)
37 {
38     auto frameSliceData = traceDataCache_->GetFrameSliceData();
39     auto sliceData = traceDataCache_->GetConstInternalSlicesData();
40     for (const auto& item : mAPPStartupData) {
41         if (item.second.empty()) {
42             continue;
43         }
44         auto itorSecond = item.second.begin();
45         if (itorSecond->second->ipid_ == INVALID_UINT32) {
46             continue;
47         }
48         for (int m = 0; m < frameSliceData->Ipids().size(); m++) {
49             if (itorSecond->second->ipid_ == frameSliceData->Ipids()[m] && !frameSliceData->Types()[m] &&
50                 frameSliceData->Flags()[m] != INVAILD_DATA) {
51                 auto startTime = sliceData.TimeStampData()[frameSliceData->CallStackIds()[m]];
52                 auto callId = sliceData.CallIds()[frameSliceData->CallStackIds()[m]];
53                 auto endTime = startTime + frameSliceData->Durs()[m];
54                 if (frameSliceData->Durs()[m] == INVALID_UINT64) {
55                     endTime = INVALID_UINT64;
56                 }
57                 mAPPStartupData[item.first].emplace(FIRST_FRAME_APP_PHASE,
58                                                     std::make_unique<APPStartupData>(callId, itorSecond->second->ipid_,
59                                                                                      itorSecond->second->tid_,
60                                                                                      startTime, endTime));
61                 auto dstId = frameSliceData->Dsts()[m];
62                 if (dstId == INVALID_UINT64) {
63                     continue;
64                 }
65                 callId = sliceData.CallIds()[frameSliceData->CallStackIds()[dstId]];
66                 startTime = frameSliceData->TimeStampData()[dstId];
67                 endTime = startTime + frameSliceData->Durs()[dstId];
68                 mAPPStartupData[item.first].emplace(FIRST_FRAME_RENDER_PHASE,
69                                                     std::make_unique<APPStartupData>(callId, itorSecond->second->ipid_,
70                                                                                      itorSecond->second->tid_,
71                                                                                      startTime, endTime));
72                 break;
73             }
74         }
75     }
76     return false;
77 }
78 
UpdatePidByNameIndex(const appMap & mAPPStartupData)79 void APPStartupFilter::UpdatePidByNameIndex(const appMap& mAPPStartupData)
80 {
81     auto threadData = traceDataCache_->GetConstThreadData();
82     for (const auto& item : mAPPStartupData) {
83         auto ipid = INVALID_UINT32;
84         auto tid = INVALID_UINT32;
85         if (item.second.count(UI_ABILITY_LAUNCHING)) {
86             ipid = item.second.at(UI_ABILITY_LAUNCHING)->ipid_;
87             tid = item.second.at(UI_ABILITY_LAUNCHING)->tid_;
88         } else {
89             for (int i = 0; i < threadData.size(); ++i) {
90                 if (item.first == threadData[i].nameIndex_) {
91                     ipid = threadData[i].internalPid_;
92                     tid = threadData[i].tid_;
93                 }
94             }
95         }
96         for (const auto& itemSecond : item.second) {
97             itemSecond.second->ipid_ = ipid;
98             itemSecond.second->tid_ = tid;
99         }
100     }
101 }
102 
AppendData(const appMap & mAPPStartupData)103 void APPStartupFilter::AppendData(const appMap& mAPPStartupData)
104 {
105     for (auto itor = mAPPStartupData.begin(); itor != mAPPStartupData.end(); ++itor) {
106         if (!(itor->second).count(UI_ABILITY_LAUNCHING)) {
107             continue;
108         }
109         for (auto itorSecond = itor->second.begin(); itorSecond != itor->second.end(); ++itorSecond) {
110             auto item = itorSecond;
111             auto endTime = INVALID_UINT64;
112             if (item->first < VAILD_DATA_COUNT) {
113                 int num = item->first + 1;
114                 if ((++item) != itor->second.end() && num == item->first) {
115                     endTime = (item)->second->startTime_;
116                 }
117             } else {
118                 endTime = itorSecond->second->endTime_;
119             }
120             traceDataCache_->GetAppStartupData()->AppendNewData(
121                 itorSecond->second->ipid_, itorSecond->second->tid_, itorSecond->second->callid_,
122                 itorSecond->second->startTime_, endTime, itorSecond->first, itor->first);
123         }
124     }
125 }
126 
UpdateAPPStartupData(uint32_t row,const std::string & nameString,uint32_t startIndex)127 bool APPStartupFilter::UpdateAPPStartupData(uint32_t row, const std::string& nameString, uint32_t startIndex)
128 {
129     auto sliceData = traceDataCache_->GetConstInternalSlicesData();
130     auto vNameString = SplitStringToVec(nameString, "##");
131     TS_CHECK_TRUE_RET(vNameString.size() >= MIN_VECTOR_SIZE, false);
132     auto dataIndex = traceDataCache_->GetDataIndex(vNameString[1].c_str());
133     // for update the last Item(valid val)
134     if (!procTouchItems_.empty()) {
135         auto lastProcTouchItem = std::move(procTouchItems_.back());
136         mAPPStartupData_[dataIndex].insert(std::make_pair(PROCESS_TOUCH, std::move(lastProcTouchItem)));
137         procTouchItems_.clear();
138     }
139     if (!startUIAbilityBySCBItems_.empty()) {
140         auto lastStartUIAbilityBySCBItem = std::move(startUIAbilityBySCBItems_.back());
141         mAPPStartupData_[dataIndex].insert(
142             std::make_pair(START_UI_ABILITY_BY_SCB, std::move(lastStartUIAbilityBySCBItem)));
143         startUIAbilityBySCBItems_.clear();
144     }
145     if (!loadAbilityItems_.empty()) {
146         auto lastLoadAbilityItem = std::move(loadAbilityItems_.back());
147         mAPPStartupData_[dataIndex].insert(std::make_pair(LOAD_ABILITY, std::move(lastLoadAbilityItem)));
148         loadAbilityItems_.clear();
149     }
150     auto callId = sliceData.CallIds()[row];
151     auto startTime = sliceData.TimeStampData()[row];
152     mAPPStartupData_[dataIndex].insert(
153         std::make_pair(startIndex, std::make_unique<APPStartupData>(callId, INVALID_UINT32, INVALID_UINT32, startTime,
154                                                                     INVALID_UINT64)));
155     return true;
156 }
157 
ParserAppStartup()158 void APPStartupFilter::ParserAppStartup()
159 {
160     auto sliceData = traceDataCache_->GetConstInternalSlicesData();
161     std::string mainThreadName = "";
162     for (auto i = 0; i < sliceData.NamesData().size(); i++) {
163         auto& nameString = traceDataCache_->GetDataFromDict(sliceData.NamesData()[i]);
164         auto callId = sliceData.CallIds()[i];
165         auto startTime = sliceData.TimeStampData()[i];
166         if (StartWith(nameString, procTouchCmd_)) {
167             procTouchItems_.emplace_back(
168                 std::make_unique<APPStartupData>(callId, INVALID_UINT32, INVALID_UINT32, startTime, INVALID_UINT64));
169         } else if (StartWith(nameString, startUIAbilityBySCBCmd_)) {
170             startUIAbilityBySCBItems_.emplace_back(
171                 std::make_unique<APPStartupData>(callId, INVALID_UINT32, INVALID_UINT32, startTime, INVALID_UINT64));
172         } else if (StartWith(nameString, loadAbilityCmd_)) {
173             loadAbilityItems_.emplace_back(
174                 std::make_unique<APPStartupData>(callId, INVALID_UINT32, INVALID_UINT32, startTime, INVALID_UINT64));
175         } else if (StartWith(nameString, appLaunchCmd_)) {
176             UpdateAPPStartupData(i, nameString, APPLICATION_LAUNCHING);
177         } else if (StartWith(nameString, uiLaunchCmd_)) {
178             if (!ProcAbilityLaunchData(nameString, i)) {
179                 continue;
180             }
181         } else if (StartWith(nameString, uiOnForegroundFirstCmd_) || StartWith(nameString, uiOnForegroundSecCmd_)) {
182             ProcForegroundData(i);
183         }
184     }
185     for (auto& item : mAPPStartupDataWithPid_) {
186         UpdatePidByNameIndex(item.second);
187         CaclRsDataByPid(item.second);
188         AppendData(item.second);
189     }
190     return;
191 }
192 
ProcAbilityLaunchData(const std::string & nameString,uint64_t raw)193 bool APPStartupFilter::ProcAbilityLaunchData(const std::string& nameString, uint64_t raw)
194 {
195     auto sliceData = traceDataCache_->GetConstInternalSlicesData();
196     auto vNameString = SplitStringToVec(nameString, "##");
197     TS_CHECK_TRUE_RET(vNameString.size() >= MIN_VECTOR_SIZE, false);
198     auto dataIndex = traceDataCache_->GetDataIndex(vNameString[1].c_str());
199     uint32_t callId = sliceData.CallIds()[raw];
200     uint64_t startTime = sliceData.TimeStampData()[raw];
201     if (dataIndex == INVALID_DATAINDEX) {
202         return false;
203     }
204     auto thread = traceDataCache_->GetThreadData(sliceData.CallIds()[raw]);
205     thread->nameIndex_ = dataIndex;
206     mAPPStartupData_[dataIndex].insert(std::make_pair(
207         UI_ABILITY_LAUNCHING,
208         std::make_unique<APPStartupData>(callId, thread->internalPid_, thread->tid_, startTime, INVALID_UINT64)));
209     mAPPStartupDataWithPid_.insert(std::make_pair(thread->internalPid_, std::move(mAPPStartupData_)));
210     return true;
211 }
212 
ProcForegroundData(uint64_t raw)213 void APPStartupFilter::ProcForegroundData(uint64_t raw)
214 {
215     auto sliceData = traceDataCache_->GetConstInternalSlicesData();
216     uint32_t callId = sliceData.CallIds()[raw];
217     uint64_t startTime = sliceData.TimeStampData()[raw];
218     auto threadData = traceDataCache_->GetConstThreadData();
219     // callid is thread table->itid
220     auto nameindex = threadData[callId].nameIndex_;
221     auto ipid = threadData[callId].internalPid_;
222     auto tid = threadData[callId].tid_;
223     if (mAPPStartupDataWithPid_.count(ipid) && mAPPStartupDataWithPid_[ipid].count(nameindex) &&
224         !mAPPStartupDataWithPid_[ipid][nameindex].count(UI_ABILITY_ONFOREGROUND)) {
225         mAPPStartupDataWithPid_[ipid][nameindex].insert(std::make_pair(
226             UI_ABILITY_ONFOREGROUND, std::make_unique<APPStartupData>(callId, ipid, tid, startTime, INVALID_UINT64)));
227     }
228 }
229 
CalcDepthByTimeStamp(std::map<uint32_t,std::map<uint64_t,uint32_t>>::iterator it,uint32_t & depth,uint64_t endTime,uint64_t startTime)230 void APPStartupFilter::CalcDepthByTimeStamp(std::map<uint32_t, std::map<uint64_t, uint32_t>>::iterator it,
231                                             uint32_t& depth,
232                                             uint64_t endTime,
233                                             uint64_t startTime)
234 {
235     if (!it->second.empty()) {
236         auto itor = it->second.begin();
237         if (itor->first > startTime) {
238             depth = it->second.size();
239             it->second.insert(std::make_pair(endTime, it->second.size()));
240         } else {
241             depth = itor->second;
242             for (auto itorSecond = itor; itorSecond != it->second.end(); ++itorSecond) {
243                 if (itorSecond->first < startTime && depth > itorSecond->second) {
244                     depth = itorSecond->second;
245                     itor = itorSecond;
246                 }
247             }
248             it->second.erase(itor);
249             it->second.insert(std::make_pair(endTime, depth));
250         }
251     } else {
252         it->second.insert(std::make_pair(endTime, 0));
253     }
254 }
255 
ParserSoInitalization()256 void APPStartupFilter::ParserSoInitalization()
257 {
258     std::map<uint32_t, std::map<uint64_t, uint32_t>> mMaxTimeAndDepthWithPid;
259     auto sliceData = traceDataCache_->GetConstInternalSlicesData();
260     auto threadData = traceDataCache_->GetConstThreadData();
261     std::string nameString = "";
262     for (auto i = 0; i < sliceData.NamesData().size(); i++) {
263         nameString = traceDataCache_->GetDataFromDict(sliceData.NamesData()[i]);
264         if (nameString.find(dlopenCmd_) != std::string::npos) {
265             uint64_t startTime = sliceData.TimeStampData()[i];
266             uint64_t endTime = startTime + sliceData.DursData()[i];
267             uint32_t depth = 0;
268             auto callId = sliceData.CallIds()[i];
269             auto pid = threadData[callId].internalPid_;
270             auto tid = threadData[callId].tid_;
271             auto it = mMaxTimeAndDepthWithPid.find(pid);
272             if (it == mMaxTimeAndDepthWithPid.end()) {
273                 mMaxTimeAndDepthWithPid.insert(std::make_pair(pid, std::map<uint64_t, uint32_t>{{endTime, 0}}));
274                 traceDataCache_->GetSoStaticInitalizationData()->AppendNewData(pid, tid, callId, startTime, endTime,
275                                                                                sliceData.NamesData()[i], depth);
276                 continue;
277             } else {
278                 CalcDepthByTimeStamp(it, depth, endTime, startTime);
279                 traceDataCache_->GetSoStaticInitalizationData()->AppendNewData(
280                     threadData[callId].internalPid_, threadData[callId].tid_, callId, startTime, endTime,
281                     sliceData.NamesData()[i], depth);
282             }
283         }
284     }
285 }
286 } // namespace TraceStreamer
287 } // namespace SysTuning
288