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 VendorBatteryCausedShutdown shutdown;
56 int32_t voltage_avg;
57 for (const auto &item : android::base::Split(prop_contents, ",")) {
58 if (!(voltage_avg = stoi(item))) {
59 LOG(ERROR) << "Couldn't process voltage value " << item;
60 continue;
61 }
62 LOG(INFO) << "Uploading voltage_avg: " << std::to_string(voltage_avg);
63 shutdown.set_last_recorded_micro_volt(voltage_avg);
64 reportBatteryCausedShutdown(stats_client, shutdown);
65 }
66
67 // Clear property now that we've uploaded its contents
68 SetProperty(kPersistProp, "");
69 return true;
70 }
71
saveVoltageAvg(void)72 bool LowBatteryShutdownMetrics::saveVoltageAvg(void) {
73 std::string voltage_avg;
74 std::string prop_contents;
75
76 if (!ReadFileToString(kVoltageAvg, &voltage_avg)) {
77 LOG(ERROR) << "Can't read the Maxim fuel gauge average voltage value";
78 return false;
79 }
80 voltage_avg = ::android::base::Trim(voltage_avg);
81 prop_contents = GetProperty(kPersistProp, "");
82
83 // Comma delimit additional values
84 if (prop_contents.size() > 0)
85 prop_contents += ",";
86 prop_contents += voltage_avg;
87
88 LOG(INFO) << "Saving \"" << prop_contents << "\" to " << kPersistProp;
89
90 return SetProperty(kPersistProp, prop_contents);
91 }
92
logShutdownVoltage(const HealthInfo & health_info)93 void LowBatteryShutdownMetrics::logShutdownVoltage(const HealthInfo &health_info) {
94 // If we're about to shut down due to low battery, save voltage_avg
95 if (!prop_written_ && health_info.batteryLevel == 0 &&
96 health_info.batteryStatus == BatteryStatus::DISCHARGING) {
97 prop_written_ = saveVoltageAvg();
98 } else if (!prop_empty_) { // We have data to upload
99 uploadVoltageAvg();
100 }
101
102 return;
103 }
104
logShutdownVoltage(struct android::BatteryProperties * props)105 void LowBatteryShutdownMetrics::logShutdownVoltage(struct android::BatteryProperties *props) {
106 logShutdownVoltage(ToHealthInfo(props));
107 }
108
109 } // namespace health
110 } // namespace pixel
111 } // namespace google
112 } // namespace hardware
113