1 /*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <base/files/file_path.h>
18 #include <base/files/file_util.h>
19 #include <base/files/scoped_temp_dir.h>
20 #include <base/logging.h>
21 #include <base/macros.h>
22 #include <binder/IBinder.h>
23 #include <binderwrapper/binder_test_base.h>
24 #include <binderwrapper/stub_binder_wrapper.h>
25
26 #include "wake_lock_manager.h"
27
28 namespace android {
29
30 class WakeLockManagerTest : public BinderTestBase {
31 public:
WakeLockManagerTest()32 WakeLockManagerTest() {
33 CHECK(temp_dir_.CreateUniqueTempDir());
34 lock_path_ = temp_dir_.path().Append("lock");
35 unlock_path_ = temp_dir_.path().Append("unlock");
36 ClearFiles();
37
38 manager_.set_paths_for_testing(lock_path_, unlock_path_);
39 CHECK(manager_.Init());
40 }
41 ~WakeLockManagerTest() override = default;
42
43 protected:
44 // Returns the contents of |path|.
ReadFile(const base::FilePath & path) const45 std::string ReadFile(const base::FilePath& path) const {
46 std::string value;
47 CHECK(base::ReadFileToString(path, &value));
48 return value;
49 }
50
51 // Clears |lock_path_| and |unlock_path_|.
ClearFiles()52 void ClearFiles() {
53 CHECK(base::WriteFile(lock_path_, "", 0) == 0);
54 CHECK(base::WriteFile(unlock_path_, "", 0) == 0);
55 }
56
57 base::ScopedTempDir temp_dir_;
58
59 // Files within |temp_dir_| simulating /sys/power/wake_lock and wake_unlock.
60 base::FilePath lock_path_;
61 base::FilePath unlock_path_;
62
63 WakeLockManager manager_;
64
65 private:
66 DISALLOW_COPY_AND_ASSIGN(WakeLockManagerTest);
67 };
68
TEST_F(WakeLockManagerTest,AddAndRemoveRequests)69 TEST_F(WakeLockManagerTest, AddAndRemoveRequests) {
70 // A kernel wake lock should be created for the first request.
71 sp<BBinder> binder1 = binder_wrapper()->CreateLocalBinder();
72 EXPECT_TRUE(manager_.AddRequest(binder1, "1", "1", -1));
73 EXPECT_EQ(WakeLockManager::kLockName, ReadFile(lock_path_));
74 EXPECT_EQ("", ReadFile(unlock_path_));
75
76 // Nothing should happen when a second request is made.
77 ClearFiles();
78 sp<BBinder> binder2 = binder_wrapper()->CreateLocalBinder();
79 EXPECT_TRUE(manager_.AddRequest(binder2, "2", "2", -1));
80 EXPECT_EQ("", ReadFile(lock_path_));
81 EXPECT_EQ("", ReadFile(unlock_path_));
82
83 // The wake lock should still be held after the first request is withdrawn.
84 ClearFiles();
85 EXPECT_TRUE(manager_.RemoveRequest(binder1));
86 EXPECT_EQ("", ReadFile(lock_path_));
87 EXPECT_EQ("", ReadFile(unlock_path_));
88
89 // When there are no more requests, the wake lock should be released.
90 ClearFiles();
91 EXPECT_TRUE(manager_.RemoveRequest(binder2));
92 EXPECT_EQ("", ReadFile(lock_path_));
93 EXPECT_EQ(WakeLockManager::kLockName, ReadFile(unlock_path_));
94 }
95
TEST_F(WakeLockManagerTest,DuplicateRequest)96 TEST_F(WakeLockManagerTest, DuplicateRequest) {
97 sp<BBinder> binder = binder_wrapper()->CreateLocalBinder();
98 EXPECT_TRUE(manager_.AddRequest(binder, "foo", "bar", -1));
99 EXPECT_EQ(WakeLockManager::kLockName, ReadFile(lock_path_));
100 EXPECT_EQ("", ReadFile(unlock_path_));
101
102 // Send a second request using the same binder and check a new wake lock isn't
103 // created.
104 ClearFiles();
105 EXPECT_TRUE(manager_.AddRequest(binder, "a", "b", -1));
106 EXPECT_EQ("", ReadFile(lock_path_));
107 EXPECT_EQ("", ReadFile(unlock_path_));
108
109 ClearFiles();
110 EXPECT_TRUE(manager_.RemoveRequest(binder));
111 EXPECT_EQ("", ReadFile(lock_path_));
112 EXPECT_EQ(WakeLockManager::kLockName, ReadFile(unlock_path_));
113 }
114
TEST_F(WakeLockManagerTest,InvalidRemoval)115 TEST_F(WakeLockManagerTest, InvalidRemoval) {
116 // Trying to remove an unknown binder should fail and not do anything.
117 sp<BBinder> binder = binder_wrapper()->CreateLocalBinder();
118 EXPECT_FALSE(manager_.RemoveRequest(binder));
119 EXPECT_EQ("", ReadFile(lock_path_));
120 EXPECT_EQ("", ReadFile(unlock_path_));
121 }
122
TEST_F(WakeLockManagerTest,BinderDeath)123 TEST_F(WakeLockManagerTest, BinderDeath) {
124 sp<BBinder> binder = binder_wrapper()->CreateLocalBinder();
125 EXPECT_TRUE(manager_.AddRequest(binder, "foo", "bar", -1));
126 EXPECT_EQ(WakeLockManager::kLockName, ReadFile(lock_path_));
127 EXPECT_EQ("", ReadFile(unlock_path_));
128
129 // If the binder dies, the wake lock should be released.
130 ClearFiles();
131 binder_wrapper()->NotifyAboutBinderDeath(binder);
132 EXPECT_EQ("", ReadFile(lock_path_));
133 EXPECT_EQ(WakeLockManager::kLockName, ReadFile(unlock_path_));
134
135 // Check that a new request can be created using the same binder.
136 ClearFiles();
137 EXPECT_TRUE(manager_.AddRequest(binder, "foo", "bar", -1));
138 EXPECT_EQ(WakeLockManager::kLockName, ReadFile(lock_path_));
139 EXPECT_EQ("", ReadFile(unlock_path_));
140 }
141
142 } // namespace android
143