aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Erat <derat@google.com>2015-09-18 09:58:03 -0600
committerDaniel Erat <derat@google.com>2015-09-18 12:04:37 -0600
commitcb57344ce792f41e58bc476840a82eba14b0fde9 (patch)
treed1cbf876d54cd2d953afba4dec454211917a0c4a
parent11ad82ee79a70d27788a725fb235029864569363 (diff)
downloadnativepower-cb57344ce792f41e58bc476840a82eba14b0fde9.tar.gz
Add libnativepower and nativepowerman.
Add the skeleton of a C++ library and daemon that can be used for power management by Brillo. Bug: 22122485 Change-Id: I3769ecc3e7b43efc3e03af4afada48d570f56ef9
-rw-r--r--Android.mk22
-rw-r--r--MODULE_LICENSE_APACHE20
-rw-r--r--NOTICE190
-rw-r--r--README7
-rw-r--r--client/Android.mk63
-rw-r--r--client/wake_lock.cc86
-rw-r--r--client/wake_lock_unittest.cc70
-rw-r--r--daemon/Android.mk119
-rw-r--r--daemon/BnPowerManager.cc72
-rw-r--r--daemon/main.cc65
-rw-r--r--daemon/power_manager.cc89
-rw-r--r--daemon/power_manager.h78
-rw-r--r--daemon/power_manager_stub.cc100
-rw-r--r--daemon/power_manager_unittest.cc69
-rw-r--r--daemon/wake_lock_manager.cc130
-rw-r--r--daemon/wake_lock_manager.h92
-rw-r--r--daemon/wake_lock_manager_stub.cc43
-rw-r--r--daemon/wake_lock_manager_stub.h61
-rw-r--r--daemon/wake_lock_manager_unittest.cc142
-rw-r--r--example/Android.mk39
-rw-r--r--example/power_example.cc48
-rw-r--r--include/nativepower/BnPowerManager.h37
-rw-r--r--include/nativepower/constants.h27
-rw-r--r--include/nativepower/power_manager_stub.h87
-rw-r--r--include/nativepower/wake_lock.h68
25 files changed, 1804 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..72394ad
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2015 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.
+#
+
+# libchromeos is only built for Linux, so this package is too.
+ifeq ($(HOST_OS),linux)
+
+include $(call all-subdir-makefiles)
+
+endif # HOST_OS == linux
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_APACHE2
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..a849a94
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2014-2015, 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.
+
+ 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.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/README b/README
new file mode 100644
index 0000000..bf8a5c7
--- /dev/null
+++ b/README
@@ -0,0 +1,7 @@
+This directory contains a C++ implementation of power management for use by
+Brillo:
+
+ client/ - libnativepower, a client library for calling nativepowerman
+ daemon/ - nativepowerman, a daemon that performs power management
+ example/ - power_example, an example executable that uses libnativepower
+ include/ - exported header files
diff --git a/client/Android.mk b/client/Android.mk
new file mode 100644
index 0000000..e2225df
--- /dev/null
+++ b/client/Android.mk
@@ -0,0 +1,63 @@
+#
+# Copyright (C) 2015 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+libnativepower_CommonCFlags := -Wall -Werror -Wno-unused-parameter
+libnativepower_CommonCFlags += -Wno-sign-promo # for libchrome
+libnativepower_CommonCIncludes := $(LOCAL_PATH)/../include
+libnativepower_CommonSharedLibraries := \
+ libbinder \
+ libbinderwrapper \
+ libchrome \
+ libchromeos \
+ libpowermanager \
+ libutils \
+
+# libnativepower shared library
+# ========================================================
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libnativepower
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_CFLAGS := $(libnativepower_CommonCFlags)
+LOCAL_C_INCLUDES := $(libnativepower_CommonCIncludes)
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/../include
+LOCAL_SHARED_LIBRARIES := $(libnativepower_CommonSharedLibraries)
+LOCAL_SRC_FILES := \
+ wake_lock.cc \
+
+include $(BUILD_SHARED_LIBRARY)
+
+# libnativepower_tests executable
+# ========================================================
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libnativepower_tests
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_CFLAGS := $(libnativepower_CommonCFlags)
+LOCAL_C_INCLUDES := $(libnativepower_CommonCIncludes)
+LOCAL_STATIC_LIBRARIES := libgtest libBionicGtestMain
+LOCAL_SHARED_LIBRARIES := \
+ $(libnativepower_CommonSharedLibraries) \
+ libbinderwrapper_test_support \
+ libnativepower \
+ libnativepower_test_support \
+
+LOCAL_SRC_FILES := \
+ wake_lock_unittest.cc \
+
+include $(BUILD_NATIVE_TEST)
diff --git a/client/wake_lock.cc b/client/wake_lock.cc
new file mode 100644
index 0000000..98dcb0e
--- /dev/null
+++ b/client/wake_lock.cc
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2015 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 <nativepower/wake_lock.h>
+
+#include <base/bind.h>
+#include <base/logging.h>
+#include <binder/IBinder.h>
+#include <binderwrapper/binder_wrapper.h>
+#include <nativepower/constants.h>
+#include <powermanager/PowerManager.h>
+
+namespace android {
+
+// static
+std::unique_ptr<WakeLock> WakeLock::Create(const std::string& tag,
+ const std::string& package) {
+ std::unique_ptr<WakeLock> lock(new WakeLock(tag, package));
+ if (!lock->Init())
+ lock.reset();
+ return lock;
+}
+
+WakeLock::~WakeLock() {
+ if (power_manager_.get()) {
+ BinderWrapper::Get()->UnregisterForDeathNotifications(
+ IInterface::asBinder(power_manager_));
+ status_t status =
+ power_manager_->releaseWakeLock(lock_binder_, 0 /* flags */);
+ if (status != OK) {
+ LOG(ERROR) << "Wake lock release request for \"" << tag_ << "\" failed "
+ << "with status " << status;
+ }
+ }
+}
+
+WakeLock::WakeLock(const std::string& tag, const std::string& package)
+ : tag_(tag),
+ package_(package) {}
+
+bool WakeLock::Init() {
+ sp<IBinder> power_manager_binder =
+ BinderWrapper::Get()->GetService(kPowerManagerServiceName);
+ if (!power_manager_binder.get()) {
+ LOG(ERROR) << "Didn't get " << kPowerManagerServiceName << " service";
+ return false;
+ }
+
+ power_manager_ = interface_cast<IPowerManager>(power_manager_binder);
+ BinderWrapper::Get()->RegisterForDeathNotifications(
+ power_manager_binder,
+ base::Bind(&WakeLock::OnPowerManagerDied, base::Unretained(this)));
+
+ lock_binder_ = BinderWrapper::Get()->CreateLocalBinder();
+ status_t status = power_manager_->acquireWakeLock(
+ POWERMANAGER_PARTIAL_WAKE_LOCK,
+ lock_binder_, String16(tag_.c_str()), String16(package_.c_str()));
+ if (status != OK) {
+ LOG(ERROR) << "Wake lock acquire request for tag \"" << tag_ << "\" failed "
+ << "with status " << status;
+ power_manager_.clear();
+ return false;
+ }
+
+ return true;
+}
+
+void WakeLock::OnPowerManagerDied() {
+ LOG(WARNING) << "Power manager died; lost wake lock for \"" << tag_ << "\"";
+ power_manager_.clear();
+}
+
+} // namespace android
diff --git a/client/wake_lock_unittest.cc b/client/wake_lock_unittest.cc
new file mode 100644
index 0000000..1221f1a
--- /dev/null
+++ b/client/wake_lock_unittest.cc
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2015 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 <memory>
+
+#include <base/macros.h>
+#include <binder/Binder.h>
+#include <binder/IBinder.h>
+#include <binderwrapper/binder_test_base.h>
+#include <binderwrapper/stub_binder_wrapper.h>
+#include <nativepower/constants.h>
+#include <nativepower/power_manager_stub.h>
+#include <nativepower/wake_lock.h>
+
+namespace android {
+
+class WakeLockTest : public BinderTestBase {
+ public:
+ WakeLockTest()
+ : power_manager_(new PowerManagerStub()),
+ power_manager_binder_(power_manager_) {
+ binder_wrapper_->SetBinderForService(kPowerManagerServiceName,
+ power_manager_binder_);
+ }
+ ~WakeLockTest() override = default;
+
+ protected:
+ PowerManagerStub* power_manager_; // Owned by |power_manager_binder_|.
+ sp<IBinder> power_manager_binder_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(WakeLockTest);
+};
+
+TEST_F(WakeLockTest, CreateAndDestroy) {
+ std::unique_ptr<WakeLock> lock(WakeLock::Create("foo", "bar"));
+ ASSERT_EQ(1u, power_manager_->num_locks());
+ ASSERT_EQ(1u, binder_wrapper()->local_binders().size());
+ EXPECT_EQ(
+ PowerManagerStub::ConstructLockString("foo", "bar", -1),
+ power_manager_->GetLockString(binder_wrapper()->local_binders()[0]));
+
+ lock.reset();
+ EXPECT_EQ(0u, power_manager_->num_locks());
+}
+
+TEST_F(WakeLockTest, PowerManagerDeath) {
+ std::unique_ptr<WakeLock> lock(WakeLock::Create("foo", "bar"));
+ binder_wrapper()->NotifyAboutBinderDeath(power_manager_binder_);
+
+ // Since the WakeLock was informed that the power manager died, it shouldn't
+ // try to release its lock on destruction.
+ lock.reset();
+ EXPECT_EQ(1u, power_manager_->num_locks());
+}
+
+} // namespace android
diff --git a/daemon/Android.mk b/daemon/Android.mk
new file mode 100644
index 0000000..d8ad7b1
--- /dev/null
+++ b/daemon/Android.mk
@@ -0,0 +1,119 @@
+#
+# Copyright (C) 2015 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+nativepowerman_CommonCFlags := -Wall -Werror -Wno-unused-parameter
+nativepowerman_CommonCFlags += -Wno-sign-promo # for libchrome
+nativepowerman_CommonCIncludes := $(LOCAL_PATH)/../include
+nativepowerman_CommonSharedLibraries := \
+ libbinder \
+ libchrome \
+ libpowermanager \
+ libutils \
+
+# nativepowerman executable
+# ========================================================
+
+include $(CLEAR_VARS)
+# "nativepowermanager" would probably be a better name, but Android service
+# names are limited to 16 characters.
+LOCAL_MODULE := nativepowerman
+LOCAL_REQUIRED_MODULES := init.nativepowerman.rc
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_CFLAGS := $(nativepowerman_CommonCFlags)
+LOCAL_STATIC_LIBRARIES := libnativepowerman
+LOCAL_SHARED_LIBRARIES := \
+ $(nativepowerman_CommonSharedLibraries) \
+ libbinderwrapper \
+ libchromeos \
+ libchromeos-binder \
+
+LOCAL_SRC_FILES := main.cc
+
+include $(BUILD_EXECUTABLE)
+
+# init.nativepowerman.rc script
+# ========================================================
+
+ifdef INITRC_TEMPLATE
+include $(CLEAR_VARS)
+LOCAL_MODULE := init.nativepowerman.rc
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_INITRCD)
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(INITRC_TEMPLATE)
+ $(call generate-initrc-file,nativepowerman,,)
+endif
+
+# libnativepowerman client library (for daemon and tests)
+# ========================================================
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libnativepowerman
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_CFLAGS := $(nativepowerman_CommonCFlags)
+LOCAL_C_INCLUDES := $(nativepowerman_CommonCIncludes) external/gtest/include
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/../include
+LOCAL_SHARED_LIBRARIES := \
+ $(nativepowerman_CommonSharedLibraries) \
+ libbinderwrapper \
+ libchromeos \
+
+LOCAL_SRC_FILES := \
+ BnPowerManager.cc \
+ power_manager.cc \
+ wake_lock_manager.cc \
+
+include $(BUILD_STATIC_LIBRARY)
+
+# nativepowerman_tests executable
+# ========================================================
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := nativepowerman_tests
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_CFLAGS := $(nativepowerman_CommonCFlags)
+LOCAL_STATIC_LIBRARIES := libnativepowerman libgtest libBionicGtestMain
+LOCAL_SHARED_LIBRARIES := \
+ $(nativepowerman_CommonSharedLibraries) \
+ libbinderwrapper \
+ libbinderwrapper_test_support \
+
+LOCAL_SRC_FILES := \
+ power_manager_unittest.cc \
+ wake_lock_manager_stub.cc \
+ wake_lock_manager_unittest.cc \
+
+include $(BUILD_NATIVE_TEST)
+
+# libnativepower_test_support shared library
+# ========================================================
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libnativepower_test_support
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_CFLAGS := $(nativepowerman_CommonCFlags)
+LOCAL_C_INCLUDES := $(nativepowerman_CommonCIncludes)
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/../include
+LOCAL_SHARED_LIBRARIES := $(nativepowerman_CommonSharedLibraries)
+LOCAL_SRC_FILES := \
+ BnPowerManager.cc \
+ power_manager_stub.cc \
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/daemon/BnPowerManager.cc b/daemon/BnPowerManager.cc
new file mode 100644
index 0000000..ed6b9e1
--- /dev/null
+++ b/daemon/BnPowerManager.cc
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2015 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 <nativepower/BnPowerManager.h>
+
+#include <binder/Parcel.h>
+
+namespace android {
+
+status_t BnPowerManager::onTransact(uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags) {
+ switch (code) {
+ case IPowerManager::ACQUIRE_WAKE_LOCK: {
+ // The parameter orders in IPowerManager.aidl and IPowerManager.h don't
+ // match. :-( (BpPowerManager in IPowerManager.cpp passes arguments in the
+ // order that the AIDL file describes and that we use here, though.)
+ CHECK_INTERFACE(IPowerManager, data, reply);
+ sp<IBinder> lock = data.readStrongBinder();
+ int32_t flags = data.readInt32();
+ String16 tag = data.readString16();
+ String16 package_name = data.readString16();
+ // Ignore work source and history.
+ return acquireWakeLock(flags, lock, tag, package_name);
+ }
+ case IPowerManager::ACQUIRE_WAKE_LOCK_UID: {
+ CHECK_INTERFACE(IPowerManager, data, reply);
+ sp<IBinder> lock = data.readStrongBinder();
+ int32_t flags = data.readInt32();
+ String16 tag = data.readString16();
+ String16 package_name = data.readString16();
+ int32_t uid = data.readInt32();
+ return acquireWakeLockWithUid(flags, lock, tag, package_name, uid);
+ }
+ case IPowerManager::RELEASE_WAKE_LOCK: {
+ CHECK_INTERFACE(IPowerManager, data, reply);
+ sp<IBinder> lock = data.readStrongBinder();
+ int32_t flags = data.readInt32();
+ return releaseWakeLock(lock, flags);
+ }
+ case IPowerManager::UPDATE_WAKE_LOCK_UIDS: {
+ CHECK_INTERFACE(IPowerManager, data, reply);
+ sp<IBinder> lock = data.readStrongBinder();
+ // TODO: There's no Parcel::readInt32Array(). Add one.
+ return updateWakeLockUids(lock, 0, nullptr);
+ }
+ case IPowerManager::POWER_HINT: {
+ CHECK_INTERFACE(IPowerManager, data, reply);
+ int32_t hint_id = data.readInt32();
+ int32_t params = data.readInt32();
+ return powerHint(hint_id, params);
+ }
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+}
+
+} // namespace android
diff --git a/daemon/main.cc b/daemon/main.cc
new file mode 100644
index 0000000..0458441
--- /dev/null
+++ b/daemon/main.cc
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015 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 <sysexits.h>
+
+#include <base/logging.h>
+#include <base/macros.h>
+#include <binderwrapper/binder_wrapper.h>
+#include <chromeos/binder_watcher.h>
+#include <chromeos/daemons/daemon.h>
+#include <chromeos/flag_helper.h>
+
+#include "power_manager.h"
+
+namespace {
+
+class PowerManagerDaemon : public chromeos::Daemon {
+ public:
+ PowerManagerDaemon() = default;
+ ~PowerManagerDaemon() override = default;
+
+ private:
+ // chromeos::Daemon:
+ int OnInit() override {
+ int result = chromeos::Daemon::OnInit();
+ if (result != EX_OK)
+ return result;
+
+ android::BinderWrapper::Create();
+ if (!binder_watcher_.Init())
+ return EX_OSERR;
+ if (!power_manager_.Init())
+ return EX_OSERR;
+
+ LOG(INFO) << "Initialization complete";
+ return EX_OK;
+ }
+
+ chromeos::BinderWatcher binder_watcher_;
+ android::PowerManager power_manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(PowerManagerDaemon);
+};
+
+} // namespace
+
+int main(int argc, char *argv[]) {
+ // This also initializes base::CommandLine(), which is needed for logging.
+ chromeos::FlagHelper::Init(argc, argv, "Power management daemon");
+ logging::InitLogging(logging::LoggingSettings());
+ return PowerManagerDaemon().Run();
+}
diff --git a/daemon/power_manager.cc b/daemon/power_manager.cc
new file mode 100644
index 0000000..55dd799
--- /dev/null
+++ b/daemon/power_manager.cc
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2015 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 "power_manager.h"
+
+#include <base/logging.h>
+#include <binderwrapper/binder_wrapper.h>
+#include <nativepower/constants.h>
+#include <powermanager/IPowerManager.h>
+#include <utils/Errors.h>
+#include <utils/String8.h>
+
+namespace android {
+
+PowerManager::PowerManager() = default;
+
+PowerManager::~PowerManager() = default;
+
+bool PowerManager::Init() {
+ if (!wake_lock_manager_) {
+ wake_lock_manager_.reset(new WakeLockManager());
+ if (!static_cast<WakeLockManager*>(wake_lock_manager_.get())->Init())
+ return false;
+ }
+
+ LOG(INFO) << "Registering with service manager as "
+ << kPowerManagerServiceName;
+ return BinderWrapper::Get()->RegisterService(kPowerManagerServiceName, this);
+}
+
+status_t PowerManager::acquireWakeLock(int flags,
+ const sp<IBinder>& lock,
+ const String16& tag,
+ const String16& packageName,
+ bool isOneWay) {
+ return AddWakeLockRequest(lock, tag, packageName, -1) ? OK : UNKNOWN_ERROR;
+}
+
+status_t PowerManager::acquireWakeLockWithUid(int flags,
+ const sp<IBinder>& lock,
+ const String16& tag,
+ const String16& packageName,
+ int uid,
+ bool isOneWay) {
+ return AddWakeLockRequest(lock, tag, packageName, uid) ? OK : UNKNOWN_ERROR;
+}
+
+status_t PowerManager::releaseWakeLock(const sp<IBinder>& lock,
+ int flags,
+ bool isOneWay) {
+ return wake_lock_manager_->RemoveRequest(lock) ? OK : UNKNOWN_ERROR;
+}
+
+status_t PowerManager::updateWakeLockUids(const sp<IBinder>& lock,
+ int len,
+ const int* uids,
+ bool isOneWay) {
+ NOTIMPLEMENTED() << "updateWakeLockUids: lock=" << lock.get()
+ << " len=" << len;
+ return OK;
+}
+
+status_t PowerManager::powerHint(int hintId, int data) {
+ NOTIMPLEMENTED() << "powerHint: hintId=" << hintId << " data=" << data;
+ return OK;
+}
+
+bool PowerManager::AddWakeLockRequest(const sp<IBinder>& lock,
+ const String16& tag,
+ const String16& packageName,
+ int uid) {
+ return wake_lock_manager_->AddRequest(lock, String8(tag).string(),
+ String8(packageName).string(), uid);
+}
+
+} // namespace android
diff --git a/daemon/power_manager.h b/daemon/power_manager.h
new file mode 100644
index 0000000..98385b0
--- /dev/null
+++ b/daemon/power_manager.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015 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 SYSTEM_NATIVEPOWER_DAEMON_POWER_MANAGER_H_
+#define SYSTEM_NATIVEPOWER_DAEMON_POWER_MANAGER_H_
+
+#include <memory>
+
+#include <base/macros.h>
+#include <nativepower/BnPowerManager.h>
+
+#include "wake_lock_manager.h"
+
+namespace android {
+
+class PowerManager : public BnPowerManager {
+ public:
+ PowerManager();
+ ~PowerManager() override;
+
+ // Must be called before Init().
+ void set_wake_lock_manager_for_testing(
+ std::unique_ptr<WakeLockManagerInterface> manager) {
+ wake_lock_manager_ = std::move(manager);
+ }
+
+ // Initializes the object, returning true on success.
+ bool Init();
+
+ // BnPowerManager:
+ status_t acquireWakeLock(int flags,
+ const sp<IBinder>& lock,
+ const String16& tag,
+ const String16& packageName,
+ bool isOneWay=false) override;
+ status_t acquireWakeLockWithUid(int flags,
+ const sp<IBinder>& lock,
+ const String16& tag,
+ const String16& packageName,
+ int uid,
+ bool isOneWay=false) override;
+ status_t releaseWakeLock(const sp<IBinder>& lock,
+ int flags,
+ bool isOneWay=false) override;
+ status_t updateWakeLockUids(const sp<IBinder>& lock,
+ int len,
+ const int* uids,
+ bool isOneWay=false) override;
+ status_t powerHint(int hintId, int data) override;
+
+ private:
+ // Helper method for acquireWakeLock*(). Returns true on success.
+ bool AddWakeLockRequest(const sp<IBinder>& lock,
+ const String16& tag,
+ const String16& packageName,
+ int uid);
+
+ std::unique_ptr<WakeLockManagerInterface> wake_lock_manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(PowerManager);
+};
+
+} // namespace android
+
+#endif // SYSTEM_NATIVEPOWER_DAEMON_POWER_MANAGER_H_
diff --git a/daemon/power_manager_stub.cc b/daemon/power_manager_stub.cc
new file mode 100644
index 0000000..40490d3
--- /dev/null
+++ b/daemon/power_manager_stub.cc
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2015 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 <base/logging.h>
+#include <base/strings/stringprintf.h>
+#include <nativepower/power_manager_stub.h>
+#include <utils/String8.h>
+
+namespace android {
+
+PowerManagerStub::LockInfo::LockInfo() : uid(-1) {}
+
+PowerManagerStub::LockInfo::LockInfo(const LockInfo& info) = default;
+
+PowerManagerStub::LockInfo::LockInfo(const std::string& tag,
+ const std::string& package,
+ int uid)
+ : tag(tag),
+ package(package),
+ uid(uid) {}
+
+// static
+std::string PowerManagerStub::ConstructLockString(const std::string& tag,
+ const std::string& package,
+ int uid) {
+ return base::StringPrintf("%s,%s,%d", tag.c_str(), package.c_str(), uid);
+}
+
+PowerManagerStub::PowerManagerStub() = default;
+
+PowerManagerStub::~PowerManagerStub() = default;
+
+std::string PowerManagerStub::GetLockString(const sp<IBinder>& binder) const {
+ const auto it = locks_.find(binder);
+ if (it == locks_.end())
+ return std::string();
+
+ const LockInfo& info = it->second;
+ return ConstructLockString(info.tag, info.package, info.uid);
+}
+
+status_t PowerManagerStub::acquireWakeLock(int flags,
+ const sp<IBinder>& lock,
+ const String16& tag,
+ const String16& packageName,
+ bool isOneWay) {
+ CHECK(!locks_.count(lock)) << "Got acquireWakeLock() request for "
+ << "already-registered binder " << lock.get();
+ locks_[lock] =
+ LockInfo(String8(tag).string(), String8(packageName).string(), -1);
+ return OK;
+}
+
+status_t PowerManagerStub::acquireWakeLockWithUid(int flags,
+ const sp<IBinder>& lock,
+ const String16& tag,
+ const String16& packageName,
+ int uid,
+ bool isOneWay) {
+ CHECK(!locks_.count(lock)) << "Got acquireWakeLockWithUid() request for "
+ << "already-registered binder " << lock.get();
+ locks_[lock] =
+ LockInfo(String8(tag).string(), String8(packageName).string(), uid);
+ return OK;
+}
+
+status_t PowerManagerStub::releaseWakeLock(const sp<IBinder>& lock,
+ int flags,
+ bool isOneWay) {
+ CHECK(locks_.count(lock)) << "Got releaseWakeLock() request for unregistered "
+ << "binder " << lock.get();
+ locks_.erase(lock);
+ return OK;
+}
+
+status_t PowerManagerStub::updateWakeLockUids(const sp<IBinder>& lock,
+ int len,
+ const int* uids,
+ bool isOneWay) {
+ return OK;
+}
+
+status_t PowerManagerStub::powerHint(int hintId, int data) {
+ return OK;
+}
+
+} // namespace android
diff --git a/daemon/power_manager_unittest.cc b/daemon/power_manager_unittest.cc
new file mode 100644
index 0000000..45c5bc6
--- /dev/null
+++ b/daemon/power_manager_unittest.cc
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2015 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 <base/macros.h>
+#include <binder/IBinder.h>
+#include <binder/IInterface.h>
+#include <binderwrapper/binder_test_base.h>
+#include <binderwrapper/stub_binder_wrapper.h>
+#include <nativepower/constants.h>
+#include <powermanager/PowerManager.h>
+
+#include "power_manager.h"
+#include "wake_lock_manager.h"
+#include "wake_lock_manager_stub.h"
+
+namespace android {
+
+class PowerManagerTest : public BinderTestBase {
+ public:
+ PowerManagerTest()
+ : power_manager_(new PowerManager()),
+ wake_lock_manager_(new WakeLockManagerStub()) {
+ power_manager_->set_wake_lock_manager_for_testing(
+ std::unique_ptr<WakeLockManagerInterface>(wake_lock_manager_));
+ CHECK(power_manager_->Init());
+ }
+ ~PowerManagerTest() override = default;
+
+ protected:
+ sp<PowerManager> power_manager_;
+ WakeLockManagerStub* wake_lock_manager_; // Owned by |power_manager_|.
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PowerManagerTest);
+};
+
+TEST_F(PowerManagerTest, RegisterService) {
+ EXPECT_EQ(power_manager_,
+ binder_wrapper()->GetRegisteredService(kPowerManagerServiceName));
+}
+
+TEST_F(PowerManagerTest, AcquireAndReleaseWakeLock) {
+ sp<BBinder> binder = binder_wrapper()->CreateLocalBinder();
+ EXPECT_EQ(OK,
+ interface_cast<IPowerManager>(power_manager_)->acquireWakeLock(
+ 0, binder, String16(), String16()));
+ ASSERT_EQ(1u, wake_lock_manager_->request_binders().size());
+ EXPECT_TRUE(wake_lock_manager_->has_request_binder(binder));
+
+ EXPECT_EQ(OK,
+ interface_cast<IPowerManager>(power_manager_)->releaseWakeLock(
+ binder, 0));
+ EXPECT_TRUE(wake_lock_manager_->request_binders().empty());
+}
+
+} // namespace android
diff --git a/daemon/wake_lock_manager.cc b/daemon/wake_lock_manager.cc
new file mode 100644
index 0000000..3c875f6
--- /dev/null
+++ b/daemon/wake_lock_manager.cc
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2015 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 "wake_lock_manager.h"
+
+#include <base/bind.h>
+#include <base/files/file_util.h>
+#include <base/format_macros.h>
+#include <base/logging.h>
+#include <base/strings/stringprintf.h>
+#include <binder/IBinder.h>
+#include <binderwrapper/binder_wrapper.h>
+
+namespace android {
+namespace {
+
+// Paths to the sysfs lock and unlock files.
+const char kLockPath[] = "/sys/power/wake_lock";
+const char kUnlockPath[] = "/sys/power/wake_unlock";
+
+// Writes |data| to |path|, returning true on success or logging an error and
+// returning false otherwise.
+bool WriteToFile(const base::FilePath& path, const std::string& data) {
+ // This are sysfs "files" in real life, so it doesn't matter if we overwrite
+ // them or append to them, but appending makes it easier for tests to detect
+ // multiple writes when using real temporary files.
+ VLOG(1) << "Writing \"" << data << "\" to " << path.value();
+ if (!base::AppendToFile(path, data.data(), data.size())) {
+ PLOG(ERROR) << "Failed to write \"" << data << "\" to " << path.value();
+ return false;
+ }
+ return true;
+}
+
+} // namespace
+
+const char WakeLockManager::kLockName[] = "nativepowerman";
+
+WakeLockManager::Request::Request(const std::string& tag,
+ const std::string& package,
+ int uid)
+ : tag(tag),
+ package(package),
+ uid(uid) {}
+
+WakeLockManager::Request::Request(const Request& request) = default;
+
+WakeLockManager::Request::Request() : uid(0) {}
+
+WakeLockManager::WakeLockManager()
+ : lock_path_(kLockPath),
+ unlock_path_(kUnlockPath) {}
+
+WakeLockManager::~WakeLockManager() {
+ while (!requests_.empty())
+ RemoveRequest(requests_.begin()->first);
+}
+
+bool WakeLockManager::Init() {
+ if (!base::PathIsWritable(lock_path_) ||
+ !base::PathIsWritable(unlock_path_)) {
+ LOG(ERROR) << lock_path_.value() << " and/or " << unlock_path_.value()
+ << " are not writable";
+ return false;
+ }
+ return true;
+}
+
+bool WakeLockManager::AddRequest(sp<IBinder> client_binder,
+ const std::string& tag,
+ const std::string& package,
+ int uid) {
+ const bool new_request = !requests_.count(client_binder);
+ LOG(INFO) << (new_request ? "Adding" : "Updating") << " request for binder "
+ << client_binder.get() << ": tag=\"" << tag << "\""
+ << " package=\"" << package << "\" uid=" << uid;
+
+ const bool first_request = requests_.empty();
+
+ if (new_request) {
+ if (!BinderWrapper::Get()->RegisterForDeathNotifications(
+ client_binder,
+ base::Bind(&WakeLockManager::HandleBinderDeath,
+ base::Unretained(this), client_binder))) {
+ return false;
+ }
+ }
+ requests_[client_binder] = Request(tag, package, uid);
+
+ if (first_request && !WriteToFile(lock_path_, kLockName))
+ return false;
+
+ return true;
+}
+
+bool WakeLockManager::RemoveRequest(sp<IBinder> client_binder) {
+ LOG(INFO) << "Removing request for binder " << client_binder.get();
+
+ if (!requests_.erase(client_binder)) {
+ LOG(WARNING) << "Ignoring removal request for unknown binder "
+ << client_binder.get();
+ return false;
+ }
+ BinderWrapper::Get()->UnregisterForDeathNotifications(client_binder);
+
+ if (requests_.empty() && !WriteToFile(unlock_path_, kLockName))
+ return false;
+
+ return true;
+}
+
+void WakeLockManager::HandleBinderDeath(sp<IBinder> binder) {
+ LOG(INFO) << "Received death notification for binder " << binder.get();
+ RemoveRequest(binder);
+}
+
+} // namespace android
diff --git a/daemon/wake_lock_manager.h b/daemon/wake_lock_manager.h
new file mode 100644
index 0000000..471ad10
--- /dev/null
+++ b/daemon/wake_lock_manager.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2015 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 SYSTEM_NATIVEPOWER_DAEMON_WAKE_LOCK_MANAGER_H_
+#define SYSTEM_NATIVEPOWER_DAEMON_WAKE_LOCK_MANAGER_H_
+
+#include <map>
+#include <string>
+
+#include <base/files/file_path.h>
+#include <base/macros.h>
+#include <base/time/time.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+class IBinder;
+
+class WakeLockManagerInterface {
+ public:
+ WakeLockManagerInterface() {}
+ virtual ~WakeLockManagerInterface() {}
+
+ virtual bool AddRequest(sp<IBinder> client_binder,
+ const std::string& tag,
+ const std::string& package,
+ int uid) = 0;
+ virtual bool RemoveRequest(sp<IBinder> client_binder) = 0;
+};
+
+class WakeLockManager : public WakeLockManagerInterface {
+ public:
+ // Name of the kernel wake lock created by this class.
+ static const char kLockName[];
+
+ WakeLockManager();
+ ~WakeLockManager() override;
+
+ void set_paths_for_testing(const base::FilePath& lock_path,
+ const base::FilePath& unlock_path) {
+ lock_path_ = lock_path;
+ unlock_path_ = unlock_path;
+ }
+
+ bool Init();
+
+ // WakeLockManagerInterface:
+ bool AddRequest(sp<IBinder> client_binder,
+ const std::string& tag,
+ const std::string& package,
+ int uid) override;
+ bool RemoveRequest(sp<IBinder> client_binder) override;
+
+ private:
+ // Information about a request from a client.
+ struct Request {
+ Request(const std::string& tag, const std::string& package, int uid);
+ Request(const Request& request);
+ Request();
+
+ std::string tag;
+ std::string package;
+ int uid;
+ };
+
+ void HandleBinderDeath(sp<IBinder> binder);
+
+ base::FilePath lock_path_;
+ base::FilePath unlock_path_;
+
+ // Currently-active requests, keyed by client binders.
+ std::map<sp<IBinder>, Request> requests_;
+
+ DISALLOW_COPY_AND_ASSIGN(WakeLockManager);
+};
+
+} // namespace android
+
+#endif // SYSTEM_NATIVEPOWER_DAEMON_WAKE_LOCK_MANAGER_H_
diff --git a/daemon/wake_lock_manager_stub.cc b/daemon/wake_lock_manager_stub.cc
new file mode 100644
index 0000000..da7dc5e
--- /dev/null
+++ b/daemon/wake_lock_manager_stub.cc
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2015 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 "wake_lock_manager_stub.h"
+
+#include <binder/IBinder.h>
+
+namespace android {
+
+WakeLockManagerStub::WakeLockManagerStub() = default;
+
+WakeLockManagerStub::~WakeLockManagerStub() = default;
+
+bool WakeLockManagerStub::AddRequest(sp<IBinder> client_binder,
+ const std::string& tag,
+ const std::string& package,
+ int uid) {
+ request_binders_.insert(client_binder);
+ return true;
+}
+
+bool WakeLockManagerStub::RemoveRequest(sp<IBinder> client_binder) {
+ if (!request_binders_.count(client_binder))
+ return false;
+
+ request_binders_.erase(client_binder);
+ return true;
+}
+
+} // namespace android
diff --git a/daemon/wake_lock_manager_stub.h b/daemon/wake_lock_manager_stub.h
new file mode 100644
index 0000000..3b73749
--- /dev/null
+++ b/daemon/wake_lock_manager_stub.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 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 SYSTEM_NATIVEPOWER_DAEMON_WAKE_LOCK_MANAGER_STUB_H_
+#define SYSTEM_NATIVEPOWER_DAEMON_WAKE_LOCK_MANAGER_STUB_H_
+
+#include <set>
+#include <string>
+
+#include <base/macros.h>
+#include <utils/StrongPointer.h>
+
+#include "wake_lock_manager.h"
+
+namespace android {
+
+class IBinder;
+
+// Stub implementation used by tests.
+class WakeLockManagerStub : public WakeLockManagerInterface {
+ public:
+ using BinderSet = std::set<sp<IBinder>>;
+
+ WakeLockManagerStub();
+ ~WakeLockManagerStub() override;
+
+ const BinderSet& request_binders() const { return request_binders_; }
+ bool has_request_binder(const sp<IBinder>& binder) const {
+ return request_binders_.count(binder);
+ }
+
+ // WakeLockManagerInterface:
+ bool AddRequest(sp<IBinder> client_binder,
+ const std::string& tag,
+ const std::string& package,
+ int uid) override;
+ bool RemoveRequest(sp<IBinder> client_binder) override;
+
+ private:
+ // Binders passed to AddRequest() for currently-active requests.
+ BinderSet request_binders_;
+
+ DISALLOW_COPY_AND_ASSIGN(WakeLockManagerStub);
+};
+
+} // namespace android
+
+#endif // SYSTEM_NATIVEPOWER_DAEMON_WAKE_LOCK_MANAGER_STUB_H_
diff --git a/daemon/wake_lock_manager_unittest.cc b/daemon/wake_lock_manager_unittest.cc
new file mode 100644
index 0000000..887b564
--- /dev/null
+++ b/daemon/wake_lock_manager_unittest.cc
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2015 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 <base/files/file_path.h>
+#include <base/files/file_util.h>
+#include <base/files/scoped_temp_dir.h>
+#include <base/logging.h>
+#include <base/macros.h>
+#include <binder/IBinder.h>
+#include <binderwrapper/binder_test_base.h>
+#include <binderwrapper/stub_binder_wrapper.h>
+
+#include "wake_lock_manager.h"
+
+namespace android {
+
+class WakeLockManagerTest : public BinderTestBase {
+ public:
+ WakeLockManagerTest() {
+ CHECK(temp_dir_.CreateUniqueTempDir());
+ lock_path_ = temp_dir_.path().Append("lock");
+ unlock_path_ = temp_dir_.path().Append("unlock");
+ ClearFiles();
+
+ manager_.set_paths_for_testing(lock_path_, unlock_path_);
+ CHECK(manager_.Init());
+ }
+ ~WakeLockManagerTest() override = default;
+
+ protected:
+ // Returns the contents of |path|.
+ std::string ReadFile(const base::FilePath& path) const {
+ std::string value;
+ CHECK(base::ReadFileToString(path, &value));
+ return value;
+ }
+
+ // Clears |lock_path_| and |unlock_path_|.
+ void ClearFiles() {
+ CHECK(base::WriteFile(lock_path_, "", 0) == 0);
+ CHECK(base::WriteFile(unlock_path_, "", 0) == 0);
+ }
+
+ base::ScopedTempDir temp_dir_;
+
+ // Files within |temp_dir_| simulating /sys/power/wake_lock and wake_unlock.
+ base::FilePath lock_path_;
+ base::FilePath unlock_path_;
+
+ WakeLockManager manager_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(WakeLockManagerTest);
+};
+
+TEST_F(WakeLockManagerTest, AddAndRemoveRequests) {
+ // A kernel wake lock should be created for the first request.
+ sp<BBinder> binder1 = binder_wrapper()->CreateLocalBinder();
+ EXPECT_TRUE(manager_.AddRequest(binder1, "1", "1", -1));
+ EXPECT_EQ(WakeLockManager::kLockName, ReadFile(lock_path_));
+ EXPECT_EQ("", ReadFile(unlock_path_));
+
+ // Nothing should happen when a second request is made.
+ ClearFiles();
+ sp<BBinder> binder2 = binder_wrapper()->CreateLocalBinder();
+ EXPECT_TRUE(manager_.AddRequest(binder2, "2", "2", -1));
+ EXPECT_EQ("", ReadFile(lock_path_));
+ EXPECT_EQ("", ReadFile(unlock_path_));
+
+ // The wake lock should still be held after the first request is withdrawn.
+ ClearFiles();
+ EXPECT_TRUE(manager_.RemoveRequest(binder1));
+ EXPECT_EQ("", ReadFile(lock_path_));
+ EXPECT_EQ("", ReadFile(unlock_path_));
+
+ // When there are no more requests, the wake lock should be released.
+ ClearFiles();
+ EXPECT_TRUE(manager_.RemoveRequest(binder2));
+ EXPECT_EQ("", ReadFile(lock_path_));
+ EXPECT_EQ(WakeLockManager::kLockName, ReadFile(unlock_path_));
+}
+
+TEST_F(WakeLockManagerTest, DuplicateRequest) {
+ sp<BBinder> binder = binder_wrapper()->CreateLocalBinder();
+ EXPECT_TRUE(manager_.AddRequest(binder, "foo", "bar", -1));
+ EXPECT_EQ(WakeLockManager::kLockName, ReadFile(lock_path_));
+ EXPECT_EQ("", ReadFile(unlock_path_));
+
+ // Send a second request using the same binder and check a new wake lock isn't
+ // created.
+ ClearFiles();
+ EXPECT_TRUE(manager_.AddRequest(binder, "a", "b", -1));
+ EXPECT_EQ("", ReadFile(lock_path_));
+ EXPECT_EQ("", ReadFile(unlock_path_));
+
+ ClearFiles();
+ EXPECT_TRUE(manager_.RemoveRequest(binder));
+ EXPECT_EQ("", ReadFile(lock_path_));
+ EXPECT_EQ(WakeLockManager::kLockName, ReadFile(unlock_path_));
+}
+
+TEST_F(WakeLockManagerTest, InvalidRemoval) {
+ // Trying to remove an unknown binder should fail and not do anything.
+ sp<BBinder> binder = binder_wrapper()->CreateLocalBinder();
+ EXPECT_FALSE(manager_.RemoveRequest(binder));
+ EXPECT_EQ("", ReadFile(lock_path_));
+ EXPECT_EQ("", ReadFile(unlock_path_));
+}
+
+TEST_F(WakeLockManagerTest, BinderDeath) {
+ sp<BBinder> binder = binder_wrapper()->CreateLocalBinder();
+ EXPECT_TRUE(manager_.AddRequest(binder, "foo", "bar", -1));
+ EXPECT_EQ(WakeLockManager::kLockName, ReadFile(lock_path_));
+ EXPECT_EQ("", ReadFile(unlock_path_));
+
+ // If the binder dies, the wake lock should be released.
+ ClearFiles();
+ binder_wrapper()->NotifyAboutBinderDeath(binder);
+ EXPECT_EQ("", ReadFile(lock_path_));
+ EXPECT_EQ(WakeLockManager::kLockName, ReadFile(unlock_path_));
+
+ // Check that a new request can be created using the same binder.
+ ClearFiles();
+ EXPECT_TRUE(manager_.AddRequest(binder, "foo", "bar", -1));
+ EXPECT_EQ(WakeLockManager::kLockName, ReadFile(lock_path_));
+ EXPECT_EQ("", ReadFile(unlock_path_));
+}
+
+} // namespace android
diff --git a/example/Android.mk b/example/Android.mk
new file mode 100644
index 0000000..19936e5
--- /dev/null
+++ b/example/Android.mk
@@ -0,0 +1,39 @@
+#
+# Copyright (C) 2015 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+# power_example executable
+# ========================================================
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := power_example
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_CFLAGS := -Wall -Werror -Wno-unused-parameter
+LOCAL_CFLAGS += -Wno-sign-promo # for libchrome
+LOCAL_SHARED_LIBRARIES := \
+ libbinder \
+ libbinderwrapper \
+ libchrome \
+ libchromeos \
+ libnativepower \
+ libpowermanager \
+ libutils \
+
+LOCAL_SRC_FILES := \
+ power_example.cc \
+
+include $(BUILD_EXECUTABLE)
diff --git a/example/power_example.cc b/example/power_example.cc
new file mode 100644
index 0000000..0ad9138
--- /dev/null
+++ b/example/power_example.cc
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2015 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 <unistd.h>
+
+#include <memory>
+
+#include <base/at_exit.h>
+#include <base/logging.h>
+#include <base/message_loop/message_loop.h>
+#include <binderwrapper/binder_wrapper.h>
+#include <chromeos/flag_helper.h>
+#include <nativepower/wake_lock.h>
+
+using android::BinderWrapper;
+using android::WakeLock;
+
+int main(int argc, char *argv[]) {
+ DEFINE_int32(sleep_sec, 5, "Number of seconds to sleep");
+
+ chromeos::FlagHelper::Init(argc, argv, "Example power-management client.");
+ logging::InitLogging(logging::LoggingSettings());
+ base::AtExitManager at_exit;
+ base::MessageLoopForIO loop;
+ BinderWrapper::Create();
+
+ LOG(INFO) << "Creating wake lock";
+ std::unique_ptr<WakeLock> lock(WakeLock::Create("power_example", "power"));
+
+ LOG(INFO) << "Sleeping for " << FLAGS_sleep_sec << " seconds";
+ sleep(FLAGS_sleep_sec);
+
+ LOG(INFO) << "Exiting";
+ return 0;
+}
diff --git a/include/nativepower/BnPowerManager.h b/include/nativepower/BnPowerManager.h
new file mode 100644
index 0000000..db14ef3
--- /dev/null
+++ b/include/nativepower/BnPowerManager.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 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 SYSTEM_NATIVEPOWER_INCLUDE_NATIVEPOWER_BN_POWER_MANAGER_H_
+#define SYSTEM_NATIVEPOWER_INCLUDE_NATIVEPOWER_BN_POWER_MANAGER_H_
+
+#include <binder/IInterface.h>
+#include <powermanager/IPowerManager.h>
+
+namespace android {
+
+// Receiver-side binder implementation.
+class BnPowerManager : public BnInterface<IPowerManager> {
+public:
+ // BnInterface:
+ status_t onTransact(uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags=0) override;
+};
+
+} // namespace android
+
+#endif // SYSTEM_NATIVEPOWER_INCLUDE_NATIVEPOWER_BN_POWER_MANAGER_H_
diff --git a/include/nativepower/constants.h b/include/nativepower/constants.h
new file mode 100644
index 0000000..ddeb3d7
--- /dev/null
+++ b/include/nativepower/constants.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2015 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 SYSTEM_NATIVEPOWER_INCLUDE_NATIVEPOWER_CONSTANTS_H_
+#define SYSTEM_NATIVEPOWER_INCLUDE_NATIVEPOWER_CONSTANTS_H_
+
+namespace android {
+
+// Name used to register the power manager with the service manager.
+const char kPowerManagerServiceName[] = "power";
+
+} // namespace android
+
+#endif // SYSTEM_NATIVEPOWER_INCLUDE_NATIVEPOWER_CONSTANTS_H_
diff --git a/include/nativepower/power_manager_stub.h b/include/nativepower/power_manager_stub.h
new file mode 100644
index 0000000..ab303c2
--- /dev/null
+++ b/include/nativepower/power_manager_stub.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2015 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 <map>
+#include <string>
+
+#include <base/macros.h>
+#include <nativepower/BnPowerManager.h>
+
+namespace android {
+
+// Stub implementation of BnPowerManager for use in tests.
+class PowerManagerStub : public BnPowerManager {
+ public:
+ PowerManagerStub();
+ ~PowerManagerStub() override;
+
+ // Constructs a string that can be compared with one returned by
+ // GetLockString().
+ static std::string ConstructLockString(const std::string& tag,
+ const std::string& package,
+ int uid);
+
+ size_t num_locks() const { return locks_.size(); }
+
+ // Returns a string describing the lock registered for |binder|, or an empty
+ // string if no lock is present.
+ std::string GetLockString(const sp<IBinder>& binder) const;
+
+ // BnPowerManager:
+ status_t acquireWakeLock(int flags,
+ const sp<IBinder>& lock,
+ const String16& tag,
+ const String16& packageName,
+ bool isOneWay=false) override;
+ status_t acquireWakeLockWithUid(int flags,
+ const sp<IBinder>& lock,
+ const String16& tag,
+ const String16& packageName,
+ int uid,
+ bool isOneWay=false) override;
+ status_t releaseWakeLock(const sp<IBinder>& lock,
+ int flags,
+ bool isOneWay=false) override;
+ status_t updateWakeLockUids(const sp<IBinder>& lock,
+ int len,
+ const int* uids,
+ bool isOneWay=false) override;
+ status_t powerHint(int hintId, int data) override;
+
+ private:
+ // Contains information passed to acquireWakeLock() or
+ // acquireWakeLockWithUid().
+ struct LockInfo {
+ LockInfo();
+ LockInfo(const LockInfo& info);
+ LockInfo(const std::string& tag,
+ const std::string& package,
+ int uid);
+
+ std::string tag;
+ std::string package;
+
+ // -1 if acquireWakeLock() was used.
+ int uid;
+ };
+
+ using LockInfoMap = std::map<sp<IBinder>, LockInfo>;
+ LockInfoMap locks_;
+
+ DISALLOW_COPY_AND_ASSIGN(PowerManagerStub);
+};
+
+} // namespace android
diff --git a/include/nativepower/wake_lock.h b/include/nativepower/wake_lock.h
new file mode 100644
index 0000000..6fc0782
--- /dev/null
+++ b/include/nativepower/wake_lock.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2015 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 SYSTEM_NATIVEPOWER_INCLUDE_NATIVEPOWER_WAKE_LOCK_H_
+#define SYSTEM_NATIVEPOWER_INCLUDE_NATIVEPOWER_WAKE_LOCK_H_
+
+#include <memory>
+#include <string>
+
+#include <base/macros.h>
+#include <powermanager/IPowerManager.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+class IBinder;
+
+// RAII-style object that prevents the system from suspending.
+//
+// android::BinderWrapper must be initialized before constructing this class.
+class WakeLock {
+ public:
+ // Creates and returns a wake lock identified by |tag| and |package|.
+ // An empty pointer is returned on failure (e.g. due to issues communicating
+ // with the power manager).
+ static std::unique_ptr<WakeLock> Create(const std::string& tag,
+ const std::string& package);
+
+ ~WakeLock();
+
+ private:
+ // Called by Create().
+ WakeLock(const std::string& tag, const std::string& package);
+
+ // Initializes the object and returns true on success. Called by Create().
+ bool Init();
+
+ // Called by |death_recipient_| in response to |power_manager_| dying.
+ void OnPowerManagerDied();
+
+ std::string tag_;
+ std::string package_;
+
+ // Interface for communicating with the power manager.
+ sp<IPowerManager> power_manager_;
+
+ // Locally-created binder passed to the power manager.
+ sp<IBinder> lock_binder_;
+
+ DISALLOW_COPY_AND_ASSIGN(WakeLock);
+};
+
+} // namespace android
+
+#endif // SYSTEM_NATIVEPOWER_INCLUDE_NATIVEPOWER_WAKE_LOCK_H_