OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "remoting/client/log_to_server.h" | 5 #include "remoting/client/client_status_logger.h" |
6 | 6 |
7 #include "base/macros.h" | 7 #include "base/macros.h" |
8 #include "base/rand_util.h" | 8 #include "base/rand_util.h" |
9 #include "remoting/base/constants.h" | |
10 #include "remoting/client/chromoting_stats.h" | 9 #include "remoting/client/chromoting_stats.h" |
11 #include "remoting/client/server_log_entry_client.h" | 10 #include "remoting/client/server_log_entry_client.h" |
12 #include "remoting/jingle_glue/iq_sender.h" | |
13 #include "remoting/jingle_glue/signal_strategy.h" | |
14 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" | |
15 #include "third_party/libjingle/source/talk/xmpp/constants.h" | |
16 | 11 |
17 using buzz::QName; | |
18 using buzz::XmlElement; | |
19 using remoting::protocol::ConnectionToHost; | 12 using remoting::protocol::ConnectionToHost; |
20 | 13 |
21 namespace { | 14 namespace { |
22 | 15 |
23 const char kSessionIdAlphabet[] = | 16 const char kSessionIdAlphabet[] = |
24 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; | 17 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; |
25 const int kSessionIdLength = 20; | 18 const int kSessionIdLength = 20; |
26 | 19 |
27 const int kMaxSessionIdAgeDays = 1; | 20 const int kMaxSessionIdAgeDays = 1; |
28 | 21 |
(...skipping 13 matching lines...) Expand all Loading... |
42 // Duration is added to log entries at the end of the session, as well as at | 35 // Duration is added to log entries at the end of the session, as well as at |
43 // some intermediate states where it is relevant (e.g. to determine how long | 36 // some intermediate states where it is relevant (e.g. to determine how long |
44 // it took for a session to become CONNECTED). | 37 // it took for a session to become CONNECTED). |
45 return IsEndOfSession(state) || state == ConnectionToHost::CONNECTED; | 38 return IsEndOfSession(state) || state == ConnectionToHost::CONNECTED; |
46 } | 39 } |
47 | 40 |
48 } // namespace | 41 } // namespace |
49 | 42 |
50 namespace remoting { | 43 namespace remoting { |
51 | 44 |
52 namespace client { | 45 ClientStatusLogger::ClientStatusLogger(ServerLogEntry::Mode mode, |
53 | 46 SignalStrategy* signal_strategy, |
54 LogToServer::LogToServer(ServerLogEntry::Mode mode, | 47 const std::string& directory_bot_jid) |
55 SignalStrategy* signal_strategy, | 48 : log_to_server_(mode, signal_strategy, directory_bot_jid) { |
56 const std::string& directory_bot_jid) | |
57 : mode_(mode), | |
58 signal_strategy_(signal_strategy), | |
59 directory_bot_jid_(directory_bot_jid) { | |
60 signal_strategy_->AddListener(this); | |
61 } | 49 } |
62 | 50 |
63 LogToServer::~LogToServer() { | 51 ClientStatusLogger::~ClientStatusLogger() { |
64 signal_strategy_->RemoveListener(this); | |
65 } | 52 } |
66 | 53 |
67 void LogToServer::LogSessionStateChange( | 54 void ClientStatusLogger::LogSessionStateChange( |
68 protocol::ConnectionToHost::State state, | 55 protocol::ConnectionToHost::State state, |
69 protocol::ErrorCode error) { | 56 protocol::ErrorCode error) { |
70 DCHECK(CalledOnValidThread()); | 57 DCHECK(CalledOnValidThread()); |
71 | 58 |
72 scoped_ptr<ServerLogEntry> entry( | 59 scoped_ptr<ServerLogEntry> entry( |
73 MakeLogEntryForSessionStateChange(state, error)); | 60 MakeLogEntryForSessionStateChange(state, error)); |
74 AddClientFieldsToLogEntry(entry.get()); | 61 AddClientFieldsToLogEntry(entry.get()); |
75 entry->AddModeField(mode_); | 62 entry->AddModeField(log_to_server_.mode()); |
76 | 63 |
77 MaybeExpireSessionId(); | 64 MaybeExpireSessionId(); |
78 if (IsStartOfSession(state)) { | 65 if (IsStartOfSession(state)) { |
79 // Maybe set the session ID and start time. | 66 // Maybe set the session ID and start time. |
80 if (session_id_.empty()) { | 67 if (session_id_.empty()) { |
81 GenerateSessionId(); | 68 GenerateSessionId(); |
82 } | 69 } |
83 if (session_start_time_.is_null()) { | 70 if (session_start_time_.is_null()) { |
84 session_start_time_ = base::TimeTicks::Now(); | 71 session_start_time_ = base::TimeTicks::Now(); |
85 } | 72 } |
86 } | 73 } |
87 | 74 |
88 if (!session_id_.empty()) { | 75 if (!session_id_.empty()) { |
89 AddSessionIdToLogEntry(entry.get(), session_id_); | 76 AddSessionIdToLogEntry(entry.get(), session_id_); |
90 } | 77 } |
91 | 78 |
92 // Maybe clear the session start time and log the session duration. | 79 // Maybe clear the session start time and log the session duration. |
93 if (ShouldAddDuration(state) && !session_start_time_.is_null()) { | 80 if (ShouldAddDuration(state) && !session_start_time_.is_null()) { |
94 AddSessionDurationToLogEntry(entry.get(), | 81 AddSessionDurationToLogEntry(entry.get(), |
95 base::TimeTicks::Now() - session_start_time_); | 82 base::TimeTicks::Now() - session_start_time_); |
96 } | 83 } |
97 | 84 |
98 if (IsEndOfSession(state)) { | 85 if (IsEndOfSession(state)) { |
99 session_start_time_ = base::TimeTicks(); | 86 session_start_time_ = base::TimeTicks(); |
100 session_id_.clear(); | 87 session_id_.clear(); |
101 } | 88 } |
102 | 89 |
103 Log(*entry.get()); | 90 log_to_server_.Log(*entry.get()); |
104 } | 91 } |
105 | 92 |
106 void LogToServer::LogStatistics(ChromotingStats* statistics) { | 93 void ClientStatusLogger::LogStatistics(ChromotingStats* statistics) { |
107 DCHECK(CalledOnValidThread()); | 94 DCHECK(CalledOnValidThread()); |
108 | 95 |
109 MaybeExpireSessionId(); | 96 MaybeExpireSessionId(); |
110 | 97 |
111 scoped_ptr<ServerLogEntry> entry(MakeLogEntryForStatistics(statistics)); | 98 scoped_ptr<ServerLogEntry> entry(MakeLogEntryForStatistics(statistics)); |
112 AddClientFieldsToLogEntry(entry.get()); | 99 AddClientFieldsToLogEntry(entry.get()); |
113 entry->AddModeField(mode_); | 100 entry->AddModeField(log_to_server_.mode()); |
114 AddSessionIdToLogEntry(entry.get(), session_id_); | 101 AddSessionIdToLogEntry(entry.get(), session_id_); |
115 Log(*entry.get()); | 102 log_to_server_.Log(*entry.get()); |
116 } | 103 } |
117 | 104 |
118 void LogToServer::OnSignalStrategyStateChange(SignalStrategy::State state) { | 105 void ClientStatusLogger::SetSignalingStateForTest(SignalStrategy::State state) { |
119 DCHECK(CalledOnValidThread()); | 106 log_to_server_.OnSignalStrategyStateChange(state); |
120 | |
121 if (state == SignalStrategy::CONNECTED) { | |
122 iq_sender_.reset(new IqSender(signal_strategy_)); | |
123 SendPendingEntries(); | |
124 } else if (state == SignalStrategy::DISCONNECTED) { | |
125 iq_sender_.reset(); | |
126 } | |
127 } | 107 } |
128 | 108 |
129 bool LogToServer::OnSignalStrategyIncomingStanza( | 109 void ClientStatusLogger::GenerateSessionId() { |
130 const buzz::XmlElement* stanza) { | |
131 return false; | |
132 } | |
133 | |
134 void LogToServer::Log(const ServerLogEntry& entry) { | |
135 pending_entries_.push_back(entry); | |
136 SendPendingEntries(); | |
137 } | |
138 | |
139 void LogToServer::SendPendingEntries() { | |
140 if (iq_sender_ == NULL) { | |
141 return; | |
142 } | |
143 if (pending_entries_.empty()) { | |
144 return; | |
145 } | |
146 // Make one stanza containing all the pending entries. | |
147 scoped_ptr<XmlElement> stanza(ServerLogEntry::MakeStanza()); | |
148 while (!pending_entries_.empty()) { | |
149 ServerLogEntry& entry = pending_entries_.front(); | |
150 stanza->AddElement(entry.ToStanza().release()); | |
151 pending_entries_.pop_front(); | |
152 } | |
153 // Send the stanza to the server. | |
154 scoped_ptr<IqRequest> req = iq_sender_->SendIq( | |
155 buzz::STR_SET, directory_bot_jid_, stanza.Pass(), | |
156 IqSender::ReplyCallback()); | |
157 // We ignore any response, so let the IqRequest be destroyed. | |
158 return; | |
159 } | |
160 | |
161 void LogToServer::GenerateSessionId() { | |
162 session_id_.resize(kSessionIdLength); | 110 session_id_.resize(kSessionIdLength); |
163 for (int i = 0; i < kSessionIdLength; i++) { | 111 for (int i = 0; i < kSessionIdLength; i++) { |
164 const int alphabet_size = arraysize(kSessionIdAlphabet) - 1; | 112 const int alphabet_size = arraysize(kSessionIdAlphabet) - 1; |
165 session_id_[i] = kSessionIdAlphabet[base::RandGenerator(alphabet_size)]; | 113 session_id_[i] = kSessionIdAlphabet[base::RandGenerator(alphabet_size)]; |
166 } | 114 } |
167 session_id_generation_time_ = base::TimeTicks::Now(); | 115 session_id_generation_time_ = base::TimeTicks::Now(); |
168 } | 116 } |
169 | 117 |
170 void LogToServer::MaybeExpireSessionId() { | 118 void ClientStatusLogger::MaybeExpireSessionId() { |
171 if (session_id_.empty()) { | 119 if (session_id_.empty()) { |
172 return; | 120 return; |
173 } | 121 } |
174 | 122 |
175 base::TimeDelta max_age = base::TimeDelta::FromDays(kMaxSessionIdAgeDays); | 123 base::TimeDelta max_age = base::TimeDelta::FromDays(kMaxSessionIdAgeDays); |
176 if (base::TimeTicks::Now() - session_id_generation_time_ > max_age) { | 124 if (base::TimeTicks::Now() - session_id_generation_time_ > max_age) { |
177 // Log the old session ID. | 125 // Log the old session ID. |
178 scoped_ptr<ServerLogEntry> entry(MakeLogEntryForSessionIdOld(session_id_)); | 126 scoped_ptr<ServerLogEntry> entry(MakeLogEntryForSessionIdOld(session_id_)); |
179 entry->AddModeField(mode_); | 127 entry->AddModeField(log_to_server_.mode()); |
180 Log(*entry.get()); | 128 log_to_server_.Log(*entry.get()); |
181 | 129 |
182 // Generate a new session ID. | 130 // Generate a new session ID. |
183 GenerateSessionId(); | 131 GenerateSessionId(); |
184 | 132 |
185 // Log the new session ID. | 133 // Log the new session ID. |
186 entry = MakeLogEntryForSessionIdNew(session_id_); | 134 entry = MakeLogEntryForSessionIdNew(session_id_); |
187 entry->AddModeField(mode_); | 135 entry->AddModeField(log_to_server_.mode()); |
188 Log(*entry.get()); | 136 log_to_server_.Log(*entry.get()); |
189 } | 137 } |
190 } | 138 } |
191 | 139 |
192 } // namespace client | |
193 | |
194 } // namespace remoting | 140 } // namespace remoting |
OLD | NEW |