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