Merge "Grant wmtrace access to platform_app:systemui"
diff --git a/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp b/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp
index 28154a7..a05bcec 100644
--- a/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp
+++ b/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp
@@ -303,86 +303,8 @@
}
}
-static void print_main_thread(CallbackType callback, const Tombstone& tombstone,
- const Thread& thread) {
+static void print_memory_maps(CallbackType callback, const Tombstone& tombstone) {
int word_size = pointer_width(tombstone);
- print_thread_header(callback, tombstone, thread, true);
-
- const Signal& signal_info = tombstone.signal_info();
- std::string sender_desc;
-
- if (signal_info.has_sender()) {
- sender_desc =
- StringPrintf(" from pid %d, uid %d", signal_info.sender_pid(), signal_info.sender_uid());
- }
-
- if (!tombstone.has_signal_info()) {
- CBL("signal information missing");
- } else {
- std::string fault_addr_desc;
- if (signal_info.has_fault_address()) {
- fault_addr_desc = StringPrintf("0x%0*" PRIx64, 2 * word_size, signal_info.fault_address());
- } else {
- fault_addr_desc = "--------";
- }
-
- CBL("signal %d (%s), code %d (%s%s), fault addr %s", signal_info.number(),
- signal_info.name().c_str(), signal_info.code(), signal_info.code_name().c_str(),
- sender_desc.c_str(), fault_addr_desc.c_str());
- }
-
- if (tombstone.causes_size() == 1) {
- CBL("Cause: %s", tombstone.causes(0).human_readable().c_str());
- }
-
- if (!tombstone.abort_message().empty()) {
- CBL("Abort message: '%s'", tombstone.abort_message().c_str());
- }
-
- print_thread_registers(callback, tombstone, thread, true);
- print_thread_backtrace(callback, tombstone, thread, true);
-
- if (tombstone.causes_size() > 1) {
- CBS("");
- CBL("Note: multiple potential causes for this crash were detected, listing them in decreasing "
- "order of likelihood.");
- }
-
- for (const Cause& cause : tombstone.causes()) {
- if (tombstone.causes_size() > 1) {
- CBS("");
- CBL("Cause: %s", cause.human_readable().c_str());
- }
-
- if (cause.has_memory_error() && cause.memory_error().has_heap()) {
- const HeapObject& heap_object = cause.memory_error().heap();
-
- if (heap_object.deallocation_backtrace_size() != 0) {
- CBS("");
- CBL("deallocated by thread %" PRIu64 ":", heap_object.deallocation_tid());
- print_backtrace(callback, tombstone, heap_object.deallocation_backtrace(), true);
- }
-
- if (heap_object.allocation_backtrace_size() != 0) {
- CBS("");
- CBL("allocated by thread %" PRIu64 ":", heap_object.allocation_tid());
- print_backtrace(callback, tombstone, heap_object.allocation_backtrace(), true);
- }
- }
- }
-
- print_tag_dump(callback, tombstone);
-
- print_thread_memory_dump(callback, tombstone, thread);
-
- CBS("");
-
- // No memory maps to print.
- if (tombstone.memory_mappings().empty()) {
- CBS("No memory maps found");
- return;
- }
-
const auto format_pointer = [word_size](uint64_t ptr) -> std::string {
if (word_size == 8) {
uint64_t top = ptr >> 32;
@@ -397,6 +319,7 @@
StringPrintf("memory map (%d %s):", tombstone.memory_mappings().size(),
tombstone.memory_mappings().size() == 1 ? "entry" : "entries");
+ const Signal& signal_info = tombstone.signal_info();
bool has_fault_address = signal_info.has_fault_address();
uint64_t fault_address = untag_address(signal_info.fault_address());
bool preamble_printed = false;
@@ -456,6 +379,106 @@
}
}
+static void print_main_thread(CallbackType callback, const Tombstone& tombstone,
+ const Thread& thread) {
+ print_thread_header(callback, tombstone, thread, true);
+
+ const Signal& signal_info = tombstone.signal_info();
+ std::string sender_desc;
+
+ if (signal_info.has_sender()) {
+ sender_desc =
+ StringPrintf(" from pid %d, uid %d", signal_info.sender_pid(), signal_info.sender_uid());
+ }
+
+ bool is_async_mte_crash = false;
+ bool is_mte_crash = false;
+ if (!tombstone.has_signal_info()) {
+ CBL("signal information missing");
+ } else {
+ std::string fault_addr_desc;
+ if (signal_info.has_fault_address()) {
+ fault_addr_desc =
+ StringPrintf("0x%0*" PRIx64, 2 * pointer_width(tombstone), signal_info.fault_address());
+ } else {
+ fault_addr_desc = "--------";
+ }
+
+ CBL("signal %d (%s), code %d (%s%s), fault addr %s", signal_info.number(),
+ signal_info.name().c_str(), signal_info.code(), signal_info.code_name().c_str(),
+ sender_desc.c_str(), fault_addr_desc.c_str());
+#ifdef SEGV_MTEAERR
+ is_async_mte_crash = signal_info.number() == SIGSEGV && signal_info.code() == SEGV_MTEAERR;
+ is_mte_crash = is_async_mte_crash ||
+ (signal_info.number() == SIGSEGV && signal_info.code() == SEGV_MTESERR);
+#endif
+ }
+
+ if (tombstone.causes_size() == 1) {
+ CBL("Cause: %s", tombstone.causes(0).human_readable().c_str());
+ }
+
+ if (!tombstone.abort_message().empty()) {
+ CBL("Abort message: '%s'", tombstone.abort_message().c_str());
+ }
+
+ print_thread_registers(callback, tombstone, thread, true);
+ if (is_async_mte_crash) {
+ CBL("Note: This crash is a delayed async MTE crash. Memory corruption has occurred");
+ CBL(" in this process. The stack trace below is the first system call or context");
+ CBL(" switch that was executed after the memory corruption happened.");
+ }
+ print_thread_backtrace(callback, tombstone, thread, true);
+
+ if (tombstone.causes_size() > 1) {
+ CBS("");
+ CBL("Note: multiple potential causes for this crash were detected, listing them in decreasing "
+ "order of likelihood.");
+ }
+
+ for (const Cause& cause : tombstone.causes()) {
+ if (tombstone.causes_size() > 1) {
+ CBS("");
+ CBL("Cause: %s", cause.human_readable().c_str());
+ }
+
+ if (cause.has_memory_error() && cause.memory_error().has_heap()) {
+ const HeapObject& heap_object = cause.memory_error().heap();
+
+ if (heap_object.deallocation_backtrace_size() != 0) {
+ CBS("");
+ CBL("deallocated by thread %" PRIu64 ":", heap_object.deallocation_tid());
+ print_backtrace(callback, tombstone, heap_object.deallocation_backtrace(), true);
+ }
+
+ if (heap_object.allocation_backtrace_size() != 0) {
+ CBS("");
+ CBL("allocated by thread %" PRIu64 ":", heap_object.allocation_tid());
+ print_backtrace(callback, tombstone, heap_object.allocation_backtrace(), true);
+ }
+ }
+ }
+
+ print_tag_dump(callback, tombstone);
+
+ if (is_mte_crash) {
+ CBS("");
+ CBL("Learn more about MTE reports: "
+ "https://source.android.com/docs/security/test/memory-safety/mte-reports");
+ }
+
+ print_thread_memory_dump(callback, tombstone, thread);
+
+ CBS("");
+
+ // No memory maps to print.
+ if (!tombstone.memory_mappings().empty()) {
+ print_memory_maps(callback, tombstone);
+ } else {
+ CBS("No memory maps found");
+ }
+}
+
void print_logs(CallbackType callback, const Tombstone& tombstone, int tail) {
for (const auto& buffer : tombstone.log_buffers()) {
if (tail) {
diff --git a/fastboot/Android.bp b/fastboot/Android.bp
index 765174b..a801900 100644
--- a/fastboot/Android.bp
+++ b/fastboot/Android.bp
@@ -170,7 +170,7 @@
"android.hardware.fastboot@1.1",
"android.hardware.fastboot-V1-ndk",
"android.hardware.health@2.0",
- "android.hardware.health-V1-ndk",
+ "android.hardware.health-V2-ndk",
"libasyncio",
"libbase",
"libbinder_ndk",
diff --git a/fs_mgr/TEST_MAPPING b/fs_mgr/TEST_MAPPING
index 2b5e337..b6710d5 100644
--- a/fs_mgr/TEST_MAPPING
+++ b/fs_mgr/TEST_MAPPING
@@ -22,6 +22,12 @@
"name": "vts_libsnapshot_test"
},
{
+ "name": "vab_legacy_tests"
+ },
+ {
+ "name": "vabc_legacy_tests"
+ },
+ {
"name": "libsnapshot_fuzzer_test"
},
{
@@ -37,6 +43,12 @@
},
{
"name": "vts_libsnapshot_test"
+ },
+ {
+ "name": "vab_legacy_tests"
+ },
+ {
+ "name": "vabc_legacy_tests"
}
]
}
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index 46f54cc..46cdb62 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -33,7 +33,7 @@
*/
#define FS_MGR_CHECK(x) CHECK(x) << "in libfs_mgr "
-#define FS_MGR_TAG "[libfs_mgr]"
+#define FS_MGR_TAG "[libfs_mgr] "
// Logs a message to kernel
#define LINFO LOG(INFO) << FS_MGR_TAG
diff --git a/fs_mgr/libdm/Android.bp b/fs_mgr/libdm/Android.bp
index 2bb9035..5cc0346 100644
--- a/fs_mgr/libdm/Android.bp
+++ b/fs_mgr/libdm/Android.bp
@@ -90,19 +90,3 @@
min_shipping_api_level: 29,
},
}
-
-cc_fuzz {
- name: "dm_linear_table_fuzzer",
- defaults: ["fs_mgr_defaults"],
- srcs: [
- "dm_linear_fuzzer.cpp",
- "test_util.cpp",
- ],
- static_libs: [
- "libdm",
- "libbase",
- "libext2_uuid",
- "libfs_mgr",
- "liblog",
- ],
-}
diff --git a/fs_mgr/libdm/dm_linear_fuzzer.cpp b/fs_mgr/libdm/dm_linear_fuzzer.cpp
deleted file mode 100644
index 8462901..0000000
--- a/fs_mgr/libdm/dm_linear_fuzzer.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2019 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 <stddef.h>
-#include <stdint.h>
-#include <string.h>
-
-#include <chrono>
-
-#include <android-base/file.h>
-#include <android-base/unique_fd.h>
-#include <libdm/dm_table.h>
-#include <libdm/loop_control.h>
-
-#include "test_util.h"
-
-using namespace android;
-using namespace android::base;
-using namespace android::dm;
-using namespace std;
-using namespace std::chrono_literals;
-
-/*
- * This test aims at making the library crash, so these functions are not
- * really useful.
- * Keeping them here for future use.
- */
-template <class T, class C>
-void ASSERT_EQ(const T& /*a*/, const C& /*b*/) {
- // if (a != b) {}
-}
-
-template <class T>
-void ASSERT_FALSE(const T& /*a*/) {
- // if (a) {}
-}
-
-template <class T, class C>
-void ASSERT_GE(const T& /*a*/, const C& /*b*/) {
- // if (a < b) {}
-}
-
-template <class T, class C>
-void ASSERT_NE(const T& /*a*/, const C& /*b*/) {
- // if (a == b) {}
-}
-
-template <class T>
-void ASSERT_TRUE(const T& /*a*/) {
- // if (!a) {}
-}
-
-template <class T, class C>
-void EXPECT_EQ(const T& a, const C& b) {
- ASSERT_EQ(a, b);
-}
-
-template <class T>
-void EXPECT_TRUE(const T& a) {
- ASSERT_TRUE(a);
-}
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- uint64_t val[6];
-
- if (size != sizeof(val)) {
- return 0;
- }
-
- memcpy(&val, &data[0], sizeof(*val));
-
- unique_fd tmp1(CreateTempFile("file_1", 4096));
- ASSERT_GE(tmp1, 0);
- unique_fd tmp2(CreateTempFile("file_2", 4096));
- ASSERT_GE(tmp2, 0);
-
- LoopDevice loop_a(tmp1, 10s);
- ASSERT_TRUE(loop_a.valid());
- LoopDevice loop_b(tmp2, 10s);
- ASSERT_TRUE(loop_b.valid());
-
- // Define a 2-sector device, with each sector mapping to the first sector
- // of one of our loop devices.
- DmTable table;
- ASSERT_TRUE(table.Emplace<DmTargetLinear>(val[0], val[1], loop_a.device(), val[2]));
- ASSERT_TRUE(table.Emplace<DmTargetLinear>(val[3], val[4], loop_b.device(), val[5]));
- ASSERT_TRUE(table.valid());
- ASSERT_EQ(2u, table.num_sectors());
-
- TempDevice dev("libdm-test-dm-linear", table);
- ASSERT_TRUE(dev.valid());
- ASSERT_FALSE(dev.path().empty());
-
- auto& dm = DeviceMapper::Instance();
-
- dev_t dev_number;
- ASSERT_TRUE(dm.GetDeviceNumber(dev.name(), &dev_number));
- ASSERT_NE(dev_number, 0);
-
- std::string dev_string;
- ASSERT_TRUE(dm.GetDeviceString(dev.name(), &dev_string));
- ASSERT_FALSE(dev_string.empty());
-
- // Test GetTableStatus.
- vector<DeviceMapper::TargetInfo> targets;
- ASSERT_TRUE(dm.GetTableStatus(dev.name(), &targets));
- ASSERT_EQ(targets.size(), 2);
- EXPECT_EQ(strcmp(targets[0].spec.target_type, "linear"), 0);
- EXPECT_TRUE(targets[0].data.empty());
- EXPECT_EQ(targets[0].spec.sector_start, 0);
- EXPECT_EQ(targets[0].spec.length, 1);
- EXPECT_EQ(strcmp(targets[1].spec.target_type, "linear"), 0);
- EXPECT_TRUE(targets[1].data.empty());
- EXPECT_EQ(targets[1].spec.sector_start, 1);
- EXPECT_EQ(targets[1].spec.length, 1);
-
- // Test GetTargetType().
- EXPECT_EQ(DeviceMapper::GetTargetType(targets[0].spec), std::string{"linear"});
- EXPECT_EQ(DeviceMapper::GetTargetType(targets[1].spec), std::string{"linear"});
-
- // Normally the TestDevice destructor would delete this, but at least one
- // test should ensure that device deletion works.
- ASSERT_TRUE(dev.Destroy());
-
- return 0;
-}
diff --git a/fs_mgr/libdm/dm_test.cpp b/fs_mgr/libdm/dm_test.cpp
index 4448d35..788cf51 100644
--- a/fs_mgr/libdm/dm_test.cpp
+++ b/fs_mgr/libdm/dm_test.cpp
@@ -19,6 +19,7 @@
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
+#include <sys/utsname.h>
#include <time.h>
#include <unistd.h>
@@ -692,7 +693,17 @@
}
TEST(libdm, UeventAfterLoadTable) {
- static const char* kDeviceName = "libmd-test-uevent-load-table";
+ static const char* kDeviceName = "libdm-test-uevent-load-table";
+
+ struct utsname u;
+ ASSERT_EQ(uname(&u), 0);
+
+ unsigned int major, minor;
+ ASSERT_EQ(sscanf(u.release, "%u.%u", &major, &minor), 2);
+
+ if (major < 5 || (major == 5 && minor < 15)) {
+ GTEST_SKIP() << "Skipping test on kernel < 5.15";
+ }
DeviceMapper& dm = DeviceMapper::Instance();
ASSERT_TRUE(dm.CreateEmptyDevice(kDeviceName));
diff --git a/fs_mgr/libfs_avb/util.h b/fs_mgr/libfs_avb/util.h
index 427ab7c..29d1e9c 100644
--- a/fs_mgr/libfs_avb/util.h
+++ b/fs_mgr/libfs_avb/util.h
@@ -31,7 +31,7 @@
using android::base::ErrnoError;
using android::base::Result;
-#define FS_AVB_TAG "[libfs_avb]"
+#define FS_AVB_TAG "[libfs_avb] "
// Logs a message to kernel
#define LINFO LOG(INFO) << FS_AVB_TAG
diff --git a/fs_mgr/liblp/utility.h b/fs_mgr/liblp/utility.h
index aa3a6a0..32a59a5 100644
--- a/fs_mgr/liblp/utility.h
+++ b/fs_mgr/liblp/utility.h
@@ -30,7 +30,7 @@
#include "liblp/liblp.h"
-#define LP_TAG "[liblp]"
+#define LP_TAG "[liblp] "
#define LWARN LOG(WARNING) << LP_TAG
#define LINFO LOG(INFO) << LP_TAG
#define LERROR LOG(ERROR) << LP_TAG
diff --git a/fs_mgr/libsnapshot/Android.bp b/fs_mgr/libsnapshot/Android.bp
index 2165961..c2f435f 100644
--- a/fs_mgr/libsnapshot/Android.bp
+++ b/fs_mgr/libsnapshot/Android.bp
@@ -269,14 +269,19 @@
defaults: ["libsnapshot_test_defaults", "libsnapshot_hal_deps"],
}
-sh_test {
- name: "run_snapshot_tests",
- src: "run_snapshot_tests.sh",
- test_suites: [
- "device-tests",
+cc_test {
+ name: "vab_legacy_tests",
+ defaults: ["libsnapshot_test_defaults", "libsnapshot_hal_deps"],
+ cppflags: [
+ "-DLIBSNAPSHOT_TEST_VAB_LEGACY",
],
- required: [
- "vts_libsnapshot_test",
+}
+
+cc_test {
+ name: "vabc_legacy_tests",
+ defaults: ["libsnapshot_test_defaults", "libsnapshot_hal_deps"],
+ cppflags: [
+ "-DLIBSNAPSHOT_TEST_VABC_LEGACY",
],
}
diff --git a/fs_mgr/libsnapshot/run_snapshot_tests.sh b/fs_mgr/libsnapshot/run_snapshot_tests.sh
deleted file mode 100644
index b03a4e0..0000000
--- a/fs_mgr/libsnapshot/run_snapshot_tests.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/system/bin/sh
-
-# Detect host or AOSP.
-getprop ro.build.version.sdk > /dev/null 2>&1
-if [ $? -eq 0 ]; then
- cmd_prefix=""
- local_root=""
-else
- cmd_prefix="adb shell"
- local_root="${ANDROID_PRODUCT_OUT}"
- set -e
- set -x
- adb root
- adb sync data
- set +x
- set +e
-fi
-
-testpath64="/data/nativetest64/vts_libsnapshot_test/vts_libsnapshot_test"
-testpath32="/data/nativetest/vts_libsnapshot_test/vts_libsnapshot_test"
-if [ -f "${local_root}/${testpath64}" ]; then
- testpath="${testpath64}"
-elif [ -f "${local_root}/${testpath32}" ]; then
- testpath="${testpath32}"
-else
- echo "ERROR: vts_libsnapshot_test not found." 1>&2
- echo "Make sure to build vts_libsnapshot_test or snapshot_tests first." 1>&2
- exit 1
-fi
-
-# Verbose, error on failure.
-set -x
-set -e
-
-time ${cmd_prefix} ${testpath}
diff --git a/fs_mgr/libsnapshot/snapshot_test.cpp b/fs_mgr/libsnapshot/snapshot_test.cpp
index 2c01cf6..4014380 100644
--- a/fs_mgr/libsnapshot/snapshot_test.cpp
+++ b/fs_mgr/libsnapshot/snapshot_test.cpp
@@ -53,7 +53,15 @@
#include <libsnapshot/mock_device_info.h>
#include <libsnapshot/mock_snapshot.h>
-DEFINE_string(force_mode, "",
+#if defined(LIBSNAPSHOT_TEST_VAB_LEGACY)
+#define DEFAULT_MODE "vab-legacy"
+#elif defined(LIBSNAPSHOT_TEST_VABC_LEGACY)
+#define DEFAULT_MODE "vabc-legacy"
+#else
+#define DEFAULT_MODE ""
+#endif
+
+DEFINE_string(force_mode, DEFAULT_MODE,
"Force testing older modes (vab-legacy, vabc-legacy) ignoring device config.");
DEFINE_string(force_iouring_disable, "",
"Force testing mode (iouring_disabled) - disable io_uring");
diff --git a/fs_mgr/libvbmeta/utility.h b/fs_mgr/libvbmeta/utility.h
index 91db0ad..ab9828d 100644
--- a/fs_mgr/libvbmeta/utility.h
+++ b/fs_mgr/libvbmeta/utility.h
@@ -19,7 +19,7 @@
#include <android-base/logging.h>
#include <android-base/result.h>
-#define VBMETA_TAG "[libvbmeta]"
+#define VBMETA_TAG "[libvbmeta] "
#define LWARN LOG(WARNING) << VBMETA_TAG
#define LINFO LOG(INFO) << VBMETA_TAG
#define LERROR LOG(ERROR) << VBMETA_TAG
diff --git a/healthd/Android.bp b/healthd/Android.bp
index 76b6ad0..235303f 100644
--- a/healthd/Android.bp
+++ b/healthd/Android.bp
@@ -4,7 +4,6 @@
cc_defaults {
name: "libbatterymonitor_defaults",
- srcs: ["BatteryMonitor.cpp"],
cflags: ["-Wall", "-Werror"],
vendor_available: true,
recovery_available: true,
@@ -75,8 +74,9 @@
cc_library_static {
name: "libbatterymonitor",
defaults: ["libbatterymonitor_defaults"],
+ srcs: ["BatteryMonitor.cpp"],
static_libs: [
- "android.hardware.health-V1-ndk",
+ "android.hardware.health-V2-ndk",
],
whole_static_libs: [
// Need to translate HIDL to AIDL to support legacy APIs in
@@ -89,6 +89,7 @@
cc_library_static {
name: "libbatterymonitor-V1",
defaults: ["libbatterymonitor_defaults"],
+ srcs: ["BatteryMonitor_v1.cpp"],
static_libs: [
"android.hardware.health-V1-ndk",
],
@@ -202,12 +203,12 @@
defaults: ["libhealthd_charger_ui_defaults"],
static_libs: [
- "android.hardware.health-V1-ndk",
+ "android.hardware.health-V2-ndk",
"android.hardware.health-translate-ndk",
],
export_static_lib_headers: [
- "android.hardware.health-V1-ndk",
+ "android.hardware.health-V2-ndk",
],
}
@@ -279,7 +280,7 @@
static_libs: [
// common
"android.hardware.health@1.0-convert",
- "android.hardware.health-V1-ndk",
+ "android.hardware.health-V2-ndk",
"libbatterymonitor",
"libcharger_sysprop",
"libhealthd_charger_nops",
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index a7571a2..4ea452a 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -55,7 +55,10 @@
using HealthInfo_2_0 = android::hardware::health::V2_0::HealthInfo;
using HealthInfo_2_1 = android::hardware::health::V2_1::HealthInfo;
using aidl::android::hardware::health::BatteryCapacityLevel;
+using aidl::android::hardware::health::BatteryChargingPolicy;
+using aidl::android::hardware::health::BatteryChargingState;
using aidl::android::hardware::health::BatteryHealth;
+using aidl::android::hardware::health::BatteryHealthData;
using aidl::android::hardware::health::BatteryStatus;
using aidl::android::hardware::health::HealthInfo;
@@ -227,6 +230,37 @@
return *ret;
}
+BatteryChargingPolicy getBatteryChargingPolicy(const char* chargingPolicy) {
+ static SysfsStringEnumMap<BatteryChargingPolicy> batteryChargingPolicyMap[] = {
+ {"0", BatteryChargingPolicy::INVALID}, {"1", BatteryChargingPolicy::DEFAULT},
+ {"2", BatteryChargingPolicy::LONG_LIFE}, {"3", BatteryChargingPolicy::ADAPTIVE},
+ {NULL, BatteryChargingPolicy::DEFAULT},
+ };
+
+ auto ret = mapSysfsString(chargingPolicy, batteryChargingPolicyMap);
+ if (!ret) {
+ *ret = BatteryChargingPolicy::DEFAULT;
+ }
+
+ return *ret;
+}
+
+BatteryChargingState getBatteryChargingState(const char* chargingState) {
+ static SysfsStringEnumMap<BatteryChargingState> batteryChargingStateMap[] = {
+ {"0", BatteryChargingState::INVALID}, {"1", BatteryChargingState::NORMAL},
+ {"2", BatteryChargingState::TOO_COLD}, {"3", BatteryChargingState::TOO_HOT},
+ {"4", BatteryChargingState::LONG_LIFE}, {"5", BatteryChargingState::ADAPTIVE},
+ {NULL, BatteryChargingState::NORMAL},
+ };
+
+ auto ret = mapSysfsString(chargingState, batteryChargingStateMap);
+ if (!ret) {
+ *ret = BatteryChargingState::NORMAL;
+ }
+
+ return *ret;
+}
+
static int readFromFile(const String8& path, std::string* buf) {
buf->clear();
if (android::base::ReadFileToString(path.c_str(), buf)) {
@@ -235,6 +269,10 @@
return buf->length();
}
+static bool writeToFile(const String8& path, int32_t in_value) {
+ return android::base::WriteStringToFile(std::to_string(in_value), path.c_str());
+}
+
static BatteryMonitor::PowerSupplyType readPowerSupplyType(const String8& path) {
static SysfsStringEnumMap<int> supplyTypeMap[] = {
{"Unknown", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_UNKNOWN},
@@ -336,6 +374,17 @@
mHealthInfo->batteryFullChargeDesignCapacityUah =
getIntField(mHealthdConfig->batteryFullChargeDesignCapacityUahPath);
+ if (!mHealthdConfig->batteryStateOfHealthPath.isEmpty())
+ mHealthInfo->batteryStateOfHealth = getIntField(mHealthdConfig->batteryStateOfHealthPath);
+
+ if (!mHealthdConfig->batteryManufacturingDatePath.isEmpty())
+ mHealthInfo->batteryHealthData->batteryManufacturingDateSeconds =
+ getIntField(mHealthdConfig->batteryManufacturingDatePath);
+
+ if (!mHealthdConfig->batteryFirstUsageDatePath.isEmpty())
+ mHealthInfo->batteryHealthData->batteryFirstUsageSeconds =
+ getIntField(mHealthdConfig->batteryFirstUsageDatePath);
+
mHealthInfo->batteryTemperatureTenthsCelsius =
mBatteryFixedTemperature ? mBatteryFixedTemperature
: getIntField(mHealthdConfig->batteryTemperaturePath);
@@ -354,6 +403,12 @@
if (readFromFile(mHealthdConfig->batteryTechnologyPath, &buf) > 0)
mHealthInfo->batteryTechnology = String8(buf.c_str());
+ if (readFromFile(mHealthdConfig->chargingPolicyPath, &buf) > 0)
+ mHealthInfo->chargingPolicy = getBatteryChargingPolicy(buf.c_str());
+
+ if (readFromFile(mHealthdConfig->chargingStatePath, &buf) > 0)
+ mHealthInfo->chargingState = getBatteryChargingState(buf.c_str());
+
double MaxPower = 0;
for (size_t i = 0; i < mChargerNames.size(); i++) {
@@ -476,6 +531,43 @@
return static_cast<int>(result);
}
+status_t BatteryMonitor::setChargingPolicy(int value) {
+ status_t ret = NAME_NOT_FOUND;
+ bool result;
+ if (!mHealthdConfig->chargingPolicyPath.isEmpty()) {
+ result = writeToFile(mHealthdConfig->chargingPolicyPath, value);
+ if (!result) {
+ KLOG_WARNING(LOG_TAG, "setChargingPolicy fail\n");
+ ret = BAD_VALUE;
+ } else {
+ ret = OK;
+ }
+ }
+ return ret;
+}
+
+int BatteryMonitor::getChargingPolicy() {
+ BatteryChargingPolicy result = BatteryChargingPolicy::DEFAULT;
+ if (!mHealthdConfig->chargingPolicyPath.isEmpty()) {
+ std::string buf;
+ if (readFromFile(mHealthdConfig->chargingPolicyPath, &buf) > 0)
+ result = getBatteryChargingPolicy(buf.c_str());
+ }
+ return static_cast<int>(result);
+}
+
+int BatteryMonitor::getBatteryHealthData(int id) {
+ if (id == BATTERY_PROP_MANUFACTURING_DATE) {
+ if (!mHealthdConfig->batteryManufacturingDatePath.isEmpty())
+ return getIntField(mHealthdConfig->batteryManufacturingDatePath);
+ }
+ if (id == BATTERY_PROP_FIRST_USAGE_DATE) {
+ if (!mHealthdConfig->batteryFirstUsageDatePath.isEmpty())
+ return getIntField(mHealthdConfig->batteryFirstUsageDatePath);
+ }
+ return 0;
+}
+
status_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) {
status_t ret = BAD_VALUE;
std::string buf;
@@ -536,6 +628,21 @@
ret = OK;
break;
+ case BATTERY_PROP_CHARGING_POLICY:
+ val->valueInt64 = getChargingPolicy();
+ ret = OK;
+ break;
+
+ case BATTERY_PROP_MANUFACTURING_DATE:
+ val->valueInt64 = getBatteryHealthData(BATTERY_PROP_MANUFACTURING_DATE);
+ ret = OK;
+ break;
+
+ case BATTERY_PROP_FIRST_USAGE_DATE:
+ val->valueInt64 = getBatteryHealthData(BATTERY_PROP_FIRST_USAGE_DATE);
+ ret = OK;
+ break;
+
default:
break;
}
@@ -758,6 +865,44 @@
mHealthdConfig->batteryTechnologyPath = path;
}
+ if (mHealthdConfig->batteryStateOfHealthPath.isEmpty()) {
+ path.clear();
+ path.appendFormat("%s/%s/state_of_health", POWER_SUPPLY_SYSFS_PATH, name);
+ if (access(path, R_OK) == 0) {
+ mHealthdConfig->batteryStateOfHealthPath = path;
+ } else {
+ path.clear();
+ path.appendFormat("%s/%s/health_index", POWER_SUPPLY_SYSFS_PATH, name);
+ if (access(path, R_OK) == 0)
+ mHealthdConfig->batteryStateOfHealthPath = path;
+ }
+ }
+
+ if (mHealthdConfig->batteryManufacturingDatePath.isEmpty()) {
+ path.clear();
+ path.appendFormat("%s/%s/manufacturing_date", POWER_SUPPLY_SYSFS_PATH, name);
+ if (access(path, R_OK) == 0)
+ mHealthdConfig->batteryManufacturingDatePath = path;
+ }
+
+ if (mHealthdConfig->batteryFirstUsageDatePath.isEmpty()) {
+ path.clear();
+ path.appendFormat("%s/%s/first_usage_date", POWER_SUPPLY_SYSFS_PATH, name);
+ if (access(path, R_OK) == 0) mHealthdConfig->batteryFirstUsageDatePath = path;
+ }
+
+ if (mHealthdConfig->chargingStatePath.isEmpty()) {
+ path.clear();
+ path.appendFormat("%s/%s/charging_state", POWER_SUPPLY_SYSFS_PATH, name);
+ if (access(path, R_OK) == 0) mHealthdConfig->chargingStatePath = path;
+ }
+
+ if (mHealthdConfig->chargingPolicyPath.isEmpty()) {
+ path.clear();
+ path.appendFormat("%s/%s/charging_policy", POWER_SUPPLY_SYSFS_PATH, name);
+ if (access(path, R_OK) == 0) mHealthdConfig->chargingPolicyPath = path;
+ }
+
break;
case ANDROID_POWER_SUPPLY_TYPE_UNKNOWN:
@@ -810,6 +955,16 @@
KLOG_WARNING(LOG_TAG, "batteryChargeTimeToFullNowPath. not found\n");
if (mHealthdConfig->batteryFullChargeDesignCapacityUahPath.isEmpty())
KLOG_WARNING(LOG_TAG, "batteryFullChargeDesignCapacityUahPath. not found\n");
+ if (mHealthdConfig->batteryStateOfHealthPath.isEmpty())
+ KLOG_WARNING(LOG_TAG, "batteryStateOfHealthPath not found\n");
+ if (mHealthdConfig->batteryManufacturingDatePath.isEmpty())
+ KLOG_WARNING(LOG_TAG, "batteryManufacturingDatePath not found\n");
+ if (mHealthdConfig->batteryFirstUsageDatePath.isEmpty())
+ KLOG_WARNING(LOG_TAG, "batteryFirstUsageDatePath not found\n");
+ if (mHealthdConfig->chargingStatePath.isEmpty())
+ KLOG_WARNING(LOG_TAG, "chargingStatePath not found\n");
+ if (mHealthdConfig->chargingPolicyPath.isEmpty())
+ KLOG_WARNING(LOG_TAG, "chargingPolicyPath not found\n");
}
if (property_get("ro.boot.fake_battery", pval, NULL) > 0
diff --git a/healthd/BatteryMonitor_v1.cpp b/healthd/BatteryMonitor_v1.cpp
new file mode 100644
index 0000000..b87c493
--- /dev/null
+++ b/healthd/BatteryMonitor_v1.cpp
@@ -0,0 +1,822 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#define LOG_TAG "healthd"
+
+#include <healthd/healthd.h>
+#include <healthd/BatteryMonitor_v1.h>
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <memory>
+#include <optional>
+
+#include <aidl/android/hardware/health/HealthInfo.h>
+#include <android-base/file.h>
+#include <android-base/parseint.h>
+#include <android-base/strings.h>
+#include <android/hardware/health/2.1/types.h>
+#include <android/hardware/health/translate-ndk.h>
+#include <batteryservice/BatteryService.h>
+#include <cutils/klog.h>
+#include <cutils/properties.h>
+#include <utils/Errors.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
+
+#define POWER_SUPPLY_SUBSYSTEM "power_supply"
+#define POWER_SUPPLY_SYSFS_PATH "/sys/class/" POWER_SUPPLY_SUBSYSTEM
+#define FAKE_BATTERY_CAPACITY 42
+#define FAKE_BATTERY_TEMPERATURE 424
+#define MILLION 1.0e6
+#define DEFAULT_VBUS_VOLTAGE 5000000
+
+using HealthInfo_1_0 = android::hardware::health::V1_0::HealthInfo;
+using HealthInfo_2_0 = android::hardware::health::V2_0::HealthInfo;
+using HealthInfo_2_1 = android::hardware::health::V2_1::HealthInfo;
+using aidl::android::hardware::health::BatteryCapacityLevel;
+using aidl::android::hardware::health::BatteryHealth;
+using aidl::android::hardware::health::BatteryStatus;
+using aidl::android::hardware::health::HealthInfo;
+
+namespace {
+
+// Translate from AIDL back to HIDL definition for getHealthInfo_*_* calls.
+// Skips storageInfo and diskStats.
+void translateToHidl(const ::aidl::android::hardware::health::HealthInfo& in,
+ ::android::hardware::health::V1_0::HealthInfo* out) {
+ out->chargerAcOnline = in.chargerAcOnline;
+ out->chargerUsbOnline = in.chargerUsbOnline;
+ out->chargerWirelessOnline = in.chargerWirelessOnline;
+ out->maxChargingCurrent = in.maxChargingCurrentMicroamps;
+ out->maxChargingVoltage = in.maxChargingVoltageMicrovolts;
+ out->batteryStatus =
+ static_cast<::android::hardware::health::V1_0::BatteryStatus>(in.batteryStatus);
+ out->batteryHealth =
+ static_cast<::android::hardware::health::V1_0::BatteryHealth>(in.batteryHealth);
+ out->batteryPresent = in.batteryPresent;
+ out->batteryLevel = in.batteryLevel;
+ out->batteryVoltage = in.batteryVoltageMillivolts;
+ out->batteryTemperature = in.batteryTemperatureTenthsCelsius;
+ out->batteryCurrent = in.batteryCurrentMicroamps;
+ out->batteryCycleCount = in.batteryCycleCount;
+ out->batteryFullCharge = in.batteryFullChargeUah;
+ out->batteryChargeCounter = in.batteryChargeCounterUah;
+ out->batteryTechnology = in.batteryTechnology;
+}
+
+void translateToHidl(const ::aidl::android::hardware::health::HealthInfo& in,
+ ::android::hardware::health::V2_0::HealthInfo* out) {
+ translateToHidl(in, &out->legacy);
+ out->batteryCurrentAverage = in.batteryCurrentAverageMicroamps;
+ // Skip storageInfo and diskStats
+}
+
+void translateToHidl(const ::aidl::android::hardware::health::HealthInfo& in,
+ ::android::hardware::health::V2_1::HealthInfo* out) {
+ translateToHidl(in, &out->legacy);
+ out->batteryCapacityLevel = static_cast<android::hardware::health::V2_1::BatteryCapacityLevel>(
+ in.batteryCapacityLevel);
+ out->batteryChargeTimeToFullNowSeconds = in.batteryChargeTimeToFullNowSeconds;
+ out->batteryFullChargeDesignCapacityUah = in.batteryFullChargeDesignCapacityUah;
+}
+
+} // namespace
+
+namespace android {
+
+template <typename T>
+struct SysfsStringEnumMap {
+ const char* s;
+ T val;
+};
+
+template <typename T>
+static std::optional<T> mapSysfsString(const char* str, SysfsStringEnumMap<T> map[]) {
+ for (int i = 0; map[i].s; i++)
+ if (!strcmp(str, map[i].s))
+ return map[i].val;
+
+ return std::nullopt;
+}
+
+static void initHealthInfo(HealthInfo* health_info) {
+ *health_info = {
+ .batteryCapacityLevel = BatteryCapacityLevel::UNSUPPORTED,
+ .batteryChargeTimeToFullNowSeconds =
+ (int64_t)HealthInfo::BATTERY_CHARGE_TIME_TO_FULL_NOW_SECONDS_UNSUPPORTED,
+ .batteryStatus = BatteryStatus::UNKNOWN,
+ .batteryHealth = BatteryHealth::UNKNOWN,
+ };
+}
+
+BatteryMonitor::BatteryMonitor()
+ : mHealthdConfig(nullptr),
+ mBatteryDevicePresent(false),
+ mBatteryFixedCapacity(0),
+ mBatteryFixedTemperature(0),
+ mHealthInfo(std::make_unique<HealthInfo>()) {
+ initHealthInfo(mHealthInfo.get());
+}
+
+BatteryMonitor::~BatteryMonitor() {}
+
+HealthInfo_1_0 BatteryMonitor::getHealthInfo_1_0() const {
+ HealthInfo_1_0 health_info_1_0;
+ translateToHidl(*mHealthInfo, &health_info_1_0);
+ return health_info_1_0;
+}
+
+HealthInfo_2_0 BatteryMonitor::getHealthInfo_2_0() const {
+ HealthInfo_2_0 health_info_2_0;
+ translateToHidl(*mHealthInfo, &health_info_2_0);
+ return health_info_2_0;
+}
+
+HealthInfo_2_1 BatteryMonitor::getHealthInfo_2_1() const {
+ HealthInfo_2_1 health_info_2_1;
+ translateToHidl(*mHealthInfo, &health_info_2_1);
+ return health_info_2_1;
+}
+
+const HealthInfo& BatteryMonitor::getHealthInfo() const {
+ return *mHealthInfo;
+}
+
+BatteryStatus getBatteryStatus(const char* status) {
+ static SysfsStringEnumMap<BatteryStatus> batteryStatusMap[] = {
+ {"Unknown", BatteryStatus::UNKNOWN},
+ {"Charging", BatteryStatus::CHARGING},
+ {"Discharging", BatteryStatus::DISCHARGING},
+ {"Not charging", BatteryStatus::NOT_CHARGING},
+ {"Full", BatteryStatus::FULL},
+ {NULL, BatteryStatus::UNKNOWN},
+ };
+
+ auto ret = mapSysfsString(status, batteryStatusMap);
+ if (!ret) {
+ KLOG_WARNING(LOG_TAG, "Unknown battery status '%s'\n", status);
+ *ret = BatteryStatus::UNKNOWN;
+ }
+
+ return *ret;
+}
+
+BatteryCapacityLevel getBatteryCapacityLevel(const char* capacityLevel) {
+ static SysfsStringEnumMap<BatteryCapacityLevel> batteryCapacityLevelMap[] = {
+ {"Unknown", BatteryCapacityLevel::UNKNOWN},
+ {"Critical", BatteryCapacityLevel::CRITICAL},
+ {"Low", BatteryCapacityLevel::LOW},
+ {"Normal", BatteryCapacityLevel::NORMAL},
+ {"High", BatteryCapacityLevel::HIGH},
+ {"Full", BatteryCapacityLevel::FULL},
+ {NULL, BatteryCapacityLevel::UNSUPPORTED},
+ };
+
+ auto ret = mapSysfsString(capacityLevel, batteryCapacityLevelMap);
+ if (!ret) {
+ KLOG_WARNING(LOG_TAG, "Unsupported battery capacity level '%s'\n", capacityLevel);
+ *ret = BatteryCapacityLevel::UNSUPPORTED;
+ }
+
+ return *ret;
+}
+
+BatteryHealth getBatteryHealth(const char* status) {
+ static SysfsStringEnumMap<BatteryHealth> batteryHealthMap[] = {
+ {"Unknown", BatteryHealth::UNKNOWN},
+ {"Good", BatteryHealth::GOOD},
+ {"Overheat", BatteryHealth::OVERHEAT},
+ {"Dead", BatteryHealth::DEAD},
+ {"Over voltage", BatteryHealth::OVER_VOLTAGE},
+ {"Unspecified failure", BatteryHealth::UNSPECIFIED_FAILURE},
+ {"Cold", BatteryHealth::COLD},
+ // battery health values from JEITA spec
+ {"Warm", BatteryHealth::GOOD},
+ {"Cool", BatteryHealth::GOOD},
+ {"Hot", BatteryHealth::OVERHEAT},
+ {NULL, BatteryHealth::UNKNOWN},
+ };
+
+ auto ret = mapSysfsString(status, batteryHealthMap);
+ if (!ret) {
+ KLOG_WARNING(LOG_TAG, "Unknown battery health '%s'\n", status);
+ *ret = BatteryHealth::UNKNOWN;
+ }
+
+ return *ret;
+}
+
+static int readFromFile(const String8& path, std::string* buf) {
+ buf->clear();
+ if (android::base::ReadFileToString(path.c_str(), buf)) {
+ *buf = android::base::Trim(*buf);
+ }
+ return buf->length();
+}
+
+static BatteryMonitor::PowerSupplyType readPowerSupplyType(const String8& path) {
+ static SysfsStringEnumMap<int> supplyTypeMap[] = {
+ {"Unknown", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_UNKNOWN},
+ {"Battery", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_BATTERY},
+ {"UPS", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
+ {"Mains", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
+ {"USB", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_USB},
+ {"USB_DCP", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
+ {"USB_HVDCP", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
+ {"USB_CDP", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
+ {"USB_ACA", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
+ {"USB_C", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
+ {"USB_PD", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_AC},
+ {"USB_PD_DRP", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_USB},
+ {"Wireless", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_WIRELESS},
+ {"Dock", BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_DOCK},
+ {NULL, 0},
+ };
+ std::string buf;
+
+ if (readFromFile(path, &buf) <= 0) {
+ return BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
+ }
+
+ auto ret = mapSysfsString(buf.c_str(), supplyTypeMap);
+ if (!ret) {
+ KLOG_WARNING(LOG_TAG, "Unknown power supply type '%s'\n", buf.c_str());
+ *ret = BatteryMonitor::ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
+ }
+
+ return static_cast<BatteryMonitor::PowerSupplyType>(*ret);
+}
+
+static bool getBooleanField(const String8& path) {
+ std::string buf;
+ bool value = false;
+
+ if (readFromFile(path, &buf) > 0)
+ if (buf[0] != '0')
+ value = true;
+
+ return value;
+}
+
+static int getIntField(const String8& path) {
+ std::string buf;
+ int value = 0;
+
+ if (readFromFile(path, &buf) > 0)
+ android::base::ParseInt(buf, &value);
+
+ return value;
+}
+
+static bool isScopedPowerSupply(const char* name) {
+ constexpr char kScopeDevice[] = "Device";
+
+ String8 path;
+ path.appendFormat("%s/%s/scope", POWER_SUPPLY_SYSFS_PATH, name);
+ std::string scope;
+ return (readFromFile(path, &scope) > 0 && scope == kScopeDevice);
+}
+
+void BatteryMonitor::updateValues(void) {
+ initHealthInfo(mHealthInfo.get());
+
+ if (!mHealthdConfig->batteryPresentPath.isEmpty())
+ mHealthInfo->batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath);
+ else
+ mHealthInfo->batteryPresent = mBatteryDevicePresent;
+
+ mHealthInfo->batteryLevel = mBatteryFixedCapacity
+ ? mBatteryFixedCapacity
+ : getIntField(mHealthdConfig->batteryCapacityPath);
+ mHealthInfo->batteryVoltageMillivolts = getIntField(mHealthdConfig->batteryVoltagePath) / 1000;
+
+ if (!mHealthdConfig->batteryCurrentNowPath.isEmpty())
+ mHealthInfo->batteryCurrentMicroamps = getIntField(mHealthdConfig->batteryCurrentNowPath);
+
+ if (!mHealthdConfig->batteryFullChargePath.isEmpty())
+ mHealthInfo->batteryFullChargeUah = getIntField(mHealthdConfig->batteryFullChargePath);
+
+ if (!mHealthdConfig->batteryCycleCountPath.isEmpty())
+ mHealthInfo->batteryCycleCount = getIntField(mHealthdConfig->batteryCycleCountPath);
+
+ if (!mHealthdConfig->batteryChargeCounterPath.isEmpty())
+ mHealthInfo->batteryChargeCounterUah =
+ getIntField(mHealthdConfig->batteryChargeCounterPath);
+
+ if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty())
+ mHealthInfo->batteryCurrentAverageMicroamps =
+ getIntField(mHealthdConfig->batteryCurrentAvgPath);
+
+ if (!mHealthdConfig->batteryChargeTimeToFullNowPath.isEmpty())
+ mHealthInfo->batteryChargeTimeToFullNowSeconds =
+ getIntField(mHealthdConfig->batteryChargeTimeToFullNowPath);
+
+ if (!mHealthdConfig->batteryFullChargeDesignCapacityUahPath.isEmpty())
+ mHealthInfo->batteryFullChargeDesignCapacityUah =
+ getIntField(mHealthdConfig->batteryFullChargeDesignCapacityUahPath);
+
+ mHealthInfo->batteryTemperatureTenthsCelsius =
+ mBatteryFixedTemperature ? mBatteryFixedTemperature
+ : getIntField(mHealthdConfig->batteryTemperaturePath);
+
+ std::string buf;
+
+ if (readFromFile(mHealthdConfig->batteryCapacityLevelPath, &buf) > 0)
+ mHealthInfo->batteryCapacityLevel = getBatteryCapacityLevel(buf.c_str());
+
+ if (readFromFile(mHealthdConfig->batteryStatusPath, &buf) > 0)
+ mHealthInfo->batteryStatus = getBatteryStatus(buf.c_str());
+
+ if (readFromFile(mHealthdConfig->batteryHealthPath, &buf) > 0)
+ mHealthInfo->batteryHealth = getBatteryHealth(buf.c_str());
+
+ if (readFromFile(mHealthdConfig->batteryTechnologyPath, &buf) > 0)
+ mHealthInfo->batteryTechnology = String8(buf.c_str());
+
+ double MaxPower = 0;
+
+ for (size_t i = 0; i < mChargerNames.size(); i++) {
+ String8 path;
+ path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH,
+ mChargerNames[i].string());
+ if (getIntField(path)) {
+ path.clear();
+ path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH,
+ mChargerNames[i].string());
+ switch(readPowerSupplyType(path)) {
+ case ANDROID_POWER_SUPPLY_TYPE_AC:
+ mHealthInfo->chargerAcOnline = true;
+ break;
+ case ANDROID_POWER_SUPPLY_TYPE_USB:
+ mHealthInfo->chargerUsbOnline = true;
+ break;
+ case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
+ mHealthInfo->chargerWirelessOnline = true;
+ break;
+ case ANDROID_POWER_SUPPLY_TYPE_DOCK:
+ mHealthInfo->chargerDockOnline = true;
+ break;
+ default:
+ path.clear();
+ path.appendFormat("%s/%s/is_dock", POWER_SUPPLY_SYSFS_PATH,
+ mChargerNames[i].string());
+ if (access(path.string(), R_OK) == 0)
+ mHealthInfo->chargerDockOnline = true;
+ else
+ KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n",
+ mChargerNames[i].string());
+ }
+ path.clear();
+ path.appendFormat("%s/%s/current_max", POWER_SUPPLY_SYSFS_PATH,
+ mChargerNames[i].string());
+ int ChargingCurrent =
+ (access(path.string(), R_OK) == 0) ? getIntField(path) : 0;
+
+ path.clear();
+ path.appendFormat("%s/%s/voltage_max", POWER_SUPPLY_SYSFS_PATH,
+ mChargerNames[i].string());
+
+ int ChargingVoltage =
+ (access(path.string(), R_OK) == 0) ? getIntField(path) :
+ DEFAULT_VBUS_VOLTAGE;
+
+ double power = ((double)ChargingCurrent / MILLION) *
+ ((double)ChargingVoltage / MILLION);
+ if (MaxPower < power) {
+ mHealthInfo->maxChargingCurrentMicroamps = ChargingCurrent;
+ mHealthInfo->maxChargingVoltageMicrovolts = ChargingVoltage;
+ MaxPower = power;
+ }
+ }
+ }
+}
+
+static void doLogValues(const HealthInfo& props, const struct healthd_config& healthd_config) {
+ char dmesgline[256];
+ size_t len;
+ if (props.batteryPresent) {
+ snprintf(dmesgline, sizeof(dmesgline), "battery l=%d v=%d t=%s%d.%d h=%d st=%d",
+ props.batteryLevel, props.batteryVoltageMillivolts,
+ props.batteryTemperatureTenthsCelsius < 0 ? "-" : "",
+ abs(props.batteryTemperatureTenthsCelsius / 10),
+ abs(props.batteryTemperatureTenthsCelsius % 10), props.batteryHealth,
+ props.batteryStatus);
+
+ len = strlen(dmesgline);
+ if (!healthd_config.batteryCurrentNowPath.isEmpty()) {
+ len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " c=%d",
+ props.batteryCurrentMicroamps);
+ }
+
+ if (!healthd_config.batteryFullChargePath.isEmpty()) {
+ len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " fc=%d",
+ props.batteryFullChargeUah);
+ }
+
+ if (!healthd_config.batteryCycleCountPath.isEmpty()) {
+ len += snprintf(dmesgline + len, sizeof(dmesgline) - len, " cc=%d",
+ props.batteryCycleCount);
+ }
+ } else {
+ len = snprintf(dmesgline, sizeof(dmesgline), "battery none");
+ }
+
+ snprintf(dmesgline + len, sizeof(dmesgline) - len, " chg=%s%s%s%s",
+ props.chargerAcOnline ? "a" : "", props.chargerUsbOnline ? "u" : "",
+ props.chargerWirelessOnline ? "w" : "", props.chargerDockOnline ? "d" : "");
+
+ KLOG_WARNING(LOG_TAG, "%s\n", dmesgline);
+}
+
+void BatteryMonitor::logValues(const HealthInfo_2_1& health_info,
+ const struct healthd_config& healthd_config) {
+ HealthInfo aidl_health_info;
+ (void)android::h2a::translate(health_info, &aidl_health_info);
+ doLogValues(aidl_health_info, healthd_config);
+}
+
+void BatteryMonitor::logValues(void) {
+ doLogValues(*mHealthInfo, *mHealthdConfig);
+}
+
+bool BatteryMonitor::isChargerOnline() {
+ const HealthInfo& props = *mHealthInfo;
+ return props.chargerAcOnline | props.chargerUsbOnline | props.chargerWirelessOnline |
+ props.chargerDockOnline;
+}
+
+int BatteryMonitor::getChargeStatus() {
+ BatteryStatus result = BatteryStatus::UNKNOWN;
+ if (!mHealthdConfig->batteryStatusPath.isEmpty()) {
+ std::string buf;
+ if (readFromFile(mHealthdConfig->batteryStatusPath, &buf) > 0)
+ result = getBatteryStatus(buf.c_str());
+ }
+ return static_cast<int>(result);
+}
+
+status_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) {
+ status_t ret = BAD_VALUE;
+ std::string buf;
+
+ val->valueInt64 = LONG_MIN;
+
+ switch(id) {
+ case BATTERY_PROP_CHARGE_COUNTER:
+ if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
+ val->valueInt64 =
+ getIntField(mHealthdConfig->batteryChargeCounterPath);
+ ret = OK;
+ } else {
+ ret = NAME_NOT_FOUND;
+ }
+ break;
+
+ case BATTERY_PROP_CURRENT_NOW:
+ if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
+ val->valueInt64 =
+ getIntField(mHealthdConfig->batteryCurrentNowPath);
+ ret = OK;
+ } else {
+ ret = NAME_NOT_FOUND;
+ }
+ break;
+
+ case BATTERY_PROP_CURRENT_AVG:
+ if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
+ val->valueInt64 =
+ getIntField(mHealthdConfig->batteryCurrentAvgPath);
+ ret = OK;
+ } else {
+ ret = NAME_NOT_FOUND;
+ }
+ break;
+
+ case BATTERY_PROP_CAPACITY:
+ if (!mHealthdConfig->batteryCapacityPath.isEmpty()) {
+ val->valueInt64 =
+ getIntField(mHealthdConfig->batteryCapacityPath);
+ ret = OK;
+ } else {
+ ret = NAME_NOT_FOUND;
+ }
+ break;
+
+ case BATTERY_PROP_ENERGY_COUNTER:
+ if (mHealthdConfig->energyCounter) {
+ ret = mHealthdConfig->energyCounter(&val->valueInt64);
+ } else {
+ ret = NAME_NOT_FOUND;
+ }
+ break;
+
+ case BATTERY_PROP_BATTERY_STATUS:
+ val->valueInt64 = getChargeStatus();
+ ret = OK;
+ break;
+
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+void BatteryMonitor::dumpState(int fd) {
+ int v;
+ char vs[128];
+ const HealthInfo& props = *mHealthInfo;
+
+ snprintf(vs, sizeof(vs),
+ "ac: %d usb: %d wireless: %d dock: %d current_max: %d voltage_max: %d\n",
+ props.chargerAcOnline, props.chargerUsbOnline, props.chargerWirelessOnline,
+ props.chargerDockOnline, props.maxChargingCurrentMicroamps,
+ props.maxChargingVoltageMicrovolts);
+ write(fd, vs, strlen(vs));
+ snprintf(vs, sizeof(vs), "status: %d health: %d present: %d\n",
+ props.batteryStatus, props.batteryHealth, props.batteryPresent);
+ write(fd, vs, strlen(vs));
+ snprintf(vs, sizeof(vs), "level: %d voltage: %d temp: %d\n", props.batteryLevel,
+ props.batteryVoltageMillivolts, props.batteryTemperatureTenthsCelsius);
+ write(fd, vs, strlen(vs));
+
+ if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
+ v = getIntField(mHealthdConfig->batteryCurrentNowPath);
+ snprintf(vs, sizeof(vs), "current now: %d\n", v);
+ write(fd, vs, strlen(vs));
+ }
+
+ if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
+ v = getIntField(mHealthdConfig->batteryCurrentAvgPath);
+ snprintf(vs, sizeof(vs), "current avg: %d\n", v);
+ write(fd, vs, strlen(vs));
+ }
+
+ if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
+ v = getIntField(mHealthdConfig->batteryChargeCounterPath);
+ snprintf(vs, sizeof(vs), "charge counter: %d\n", v);
+ write(fd, vs, strlen(vs));
+ }
+
+ if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
+ snprintf(vs, sizeof(vs), "current now: %d\n", props.batteryCurrentMicroamps);
+ write(fd, vs, strlen(vs));
+ }
+
+ if (!mHealthdConfig->batteryCycleCountPath.isEmpty()) {
+ snprintf(vs, sizeof(vs), "cycle count: %d\n", props.batteryCycleCount);
+ write(fd, vs, strlen(vs));
+ }
+
+ if (!mHealthdConfig->batteryFullChargePath.isEmpty()) {
+ snprintf(vs, sizeof(vs), "Full charge: %d\n", props.batteryFullChargeUah);
+ write(fd, vs, strlen(vs));
+ }
+}
+
+void BatteryMonitor::init(struct healthd_config *hc) {
+ String8 path;
+ char pval[PROPERTY_VALUE_MAX];
+
+ mHealthdConfig = hc;
+ std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(POWER_SUPPLY_SYSFS_PATH), closedir);
+ if (dir == NULL) {
+ KLOG_ERROR(LOG_TAG, "Could not open %s\n", POWER_SUPPLY_SYSFS_PATH);
+ } else {
+ struct dirent* entry;
+
+ while ((entry = readdir(dir.get()))) {
+ const char* name = entry->d_name;
+
+ if (!strcmp(name, ".") || !strcmp(name, ".."))
+ continue;
+
+ std::vector<String8>::iterator itIgnoreName =
+ find(hc->ignorePowerSupplyNames.begin(), hc->ignorePowerSupplyNames.end(),
+ String8(name));
+ if (itIgnoreName != hc->ignorePowerSupplyNames.end())
+ continue;
+
+ // Look for "type" file in each subdirectory
+ path.clear();
+ path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, name);
+ switch(readPowerSupplyType(path)) {
+ case ANDROID_POWER_SUPPLY_TYPE_AC:
+ case ANDROID_POWER_SUPPLY_TYPE_USB:
+ case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
+ case ANDROID_POWER_SUPPLY_TYPE_DOCK:
+ path.clear();
+ path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name);
+ if (access(path.string(), R_OK) == 0)
+ mChargerNames.add(String8(name));
+ break;
+
+ case ANDROID_POWER_SUPPLY_TYPE_BATTERY:
+ // Some devices expose the battery status of sub-component like
+ // stylus. Such a device-scoped battery info needs to be skipped
+ // in BatteryMonitor, which is intended to report the status of
+ // the battery supplying the power to the whole system.
+ if (isScopedPowerSupply(name)) continue;
+ mBatteryDevicePresent = true;
+
+ if (mHealthdConfig->batteryStatusPath.isEmpty()) {
+ path.clear();
+ path.appendFormat("%s/%s/status", POWER_SUPPLY_SYSFS_PATH,
+ name);
+ if (access(path, R_OK) == 0)
+ mHealthdConfig->batteryStatusPath = path;
+ }
+
+ if (mHealthdConfig->batteryHealthPath.isEmpty()) {
+ path.clear();
+ path.appendFormat("%s/%s/health", POWER_SUPPLY_SYSFS_PATH,
+ name);
+ if (access(path, R_OK) == 0)
+ mHealthdConfig->batteryHealthPath = path;
+ }
+
+ if (mHealthdConfig->batteryPresentPath.isEmpty()) {
+ path.clear();
+ path.appendFormat("%s/%s/present", POWER_SUPPLY_SYSFS_PATH,
+ name);
+ if (access(path, R_OK) == 0)
+ mHealthdConfig->batteryPresentPath = path;
+ }
+
+ if (mHealthdConfig->batteryCapacityPath.isEmpty()) {
+ path.clear();
+ path.appendFormat("%s/%s/capacity", POWER_SUPPLY_SYSFS_PATH,
+ name);
+ if (access(path, R_OK) == 0)
+ mHealthdConfig->batteryCapacityPath = path;
+ }
+
+ if (mHealthdConfig->batteryVoltagePath.isEmpty()) {
+ path.clear();
+ path.appendFormat("%s/%s/voltage_now",
+ POWER_SUPPLY_SYSFS_PATH, name);
+ if (access(path, R_OK) == 0) {
+ mHealthdConfig->batteryVoltagePath = path;
+ }
+ }
+
+ if (mHealthdConfig->batteryFullChargePath.isEmpty()) {
+ path.clear();
+ path.appendFormat("%s/%s/charge_full",
+ POWER_SUPPLY_SYSFS_PATH, name);
+ if (access(path, R_OK) == 0)
+ mHealthdConfig->batteryFullChargePath = path;
+ }
+
+ if (mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
+ path.clear();
+ path.appendFormat("%s/%s/current_now",
+ POWER_SUPPLY_SYSFS_PATH, name);
+ if (access(path, R_OK) == 0)
+ mHealthdConfig->batteryCurrentNowPath = path;
+ }
+
+ if (mHealthdConfig->batteryCycleCountPath.isEmpty()) {
+ path.clear();
+ path.appendFormat("%s/%s/cycle_count",
+ POWER_SUPPLY_SYSFS_PATH, name);
+ if (access(path, R_OK) == 0)
+ mHealthdConfig->batteryCycleCountPath = path;
+ }
+
+ if (mHealthdConfig->batteryCapacityLevelPath.isEmpty()) {
+ path.clear();
+ path.appendFormat("%s/%s/capacity_level", POWER_SUPPLY_SYSFS_PATH, name);
+ if (access(path, R_OK) == 0) mHealthdConfig->batteryCapacityLevelPath = path;
+ }
+
+ if (mHealthdConfig->batteryChargeTimeToFullNowPath.isEmpty()) {
+ path.clear();
+ path.appendFormat("%s/%s/time_to_full_now", POWER_SUPPLY_SYSFS_PATH, name);
+ if (access(path, R_OK) == 0)
+ mHealthdConfig->batteryChargeTimeToFullNowPath = path;
+ }
+
+ if (mHealthdConfig->batteryFullChargeDesignCapacityUahPath.isEmpty()) {
+ path.clear();
+ path.appendFormat("%s/%s/charge_full_design", POWER_SUPPLY_SYSFS_PATH, name);
+ if (access(path, R_OK) == 0)
+ mHealthdConfig->batteryFullChargeDesignCapacityUahPath = path;
+ }
+
+ if (mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
+ path.clear();
+ path.appendFormat("%s/%s/current_avg",
+ POWER_SUPPLY_SYSFS_PATH, name);
+ if (access(path, R_OK) == 0)
+ mHealthdConfig->batteryCurrentAvgPath = path;
+ }
+
+ if (mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
+ path.clear();
+ path.appendFormat("%s/%s/charge_counter",
+ POWER_SUPPLY_SYSFS_PATH, name);
+ if (access(path, R_OK) == 0)
+ mHealthdConfig->batteryChargeCounterPath = path;
+ }
+
+ if (mHealthdConfig->batteryTemperaturePath.isEmpty()) {
+ path.clear();
+ path.appendFormat("%s/%s/temp", POWER_SUPPLY_SYSFS_PATH,
+ name);
+ if (access(path, R_OK) == 0) {
+ mHealthdConfig->batteryTemperaturePath = path;
+ }
+ }
+
+ if (mHealthdConfig->batteryTechnologyPath.isEmpty()) {
+ path.clear();
+ path.appendFormat("%s/%s/technology",
+ POWER_SUPPLY_SYSFS_PATH, name);
+ if (access(path, R_OK) == 0)
+ mHealthdConfig->batteryTechnologyPath = path;
+ }
+
+ break;
+
+ case ANDROID_POWER_SUPPLY_TYPE_UNKNOWN:
+ break;
+ }
+
+ // Look for "is_dock" file
+ path.clear();
+ path.appendFormat("%s/%s/is_dock", POWER_SUPPLY_SYSFS_PATH, name);
+ if (access(path.string(), R_OK) == 0) {
+ path.clear();
+ path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name);
+ if (access(path.string(), R_OK) == 0)
+ mChargerNames.add(String8(name));
+
+ }
+ }
+ }
+
+ // Typically the case for devices which do not have a battery and
+ // and are always plugged into AC mains.
+ if (!mBatteryDevicePresent) {
+ KLOG_WARNING(LOG_TAG, "No battery devices found\n");
+ hc->periodic_chores_interval_fast = -1;
+ hc->periodic_chores_interval_slow = -1;
+ } else {
+ if (mHealthdConfig->batteryStatusPath.isEmpty())
+ KLOG_WARNING(LOG_TAG, "BatteryStatusPath not found\n");
+ if (mHealthdConfig->batteryHealthPath.isEmpty())
+ KLOG_WARNING(LOG_TAG, "BatteryHealthPath not found\n");
+ if (mHealthdConfig->batteryPresentPath.isEmpty())
+ KLOG_WARNING(LOG_TAG, "BatteryPresentPath not found\n");
+ if (mHealthdConfig->batteryCapacityPath.isEmpty())
+ KLOG_WARNING(LOG_TAG, "BatteryCapacityPath not found\n");
+ if (mHealthdConfig->batteryVoltagePath.isEmpty())
+ KLOG_WARNING(LOG_TAG, "BatteryVoltagePath not found\n");
+ if (mHealthdConfig->batteryTemperaturePath.isEmpty())
+ KLOG_WARNING(LOG_TAG, "BatteryTemperaturePath not found\n");
+ if (mHealthdConfig->batteryTechnologyPath.isEmpty())
+ KLOG_WARNING(LOG_TAG, "BatteryTechnologyPath not found\n");
+ if (mHealthdConfig->batteryCurrentNowPath.isEmpty())
+ KLOG_WARNING(LOG_TAG, "BatteryCurrentNowPath not found\n");
+ if (mHealthdConfig->batteryFullChargePath.isEmpty())
+ KLOG_WARNING(LOG_TAG, "BatteryFullChargePath not found\n");
+ if (mHealthdConfig->batteryCycleCountPath.isEmpty())
+ KLOG_WARNING(LOG_TAG, "BatteryCycleCountPath not found\n");
+ if (mHealthdConfig->batteryCapacityLevelPath.isEmpty())
+ KLOG_WARNING(LOG_TAG, "batteryCapacityLevelPath not found\n");
+ if (mHealthdConfig->batteryChargeTimeToFullNowPath.isEmpty())
+ KLOG_WARNING(LOG_TAG, "batteryChargeTimeToFullNowPath. not found\n");
+ if (mHealthdConfig->batteryFullChargeDesignCapacityUahPath.isEmpty())
+ KLOG_WARNING(LOG_TAG, "batteryFullChargeDesignCapacityUahPath. not found\n");
+ }
+
+ if (property_get("ro.boot.fake_battery", pval, NULL) > 0
+ && strtol(pval, NULL, 10) != 0) {
+ mBatteryFixedCapacity = FAKE_BATTERY_CAPACITY;
+ mBatteryFixedTemperature = FAKE_BATTERY_TEMPERATURE;
+ }
+}
+
+}; // namespace android
diff --git a/healthd/include/healthd/BatteryMonitor.h b/healthd/include/healthd/BatteryMonitor.h
index 8cbf5ea..4af2a87 100644
--- a/healthd/include/healthd/BatteryMonitor.h
+++ b/healthd/include/healthd/BatteryMonitor.h
@@ -72,6 +72,10 @@
void logValues(void);
bool isChargerOnline();
+ int setChargingPolicy(int value);
+ int getChargingPolicy();
+ int getBatteryHealthData(int id);
+
static void logValues(const android::hardware::health::V2_1::HealthInfo& health_info,
const struct healthd_config& healthd_config);
diff --git a/healthd/include/healthd/BatteryMonitor_v1.h b/healthd/include/healthd/BatteryMonitor_v1.h
new file mode 100644
index 0000000..49f6f9d
--- /dev/null
+++ b/healthd/include/healthd/BatteryMonitor_v1.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2013 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 HEALTHD_BATTERYMONITOR_V1_H
+#define HEALTHD_BATTERYMONITOR_V1_H
+
+#include <memory>
+
+#include <batteryservice/BatteryService.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
+
+#include <healthd/healthd.h>
+
+namespace aidl::android::hardware::health {
+class HealthInfo;
+} // namespace aidl::android::hardware::health
+
+namespace android {
+namespace hardware {
+namespace health {
+namespace V1_0 {
+struct HealthInfo;
+} // namespace V1_0
+namespace V2_0 {
+struct HealthInfo;
+} // namespace V2_0
+namespace V2_1 {
+struct HealthInfo;
+} // namespace V2_1
+} // namespace health
+} // namespace hardware
+
+class BatteryMonitor {
+ public:
+
+ enum PowerSupplyType {
+ ANDROID_POWER_SUPPLY_TYPE_UNKNOWN = 0,
+ ANDROID_POWER_SUPPLY_TYPE_AC,
+ ANDROID_POWER_SUPPLY_TYPE_USB,
+ ANDROID_POWER_SUPPLY_TYPE_WIRELESS,
+ ANDROID_POWER_SUPPLY_TYPE_BATTERY,
+ ANDROID_POWER_SUPPLY_TYPE_DOCK
+ };
+
+ BatteryMonitor();
+ ~BatteryMonitor();
+ void init(struct healthd_config *hc);
+ int getChargeStatus();
+ status_t getProperty(int id, struct BatteryProperty *val);
+ void dumpState(int fd);
+
+ android::hardware::health::V1_0::HealthInfo getHealthInfo_1_0() const;
+ android::hardware::health::V2_0::HealthInfo getHealthInfo_2_0() const;
+ android::hardware::health::V2_1::HealthInfo getHealthInfo_2_1() const;
+ const aidl::android::hardware::health::HealthInfo& getHealthInfo() const;
+
+ void updateValues(void);
+ void logValues(void);
+ bool isChargerOnline();
+
+ static void logValues(const android::hardware::health::V2_1::HealthInfo& health_info,
+ const struct healthd_config& healthd_config);
+
+ private:
+ struct healthd_config *mHealthdConfig;
+ Vector<String8> mChargerNames;
+ bool mBatteryDevicePresent;
+ int mBatteryFixedCapacity;
+ int mBatteryFixedTemperature;
+ std::unique_ptr<aidl::android::hardware::health::HealthInfo> mHealthInfo;
+};
+
+}; // namespace android
+
+#endif // HEALTHD_BATTERYMONITOR_V1_H
diff --git a/healthd/include/healthd/healthd.h b/healthd/include/healthd/healthd.h
index 706c332..e1c357c 100644
--- a/healthd/include/healthd/healthd.h
+++ b/healthd/include/healthd/healthd.h
@@ -72,6 +72,11 @@
android::String8 batteryCapacityLevelPath;
android::String8 batteryChargeTimeToFullNowPath;
android::String8 batteryFullChargeDesignCapacityUahPath;
+ android::String8 batteryStateOfHealthPath;
+ android::String8 batteryManufacturingDatePath;
+ android::String8 batteryFirstUsageDatePath;
+ android::String8 chargingStatePath;
+ android::String8 chargingPolicyPath;
int (*energyCounter)(int64_t *);
int boot_min_cap;
diff --git a/libcutils/qtaguid.cpp b/libcutils/qtaguid.cpp
index a987b85..f847782 100644
--- a/libcutils/qtaguid.cpp
+++ b/libcutils/qtaguid.cpp
@@ -22,76 +22,60 @@
#include <dlfcn.h>
#include <errno.h>
-#include <fcntl.h>
#include <inttypes.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
#include <log/log.h>
-class netdHandler {
- public:
+struct netdHandler {
int (*netdTagSocket)(int, uint32_t, uid_t);
int (*netdUntagSocket)(int);
};
-int stubTagSocket(int, uint32_t, uid_t) {
+static int stubTagSocket(int, uint32_t, uid_t) {
return -EREMOTEIO;
}
-int stubUntagSocket(int) {
+static int stubUntagSocket(int) {
return -EREMOTEIO;
}
-netdHandler initHandler(void) {
- netdHandler handler = {stubTagSocket, stubUntagSocket};
+static netdHandler initHandler(void) {
+ const netdHandler stubHandler = { stubTagSocket, stubUntagSocket };
void* netdClientHandle = dlopen("libnetd_client.so", RTLD_NOW);
if (!netdClientHandle) {
ALOGE("Failed to open libnetd_client.so: %s", dlerror());
- return handler;
+ return stubHandler;
}
+ netdHandler handler;
handler.netdTagSocket = (int (*)(int, uint32_t, uid_t))dlsym(netdClientHandle, "tagSocket");
if (!handler.netdTagSocket) {
ALOGE("load netdTagSocket handler failed: %s", dlerror());
+ return stubHandler;
}
handler.netdUntagSocket = (int (*)(int))dlsym(netdClientHandle, "untagSocket");
if (!handler.netdUntagSocket) {
ALOGE("load netdUntagSocket handler failed: %s", dlerror());
+ return stubHandler;
}
return handler;
}
// The language guarantees that this object will be initialized in a thread-safe way.
-static netdHandler& getHandler() {
- static netdHandler instance = initHandler();
+static const netdHandler& getHandler() {
+ static const netdHandler instance = initHandler();
return instance;
}
int qtaguid_tagSocket(int sockfd, int tag, uid_t uid) {
- // Check the socket fd passed to us is still valid before we load the netd
- // client. Pass a already closed socket fd to netd client may let netd open
- // the unix socket with the same fd number and pass it to server for
- // tagging.
- // TODO: move the check into netdTagSocket.
- int res = fcntl(sockfd, F_GETFD);
- if (res < 0) return res;
-
ALOGV("Tagging socket %d with tag %u for uid %d", sockfd, tag, uid);
return getHandler().netdTagSocket(sockfd, tag, uid);
}
int qtaguid_untagSocket(int sockfd) {
- // Similiar to tag socket. We need a check before untag to make sure untag a closed socket fail
- // as expected.
- // TODO: move the check into netdTagSocket.
- int res = fcntl(sockfd, F_GETFD);
- if (res < 0) return res;
-
ALOGV("Untagging socket %d", sockfd);
return getHandler().netdUntagSocket(sockfd);
}
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index fe23b62..3dd269a 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -213,4 +213,15 @@
$(hide) $(foreach lib,$(PRIVATE_SANITIZER_RUNTIME_LIBRARIES), \
echo $(lib) >> $@;)
+#######################################
+# ramdisk_node_list
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := ramdisk_node_list
+LOCAL_MODULE_CLASS := ETC
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)
+
+include $(BUILD_PREBUILT)
+
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/rootdir/ramdisk_node_list b/rootdir/ramdisk_node_list
new file mode 100644
index 0000000..d3ab8a6
--- /dev/null
+++ b/rootdir/ramdisk_node_list
@@ -0,0 +1,3 @@
+dir dev 0755 0 0
+nod dev/null 0600 0 0 c 1 3
+nod dev/console 0600 0 0 c 5 1
diff --git a/storaged/Android.bp b/storaged/Android.bp
index 7960af3..c3447d2 100644
--- a/storaged/Android.bp
+++ b/storaged/Android.bp
@@ -24,7 +24,7 @@
shared_libs: [
"android.hardware.health@1.0",
"android.hardware.health@2.0",
- "android.hardware.health-V1-ndk",
+ "android.hardware.health-V2-ndk",
"libbase",
"libbinder",
"libbinder_ndk",
diff --git a/toolbox/modprobe.cpp b/toolbox/modprobe.cpp
index 711586a..17f8156 100644
--- a/toolbox/modprobe.cpp
+++ b/toolbox/modprobe.cpp
@@ -23,8 +23,11 @@
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/strings.h>
+#include <android-base/stringprintf.h>
#include <modprobe/modprobe.h>
+#include <sys/utsname.h>
+
namespace {
enum modprobe_mode {
@@ -37,9 +40,8 @@
void print_usage(void) {
LOG(INFO) << "Usage:";
LOG(INFO);
- // -d option is required on Android
- LOG(INFO) << " modprobe [options] -d DIR [--all=FILE|MODULE]...";
- LOG(INFO) << " modprobe [options] -d DIR MODULE [symbol=value]...";
+ LOG(INFO) << " modprobe [options] [-d DIR] [--all=FILE|MODULE]...";
+ LOG(INFO) << " modprobe [options] [-d DIR] MODULE [symbol=value]...";
LOG(INFO);
LOG(INFO) << "Options:";
LOG(INFO) << " --all=FILE: FILE to acquire module names from";
@@ -189,6 +191,12 @@
}
}
+ if (mod_dirs.empty()) {
+ utsname uts;
+ uname(&uts);
+ mod_dirs.emplace_back(android::base::StringPrintf("/lib/modules/%s", uts.release));
+ }
+
LOG(DEBUG) << "mode is " << mode;
LOG(DEBUG) << "mod_dirs is: " << android::base::Join(mod_dirs, " ");
LOG(DEBUG) << "modules is: " << android::base::Join(modules, " ");
diff --git a/trusty/keymaster/TEST_MAPPING b/trusty/keymaster/TEST_MAPPING
index ae48327..0dd39fb 100644
--- a/trusty/keymaster/TEST_MAPPING
+++ b/trusty/keymaster/TEST_MAPPING
@@ -1,9 +1,6 @@
{
"presubmit": [
{
- "name": "RemoteProvisionerUnitTests"
- },
- {
"name": "VtsAidlKeyMintTargetTest"
},
{
diff --git a/trusty/libtrusty/Android.bp b/trusty/libtrusty/Android.bp
index 086051d..9d94ec4 100644
--- a/trusty/libtrusty/Android.bp
+++ b/trusty/libtrusty/Android.bp
@@ -33,5 +33,6 @@
// TODO(b/170753563): cc_fuzz can't deal with vendor components. Build
// libtrusty for system and vendor.
vendor_available: true,
+ recovery_available: true,
defaults: ["libtrusty_defaults"],
}