Merge "libpower: Use AIDL suspend HAL"

This commit is contained in:
Kalesh Singh 2021-07-23 17:17:03 +00:00 committed by Gerrit Code Review
commit fc7f7499c2
2 changed files with 41 additions and 35 deletions

View file

@ -40,7 +40,7 @@ cc_library {
defaults: ["libpower_defaults"],
srcs: ["power.cpp"],
export_include_dirs: ["include"],
shared_libs: ["android.system.suspend@1.0"],
shared_libs: ["android.system.suspend-V1-ndk_platform"],
vendor_available: true,
vndk: {
enabled: true,
@ -54,7 +54,7 @@ cc_test {
static_libs: ["libpower"],
shared_libs: [
"android.system.suspend.control.internal-cpp",
"android.system.suspend@1.0",
"android.system.suspend-V1-ndk_platform",
],
test_suites: ["device-tests"],
require_root: true,
@ -69,7 +69,7 @@ cc_library_shared {
},
shared_libs: [
"android.system.suspend@1.0",
"android.system.suspend-V1-ndk_platform",
"libdl",
],
@ -98,7 +98,7 @@ cc_test {
srcs: ["block_suspend.cpp"],
static_libs: ["libpower"],
shared_libs: [
"android.system.suspend@1.0",
"android.system.suspend-V1-ndk_platform",
],
gtest: false,
}

View file

@ -20,8 +20,10 @@
#include <hardware_legacy/power.h>
#include <wakelock/wakelock.h>
#include <aidl/android/system/suspend/ISystemSuspend.h>
#include <aidl/android/system/suspend/IWakeLock.h>
#include <android/binder_manager.h>
#include <android-base/logging.h>
#include <android/system/suspend/1.0/ISystemSuspend.h>
#include <utils/Trace.h>
#include <mutex>
@ -29,22 +31,23 @@
#include <thread>
#include <unordered_map>
using android::sp;
using android::system::suspend::V1_0::ISystemSuspend;
using android::system::suspend::V1_0::IWakeLock;
using android::system::suspend::V1_0::WakeLockType;
using aidl::android::system::suspend::ISystemSuspend;
using aidl::android::system::suspend::IWakeLock;
using aidl::android::system::suspend::WakeLockType;
static std::mutex gLock;
static std::unordered_map<std::string, sp<IWakeLock>> gWakeLockMap;
static std::unordered_map<std::string, std::shared_ptr<IWakeLock>> gWakeLockMap;
static const sp<ISystemSuspend>& getSystemSuspendServiceOnce() {
static sp<ISystemSuspend> suspendService = ISystemSuspend::getService();
static const std::shared_ptr<ISystemSuspend> getSystemSuspendServiceOnce() {
static std::shared_ptr<ISystemSuspend> suspendService =
ISystemSuspend::fromBinder(ndk::SpAIBinder(AServiceManager_checkService(
(ISystemSuspend::descriptor + std::string("/default")).c_str())));
return suspendService;
}
int acquire_wake_lock(int, const char* id) {
ATRACE_CALL();
const auto& suspendService = getSystemSuspendServiceOnce();
const auto suspendService = getSystemSuspendServiceOnce();
if (!suspendService) {
LOG(ERROR) << "ISystemSuspend::getService() failed.";
return -1;
@ -52,14 +55,16 @@ int acquire_wake_lock(int, const char* id) {
std::lock_guard<std::mutex> l{gLock};
if (!gWakeLockMap[id]) {
auto ret = suspendService->acquireWakeLock(WakeLockType::PARTIAL, id);
// It's possible that during device shutdown SystemSuspend service has already exited. In
// these situations HIDL calls to it will result in a DEAD_OBJECT transaction error. We
// check for DEAD_OBJECT so that libpower clients can shutdown cleanly.
if (ret.isDeadObject()) {
std::shared_ptr<IWakeLock> wl = nullptr;
auto status = suspendService->acquireWakeLock(WakeLockType::PARTIAL, id, &wl);
// It's possible that during device shutdown SystemSuspend service has already exited.
// Check that the wakelock object is not null.
if (!wl) {
LOG(ERROR) << "ISuspendService::acquireWakeLock() call failed: "
<< status.getDescription();
return -1;
} else {
gWakeLockMap[id] = ret;
gWakeLockMap[id] = wl;
}
}
return 0;
@ -70,12 +75,12 @@ int release_wake_lock(const char* id) {
std::lock_guard<std::mutex> l{gLock};
if (gWakeLockMap[id]) {
// Ignore errors on release() call since hwbinder driver will clean up the underlying object
// once we clear the corresponding strong pointer.
auto ret = gWakeLockMap[id]->release();
if (!ret.isOk()) {
LOG(ERROR) << "IWakeLock::release() call failed: " << ret.description();
// once we clear the corresponding shared_ptr.
auto status = gWakeLockMap[id]->release();
if (!status.isOk()) {
LOG(ERROR) << "IWakeLock::release() call failed: " << status.getDescription();
}
gWakeLockMap[id].clear();
gWakeLockMap[id] = nullptr;
return 0;
}
return -1;
@ -91,7 +96,7 @@ class WakeLock::WakeLockImpl {
bool acquireOk();
private:
sp<IWakeLock> mWakeLock;
std::shared_ptr<IWakeLock> mWakeLock;
};
std::optional<WakeLock> WakeLock::tryGet(const std::string& name) {
@ -109,14 +114,15 @@ WakeLock::WakeLock(std::unique_ptr<WakeLockImpl> wlImpl) : mImpl(std::move(wlImp
WakeLock::~WakeLock() = default;
WakeLock::WakeLockImpl::WakeLockImpl(const std::string& name) : mWakeLock(nullptr) {
static sp<ISystemSuspend> suspendService = ISystemSuspend::getService();
auto ret = suspendService->acquireWakeLock(WakeLockType::PARTIAL, name);
// It's possible that during device SystemSuspend service is not avaiable. In these
// situations HIDL calls to it will result in a DEAD_OBJECT transaction error.
if (ret.isDeadObject()) {
LOG(ERROR) << "ISuspendService::acquireWakeLock() call failed: " << ret.description();
const auto suspendService = getSystemSuspendServiceOnce();
std::shared_ptr<IWakeLock> wl = nullptr;
auto status = suspendService->acquireWakeLock(WakeLockType::PARTIAL, name, &wl);
// It's possible that during device shutdown SystemSuspend service has already exited.
// Check that the wakelock object is not null.
if (!wl) {
LOG(ERROR) << "ISuspendService::acquireWakeLock() call failed: " << status.getDescription();
} else {
mWakeLock = ret;
mWakeLock = wl;
}
}
@ -124,9 +130,9 @@ WakeLock::WakeLockImpl::~WakeLockImpl() {
if (!acquireOk()) {
return;
}
auto ret = mWakeLock->release();
if (!ret.isOk()) {
LOG(ERROR) << "IWakeLock::release() call failed: " << ret.description();
auto status = mWakeLock->release();
if (!status.isOk()) {
LOG(ERROR) << "IWakeLock::release() call failed: " << status.getDescription();
}
}