• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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