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/HealthHelper.h>
19 #include <pixelhealth/LowBatteryShutdownMetrics.h>
20 #include <pixelhealth/StatsHelper.h>
21 
22 namespace hardware {
23 namespace google {
24 namespace pixel {
25 namespace health {
26 
27 using aidl::android::hardware::health::BatteryStatus;
28 using aidl::android::hardware::health::HealthInfo;
29 using android::base::GetProperty;
30 using android::base::ReadFileToString;
31 using android::base::SetProperty;
32 
LowBatteryShutdownMetrics(const char * const voltage_avg,const char * const persist_prop)33 LowBatteryShutdownMetrics::LowBatteryShutdownMetrics(const char *const voltage_avg,
34                                                      const char *const persist_prop)
35     : kVoltageAvg(voltage_avg), kPersistProp(persist_prop) {
36     prop_written_ = false;
37     prop_empty_ = false;
38 }
39 
uploadVoltageAvg(void)40 bool LowBatteryShutdownMetrics::uploadVoltageAvg(void) {
41     std::string prop_contents = GetProperty(kPersistProp, "");
42     LOG(INFO) << kPersistProp << " property contents: " << prop_contents;
43     if (prop_contents.size() == 0) {  // we don't have anything to upload
44         prop_empty_ = true;
45         return false;
46     }
47 
48     std::shared_ptr<IStats> stats_client = getStatsService();
49     if (!stats_client) {
50         LOG(ERROR) << "Unable to connect to IStats service";
51         return false;
52     }
53 
54     // Process and upload comma-delimited last voltage values
55     int32_t voltage_avg;
56     for (const auto &item : android::base::Split(prop_contents, ",")) {
57         if (!(voltage_avg = stoi(item))) {
58             LOG(ERROR) << "Couldn't process voltage value " << item;
59             continue;
60         }
61         LOG(INFO) << "Uploading voltage_avg: " << std::to_string(voltage_avg);
62         reportBatteryCausedShutdown(stats_client, voltage_avg);
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(const HealthInfo & health_info)91 void LowBatteryShutdownMetrics::logShutdownVoltage(const HealthInfo &health_info) {
92     // If we're about to shut down due to low battery, save voltage_avg
93     if (!prop_written_ && health_info.batteryLevel == 0 &&
94         health_info.batteryStatus == BatteryStatus::DISCHARGING) {
95         prop_written_ = saveVoltageAvg();
96     } else if (!prop_empty_) {  // We have data to upload
97         uploadVoltageAvg();
98     }
99 
100     return;
101 }
102 
logShutdownVoltage(struct android::BatteryProperties * props)103 void LowBatteryShutdownMetrics::logShutdownVoltage(struct android::BatteryProperties *props) {
104     logShutdownVoltage(ToHealthInfo(props));
105 }
106 
107 }  // namespace health
108 }  // namespace pixel
109 }  // namespace google
110 }  // namespace hardware
111