• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "pixelstats: BrownoutDetected"
18 
19 #include <aidl/android/frameworks/stats/IStats.h>
20 #include <android-base/file.h>
21 #include <android-base/parseint.h>
22 #include <android-base/properties.h>
23 #include <android-base/stringprintf.h>
24 #include <android-base/strings.h>
25 #include <android/binder_manager.h>
26 #include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
27 #include <pixelstats/BrownoutDetectedReporter.h>
28 #include <time.h>
29 #include <utils/Log.h>
30 
31 #include <map>
32 #include <regex>
33 
34 namespace android {
35 namespace hardware {
36 namespace google {
37 namespace pixel {
38 
39 using aidl::android::frameworks::stats::IStats;
40 using aidl::android::frameworks::stats::VendorAtom;
41 using aidl::android::frameworks::stats::VendorAtomValue;
42 using android::base::ReadFileToString;
43 using android::hardware::google::pixel::PixelAtoms::BrownoutDetected;
44 
45 #define READING_IDX 2
46 #define KEY_IDX 0
47 #define DEFAULT_BATTERY_TEMP 9999999
48 #define DEFAULT_BATTERY_SOC 100
49 #define DEFAULT_BATTERY_VOLT 5000000
50 #define ONE_SECOND_IN_US 1000000
51 
52 const std::regex kTimestampPattern("^\\S+\\s[0-9]+:[0-9]+:[0-9]+\\S+$");
53 const std::regex kIrqPattern("^(\\S+)\\striggered\\sat\\s\\S+$");
54 const std::regex kOdpmPattern("^CH\\d+\\[(\\S+)\\],\\s(\\d+)$");
55 const std::regex kDvfsPattern("^([A-Z1-9]+):(\\d+)$");
56 const std::regex kFgPattern("^(voltage_now):(\\d+)$");
57 const std::regex kBatteryTempPattern("^(battery):(\\d+)$");
58 const std::regex kBatteryCyclePattern("^(battery_cycle):(\\d+)$");
59 const std::regex kBatterySocPattern("^(soc):(\\d+)$");
60 const std::regex kAlreadyUpdatedPattern("^(LASTMEAL_UPDATED)$");
61 
62 const std::map<std::string, int> kBrownoutReason = {{"uvlo,pmic,if", BrownoutDetected::UVLO_IF},
63                                                     {"ocp,pmic,if", BrownoutDetected::OCP_IF},
64                                                     {"ocp2,pmic,if", BrownoutDetected::OCP2_IF},
65                                                     {"uvlo,pmic,main", BrownoutDetected::UVLO_MAIN},
66                                                     {"uvlo,pmic,sub", BrownoutDetected::UVLO_SUB},
67                                                     {"ocp,buck1m", BrownoutDetected::OCP_B1M},
68                                                     {"ocp,buck2m", BrownoutDetected::OCP_B2M},
69                                                     {"ocp,buck3m", BrownoutDetected::OCP_B3M},
70                                                     {"ocp,buck4m", BrownoutDetected::OCP_B4M},
71                                                     {"ocp,buck5m", BrownoutDetected::OCP_B5M},
72                                                     {"ocp,buck6m", BrownoutDetected::OCP_B6M},
73                                                     {"ocp,buck7m", BrownoutDetected::OCP_B7M},
74                                                     {"ocp,buck8m", BrownoutDetected::OCP_B8M},
75                                                     {"ocp,buck9m", BrownoutDetected::OCP_B9M},
76                                                     {"ocp,buck10m", BrownoutDetected::OCP_B10M},
77                                                     {"ocp,buck1s", BrownoutDetected::OCP_B1S},
78                                                     {"ocp,buck2s", BrownoutDetected::OCP_B2S},
79                                                     {"ocp,buck3s", BrownoutDetected::OCP_B3S},
80                                                     {"ocp,buck4s", BrownoutDetected::OCP_B4S},
81                                                     {"ocp,buck5s", BrownoutDetected::OCP_B5S},
82                                                     {"ocp,buck6s", BrownoutDetected::OCP_B6S},
83                                                     {"ocp,buck7s", BrownoutDetected::OCP_B7S},
84                                                     {"ocp,buck8s", BrownoutDetected::OCP_B8S},
85                                                     {"ocp,buck9s", BrownoutDetected::OCP_B9S},
86                                                     {"ocp,buck10s", BrownoutDetected::OCP_B10S},
87                                                     {"ocp,buckas", BrownoutDetected::OCP_BAS},
88                                                     {"ocp,buckbs", BrownoutDetected::OCP_BBS},
89                                                     {"ocp,buckcs", BrownoutDetected::OCP_BCS},
90                                                     {"ocp,buckds", BrownoutDetected::OCP_BDS}};
91 
updateIfFound(std::string line,std::regex pattern,int * current_value,Update flag)92 bool BrownoutDetectedReporter::updateIfFound(std::string line, std::regex pattern,
93                                              int *current_value, Update flag) {
94     bool found = false;
95     std::smatch pattern_match;
96     if (std::regex_match(line, pattern_match, pattern)) {
97         if (pattern_match.size() < (READING_IDX + 1)) {
98             return found;
99         }
100         found = true;
101         int reading = std::stoi(pattern_match[READING_IDX].str());
102         if (flag == kUpdateMax) {
103             if (*current_value < reading) {
104                 *current_value = reading;
105             }
106         } else {
107             if (*current_value > reading) {
108                 *current_value = reading;
109             }
110         }
111     }
112     return found;
113 }
114 
setAtomFieldValue(std::vector<VendorAtomValue> & values,int offset,int content)115 void BrownoutDetectedReporter::setAtomFieldValue(std::vector<VendorAtomValue> &values, int offset,
116                                                  int content) {
117     if (offset - kVendorAtomOffset < values.size()) {
118         ALOGW("VendorAtomValue size is smaller than offset");
119         values[offset - kVendorAtomOffset].set<VendorAtomValue::intValue>(content);
120     }
121 }
122 
uploadData(const std::shared_ptr<IStats> & stats_client,const struct BrownoutDetectedInfo max_value)123 void BrownoutDetectedReporter::uploadData(const std::shared_ptr<IStats> &stats_client,
124                                           const struct BrownoutDetectedInfo max_value) {
125     // Load values array
126     VendorAtomValue tmp;
127     std::vector<VendorAtomValue> values(90);
128     setAtomFieldValue(values, BrownoutDetected::kTriggeredIrqFieldNumber, max_value.triggered_irq_);
129     setAtomFieldValue(values, BrownoutDetected::kTriggeredTimestampFieldNumber,
130                       max_value.triggered_timestamp_);
131     setAtomFieldValue(values, BrownoutDetected::kBatteryTempFieldNumber, max_value.battery_temp_);
132     setAtomFieldValue(values, BrownoutDetected::kBatterySocFieldNumber,
133                       100 - max_value.battery_soc_);
134     setAtomFieldValue(values, BrownoutDetected::kBatteryCycleFieldNumber, max_value.battery_cycle_);
135     setAtomFieldValue(values, BrownoutDetected::kVoltageNowFieldNumber, max_value.voltage_now_);
136 
137     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel01FieldNumber,
138                       max_value.odpm_value_[0]);
139     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel02FieldNumber,
140                       max_value.odpm_value_[1]);
141     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel03FieldNumber,
142                       max_value.odpm_value_[2]);
143     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel04FieldNumber,
144                       max_value.odpm_value_[3]);
145     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel05FieldNumber,
146                       max_value.odpm_value_[4]);
147     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel06FieldNumber,
148                       max_value.odpm_value_[5]);
149     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel07FieldNumber,
150                       max_value.odpm_value_[6]);
151     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel08FieldNumber,
152                       max_value.odpm_value_[7]);
153     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel09FieldNumber,
154                       max_value.odpm_value_[8]);
155     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel10FieldNumber,
156                       max_value.odpm_value_[9]);
157     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel11FieldNumber,
158                       max_value.odpm_value_[10]);
159     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel12FieldNumber,
160                       max_value.odpm_value_[11]);
161     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel13FieldNumber,
162                       max_value.odpm_value_[12]);
163     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel14FieldNumber,
164                       max_value.odpm_value_[13]);
165     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel15FieldNumber,
166                       max_value.odpm_value_[14]);
167     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel16FieldNumber,
168                       max_value.odpm_value_[15]);
169     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel17FieldNumber,
170                       max_value.odpm_value_[16]);
171     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel18FieldNumber,
172                       max_value.odpm_value_[17]);
173     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel19FieldNumber,
174                       max_value.odpm_value_[18]);
175     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel20FieldNumber,
176                       max_value.odpm_value_[19]);
177     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel21FieldNumber,
178                       max_value.odpm_value_[20]);
179     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel22FieldNumber,
180                       max_value.odpm_value_[21]);
181     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel23FieldNumber,
182                       max_value.odpm_value_[22]);
183     setAtomFieldValue(values, BrownoutDetected::kOdpmChannel24FieldNumber,
184                       max_value.odpm_value_[23]);
185 
186     setAtomFieldValue(values, BrownoutDetected::kDvfsChannel1FieldNumber, max_value.dvfs_value_[0]);
187     setAtomFieldValue(values, BrownoutDetected::kDvfsChannel2FieldNumber, max_value.dvfs_value_[1]);
188     setAtomFieldValue(values, BrownoutDetected::kDvfsChannel3FieldNumber, max_value.dvfs_value_[2]);
189     setAtomFieldValue(values, BrownoutDetected::kDvfsChannel4FieldNumber, max_value.dvfs_value_[3]);
190     setAtomFieldValue(values, BrownoutDetected::kDvfsChannel5FieldNumber, max_value.dvfs_value_[4]);
191     setAtomFieldValue(values, BrownoutDetected::kDvfsChannel6FieldNumber, max_value.dvfs_value_[5]);
192     setAtomFieldValue(values, BrownoutDetected::kBrownoutReasonFieldNumber,
193                       max_value.brownout_reason_);
194 
195     setAtomFieldValue(values, BrownoutDetected::kMaxCurrentFieldNumber, max_value.max_curr_);
196     setAtomFieldValue(values, BrownoutDetected::kEvtCntUvlo1FieldNumber, max_value.evt_cnt_uvlo1_);
197     setAtomFieldValue(values, BrownoutDetected::kEvtCntUvlo2FieldNumber, max_value.evt_cnt_uvlo2_);
198     setAtomFieldValue(values, BrownoutDetected::kEvtCntOilo1FieldNumber, max_value.evt_cnt_oilo1_);
199     setAtomFieldValue(values, BrownoutDetected::kEvtCntOilo2FieldNumber, max_value.evt_cnt_oilo2_);
200     setAtomFieldValue(values, BrownoutDetected::kVimonVbattFieldNumber, max_value.vimon_vbatt_);
201     setAtomFieldValue(values, BrownoutDetected::kVimonIbattFieldNumber, max_value.vimon_ibatt_);
202 
203     setAtomFieldValue(values, BrownoutDetected::kMitigationMethod0FieldNumber,
204                       max_value.mitigation_method_0_);
205     setAtomFieldValue(values, BrownoutDetected::kMitigationMethod0CountFieldNumber,
206                       max_value.mitigation_method_0_count_);
207     setAtomFieldValue(values, BrownoutDetected::kMitigationMethod0TimeUsFieldNumber,
208                       max_value.mitigation_method_0_time_us_);
209 
210     setAtomFieldValue(values, BrownoutDetected::kPreOcpCpu1BckupFieldNumber,
211                       max_value.pre_ocp_cpu1_bckup_);
212     setAtomFieldValue(values, BrownoutDetected::kPreOcpCpu2BckupFieldNumber,
213                       max_value.pre_ocp_cpu2_bckup_);
214     setAtomFieldValue(values, BrownoutDetected::kPreOcpTpuBckupFieldNumber,
215                       max_value.pre_ocp_tpu_bckup_);
216     setAtomFieldValue(values, BrownoutDetected::kPreOcpGpuBckupFieldNumber,
217                       max_value.pre_ocp_gpu_bckup_);
218     setAtomFieldValue(values, BrownoutDetected::kPreUvloHitCntMFieldNumber,
219                       max_value.pre_uvlo_hit_cnt_m_);
220     setAtomFieldValue(values, BrownoutDetected::kPreUvloHitCntSFieldNumber,
221                       max_value.pre_uvlo_hit_cnt_s_);
222     setAtomFieldValue(values, BrownoutDetected::kPreUvloDurFieldNumber, max_value.uvlo_dur_);
223 
224     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat0SysEvtMainBckupFieldNumber,
225                       max_value.odpm_irq_stat_0_sys_evt_main_bckup_);
226     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat1SysEvtMainBckupFieldNumber,
227                       max_value.odpm_irq_stat_1_sys_evt_main_bckup_);
228     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat2SysEvtMainBckupFieldNumber,
229                       max_value.odpm_irq_stat_2_sys_evt_main_bckup_);
230     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat3SysEvtMainBckupFieldNumber,
231                       max_value.odpm_irq_stat_3_sys_evt_main_bckup_);
232     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat4SysEvtMainBckupFieldNumber,
233                       max_value.odpm_irq_stat_4_sys_evt_main_bckup_);
234     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat5SysEvtMainBckupFieldNumber,
235                       max_value.odpm_irq_stat_5_sys_evt_main_bckup_);
236     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat6SysEvtMainBckupFieldNumber,
237                       max_value.odpm_irq_stat_6_sys_evt_main_bckup_);
238     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat7SysEvtMainBckupFieldNumber,
239                       max_value.odpm_irq_stat_7_sys_evt_main_bckup_);
240     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat8SysEvtMainBckupFieldNumber,
241                       max_value.odpm_irq_stat_8_sys_evt_main_bckup_);
242     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat9SysEvtMainBckupFieldNumber,
243                       max_value.odpm_irq_stat_9_sys_evt_main_bckup_);
244     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat10SysEvtMainBckupFieldNumber,
245                       max_value.odpm_irq_stat_10_sys_evt_main_bckup_);
246     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat11SysEvtMainBckupFieldNumber,
247                       max_value.odpm_irq_stat_11_sys_evt_main_bckup_);
248 
249     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat0SysEvtSubBckupFieldNumber,
250                       max_value.odpm_irq_stat_0_sys_evt_sub_bckup_);
251     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat1SysEvtSubBckupFieldNumber,
252                       max_value.odpm_irq_stat_1_sys_evt_sub_bckup_);
253     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat2SysEvtSubBckupFieldNumber,
254                       max_value.odpm_irq_stat_2_sys_evt_sub_bckup_);
255     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat3SysEvtSubBckupFieldNumber,
256                       max_value.odpm_irq_stat_3_sys_evt_sub_bckup_);
257     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat4SysEvtSubBckupFieldNumber,
258                       max_value.odpm_irq_stat_4_sys_evt_sub_bckup_);
259     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat5SysEvtSubBckupFieldNumber,
260                       max_value.odpm_irq_stat_5_sys_evt_sub_bckup_);
261     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat6SysEvtSubBckupFieldNumber,
262                       max_value.odpm_irq_stat_6_sys_evt_sub_bckup_);
263     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat7SysEvtSubBckupFieldNumber,
264                       max_value.odpm_irq_stat_7_sys_evt_sub_bckup_);
265     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat8SysEvtSubBckupFieldNumber,
266                       max_value.odpm_irq_stat_8_sys_evt_sub_bckup_);
267     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat9SysEvtSubBckupFieldNumber,
268                       max_value.odpm_irq_stat_9_sys_evt_sub_bckup_);
269     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat10SysEvtSubBckupFieldNumber,
270                       max_value.odpm_irq_stat_10_sys_evt_sub_bckup_);
271     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStat11SysEvtSubBckupFieldNumber,
272                       max_value.odpm_irq_stat_11_sys_evt_sub_bckup_);
273 
274     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStatExt0SysEvtMainBckupFieldNumber,
275                       max_value.odpm_irq_stat_ext_0_sys_evt_main_bckup_);
276     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStatExt1SysEvtMainBckupFieldNumber,
277                       max_value.odpm_irq_stat_ext_1_sys_evt_main_bckup_);
278     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStatExt2SysEvtMainBckupFieldNumber,
279                       max_value.odpm_irq_stat_ext_2_sys_evt_main_bckup_);
280     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStatExt3SysEvtMainBckupFieldNumber,
281                       max_value.odpm_irq_stat_ext_3_sys_evt_main_bckup_);
282 
283     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStatExt0SysEvtSubBckupFieldNumber,
284                       max_value.odpm_irq_stat_ext_0_sys_evt_sub_bckup_);
285     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStatExt1SysEvtSubBckupFieldNumber,
286                       max_value.odpm_irq_stat_ext_1_sys_evt_sub_bckup_);
287     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStatExt2SysEvtSubBckupFieldNumber,
288                       max_value.odpm_irq_stat_ext_2_sys_evt_sub_bckup_);
289     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStatExt3SysEvtSubBckupFieldNumber,
290                       max_value.odpm_irq_stat_ext_3_sys_evt_sub_bckup_);
291 
292     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStatGpuBckupFieldNumber,
293                       max_value.odpm_irq_stat_gpu_bckup_);
294     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStatTpuBckupFieldNumber,
295                       max_value.odpm_irq_stat_tpu_bckup_);
296     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStatCpu1BckupFieldNumber,
297                       max_value.odpm_irq_stat_cpu1_bckup_);
298     setAtomFieldValue(values, BrownoutDetected::kOdpmIrqStatCpu2BckupFieldNumber,
299                       max_value.odpm_irq_stat_cpu2_bckup_);
300 
301     // Send vendor atom to IStats HAL
302     VendorAtom event = {.reverseDomainName = "",
303                         .atomId = PixelAtoms::Atom::kBrownoutDetected,
304                         .values = std::move(values)};
305     const ndk::ScopedAStatus ret = stats_client->reportVendorAtom(event);
306     if (!ret.isOk())
307         ALOGE("Unable to report ChargeStats to Stats service");
308 }
309 
parseTimestamp(std::string timestamp)310 long BrownoutDetectedReporter::parseTimestamp(std::string timestamp) {
311     struct tm triggeredTimestamp = {};
312     std::string timestampFormat = "%Y-%m-%d %H:%M:%S";
313     if (strptime(timestamp.substr(0, 19).c_str(), timestampFormat.c_str(), &triggeredTimestamp)) {
314         auto logFileTime = std::chrono::system_clock::from_time_t(mktime(&triggeredTimestamp));
315         return logFileTime.time_since_epoch().count() / ONE_SECOND_IN_US;
316     }
317     return 0;
318 }
319 
brownoutReasonCheck(const std::string & brownoutReasonProp)320 int BrownoutDetectedReporter::brownoutReasonCheck(const std::string &brownoutReasonProp) {
321     std::string reason = android::base::GetProperty(brownoutReasonProp.c_str(), "");
322     if (reason.empty()) {
323         // Brownout not found
324         return -1;
325     }
326     auto key = kBrownoutReason.find(reason);
327     if (key == kBrownoutReason.end()) {
328         return -1;
329     }
330     return key->second;
331 }
332 
parseIRQ(const std::string & element)333 int parseIRQ(const std::string &element) {
334     int idx = atoi(element.c_str());
335     if (idx == SMPL_WARN) {
336         return BrownoutDetected::SMPL_WARN;
337     } else if (idx == UVLO1) {
338         return BrownoutDetected::UVLO1;
339     } else if (idx == UVLO2) {
340         return BrownoutDetected::UVLO2;
341     } else if (idx == BATOILO) {
342         return BrownoutDetected::BATOILO;
343     } else if (idx == BATOILO2) {
344         return BrownoutDetected::BATOILO2;
345     }
346     return -1;
347 }
348 
logBrownoutCsv(const std::shared_ptr<IStats> & stats_client,const std::string & CsvFilePath,const std::string & brownoutReasonProp)349 void BrownoutDetectedReporter::logBrownoutCsv(const std::shared_ptr<IStats> &stats_client,
350                                               const std::string &CsvFilePath,
351                                               const std::string &brownoutReasonProp) {
352     std::string csvFile;
353     if (!android::base::ReadFileToString(CsvFilePath, &csvFile)) {
354         return;
355     }
356     std::istringstream content(csvFile);
357     std::string line;
358     struct BrownoutDetectedInfo max_value = {};
359     max_value.voltage_now_ = DEFAULT_BATTERY_VOLT;
360     max_value.battery_soc_ = DEFAULT_BATTERY_SOC;
361     max_value.battery_temp_ = DEFAULT_BATTERY_TEMP;
362     std::smatch pattern_match;
363     max_value.brownout_reason_ = brownoutReasonCheck(brownoutReasonProp);
364     if (max_value.brownout_reason_ < 0) {
365         return;
366     }
367     bool isAlreadyUpdated = false;
368     std::vector<std::vector<std::string>> rows;
369     int row_num = 0;
370     while (std::getline(content, line)) {
371         if (std::regex_match(line, pattern_match, kAlreadyUpdatedPattern)) {
372             isAlreadyUpdated = true;
373             break;
374         }
375         row_num++;
376         if (row_num == 1) {
377             continue;
378         }
379         std::vector<std::string> row;
380         std::stringstream ss(line);
381         std::string field;
382         while (getline(ss, field, ',')) {
383             row.push_back(field);
384         }
385 
386         max_value.triggered_timestamp_ = parseTimestamp(row[TIMESTAMP_IDX].c_str());
387         max_value.triggered_irq_ = parseIRQ(row[IRQ_IDX]);
388         max_value.battery_soc_ = atoi(row[SOC_IDX].c_str());
389         max_value.battery_temp_ = atoi(row[TEMP_IDX].c_str());
390         max_value.battery_cycle_ = atoi(row[CYCLE_IDX].c_str());
391         max_value.voltage_now_ = atoi(row[VOLTAGE_IDX].c_str());
392         for (int i = 0; i < DVFS_MAX_IDX; i++) {
393             max_value.dvfs_value_[i] = atoi(row[i + DVFS_CHANNEL_0].c_str());
394         }
395         for (int i = 0; i < ODPM_MAX_IDX; i++) {
396             max_value.odpm_value_[i] = atoi(row[i + ODPM_CHANNEL_0].c_str());
397         }
398         if (row.size() > MITIGATION_METHOD_0_TIME) {
399             max_value.mitigation_method_0_ = atoi(row[MITIGATION_METHOD_0].c_str());
400             max_value.mitigation_method_0_count_ = atoi(row[MITIGATION_METHOD_0_COUNT].c_str());
401             max_value.mitigation_method_0_time_us_ = atoi(row[MITIGATION_METHOD_0_TIME].c_str());
402         }
403         if (row.size() > MAX_CURR) {
404             max_value.evt_cnt_oilo1_ = atoi(row[EVT_CNT_IDX_OILO1].c_str());
405             max_value.evt_cnt_oilo2_ = atoi(row[EVT_CNT_IDX_OILO2].c_str());
406             max_value.evt_cnt_uvlo1_ = atoi(row[EVT_CNT_IDX_UVLO1].c_str());
407             max_value.evt_cnt_uvlo2_ = atoi(row[EVT_CNT_IDX_UVLO2].c_str());
408             max_value.max_curr_ = atoi(row[MAX_CURR].c_str());
409         }
410         if (row.size() > IDX_VIMON_I) {
411             max_value.vimon_vbatt_ = atoi(row[IDX_VIMON_V].c_str());
412             max_value.vimon_ibatt_ = atoi(row[IDX_VIMON_I].c_str());
413         }
414         if (row.size() > UVLO_DUR_IDX) {
415             max_value.pre_ocp_cpu1_bckup_ = atoi(row[PRE_OCP_CPU1_BCKUP_IDX].c_str());
416             max_value.pre_ocp_cpu2_bckup_ = atoi(row[PRE_OCP_CPU2_BCKUP_IDX].c_str());
417             max_value.pre_ocp_tpu_bckup_ = atoi(row[PRE_OCP_TPU_BCKUP_IDX].c_str());
418             max_value.pre_ocp_gpu_bckup_ = atoi(row[PRE_OCP_GPU_BCKUP_IDX].c_str());
419             max_value.pre_uvlo_hit_cnt_m_ = atoi(row[PRE_UVLO_HIT_CNT_M_IDX].c_str());
420             max_value.pre_uvlo_hit_cnt_s_ = atoi(row[PRE_UVLO_HIT_CNT_S_IDX].c_str());
421             max_value.uvlo_dur_ = atoi(row[UVLO_DUR_IDX].c_str());
422         }
423         if (row.size() > ODPM_IRQ_STAT_CPU2_BCKUP_IDX) {
424             max_value.pre_ocp_cpu1_bckup_ = atoi(row[PRE_OCP_CPU1_BCKUP_IDX].c_str());
425             max_value.pre_ocp_cpu2_bckup_ = atoi(row[PRE_OCP_CPU2_BCKUP_IDX].c_str());
426 
427             max_value.odpm_irq_stat_0_sys_evt_main_bckup_ =
428                     atoi(row[ODPM_IRQ_STAT_0_SYS_EVT_MAIN_BCKUP_IDX].c_str());
429             max_value.odpm_irq_stat_1_sys_evt_main_bckup_ =
430                     atoi(row[ODPM_IRQ_STAT_1_SYS_EVT_MAIN_BCKUP_IDX].c_str());
431             max_value.odpm_irq_stat_2_sys_evt_main_bckup_ =
432                     atoi(row[ODPM_IRQ_STAT_2_SYS_EVT_MAIN_BCKUP_IDX].c_str());
433             max_value.odpm_irq_stat_3_sys_evt_main_bckup_ =
434                     atoi(row[ODPM_IRQ_STAT_3_SYS_EVT_MAIN_BCKUP_IDX].c_str());
435             max_value.odpm_irq_stat_4_sys_evt_main_bckup_ =
436                     atoi(row[ODPM_IRQ_STAT_4_SYS_EVT_MAIN_BCKUP_IDX].c_str());
437             max_value.odpm_irq_stat_5_sys_evt_main_bckup_ =
438                     atoi(row[ODPM_IRQ_STAT_5_SYS_EVT_MAIN_BCKUP_IDX].c_str());
439             max_value.odpm_irq_stat_6_sys_evt_main_bckup_ =
440                     atoi(row[ODPM_IRQ_STAT_6_SYS_EVT_MAIN_BCKUP_IDX].c_str());
441             max_value.odpm_irq_stat_7_sys_evt_main_bckup_ =
442                     atoi(row[ODPM_IRQ_STAT_7_SYS_EVT_MAIN_BCKUP_IDX].c_str());
443             max_value.odpm_irq_stat_8_sys_evt_main_bckup_ =
444                     atoi(row[ODPM_IRQ_STAT_8_SYS_EVT_MAIN_BCKUP_IDX].c_str());
445             max_value.odpm_irq_stat_9_sys_evt_main_bckup_ =
446                     atoi(row[ODPM_IRQ_STAT_9_SYS_EVT_MAIN_BCKUP_IDX].c_str());
447             max_value.odpm_irq_stat_10_sys_evt_main_bckup_ =
448                     atoi(row[ODPM_IRQ_STAT_10_SYS_EVT_MAIN_BCKUP_IDX].c_str());
449             max_value.odpm_irq_stat_11_sys_evt_main_bckup_ =
450                     atoi(row[ODPM_IRQ_STAT_11_SYS_EVT_MAIN_BCKUP_IDX].c_str());
451 
452             max_value.odpm_irq_stat_0_sys_evt_sub_bckup_ =
453                     atoi(row[ODPM_IRQ_STAT_0_SYS_EVT_SUB_BCKUP_IDX].c_str());
454             max_value.odpm_irq_stat_1_sys_evt_sub_bckup_ =
455                     atoi(row[ODPM_IRQ_STAT_1_SYS_EVT_SUB_BCKUP_IDX].c_str());
456             max_value.odpm_irq_stat_2_sys_evt_sub_bckup_ =
457                     atoi(row[ODPM_IRQ_STAT_2_SYS_EVT_SUB_BCKUP_IDX].c_str());
458             max_value.odpm_irq_stat_3_sys_evt_sub_bckup_ =
459                     atoi(row[ODPM_IRQ_STAT_3_SYS_EVT_SUB_BCKUP_IDX].c_str());
460             max_value.odpm_irq_stat_4_sys_evt_sub_bckup_ =
461                     atoi(row[ODPM_IRQ_STAT_4_SYS_EVT_SUB_BCKUP_IDX].c_str());
462             max_value.odpm_irq_stat_5_sys_evt_sub_bckup_ =
463                     atoi(row[ODPM_IRQ_STAT_5_SYS_EVT_SUB_BCKUP_IDX].c_str());
464             max_value.odpm_irq_stat_6_sys_evt_sub_bckup_ =
465                     atoi(row[ODPM_IRQ_STAT_6_SYS_EVT_SUB_BCKUP_IDX].c_str());
466             max_value.odpm_irq_stat_7_sys_evt_sub_bckup_ =
467                     atoi(row[ODPM_IRQ_STAT_7_SYS_EVT_SUB_BCKUP_IDX].c_str());
468             max_value.odpm_irq_stat_8_sys_evt_sub_bckup_ =
469                     atoi(row[ODPM_IRQ_STAT_8_SYS_EVT_SUB_BCKUP_IDX].c_str());
470             max_value.odpm_irq_stat_9_sys_evt_sub_bckup_ =
471                     atoi(row[ODPM_IRQ_STAT_9_SYS_EVT_SUB_BCKUP_IDX].c_str());
472             max_value.odpm_irq_stat_10_sys_evt_sub_bckup_ =
473                     atoi(row[ODPM_IRQ_STAT_10_SYS_EVT_SUB_BCKUP_IDX].c_str());
474             max_value.odpm_irq_stat_11_sys_evt_sub_bckup_ =
475                     atoi(row[ODPM_IRQ_STAT_11_SYS_EVT_SUB_BCKUP_IDX].c_str());
476 
477             max_value.odpm_irq_stat_ext_0_sys_evt_main_bckup_ =
478                     atoi(row[ODPM_IRQ_STAT_EXT_0_SYS_EVT_MAIN_BCKUP_IDX].c_str());
479             max_value.odpm_irq_stat_ext_1_sys_evt_main_bckup_ =
480                     atoi(row[ODPM_IRQ_STAT_EXT_1_SYS_EVT_MAIN_BCKUP_IDX].c_str());
481             max_value.odpm_irq_stat_ext_2_sys_evt_main_bckup_ =
482                     atoi(row[ODPM_IRQ_STAT_EXT_2_SYS_EVT_MAIN_BCKUP_IDX].c_str());
483             max_value.odpm_irq_stat_ext_3_sys_evt_main_bckup_ =
484                     atoi(row[ODPM_IRQ_STAT_EXT_3_SYS_EVT_MAIN_BCKUP_IDX].c_str());
485 
486             max_value.odpm_irq_stat_ext_0_sys_evt_sub_bckup_ =
487                     atoi(row[ODPM_IRQ_STAT_EXT_0_SYS_EVT_SUB_BCKUP_IDX].c_str());
488             max_value.odpm_irq_stat_ext_1_sys_evt_sub_bckup_ =
489                     atoi(row[ODPM_IRQ_STAT_EXT_1_SYS_EVT_SUB_BCKUP_IDX].c_str());
490             max_value.odpm_irq_stat_ext_2_sys_evt_sub_bckup_ =
491                     atoi(row[ODPM_IRQ_STAT_EXT_2_SYS_EVT_SUB_BCKUP_IDX].c_str());
492             max_value.odpm_irq_stat_ext_3_sys_evt_sub_bckup_ =
493                     atoi(row[ODPM_IRQ_STAT_EXT_3_SYS_EVT_SUB_BCKUP_IDX].c_str());
494         }
495     }
496     if (!isAlreadyUpdated && max_value.battery_temp_ != DEFAULT_BATTERY_TEMP) {
497         std::string file_content = "LASTMEAL_UPDATED\n" + csvFile;
498         android::base::WriteStringToFile(file_content, CsvFilePath);
499         uploadData(stats_client, max_value);
500     }
501 }
502 
logBrownout(const std::shared_ptr<IStats> & stats_client,const std::string & logFilePath,const std::string & brownoutReasonProp)503 void BrownoutDetectedReporter::logBrownout(const std::shared_ptr<IStats> &stats_client,
504                                            const std::string &logFilePath,
505                                            const std::string &brownoutReasonProp) {
506     std::string logFile;
507     if (!android::base::ReadFileToString(logFilePath, &logFile)) {
508         return;
509     }
510     std::istringstream content(logFile);
511     std::string line;
512     struct BrownoutDetectedInfo max_value = {};
513     max_value.voltage_now_ = DEFAULT_BATTERY_VOLT;
514     max_value.battery_soc_ = DEFAULT_BATTERY_SOC;
515     max_value.battery_temp_ = DEFAULT_BATTERY_TEMP;
516     std::smatch pattern_match;
517     int odpm_index = 0, dvfs_index = 0;
518     max_value.brownout_reason_ = brownoutReasonCheck(brownoutReasonProp);
519     if (max_value.brownout_reason_ < 0) {
520         return;
521     }
522     bool isAlreadyUpdated = false;
523     while (std::getline(content, line)) {
524         if (std::regex_match(line, pattern_match, kAlreadyUpdatedPattern)) {
525             isAlreadyUpdated = true;
526             break;
527         }
528         if (std::regex_match(line, pattern_match, kIrqPattern)) {
529             if (pattern_match.size() < (KEY_IDX + 1)) {
530                 return;
531             }
532             std::ssub_match irq = pattern_match[KEY_IDX];
533             if (irq.str().find("batoilo") != std::string::npos) {
534                 max_value.triggered_irq_ = BrownoutDetected::BATOILO;
535                 continue;
536             }
537             if (irq.str().find("vdroop1") != std::string::npos) {
538                 max_value.triggered_irq_ = BrownoutDetected::UVLO1;
539                 continue;
540             }
541             if (irq.str().find("vdroop2") != std::string::npos) {
542                 max_value.triggered_irq_ = BrownoutDetected::UVLO2;
543                 continue;
544             }
545             if (irq.str().find("smpl_gm") != std::string::npos) {
546                 max_value.triggered_irq_ = BrownoutDetected::SMPL_WARN;
547                 continue;
548             }
549             continue;
550         }
551         if (std::regex_match(line, pattern_match, kTimestampPattern)) {
552             max_value.triggered_timestamp_ = parseTimestamp(line.c_str());
553             continue;
554         }
555         if (updateIfFound(line, kBatterySocPattern, &max_value.battery_soc_, kUpdateMin)) {
556             continue;
557         }
558         if (updateIfFound(line, kBatteryTempPattern, &max_value.battery_temp_, kUpdateMin)) {
559             continue;
560         }
561         if (updateIfFound(line, kBatteryCyclePattern, &max_value.battery_cycle_, kUpdateMax)) {
562             continue;
563         }
564         if (updateIfFound(line, kFgPattern, &max_value.voltage_now_, kUpdateMin)) {
565             continue;
566         }
567         if (updateIfFound(line, kDvfsPattern, &max_value.dvfs_value_[dvfs_index], kUpdateMax)) {
568             dvfs_index++;
569             // Discarding previous value and update with new DVFS value
570             if (dvfs_index == DVFS_MAX_IDX) {
571                 dvfs_index = 0;
572             }
573             continue;
574         }
575         if (updateIfFound(line, kOdpmPattern, &max_value.odpm_value_[odpm_index], kUpdateMax)) {
576             odpm_index++;
577             // Discarding previous value and update with new ODPM value
578             if (odpm_index == ODPM_MAX_IDX) {
579                 odpm_index = 0;
580             }
581             continue;
582         }
583     }
584     if (!isAlreadyUpdated && max_value.battery_temp_ != DEFAULT_BATTERY_TEMP) {
585         std::string file_content = "LASTMEAL_UPDATED\n" + logFile;
586         android::base::WriteStringToFile(file_content, logFilePath);
587         uploadData(stats_client, max_value);
588     }
589 }
590 
591 }  // namespace pixel
592 }  // namespace google
593 }  // namespace hardware
594 }  // namespace android
595