From fa1279bd6bbab0b2ff07e5079da45a082efd3622 Mon Sep 17 00:00:00 2001 From: Thierry Strudel Date: Tue, 3 Apr 2018 17:22:55 -0700 Subject: [PATCH] battery cycle counts: backup/restore + update dumpstate Tests: - pts-tradefed run pts -a arm64-v8a -m PtsHardwareInfoHostTestCases - adb bugreport - no "avc: denied" on health vendor service - cycle count stored in /persist/battery/qcom_cycle_counts_bins Bug: 72776338 Bug: 77498107 Change-Id: Ia1a58441fff511c60278b5d97806655c34aec610 Signed-off-by: Thierry Strudel --- dumpstate/DumpstateDevice.cpp | 2 +- health/Android.bp | 1 + health/CycleCountBackupRestore.cpp | 132 ++++++++++++++++++++++++++ health/CycleCountBackupRestore.h | 54 +++++++++++ health/HealthService.cpp | 42 +++++++- init.hardware.rc | 9 ++ sepolicy/vendor/file.te | 1 + sepolicy/vendor/file_contexts | 1 + sepolicy/vendor/genfs_contexts | 2 +- sepolicy/vendor/hal_dumpstate_impl.te | 2 +- sepolicy/vendor/hal_health_default.te | 5 + sepolicy/vendor/hardware_info_app.te | 3 +- 12 files changed, 246 insertions(+), 8 deletions(-) create mode 100644 health/CycleCountBackupRestore.cpp create mode 100644 health/CycleCountBackupRestore.h diff --git a/dumpstate/DumpstateDevice.cpp b/dumpstate/DumpstateDevice.cpp index e7e0bb67..750d4e6a 100755 --- a/dumpstate/DumpstateDevice.cpp +++ b/dumpstate/DumpstateDevice.cpp @@ -260,7 +260,7 @@ Return DumpstateDevice::dumpstateBoard(const hidl_handle& handle) { RunCommandToFd(fd, "QSEE logs", {"/vendor/bin/sh", "-c", "cat /d/tzdbg/qsee_log"}); RunCommandToFd(fd, "Power supply properties", {"/vendor/bin/sh", "-c", "for f in /sys/class/power_supply/*/uevent ; do echo \"\n------ $f\" ; cat $f ; done"}); - RunCommandToFd(fd, "Battery cycle count", {"/vendor/bin/sh", "-c", "for f in 1 2 3 4 5 6 7 8 ; do echo $f > /sys/class/power_supply/bms/cycle_count_id; count=`cat /sys/class/power_supply/bms/cycle_count`; echo \"$f: $count\"; done"}); + DumpFileToFd(fd, "Battery cycle count", "/sys/class/power_supply/bms/device/cycle_counts_bins"); RunCommandToFd(fd, "QCOM FG SRAM", {"/vendor/bin/sh", "-c", "echo 0 > /d/fg/sram/address ; echo 500 > /d/fg/sram/count ; cat /d/fg/sram/data"}); DumpFileToFd(fd, "WLAN FW Log Symbol Table", "/vendor/firmware/Data.msc"); diff --git a/health/Android.bp b/health/Android.bp index e1d9bd3a..ba241482 100644 --- a/health/Android.bp +++ b/health/Android.bp @@ -20,6 +20,7 @@ cc_binary { relative_install_path: "hw", srcs: [ "HealthService.cpp", + "CycleCountBackupRestore.cpp", ], cflags: [ diff --git a/health/CycleCountBackupRestore.cpp b/health/CycleCountBackupRestore.cpp new file mode 100644 index 00000000..b9f83df0 --- /dev/null +++ b/health/CycleCountBackupRestore.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "CycleCountBackupRestore.h" + +namespace device { +namespace google { +namespace wahoo { +namespace health { + +static constexpr char kCycCntFile[] = "sys/class/power_supply/bms/device/cycle_counts_bins"; +static constexpr char kSysPersistFile[] = "/persist/battery/qcom_cycle_counts_bins"; +static constexpr int kBuffSize = 256; + +CycleCountBackupRestore::CycleCountBackupRestore() { } + +void CycleCountBackupRestore::Restore() +{ + ReadFromStorage(); + ReadFromSRAM(); + UpdateAndSave(); +} + +void CycleCountBackupRestore::Backup() +{ + ReadFromSRAM(); + UpdateAndSave(); +} + +void CycleCountBackupRestore::ReadFromStorage() +{ + std::string buffer; + + if (!android::base::ReadFileToString(std::string(kSysPersistFile), &buffer)) { + LOG(ERROR) << "Cannot read the storage file"; + return; + } + + if (sscanf(buffer.c_str(), "%d %d %d %d %d %d %d %d", + &sw_bins_[0], &sw_bins_[1], &sw_bins_[2], &sw_bins_[3], + &sw_bins_[4], &sw_bins_[5], &sw_bins_[6], &sw_bins_[7]) + != kBucketCount) + LOG(ERROR) << "data format is wrong in the storage file: " << buffer; + else + LOG(INFO) << "Storage data: " << buffer; +} + +void CycleCountBackupRestore::SaveToStorage() +{ + char strData[kBuffSize]; + + snprintf(strData, kBuffSize, "%d %d %d %d %d %d %d %d", + sw_bins_[0], sw_bins_[1], sw_bins_[2], sw_bins_[3], + sw_bins_[4], sw_bins_[5], sw_bins_[6], sw_bins_[7]); + + LOG(INFO) << "Save to Storage: " << strData; + + if (!android::base::WriteStringToFile(strData, std::string(kSysPersistFile))) + LOG(ERROR) << "Write file error: " << strerror(errno); +} + +void CycleCountBackupRestore::ReadFromSRAM() +{ + std::string buffer; + + if (!android::base::ReadFileToString(std::string(kCycCntFile), &buffer)) { + LOG(ERROR) << "Read cycle counter error: " << strerror(errno); + return; + } + + buffer = android::base::Trim(buffer); + + if (sscanf(buffer.c_str(), "%d %d %d %d %d %d %d %d", + &hw_bins_[0], &hw_bins_[1], &hw_bins_[2], &hw_bins_[3], + &hw_bins_[4], &hw_bins_[5], &hw_bins_[6], &hw_bins_[7]) + != kBucketCount) + LOG(ERROR) << "Failed to parse SRAM bins: " << buffer; + else + LOG(INFO) << "SRAM data: " << buffer; +} + +void CycleCountBackupRestore::SaveToSRAM() +{ + char strData[kBuffSize]; + + snprintf(strData, kBuffSize, "%d %d %d %d %d %d %d %d", + hw_bins_[0], hw_bins_[1], hw_bins_[2], hw_bins_[3], + hw_bins_[4], hw_bins_[5], hw_bins_[6], hw_bins_[7]); + + LOG(INFO) << "Save to SRAM: " << strData ; + + if (!android::base::WriteStringToFile(strData, std::string(kCycCntFile))) + LOG(ERROR) << "Write data error: " << strerror(errno); +} + + +void CycleCountBackupRestore::UpdateAndSave() +{ + bool backup = false; + bool restore = false; + for (int i = 0; i < kBucketCount; i++) { + if (hw_bins_[i] < sw_bins_[i]) { + hw_bins_[i] = sw_bins_[i]; + restore = true; + } else if (hw_bins_[i] > sw_bins_[i]) { + sw_bins_[i] = hw_bins_[i]; + backup = true; + } + } + if (restore) + SaveToSRAM(); + if (backup) + SaveToStorage(); +} + +} // namespace health +} // namespace wahoo +} // namespace google +} // namespace device diff --git a/health/CycleCountBackupRestore.h b/health/CycleCountBackupRestore.h new file mode 100644 index 00000000..e113c323 --- /dev/null +++ b/health/CycleCountBackupRestore.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DEVICE_GOOGLE_WAHOO_HEALTH_CYCLECOUNTBACKUPRESTORE_H +#define DEVICE_GOOGLE_WAHOO_HEALTH_CYCLECOUNTBACKUPRESTORE_H + +#include +#include +#include +#include + +namespace device { +namespace google { +namespace wahoo { +namespace health { + +static constexpr int kBucketCount = 8; + +class CycleCountBackupRestore { +public: + CycleCountBackupRestore(); + void Restore(); + void Backup(); + +private: + int sw_bins_[kBucketCount]; + int hw_bins_[kBucketCount]; + + void ReadFromStorage(); + void SaveToStorage(); + void ReadFromSRAM(); + void SaveToSRAM(); + void UpdateAndSave(); +}; + +} // namespace health +} // namespace wahoo +} // namespace google +} // namespace device + +#endif // #ifndef DEVICE_GOOGLE_WAHOO_HEALTH_CYCLECOUNTBACKUPRESTORE_H diff --git a/health/HealthService.cpp b/health/HealthService.cpp index 1e7b4508..45d18c30 100644 --- a/health/HealthService.cpp +++ b/health/HealthService.cpp @@ -27,14 +27,50 @@ #include #include +#include "CycleCountBackupRestore.h" + using android::hardware::health::V2_0::StorageInfo; using android::hardware::health::V2_0::DiskStats; +using ::device::google::wahoo::health::CycleCountBackupRestore; -void healthd_board_init(struct healthd_config*) { +static constexpr int kBackupTrigger = 20; +static CycleCountBackupRestore ccBackupRestore; + +int cycle_count_backup(int battery_level) +{ + static int saved_soc = 0; + static int soc_inc = 0; + static bool is_first = true; + + if (is_first) { + is_first = false; + saved_soc = battery_level; + return 0; + } + + if (battery_level > saved_soc) { + soc_inc += battery_level - saved_soc; + } + + saved_soc = battery_level; + + if (soc_inc >= kBackupTrigger) { + ccBackupRestore.Backup(); + soc_inc = 0; + } + return 0; } -int healthd_board_battery_update(struct android::BatteryProperties*) { - return 0; +// See : hardware/interfaces/health/2.0/README + +void healthd_board_init(struct healthd_config*) +{ + ccBackupRestore.Restore(); +} + +int healthd_board_battery_update(struct android::BatteryProperties *props) +{ + return cycle_count_backup(props->batteryLevel); } const char kUFSHealthFile[] = "/sys/kernel/debug/ufshcd0/dump_health_desc"; diff --git a/init.hardware.rc b/init.hardware.rc index 50f8c27a..d1c20db2 100644 --- a/init.hardware.rc +++ b/init.hardware.rc @@ -187,6 +187,10 @@ on fs chmod 0770 /persist/rfs/apq chmod 0770 /persist/rfs/apq/gnss chmod 0770 /persist/hlos_rfs + + # for android.hardware.health@2.0-service.marlin cycle count backup + mkdir /persist/battery 0700 system system + restorecon_recursive /persist # Start HW service manager early @@ -425,6 +429,11 @@ on early-boot chown system system /sys/class/leds/blue/rgb_start chown system system /sys/class/graphics/fb0/msm_fb_persist_mode + # dumpstate needs to read, vendor.health-hal needs to be able to RW + chown system system /sys/devices/soc/800f000.qcom,spmi/spmi-0/spmi0-02/800f000.qcom,spmi:qcom,pmi8998@2:qpnp,fg/cycle_counts_bins + # HardwareInfo needs to be able to read CC bins + chmod 644 /sys/devices/soc/800f000.qcom,spmi/spmi-0/spmi0-02/800f000.qcom,spmi:qcom,pmi8998@2:qpnp,fg/cycle_counts_bins + on boot mkdir /dev/socket/qmux_radio 0770 radio radio chmod 2770 /dev/socket/qmux_radio diff --git a/sepolicy/vendor/file.te b/sepolicy/vendor/file.te index 821859af..108b7361 100644 --- a/sepolicy/vendor/file.te +++ b/sepolicy/vendor/file.te @@ -63,6 +63,7 @@ type persist_haptics_file, file_type; type persist_rfs_file, file_type; type persist_sensors_file, file_type; type persist_time_file, file_type; +type persist_battery_file, file_type; type netmgr_data_file, file_type, data_file_type; type ipa_vendor_data_file, file_type, data_file_type; diff --git a/sepolicy/vendor/file_contexts b/sepolicy/vendor/file_contexts index 8a9359a0..f08778fe 100644 --- a/sepolicy/vendor/file_contexts +++ b/sepolicy/vendor/file_contexts @@ -286,6 +286,7 @@ /persist/rfs(/.*)? u:object_r:persist_rfs_file:s0 /persist/sensors(/.*)? u:object_r:persist_sensors_file:s0 /persist/time(/.*)? u:object_r:persist_time_file:s0 +/persist/battery(/.*)? u:object_r:persist_battery_file:s0 /metadata u:object_r:rootfs:s0 /metadata/.* u:object_r:vold_data_file:s0 diff --git a/sepolicy/vendor/genfs_contexts b/sepolicy/vendor/genfs_contexts index dd1ad28a..e9b72e6a 100644 --- a/sepolicy/vendor/genfs_contexts +++ b/sepolicy/vendor/genfs_contexts @@ -61,7 +61,7 @@ genfscon sysfs /devices/soc/8c0000.qcom,msm-cam u:object genfscon sysfs /devices/soc0 u:object_r:sysfs_soc:s0 genfscon sysfs /devices/soc/caa0000.qcom,jpeg u:object_r:sysfs_camera:s0 genfscon sysfs /devices/soc/caa4000.qcom,fd u:object_r:sysfs_camera:s0 -genfscon sysfs /devices/soc/800f000.qcom,spmi/spmi-0/spmi0-02/800f000.qcom,spmi:qcom,pmi8998@2:qpnp,fg/power_supply u:object_r:sysfs_batteryinfo:s0 +genfscon sysfs /devices/soc/800f000.qcom,spmi/spmi-0/spmi0-02/800f000.qcom,spmi:qcom,pmi8998@2:qpnp,fg u:object_r:sysfs_batteryinfo:s0 genfscon sysfs /devices/soc/800f000.qcom,spmi/spmi-0/spmi0-02/800f000.qcom,spmi:qcom,pmi8998@2:qcom,qpnp-smb2/power_supply u:object_r:sysfs_batteryinfo:s0 genfscon sysfs /bus/msm_subsys u:object_r:sysfs_msm_subsys:s0 genfscon sysfs /module/subsystem_restart u:object_r:sysfs_msm_subsys_restart:s0 diff --git a/sepolicy/vendor/hal_dumpstate_impl.te b/sepolicy/vendor/hal_dumpstate_impl.te index 26d29cf9..39a89957 100644 --- a/sepolicy/vendor/hal_dumpstate_impl.te +++ b/sepolicy/vendor/hal_dumpstate_impl.te @@ -75,7 +75,7 @@ dontaudit hal_dumpstate_impl debugfs_dma_bufinfo:file r_file_perms; # Query and dump power supply nodes allow hal_dumpstate_impl sysfs_batteryinfo:dir search; -allow hal_dumpstate_impl sysfs_batteryinfo:file rw_file_perms; +allow hal_dumpstate_impl sysfs_batteryinfo:file r_file_perms; # Dump QCOM FG content allow hal_dumpstate_impl debugfs_fg_sram:dir search; diff --git a/sepolicy/vendor/hal_health_default.te b/sepolicy/vendor/hal_health_default.te index 9f7f6815..bb3a65a7 100644 --- a/sepolicy/vendor/hal_health_default.te +++ b/sepolicy/vendor/hal_health_default.te @@ -4,3 +4,8 @@ allow hal_health_default debugfs_ufs:dir search; allow hal_health_default sysfs_scsi_devices_0000:dir search; allow hal_health_default debugfs_ufs:file { getattr open read }; allow hal_health_default sysfs_scsi_devices_0000:file { getattr open read }; + +allow hal_health_default persist_battery_file:file create_file_perms; +allow hal_health_default persist_battery_file:dir rw_dir_perms; +allow hal_health_default persist_file:dir search; +allow hal_health_default sysfs_batteryinfo:file rw_file_perms; diff --git a/sepolicy/vendor/hardware_info_app.te b/sepolicy/vendor/hardware_info_app.te index ba57b624..27ce4405 100644 --- a/sepolicy/vendor/hardware_info_app.te +++ b/sepolicy/vendor/hardware_info_app.te @@ -14,8 +14,7 @@ allow hardware_info_app shell_data_file:file { open read }; # SysFS allow hardware_info_app sysfs_batteryinfo:dir search; -allow hardware_info_app sysfs_batteryinfo:file { getattr open read write }; -allow hardware_info_app sysfs_batteryinfo:file write; +allow hardware_info_app sysfs_batteryinfo:file { getattr open read }; allow hardware_info_app sysfs_camera:dir search; allow hardware_info_app sysfs_camera:file { getattr open read }; allow hardware_info_app sysfs_msm_subsys:dir search;