diff options
author | Tri Vo <trong@google.com> | 2019-06-20 15:25:39 -0700 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2019-06-20 15:25:39 -0700 |
commit | 8fbabc2d9a8c3547ad2a2e6cd325a77b7fb7346e (patch) | |
tree | 75c87d6bc7668279b07bdf86a1bd09ff66e1c1c3 | |
parent | d48d28f04253b33d7c991bcf7cacb1a6196d0374 (diff) | |
parent | cc685232f760dcec1384db1c455d93b766f080ba (diff) | |
download | platform_hardware_libhardware_legacy-8fbabc2d9a8c3547ad2a2e6cd325a77b7fb7346e.tar.gz platform_hardware_libhardware_legacy-8fbabc2d9a8c3547ad2a2e6cd325a77b7fb7346e.tar.bz2 platform_hardware_libhardware_legacy-8fbabc2d9a8c3547ad2a2e6cd325a77b7fb7346e.zip |
Merge "libpower: RAII wake lock implementation"
am: cc685232f7
Change-Id: Ia6a2bbfe192b7fccfe1ac0f8b10c3a420460c24c
-rw-r--r-- | Android.bp | 5 | ||||
-rw-r--r-- | include/hardware_legacy/power.h | 26 | ||||
-rw-r--r-- | power.cpp | 25 | ||||
-rw-r--r-- | power_test.cpp | 60 |
4 files changed, 107 insertions, 9 deletions
@@ -35,7 +35,10 @@ cc_test { defaults: ["libpower_defaults"], srcs: ["power_test.cpp"], static_libs: ["libpower"], - shared_libs: ["android.system.suspend@1.0"], + shared_libs: [ + "android.system.suspend@1.0", + "suspend_control_aidl_interface-cpp", + ], test_suites: ["device-tests"], require_root: true, } diff --git a/include/hardware_legacy/power.h b/include/hardware_legacy/power.h index 604e0ed..a053583 100644 --- a/include/hardware_legacy/power.h +++ b/include/hardware_legacy/power.h @@ -17,6 +17,10 @@ #ifndef _HARDWARE_POWER_H #define _HARDWARE_POWER_H +#if __cplusplus +#include <memory> +#include <string> +#endif #include <stdint.h> #if __cplusplus @@ -33,9 +37,27 @@ enum { int acquire_wake_lock(int lock, const char* id); int release_wake_lock(const char* id); +#if __cplusplus +} // extern "C" +#endif #if __cplusplus -} // extern "C" +// RAII way to acquire wake locks. +namespace android { +namespace power { + +class WakeLock { + public: + WakeLock(const std::string& name); + ~WakeLock(); + + private: + class WakeLockImpl; + std::unique_ptr<WakeLockImpl> mImpl; +}; + +} // namespace power +} // namespace android #endif -#endif // _HARDWARE_POWER_H +#endif // _HARDWARE_POWER_H @@ -78,3 +78,28 @@ int release_wake_lock(const char* id) { } return -1; } + +namespace android::power { + +WakeLock::WakeLock(const std::string& name) : mImpl(std::make_unique<WakeLockImpl>(name)) {} + +WakeLock::~WakeLock() = default; + +class WakeLock::WakeLockImpl { + public: + WakeLockImpl(const std::string& name) : mWakeLock(nullptr) { + static sp<ISystemSuspend> suspendService = ISystemSuspend::getService(); + mWakeLock = suspendService->acquireWakeLock(WakeLockType::PARTIAL, name); + } + ~WakeLockImpl() { + auto ret = mWakeLock->release(); + if (!ret.isOk()) { + LOG(ERROR) << "IWakeLock::release() call failed: " << ret.description(); + } + } + + private: + sp<IWakeLock> mWakeLock; +}; + +} // namespace android::power diff --git a/power_test.cpp b/power_test.cpp index 1ade263..5ae19d6 100644 --- a/power_test.cpp +++ b/power_test.cpp @@ -14,6 +14,9 @@ * limitations under the License. */ +#include <android/system/suspend/ISuspendControlService.h> +#include <binder/IServiceManager.h> +#include <gtest/gtest.h> #include <hardware_legacy/power.h> #include <csignal> @@ -22,8 +25,9 @@ #include <thread> #include <vector> -#include <gtest/gtest.h> - +using android::sp; +using android::system::suspend::ISuspendControlService; +using android::system::suspend::WakeLockInfo; using namespace std::chrono_literals; namespace android { @@ -73,10 +77,8 @@ TEST(LibpowerTest, WakeLockStressTest) { for (int j = 0; j < numLocks; j++) { // We want ids to be unique. std::string id = std::to_string(i) + "/" + std::to_string(j); - ASSERT_EQ(acquire_wake_lock(PARTIAL_WAKE_LOCK, id.c_str()), 0) - << "id: " << id; - ASSERT_EQ(release_wake_lock(id.c_str()), 0) - << "id: " << id;; + ASSERT_EQ(acquire_wake_lock(PARTIAL_WAKE_LOCK, id.c_str()), 0) << "id: " << id; + ASSERT_EQ(release_wake_lock(id.c_str()), 0) << "id: " << id; } }); } @@ -85,4 +87,50 @@ TEST(LibpowerTest, WakeLockStressTest) { } } +// Returns true iff found. +bool findWakeLockInfoByName( + const sp<ISuspendControlService>& service, + const std::string& name, + WakeLockInfo* info) { + std::vector<WakeLockInfo> wlStats; + service->getWakeLockStats(&wlStats); + auto it = std::find_if(wlStats.begin(), wlStats.end(), + [&name](const auto& x) { return x.name == name; }); + if (it != wlStats.end()) { + *info = *it; + return true; + } + return false; +} + +// Test RAII properties of WakeLock class. +TEST(LibpowerTest, RAIIWakeLock) { + sp<IBinder> control = + android::defaultServiceManager()->getService(android::String16("suspend_control")); + ASSERT_NE(control, nullptr) << "failed to get the suspend control service"; + sp<ISuspendControlService> controlService = interface_cast<ISuspendControlService>(control); + + auto name = std::to_string(rand()); + { + android::power::WakeLock wl{name}; + + WakeLockInfo info; + auto success = findWakeLockInfoByName(controlService, name, &info); + ASSERT_TRUE(success); + ASSERT_EQ(info.name, name); + ASSERT_EQ(info.pid, getpid()); + ASSERT_TRUE(info.isActive); + } + + // SystemSuspend receives wake lock release requests on hwbinder thread, while stats requests + // come on binder thread. Sleep to make sure that stats are reported *after* wake lock release. + std::this_thread::sleep_for(1ms); + WakeLockInfo info; + auto success = findWakeLockInfoByName(controlService, name, &info); + ASSERT_TRUE(success); + ASSERT_EQ(info.name, name); + ASSERT_EQ(info.pid, getpid()); + ASSERT_FALSE(info.isActive); +} + } // namespace android |