Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 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 "blimp/common/logging.h" | 5 #include "blimp/common/logging.h" |
| 6 | 6 |
| 7 #include <iostream> | 7 #include <iostream> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <utility> | |
| 9 #include <vector> | 10 #include <vector> |
| 10 | 11 |
| 11 #include "base/format_macros.h" | 12 #include "base/format_macros.h" |
| 12 #include "base/json/string_escape.h" | 13 #include "base/json/string_escape.h" |
| 13 #include "base/lazy_instance.h" | 14 #include "base/lazy_instance.h" |
| 14 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
| 15 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
| 16 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
| 17 #include "base/strings/stringprintf.h" | 18 #include "base/strings/stringprintf.h" |
| 18 #include "blimp/common/create_blimp_message.h" | 19 #include "blimp/common/create_blimp_message.h" |
| 19 #include "blimp/common/proto/blimp_message.pb.h" | 20 #include "blimp/common/proto/blimp_message.pb.h" |
| 20 | 21 |
| 21 namespace blimp { | 22 namespace blimp { |
| 22 namespace { | 23 namespace { |
| 23 | 24 |
| 24 static base::LazyInstance<BlimpMessageLogger> g_logger = | 25 typedef std::vector<std::pair<std::string, std::string>> LogFields; |
|
Wez
2016/06/03 00:07:54
nit: Style-guide says using using instead of typed
Kevin M
2016/06/07 00:05:50
Done.
| |
| 25 LAZY_INSTANCE_INITIALIZER; | |
| 26 | 26 |
| 27 // The AddField() suite of functions are used to convert KV pairs with | 27 // The AddField() suite of functions are used to convert KV pairs with |
| 28 // arbitrarily typed values into string/string KV pairs for logging. | 28 // arbitrarily typed values into string/string KV pairs for logging. |
| 29 | 29 |
| 30 // Specialization for string values, surrounding them with quotes and escaping | 30 // Specialization for string values, surrounding them with quotes and escaping |
| 31 // characters as necessary. | 31 // characters as necessary. |
| 32 void AddField(const std::string& key, | 32 void AddField(const std::string& key, |
| 33 const std::string& value, | 33 const std::string& value, |
| 34 LogFields* output) { | 34 LogFields* output) { |
| 35 std::string escaped_value; | 35 std::string escaped_value; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 62 // Uses std::to_string() to serialize |value|. | 62 // Uses std::to_string() to serialize |value|. |
| 63 template <typename T> | 63 template <typename T> |
| 64 void AddField(const std::string& key, const T& value, LogFields* output) { | 64 void AddField(const std::string& key, const T& value, LogFields* output) { |
| 65 output->push_back(std::make_pair(key, std::to_string(value))); | 65 output->push_back(std::make_pair(key, std::to_string(value))); |
| 66 } | 66 } |
| 67 | 67 |
| 68 // The following LogExtractor subclasses contain logic for extracting loggable | 68 // The following LogExtractor subclasses contain logic for extracting loggable |
| 69 // fields from BlimpMessages. | 69 // fields from BlimpMessages. |
| 70 | 70 |
| 71 // Logs fields from COMPOSITOR messages. | 71 // Logs fields from COMPOSITOR messages. |
| 72 class CompositorLogExtractor : public LogExtractor { | 72 void ExtractCompositorMessageFields(const BlimpMessage& message, |
| 73 void ExtractFields(const BlimpMessage& message, | 73 LogFields* output) { |
| 74 LogFields* output) const override { | 74 AddField("render_widget_id", message.compositor().render_widget_id(), output); |
| 75 AddField("render_widget_id", message.compositor().render_widget_id(), | 75 } |
| 76 | |
| 77 // Logs fields from INPUT messages. | |
| 78 void ExtractInputMessageFields(const BlimpMessage& message, LogFields* output) { | |
| 79 AddField("render_widget_id", message.input().render_widget_id(), output); | |
| 80 AddField("timestamp_seconds", message.input().timestamp_seconds(), output); | |
| 81 switch (message.input().type()) { | |
| 82 case InputMessage::Type_GestureScrollBegin: | |
| 83 AddField("subtype", "GestureScrollBegin", output); | |
| 84 break; | |
| 85 case InputMessage::Type_GestureScrollEnd: | |
| 86 AddField("subtype", "GestureScrollEnd", output); | |
| 87 break; | |
| 88 case InputMessage::Type_GestureScrollUpdate: | |
| 89 AddField("subtype", "GestureScrollUpdate", output); | |
| 90 break; | |
| 91 case InputMessage::Type_GestureFlingStart: | |
| 92 AddField("subtype", "GestureFlingStart", output); | |
| 93 break; | |
| 94 case InputMessage::Type_GestureFlingCancel: | |
| 95 AddField("subtype", "GestureFlingCancel", output); | |
| 96 AddField("prevent_boosting", | |
| 97 message.input().gesture_fling_cancel().prevent_boosting(), | |
| 98 output); | |
| 99 break; | |
| 100 case InputMessage::Type_GestureTap: | |
| 101 AddField("subtype", "GestureTap", output); | |
| 102 break; | |
| 103 case InputMessage::Type_GesturePinchBegin: | |
| 104 AddField("subtype", "GesturePinchBegin", output); | |
| 105 break; | |
| 106 case InputMessage::Type_GesturePinchEnd: | |
| 107 AddField("subtype", "GesturePinchEnd", output); | |
| 108 break; | |
| 109 case InputMessage::Type_GesturePinchUpdate: | |
| 110 AddField("subtype", "GesturePinchUpdate", output); | |
| 111 break; | |
| 112 default: // unknown | |
|
Wez
2016/06/03 00:07:54
Replace the default's, here and below, with explic
Kevin M
2016/06/07 00:05:50
Done.
| |
| 113 break; | |
| 114 } | |
| 115 } | |
| 116 | |
| 117 // Logs fields from NAVIGATION messages. | |
| 118 void ExtractNavigationMessageFields(const BlimpMessage& message, | |
| 119 LogFields* output) { | |
| 120 switch (message.navigation().type()) { | |
| 121 case NavigationMessage::NAVIGATION_STATE_CHANGED: | |
| 122 AddField("subtype", "NAVIGATION_STATE_CHANGED", output); | |
| 123 if (message.navigation().navigation_state_changed().has_url()) { | |
| 124 AddField("url", message.navigation().navigation_state_changed().url(), | |
| 125 output); | |
| 126 } | |
| 127 if (message.navigation().navigation_state_changed().has_favicon()) { | |
| 128 AddField( | |
| 129 "favicon_size", | |
| 130 message.navigation().navigation_state_changed().favicon().size(), | |
| 131 output); | |
| 132 } | |
| 133 if (message.navigation().navigation_state_changed().has_title()) { | |
| 134 AddField("title", | |
| 135 message.navigation().navigation_state_changed().title(), | |
| 136 output); | |
| 137 } | |
| 138 if (message.navigation().navigation_state_changed().has_loading()) { | |
| 139 AddField("loading", | |
| 140 message.navigation().navigation_state_changed().loading(), | |
| 141 output); | |
| 142 } | |
| 143 break; | |
| 144 case NavigationMessage::LOAD_URL: | |
| 145 AddField("subtype", "LOAD_URL", output); | |
| 146 AddField("url", message.navigation().load_url().url(), output); | |
| 147 break; | |
| 148 case NavigationMessage::GO_BACK: | |
| 149 AddField("subtype", "GO_BACK", output); | |
| 150 break; | |
| 151 case NavigationMessage::GO_FORWARD: | |
| 152 AddField("subtype", "GO_FORWARD", output); | |
| 153 break; | |
| 154 case NavigationMessage::RELOAD: | |
| 155 AddField("subtype", "RELOAD", output); | |
| 156 break; | |
| 157 default: | |
| 158 break; | |
| 159 } | |
| 160 } | |
| 161 | |
| 162 // Logs fields from PROTOCOL_CONTROL messages. | |
| 163 void ExtractProtocolControlMessageFields(const BlimpMessage& message, | |
| 164 LogFields* output) { | |
| 165 switch (message.protocol_control().connection_message_case()) { | |
| 166 case ProtocolControlMessage::kStartConnection: | |
| 167 AddField("subtype", "START_CONNECTION", output); | |
| 168 AddField("client_token", | |
| 169 message.protocol_control().start_connection().client_token(), | |
| 170 output); | |
| 171 AddField("protocol_version", | |
| 172 message.protocol_control().start_connection().protocol_version(), | |
| 173 output); | |
| 174 break; | |
| 175 case ProtocolControlMessage::kCheckpointAck: | |
| 176 AddField("subtype", "CHECKPOINT_ACK", output); | |
| 177 AddField("checkpoint_id", | |
| 178 message.protocol_control().checkpoint_ack().checkpoint_id(), | |
| 179 output); | |
| 180 break; | |
| 181 default: | |
| 182 break; | |
| 183 } | |
| 184 } | |
| 185 | |
| 186 // Logs fields from RENDER_WIDGET messages. | |
| 187 void ExtractRenderWidgetMessageFields(const BlimpMessage& message, | |
| 188 LogFields* output) { | |
| 189 switch (message.render_widget().type()) { | |
| 190 case RenderWidgetMessage::INITIALIZE: | |
| 191 AddField("subtype", "INITIALIZE", output); | |
| 192 break; | |
| 193 case RenderWidgetMessage::CREATED: | |
| 194 AddField("subtype", "CREATED", output); | |
| 195 break; | |
| 196 case RenderWidgetMessage::DELETED: | |
| 197 AddField("subtype", "DELETED", output); | |
| 198 break; | |
| 199 } | |
| 200 AddField("render_widget_id", message.render_widget().render_widget_id(), | |
| 201 output); | |
| 202 } | |
| 203 | |
| 204 // Logs fields from SETTINGS messages. | |
| 205 void ExtractSettingsMessageFields(const BlimpMessage& message, | |
| 206 LogFields* output) { | |
| 207 if (message.settings().has_engine_settings()) { | |
| 208 const EngineSettingsMessage& engine_settings = | |
| 209 message.settings().engine_settings(); | |
| 210 AddField("subtype", "ENGINE_SETTINGS", output); | |
| 211 AddField("record_whole_document", engine_settings.record_whole_document(), | |
| 76 output); | 212 output); |
| 77 } | 213 AddField("client_os_info", engine_settings.client_os_info(), output); |
| 78 }; | 214 } |
| 79 | 215 } |
| 80 // Logs fields from INPUT messages. | |
| 81 class InputLogExtractor : public LogExtractor { | |
| 82 void ExtractFields(const BlimpMessage& message, | |
| 83 LogFields* output) const override { | |
| 84 AddField("render_widget_id", message.input().render_widget_id(), output); | |
| 85 AddField("timestamp_seconds", message.input().timestamp_seconds(), output); | |
| 86 switch (message.input().type()) { | |
| 87 case InputMessage::Type_GestureScrollBegin: | |
| 88 AddField("subtype", "GestureScrollBegin", output); | |
| 89 break; | |
| 90 case InputMessage::Type_GestureScrollEnd: | |
| 91 AddField("subtype", "GestureScrollEnd", output); | |
| 92 break; | |
| 93 case InputMessage::Type_GestureScrollUpdate: | |
| 94 AddField("subtype", "GestureScrollUpdate", output); | |
| 95 break; | |
| 96 case InputMessage::Type_GestureFlingStart: | |
| 97 AddField("subtype", "GestureFlingStart", output); | |
| 98 break; | |
| 99 case InputMessage::Type_GestureFlingCancel: | |
| 100 AddField("subtype", "GestureFlingCancel", output); | |
| 101 AddField("prevent_boosting", | |
| 102 message.input().gesture_fling_cancel().prevent_boosting(), | |
| 103 output); | |
| 104 break; | |
| 105 case InputMessage::Type_GestureTap: | |
| 106 AddField("subtype", "GestureTap", output); | |
| 107 break; | |
| 108 case InputMessage::Type_GesturePinchBegin: | |
| 109 AddField("subtype", "GesturePinchBegin", output); | |
| 110 break; | |
| 111 case InputMessage::Type_GesturePinchEnd: | |
| 112 AddField("subtype", "GesturePinchEnd", output); | |
| 113 break; | |
| 114 case InputMessage::Type_GesturePinchUpdate: | |
| 115 AddField("subtype", "GesturePinchUpdate", output); | |
| 116 break; | |
| 117 default: // unknown | |
| 118 break; | |
| 119 } | |
| 120 } | |
| 121 }; | |
| 122 | |
| 123 // Logs fields from NAVIGATION messages. | |
| 124 class NavigationLogExtractor : public LogExtractor { | |
| 125 void ExtractFields(const BlimpMessage& message, | |
| 126 LogFields* output) const override { | |
| 127 switch (message.navigation().type()) { | |
| 128 case NavigationMessage::NAVIGATION_STATE_CHANGED: | |
| 129 AddField("subtype", "NAVIGATION_STATE_CHANGED", output); | |
| 130 if (message.navigation().navigation_state_changed().has_url()) { | |
| 131 AddField("url", message.navigation().navigation_state_changed().url(), | |
| 132 output); | |
| 133 } | |
| 134 if (message.navigation().navigation_state_changed().has_favicon()) { | |
| 135 AddField( | |
| 136 "favicon_size", | |
| 137 message.navigation().navigation_state_changed().favicon().size(), | |
| 138 output); | |
| 139 } | |
| 140 if (message.navigation().navigation_state_changed().has_title()) { | |
| 141 AddField("title", | |
| 142 message.navigation().navigation_state_changed().title(), | |
| 143 output); | |
| 144 } | |
| 145 if (message.navigation().navigation_state_changed().has_loading()) { | |
| 146 AddField("loading", | |
| 147 message.navigation().navigation_state_changed().loading(), | |
| 148 output); | |
| 149 } | |
| 150 break; | |
| 151 case NavigationMessage::LOAD_URL: | |
| 152 AddField("subtype", "LOAD_URL", output); | |
| 153 AddField("url", message.navigation().load_url().url(), output); | |
| 154 break; | |
| 155 case NavigationMessage::GO_BACK: | |
| 156 AddField("subtype", "GO_BACK", output); | |
| 157 break; | |
| 158 case NavigationMessage::GO_FORWARD: | |
| 159 AddField("subtype", "GO_FORWARD", output); | |
| 160 break; | |
| 161 case NavigationMessage::RELOAD: | |
| 162 AddField("subtype", "RELOAD", output); | |
| 163 break; | |
| 164 default: | |
| 165 break; | |
| 166 } | |
| 167 } | |
| 168 }; | |
| 169 | |
| 170 // Logs fields from PROTOCOL_CONTROL messages. | |
| 171 class ProtocolControlLogExtractor : public LogExtractor { | |
| 172 void ExtractFields(const BlimpMessage& message, | |
| 173 LogFields* output) const override { | |
| 174 switch (message.protocol_control().connection_message_case()) { | |
| 175 case ProtocolControlMessage::kStartConnection: | |
| 176 AddField("subtype", "START_CONNECTION", output); | |
| 177 AddField("client_token", | |
| 178 message.protocol_control().start_connection().client_token(), | |
| 179 output); | |
| 180 AddField( | |
| 181 "protocol_version", | |
| 182 message.protocol_control().start_connection().protocol_version(), | |
| 183 output); | |
| 184 break; | |
| 185 case ProtocolControlMessage::kCheckpointAck: | |
| 186 AddField("subtype", "CHECKPOINT_ACK", output); | |
| 187 AddField("checkpoint_id", | |
| 188 message.protocol_control().checkpoint_ack().checkpoint_id(), | |
| 189 output); | |
| 190 break; | |
| 191 default: | |
| 192 break; | |
| 193 } | |
| 194 } | |
| 195 }; | |
| 196 | |
| 197 // Logs fields from RENDER_WIDGET messages. | |
| 198 class RenderWidgetLogExtractor : public LogExtractor { | |
| 199 void ExtractFields(const BlimpMessage& message, | |
| 200 LogFields* output) const override { | |
| 201 switch (message.render_widget().type()) { | |
| 202 case RenderWidgetMessage::INITIALIZE: | |
| 203 AddField("subtype", "INITIALIZE", output); | |
| 204 break; | |
| 205 case RenderWidgetMessage::CREATED: | |
| 206 AddField("subtype", "CREATED", output); | |
| 207 break; | |
| 208 case RenderWidgetMessage::DELETED: | |
| 209 AddField("subtype", "DELETED", output); | |
| 210 break; | |
| 211 } | |
| 212 AddField("render_widget_id", message.render_widget().render_widget_id(), | |
| 213 output); | |
| 214 } | |
| 215 }; | |
| 216 | |
| 217 // Logs fields from SETTINGS messages. | |
| 218 class SettingsLogExtractor : public LogExtractor { | |
| 219 void ExtractFields(const BlimpMessage& message, | |
| 220 LogFields* output) const override { | |
| 221 if (message.settings().has_engine_settings()) { | |
| 222 const EngineSettingsMessage& engine_settings = | |
| 223 message.settings().engine_settings(); | |
| 224 AddField("subtype", "ENGINE_SETTINGS", output); | |
| 225 AddField("record_whole_document", engine_settings.record_whole_document(), | |
| 226 output); | |
| 227 AddField("client_os_info", engine_settings.client_os_info(), output); | |
| 228 } | |
| 229 } | |
| 230 }; | |
| 231 | 216 |
| 232 // Logs fields from TAB_CONTROL messages. | 217 // Logs fields from TAB_CONTROL messages. |
| 233 class TabControlLogExtractor : public LogExtractor { | 218 void ExtractTabControlMessageFields(const BlimpMessage& message, |
| 234 void ExtractFields(const BlimpMessage& message, | 219 LogFields* output) { |
| 235 LogFields* output) const override { | 220 switch (message.tab_control().tab_control_case()) { |
| 236 switch (message.tab_control().tab_control_case()) { | 221 case TabControlMessage::kCreateTab: |
| 237 case TabControlMessage::kCreateTab: | 222 AddField("subtype", "CREATE_TAB", output); |
| 238 AddField("subtype", "CREATE_TAB", output); | 223 break; |
| 239 break; | 224 case TabControlMessage::kCloseTab: |
| 240 case TabControlMessage::kCloseTab: | 225 AddField("subtype", "CLOSE_TAB", output); |
| 241 AddField("subtype", "CLOSE_TAB", output); | 226 break; |
| 242 break; | 227 case TabControlMessage::kSize: |
| 243 case TabControlMessage::kSize: | 228 AddField("subtype", "SIZE", output); |
| 244 AddField("subtype", "SIZE", output); | 229 AddField("size", message.tab_control().size(), output); |
| 245 AddField("size", message.tab_control().size(), output); | 230 break; |
| 246 break; | 231 default: // unknown |
| 247 default: // unknown | 232 break; |
| 248 break; | 233 } |
| 249 } | 234 } |
| 250 } | |
| 251 }; | |
| 252 | 235 |
| 253 // Logs fields from BLOB_CHANNEL messages. | 236 // Logs fields from BLOB_CHANNEL messages. |
| 254 class BlobChannelLogExtractor : public LogExtractor { | 237 void ExtractBlobChannelMessageFields(const BlimpMessage& message, |
| 255 void ExtractFields(const BlimpMessage& message, | 238 LogFields* output) { |
| 256 LogFields* output) const override { | 239 switch (message.blob_channel().type_case()) { |
| 257 switch (message.blob_channel().type_case()) { | 240 case BlobChannelMessage::TypeCase::kTransferBlob: |
| 258 case BlobChannelMessage::TypeCase::kTransferBlob: | 241 AddField("subtype", "TRANSFER_BLOB", output); |
| 259 AddField("subtype", "TRANSFER_BLOB", output); | 242 AddField("id", |
| 260 AddField("id", | 243 base::HexEncode( |
| 261 base::HexEncode( | 244 message.blob_channel().transfer_blob().blob_id().data(), |
| 262 message.blob_channel().transfer_blob().blob_id().data(), | 245 message.blob_channel().transfer_blob().blob_id().size()), |
| 263 message.blob_channel().transfer_blob().blob_id().size()), | 246 output); |
| 264 output); | 247 AddField("payload_size", |
| 265 AddField("payload_size", | 248 message.blob_channel().transfer_blob().payload().size(), output); |
| 266 message.blob_channel().transfer_blob().payload().size(), | 249 break; |
| 267 output); | 250 case BlobChannelMessage::TypeCase::TYPE_NOT_SET: // unknown |
| 268 break; | 251 break; |
| 269 case BlobChannelMessage::TypeCase::TYPE_NOT_SET: // unknown | 252 } |
| 270 break; | 253 } |
| 271 } | |
| 272 } | |
| 273 }; | |
| 274 | |
| 275 // No fields are extracted from |message|. | |
| 276 class NullLogExtractor : public LogExtractor { | |
| 277 void ExtractFields(const BlimpMessage& message, | |
| 278 LogFields* output) const override {} | |
| 279 }; | |
| 280 | 254 |
| 281 } // namespace | 255 } // namespace |
| 282 | 256 |
| 283 BlimpMessageLogger::BlimpMessageLogger() { | 257 std::ostream& operator<<(std::ostream& out, const BlimpMessage& message) { |
| 284 AddHandler("COMPOSITOR", BlimpMessage::kCompositor, | |
| 285 base::WrapUnique(new CompositorLogExtractor)); | |
| 286 AddHandler("INPUT", BlimpMessage::kInput, | |
| 287 base::WrapUnique(new InputLogExtractor)); | |
| 288 AddHandler("NAVIGATION", BlimpMessage::kNavigation, | |
| 289 base::WrapUnique(new NavigationLogExtractor)); | |
| 290 AddHandler("PROTOCOL_CONTROL", BlimpMessage::kProtocolControl, | |
| 291 base::WrapUnique(new ProtocolControlLogExtractor)); | |
| 292 AddHandler("RENDER_WIDGET", BlimpMessage::kRenderWidget, | |
| 293 base::WrapUnique(new RenderWidgetLogExtractor)); | |
| 294 AddHandler("SETTINGS", BlimpMessage::kSettings, | |
| 295 base::WrapUnique(new SettingsLogExtractor)); | |
| 296 AddHandler("TAB_CONTROL", BlimpMessage::kTabControl, | |
| 297 base::WrapUnique(new TabControlLogExtractor)); | |
| 298 AddHandler("BLOB_CHANNEL", BlimpMessage::kBlobChannel, | |
| 299 base::WrapUnique(new BlobChannelLogExtractor)); | |
| 300 } | |
| 301 | |
| 302 BlimpMessageLogger::~BlimpMessageLogger() {} | |
| 303 | |
| 304 void BlimpMessageLogger::AddHandler(const std::string& feature_name, | |
| 305 BlimpMessage::FeatureCase feature_case, | |
| 306 std::unique_ptr<LogExtractor> extractor) { | |
| 307 DCHECK(extractors_.find(feature_case) == extractors_.end()); | |
| 308 DCHECK(!feature_name.empty()); | |
| 309 extractors_[feature_case] = make_pair(feature_name, std::move(extractor)); | |
| 310 } | |
| 311 | |
| 312 void BlimpMessageLogger::LogMessageToStream(const BlimpMessage& message, | |
| 313 std::ostream* out) const { | |
| 314 LogFields fields; | 258 LogFields fields; |
| 315 | 259 |
| 316 auto extractor = extractors_.find(message.feature_case()); | 260 switch (message.feature_case()) { |
| 317 if (extractor != extractors_.end()) { | 261 case BlimpMessage::kCompositor: |
| 318 // An extractor is registered for |message|. | 262 fields.push_back(std::make_pair("type", "COMPOSITOR")); |
|
Wez
2016/06/03 00:07:54
What was wrong with AddField() here? Seems shorter
Kevin M
2016/06/07 00:05:50
Done.
| |
| 319 // Add the human-readable name of |message.type|. | 263 ExtractCompositorMessageFields(message, &fields); |
| 320 fields.push_back(make_pair("type", extractor->second.first)); | 264 break; |
| 321 extractor->second.second->ExtractFields(message, &fields); | 265 case BlimpMessage::kInput: |
| 322 } else { | 266 fields.push_back(std::make_pair("type", "INPUT")); |
| 323 // Don't know the human-readable name of |message.type|. | 267 ExtractInputMessageFields(message, &fields); |
| 324 // Just represent it using its numeric form instead. | 268 break; |
| 325 AddField("type", message.feature_case(), &fields); | 269 case BlimpMessage::kNavigation: |
| 270 fields.push_back(std::make_pair("type", "NAVIGATION")); | |
| 271 ExtractNavigationMessageFields(message, &fields); | |
| 272 break; | |
| 273 case BlimpMessage::kProtocolControl: | |
| 274 fields.push_back(std::make_pair("type", "PROTOCOL_CONTROL")); | |
| 275 ExtractProtocolControlMessageFields(message, &fields); | |
| 276 break; | |
| 277 case BlimpMessage::kRenderWidget: | |
| 278 fields.push_back(std::make_pair("type", "RENDER_WIDGET")); | |
| 279 ExtractRenderWidgetMessageFields(message, &fields); | |
| 280 break; | |
| 281 case BlimpMessage::kSettings: | |
| 282 fields.push_back(std::make_pair("type", "SETTINGS")); | |
| 283 ExtractSettingsMessageFields(message, &fields); | |
| 284 break; | |
| 285 case BlimpMessage::kTabControl: | |
| 286 fields.push_back(std::make_pair("type", "TAB_CONTROL")); | |
| 287 ExtractTabControlMessageFields(message, &fields); | |
| 288 break; | |
| 289 case BlimpMessage::kBlobChannel: | |
| 290 fields.push_back(std::make_pair("type", "BLOB_CHANNEL")); | |
| 291 ExtractBlobChannelMessageFields(message, &fields); | |
| 292 break; | |
| 293 case BlimpMessage::kIme: | |
| 294 fields.push_back(std::make_pair("type", "IME")); | |
| 295 break; | |
| 296 case BlimpMessage::FEATURE_NOT_SET: | |
| 297 fields.push_back(std::make_pair("type", "<UNKNOWN>")); | |
|
Wez
2016/06/03 00:07:54
Off-topic: This is an interesting limitation of us
Kevin M
2016/06/07 00:05:50
Yeah, there's no analogue to unknown_fields :(
| |
| 298 break; | |
| 326 } | 299 } |
| 327 | 300 |
| 328 // Append "target_tab_id" (if present) and "byte_size" to the field set. | 301 // Append "target_tab_id" (if present) and "byte_size" to the field set. |
| 329 if (message.has_target_tab_id()) { | 302 if (message.has_target_tab_id()) { |
| 330 AddField("target_tab_id", message.target_tab_id(), &fields); | 303 AddField("target_tab_id", message.target_tab_id(), &fields); |
| 331 } | 304 } |
| 332 AddField("byte_size", message.ByteSize(), &fields); | 305 AddField("byte_size", message.ByteSize(), &fields); |
| 333 | 306 |
| 334 // Format message using the syntax: | 307 // Format message using the syntax: |
| 335 // <BlimpMessage field1=value1 field2="value 2"> | 308 // <BlimpMessage field1=value1 field2="value 2"> |
| 336 *out << "<BlimpMessage "; | 309 out << "<BlimpMessage "; |
| 337 for (size_t i = 0; i < fields.size(); ++i) { | 310 for (size_t i = 0; i < fields.size(); ++i) { |
| 338 *out << fields[i].first << "=" << fields[i].second | 311 out << fields[i].first << "=" << fields[i].second |
| 339 << (i != fields.size() - 1 ? " " : ""); | 312 << (i != fields.size() - 1 ? " " : ""); |
| 340 } | 313 } |
| 341 *out << ">"; | 314 out << ">"; |
| 342 } | |
| 343 | 315 |
| 344 std::ostream& operator<<(std::ostream& out, const BlimpMessage& message) { | |
| 345 g_logger.Get().LogMessageToStream(message, &out); | |
| 346 return out; | 316 return out; |
| 347 } | 317 } |
| 348 | 318 |
| 349 } // namespace blimp | 319 } // namespace blimp |
| OLD | NEW |