Merge "healthd: *charger_test links to a.h.health@2.x statically."
diff --git a/fastboot/Android.bp b/fastboot/Android.bp
index 339f392..708a677 100644
--- a/fastboot/Android.bp
+++ b/fastboot/Android.bp
@@ -166,8 +166,10 @@
"android.hardware.boot@1.1",
"android.hardware.fastboot@1.1",
"android.hardware.health@2.0",
+ "android.hardware.health-V1-ndk",
"libasyncio",
"libbase",
+ "libbinder_ndk",
"libbootloader_message",
"libcutils",
"libext2_uuid",
@@ -183,8 +185,10 @@
],
static_libs: [
+ "android.hardware.health-translate-ndk",
"libc++fs",
"libhealthhalutils",
+ "libhealthshim",
"libsnapshot_cow",
"libsnapshot_nobinder",
"update_metadata-protos",
diff --git a/fastboot/device/fastboot_device.cpp b/fastboot/device/fastboot_device.cpp
index 64a934d..e6a834e 100644
--- a/fastboot/device/fastboot_device.cpp
+++ b/fastboot/device/fastboot_device.cpp
@@ -21,10 +21,12 @@
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
+#include <android/binder_manager.h>
#include <android/hardware/boot/1.0/IBootControl.h>
#include <android/hardware/fastboot/1.1/IFastboot.h>
#include <fs_mgr.h>
#include <fs_mgr/roots.h>
+#include <health-shim/shim.h>
#include <healthhalutils/HealthHalUtils.h>
#include "constants.h"
@@ -32,16 +34,36 @@
#include "tcp_client.h"
#include "usb_client.h"
+using std::string_literals::operator""s;
using android::fs_mgr::EnsurePathUnmounted;
using android::fs_mgr::Fstab;
using ::android::hardware::hidl_string;
using ::android::hardware::boot::V1_0::IBootControl;
using ::android::hardware::boot::V1_0::Slot;
using ::android::hardware::fastboot::V1_1::IFastboot;
-using ::android::hardware::health::V2_0::get_health_service;
namespace sph = std::placeholders;
+std::shared_ptr<aidl::android::hardware::health::IHealth> get_health_service() {
+ using aidl::android::hardware::health::IHealth;
+ using HidlHealth = android::hardware::health::V2_0::IHealth;
+ using aidl::android::hardware::health::HealthShim;
+ auto service_name = IHealth::descriptor + "/default"s;
+ if (AServiceManager_isDeclared(service_name.c_str())) {
+ ndk::SpAIBinder binder(AServiceManager_waitForService(service_name.c_str()));
+ std::shared_ptr<IHealth> health = IHealth::fromBinder(binder);
+ if (health != nullptr) return health;
+ LOG(WARNING) << "AIDL health service is declared, but it cannot be retrieved.";
+ }
+ LOG(INFO) << "Unable to get AIDL health service, trying HIDL...";
+ android::sp<HidlHealth> hidl_health = android::hardware::health::V2_0::get_health_service();
+ if (hidl_health != nullptr) {
+ return ndk::SharedRefBase::make<HealthShim>(hidl_health);
+ }
+ LOG(WARNING) << "No health implementation is found.";
+ return nullptr;
+}
+
FastbootDevice::FastbootDevice()
: kCommandMap({
{FB_CMD_SET_ACTIVE, SetActiveHandler},
diff --git a/fastboot/device/fastboot_device.h b/fastboot/device/fastboot_device.h
index 3536136..91ffce3 100644
--- a/fastboot/device/fastboot_device.h
+++ b/fastboot/device/fastboot_device.h
@@ -22,10 +22,10 @@
#include <utility>
#include <vector>
+#include <aidl/android/hardware/health/IHealth.h>
#include <android/hardware/boot/1.0/IBootControl.h>
#include <android/hardware/boot/1.1/IBootControl.h>
#include <android/hardware/fastboot/1.1/IFastboot.h>
-#include <android/hardware/health/2.0/IHealth.h>
#include "commands.h"
#include "transport.h"
@@ -57,7 +57,7 @@
android::sp<android::hardware::fastboot::V1_1::IFastboot> fastboot_hal() {
return fastboot_hal_;
}
- android::sp<android::hardware::health::V2_0::IHealth> health_hal() { return health_hal_; }
+ std::shared_ptr<aidl::android::hardware::health::IHealth> health_hal() { return health_hal_; }
void set_active_slot(const std::string& active_slot) { active_slot_ = active_slot; }
@@ -67,7 +67,7 @@
std::unique_ptr<Transport> transport_;
android::sp<android::hardware::boot::V1_0::IBootControl> boot_control_hal_;
android::sp<android::hardware::boot::V1_1::IBootControl> boot1_1_;
- android::sp<android::hardware::health::V2_0::IHealth> health_hal_;
+ std::shared_ptr<aidl::android::hardware::health::IHealth> health_hal_;
android::sp<android::hardware::fastboot::V1_1::IFastboot> fastboot_hal_;
std::vector<char> download_data_;
std::string active_slot_;
diff --git a/fastboot/device/variables.cpp b/fastboot/device/variables.cpp
index ee1eed8..76e9889 100644
--- a/fastboot/device/variables.cpp
+++ b/fastboot/device/variables.cpp
@@ -26,7 +26,6 @@
#include <android/hardware/boot/1.1/IBootControl.h>
#include <ext4_utils/ext4_utils.h>
#include <fs_mgr.h>
-#include <healthhalutils/HealthHalUtils.h>
#include <liblp/liblp.h>
#include "fastboot_device.h"
@@ -120,23 +119,17 @@
}
bool GetBatteryVoltageHelper(FastbootDevice* device, int32_t* battery_voltage) {
- using android::hardware::health::V2_0::HealthInfo;
- using android::hardware::health::V2_0::Result;
+ using aidl::android::hardware::health::HealthInfo;
auto health_hal = device->health_hal();
if (!health_hal) {
return false;
}
- Result ret;
- auto ret_val = health_hal->getHealthInfo([&](Result result, HealthInfo info) {
- *battery_voltage = info.legacy.batteryVoltage;
- ret = result;
- });
- if (!ret_val.isOk() || (ret != Result::SUCCESS)) {
- return false;
- }
-
+ HealthInfo health_info;
+ auto res = health_hal->getHealthInfo(&health_info);
+ if (!res.isOk()) return false;
+ *battery_voltage = health_info.batteryVoltageMillivolts;
return true;
}
diff --git a/fs_mgr/libsnapshot/snapuserd/Android.bp b/fs_mgr/libsnapshot/snapuserd/Android.bp
index 4d86007..84bcb94 100644
--- a/fs_mgr/libsnapshot/snapuserd/Android.bp
+++ b/fs_mgr/libsnapshot/snapuserd/Android.bp
@@ -107,6 +107,12 @@
ramdisk_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
+
+ // Snapuserd segfaults with ThinLTO
+ // http://b/208565717
+ lto: {
+ never: true,
+ }
}
cc_test {
@@ -181,7 +187,9 @@
"libstorage_literals_headers",
"libfiemap_headers",
],
- test_min_api_level: 30,
+ test_options: {
+ min_shipping_api_level: 30,
+ },
auto_gen_config: true,
require_root: false,
}
diff --git a/gatekeeperd/Android.bp b/gatekeeperd/Android.bp
index a7f0c0e..0aedc58 100644
--- a/gatekeeperd/Android.bp
+++ b/gatekeeperd/Android.bp
@@ -29,7 +29,9 @@
srcs: [
"gatekeeperd.cpp",
],
-
+ defaults: [
+ "keymint_use_latest_hal_aidl_ndk_shared",
+ ],
shared_libs: [
"libbinder",
"libbinder_ndk",
@@ -43,7 +45,6 @@
"libhidlbase",
"android.hardware.gatekeeper@1.0",
"libgatekeeper_aidl",
- "android.hardware.security.keymint-V1-ndk",
"android.security.authorization-ndk",
],
diff --git a/init/README.md b/init/README.md
index ebab073..c102b1f 100644
--- a/init/README.md
+++ b/init/README.md
@@ -641,9 +641,10 @@
configurations. Intended to be used only once when apexd notifies the mount
event by setting `apexd.status` to ready.
-`restart <service>`
+`restart [--only-if-running] <service>`
> Stops and restarts a running service, does nothing if the service is currently
- restarting, otherwise, it just starts the service.
+ restarting, otherwise, it just starts the service. If "--only-if-running" is
+ specified, the service is only restarted if it is already running.
`restorecon <path> [ <path>\* ]`
> Restore the file named by _path_ to the security context specified
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 98831e1..8045c71 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -774,8 +774,21 @@
}
static Result<void> do_restart(const BuiltinArguments& args) {
- Service* svc = ServiceList::GetInstance().FindService(args[1]);
- if (!svc) return Error() << "service " << args[1] << " not found";
+ bool only_if_running = false;
+ if (args.size() == 3) {
+ if (args[1] == "--only-if-running") {
+ only_if_running = true;
+ } else {
+ return Error() << "Unknown argument to restart: " << args[1];
+ }
+ }
+
+ const auto& classname = args[args.size() - 1];
+ Service* svc = ServiceList::GetInstance().FindService(classname);
+ if (!svc) return Error() << "service " << classname << " not found";
+ if (only_if_running && !svc->IsRunning()) {
+ return {};
+ }
svc->Restart();
return {};
}
@@ -1453,7 +1466,7 @@
{"update_linker_config", {0, 0, {false, do_update_linker_config}}},
{"readahead", {1, 2, {true, do_readahead}}},
{"remount_userdata", {0, 0, {false, do_remount_userdata}}},
- {"restart", {1, 1, {false, do_restart}}},
+ {"restart", {1, 2, {false, do_restart}}},
{"restorecon", {1, kMax, {true, do_restorecon}}},
{"restorecon_recursive", {1, kMax, {true, do_restorecon_recursive}}},
{"rm", {1, 1, {true, do_rm}}},
diff --git a/libprocessgroup/profiles/task_profiles.json b/libprocessgroup/profiles/task_profiles.json
index 45d3c7c..b668dcb 100644
--- a/libprocessgroup/profiles/task_profiles.json
+++ b/libprocessgroup/profiles/task_profiles.json
@@ -651,6 +651,10 @@
{
"Name": "Dex2OatBootComplete",
"Profiles": [ "Dex2oatPerformance", "LowIoPriority", "TimerSlackHigh" ]
+ },
+ {
+ "Name": "OtaProfiles",
+ "Profiles": [ "ServiceCapacityLow", "LowIoPriority", "HighEnergySaving" ]
}
]
}
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index e935f99..3834f91 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -144,30 +144,13 @@
return true;
}
-bool SetCgroupAction::IsAppDependentPath(const std::string& path) {
- return path.find("<uid>", 0) != std::string::npos || path.find("<pid>", 0) != std::string::npos;
-}
-
-SetCgroupAction::SetCgroupAction(const CgroupController& c, const std::string& p)
- : controller_(c), path_(p) {
- // file descriptors for app-dependent paths can't be cached
- if (IsAppDependentPath(path_)) {
- // file descriptor is not cached
- fd_.reset(FDS_APP_DEPENDENT);
- return;
- }
-
- // file descriptor can be cached later on request
- fd_.reset(FDS_NOT_CACHED);
-}
-
-void SetCgroupAction::EnableResourceCaching() {
+void CachedFdProfileAction::EnableResourceCaching() {
std::lock_guard<std::mutex> lock(fd_mutex_);
if (fd_ != FDS_NOT_CACHED) {
return;
}
- std::string tasks_path = controller_.GetTasksFilePath(path_);
+ std::string tasks_path = GetPath();
if (access(tasks_path.c_str(), W_OK) != 0) {
// file is not accessible
@@ -185,7 +168,7 @@
fd_ = std::move(fd);
}
-void SetCgroupAction::DropResourceCaching() {
+void CachedFdProfileAction::DropResourceCaching() {
std::lock_guard<std::mutex> lock(fd_mutex_);
if (fd_ == FDS_NOT_CACHED) {
return;
@@ -194,6 +177,26 @@
fd_.reset(FDS_NOT_CACHED);
}
+bool CachedFdProfileAction::IsAppDependentPath(const std::string& path) {
+ return path.find("<uid>", 0) != std::string::npos || path.find("<pid>", 0) != std::string::npos;
+}
+
+void CachedFdProfileAction::InitFd(const std::string& path) {
+ // file descriptors for app-dependent paths can't be cached
+ if (IsAppDependentPath(path)) {
+ // file descriptor is not cached
+ fd_.reset(FDS_APP_DEPENDENT);
+ return;
+ }
+ // file descriptor can be cached later on request
+ fd_.reset(FDS_NOT_CACHED);
+}
+
+SetCgroupAction::SetCgroupAction(const CgroupController& c, const std::string& p)
+ : controller_(c), path_(p) {
+ InitFd(controller_.GetTasksFilePath(path_));
+}
+
bool SetCgroupAction::AddTidToCgroup(int tid, int fd, const char* controller_name) {
if (tid <= 0) {
return true;
@@ -270,7 +273,7 @@
std::string tasks_path = controller()->GetTasksFilePath(path_);
unique_fd tmp_fd(TEMP_FAILURE_RETRY(open(tasks_path.c_str(), O_WRONLY | O_CLOEXEC)));
if (tmp_fd < 0) {
- PLOG(WARNING) << "Failed to open " << tasks_path << ": " << strerror(errno);
+ PLOG(WARNING) << "Failed to open " << tasks_path;
return false;
}
if (!AddTidToCgroup(tid, tmp_fd, controller()->name())) {
@@ -281,37 +284,73 @@
return true;
}
-bool WriteFileAction::ExecuteForProcess(uid_t uid, pid_t pid) const {
- std::string filepath(filepath_), value(value_);
+WriteFileAction::WriteFileAction(const std::string& path, const std::string& value,
+ bool logfailures)
+ : path_(path), value_(value), logfailures_(logfailures) {
+ InitFd(path_);
+}
- filepath = StringReplace(filepath, "<uid>", std::to_string(uid), true);
- filepath = StringReplace(filepath, "<pid>", std::to_string(pid), true);
- value = StringReplace(value, "<uid>", std::to_string(uid), true);
- value = StringReplace(value, "<pid>", std::to_string(pid), true);
+bool WriteFileAction::WriteValueToFile(const std::string& value, const std::string& path,
+ bool logfailures) {
+ // Use WriteStringToFd instead of WriteStringToFile because the latter will open file with
+ // O_TRUNC which causes kernfs_mutex contention
+ unique_fd tmp_fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_WRONLY | O_CLOEXEC)));
- if (!WriteStringToFile(value, filepath)) {
- if (logfailures_) PLOG(ERROR) << "Failed to write '" << value << "' to " << filepath;
+ if (tmp_fd < 0) {
+ if (logfailures) PLOG(WARNING) << "Failed to open " << path;
+ return false;
+ }
+
+ if (!WriteStringToFd(value, tmp_fd)) {
+ if (logfailures) PLOG(ERROR) << "Failed to write '" << value << "' to " << path;
return false;
}
return true;
}
+bool WriteFileAction::ExecuteForProcess(uid_t uid, pid_t pid) const {
+ std::lock_guard<std::mutex> lock(fd_mutex_);
+ std::string value(value_);
+ std::string path(path_);
+
+ value = StringReplace(value, "<uid>", std::to_string(uid), true);
+ value = StringReplace(value, "<pid>", std::to_string(pid), true);
+ path = StringReplace(path, "<uid>", std::to_string(uid), true);
+ path = StringReplace(path, "<pid>", std::to_string(pid), true);
+
+ return WriteValueToFile(value, path, logfailures_);
+}
+
bool WriteFileAction::ExecuteForTask(int tid) const {
- std::string filepath(filepath_), value(value_);
+ std::lock_guard<std::mutex> lock(fd_mutex_);
+ std::string value(value_);
int uid = getuid();
- filepath = StringReplace(filepath, "<uid>", std::to_string(uid), true);
- filepath = StringReplace(filepath, "<pid>", std::to_string(tid), true);
value = StringReplace(value, "<uid>", std::to_string(uid), true);
value = StringReplace(value, "<pid>", std::to_string(tid), true);
- if (!WriteStringToFile(value, filepath)) {
- if (logfailures_) PLOG(ERROR) << "Failed to write '" << value << "' to " << filepath;
+ if (IsFdValid()) {
+ // fd is cached, reuse it
+ if (!WriteStringToFd(value, fd_)) {
+ if (logfailures_) PLOG(ERROR) << "Failed to write '" << value << "' to " << path_;
+ return false;
+ }
+ return true;
+ }
+
+ if (fd_ == FDS_INACCESSIBLE) {
+ // no permissions to access the file, ignore
+ return true;
+ }
+
+ if (fd_ == FDS_APP_DEPENDENT) {
+ // application-dependent path can't be used with tid
+ PLOG(ERROR) << "Application profile can't be applied to a thread";
return false;
}
- return true;
+ return WriteValueToFile(value, path_, logfailures_);
}
bool ApplyProfileAction::ExecuteForProcess(uid_t uid, pid_t pid) const {
diff --git a/libprocessgroup/task_profiles.h b/libprocessgroup/task_profiles.h
index 97c38f4..278892d 100644
--- a/libprocessgroup/task_profiles.h
+++ b/libprocessgroup/task_profiles.h
@@ -108,50 +108,67 @@
std::string value_;
};
-// Set cgroup profile element
-class SetCgroupAction : public ProfileAction {
+// Abstract profile element for cached fd
+class CachedFdProfileAction : public ProfileAction {
public:
- SetCgroupAction(const CgroupController& c, const std::string& p);
-
- virtual bool ExecuteForProcess(uid_t uid, pid_t pid) const;
- virtual bool ExecuteForTask(int tid) const;
virtual void EnableResourceCaching();
virtual void DropResourceCaching();
- const CgroupController* controller() const { return &controller_; }
- std::string path() const { return path_; }
-
- private:
+ protected:
enum FdState {
FDS_INACCESSIBLE = -1,
FDS_APP_DEPENDENT = -2,
FDS_NOT_CACHED = -3,
};
- CgroupController controller_;
- std::string path_;
android::base::unique_fd fd_;
mutable std::mutex fd_mutex_;
static bool IsAppDependentPath(const std::string& path);
- static bool AddTidToCgroup(int tid, int fd, const char* controller_name);
+ void InitFd(const std::string& path);
bool IsFdValid() const { return fd_ > FDS_INACCESSIBLE; }
+
+ virtual const std::string GetPath() const = 0;
};
-// Write to file action
-class WriteFileAction : public ProfileAction {
+// Set cgroup profile element
+class SetCgroupAction : public CachedFdProfileAction {
public:
- WriteFileAction(const std::string& filepath, const std::string& value,
- bool logfailures) noexcept
- : filepath_(filepath), value_(value), logfailures_(logfailures) {}
+ SetCgroupAction(const CgroupController& c, const std::string& p);
virtual bool ExecuteForProcess(uid_t uid, pid_t pid) const;
virtual bool ExecuteForTask(int tid) const;
+ const CgroupController* controller() const { return &controller_; }
+
+ protected:
+ const std::string GetPath() const override { return controller_.GetTasksFilePath(path_); }
+
private:
- std::string filepath_, value_;
+ CgroupController controller_;
+ std::string path_;
+
+ static bool AddTidToCgroup(int tid, int fd, const char* controller_name);
+};
+
+// Write to file action
+class WriteFileAction : public CachedFdProfileAction {
+ public:
+ WriteFileAction(const std::string& path, const std::string& value, bool logfailures);
+
+ virtual bool ExecuteForProcess(uid_t uid, pid_t pid) const;
+ virtual bool ExecuteForTask(int tid) const;
+
+ protected:
+ const std::string GetPath() const override { return path_; }
+
+ private:
+ std::string path_, value_;
bool logfailures_;
+
+ static bool WriteValueToFile(const std::string& value, const std::string& path,
+ bool logfailures);
};
class TaskProfile {
diff --git a/libutils/Threads.cpp b/libutils/Threads.cpp
index 6e293c7..3bf5779 100644
--- a/libutils/Threads.cpp
+++ b/libutils/Threads.cpp
@@ -317,10 +317,7 @@
if (pri >= ANDROID_PRIORITY_BACKGROUND) {
rc = SetTaskProfiles(tid, {"SCHED_SP_SYSTEM"}, true) ? 0 : -1;
} else if (curr_pri >= ANDROID_PRIORITY_BACKGROUND) {
- SchedPolicy policy = SP_FOREGROUND;
- // Change to the sched policy group of the process.
- get_sched_policy(getpid(), &policy);
- rc = SetTaskProfiles(tid, {get_sched_policy_profile_name(policy)}, true) ? 0 : -1;
+ rc = SetTaskProfiles(tid, {"SCHED_SP_FOREGROUND"}, true) ? 0 : -1;
}
if (rc) {
diff --git a/storaged/Android.bp b/storaged/Android.bp
index b557dee..7960af3 100644
--- a/storaged/Android.bp
+++ b/storaged/Android.bp
@@ -24,8 +24,10 @@
shared_libs: [
"android.hardware.health@1.0",
"android.hardware.health@2.0",
+ "android.hardware.health-V1-ndk",
"libbase",
"libbinder",
+ "libbinder_ndk",
"libcutils",
"libhidlbase",
"liblog",
@@ -35,6 +37,12 @@
"packagemanager_aidl-cpp",
],
+ static_libs: [
+ "android.hardware.health-translate-ndk",
+ "libhealthhalutils",
+ "libhealthshim",
+ ],
+
cflags: [
"-Wall",
"-Werror",
@@ -67,7 +75,6 @@
":storaged_aidl_private",
],
- static_libs: ["libhealthhalutils"],
header_libs: ["libbatteryservice_headers"],
logtags: ["EventLogTags.logtags"],
@@ -90,7 +97,6 @@
srcs: ["main.cpp"],
static_libs: [
- "libhealthhalutils",
"libstoraged",
],
}
@@ -107,9 +113,11 @@
srcs: ["tests/storaged_test.cpp"],
static_libs: [
- "libhealthhalutils",
"libstoraged",
],
+ test_suites: [
+ "general-tests",
+ ],
}
// AIDL interface between storaged and framework.jar
diff --git a/storaged/include/storaged.h b/storaged/include/storaged.h
index 79b5d41..e120271 100644
--- a/storaged/include/storaged.h
+++ b/storaged/include/storaged.h
@@ -28,6 +28,7 @@
#include <utils/Mutex.h>
+#include <aidl/android/hardware/health/IHealth.h>
#include <android/hardware/health/2.0/IHealth.h>
#define FRIEND_TEST(test_case_name, test_name) \
@@ -67,6 +68,8 @@
// UID IO threshold in bytes
#define DEFAULT_PERIODIC_CHORES_UID_IO_THRESHOLD ( 1024 * 1024 * 1024ULL )
+class storaged_t;
+
struct storaged_config {
int periodic_chores_interval_unit;
int periodic_chores_interval_disk_stats_publish;
@@ -75,15 +78,33 @@
int event_time_check_usec; // check how much cputime spent in event loop
};
-class storaged_t : public android::hardware::health::V2_0::IHealthInfoCallback,
- public android::hardware::hidl_death_recipient {
+struct HealthServicePair {
+ std::shared_ptr<aidl::android::hardware::health::IHealth> aidl_health;
+ android::sp<android::hardware::health::V2_0::IHealth> hidl_health;
+ static HealthServicePair get();
+};
+
+class hidl_health_death_recipient : public android::hardware::hidl_death_recipient {
+ public:
+ hidl_health_death_recipient(const android::sp<android::hardware::health::V2_0::IHealth>& health)
+ : mHealth(health) {}
+ void serviceDied(uint64_t cookie, const wp<::android::hidl::base::V1_0::IBase>& who);
+
+ private:
+ android::sp<android::hardware::health::V2_0::IHealth> mHealth;
+};
+
+class storaged_t : public RefBase {
private:
time_t mTimer;
storaged_config mConfig;
unique_ptr<disk_stats_monitor> mDsm;
uid_monitor mUidm;
time_t mStarttime;
- sp<android::hardware::health::V2_0::IHealth> health;
+ std::shared_ptr<aidl::android::hardware::health::IHealth> health;
+ sp<android::hardware::hidl_death_recipient> hidl_death_recp;
+ ndk::ScopedAIBinder_DeathRecipient aidl_death_recp;
+ shared_ptr<aidl::android::hardware::health::IHealthInfoCallback> aidl_health_callback;
unique_ptr<storage_info_t> storage_info;
static const uint32_t current_version;
Mutex proto_lock;
@@ -135,10 +156,6 @@
void add_user_ce(userid_t user_id);
void remove_user_ce(userid_t user_id);
- virtual ::android::hardware::Return<void> healthInfoChanged(
- const ::android::hardware::health::V2_0::HealthInfo& info);
- void serviceDied(uint64_t cookie, const wp<::android::hidl::base::V1_0::IBase>& who);
-
void report_storage_info();
void flush_protos(unordered_map<int, StoragedProto>* protos);
diff --git a/storaged/include/storaged_diskstats.h b/storaged/include/storaged_diskstats.h
index 0b93ba6..3996ef6 100644
--- a/storaged/include/storaged_diskstats.h
+++ b/storaged/include/storaged_diskstats.h
@@ -19,7 +19,7 @@
#include <stdint.h>
-#include <android/hardware/health/2.0/IHealth.h>
+#include <aidl/android/hardware/health/IHealth.h>
// number of attributes diskstats has
#define DISK_STATS_SIZE ( 11 )
@@ -162,7 +162,7 @@
const double mSigma;
struct disk_perf mMean;
struct disk_perf mStd;
- android::sp<android::hardware::health::V2_0::IHealth> mHealth;
+ std::shared_ptr<aidl::android::hardware::health::IHealth> mHealth;
void update_mean();
void update_std();
@@ -173,14 +173,15 @@
void update(struct disk_stats* stats);
public:
- disk_stats_monitor(const android::sp<android::hardware::health::V2_0::IHealth>& healthService,
+ disk_stats_monitor(const std::shared_ptr<aidl::android::hardware::health::IHealth>& healthService,
uint32_t window_size = 5, double sigma = 1.0)
: DISK_STATS_PATH(
- healthService != nullptr
- ? nullptr
- : (access(MMC_DISK_STATS_PATH, R_OK) == 0
- ? MMC_DISK_STATS_PATH
- : (access(SDA_DISK_STATS_PATH, R_OK) == 0 ? SDA_DISK_STATS_PATH : nullptr))),
+ healthService != nullptr
+ ? nullptr
+ : (access(MMC_DISK_STATS_PATH, R_OK) == 0
+ ? MMC_DISK_STATS_PATH
+ : (access(SDA_DISK_STATS_PATH, R_OK) == 0 ? SDA_DISK_STATS_PATH
+ : nullptr))),
mPrevious(),
mAccumulate(),
mAccumulate_pub(),
diff --git a/storaged/include/storaged_info.h b/storaged/include/storaged_info.h
index 9c3d0e7..83c97ad 100644
--- a/storaged/include/storaged_info.h
+++ b/storaged/include/storaged_info.h
@@ -21,7 +21,7 @@
#include <chrono>
-#include <android/hardware/health/2.0/IHealth.h>
+#include <aidl/android/hardware/health/IHealth.h>
#include <utils/Mutex.h>
#include "storaged.h"
@@ -71,8 +71,8 @@
public:
static storage_info_t* get_storage_info(
- const sp<android::hardware::health::V2_0::IHealth>& healthService);
- virtual ~storage_info_t() {};
+ const shared_ptr<aidl::android::hardware::health::IHealth>& healthService);
+ virtual ~storage_info_t(){};
virtual void report() {};
void load_perf_history_proto(const IOPerfHistory& perf_history);
void refresh(IOPerfHistory* perf_history);
@@ -105,14 +105,14 @@
class health_storage_info_t : public storage_info_t {
private:
- using IHealth = hardware::health::V2_0::IHealth;
- using StorageInfo = hardware::health::V2_0::StorageInfo;
+ using IHealth = aidl::android::hardware::health::IHealth;
+ using StorageInfo = aidl::android::hardware::health::StorageInfo;
- sp<IHealth> mHealth;
+ shared_ptr<IHealth> mHealth;
void set_values_from_hal_storage_info(const StorageInfo& halInfo);
public:
- health_storage_info_t(const sp<IHealth>& service) : mHealth(service){};
+ health_storage_info_t(const shared_ptr<IHealth>& service) : mHealth(service){};
virtual ~health_storage_info_t() {}
virtual void report();
};
diff --git a/storaged/storaged.cpp b/storaged/storaged.cpp
index b7aa89f..fb855f7 100644
--- a/storaged/storaged.cpp
+++ b/storaged/storaged.cpp
@@ -28,12 +28,16 @@
#include <sstream>
#include <string>
+#include <aidl/android/hardware/health/BnHealthInfoCallback.h>
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/unique_fd.h>
+#include <android/binder_ibinder.h>
+#include <android/binder_manager.h>
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <batteryservice/BatteryServiceConstants.h>
#include <cutils/properties.h>
+#include <health-shim/shim.h>
#include <healthhalutils/HealthHalUtils.h>
#include <hidl/HidlTransportSupport.h>
#include <hwbinder/IPCThreadState.h>
@@ -64,26 +68,59 @@
const uint32_t storaged_t::current_version = 4;
+using aidl::android::hardware::health::BatteryStatus;
+using aidl::android::hardware::health::BnHealthInfoCallback;
+using aidl::android::hardware::health::HealthInfo;
+using aidl::android::hardware::health::IHealth;
+using aidl::android::hardware::health::IHealthInfoCallback;
using android::hardware::interfacesEqual;
-using android::hardware::Return;
-using android::hardware::health::V1_0::BatteryStatus;
-using android::hardware::health::V1_0::toString;
using android::hardware::health::V2_0::get_health_service;
-using android::hardware::health::V2_0::HealthInfo;
-using android::hardware::health::V2_0::IHealth;
-using android::hardware::health::V2_0::Result;
using android::hidl::manager::V1_0::IServiceManager;
+using HidlHealth = android::hardware::health::V2_0::IHealth;
+using aidl::android::hardware::health::HealthShim;
+using ndk::ScopedAIBinder_DeathRecipient;
+using ndk::ScopedAStatus;
+HealthServicePair HealthServicePair::get() {
+ HealthServicePair ret;
+ auto service_name = IHealth::descriptor + "/default"s;
+ if (AServiceManager_isDeclared(service_name.c_str())) {
+ ndk::SpAIBinder binder(AServiceManager_waitForService(service_name.c_str()));
+ ret.aidl_health = IHealth::fromBinder(binder);
+ if (ret.aidl_health == nullptr) {
+ LOG(WARNING) << "AIDL health service is declared, but it cannot be retrieved.";
+ }
+ }
+ if (ret.aidl_health == nullptr) {
+ LOG(INFO) << "Unable to get AIDL health service, trying HIDL...";
+ ret.hidl_health = get_health_service();
+ if (ret.hidl_health != nullptr) {
+ ret.aidl_health = ndk::SharedRefBase::make<HealthShim>(ret.hidl_health);
+ }
+ }
+ if (ret.aidl_health == nullptr) {
+ LOG(WARNING) << "health: failed to find IHealth service";
+ return {};
+ }
+ return ret;
+}
inline charger_stat_t is_charger_on(BatteryStatus prop) {
return (prop == BatteryStatus::CHARGING || prop == BatteryStatus::FULL) ?
CHARGER_ON : CHARGER_OFF;
}
-Return<void> storaged_t::healthInfoChanged(const HealthInfo& props) {
- mUidm.set_charger_state(is_charger_on(props.legacy.batteryStatus));
- return android::hardware::Void();
-}
+class HealthInfoCallback : public BnHealthInfoCallback {
+ public:
+ HealthInfoCallback(uid_monitor* uidm) : mUidm(uidm) {}
+ ScopedAStatus healthInfoChanged(const HealthInfo& info) override {
+ mUidm->set_charger_state(is_charger_on(info.batteryStatus));
+ return ScopedAStatus::ok();
+ }
+
+ private:
+ uid_monitor* mUidm;
+};
void storaged_t::init() {
init_health_service();
@@ -91,42 +128,59 @@
storage_info.reset(storage_info_t::get_storage_info(health));
}
+static void onHealthBinderDied(void*) {
+ LOG(ERROR) << "health service died, exiting";
+ android::hardware::IPCThreadState::self()->stopProcess();
+ exit(1);
+}
+
void storaged_t::init_health_service() {
if (!mUidm.enabled())
return;
- health = get_health_service();
- if (health == NULL) {
- LOG(WARNING) << "health: failed to find IHealth service";
- return;
- }
+ auto [aidlHealth, hidlHealth] = HealthServicePair::get();
+ health = aidlHealth;
+ if (health == nullptr) return;
BatteryStatus status = BatteryStatus::UNKNOWN;
- auto ret = health->getChargeStatus([&](Result r, BatteryStatus v) {
- if (r != Result::SUCCESS) {
- LOG(WARNING) << "health: cannot get battery status " << toString(r);
- return;
- }
- if (v == BatteryStatus::UNKNOWN) {
- LOG(WARNING) << "health: invalid battery status";
- }
- status = v;
- });
+ auto ret = health->getChargeStatus(&status);
if (!ret.isOk()) {
- LOG(WARNING) << "health: get charge status transaction error " << ret.description();
+ LOG(WARNING) << "health: cannot get battery status: " << ret.getDescription();
+ }
+ if (status == BatteryStatus::UNKNOWN) {
+ LOG(WARNING) << "health: invalid battery status";
}
mUidm.init(is_charger_on(status));
// register listener after init uid_monitor
- health->registerCallback(this);
- health->linkToDeath(this, 0 /* cookie */);
+ aidl_health_callback = std::make_shared<HealthInfoCallback>(&mUidm);
+ ret = health->registerCallback(aidl_health_callback);
+ if (!ret.isOk()) {
+ LOG(WARNING) << "health: failed to register callback: " << ret.getDescription();
+ }
+
+ if (hidlHealth != nullptr) {
+ hidl_death_recp = new hidl_health_death_recipient(hidlHealth);
+ auto ret = hidlHealth->linkToDeath(hidl_death_recp, 0 /* cookie */);
+ if (!ret.isOk()) {
+ LOG(WARNING) << "Failed to link to death (HIDL): " << ret.description();
+ }
+ } else {
+ aidl_death_recp =
+ ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(onHealthBinderDied));
+ auto ret = AIBinder_linkToDeath(health->asBinder().get(), aidl_death_recp.get(),
+ nullptr /* cookie */);
+ if (ret != STATUS_OK) {
+ LOG(WARNING) << "Failed to link to death (AIDL): "
+ << ScopedAStatus(AStatus_fromStatus(ret)).getDescription();
+ }
+ }
}
-void storaged_t::serviceDied(uint64_t cookie, const wp<::android::hidl::base::V1_0::IBase>& who) {
- if (health != NULL && interfacesEqual(health, who.promote())) {
- LOG(ERROR) << "health service died, exiting";
- android::hardware::IPCThreadState::self()->stopProcess();
- exit(1);
+void hidl_health_death_recipient::serviceDied(uint64_t cookie,
+ const wp<::android::hidl::base::V1_0::IBase>& who) {
+ if (mHealth != nullptr && interfacesEqual(mHealth, who.promote())) {
+ onHealthBinderDied(reinterpret_cast<void*>(cookie));
} else {
LOG(ERROR) << "unknown service died";
}
diff --git a/storaged/storaged_diskstats.cpp b/storaged/storaged_diskstats.cpp
index 52bd4e0..1eae5a1 100644
--- a/storaged/storaged_diskstats.cpp
+++ b/storaged/storaged_diskstats.cpp
@@ -30,11 +30,8 @@
namespace {
-using android::sp;
-using android::hardware::health::V2_0::DiskStats;
-using android::hardware::health::V2_0::IHealth;
-using android::hardware::health::V2_0::Result;
-using android::hardware::health::V2_0::toString;
+using aidl::android::hardware::health::DiskStats;
+using aidl::android::hardware::health::IHealth;
#ifdef DEBUG
void log_debug_disk_perf(struct disk_perf* perf, const char* type) {
@@ -121,39 +118,30 @@
dst->io_in_queue = src.ioInQueue;
}
-bool get_disk_stats_from_health_hal(const sp<IHealth>& service, struct disk_stats* stats) {
+bool get_disk_stats_from_health_hal(const std::shared_ptr<IHealth>& service,
+ struct disk_stats* stats) {
struct timespec ts;
if (!get_time(&ts)) {
return false;
}
- bool success = false;
- auto ret = service->getDiskStats([&success, stats](auto result, const auto& halStats) {
- if (result == Result::NOT_SUPPORTED) {
- LOG(DEBUG) << "getDiskStats is not supported on health HAL.";
- return;
+ std::vector<DiskStats> halStats;
+ auto ret = service->getDiskStats(&halStats);
+ if (ret.isOk()) {
+ if (halStats.size() > 0) {
+ convert_hal_disk_stats(stats, halStats[0]);
+ init_disk_stats_other(ts, stats);
+ return true;
}
- if (result != Result::SUCCESS || halStats.size() == 0) {
- LOG(ERROR) << "getDiskStats failed with result " << toString(result) << " and size "
- << halStats.size();
- return;
- }
-
- convert_hal_disk_stats(stats, halStats[0]);
- success = true;
- });
-
- if (!ret.isOk()) {
- LOG(ERROR) << "getDiskStats failed with " << ret.description();
+ LOG(ERROR) << "getDiskStats succeeded but size is 0";
return false;
}
-
- if (!success) {
+ if (ret.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+ LOG(DEBUG) << "getDiskStats is not supported on health HAL.";
return false;
}
-
- init_disk_stats_other(ts, stats);
- return true;
+ LOG(ERROR) << "getDiskStats failed with " << ret.getDescription();
+ return false;
}
struct disk_perf get_disk_perf(struct disk_stats* stats)
diff --git a/storaged/storaged_info.cpp b/storaged/storaged_info.cpp
index bb21829..3e646e0 100644
--- a/storaged/storaged_info.cpp
+++ b/storaged/storaged_info.cpp
@@ -36,9 +36,8 @@
using namespace android::base;
using namespace storaged_proto;
-using android::hardware::health::V2_0::IHealth;
-using android::hardware::health::V2_0::Result;
-using android::hardware::health::V2_0::StorageInfo;
+using aidl::android::hardware::health::IHealth;
+using aidl::android::hardware::health::StorageInfo;
const string emmc_info_t::emmc_sysfs = "/sys/bus/mmc/devices/mmc0:0001/";
const char* emmc_info_t::emmc_ver_str[9] = {
@@ -57,7 +56,7 @@
} // namespace
-storage_info_t* storage_info_t::get_storage_info(const sp<IHealth>& healthService) {
+storage_info_t* storage_info_t::get_storage_info(const shared_ptr<IHealth>& healthService) {
if (healthService != nullptr) {
return new health_storage_info_t(healthService);
}
@@ -326,23 +325,22 @@
}
void health_storage_info_t::report() {
- auto ret = mHealth->getStorageInfo([this](auto result, const auto& halInfos) {
- if (result == Result::NOT_SUPPORTED) {
- LOG(DEBUG) << "getStorageInfo is not supported on health HAL.";
+ vector<StorageInfo> halInfos;
+ auto ret = mHealth->getStorageInfo(&halInfos);
+ if (ret.isOk()) {
+ if (halInfos.size() != 0) {
+ set_values_from_hal_storage_info(halInfos[0]);
+ publish();
return;
}
- if (result != Result::SUCCESS || halInfos.size() == 0) {
- LOG(ERROR) << "getStorageInfo failed with result " << toString(result) << " and size "
- << halInfos.size();
- return;
- }
- set_values_from_hal_storage_info(halInfos[0]);
- publish();
- });
-
- if (!ret.isOk()) {
- LOG(ERROR) << "getStorageInfo failed with " << ret.description();
+ LOG(ERROR) << "getStorageInfo succeeded but size is 0";
+ return;
}
+ if (ret.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+ LOG(DEBUG) << "getStorageInfo is not supported on health HAL.";
+ return;
+ }
+ LOG(ERROR) << "getStorageInfo failed with " << ret.getDescription();
}
void health_storage_info_t::set_values_from_hal_storage_info(const StorageInfo& halInfo) {
diff --git a/storaged/tests/storaged_test.cpp b/storaged/tests/storaged_test.cpp
index 64009c2..bb71bf3 100644
--- a/storaged/tests/storaged_test.cpp
+++ b/storaged/tests/storaged_test.cpp
@@ -25,6 +25,7 @@
#include <gtest/gtest.h>
+#include <aidl/android/hardware/health/IHealth.h>
#include <healthhalutils/HealthHalUtils.h>
#include <storaged.h> // data structures
#include <storaged_utils.h> // functions to test
@@ -64,20 +65,23 @@
} // namespace
// the return values of the tested functions should be the expected ones
-const char* DISK_STATS_PATH;
+const char* get_disk_stats_path() {
+ if (access(MMC_DISK_STATS_PATH, R_OK) >= 0) {
+ return MMC_DISK_STATS_PATH;
+ } else if (access(SDA_DISK_STATS_PATH, R_OK) >= 0) {
+ return SDA_DISK_STATS_PATH;
+ } else {
+ return nullptr;
+ }
+}
TEST(storaged_test, retvals) {
struct disk_stats stats;
memset(&stats, 0, sizeof(struct disk_stats));
- if (access(MMC_DISK_STATS_PATH, R_OK) >= 0) {
- DISK_STATS_PATH = MMC_DISK_STATS_PATH;
- } else if (access(SDA_DISK_STATS_PATH, R_OK) >= 0) {
- DISK_STATS_PATH = SDA_DISK_STATS_PATH;
- } else {
- return;
- }
+ auto disk_stats_path = get_disk_stats_path();
+ if (disk_stats_path == nullptr) GTEST_SKIP();
- EXPECT_TRUE(parse_disk_stats(DISK_STATS_PATH, &stats));
+ EXPECT_TRUE(parse_disk_stats(disk_stats_path, &stats));
struct disk_stats old_stats;
memset(&old_stats, 0, sizeof(struct disk_stats));
@@ -92,7 +96,9 @@
TEST(storaged_test, disk_stats) {
struct disk_stats stats = {};
- ASSERT_TRUE(parse_disk_stats(DISK_STATS_PATH, &stats));
+ auto disk_stats_path = get_disk_stats_path();
+ if (disk_stats_path == nullptr) GTEST_SKIP();
+ ASSERT_TRUE(parse_disk_stats(disk_stats_path, &stats));
// every entry of stats (except io_in_flight) should all be greater than 0
for (uint i = 0; i < DISK_STATS_SIZE; ++i) {
@@ -103,7 +109,7 @@
// accumulation of the increments should be the same with the overall increment
struct disk_stats base = {}, tmp = {}, curr, acc = {}, inc[5];
for (uint i = 0; i < 5; ++i) {
- ASSERT_TRUE(parse_disk_stats(DISK_STATS_PATH, &curr));
+ ASSERT_TRUE(parse_disk_stats(disk_stats_path, &curr));
if (i == 0) {
base = curr;
tmp = curr;
@@ -235,9 +241,7 @@
}
TEST(storaged_test, disk_stats_monitor) {
- using android::hardware::health::V2_0::get_health_service;
-
- auto healthService = get_health_service();
+ auto [healthService, hidlHealth] = HealthServicePair::get();
// asserting that there is one file for diskstats
ASSERT_TRUE(healthService != nullptr || access(MMC_DISK_STATS_PATH, R_OK) >= 0 ||
@@ -246,6 +250,13 @@
// testing if detect() will return the right value
disk_stats_monitor dsm_detect{healthService};
ASSERT_TRUE(dsm_detect.enabled());
+
+ // Even if enabled(), healthService may not support disk stats. Check if it is supported.
+ std::vector<aidl::android::hardware::health::DiskStats> halStats;
+ if (healthService->getDiskStats(&halStats).getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+ GTEST_SKIP();
+ }
+
// feed monitor with constant perf data for io perf baseline
// using constant perf is reasonable since the functionality of stream_stats
// has already been tested
diff --git a/trusty/keymaster/Android.bp b/trusty/keymaster/Android.bp
index 99d9e56..0e916ef 100644
--- a/trusty/keymaster/Android.bp
+++ b/trusty/keymaster/Android.bp
@@ -105,8 +105,10 @@
"keymint/TrustySharedSecret.cpp",
"keymint/service.cpp",
],
+ defaults: [
+ "keymint_use_latest_hal_aidl_ndk_shared",
+ ],
shared_libs: [
- "android.hardware.security.keymint-V1-ndk",
"android.hardware.security.secureclock-V1-ndk",
"android.hardware.security.sharedsecret-V1-ndk",
"lib_android_keymaster_keymint_utils",