1 /*
2 * Copyright (C) 2021 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-uevent"
18
19 #include <android-base/file.h>
20 #include <android-base/logging.h>
21 #include <android-base/parseint.h>
22 #include <android-base/strings.h>
23 #include <hardware/google/pixel/pixelstats/pixelatoms.pb.h>
24 #include <log/log.h>
25 #include <pixelstats/WirelessChargeStats.h>
26
27 namespace android {
28 namespace hardware {
29 namespace google {
30 namespace pixel {
31
32 using android::base::ReadFileToString;
33 using android::base::WriteStringToFile;
34
35 /* Reference to <kernel>/private/google-modules/bms/p9221_charger.h
36 * translate sys_mode value to enum define in pixelatoms.proto
37 */
TranslateSysModeToAtomValue(const int sys_mode)38 int WirelessChargeStats::TranslateSysModeToAtomValue(const int sys_mode) {
39 switch (sys_mode) {
40 case 1:
41 return PixelAtoms::ChargeStats::ADAPTER_TYPE_WPC_BPP;
42 case 2:
43 return PixelAtoms::ChargeStats::ADAPTER_TYPE_WPC_EPP;
44 case 3:
45 return PixelAtoms::ChargeStats::ADAPTER_TYPE_WPC_L7;
46 case 0xe0:
47 return PixelAtoms::ChargeStats::ADAPTER_TYPE_DL;
48 case 0xa0:
49 return PixelAtoms::ChargeStats::ADAPTER_TYPE_L7;
50 default:
51 return PixelAtoms::ChargeStats::ADAPTER_TYPE_WLC;
52 }
53 }
54
CheckWirelessContentsAndAck(std::string * file_contents)55 bool WirelessChargeStats::CheckWirelessContentsAndAck(std::string *file_contents) {
56 std::string line;
57 std::istringstream ss;
58
59 if (!ReadFileToString(kWirelessChargeMetricsPath.c_str(), file_contents))
60 return false;
61
62 ss.str(*file_contents);
63
64 if (!std::getline(ss, line)) {
65 ALOGE("Unable to read first line %s - %s", kWirelessChargeMetricsPath.c_str(),
66 strerror(errno));
67 return false;
68 }
69 if (!WriteStringToFile(std::to_string(0), kWirelessChargeMetricsPath.c_str())) {
70 ALOGE("Couldn't clear %s - %s", kWirelessChargeMetricsPath.c_str(), strerror(errno));
71 return false;
72 }
73 return true;
74 }
75
ResetChargeMetrics()76 void WirelessChargeStats::ResetChargeMetrics() {
77 pout_min_ = 0;
78 pout_avg_ = 0;
79 pout_max_ = 0;
80 of_freq_ = 0;
81 alignment_ = 0;
82 count_ = 0;
83 }
84
CalculateWirelessChargeMetrics(const int pout_min,const int pout_avg,const int pout_max,const int of_freq,const int alignment)85 void WirelessChargeStats::CalculateWirelessChargeMetrics(const int pout_min, const int pout_avg,
86 const int pout_max, const int of_freq,
87 const int alignment) {
88 if ((pout_min_ == 0) || (pout_min_ > pout_min))
89 pout_min_ = pout_min;
90
91 pout_avg_ += pout_avg;
92 count_++;
93
94 if ((pout_max_ == 0) || (pout_max_ < pout_max))
95 pout_max_ = pout_max;
96
97 if (alignment_ == 0 || ((alignment >= 0) && (alignment_ > alignment))) {
98 of_freq_ = of_freq;
99 alignment_ = alignment;
100 }
101 }
102
CalculateWirelessChargeStats(const int ssoc_tmp,const std::string file_contents)103 void WirelessChargeStats::CalculateWirelessChargeStats(const int ssoc_tmp,
104 const std::string file_contents) {
105 std::string line;
106 std::istringstream ss;
107
108 ResetChargeMetrics();
109 ss.str(file_contents);
110
111 while (std::getline(ss, line)) {
112 int32_t buf[11] = {0};
113 if (sscanf(line.c_str(), "%d:%d, %d,%d,%d, %d,%d, %d,%d,%d,%d", &buf[0], &buf[1], &buf[2],
114 &buf[3], &buf[4], &buf[5], &buf[6], &buf[7], &buf[8], &buf[9], &buf[10]) == 11) {
115 const int32_t soc = buf[0];
116
117 /* calculate wireless charge stats of next voltage tier */
118 if (soc > tier_soc_) {
119 const int32_t alignment = buf[6];
120
121 if (alignment >= 0 && alignment < 100)
122 ALOGD("WirelessChargeStats: misalignment %s", line.c_str());
123
124 CalculateWirelessChargeMetrics(buf[2], buf[3], buf[4], buf[5], buf[6]);
125 if (soc >= ssoc_tmp) {
126 /* reach next voltage tier, restore final results before sending out*/
127 pout_avg_ = (pout_avg_ / count_);
128 tier_soc_ = soc;
129 ALOGD("WirelessChargeStats: atoms %d %d %d %d", pout_min_, pout_avg_, pout_max_,
130 of_freq_);
131 return;
132 }
133 }
134 }
135 }
136 }
137
WirelessChargeStats(const std::string wireless_charge_metrics_path)138 WirelessChargeStats::WirelessChargeStats(const std::string wireless_charge_metrics_path)
139 : kWirelessChargeMetricsPath(wireless_charge_metrics_path) {}
140
141 } // namespace pixel
142 } // namespace google
143 } // namespace hardware
144 } // namespace android
145