1 
2 /*
3  * Copyright (C) 2018 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <pixelhealth/LowBatteryShutdownMetrics.h>
19 #include <pixelhealth/StatsHelper.h>
20 
21 namespace hardware {
22 namespace google {
23 namespace pixel {
24 namespace health {
25 
26 using android::BATTERY_STATUS_DISCHARGING;
27 using android::base::GetProperty;
28 using android::base::ReadFileToString;
29 using android::base::SetProperty;
30 
LowBatteryShutdownMetrics(const char * const voltage_avg,const char * const persist_prop)31 LowBatteryShutdownMetrics::LowBatteryShutdownMetrics(const char *const voltage_avg,
32                                                      const char *const persist_prop)
33     : kVoltageAvg(voltage_avg), kPersistProp(persist_prop) {
34     prop_written_ = false;
35     prop_empty_ = false;
36 }
37 
uploadVoltageAvg(void)38 bool LowBatteryShutdownMetrics::uploadVoltageAvg(void) {
39     std::string prop_contents = GetProperty(kPersistProp, "");
40     LOG(INFO) << kPersistProp << " property contents: " << prop_contents;
41     if (prop_contents.size() == 0) {  // we don't have anything to upload
42         prop_empty_ = true;
43         return false;
44     }
45 
46     std::shared_ptr<IStats> stats_client = getStatsService();
47     if (!stats_client) {
48         LOG(ERROR) << "Unable to connect to IStats service";
49         return false;
50     }
51 
52     // Process and upload comma-delimited last voltage values
53     VendorBatteryCausedShutdown shutdown;
54     int32_t voltage_avg;
55     for (const auto &item : android::base::Split(prop_contents, ",")) {
56         if (!(voltage_avg = stoi(item))) {
57             LOG(ERROR) << "Couldn't process voltage value " << item;
58             continue;
59         }
60         LOG(INFO) << "Uploading voltage_avg: " << std::to_string(voltage_avg);
61         shutdown.set_last_recorded_micro_volt(voltage_avg);
62         reportBatteryCausedShutdown(stats_client, shutdown);
63     }
64 
65     // Clear property now that we've uploaded its contents
66     SetProperty(kPersistProp, "");
67     return true;
68 }
69 
saveVoltageAvg(void)70 bool LowBatteryShutdownMetrics::saveVoltageAvg(void) {
71     std::string voltage_avg;
72     std::string prop_contents;
73 
74     if (!ReadFileToString(kVoltageAvg, &voltage_avg)) {
75         LOG(ERROR) << "Can't read the Maxim fuel gauge average voltage value";
76         return false;
77     }
78     voltage_avg = ::android::base::Trim(voltage_avg);
79     prop_contents = GetProperty(kPersistProp, "");
80 
81     // Comma delimit additional values
82     if (prop_contents.size() > 0)
83         prop_contents += ",";
84     prop_contents += voltage_avg;
85 
86     LOG(INFO) << "Saving \"" << prop_contents << "\" to " << kPersistProp;
87 
88     return SetProperty(kPersistProp, prop_contents);
89 }
90 
logShutdownVoltage(struct android::BatteryProperties * props)91 void LowBatteryShutdownMetrics::logShutdownVoltage(struct android::BatteryProperties *props) {
92     // If we're about to shut down due to low battery, save voltage_avg
93     if (!prop_written_ && props->batteryLevel == 0 &&
94         props->batteryStatus == android::BATTERY_STATUS_DISCHARGING) {
95         prop_written_ = saveVoltageAvg();
96     } else if (!prop_empty_) {  // We have data to upload
97         uploadVoltageAvg();
98     }
99 
100     return;
101 }
102 
103 }  // namespace health
104 }  // namespace pixel
105 }  // namespace google
106 }  // namespace hardware
107