1 // Copyright 2015 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.
5 #include "remoting/test/connection_time_observer.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/time/time.h"
11 #include "base/timer/timer.h"
16 ConnectionTimeObserver::ConnectionTimeObserver() {
19 ConnectionTimeObserver::~ConnectionTimeObserver() {
22 void ConnectionTimeObserver::SetTransitionTimesMapForTest(
23 const std::map
<protocol::ConnectionToHost::State
, base::TimeTicks
>& map
) {
24 transition_times_map_
= map
;
27 void ConnectionTimeObserver::ConnectionStateChanged(
28 protocol::ConnectionToHost::State state
,
29 protocol::ErrorCode error_code
) {
30 if (transition_times_map_
.find(state
) != transition_times_map_
.end()) {
31 std::string connection_state
=
32 protocol::ConnectionToHost::StateToString(state
);
33 LOG(ERROR
) << connection_state
<< " state has already been set";
36 transition_times_map_
.insert(std::make_pair(state
, base::TimeTicks::Now()));
37 current_connection_state_
= state
;
40 void ConnectionTimeObserver::DisplayConnectionStats() const {
41 protocol::ConnectionToHost::State initializing
=
42 protocol::ConnectionToHost::State::INITIALIZING
;
43 protocol::ConnectionToHost::State current_state
= initializing
;
45 const char kStateChangeTitleFormatString
[] = "%-35s%-15s";
46 LOG(INFO
) << base::StringPrintf(kStateChangeTitleFormatString
,
47 "State to State", "Delta Time");
48 LOG(INFO
) << base::StringPrintf(kStateChangeTitleFormatString
,
49 "--------------", "----------");
51 // Note: the order of |connected_states| mimics the expected order of when a
52 // connection is made.
53 std::vector
<protocol::ConnectionToHost::State
> connected_states
;
54 connected_states
.push_back(protocol::ConnectionToHost::State::CONNECTING
);
55 connected_states
.push_back(protocol::ConnectionToHost::State::AUTHENTICATED
);
56 connected_states
.push_back(protocol::ConnectionToHost::State::CONNECTED
);
57 connected_states
.push_back(protocol::ConnectionToHost::State::FAILED
);
59 const char kStateChangeFormatString
[] = "%-13s to %-18s%-7dms";
60 auto iter_end
= transition_times_map_
.end();
61 for (protocol::ConnectionToHost::State state
: connected_states
) {
62 auto iter_state
= transition_times_map_
.find(state
);
63 if (iter_state
!= iter_end
) {
64 int state_transition_time
=
65 GetStateTransitionTime(current_state
, state
).InMilliseconds();
66 LOG(INFO
) << base::StringPrintf(kStateChangeFormatString
,
67 protocol::ConnectionToHost::StateToString(current_state
),
68 protocol::ConnectionToHost::StateToString(state
),
69 state_transition_time
);
70 current_state
= state
;
75 GetStateTransitionTime(initializing
, current_state
).InMilliseconds();
77 // |current state| will either be FAILED or CONNECTED.
78 LOG(INFO
) << "Total Connection Duration (INITIALIZING to "
79 << protocol::ConnectionToHost::StateToString(current_state
) << "): "
80 << connected_time
<< " ms";
83 base::TimeDelta
ConnectionTimeObserver::GetStateTransitionTime(
84 protocol::ConnectionToHost::State start
,
85 protocol::ConnectionToHost::State end
) const {
86 auto iter_end
= transition_times_map_
.end();
88 auto iter_start_state
= transition_times_map_
.find(start
);
89 std::string start_state
= protocol::ConnectionToHost::StateToString(start
);
90 if (iter_start_state
== iter_end
) {
91 LOG(ERROR
) << "No time found for state: " << start_state
;
92 return base::TimeDelta::Max();
95 auto iter_end_state
= transition_times_map_
.find(end
);
96 std::string end_state
= protocol::ConnectionToHost::StateToString(end
);
97 if (iter_end_state
== iter_end
) {
98 LOG(ERROR
) << "No time found for state: " << end_state
;
99 return base::TimeDelta::Max();
102 base::TimeDelta delta
= iter_end_state
->second
- iter_start_state
->second
;
103 if (delta
.InMilliseconds() < 0) {
104 LOG(ERROR
) << "Transition delay is negative. Check the state ordering: "
105 << "[start: " << start_state
<< ", end: " << end_state
<< "]";
106 return base::TimeDelta::Max();
113 } // namespace remoting