OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "remoting/test/fake_connection_event_logger.h" | |
6 | |
7 #include "base/atomicops.h" | |
8 #include "base/callback.h" | |
9 #include "base/macros.h" | |
10 #include "base/time/time.h" | |
11 #include "remoting/proto/audio.pb.h" | |
12 #include "remoting/proto/control.pb.h" | |
13 #include "remoting/proto/video.pb.h" | |
14 | |
15 #ifndef ARCH_CPU_64_BITS | |
16 #include "base/synchronization/lock.h" | |
17 #endif | |
18 | |
19 namespace remoting { | |
20 namespace test { | |
21 namespace { | |
22 | |
23 template <typename T> | |
24 class NoBarrierAtomic { | |
25 public: | |
26 T operator++() { | |
27 return base::subtle::NoBarrier_AtomicIncrement(&i_, 1) - 1; | |
28 } | |
29 | |
30 T operator++(int) { | |
31 return base::subtle::NoBarrier_AtomicIncrement(&i_, 1); | |
32 } | |
33 | |
34 T operator--() { | |
35 return base::subtle::NoBarrier_AtomicIncrement(&i_, -1) - 1; | |
36 } | |
37 | |
38 T operator--(int) { | |
39 return base::subtle::NoBarrier_AtomicIncrement(&i_, -1); | |
40 } | |
41 | |
42 T operator+=(T other) { | |
43 return base::subtle::NoBarrier_AtomicIncrement(&i_, other); | |
44 } | |
45 | |
46 T operator-=(T other) { | |
47 return base::subtle::NoBarrier_AtomicIncrement(&i_, -other); | |
48 } | |
49 | |
50 T operator*() const { | |
51 return base::subtle::NoBarrier_Load(&i_); | |
52 } | |
53 | |
54 private: | |
55 volatile T i_; | |
56 }; | |
57 | |
58 class NoBarrierAtomicInt32 : public NoBarrierAtomic<base::subtle::Atomic32> {}; | |
59 #ifdef ARCH_CPU_64_BITS | |
60 class NoBarrierAtomicInt64 : public NoBarrierAtomic<base::subtle::Atomic64> {}; | |
61 #else // ifdef ARCH_CPU_64_BITS | |
62 | |
63 using base::AutoLock; | |
64 | |
65 // A barriered, lock based implementation | |
66 class NoBarrierAtomicInt64 { | |
67 public: | |
68 int64_t operator++(); | |
69 int64_t operator++(int); | |
70 int64_t operator--(); | |
71 int64_t operator--(int); | |
72 int64_t operator+=(int64_t other); | |
73 int64_t operator-=(int64_t other); | |
74 int64_t operator*() const; | |
75 | |
76 private: | |
77 volatile int64_t i_ = 0; | |
78 mutable base::Lock lock_; // field is used in operator*() const | |
79 }; | |
80 | |
81 int64_t NoBarrierAtomicInt64::operator++() { | |
82 AutoLock l(lock_); | |
83 return i_++; | |
84 } | |
85 | |
86 int64_t NoBarrierAtomicInt64::operator++(int) { | |
87 AutoLock l(lock_); | |
88 return ++i_; | |
89 } | |
90 | |
91 int64_t NoBarrierAtomicInt64::operator--() { | |
92 AutoLock l(lock_); | |
93 return i_--; | |
94 } | |
95 | |
96 int64_t NoBarrierAtomicInt64::operator--(int) { | |
97 AutoLock l(lock_); | |
98 return --i_; | |
99 } | |
100 | |
101 int64_t NoBarrierAtomicInt64::operator+=(int64_t other) { | |
102 AutoLock l(lock_); | |
103 return (i_ += other); | |
104 } | |
105 | |
106 int64_t NoBarrierAtomicInt64::operator-=(int64_t other) { | |
107 AutoLock l(lock_); | |
108 return (i_ -= other); | |
109 } | |
110 | |
111 int64_t NoBarrierAtomicInt64::operator*() const { | |
112 AutoLock l(lock_); | |
113 return i_; | |
114 } | |
115 | |
116 #endif // ifdef ARCH_CPU_64_BITS | |
117 | |
118 class MessageCounter { | |
119 public: | |
120 MessageCounter(); | |
121 | |
122 int message_count() const { return *count_; } | |
123 int64_t message_size() const { return *size_; } | |
124 int last_message_size() const { return last_size_; } | |
125 double DurationSeconds() const; | |
126 double MessagesPerSecond() const; | |
127 double SizePerSecond() const; | |
128 double AverageMessageSize() const; | |
129 void LogMessage(const ::google::protobuf::MessageLite& message); | |
130 void DisplayStatistics(std::ostream& os, const char* name); | |
131 | |
132 private: | |
133 NoBarrierAtomicInt32 count_; | |
134 NoBarrierAtomicInt64 size_; | |
135 int last_size_ = 0; | |
136 base::Time start_time_; | |
137 | |
138 // Copy or assign the start_time_ of a MessageCounter is senseless. | |
139 DISALLOW_COPY_AND_ASSIGN(MessageCounter); | |
140 }; | |
141 | |
142 MessageCounter::MessageCounter() | |
143 : count_(), | |
144 size_(), | |
145 start_time_(base::Time::Now()) {} | |
146 | |
147 double MessageCounter::DurationSeconds() const { | |
148 return (base::Time::Now() - start_time_).InSecondsF(); | |
149 } | |
150 | |
151 double MessageCounter::MessagesPerSecond() const { | |
152 return static_cast<double>(message_count()) / DurationSeconds(); | |
153 } | |
154 double MessageCounter::SizePerSecond() const { | |
155 return static_cast<double>(message_size()) / DurationSeconds(); | |
156 } | |
157 | |
158 double MessageCounter::AverageMessageSize() const { | |
159 return static_cast<double>(message_size()) / message_count(); | |
160 } | |
161 | |
162 void MessageCounter::LogMessage( | |
163 const ::google::protobuf::MessageLite& message) { | |
164 count_++; | |
165 last_size_ = message.ByteSize(); | |
166 size_ += message.ByteSize(); | |
167 } | |
168 | |
169 void MessageCounter::DisplayStatistics(std::ostream& os, const char* name) { | |
joedow
2016/05/04 22:58:49
Could this be passed in via the c'tor of the class
Hzj_jie
2016/05/05 00:47:36
Done.
| |
170 os << name | |
171 << ": " | |
172 << message_size() | |
173 << " bytes in " | |
174 << message_count() | |
175 << " packages, last package " | |
176 << last_message_size() | |
177 << " bytes, " | |
178 << AverageMessageSize() | |
179 << " bytes/package, " | |
180 << MessagesPerSecond() | |
181 << " packages/sec, " | |
182 << SizePerSecond() | |
183 << " bytes/sec" | |
184 << std::endl; | |
185 } | |
186 | |
187 } // namespace | |
188 | |
189 // Analyzes messages from DeliverHostMessage function. | |
190 class FakeConnectionEventLogger::CounterClientStub | |
191 : public protocol::ClientStub, public MessageCounter { | |
192 public: | |
joedow
2016/05/04 22:58:49
I think these interface methods can all be private
Hzj_jie
2016/05/05 00:47:36
Done.
| |
193 void DeliverHostMessage(const protocol::ExtensionMessage& message) override; | |
194 void InjectClipboardEvent(const protocol::ClipboardEvent& event) override {} | |
195 void SetCapabilities(const protocol::Capabilities& capabilities) override {} | |
196 void SetCursorShape(const protocol::CursorShapeInfo& cursor_shape) override {} | |
197 void SetPairingResponse(const protocol::PairingResponse& response) override {} | |
198 void SetVideoLayout(const protocol::VideoLayout& video_layout) override {} | |
199 }; | |
200 | |
201 void FakeConnectionEventLogger::CounterClientStub::DeliverHostMessage( | |
202 const protocol::ExtensionMessage& message) { | |
203 LogMessage(message); | |
204 } | |
205 | |
206 // Analyzes messages from DeliverClientMessage function. | |
207 class FakeConnectionEventLogger::CounterHostStub | |
208 : public protocol::HostStub, public MessageCounter { | |
209 public: | |
210 void ControlAudio(const protocol::AudioControl& audio_control) override {} | |
211 void ControlVideo(const protocol::VideoControl& video_control) override {} | |
212 void DeliverClientMessage(const protocol::ExtensionMessage& message) override; | |
213 void NotifyClientResolution( | |
214 const protocol::ClientResolution& resolution) override {} | |
215 void RequestPairing( | |
216 const protocol::PairingRequest& pairing_request) override {} | |
217 void SetCapabilities(const protocol::Capabilities& capabilities) override {} | |
218 }; | |
219 | |
220 void FakeConnectionEventLogger::CounterHostStub::DeliverClientMessage( | |
221 const protocol::ExtensionMessage& message) { | |
222 LogMessage(message); | |
223 } | |
224 | |
225 // Analyzes messages from ProcessAudioPacket function. | |
226 class FakeConnectionEventLogger::CounterAudioStub | |
227 : public protocol::AudioStub, public MessageCounter { | |
228 public: | |
229 void ProcessAudioPacket(std::unique_ptr<AudioPacket> audio_packet, | |
230 const base::Closure& done) override; | |
231 }; | |
232 | |
233 void FakeConnectionEventLogger::CounterAudioStub::ProcessAudioPacket( | |
234 std::unique_ptr<AudioPacket> audio_packet, | |
235 const base::Closure& done) { | |
236 if (audio_packet) { | |
237 LogMessage(*audio_packet); | |
238 } | |
239 done.Run(); | |
240 } | |
241 | |
242 // Analyzes messages from ProcessVideoPacket function. | |
243 class FakeConnectionEventLogger::CounterVideoStub | |
244 : public protocol::VideoStub, public MessageCounter { | |
245 public: | |
246 CounterVideoStub(protocol::FakeConnectionToClient* connection); | |
247 | |
248 void ProcessVideoPacket(std::unique_ptr<VideoPacket> video_packet, | |
249 const base::Closure& done) override; | |
250 | |
251 private: | |
252 protocol::FakeConnectionToClient* connection_ = nullptr; | |
253 }; | |
254 | |
255 FakeConnectionEventLogger::CounterVideoStub::CounterVideoStub( | |
256 protocol::FakeConnectionToClient* connection) | |
257 : connection_(connection) {} | |
258 | |
259 void FakeConnectionEventLogger::CounterVideoStub::ProcessVideoPacket( | |
260 std::unique_ptr<VideoPacket> video_packet, | |
261 const base::Closure& done) { | |
262 if (video_packet && video_packet->has_capture_overhead_time_ms()) { | |
263 // Not a keepalive packet. | |
264 if (connection_ && | |
265 connection_->video_feedback_stub()) { | |
266 std::unique_ptr<VideoAck> ack(new VideoAck()); | |
267 ack->set_frame_id(video_packet->frame_id()); | |
268 connection_->video_feedback_stub()->ProcessVideoAck(std::move(ack)); | |
269 } | |
270 LogMessage(*video_packet); | |
271 } | |
272 done.Run(); | |
273 } | |
274 | |
275 FakeConnectionEventLogger::FakeConnectionEventLogger( | |
276 protocol::FakeConnectionToClient* connection) | |
277 : client_stub_(new CounterClientStub()), | |
278 host_stub_(new CounterHostStub()), | |
279 audio_stub_(new CounterAudioStub()), | |
280 video_stub_(new CounterVideoStub(connection)) {} | |
281 | |
282 FakeConnectionEventLogger::~FakeConnectionEventLogger() {} | |
283 | |
284 protocol::ClientStub* FakeConnectionEventLogger::client_stub() { | |
285 return client_stub_.get(); | |
286 } | |
287 | |
288 protocol::HostStub* FakeConnectionEventLogger::host_stub() { | |
289 return host_stub_.get(); | |
290 } | |
291 | |
292 protocol::AudioStub* FakeConnectionEventLogger::audio_stub() { | |
293 return audio_stub_.get(); | |
294 } | |
295 | |
296 protocol::VideoStub* FakeConnectionEventLogger::video_stub() { | |
297 return video_stub_.get(); | |
298 } | |
299 | |
300 std::ostream& operator<<(std::ostream& os, | |
301 const FakeConnectionEventLogger& logger) { | |
302 logger.audio_stub_->DisplayStatistics(os, "audio"); | |
303 logger.video_stub_->DisplayStatistics(os, "video"); | |
304 logger.client_stub_->DisplayStatistics(os, "client"); | |
305 logger.host_stub_->DisplayStatistics(os, "host"); | |
306 return os; | |
307 } | |
308 | |
309 } // namespace test | |
310 } // namespace remoting | |
OLD | NEW |