Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(80)

Side by Side Diff: chromeos/dbus/power_manager_client_unittest.cc

Issue 2403733003: chromeos: Avoid crash on synchronous suspend readiness call. (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chromeos/dbus/power_manager_client.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 int num_suspend_imminent() const { return num_suspend_imminent_; } 89 int num_suspend_imminent() const { return num_suspend_imminent_; }
90 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_; } 91 int num_dark_suspend_imminent() const { return num_dark_suspend_imminent_; }
92 base::Closure suspend_readiness_callback() const { 92 base::Closure suspend_readiness_callback() const {
93 return suspend_readiness_callback_; 93 return suspend_readiness_callback_;
94 } 94 }
95 95
96 void set_take_suspend_readiness_callback(bool take_callback) { 96 void set_take_suspend_readiness_callback(bool take_callback) {
97 take_suspend_readiness_callback_ = take_callback; 97 take_suspend_readiness_callback_ = take_callback;
98 } 98 }
99 void set_run_suspend_readiness_callback_immediately(bool run) {
100 run_suspend_readiness_callback_immediately_ = run;
101 }
99 102
100 // Runs |suspend_readiness_callback_|. 103 // Runs |suspend_readiness_callback_|.
101 bool RunSuspendReadinessCallback() WARN_UNUSED_RESULT { 104 bool RunSuspendReadinessCallback() WARN_UNUSED_RESULT {
102 if (suspend_readiness_callback_.is_null()) 105 if (suspend_readiness_callback_.is_null())
103 return false; 106 return false;
104 107
105 auto cb = suspend_readiness_callback_; 108 auto cb = suspend_readiness_callback_;
106 suspend_readiness_callback_.Reset(); 109 suspend_readiness_callback_.Reset();
107 cb.Run(); 110 cb.Run();
108 return true; 111 return true;
109 } 112 }
110 113
111 // PowerManagerClient::Observer: 114 // PowerManagerClient::Observer:
112 void SuspendImminent() override { 115 void SuspendImminent() override {
113 num_suspend_imminent_++; 116 num_suspend_imminent_++;
114 if (take_suspend_readiness_callback_) 117 if (take_suspend_readiness_callback_)
115 suspend_readiness_callback_ = client_->GetSuspendReadinessCallback(); 118 suspend_readiness_callback_ = client_->GetSuspendReadinessCallback();
119 if (run_suspend_readiness_callback_immediately_)
120 CHECK(RunSuspendReadinessCallback());
116 } 121 }
117 void SuspendDone(const base::TimeDelta& sleep_duration) override { 122 void SuspendDone(const base::TimeDelta& sleep_duration) override {
118 num_suspend_done_++; 123 num_suspend_done_++;
119 } 124 }
120 void DarkSuspendImminent() override { 125 void DarkSuspendImminent() override {
121 num_dark_suspend_imminent_++; 126 num_dark_suspend_imminent_++;
122 if (take_suspend_readiness_callback_) 127 if (take_suspend_readiness_callback_)
123 suspend_readiness_callback_ = client_->GetSuspendReadinessCallback(); 128 suspend_readiness_callback_ = client_->GetSuspendReadinessCallback();
129 if (run_suspend_readiness_callback_immediately_)
130 CHECK(RunSuspendReadinessCallback());
124 } 131 }
125 132
126 private: 133 private:
127 PowerManagerClient* client_; // Not owned. 134 PowerManagerClient* client_; // Not owned.
128 135
129 // Number of times SuspendImminent(), SuspendDone(), and DarkSuspendImminent() 136 // Number of times SuspendImminent(), SuspendDone(), and DarkSuspendImminent()
130 // have been called. 137 // have been called.
131 int num_suspend_imminent_ = 0; 138 int num_suspend_imminent_ = 0;
132 int num_suspend_done_ = 0; 139 int num_suspend_done_ = 0;
133 int num_dark_suspend_imminent_ = 0; 140 int num_dark_suspend_imminent_ = 0;
134 141
135 // Should SuspendImminent() and DarkSuspendImminent() call |client_|'s 142 // Should SuspendImminent() and DarkSuspendImminent() call |client_|'s
136 // GetSuspendReadinessCallback() method? 143 // GetSuspendReadinessCallback() method?
137 bool take_suspend_readiness_callback_ = false; 144 bool take_suspend_readiness_callback_ = false;
138 145
146 // Should SuspendImminent() and DarkSuspendImminent() run the suspend
147 // readiness callback synchronously after taking it? Only has an effect if
148 // |take_suspend_readiness_callback_| is true.
149 bool run_suspend_readiness_callback_immediately_ = false;
150
139 // Callback returned by |client_|'s GetSuspendReadinessCallback() method. 151 // Callback returned by |client_|'s GetSuspendReadinessCallback() method.
140 base::Closure suspend_readiness_callback_; 152 base::Closure suspend_readiness_callback_;
141 153
142 DISALLOW_COPY_AND_ASSIGN(TestObserver); 154 DISALLOW_COPY_AND_ASSIGN(TestObserver);
143 }; 155 };
144 156
145 // Stub implementation of PowerManagerClient::RenderProcessManagerDelegate. 157 // Stub implementation of PowerManagerClient::RenderProcessManagerDelegate.
146 class TestDelegate : public PowerManagerClient::RenderProcessManagerDelegate { 158 class TestDelegate : public PowerManagerClient::RenderProcessManagerDelegate {
147 public: 159 public:
148 explicit TestDelegate(PowerManagerClient* client) : weak_ptr_factory_(this) { 160 explicit TestDelegate(PowerManagerClient* client) : weak_ptr_factory_(this) {
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 base::Closure dark_callback = observer.suspend_readiness_callback(); 525 base::Closure dark_callback = observer.suspend_readiness_callback();
514 526
515 // Complete the suspend attempt and run both of the earlier callbacks. Neither 527 // Complete the suspend attempt and run both of the earlier callbacks. Neither
516 // should result in readiness being reported. 528 // should result in readiness being reported.
517 EmitSuspendDoneSignal(kSuspendId); 529 EmitSuspendDoneSignal(kSuspendId);
518 EXPECT_EQ(1, observer.num_suspend_done()); 530 EXPECT_EQ(1, observer.num_suspend_done());
519 regular_callback.Run(); 531 regular_callback.Run();
520 dark_callback.Run(); 532 dark_callback.Run();
521 } 533 }
522 534
535 // Tests that PowerManagerClient handles a single observer that requests a
536 // suspend-readiness callback and then runs it synchronously from within
537 // SuspendImminent() instead of running it asynchronously:
538 // http://crosbug.com/p/58295
539 TEST_F(PowerManagerClientTest, SyncCallbackWithSingleObserver) {
540 TestObserver observer(client_.get());
541 observer.set_take_suspend_readiness_callback(true);
542 observer.set_run_suspend_readiness_callback_immediately(true);
543
544 const int kSuspendId = 1;
545 ExpectSuspendReadiness(kHandleSuspendReadiness, kSuspendId, kSuspendDelayId);
546 EmitSuspendImminentSignal(kSuspendImminent, kSuspendId);
547 EmitSuspendDoneSignal(kSuspendId);
548 }
549
550 // Tests the case where one observer reports suspend readiness by running its
551 // callback before a second observer even gets notified about the suspend
552 // attempt. We shouldn't report suspend readiness until the second observer has
553 // been notified and confirmed readiness.
554 TEST_F(PowerManagerClientTest, SyncCallbackWithMultipleObservers) {
555 TestObserver observer1(client_.get());
556 observer1.set_take_suspend_readiness_callback(true);
557 observer1.set_run_suspend_readiness_callback_immediately(true);
558
559 TestObserver observer2(client_.get());
560 observer2.set_take_suspend_readiness_callback(true);
561
562 const int kSuspendId = 1;
563 EmitSuspendImminentSignal(kSuspendImminent, kSuspendId);
564 ExpectSuspendReadiness(kHandleSuspendReadiness, kSuspendId, kSuspendDelayId);
565 EXPECT_TRUE(observer2.RunSuspendReadinessCallback());
566 EmitSuspendDoneSignal(kSuspendId);
567 }
568
523 } // namespace chromeos 569 } // namespace chromeos
OLDNEW
« no previous file with comments | « chromeos/dbus/power_manager_client.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698