1// 2// Copyright (C) 2012 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 "shill/power_manager.h" 18 19#include <memory> 20#include <string> 21 22#include <base/bind.h> 23#if defined(__ANDROID__) 24#include <dbus/service_constants.h> 25#else 26#include <chromeos/dbus/service_constants.h> 27#endif // __ANDROID__ 28#include <gmock/gmock.h> 29#include <gtest/gtest.h> 30 31#include "shill/mock_control.h" 32#include "shill/mock_event_dispatcher.h" 33#include "shill/mock_metrics.h" 34#include "shill/mock_power_manager_proxy.h" 35#include "shill/power_manager_proxy_interface.h" 36 37using base::Bind; 38using base::Unretained; 39using std::map; 40using std::string; 41using testing::_; 42using testing::DoAll; 43using testing::IgnoreResult; 44using testing::InvokeWithoutArgs; 45using testing::Mock; 46using testing::Return; 47using testing::SetArgumentPointee; 48using testing::Test; 49 50namespace shill { 51 52namespace { 53 54class FakeControl : public MockControl { 55 public: 56 FakeControl() 57 : delegate_(nullptr), 58 power_manager_proxy_raw_(new MockPowerManagerProxy), 59 power_manager_proxy_(power_manager_proxy_raw_) {} 60 61 virtual PowerManagerProxyInterface* CreatePowerManagerProxy( 62 PowerManagerProxyDelegate* delegate, 63 const base::Closure& service_appeared_callback, 64 const base::Closure& service_vanished_callback) { 65 CHECK(power_manager_proxy_); 66 delegate_ = delegate; 67 // Passes ownership. 68 return power_manager_proxy_.release(); 69 } 70 71 PowerManagerProxyDelegate* delegate() const { return delegate_; } 72 // Can not guarantee that the returned object is alive. 73 MockPowerManagerProxy* power_manager_proxy() const { 74 return power_manager_proxy_raw_; 75 } 76 77 private: 78 PowerManagerProxyDelegate* delegate_; 79 MockPowerManagerProxy* const power_manager_proxy_raw_; 80 std::unique_ptr<MockPowerManagerProxy> power_manager_proxy_; 81}; 82 83} // namespace 84 85class PowerManagerTest : public Test { 86 public: 87 static const char kDescription[]; 88 static const char kDarkDescription[]; 89 static const char kPowerManagerDefaultOwner[]; 90 static const int kSuspendId1 = 123; 91 static const int kSuspendId2 = 456; 92 static const int kDelayId = 4; 93 static const int kDelayId2 = 5; 94 95 PowerManagerTest() 96 : kTimeout(base::TimeDelta::FromSeconds(3)), 97 power_manager_(&dispatcher_, &control_), 98 power_manager_proxy_(control_.power_manager_proxy()), 99 delegate_(control_.delegate()) { 100 suspend_imminent_callback_ = 101 Bind(&PowerManagerTest::SuspendImminentAction, Unretained(this)); 102 suspend_done_callback_ = 103 Bind(&PowerManagerTest::SuspendDoneAction, Unretained(this)); 104 dark_suspend_imminent_callback_ = 105 Bind(&PowerManagerTest::DarkSuspendImminentAction, Unretained(this)); 106 } 107 108 MOCK_METHOD0(SuspendImminentAction, void()); 109 MOCK_METHOD0(SuspendDoneAction, void()); 110 MOCK_METHOD0(DarkSuspendImminentAction, void()); 111 112 protected: 113 virtual void SetUp() { 114 power_manager_.Start(kTimeout, suspend_imminent_callback_, 115 suspend_done_callback_, 116 dark_suspend_imminent_callback_); 117 } 118 119 virtual void TearDown() { 120 power_manager_.Stop(); 121 } 122 123 void AddProxyExpectationForRegisterSuspendDelay(int delay_id, 124 bool return_value) { 125 EXPECT_CALL(*power_manager_proxy_, 126 RegisterSuspendDelay(kTimeout, kDescription, _)) 127 .WillOnce(DoAll(SetArgumentPointee<2>(delay_id), Return(return_value))); 128 } 129 130 void AddProxyExpectationForUnregisterSuspendDelay(int delay_id, 131 bool return_value) { 132 EXPECT_CALL(*power_manager_proxy_, UnregisterSuspendDelay(delay_id)) 133 .WillOnce(Return(return_value)); 134 } 135 136 void AddProxyExpectationForReportSuspendReadiness(int delay_id, 137 int suspend_id, 138 bool return_value) { 139 EXPECT_CALL(*power_manager_proxy_, 140 ReportSuspendReadiness(delay_id, suspend_id)) 141 .WillOnce(Return(return_value)); 142 } 143 144 void AddProxyExpectationForRecordDarkResumeWakeReason( 145 const string& wake_reason, bool return_value) { 146 EXPECT_CALL(*power_manager_proxy_, RecordDarkResumeWakeReason(wake_reason)) 147 .WillOnce(Return(return_value)); 148 } 149 150 void AddProxyExpectationForRegisterDarkSuspendDelay(int delay_id, 151 bool return_value) { 152 EXPECT_CALL(*power_manager_proxy_, 153 RegisterDarkSuspendDelay(kTimeout, kDarkDescription, _)) 154 .WillOnce(DoAll(SetArgumentPointee<2>(delay_id), Return(return_value))); 155 } 156 157 void AddProxyExpectationForReportDarkSuspendReadiness(int delay_id, 158 int suspend_id, 159 bool return_value) { 160 EXPECT_CALL(*power_manager_proxy_, 161 ReportDarkSuspendReadiness(delay_id, suspend_id)) 162 .WillOnce(Return(return_value)); 163 } 164 165 void AddProxyExpectationForUnregisterDarkSuspendDelay(int delay_id, 166 bool return_value) { 167 EXPECT_CALL(*power_manager_proxy_, UnregisterDarkSuspendDelay(delay_id)) 168 .WillOnce(Return(return_value)); 169 } 170 171 void RegisterSuspendDelays() { 172 AddProxyExpectationForRegisterSuspendDelay(kDelayId, true); 173 AddProxyExpectationForRegisterDarkSuspendDelay(kDelayId, true); 174 OnPowerManagerAppeared(); 175 Mock::VerifyAndClearExpectations(power_manager_proxy_); 176 } 177 178 void OnSuspendImminent(int suspend_id) { 179 control_.delegate()->OnSuspendImminent(suspend_id); 180 EXPECT_TRUE(power_manager_.suspending()); 181 } 182 183 void OnSuspendDone(int suspend_id) { 184 control_.delegate()->OnSuspendDone(suspend_id); 185 EXPECT_FALSE(power_manager_.suspending()); 186 } 187 188 void OnDarkSuspendImminent(int suspend_id) { 189 control_.delegate()->OnDarkSuspendImminent(suspend_id); 190 } 191 192 void OnPowerManagerAppeared() { 193 power_manager_.OnPowerManagerAppeared(); 194 } 195 196 void OnPowerManagerVanished() { 197 power_manager_.OnPowerManagerVanished(); 198 } 199 200 // This is non-static since it's a non-POD type. 201 const base::TimeDelta kTimeout; 202 203 MockEventDispatcher dispatcher_; 204 FakeControl control_; 205 PowerManager power_manager_; 206 MockPowerManagerProxy* const power_manager_proxy_; 207 PowerManagerProxyDelegate* const delegate_; 208 PowerManager::SuspendImminentCallback suspend_imminent_callback_; 209 PowerManager::SuspendDoneCallback suspend_done_callback_; 210 PowerManager::DarkSuspendImminentCallback dark_suspend_imminent_callback_; 211}; 212 213const char PowerManagerTest::kDescription[] = "shill"; 214const char PowerManagerTest::kDarkDescription[] = "shill"; 215const char PowerManagerTest::kPowerManagerDefaultOwner[] = 216 "PowerManagerDefaultOwner"; 217 218TEST_F(PowerManagerTest, SuspendingState) { 219 const int kSuspendId = 3; 220 EXPECT_FALSE(power_manager_.suspending()); 221 OnSuspendImminent(kSuspendId); 222 EXPECT_TRUE(power_manager_.suspending()); 223 OnSuspendDone(kSuspendId); 224 EXPECT_FALSE(power_manager_.suspending()); 225} 226 227TEST_F(PowerManagerTest, RegisterSuspendDelayFailure) { 228 AddProxyExpectationForRegisterSuspendDelay(kDelayId, false); 229 OnPowerManagerAppeared(); 230 Mock::VerifyAndClearExpectations(power_manager_proxy_); 231 232 // Outstanding shill callbacks should still be invoked. 233 // - suspend_done_callback: If powerd died in the middle of a suspend 234 // we want to wake shill up with suspend_done_action, so this callback 235 // should be invoked anyway. 236 // See PowerManagerTest::PowerManagerDiedInSuspend and 237 // PowerManagerTest::PowerManagerReappearedInSuspend. 238 EXPECT_CALL(*this, SuspendDoneAction()); 239 // - suspend_imminent_callback: The only case this can happen is if this 240 // callback was put on the queue, and then powerd reappeared, but we failed 241 // to registered a suspend delay with it. 242 // It is safe to go through the suspend_imminent -> timeout -> suspend_done 243 // path in this black swan case. 244 EXPECT_CALL(*this, SuspendImminentAction()); 245 OnSuspendImminent(kSuspendId1); 246 OnSuspendDone(kSuspendId1); 247 Mock::VerifyAndClearExpectations(this); 248} 249 250TEST_F(PowerManagerTest, RegisterDarkSuspendDelayFailure) { 251 AddProxyExpectationForRegisterDarkSuspendDelay(kDelayId, false); 252 OnPowerManagerAppeared(); 253 Mock::VerifyAndClearExpectations(power_manager_proxy_); 254 255 // Outstanding dark suspend imminent signal should be ignored, since we 256 // probably won't have time to cleanly do dark resume actions. Might as well 257 // ignore the signal. 258 EXPECT_CALL(*this, DarkSuspendImminentAction()).Times(0); 259 OnDarkSuspendImminent(kSuspendId1); 260} 261 262TEST_F(PowerManagerTest, ReportSuspendReadinessFailure) { 263 RegisterSuspendDelays(); 264 EXPECT_CALL(*this, SuspendImminentAction()); 265 OnSuspendImminent(kSuspendId1); 266 AddProxyExpectationForReportSuspendReadiness(kDelayId, kSuspendId1, false); 267 EXPECT_FALSE(power_manager_.ReportSuspendReadiness()); 268} 269 270TEST_F(PowerManagerTest, RecordDarkResumeWakeReasonFailure) { 271 const string kWakeReason = "WiFi.Disconnect"; 272 RegisterSuspendDelays(); 273 EXPECT_CALL(*this, DarkSuspendImminentAction()); 274 OnDarkSuspendImminent(kSuspendId1); 275 AddProxyExpectationForRecordDarkResumeWakeReason(kWakeReason, false); 276 EXPECT_FALSE(power_manager_.RecordDarkResumeWakeReason(kWakeReason)); 277} 278 279TEST_F(PowerManagerTest, RecordDarkResumeWakeReasonSuccess) { 280 const string kWakeReason = "WiFi.Disconnect"; 281 RegisterSuspendDelays(); 282 EXPECT_CALL(*this, DarkSuspendImminentAction()); 283 OnDarkSuspendImminent(kSuspendId1); 284 AddProxyExpectationForRecordDarkResumeWakeReason(kWakeReason, true); 285 EXPECT_TRUE(power_manager_.RecordDarkResumeWakeReason(kWakeReason)); 286} 287 288TEST_F(PowerManagerTest, ReportDarkSuspendReadinessFailure) { 289 RegisterSuspendDelays(); 290 EXPECT_CALL(*this, DarkSuspendImminentAction()); 291 OnDarkSuspendImminent(kSuspendId1); 292 AddProxyExpectationForReportDarkSuspendReadiness(kDelayId, kSuspendId1, 293 false); 294 EXPECT_FALSE(power_manager_.ReportDarkSuspendReadiness()); 295} 296 297TEST_F(PowerManagerTest, ReportSuspendReadinessFailsOutsideSuspend) { 298 RegisterSuspendDelays(); 299 EXPECT_CALL(*power_manager_proxy_, ReportSuspendReadiness(_, _)).Times(0); 300 EXPECT_FALSE(power_manager_.ReportSuspendReadiness()); 301} 302 303TEST_F(PowerManagerTest, ReportSuspendReadinessSynchronous) { 304 // Verifies that a synchronous ReportSuspendReadiness call by shill on a 305 // SuspendImminent callback is routed back to powerd. 306 RegisterSuspendDelays(); 307 EXPECT_CALL(*power_manager_proxy_, ReportSuspendReadiness(_, _)) 308 .WillOnce(Return(true)); 309 EXPECT_CALL(*this, SuspendImminentAction()) 310 .WillOnce(IgnoreResult(InvokeWithoutArgs( 311 &power_manager_, &PowerManager::ReportSuspendReadiness))); 312 OnSuspendImminent(kSuspendId1); 313} 314 315TEST_F(PowerManagerTest, ReportDarkSuspendReadinessSynchronous) { 316 // Verifies that a synchronous ReportDarkSuspendReadiness call by shill on a 317 // DarkSuspendImminent callback is routed back to powerd. 318 RegisterSuspendDelays(); 319 EXPECT_CALL(*power_manager_proxy_, ReportDarkSuspendReadiness(_, _)) 320 .WillOnce(Return(true)); 321 EXPECT_CALL(*this, DarkSuspendImminentAction()) 322 .WillOnce(IgnoreResult(InvokeWithoutArgs( 323 &power_manager_, &PowerManager::ReportDarkSuspendReadiness))); 324 OnDarkSuspendImminent(kSuspendId1); 325} 326 327TEST_F(PowerManagerTest, Stop) { 328 RegisterSuspendDelays(); 329 AddProxyExpectationForUnregisterSuspendDelay(kDelayId, true); 330 AddProxyExpectationForUnregisterDarkSuspendDelay(kDelayId, true); 331 power_manager_.Stop(); 332} 333 334TEST_F(PowerManagerTest, StopFailure) { 335 RegisterSuspendDelays(); 336 337 AddProxyExpectationForUnregisterSuspendDelay(kDelayId, false); 338 power_manager_.Stop(); 339 Mock::VerifyAndClearExpectations(power_manager_proxy_); 340 341 // As a result, callbacks should still be invoked. 342 EXPECT_CALL(*this, SuspendImminentAction()); 343 EXPECT_CALL(*this, SuspendDoneAction()); 344 OnSuspendImminent(kSuspendId1); 345 OnSuspendDone(kSuspendId1); 346} 347 348TEST_F(PowerManagerTest, OnPowerManagerReappeared) { 349 RegisterSuspendDelays(); 350 351 // Check that we re-register suspend delay on powerd restart. 352 AddProxyExpectationForRegisterSuspendDelay(kDelayId2, true); 353 AddProxyExpectationForRegisterDarkSuspendDelay(kDelayId2, true); 354 OnPowerManagerVanished(); 355 OnPowerManagerAppeared(); 356 Mock::VerifyAndClearExpectations(power_manager_proxy_); 357 358 // Check that a |ReportSuspendReadiness| message is sent with the new delay 359 // id. 360 EXPECT_CALL(*this, SuspendImminentAction()); 361 OnSuspendImminent(kSuspendId1); 362 AddProxyExpectationForReportSuspendReadiness(kDelayId2, kSuspendId1, true); 363 EXPECT_TRUE(power_manager_.ReportSuspendReadiness()); 364 Mock::VerifyAndClearExpectations(power_manager_proxy_); 365 366 // Check that a |ReportDarkSuspendReadiness| message is sent with the new 367 // delay id. 368 EXPECT_CALL(*this, DarkSuspendImminentAction()); 369 OnDarkSuspendImminent(kSuspendId1); 370 AddProxyExpectationForReportDarkSuspendReadiness(kDelayId2, kSuspendId1, 371 true); 372 EXPECT_TRUE(power_manager_.ReportDarkSuspendReadiness()); 373} 374 375TEST_F(PowerManagerTest, PowerManagerDiedInSuspend) { 376 RegisterSuspendDelays(); 377 EXPECT_CALL(*this, SuspendImminentAction()); 378 OnSuspendImminent(kSuspendId1); 379 Mock::VerifyAndClearExpectations(this); 380 381 EXPECT_CALL(*this, SuspendDoneAction()); 382 OnPowerManagerVanished(); 383 EXPECT_FALSE(power_manager_.suspending()); 384} 385 386TEST_F(PowerManagerTest, PowerManagerReappearedInSuspend) { 387 RegisterSuspendDelays(); 388 EXPECT_CALL(*this, SuspendImminentAction()); 389 OnSuspendImminent(kSuspendId1); 390 Mock::VerifyAndClearExpectations(this); 391 392 AddProxyExpectationForRegisterSuspendDelay(kDelayId2, true); 393 AddProxyExpectationForRegisterDarkSuspendDelay(kDelayId2, true); 394 EXPECT_CALL(*this, SuspendDoneAction()); 395 OnPowerManagerVanished(); 396 OnPowerManagerAppeared(); 397 EXPECT_FALSE(power_manager_.suspending()); 398 Mock::VerifyAndClearExpectations(this); 399 400 // Let's check a normal suspend request after the fact. 401 EXPECT_CALL(*this, SuspendImminentAction()); 402 OnSuspendImminent(kSuspendId2); 403} 404 405} // namespace shill 406