• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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: BatteryFGReporter"
18 
19 #include <log/log.h>
20 #include <time.h>
21 #include <utils/Timers.h>
22 #include <cinttypes>
23 #include <cmath>
24 
25 #include <android-base/file.h>
26 #include <pixelstats/BatteryFGReporter.h>
27 #include <pixelstats/StatsHelper.h>
28 #include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
29 
30 namespace android {
31 namespace hardware {
32 namespace google {
33 namespace pixel {
34 
35 using aidl::android::frameworks::stats::VendorAtom;
36 using aidl::android::frameworks::stats::VendorAtomValue;
37 using android::base::ReadFileToString;
38 using android::hardware::google::pixel::PixelAtoms::BatteryEEPROM;
39 using android::hardware::google::pixel::PixelAtoms::FuelGaugeAbnormalityReported;
40 
41 
BatteryFGReporter()42 BatteryFGReporter::BatteryFGReporter() {}
43 
getTimeSecs()44 int64_t BatteryFGReporter::getTimeSecs() {
45     return nanoseconds_to_seconds(systemTime(SYSTEM_TIME_BOOTTIME));
46 }
47 
reportFGEvent(const std::shared_ptr<IStats> & stats_client,struct BatteryFGPipeline & data)48 void BatteryFGReporter::reportFGEvent(const std::shared_ptr<IStats> &stats_client,
49                                       struct BatteryFGPipeline &data) {
50     // Load values array
51     std::vector<VendorAtomValue> values(kNumFGPipelineFields);
52 
53     if (data.event >= kNumMaxEvents) {
54         ALOGE("Exceed max number of events, expected=%d, event=%d",
55                kNumMaxEvents, data.event);
56         return;
57     }
58 
59     /* save time when trigger, calculate duration when clear */
60     if (data.state == 1 && ab_trigger_time_[data.event] == 0) {
61         ab_trigger_time_[data.event] = getTimeSecs();
62     } else {
63         data.duration = getTimeSecs() - ab_trigger_time_[data.event];
64         ab_trigger_time_[data.event] = 0;
65     }
66 
67     ALOGD("reportEvent: event=%d, state=%d, duration=%d, addr01=%04X, data01=%04X, "
68           "addr02=%04X, data02=%04X, addr03=%04X, data03=%04X, addr04=%04X, data04=%04X, "
69           "addr05=%04X, data05=%04X, addr06=%04X, data06=%04X, addr07=%04X, data07=%04X, "
70           "addr08=%04X, data08=%04X, addr09=%04X, data09=%04X, addr10=%04X, data10=%04X, "
71           "addr11=%04X, data11=%04X, addr12=%04X, data12=%04X, addr13=%04X, data13=%04X, "
72           "addr14=%04X, data14=%04X, addr15=%04X, data15=%04X, addr16=%04X, data16=%04X",
73           data.event, data.state, data.duration, data.addr01, data.data01,
74           data.addr02, data.data02, data.addr03, data.data03, data.addr04, data.data04,
75           data.addr05, data.data05, data.addr06, data.data06, data.addr07, data.data07,
76           data.addr08, data.data08, data.addr09, data.data09, data.addr10, data.data10,
77           data.addr11, data.data11, data.addr12, data.data12, data.addr13, data.data13,
78           data.addr14, data.data14, data.addr15, data.data15, data.addr16, data.data16);
79 
80 
81     /*
82      * state=0 -> untrigger, state=1 -> trigger
83      * Since atom enum reserves unknown value at 0, offset by 1 here
84      * state=1-> untrigger, state=2 -> trigger
85      */
86     data.state += 1;
87 
88     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kEventFieldNumber, data.event);
89     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kEventStateFieldNumber, data.state);
90     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kDurationSecsFieldNumber,
91                       data.duration);
92     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterAddress1FieldNumber,
93                       data.addr01);
94     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterData1FieldNumber,
95                       data.data01);
96     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterAddress2FieldNumber,
97                       data.addr02);
98     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterData2FieldNumber,
99                       data.data02);
100     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterAddress3FieldNumber,
101                       data.addr03);
102     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterData3FieldNumber,
103                       data.data03);
104     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterAddress4FieldNumber,
105                       data.addr04);
106     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterData4FieldNumber,
107                       data.data04);
108     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterAddress5FieldNumber,
109                       data.addr05);
110     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterData5FieldNumber,
111                       data.data05);
112     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterAddress6FieldNumber,
113                       data.addr06);
114     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterData6FieldNumber,
115                       data.data06);
116     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterAddress7FieldNumber,
117                       data.addr07);
118     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterData7FieldNumber,
119                       data.data07);
120     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterAddress8FieldNumber,
121                       data.addr08);
122     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterData8FieldNumber,
123                       data.data08);
124     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterAddress9FieldNumber,
125                       data.addr09);
126     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterData9FieldNumber,
127                       data.data09);
128     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterAddress10FieldNumber,
129                       data.addr10);
130     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterData10FieldNumber,
131                       data.data10);
132     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterAddress11FieldNumber,
133                       data.addr11);
134     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterData11FieldNumber,
135                       data.data11);
136     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterAddress12FieldNumber,
137                       data.addr12);
138     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterData12FieldNumber,
139                       data.data12);
140     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterAddress13FieldNumber,
141                       data.addr13);
142     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterData13FieldNumber,
143                       data.data13);
144     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterAddress14FieldNumber,
145                       data.addr14);
146     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterData14FieldNumber,
147                       data.data14);
148     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterAddress15FieldNumber,
149                       data.addr15);
150     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterData15FieldNumber,
151                       data.data15);
152     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterAddress16FieldNumber,
153                       data.addr16);
154     setAtomFieldValue(&values, FuelGaugeAbnormalityReported::kFgRegisterData16FieldNumber,
155                       data.data16);
156 
157     VendorAtom event = {.reverseDomainName = "",
158                         .atomId = PixelAtoms::Atom::kFuelGaugeAbnormalityReported,
159                         .values = std::move(values)};
160     reportVendorAtom(stats_client, event);
161 }
162 
checkAndReportFGAbnormality(const std::shared_ptr<IStats> & stats_client,const std::vector<std::string> & paths)163 void BatteryFGReporter::checkAndReportFGAbnormality(const std::shared_ptr<IStats> &stats_client,
164                                                     const std::vector<std::string> &paths) {
165     std::string path;
166     struct timespec boot_time;
167     std::vector<std::vector<uint32_t>> events;
168 
169     if (paths.empty())
170         return;
171 
172     for (int i = 0; i < paths.size(); i++) {
173         if (fileExists(paths[i])) {
174             path = paths[i];
175             break;
176         }
177     }
178 
179     clock_gettime(CLOCK_MONOTONIC, &boot_time);
180     readLogbuffer(path, kNumFGPipelineFields, EvtFGAbnormalEvent, FormatOnlyVal, last_ab_check_,
181                   events);
182     for (int seq = 0; seq < events.size(); seq++) {
183         if (events[seq].size() == kNumFGPipelineFields) {
184             struct BatteryFGPipeline data;
185             std::copy(events[seq].begin(), events[seq].end(), (int32_t *)&data);
186             reportFGEvent(stats_client, data);
187         } else {
188             ALOGE("Not support %zu fields for FG abnormal event", events[seq].size());
189         }
190     }
191 
192     last_ab_check_ = (unsigned int)boot_time.tv_sec;
193 }
194 
195 }  // namespace pixel
196 }  // namespace google
197 }  // namespace hardware
198 }  // namespace android
199