Merge "RAII style wakelocks: Add tryGet() factory method." am: ddff8e6dd0

Original change: https://android-review.googlesource.com/c/platform/hardware/libhardware_legacy/+/1592033

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I1d63478a6f2956d687971033621360f2abb3b9d2
This commit is contained in:
Kalesh Singh 2021-02-24 22:14:07 +00:00 committed by Automerger Merge Worker
commit e3a6357533
4 changed files with 45 additions and 8 deletions

View file

@ -34,7 +34,11 @@ int main(int argc, char ** /* argv */) {
return 0;
}
android::wakelock::WakeLock wl{gWakeLockName}; // RAII object
auto wl = android::wakelock::WakeLock::tryGet(gWakeLockName); // RAII object
if (!wl.has_value()) {
return EXIT_FAILURE;
}
while (true) { sleep(1000000); };
std::abort(); // should never reach here
return 0;

View file

@ -17,6 +17,7 @@
#pragma once
#include <memory>
#include <optional>
#include <string>
namespace android {
@ -24,13 +25,17 @@ namespace wakelock {
// RAII-style wake lock implementation
class WakeLock {
public:
WakeLock(const std::string& name);
~WakeLock();
private:
class WakeLockImpl;
std::unique_ptr<WakeLockImpl> mImpl;
public:
static std::optional<WakeLock> tryGet(const std::string& name);
// Constructor is only made public for use with std::optional.
// It is not intended to be and cannot be invoked from public context,
// since private WakeLockImpl prevents calling the constructor directly.
WakeLock(std::unique_ptr<WakeLockImpl> wlImpl);
~WakeLock();
};
} // namespace wakelock

View file

@ -88,26 +88,51 @@ class WakeLock::WakeLockImpl {
public:
WakeLockImpl(const std::string& name);
~WakeLockImpl();
bool acquireOk();
private:
sp<IWakeLock> mWakeLock;
};
WakeLock::WakeLock(const std::string& name) : mImpl(std::make_unique<WakeLockImpl>(name)) {}
std::optional<WakeLock> WakeLock::tryGet(const std::string& name) {
std::unique_ptr<WakeLockImpl> wlImpl = std::make_unique<WakeLockImpl>(name);
if (wlImpl->acquireOk()) {
return { std::move(wlImpl) };
} else {
LOG(ERROR) << "Failed to acquire wakelock: " << name;
return {};
}
}
WakeLock::WakeLock(std::unique_ptr<WakeLockImpl> wlImpl) : mImpl(std::move(wlImpl)) {}
WakeLock::~WakeLock() = default;
WakeLock::WakeLockImpl::WakeLockImpl(const std::string& name) : mWakeLock(nullptr) {
static sp<ISystemSuspend> suspendService = ISystemSuspend::getService();
mWakeLock = suspendService->acquireWakeLock(WakeLockType::PARTIAL, name);
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();
} else {
mWakeLock = ret;
}
}
WakeLock::WakeLockImpl::~WakeLockImpl() {
if (!acquireOk()) {
return;
}
auto ret = mWakeLock->release();
if (!ret.isOk()) {
LOG(ERROR) << "IWakeLock::release() call failed: " << ret.description();
}
}
bool WakeLock::WakeLockImpl::acquireOk() {
return mWakeLock != nullptr;
}
} // namespace wakelock
} // namespace android

View file

@ -121,7 +121,10 @@ class WakeLockTest : public ::testing::Test {
TEST_F(WakeLockTest, WakeLockDestructor) {
auto name = std::to_string(rand());
{
android::wakelock::WakeLock wl{name};
auto wl = android::wakelock::WakeLock::tryGet(name);
if (!wl.has_value()) {
return;
}
WakeLockInfo info;
auto success = findWakeLockInfoByName(controlService, name, &info);