1 /*
2 * Copyright (C) 2018 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 #define LOG_TAG "android.hardware.health@2.0-service.bonito"
17 #include <android-base/file.h>
18 #include <android-base/logging.h>
19 #include <android-base/parseint.h>
20 #include <android-base/strings.h>
21 #include <health2/Health.h>
22 #include <health2/service.h>
23 #include <healthd/healthd.h>
24 #include <hidl/HidlTransportSupport.h>
25 #include <pixelhealth/BatteryDefender.h>
26 #include <pixelhealth/BatteryMetricsLogger.h>
27 #include <pixelhealth/BatteryThermalControl.h>
28 #include <pixelhealth/CycleCountBackupRestore.h>
29 #include <pixelhealth/DeviceHealth.h>
30 #include <pixelhealth/LowBatteryShutdownMetrics.h>
31
32 #include <fstream>
33 #include <iomanip>
34 #include <string>
35 #include <vector>
36
37 #include "BatteryInfoUpdate.h"
38 #include "BatteryRechargingControl.h"
39 #include "LearnedCapacityBackupRestore.h"
40
41 namespace {
42
43 using android::hardware::health::V2_0::DiskStats;
44 using android::hardware::health::V2_0::StorageAttribute;
45 using android::hardware::health::V2_0::StorageInfo;
46 using ::device::google::bonito::health::BatteryRechargingControl;
47 using ::device::google::bonito::health::BatteryInfoUpdate;
48 using ::device::google::bonito::health::LearnedCapacityBackupRestore;
49 using hardware::google::pixel::health::BatteryDefender;
50 using hardware::google::pixel::health::BatteryMetricsLogger;
51 using hardware::google::pixel::health::BatteryThermalControl;
52 using hardware::google::pixel::health::CycleCountBackupRestore;
53 using hardware::google::pixel::health::DeviceHealth;
54 using hardware::google::pixel::health::LowBatteryShutdownMetrics;
55
56 #define FG_DIR "/sys/class/power_supply"
57 constexpr char kBatteryResistance[] {FG_DIR "/bms/resistance"};
58 constexpr char kBatteryOCV[] {FG_DIR "/bms/voltage_ocv"};
59 constexpr char kVoltageAvg[] {FG_DIR "/battery/voltage_now"};
60 constexpr char kCycleCountsBins[] {FG_DIR "/bms/device/cycle_counts_bins"};
61
62 static BatteryDefender battDefender;
63 static BatteryRechargingControl battRechargingControl;
64 static BatteryInfoUpdate battInfoUpdate;
65 static BatteryThermalControl battThermalControl("sys/devices/virtual/thermal/tz-by-name/soc/mode");
66 static BatteryMetricsLogger battMetricsLogger(kBatteryResistance, kBatteryOCV);
67 static LowBatteryShutdownMetrics shutdownMetrics(kVoltageAvg);
68 static CycleCountBackupRestore ccBackupRestoreBMS(
69 8, kCycleCountsBins, "/mnt/vendor/persist/battery/qcom_cycle_counts_bins");
70 static DeviceHealth deviceHealth;
71 static LearnedCapacityBackupRestore lcBackupRestore;
72
73 #define EMMC_DIR "/sys/devices/platform/soc/7c4000.sdhci"
74 const std::string kEmmcHealthEol{EMMC_DIR "/health/eol"};
75 const std::string kEmmcHealthLifetimeA{EMMC_DIR "/health/lifetimeA"};
76 const std::string kEmmcHealthLifetimeB{EMMC_DIR "/health/lifetimeB"};
77 const std::string kEmmcVersion{"/sys/block/mmcblk0/device/fwrev"};
78 const std::string kDiskStatsFile{"/sys/block/mmcblk0/stat"};
79 const std::string kEmmcName{"MMC0"};
80
assert_open(const std::string & path)81 std::ifstream assert_open(const std::string& path) {
82 std::ifstream stream(path);
83 if (!stream.is_open()) {
84 LOG(FATAL) << "Cannot read " << path;
85 }
86 return stream;
87 }
88
89 template <typename T>
read_value_from_file(const std::string & path,T * field)90 void read_value_from_file(const std::string& path, T* field) {
91 auto stream = assert_open(path);
92 stream.unsetf(std::ios_base::basefield);
93 stream >> *field;
94 }
95
read_emmc_version(StorageInfo * info)96 void read_emmc_version(StorageInfo* info) {
97 uint64_t value;
98 read_value_from_file(kEmmcVersion, &value);
99 std::stringstream ss;
100 ss << "mmc0 " << std::hex << value;
101 info->version = ss.str();
102 }
103
fill_emmc_storage_attribute(StorageAttribute * attr)104 void fill_emmc_storage_attribute(StorageAttribute* attr) {
105 attr->isInternal = true;
106 attr->isBootDevice = true;
107 attr->name = kEmmcName;
108 }
109
110 } // anonymous namespace
111
healthd_board_init(struct healthd_config *)112 void healthd_board_init(struct healthd_config*) {
113 ccBackupRestoreBMS.Restore();
114 lcBackupRestore.Restore();
115 }
116
healthd_board_battery_update(struct android::BatteryProperties * props)117 int healthd_board_battery_update(struct android::BatteryProperties *props) {
118 battRechargingControl.updateBatteryProperties(props);
119 deviceHealth.update(props);
120 battThermalControl.updateThermalState(props);
121 battInfoUpdate.update(props);
122 battMetricsLogger.logBatteryProperties(props);
123 shutdownMetrics.logShutdownVoltage(props);
124 ccBackupRestoreBMS.Backup(props->batteryLevel);
125 lcBackupRestore.Backup();
126 battDefender.update(props);
127 return 0;
128 }
129
get_storage_info(std::vector<StorageInfo> & vec_storage_info)130 void get_storage_info(std::vector<StorageInfo>& vec_storage_info) {
131 vec_storage_info.resize(1);
132 StorageInfo* storage_info = &vec_storage_info[0];
133 fill_emmc_storage_attribute(&storage_info->attr);
134
135 read_emmc_version(storage_info);
136 read_value_from_file(kEmmcHealthEol, &storage_info->eol);
137 read_value_from_file(kEmmcHealthLifetimeA, &storage_info->lifetimeA);
138 read_value_from_file(kEmmcHealthLifetimeB, &storage_info->lifetimeB);
139 return;
140 }
141
get_disk_stats(std::vector<DiskStats> & vec_stats)142 void get_disk_stats(std::vector<DiskStats>& vec_stats) {
143 vec_stats.resize(1);
144 DiskStats* stats = &vec_stats[0];
145 fill_emmc_storage_attribute(&stats->attr);
146
147 auto stream = assert_open(kDiskStatsFile);
148 // Regular diskstats entries
149 stream >> stats->reads
150 >> stats->readMerges
151 >> stats->readSectors
152 >> stats->readTicks
153 >> stats->writes
154 >> stats->writeMerges
155 >> stats->writeSectors
156 >> stats->writeTicks
157 >> stats->ioInFlight
158 >> stats->ioTicks
159 >> stats->ioInQueue;
160 return;
161 }
162
main(void)163 int main(void) {
164 return health_service_main();
165 }
166