| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chromeos/dbus/power_manager_client.h" | 5 #include "chromeos/dbus/power_manager_client.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 using ::testing::Return; | 25 using ::testing::Return; |
| 26 using ::testing::SaveArg; | 26 using ::testing::SaveArg; |
| 27 | 27 |
| 28 namespace chromeos { | 28 namespace chromeos { |
| 29 | 29 |
| 30 namespace { | 30 namespace { |
| 31 | 31 |
| 32 // Shorthand for a few commonly-used constants. | 32 // Shorthand for a few commonly-used constants. |
| 33 const char* kInterface = power_manager::kPowerManagerInterface; | 33 const char* kInterface = power_manager::kPowerManagerInterface; |
| 34 const char* kSuspendImminent = power_manager::kSuspendImminentSignal; | 34 const char* kSuspendImminent = power_manager::kSuspendImminentSignal; |
| 35 const char* kDarkSuspendImminent = power_manager::kDarkSuspendImminentSignal; |
| 35 const char* kHandleSuspendReadiness = | 36 const char* kHandleSuspendReadiness = |
| 36 power_manager::kHandleSuspendReadinessMethod; | 37 power_manager::kHandleSuspendReadinessMethod; |
| 38 const char* kHandleDarkSuspendReadiness = |
| 39 power_manager::kHandleDarkSuspendReadinessMethod; |
| 37 | 40 |
| 38 // Matcher that verifies that a dbus::Message has member |name|. | 41 // Matcher that verifies that a dbus::Message has member |name|. |
| 39 MATCHER_P(HasMember, name, "") { | 42 MATCHER_P(HasMember, name, "") { |
| 40 if (arg->GetMember() != name) { | 43 if (arg->GetMember() != name) { |
| 41 *result_listener << "has member " << arg->GetMember(); | 44 *result_listener << "has member " << arg->GetMember(); |
| 42 return false; | 45 return false; |
| 43 } | 46 } |
| 44 return true; | 47 return true; |
| 45 } | 48 } |
| 46 | 49 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 // Stub implementation of PowerManagerClient::Observer. | 81 // Stub implementation of PowerManagerClient::Observer. |
| 79 class TestObserver : public PowerManagerClient::Observer { | 82 class TestObserver : public PowerManagerClient::Observer { |
| 80 public: | 83 public: |
| 81 explicit TestObserver(PowerManagerClient* client) : client_(client) { | 84 explicit TestObserver(PowerManagerClient* client) : client_(client) { |
| 82 client_->AddObserver(this); | 85 client_->AddObserver(this); |
| 83 } | 86 } |
| 84 ~TestObserver() override { client_->RemoveObserver(this); } | 87 ~TestObserver() override { client_->RemoveObserver(this); } |
| 85 | 88 |
| 86 int num_suspend_imminent() const { return num_suspend_imminent_; } | 89 int num_suspend_imminent() const { return num_suspend_imminent_; } |
| 87 int num_suspend_done() const { return num_suspend_done_; } | 90 int num_suspend_done() const { return num_suspend_done_; } |
| 91 int num_dark_suspend_imminent() const { return num_dark_suspend_imminent_; } |
| 92 base::Closure suspend_readiness_callback() const { |
| 93 return suspend_readiness_callback_; |
| 94 } |
| 88 | 95 |
| 89 void set_take_suspend_readiness_callback(bool take_callback) { | 96 void set_take_suspend_readiness_callback(bool take_callback) { |
| 90 take_suspend_readiness_callback_ = take_callback; | 97 take_suspend_readiness_callback_ = take_callback; |
| 91 } | 98 } |
| 92 | 99 |
| 93 // Runs |suspend_readiness_callback_|. | 100 // Runs |suspend_readiness_callback_|. |
| 94 bool RunSuspendReadinessCallback() WARN_UNUSED_RESULT { | 101 bool RunSuspendReadinessCallback() WARN_UNUSED_RESULT { |
| 95 if (suspend_readiness_callback_.is_null()) | 102 if (suspend_readiness_callback_.is_null()) |
| 96 return false; | 103 return false; |
| 97 | 104 |
| 98 auto cb = suspend_readiness_callback_; | 105 auto cb = suspend_readiness_callback_; |
| 99 suspend_readiness_callback_.Reset(); | 106 suspend_readiness_callback_.Reset(); |
| 100 cb.Run(); | 107 cb.Run(); |
| 101 return true; | 108 return true; |
| 102 } | 109 } |
| 103 | 110 |
| 104 // PowerManagerClient::Observer: | 111 // PowerManagerClient::Observer: |
| 105 void SuspendImminent() override { | 112 void SuspendImminent() override { |
| 106 num_suspend_imminent_++; | 113 num_suspend_imminent_++; |
| 107 if (take_suspend_readiness_callback_) | 114 if (take_suspend_readiness_callback_) |
| 108 suspend_readiness_callback_ = client_->GetSuspendReadinessCallback(); | 115 suspend_readiness_callback_ = client_->GetSuspendReadinessCallback(); |
| 109 } | 116 } |
| 110 void SuspendDone(const base::TimeDelta& sleep_duration) override { | 117 void SuspendDone(const base::TimeDelta& sleep_duration) override { |
| 111 num_suspend_done_++; | 118 num_suspend_done_++; |
| 112 } | 119 } |
| 120 void DarkSuspendImminent() override { |
| 121 num_dark_suspend_imminent_++; |
| 122 if (take_suspend_readiness_callback_) |
| 123 suspend_readiness_callback_ = client_->GetSuspendReadinessCallback(); |
| 124 } |
| 113 | 125 |
| 114 private: | 126 private: |
| 115 PowerManagerClient* client_; // Not owned. | 127 PowerManagerClient* client_; // Not owned. |
| 116 | 128 |
| 117 // Number of times SuspendImminent() and SuspendDone() have been called. | 129 // Number of times SuspendImminent(), SuspendDone(), and DarkSuspendImminent() |
| 130 // have been called. |
| 118 int num_suspend_imminent_ = 0; | 131 int num_suspend_imminent_ = 0; |
| 119 int num_suspend_done_ = 0; | 132 int num_suspend_done_ = 0; |
| 133 int num_dark_suspend_imminent_ = 0; |
| 120 | 134 |
| 121 // Should SuspendImminent() call |client_|'s GetSuspendReadinessCallback() | 135 // Should SuspendImminent() and DarkSuspendImminent() call |client_|'s |
| 122 // method? | 136 // GetSuspendReadinessCallback() method? |
| 123 bool take_suspend_readiness_callback_ = false; | 137 bool take_suspend_readiness_callback_ = false; |
| 124 | 138 |
| 125 // Callback returned by |client_|'s GetSuspendReadinessCallback() method. | 139 // Callback returned by |client_|'s GetSuspendReadinessCallback() method. |
| 126 base::Closure suspend_readiness_callback_; | 140 base::Closure suspend_readiness_callback_; |
| 127 | 141 |
| 128 DISALLOW_COPY_AND_ASSIGN(TestObserver); | 142 DISALLOW_COPY_AND_ASSIGN(TestObserver); |
| 129 }; | 143 }; |
| 130 | 144 |
| 131 // Stub implementation of PowerManagerClient::RenderProcessManagerDelegate. | 145 // Stub implementation of PowerManagerClient::RenderProcessManagerDelegate. |
| 132 class TestDelegate : public PowerManagerClient::RenderProcessManagerDelegate { | 146 class TestDelegate : public PowerManagerClient::RenderProcessManagerDelegate { |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 CHECK(dbus::MessageWriter(response.get()).AppendProtoAsArrayOfBytes(proto)); | 312 CHECK(dbus::MessageWriter(response.get()).AppendProtoAsArrayOfBytes(proto)); |
| 299 | 313 |
| 300 message_loop_.task_runner()->PostTask( | 314 message_loop_.task_runner()->PostTask( |
| 301 FROM_HERE, | 315 FROM_HERE, |
| 302 base::Bind(&RunResponseCallback, callback, base::Passed(&response))); | 316 base::Bind(&RunResponseCallback, callback, base::Passed(&response))); |
| 303 } | 317 } |
| 304 | 318 |
| 305 DISALLOW_COPY_AND_ASSIGN(PowerManagerClientTest); | 319 DISALLOW_COPY_AND_ASSIGN(PowerManagerClientTest); |
| 306 }; | 320 }; |
| 307 | 321 |
| 308 // Suspend readiness should be reported immediately when there are no observers. | 322 // Tests that suspend readiness is reported immediately when there are no |
| 323 // observers. |
| 309 TEST_F(PowerManagerClientTest, ReportSuspendReadinessWithoutObservers) { | 324 TEST_F(PowerManagerClientTest, ReportSuspendReadinessWithoutObservers) { |
| 310 const int kSuspendId = 1; | 325 const int kSuspendId = 1; |
| 311 ExpectSuspendReadiness(kHandleSuspendReadiness, kSuspendId, kSuspendDelayId); | 326 ExpectSuspendReadiness(kHandleSuspendReadiness, kSuspendId, kSuspendDelayId); |
| 312 EmitSuspendImminentSignal(kSuspendImminent, kSuspendId); | 327 EmitSuspendImminentSignal(kSuspendImminent, kSuspendId); |
| 313 EmitSuspendDoneSignal(kSuspendId); | 328 EmitSuspendDoneSignal(kSuspendId); |
| 314 } | 329 } |
| 315 | 330 |
| 316 // Observers should be notified when suspend is imminent and done. Readiness | 331 // Tests that synchronous observers are notified about impending suspend |
| 317 // should be reported synchronously when GetSuspendReadinessCallback() hasn't | 332 // attempts and completion. |
| 318 // been called. | |
| 319 TEST_F(PowerManagerClientTest, ReportSuspendReadinessWithoutCallbacks) { | 333 TEST_F(PowerManagerClientTest, ReportSuspendReadinessWithoutCallbacks) { |
| 320 TestObserver observer_1(client_.get()); | 334 TestObserver observer_1(client_.get()); |
| 321 TestObserver observer_2(client_.get()); | 335 TestObserver observer_2(client_.get()); |
| 322 | 336 |
| 337 // Observers should be notified when suspend is imminent. Readiness should be |
| 338 // reported synchronously since GetSuspendReadinessCallback() hasn't been |
| 339 // called. |
| 323 const int kSuspendId = 1; | 340 const int kSuspendId = 1; |
| 324 ExpectSuspendReadiness(kHandleSuspendReadiness, kSuspendId, kSuspendDelayId); | 341 ExpectSuspendReadiness(kHandleSuspendReadiness, kSuspendId, kSuspendDelayId); |
| 325 EmitSuspendImminentSignal(kSuspendImminent, kSuspendId); | 342 EmitSuspendImminentSignal(kSuspendImminent, kSuspendId); |
| 326 EXPECT_EQ(1, observer_1.num_suspend_imminent()); | 343 EXPECT_EQ(1, observer_1.num_suspend_imminent()); |
| 327 EXPECT_EQ(0, observer_1.num_suspend_done()); | 344 EXPECT_EQ(0, observer_1.num_suspend_done()); |
| 328 EXPECT_EQ(1, observer_2.num_suspend_imminent()); | 345 EXPECT_EQ(1, observer_2.num_suspend_imminent()); |
| 329 EXPECT_EQ(0, observer_2.num_suspend_done()); | 346 EXPECT_EQ(0, observer_2.num_suspend_done()); |
| 330 | 347 |
| 331 EmitSuspendDoneSignal(kSuspendId); | 348 EmitSuspendDoneSignal(kSuspendId); |
| 332 EXPECT_EQ(1, observer_1.num_suspend_imminent()); | 349 EXPECT_EQ(1, observer_1.num_suspend_imminent()); |
| 333 EXPECT_EQ(1, observer_1.num_suspend_done()); | 350 EXPECT_EQ(1, observer_1.num_suspend_done()); |
| 334 EXPECT_EQ(1, observer_2.num_suspend_imminent()); | 351 EXPECT_EQ(1, observer_2.num_suspend_imminent()); |
| 335 EXPECT_EQ(1, observer_2.num_suspend_done()); | 352 EXPECT_EQ(1, observer_2.num_suspend_done()); |
| 336 } | 353 } |
| 337 | 354 |
| 338 // When observers call GetSuspendReadinessCallback() from their | 355 // Tests that readiness is deferred until asynchronous observers have run their |
| 339 // SuspendImminent() methods, the HandleSuspendReadiness method call should be | 356 // callbacks. |
| 340 // deferred until all callbacks are run. | |
| 341 TEST_F(PowerManagerClientTest, ReportSuspendReadinessWithCallbacks) { | 357 TEST_F(PowerManagerClientTest, ReportSuspendReadinessWithCallbacks) { |
| 342 TestObserver observer_1(client_.get()); | 358 TestObserver observer_1(client_.get()); |
| 343 observer_1.set_take_suspend_readiness_callback(true); | 359 observer_1.set_take_suspend_readiness_callback(true); |
| 344 TestObserver observer_2(client_.get()); | 360 TestObserver observer_2(client_.get()); |
| 345 observer_2.set_take_suspend_readiness_callback(true); | 361 observer_2.set_take_suspend_readiness_callback(true); |
| 346 TestObserver observer_3(client_.get()); | 362 TestObserver observer_3(client_.get()); |
| 347 | 363 |
| 364 // When observers call GetSuspendReadinessCallback() from their |
| 365 // SuspendImminent() methods, the HandleSuspendReadiness method call should be |
| 366 // deferred until all callbacks are run. |
| 348 const int kSuspendId = 1; | 367 const int kSuspendId = 1; |
| 349 EmitSuspendImminentSignal(kSuspendImminent, kSuspendId); | 368 EmitSuspendImminentSignal(kSuspendImminent, kSuspendId); |
| 350 EXPECT_TRUE(observer_1.RunSuspendReadinessCallback()); | 369 EXPECT_TRUE(observer_1.RunSuspendReadinessCallback()); |
| 351 ExpectSuspendReadiness(kHandleSuspendReadiness, kSuspendId, kSuspendDelayId); | 370 ExpectSuspendReadiness(kHandleSuspendReadiness, kSuspendId, kSuspendDelayId); |
| 352 EXPECT_TRUE(observer_2.RunSuspendReadinessCallback()); | 371 EXPECT_TRUE(observer_2.RunSuspendReadinessCallback()); |
| 353 EmitSuspendDoneSignal(kSuspendId); | 372 EmitSuspendDoneSignal(kSuspendId); |
| 373 EXPECT_EQ(1, observer_1.num_suspend_done()); |
| 374 EXPECT_EQ(1, observer_2.num_suspend_done()); |
| 354 } | 375 } |
| 355 | 376 |
| 356 // The RenderProcessManagerDelegate should be notified that suspend is imminent | 377 // Tests that RenderProcessManagerDelegate is notified about suspend and resume |
| 357 // only after observers have reported readiness. | 378 // in the common case where suspend readiness is reported. |
| 358 TEST_F(PowerManagerClientTest, NotifyRenderProcessManagerDelegate) { | 379 TEST_F(PowerManagerClientTest, NotifyRenderProcessManagerDelegate) { |
| 359 TestDelegate delegate(client_.get()); | 380 TestDelegate delegate(client_.get()); |
| 360 TestObserver observer(client_.get()); | 381 TestObserver observer(client_.get()); |
| 361 observer.set_take_suspend_readiness_callback(true); | 382 observer.set_take_suspend_readiness_callback(true); |
| 362 | 383 |
| 363 const int kSuspendId = 1; | 384 const int kSuspendId = 1; |
| 364 EmitSuspendImminentSignal(kSuspendImminent, kSuspendId); | 385 EmitSuspendImminentSignal(kSuspendImminent, kSuspendId); |
| 365 EXPECT_EQ(0, delegate.num_suspend_imminent()); | 386 EXPECT_EQ(0, delegate.num_suspend_imminent()); |
| 366 EXPECT_EQ(0, delegate.num_suspend_done()); | 387 EXPECT_EQ(0, delegate.num_suspend_done()); |
| 367 | 388 |
| 389 // The RenderProcessManagerDelegate should be notified that suspend is |
| 390 // imminent only after observers have reported readiness. |
| 368 ExpectSuspendReadiness(kHandleSuspendReadiness, kSuspendId, kSuspendDelayId); | 391 ExpectSuspendReadiness(kHandleSuspendReadiness, kSuspendId, kSuspendDelayId); |
| 369 EXPECT_TRUE(observer.RunSuspendReadinessCallback()); | 392 EXPECT_TRUE(observer.RunSuspendReadinessCallback()); |
| 370 EXPECT_EQ(1, delegate.num_suspend_imminent()); | 393 EXPECT_EQ(1, delegate.num_suspend_imminent()); |
| 371 EXPECT_EQ(0, delegate.num_suspend_done()); | 394 EXPECT_EQ(0, delegate.num_suspend_done()); |
| 372 | 395 |
| 396 // The delegate should be notified immediately after the attempt completes. |
| 373 EmitSuspendDoneSignal(kSuspendId); | 397 EmitSuspendDoneSignal(kSuspendId); |
| 374 EXPECT_EQ(1, delegate.num_suspend_imminent()); | 398 EXPECT_EQ(1, delegate.num_suspend_imminent()); |
| 375 EXPECT_EQ(1, delegate.num_suspend_done()); | 399 EXPECT_EQ(1, delegate.num_suspend_done()); |
| 376 } | 400 } |
| 377 | 401 |
| 378 // TODO(derat): Add more tests, e.g. for SuspendDone being received while | 402 // Tests that DarkSuspendImminent is handled in a manner similar to |
| 379 // readiness callbacks are still outstanding (http://crbug.com/646912) and for | 403 // SuspendImminent. |
| 380 // the handling of DarkSuspendImminent signals. | 404 TEST_F(PowerManagerClientTest, ReportDarkSuspendReadiness) { |
| 405 TestDelegate delegate(client_.get()); |
| 406 TestObserver observer(client_.get()); |
| 407 observer.set_take_suspend_readiness_callback(true); |
| 408 |
| 409 const int kSuspendId = 1; |
| 410 EmitSuspendImminentSignal(kSuspendImminent, kSuspendId); |
| 411 EXPECT_EQ(1, observer.num_suspend_imminent()); |
| 412 EXPECT_EQ(0, delegate.num_suspend_imminent()); |
| 413 |
| 414 ExpectSuspendReadiness(kHandleSuspendReadiness, kSuspendId, kSuspendDelayId); |
| 415 EXPECT_TRUE(observer.RunSuspendReadinessCallback()); |
| 416 EXPECT_EQ(1, delegate.num_suspend_imminent()); |
| 417 |
| 418 // The RenderProcessManagerDelegate shouldn't be notified about dark suspend |
| 419 // attempts. |
| 420 const int kDarkSuspendId = 5; |
| 421 EmitSuspendImminentSignal(kDarkSuspendImminent, kDarkSuspendId); |
| 422 EXPECT_EQ(1, observer.num_dark_suspend_imminent()); |
| 423 EXPECT_EQ(1, delegate.num_suspend_imminent()); |
| 424 EXPECT_EQ(0, delegate.num_suspend_done()); |
| 425 |
| 426 ExpectSuspendReadiness(kHandleDarkSuspendReadiness, kDarkSuspendId, |
| 427 kDarkSuspendDelayId); |
| 428 EXPECT_TRUE(observer.RunSuspendReadinessCallback()); |
| 429 EXPECT_EQ(0, delegate.num_suspend_done()); |
| 430 |
| 431 EmitSuspendDoneSignal(kSuspendId); |
| 432 EXPECT_EQ(1, observer.num_suspend_done()); |
| 433 EXPECT_EQ(1, delegate.num_suspend_done()); |
| 434 } |
| 435 |
| 436 // Tests the case where a SuspendDone signal is received while a readiness |
| 437 // callback is still pending. |
| 438 TEST_F(PowerManagerClientTest, SuspendCancelledWhileCallbackPending) { |
| 439 TestDelegate delegate(client_.get()); |
| 440 TestObserver observer(client_.get()); |
| 441 observer.set_take_suspend_readiness_callback(true); |
| 442 |
| 443 const int kSuspendId = 1; |
| 444 EmitSuspendImminentSignal(kSuspendImminent, kSuspendId); |
| 445 EXPECT_EQ(1, observer.num_suspend_imminent()); |
| 446 |
| 447 // If the suspend attempt completes (probably due to cancellation) before the |
| 448 // observer has run its readiness callback, the observer (but not the |
| 449 // delegate, which hasn't been notified about suspend being imminent yet) |
| 450 // should be notified about completion. |
| 451 EmitSuspendDoneSignal(kSuspendId); |
| 452 EXPECT_EQ(1, observer.num_suspend_done()); |
| 453 EXPECT_EQ(0, delegate.num_suspend_done()); |
| 454 |
| 455 // Ensure that the delegate doesn't receive late notification of suspend being |
| 456 // imminent if the readiness callback runs at this point, since that would |
| 457 // leave the renderers in a frozen state (http://crbug.com/646912). There's an |
| 458 // implicit expectation that powerd doesn't get notified about readiness here, |
| 459 // too. |
| 460 EXPECT_TRUE(observer.RunSuspendReadinessCallback()); |
| 461 EXPECT_EQ(0, delegate.num_suspend_imminent()); |
| 462 EXPECT_EQ(0, delegate.num_suspend_done()); |
| 463 } |
| 464 |
| 465 // Tests the case where a SuspendDone signal is received while a dark suspend |
| 466 // readiness callback is still pending. |
| 467 TEST_F(PowerManagerClientTest, SuspendDoneWhileDarkSuspendCallbackPending) { |
| 468 TestDelegate delegate(client_.get()); |
| 469 TestObserver observer(client_.get()); |
| 470 observer.set_take_suspend_readiness_callback(true); |
| 471 |
| 472 const int kSuspendId = 1; |
| 473 EmitSuspendImminentSignal(kSuspendImminent, kSuspendId); |
| 474 ExpectSuspendReadiness(kHandleSuspendReadiness, kSuspendId, kSuspendDelayId); |
| 475 EXPECT_TRUE(observer.RunSuspendReadinessCallback()); |
| 476 EXPECT_EQ(1, delegate.num_suspend_imminent()); |
| 477 |
| 478 const int kDarkSuspendId = 5; |
| 479 EmitSuspendImminentSignal(kDarkSuspendImminent, kDarkSuspendId); |
| 480 EXPECT_EQ(1, observer.num_dark_suspend_imminent()); |
| 481 |
| 482 // The delegate should be notified if the attempt completes now. |
| 483 EmitSuspendDoneSignal(kSuspendId); |
| 484 EXPECT_EQ(1, observer.num_suspend_done()); |
| 485 EXPECT_EQ(1, delegate.num_suspend_done()); |
| 486 |
| 487 // Dark suspend readiness shouldn't be reported even if the callback runs at |
| 488 // this point, since the suspend attempt is already done. The delegate also |
| 489 // shouldn't receive any more calls. |
| 490 EXPECT_TRUE(observer.RunSuspendReadinessCallback()); |
| 491 EXPECT_EQ(1, delegate.num_suspend_imminent()); |
| 492 EXPECT_EQ(1, delegate.num_suspend_done()); |
| 493 } |
| 494 |
| 495 // Tests the case where dark suspend is announced while readiness hasn't been |
| 496 // reported for the initial regular suspend attempt. |
| 497 TEST_F(PowerManagerClientTest, DarkSuspendImminentWhileCallbackPending) { |
| 498 TestDelegate delegate(client_.get()); |
| 499 TestObserver observer(client_.get()); |
| 500 observer.set_take_suspend_readiness_callback(true); |
| 501 |
| 502 // Announce that suspend is imminent and grab, but don't run, the readiness |
| 503 // callback. |
| 504 const int kSuspendId = 1; |
| 505 EmitSuspendImminentSignal(kSuspendImminent, kSuspendId); |
| 506 EXPECT_EQ(1, observer.num_suspend_imminent()); |
| 507 base::Closure regular_callback = observer.suspend_readiness_callback(); |
| 508 |
| 509 // Before readiness is reported, announce that dark suspend is imminent. |
| 510 const int kDarkSuspendId = 1; |
| 511 EmitSuspendImminentSignal(kDarkSuspendImminent, kDarkSuspendId); |
| 512 EXPECT_EQ(1, observer.num_dark_suspend_imminent()); |
| 513 base::Closure dark_callback = observer.suspend_readiness_callback(); |
| 514 |
| 515 // Complete the suspend attempt and run both of the earlier callbacks. Neither |
| 516 // should result in readiness being reported. |
| 517 EmitSuspendDoneSignal(kSuspendId); |
| 518 EXPECT_EQ(1, observer.num_suspend_done()); |
| 519 regular_callback.Run(); |
| 520 dark_callback.Run(); |
| 521 } |
| 381 | 522 |
| 382 } // namespace chromeos | 523 } // namespace chromeos |
| OLD | NEW |