Maggie White | 8c72de9 | 2018-09-28 16:18:35 -0700 | [diff] [blame] | 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 | |
Yifan Hong | 6329994 | 2022-01-05 00:07:59 -0800 | [diff] [blame] | 18 | #include <pixelhealth/HealthHelper.h> |
Maggie White | 8c72de9 | 2018-09-28 16:18:35 -0700 | [diff] [blame] | 19 | #include <pixelhealth/LowBatteryShutdownMetrics.h> |
Vova Sharaienko | dc6e6ba | 2021-03-24 02:10:12 +0000 | [diff] [blame] | 20 | #include <pixelhealth/StatsHelper.h> |
Maggie White | 8c72de9 | 2018-09-28 16:18:35 -0700 | [diff] [blame] | 21 | |
| 22 | namespace hardware { |
| 23 | namespace google { |
| 24 | namespace pixel { |
| 25 | namespace health { |
| 26 | |
Yifan Hong | 6329994 | 2022-01-05 00:07:59 -0800 | [diff] [blame] | 27 | using aidl::android::hardware::health::BatteryStatus; |
| 28 | using aidl::android::hardware::health::HealthInfo; |
Maggie White | 8c72de9 | 2018-09-28 16:18:35 -0700 | [diff] [blame] | 29 | using android::base::GetProperty; |
| 30 | using android::base::ReadFileToString; |
| 31 | using android::base::SetProperty; |
Maggie White | 8c72de9 | 2018-09-28 16:18:35 -0700 | [diff] [blame] | 32 | |
| 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 | |
| 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 | |
Vova Sharaienko | dc6e6ba | 2021-03-24 02:10:12 +0000 | [diff] [blame] | 48 | std::shared_ptr<IStats> stats_client = getStatsService(); |
Maggie White | eb2b7cf | 2018-12-05 15:48:09 -0800 | [diff] [blame] | 49 | if (!stats_client) { |
Vova Sharaienko | dc6e6ba | 2021-03-24 02:10:12 +0000 | [diff] [blame] | 50 | LOG(ERROR) << "Unable to connect to IStats service"; |
Maggie White | eb2b7cf | 2018-12-05 15:48:09 -0800 | [diff] [blame] | 51 | return false; |
| 52 | } |
| 53 | |
Maggie White | 8c72de9 | 2018-09-28 16:18:35 -0700 | [diff] [blame] | 54 | // Process and upload comma-delimited last voltage values |
Vova Sharaienko | dc6e6ba | 2021-03-24 02:10:12 +0000 | [diff] [blame] | 55 | VendorBatteryCausedShutdown shutdown; |
Maggie White | 8c72de9 | 2018-09-28 16:18:35 -0700 | [diff] [blame] | 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); |
Vova Sharaienko | dc6e6ba | 2021-03-24 02:10:12 +0000 | [diff] [blame] | 63 | shutdown.set_last_recorded_micro_volt(voltage_avg); |
| 64 | reportBatteryCausedShutdown(stats_client, shutdown); |
Maggie White | 8c72de9 | 2018-09-28 16:18:35 -0700 | [diff] [blame] | 65 | } |
| 66 | |
| 67 | // Clear property now that we've uploaded its contents |
| 68 | SetProperty(kPersistProp, ""); |
| 69 | return true; |
| 70 | } |
| 71 | |
| 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 | |
Yifan Hong | 6329994 | 2022-01-05 00:07:59 -0800 | [diff] [blame] | 93 | void LowBatteryShutdownMetrics::logShutdownVoltage(const HealthInfo &health_info) { |
Maggie White | 8c72de9 | 2018-09-28 16:18:35 -0700 | [diff] [blame] | 94 | // If we're about to shut down due to low battery, save voltage_avg |
Yifan Hong | 6329994 | 2022-01-05 00:07:59 -0800 | [diff] [blame] | 95 | if (!prop_written_ && health_info.batteryLevel == 0 && |
| 96 | health_info.batteryStatus == BatteryStatus::DISCHARGING) { |
Maggie White | 8c72de9 | 2018-09-28 16:18:35 -0700 | [diff] [blame] | 97 | prop_written_ = saveVoltageAvg(); |
| 98 | } else if (!prop_empty_) { // We have data to upload |
| 99 | uploadVoltageAvg(); |
| 100 | } |
| 101 | |
| 102 | return; |
| 103 | } |
| 104 | |
Yifan Hong | 6329994 | 2022-01-05 00:07:59 -0800 | [diff] [blame] | 105 | void LowBatteryShutdownMetrics::logShutdownVoltage(struct android::BatteryProperties *props) { |
| 106 | logShutdownVoltage(ToHealthInfo(props)); |
| 107 | } |
| 108 | |
Maggie White | 8c72de9 | 2018-09-28 16:18:35 -0700 | [diff] [blame] | 109 | } // namespace health |
| 110 | } // namespace pixel |
| 111 | } // namespace google |
| 112 | } // namespace hardware |