OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/plugin/chromoting_instance.h" | 5 #include "remoting/client/plugin/chromoting_instance.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #if defined(OS_NACL) | 10 #if defined(OS_NACL) |
(...skipping 14 matching lines...) Expand all Loading... | |
25 #include "base/threading/thread.h" | 25 #include "base/threading/thread.h" |
26 #include "base/values.h" | 26 #include "base/values.h" |
27 #include "crypto/random.h" | 27 #include "crypto/random.h" |
28 #include "jingle/glue/thread_wrapper.h" | 28 #include "jingle/glue/thread_wrapper.h" |
29 #include "media/base/yuv_convert.h" | 29 #include "media/base/yuv_convert.h" |
30 #include "net/socket/ssl_server_socket.h" | 30 #include "net/socket/ssl_server_socket.h" |
31 #include "ppapi/cpp/completion_callback.h" | 31 #include "ppapi/cpp/completion_callback.h" |
32 #include "ppapi/cpp/dev/url_util_dev.h" | 32 #include "ppapi/cpp/dev/url_util_dev.h" |
33 #include "ppapi/cpp/image_data.h" | 33 #include "ppapi/cpp/image_data.h" |
34 #include "ppapi/cpp/input_event.h" | 34 #include "ppapi/cpp/input_event.h" |
35 #include "ppapi/cpp/private/uma_private.h" | |
35 #include "ppapi/cpp/rect.h" | 36 #include "ppapi/cpp/rect.h" |
36 #include "ppapi/cpp/var_array_buffer.h" | 37 #include "ppapi/cpp/var_array_buffer.h" |
37 #include "ppapi/cpp/var_dictionary.h" | 38 #include "ppapi/cpp/var_dictionary.h" |
38 #include "remoting/base/constants.h" | 39 #include "remoting/base/constants.h" |
39 #include "remoting/base/util.h" | 40 #include "remoting/base/util.h" |
40 #include "remoting/client/chromoting_client.h" | 41 #include "remoting/client/chromoting_client.h" |
41 #include "remoting/client/plugin/delegating_signal_strategy.h" | 42 #include "remoting/client/plugin/delegating_signal_strategy.h" |
42 #include "remoting/client/plugin/normalizing_input_filter_cros.h" | 43 #include "remoting/client/plugin/normalizing_input_filter_cros.h" |
43 #include "remoting/client/plugin/normalizing_input_filter_mac.h" | 44 #include "remoting/client/plugin/normalizing_input_filter_mac.h" |
44 #include "remoting/client/plugin/pepper_audio_player.h" | 45 #include "remoting/client/plugin/pepper_audio_player.h" |
(...skipping 15 matching lines...) Expand all Loading... | |
60 #undef PostMessage | 61 #undef PostMessage |
61 #endif | 62 #endif |
62 | 63 |
63 namespace remoting { | 64 namespace remoting { |
64 | 65 |
65 namespace { | 66 namespace { |
66 | 67 |
67 // Default DPI to assume for old clients that use notifyClientResolution. | 68 // Default DPI to assume for old clients that use notifyClientResolution. |
68 const int kDefaultDPI = 96; | 69 const int kDefaultDPI = 96; |
69 | 70 |
70 // Interval at which to sample performance statistics. | |
71 const int kPerfStatsIntervalMs = 1000; | |
72 | |
73 // URL scheme used by Chrome apps and extensions. | 71 // URL scheme used by Chrome apps and extensions. |
74 const char kChromeExtensionUrlScheme[] = "chrome-extension"; | 72 const char kChromeExtensionUrlScheme[] = "chrome-extension"; |
75 | 73 |
74 // The boundary value for the FPS histogram: we don't expect video frame-rate to | |
75 // be greater than 40fps. Leaving some room for future improvements, we'll set | |
76 // the max frame rate to 60fps. | |
77 // Histograms expect samples to be less than the boundary value, so set to 41. | |
rkaplow
2015/07/10 17:41:40
61
anandc
2015/07/10 19:37:14
Done.
| |
78 const int kMaxFrameRate = 61; | |
79 | |
80 // For bandwidth, based on expected real-world numbers, we'll use a histogram | |
81 // ranging from 0 to 10MB/s, spread across 1000 buckets. | |
rkaplow
2015/07/10 17:41:40
I feel 1000 buckets is excessive. I suspect you sh
anandc
2015/07/10 19:37:14
Thanks. Done.
| |
82 // Histograms are log-scaled by default. This results in fine-grained buckets at | |
83 // lower values and wider-ranged buckets closer to the maximum. | |
84 // Values above the maximum defined here end up in the right-most bucket. | |
85 // See $/src/base/metrics/histogram.h for more details. | |
86 const int kBandwidthHistogramMin = 1; | |
87 const int kBandwidthHistogramMax = 10240000; | |
88 const int kBandwidthHistogramNumBuckets = 1000; | |
89 | |
76 #if defined(USE_OPENSSL) | 90 #if defined(USE_OPENSSL) |
77 // Size of the random seed blob used to initialize RNG in libjingle. Libjingle | 91 // Size of the random seed blob used to initialize RNG in libjingle. Libjingle |
78 // uses the seed only for OpenSSL builds. OpenSSL needs at least 32 bytes of | 92 // uses the seed only for OpenSSL builds. OpenSSL needs at least 32 bytes of |
79 // entropy (see http://wiki.openssl.org/index.php/Random_Numbers), but stores | 93 // entropy (see http://wiki.openssl.org/index.php/Random_Numbers), but stores |
80 // 1039 bytes of state, so we initialize it with 1k or random data. | 94 // 1039 bytes of state, so we initialize it with 1k or random data. |
81 const int kRandomSeedSize = 1024; | 95 const int kRandomSeedSize = 1024; |
82 #endif // defined(USE_OPENSSL) | 96 #endif // defined(USE_OPENSSL) |
83 | 97 |
84 std::string ConnectionStateToString(protocol::ConnectionToHost::State state) { | 98 std::string ConnectionStateToString(protocol::ConnectionToHost::State state) { |
85 // Values returned by this function must match the | 99 // Values returned by this function must match the |
(...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
721 host_public_key)); | 735 host_public_key)); |
722 scoped_ptr<protocol::Authenticator> authenticator( | 736 scoped_ptr<protocol::Authenticator> authenticator( |
723 new protocol::NegotiatingClientAuthenticator( | 737 new protocol::NegotiatingClientAuthenticator( |
724 client_pairing_id, client_paired_secret, authentication_tag, | 738 client_pairing_id, client_paired_secret, authentication_tag, |
725 fetch_secret_callback, token_fetcher.Pass(), auth_methods)); | 739 fetch_secret_callback, token_fetcher.Pass(), auth_methods)); |
726 | 740 |
727 // Kick off the connection. | 741 // Kick off the connection. |
728 client_->Start(signal_strategy_.get(), authenticator.Pass(), | 742 client_->Start(signal_strategy_.get(), authenticator.Pass(), |
729 transport_factory.Pass(), host_jid, capabilities); | 743 transport_factory.Pass(), host_jid, capabilities); |
730 | 744 |
731 // Start timer that periodically sends perf stats. | 745 // Start timers that periodically send perf stats. |
732 plugin_task_runner_->PostDelayedTask( | 746 plugin_task_runner_->PostDelayedTask( |
733 FROM_HERE, base::Bind(&ChromotingInstance::SendPerfStats, | 747 FROM_HERE, base::Bind(&ChromotingInstance::SendPerfStats, |
734 weak_factory_.GetWeakPtr()), | 748 weak_factory_.GetWeakPtr()), |
735 base::TimeDelta::FromMilliseconds(kPerfStatsIntervalMs)); | 749 base::TimeDelta::FromSeconds( |
750 ChromotingStats::kStatsUpdateFrequencyInSeconds)); | |
736 } | 751 } |
737 | 752 |
738 void ChromotingInstance::HandleDisconnect(const base::DictionaryValue& data) { | 753 void ChromotingInstance::HandleDisconnect(const base::DictionaryValue& data) { |
739 DCHECK(plugin_task_runner_->BelongsToCurrentThread()); | 754 DCHECK(plugin_task_runner_->BelongsToCurrentThread()); |
740 Disconnect(); | 755 Disconnect(); |
741 } | 756 } |
742 | 757 |
743 void ChromotingInstance::HandleOnIncomingIq(const base::DictionaryValue& data) { | 758 void ChromotingInstance::HandleOnIncomingIq(const base::DictionaryValue& data) { |
744 std::string iq; | 759 std::string iq; |
745 if (!data.GetString("iq", &iq)) { | 760 if (!data.GetString("iq", &iq)) { |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1045 } | 1060 } |
1046 | 1061 |
1047 void ChromotingInstance::SendPerfStats() { | 1062 void ChromotingInstance::SendPerfStats() { |
1048 if (!video_renderer_.get()) { | 1063 if (!video_renderer_.get()) { |
1049 return; | 1064 return; |
1050 } | 1065 } |
1051 | 1066 |
1052 plugin_task_runner_->PostDelayedTask( | 1067 plugin_task_runner_->PostDelayedTask( |
1053 FROM_HERE, base::Bind(&ChromotingInstance::SendPerfStats, | 1068 FROM_HERE, base::Bind(&ChromotingInstance::SendPerfStats, |
1054 weak_factory_.GetWeakPtr()), | 1069 weak_factory_.GetWeakPtr()), |
1055 base::TimeDelta::FromMilliseconds(kPerfStatsIntervalMs)); | 1070 base::TimeDelta::FromSeconds( |
1071 ChromotingStats::kStatsUpdateFrequencyInSeconds)); | |
1056 | 1072 |
1073 // Update performance stats and send them to the client for display to users. | |
1074 // The rate metrics are averaged over 1s, and the latency metrics are averaged | |
1075 // over the 10 most recent samples. | |
1057 scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue()); | 1076 scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue()); |
1058 ChromotingStats* stats = video_renderer_->GetStats(); | 1077 ChromotingStats* stats = video_renderer_->GetStats(); |
1059 data->SetDouble("videoBandwidth", stats->video_bandwidth()->Rate()); | 1078 data->SetDouble("videoBandwidth", stats->video_bandwidth()->Rate()); |
1060 data->SetDouble("videoFrameRate", stats->video_frame_rate()->Rate()); | 1079 data->SetDouble("videoFrameRate", stats->video_frame_rate()->Rate()); |
1061 data->SetDouble("captureLatency", stats->video_capture_ms()->Average()); | 1080 data->SetDouble("captureLatency", stats->video_capture_ms()->Average()); |
1062 data->SetDouble("encodeLatency", stats->video_encode_ms()->Average()); | 1081 data->SetDouble("encodeLatency", stats->video_encode_ms()->Average()); |
1063 data->SetDouble("decodeLatency", stats->video_decode_ms()->Average()); | 1082 data->SetDouble("decodeLatency", stats->video_decode_ms()->Average()); |
1064 data->SetDouble("renderLatency", stats->video_paint_ms()->Average()); | 1083 data->SetDouble("renderLatency", stats->video_paint_ms()->Average()); |
1065 data->SetDouble("roundtripLatency", stats->round_trip_ms()->Average()); | 1084 data->SetDouble("roundtripLatency", stats->round_trip_ms()->Average()); |
1066 PostLegacyJsonMessage("onPerfStats", data.Pass()); | 1085 PostLegacyJsonMessage("onPerfStats", data.Pass()); |
1086 | |
1087 // Upload to UMA the video frame-rate, packet-rate and bandwidth stats, | |
1088 // averaged over 1s. | |
1089 pp::UMAPrivate uma(this); | |
1090 uma.HistogramEnumeration("Chromoting.Video.FrameRate", | |
1091 stats->video_frame_rate()->Rate(), kMaxFrameRate); | |
1092 uma.HistogramEnumeration("Chromoting.Video.PacketRate", | |
1093 stats->video_packet_rate()->Rate(), kMaxFrameRate); | |
rkaplow
2015/07/10 17:41:40
is the max packet rate always same as frame rate?
anandc
2015/07/10 19:37:14
Good point.
They may not always be the same: we e
| |
1094 uma.HistogramCustomCounts("Chromoting.Video.Bandwidth", | |
1095 stats->video_bandwidth()->Rate(), kBandwidthHistogramMin, | |
1096 kBandwidthHistogramMax, kBandwidthHistogramNumBuckets); | |
1067 } | 1097 } |
1068 | 1098 |
1069 // static | 1099 // static |
1070 void ChromotingInstance::RegisterLogMessageHandler() { | 1100 void ChromotingInstance::RegisterLogMessageHandler() { |
1071 base::AutoLock lock(g_logging_lock.Get()); | 1101 base::AutoLock lock(g_logging_lock.Get()); |
1072 | 1102 |
1073 VLOG(1) << "Registering global log handler"; | 1103 VLOG(1) << "Registering global log handler"; |
1074 | 1104 |
1075 // Record previous handler so we can call it in a chain. | 1105 // Record previous handler so we can call it in a chain. |
1076 g_logging_old_handler = logging::GetLogMessageHandler(); | 1106 g_logging_old_handler = logging::GetLogMessageHandler(); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1196 | 1226 |
1197 #if !defined(OS_NACL) | 1227 #if !defined(OS_NACL) |
1198 // Log messages are forwarded to the webapp only in PNaCl version of the | 1228 // Log messages are forwarded to the webapp only in PNaCl version of the |
1199 // plugin, so ProcessLogToUI() needs to be called explicitly in the non-PNaCl | 1229 // plugin, so ProcessLogToUI() needs to be called explicitly in the non-PNaCl |
1200 // version. | 1230 // version. |
1201 ProcessLogToUI(message); | 1231 ProcessLogToUI(message); |
1202 #endif // !defined(OS_NACL) | 1232 #endif // !defined(OS_NACL) |
1203 } | 1233 } |
1204 | 1234 |
1205 } // namespace remoting | 1235 } // namespace remoting |
OLD | NEW |