Chromium Code Reviews| 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. | |
|
Wez
2015/07/08 23:42:29
Why not? Where does the 40fps come from? What happ
anandc
2015/07/09 19:17:10
The 40fps came from our expected happy-path scenar
| |
| 76 // Histograms expect samples to be less than the boundary value, so set to 41. | |
| 77 const int kMaxFrameRate = 41; | |
|
Wez
2015/07/08 23:42:29
nit: Blank line after this.
anandc
2015/07/09 19:17:10
Done.
| |
| 78 // For bandwidth, we'll use a histogram ranging from 0 to 1MB/s, spread across | |
|
Wez
2015/07/08 23:42:29
Why is 1MB/s the maximum?
anandc
2015/07/09 19:17:10
Added clarification.
| |
| 79 // 1000 buckets. | |
| 80 // Histograms are log-scaled by default. This results in fine-grained buckets at | |
| 81 // lower values and wider-ranged buckets closer to the maximum. | |
| 82 // Values above the maximum defined here end up in the right-most bucket. | |
| 83 // See $/src/base/metrics/histogram.h for more details. | |
| 84 const int kBandwidthHistogramMin = 1; | |
| 85 const int kBandwidthHistogramMax = 1024000; | |
| 86 const int kBandwidthHistogramNumBuckets = 1000; | |
| 87 | |
| 88 // For the latency metrics, we'll set the max histogram value to 20,000ms, split | |
| 89 // over 1000 buckets. | |
|
Wez
2015/07/08 23:42:29
Again, explain why these numbers were chosen?
anandc
2015/07/09 19:17:10
Removed from this CL.
| |
| 90 const int kLatencyHistogramMin = 1; | |
| 91 const int kLatencyHistogramMax = 20000; | |
| 92 const int kLatencyHistogramNumBuckets = 1000; | |
| 93 | |
| 76 #if defined(USE_OPENSSL) | 94 #if defined(USE_OPENSSL) |
| 77 // Size of the random seed blob used to initialize RNG in libjingle. Libjingle | 95 // 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 | 96 // 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 | 97 // 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. | 98 // 1039 bytes of state, so we initialize it with 1k or random data. |
| 81 const int kRandomSeedSize = 1024; | 99 const int kRandomSeedSize = 1024; |
| 82 #endif // defined(USE_OPENSSL) | 100 #endif // defined(USE_OPENSSL) |
| 83 | 101 |
| 84 std::string ConnectionStateToString(protocol::ConnectionToHost::State state) { | 102 std::string ConnectionStateToString(protocol::ConnectionToHost::State state) { |
| 85 // Values returned by this function must match the | 103 // 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)); | 739 host_public_key)); |
| 722 scoped_ptr<protocol::Authenticator> authenticator( | 740 scoped_ptr<protocol::Authenticator> authenticator( |
| 723 new protocol::NegotiatingClientAuthenticator( | 741 new protocol::NegotiatingClientAuthenticator( |
| 724 client_pairing_id, client_paired_secret, authentication_tag, | 742 client_pairing_id, client_paired_secret, authentication_tag, |
| 725 fetch_secret_callback, token_fetcher.Pass(), auth_methods)); | 743 fetch_secret_callback, token_fetcher.Pass(), auth_methods)); |
| 726 | 744 |
| 727 // Kick off the connection. | 745 // Kick off the connection. |
| 728 client_->Start(signal_strategy_.get(), authenticator.Pass(), | 746 client_->Start(signal_strategy_.get(), authenticator.Pass(), |
| 729 transport_factory.Pass(), host_jid, capabilities); | 747 transport_factory.Pass(), host_jid, capabilities); |
| 730 | 748 |
| 731 // Start timer that periodically sends perf stats. | 749 // Start timers that periodically send perf stats, for display and for UMA. |
| 732 plugin_task_runner_->PostDelayedTask( | 750 plugin_task_runner_->PostDelayedTask( |
| 733 FROM_HERE, base::Bind(&ChromotingInstance::SendPerfStats, | 751 FROM_HERE, base::Bind(&ChromotingInstance::SendDisplayPerfStats, |
| 734 weak_factory_.GetWeakPtr()), | 752 weak_factory_.GetWeakPtr()), |
| 735 base::TimeDelta::FromMilliseconds(kPerfStatsIntervalMs)); | 753 base::TimeDelta::FromSeconds( |
| 754 video_renderer_->GetStats()->kDisplayStatsUpdateWindowInSeconds)); | |
|
Wez
2015/07/08 23:42:29
This is a constant, not a member, so you can just
anandc
2015/07/09 19:17:10
Done.
| |
| 755 plugin_task_runner_->PostDelayedTask( | |
| 756 FROM_HERE, base::Bind(&ChromotingInstance::SendUMAPerfStats, | |
| 757 weak_factory_.GetWeakPtr()), | |
| 758 base::TimeDelta::FromSeconds( | |
| 759 video_renderer_->GetStats()->kUMAStatsTimeWindowInSeconds)); | |
| 736 } | 760 } |
| 737 | 761 |
| 738 void ChromotingInstance::HandleDisconnect(const base::DictionaryValue& data) { | 762 void ChromotingInstance::HandleDisconnect(const base::DictionaryValue& data) { |
| 739 DCHECK(plugin_task_runner_->BelongsToCurrentThread()); | 763 DCHECK(plugin_task_runner_->BelongsToCurrentThread()); |
| 740 Disconnect(); | 764 Disconnect(); |
| 741 } | 765 } |
| 742 | 766 |
| 743 void ChromotingInstance::HandleOnIncomingIq(const base::DictionaryValue& data) { | 767 void ChromotingInstance::HandleOnIncomingIq(const base::DictionaryValue& data) { |
| 744 std::string iq; | 768 std::string iq; |
| 745 if (!data.GetString("iq", &iq)) { | 769 if (!data.GetString("iq", &iq)) { |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1037 data->SetBoolean("pressed", pressed); | 1061 data->SetBoolean("pressed", pressed); |
| 1038 PostLegacyJsonMessage("trappedKeyEvent", data.Pass()); | 1062 PostLegacyJsonMessage("trappedKeyEvent", data.Pass()); |
| 1039 } | 1063 } |
| 1040 | 1064 |
| 1041 void ChromotingInstance::SendOutgoingIq(const std::string& iq) { | 1065 void ChromotingInstance::SendOutgoingIq(const std::string& iq) { |
| 1042 scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue()); | 1066 scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue()); |
| 1043 data->SetString("iq", iq); | 1067 data->SetString("iq", iq); |
| 1044 PostLegacyJsonMessage("sendOutgoingIq", data.Pass()); | 1068 PostLegacyJsonMessage("sendOutgoingIq", data.Pass()); |
| 1045 } | 1069 } |
| 1046 | 1070 |
| 1047 void ChromotingInstance::SendPerfStats() { | 1071 void ChromotingInstance::SendDisplayPerfStats() { |
| 1048 if (!video_renderer_.get()) { | 1072 if (!video_renderer_.get()) { |
| 1049 return; | 1073 return; |
| 1050 } | 1074 } |
| 1051 | 1075 |
| 1052 plugin_task_runner_->PostDelayedTask( | 1076 plugin_task_runner_->PostDelayedTask( |
| 1053 FROM_HERE, base::Bind(&ChromotingInstance::SendPerfStats, | 1077 FROM_HERE, base::Bind(&ChromotingInstance::SendDisplayPerfStats, |
| 1054 weak_factory_.GetWeakPtr()), | 1078 weak_factory_.GetWeakPtr()), |
| 1055 base::TimeDelta::FromMilliseconds(kPerfStatsIntervalMs)); | 1079 base::TimeDelta::FromSeconds( |
| 1080 ChromotingStats::kDisplayStatsUpdateWindowInSeconds)); | |
| 1056 | 1081 |
| 1082 // Update performance stats, averaged over the past few seconds. | |
| 1083 // These are eventually upstreamed to the client and available for display to | |
| 1084 // the user. | |
|
Wez
2015/07/08 23:42:29
This is very vague... why "eventually", and what d
anandc
2015/07/09 19:17:10
Thanks. PTAL at latest comment.
| |
| 1057 scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue()); | 1085 scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue()); |
| 1058 ChromotingStats* stats = video_renderer_->GetStats(); | 1086 ChromotingStats* stats = video_renderer_->GetStats(); |
| 1059 data->SetDouble("videoBandwidth", stats->video_bandwidth()->Rate()); | 1087 data->SetDouble("videoBandwidth", stats->video_bandwidth_display()->Rate()); |
| 1060 data->SetDouble("videoFrameRate", stats->video_frame_rate()->Rate()); | 1088 data->SetDouble("videoFrameRate", stats->video_frame_rate_display()->Rate()); |
| 1061 data->SetDouble("captureLatency", stats->video_capture_ms()->Average()); | 1089 data->SetDouble("captureLatency", stats->video_capture_ms()->Average()); |
| 1062 data->SetDouble("encodeLatency", stats->video_encode_ms()->Average()); | 1090 data->SetDouble("encodeLatency", stats->video_encode_ms()->Average()); |
| 1063 data->SetDouble("decodeLatency", stats->video_decode_ms()->Average()); | 1091 data->SetDouble("decodeLatency", stats->video_decode_ms()->Average()); |
| 1064 data->SetDouble("renderLatency", stats->video_paint_ms()->Average()); | 1092 data->SetDouble("renderLatency", stats->video_paint_ms()->Average()); |
| 1065 data->SetDouble("roundtripLatency", stats->round_trip_ms()->Average()); | 1093 data->SetDouble("roundtripLatency", stats->round_trip_ms()->Average()); |
| 1066 PostLegacyJsonMessage("onPerfStats", data.Pass()); | 1094 PostLegacyJsonMessage("onPerfStats", data.Pass()); |
| 1067 } | 1095 } |
| 1068 | 1096 |
| 1097 void ChromotingInstance::SendUMAPerfStats() { | |
| 1098 if (!video_renderer_.get()) { | |
| 1099 return; | |
| 1100 } | |
| 1101 | |
| 1102 plugin_task_runner_->PostDelayedTask( | |
| 1103 FROM_HERE, base::Bind(&ChromotingInstance::SendUMAPerfStats, | |
| 1104 weak_factory_.GetWeakPtr()), | |
| 1105 base::TimeDelta::FromSeconds( | |
| 1106 ChromotingStats::kUMAStatsTimeWindowInSeconds)); | |
| 1107 | |
| 1108 // Update UMA histograms for video frame-rate, bandwidth and latencies. | |
| 1109 // These metrics will be averaged over the last second. | |
|
Wez
2015/07/08 23:42:29
Will be averaged by whom...? The UMA APIs average
anandc
2015/07/09 19:17:09
Yes, we are averaging them. Clarified.
| |
| 1110 ChromotingStats* stats = video_renderer_->GetStats(); | |
| 1111 pp::UMAPrivate uma(this); | |
| 1112 uma.HistogramEnumeration("Chromoting.Video.FrameRate", | |
| 1113 stats->video_frame_rate_uma()->Rate(), kMaxFrameRate); | |
| 1114 uma.HistogramEnumeration("Chromoting.Video.PacketRate", | |
| 1115 stats->video_packet_rate_uma()->Rate(), kMaxFrameRate); | |
| 1116 uma.HistogramCustomCounts("Chromoting.Video.Bandwidth", | |
| 1117 stats->video_bandwidth_uma()->Rate(), kBandwidthHistogramMin, | |
| 1118 kBandwidthHistogramMax, kBandwidthHistogramNumBuckets); | |
| 1119 uma.HistogramCustomTimes("Chromoting.Video.CaptureLatency", | |
|
Wez
2015/07/08 23:42:29
nit: This isn't a latency, it's the time taken to
anandc
2015/07/09 19:17:09
You are correct. The latency metrics, if uploaded
| |
| 1120 stats->video_capture_ms()->Average(), kLatencyHistogramMin, | |
| 1121 kLatencyHistogramMax, kLatencyHistogramNumBuckets); | |
| 1122 uma.HistogramCustomTimes("Chromoting.Video.EncodeLatency", | |
| 1123 stats->video_encode_ms()->Average(), kLatencyHistogramMin, | |
| 1124 kLatencyHistogramMax, kLatencyHistogramNumBuckets); | |
| 1125 uma.HistogramCustomTimes("Chromoting.Video.RoundTripLatency", | |
| 1126 stats->round_trip_ms()->Average(), kLatencyHistogramMin, | |
| 1127 kLatencyHistogramMax, kLatencyHistogramNumBuckets); | |
| 1128 } | |
| 1129 | |
| 1069 // static | 1130 // static |
| 1070 void ChromotingInstance::RegisterLogMessageHandler() { | 1131 void ChromotingInstance::RegisterLogMessageHandler() { |
| 1071 base::AutoLock lock(g_logging_lock.Get()); | 1132 base::AutoLock lock(g_logging_lock.Get()); |
| 1072 | 1133 |
| 1073 VLOG(1) << "Registering global log handler"; | 1134 VLOG(1) << "Registering global log handler"; |
| 1074 | 1135 |
| 1075 // Record previous handler so we can call it in a chain. | 1136 // Record previous handler so we can call it in a chain. |
| 1076 g_logging_old_handler = logging::GetLogMessageHandler(); | 1137 g_logging_old_handler = logging::GetLogMessageHandler(); |
| 1077 | 1138 |
| 1078 // Set up log message handler. | 1139 // Set up log message handler. |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1196 | 1257 |
| 1197 #if !defined(OS_NACL) | 1258 #if !defined(OS_NACL) |
| 1198 // Log messages are forwarded to the webapp only in PNaCl version of the | 1259 // 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 | 1260 // plugin, so ProcessLogToUI() needs to be called explicitly in the non-PNaCl |
| 1200 // version. | 1261 // version. |
| 1201 ProcessLogToUI(message); | 1262 ProcessLogToUI(message); |
| 1202 #endif // !defined(OS_NACL) | 1263 #endif // !defined(OS_NACL) |
| 1203 } | 1264 } |
| 1204 | 1265 |
| 1205 } // namespace remoting | 1266 } // namespace remoting |
| OLD | NEW |