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 4:
47 return PixelAtoms::ChargeStats::ADAPTER_TYPE_WPC_MPP;
48 case 5:
49 return PixelAtoms::ChargeStats::ADAPTER_TYPE_WPC_MPP25;
50 case 0xe0:
51 return PixelAtoms::ChargeStats::ADAPTER_TYPE_DL;
52 case 0xa0:
53 return PixelAtoms::ChargeStats::ADAPTER_TYPE_L7;
54 default:
55 return PixelAtoms::ChargeStats::ADAPTER_TYPE_WLC;
56 }
57 }
58
CheckWirelessContentsAndAck(std::string * file_contents)59 bool WirelessChargeStats::CheckWirelessContentsAndAck(std::string *file_contents) {
60 std::string line;
61 std::istringstream ss;
62
63 if (!ReadFileToString(kWirelessChargeMetricsPath.c_str(), file_contents))
64 return false;
65
66 ss.str(*file_contents);
67
68 if (!std::getline(ss, line)) {
69 ALOGE("Unable to read first line %s - %s", kWirelessChargeMetricsPath.c_str(),
70 strerror(errno));
71 return false;
72 }
73 if (!WriteStringToFile(std::to_string(0), kWirelessChargeMetricsPath.c_str())) {
74 ALOGE("Couldn't clear %s - %s", kWirelessChargeMetricsPath.c_str(), strerror(errno));
75 return false;
76 }
77 return true;
78 }
79
ResetChargeMetrics()80 void WirelessChargeStats::ResetChargeMetrics() {
81 pout_min_ = 0;
82 pout_avg_ = 0;
83 pout_max_ = 0;
84 of_freq_ = 0;
85 alignment_ = 0;
86 count_ = 0;
87 }
88
CalculateWirelessChargeMetrics(const int pout_min,const int pout_avg,const int pout_max,const int of_freq,const int alignment)89 void WirelessChargeStats::CalculateWirelessChargeMetrics(const int pout_min, const int pout_avg,
90 const int pout_max, const int of_freq,
91 const int alignment) {
92 if ((pout_min_ == 0) || (pout_min_ > pout_min))
93 pout_min_ = pout_min;
94
95 pout_avg_ += pout_avg;
96 count_++;
97
98 if ((pout_max_ == 0) || (pout_max_ < pout_max))
99 pout_max_ = pout_max;
100
101 if (alignment_ == 0 || ((alignment >= 0) && (alignment_ > alignment))) {
102 of_freq_ = of_freq;
103 alignment_ = alignment;
104 }
105 }
106
CalculateWirelessChargeStats(const int ssoc_tmp,const std::string file_contents)107 void WirelessChargeStats::CalculateWirelessChargeStats(const int ssoc_tmp,
108 const std::string file_contents) {
109 std::string line;
110 std::istringstream ss;
111
112 ResetChargeMetrics();
113 ss.str(file_contents);
114
115 while (std::getline(ss, line)) {
116 int32_t buf[11] = {0};
117 if (sscanf(line.c_str(), "%d:%d, %d,%d,%d, %d,%d, %d,%d,%d,%d", &buf[0], &buf[1], &buf[2],
118 &buf[3], &buf[4], &buf[5], &buf[6], &buf[7], &buf[8], &buf[9], &buf[10]) == 11) {
119 const int32_t soc = buf[0];
120
121 /* calculate wireless charge stats of next voltage tier */
122 if (soc > tier_soc_) {
123 const int32_t alignment = buf[6];
124
125 if (alignment >= 0 && alignment < 100)
126 ALOGD("WirelessChargeStats: misalignment %s", line.c_str());
127
128 CalculateWirelessChargeMetrics(buf[2], buf[3], buf[4], buf[5], buf[6]);
129 if (soc >= ssoc_tmp) {
130 /* reach next voltage tier, restore final results before sending out*/
131 pout_avg_ = (pout_avg_ / count_);
132 tier_soc_ = soc;
133 ALOGD("WirelessChargeStats: atoms %d %d %d %d", pout_min_, pout_avg_, pout_max_,
134 of_freq_);
135 return;
136 }
137 }
138 }
139 }
140 }
141
WirelessChargeStats(const std::string wireless_charge_metrics_path)142 WirelessChargeStats::WirelessChargeStats(const std::string wireless_charge_metrics_path)
143 : kWirelessChargeMetricsPath(wireless_charge_metrics_path) {}
144
145 } // namespace pixel
146 } // namespace google
147 } // namespace hardware
148 } // namespace android
149