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 "content/browser/media/media_internals.h" | 5 #include "content/browser/media/media_internals.h" |
6 | 6 |
7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
8 #include "base/strings/string16.h" | 8 #include "base/strings/string16.h" |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 void Observe(int type, | 257 void Observe(int type, |
258 const NotificationSource& source, | 258 const NotificationSource& source, |
259 const NotificationDetails& details) override; | 259 const NotificationDetails& details) override; |
260 | 260 |
261 // Reports the pipeline status to UMA for every player | 261 // Reports the pipeline status to UMA for every player |
262 // associated with the renderer process and then deletes the player state. | 262 // associated with the renderer process and then deletes the player state. |
263 void LogAndClearPlayersInRenderer(int render_process_id); | 263 void LogAndClearPlayersInRenderer(int render_process_id); |
264 | 264 |
265 // Helper function to save the event payload to RendererPlayerMap. | 265 // Helper function to save the event payload to RendererPlayerMap. |
266 void SavePlayerState(const media::MediaLogEvent& event, | 266 void SavePlayerState(const media::MediaLogEvent& event, |
| 267 const base::string16& event_serialized, |
267 int render_process_id); | 268 int render_process_id); |
268 | 269 |
| 270 std::vector<base::string16> GetHistoricalEvents(); |
| 271 |
269 private: | 272 private: |
270 struct PipelineInfo { | 273 struct PipelineInfo { |
271 media::PipelineStatus last_pipeline_status; | 274 media::PipelineStatus last_pipeline_status; |
272 bool has_audio; | 275 bool has_audio; |
273 bool has_video; | 276 bool has_video; |
274 bool video_dds; | 277 bool video_dds; |
275 bool video_decoder_changed; | 278 bool video_decoder_changed; |
276 std::string audio_codec_name; | 279 std::string audio_codec_name; |
277 std::string video_codec_name; | 280 std::string video_codec_name; |
278 std::string video_decoder; | 281 std::string video_decoder; |
| 282 // Remember media log events so that when a new media internals page is |
| 283 // opened they can be replayed. |
| 284 std::vector<base::string16> media_log_event_history; |
279 PipelineInfo() | 285 PipelineInfo() |
280 : last_pipeline_status(media::PIPELINE_OK), | 286 : last_pipeline_status(media::PIPELINE_OK), |
281 has_audio(false), | 287 has_audio(false), |
282 has_video(false), | 288 has_video(false), |
283 video_dds(false), | 289 video_dds(false), |
284 video_decoder_changed(false) {} | 290 video_decoder_changed(false) {} |
285 }; | 291 }; |
286 | 292 |
287 // Helper function to report PipelineStatus associated with a player to UMA. | 293 // Helper function to report PipelineStatus associated with a player to UMA. |
288 void ReportUMAForPipelineStatus(const PipelineInfo& player_info); | 294 void ReportUMAForPipelineStatus(const PipelineInfo& player_info); |
(...skipping 25 matching lines...) Expand all Loading... |
314 const NotificationSource& source, | 320 const NotificationSource& source, |
315 const NotificationDetails& details) { | 321 const NotificationDetails& details) { |
316 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 322 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
317 DCHECK_EQ(type, NOTIFICATION_RENDERER_PROCESS_TERMINATED); | 323 DCHECK_EQ(type, NOTIFICATION_RENDERER_PROCESS_TERMINATED); |
318 RenderProcessHost* process = Source<RenderProcessHost>(source).ptr(); | 324 RenderProcessHost* process = Source<RenderProcessHost>(source).ptr(); |
319 | 325 |
320 // Post the task to the IO thread to avoid race in updating renderer_info_ map | 326 // Post the task to the IO thread to avoid race in updating renderer_info_ map |
321 // by both SavePlayerState & LogAndClearPlayersInRenderer from different | 327 // by both SavePlayerState & LogAndClearPlayersInRenderer from different |
322 // threads. | 328 // threads. |
323 // Using base::Unretained() on MediaInternalsUMAHandler is safe since | 329 // Using base::Unretained() on MediaInternalsUMAHandler is safe since |
324 // it is owned by MediaInternals and share the same lifetime | 330 // it is owned by MediaInternals and shares the same lifetime. |
325 BrowserThread::PostTask( | 331 BrowserThread::PostTask( |
326 BrowserThread::IO, FROM_HERE, | 332 BrowserThread::IO, FROM_HERE, |
327 base::Bind(&MediaInternalsUMAHandler::LogAndClearPlayersInRenderer, | 333 base::Bind(&MediaInternalsUMAHandler::LogAndClearPlayersInRenderer, |
328 base::Unretained(this), process->GetID())); | 334 base::Unretained(this), process->GetID())); |
329 } | 335 } |
330 | 336 |
331 void MediaInternals::MediaInternalsUMAHandler::SavePlayerState( | 337 void MediaInternals::MediaInternalsUMAHandler::SavePlayerState( |
332 const media::MediaLogEvent& event, | 338 const media::MediaLogEvent& event, |
| 339 const base::string16& event_serialized, |
333 int render_process_id) { | 340 int render_process_id) { |
334 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 341 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
335 PlayerInfoMap& player_info = renderer_info_[render_process_id]; | 342 PlayerInfoMap& player_info = renderer_info_[render_process_id]; |
| 343 // This can grow unbounded.. |
| 344 player_info[event.id].media_log_event_history.push_back(event_serialized); |
336 switch (event.type) { | 345 switch (event.type) { |
337 case media::MediaLogEvent::PIPELINE_ERROR: { | 346 case media::MediaLogEvent::PIPELINE_ERROR: { |
338 int status; | 347 int status; |
339 event.params.GetInteger("pipeline_error", &status); | 348 event.params.GetInteger("pipeline_error", &status); |
340 player_info[event.id].last_pipeline_status = | 349 player_info[event.id].last_pipeline_status = |
341 static_cast<media::PipelineStatus>(status); | 350 static_cast<media::PipelineStatus>(status); |
342 break; | 351 break; |
343 } | 352 } |
344 case media::MediaLogEvent::PROPERTY_CHANGE: | 353 case media::MediaLogEvent::PROPERTY_CHANGE: |
345 if (event.params.HasKey("found_audio_stream")) { | 354 if (event.params.HasKey("found_audio_stream")) { |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 int render_process_id) { | 452 int render_process_id) { |
444 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 453 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
445 auto players_it = renderer_info_.find(render_process_id); | 454 auto players_it = renderer_info_.find(render_process_id); |
446 if (players_it == renderer_info_.end()) | 455 if (players_it == renderer_info_.end()) |
447 return; | 456 return; |
448 auto it = players_it->second.begin(); | 457 auto it = players_it->second.begin(); |
449 while (it != players_it->second.end()) { | 458 while (it != players_it->second.end()) { |
450 ReportUMAForPipelineStatus(it->second); | 459 ReportUMAForPipelineStatus(it->second); |
451 players_it->second.erase(it++); | 460 players_it->second.erase(it++); |
452 } | 461 } |
| 462 renderer_info_.erase(players_it); |
| 463 } |
| 464 |
| 465 std::vector<base::string16> |
| 466 MediaInternals::MediaInternalsUMAHandler::GetHistoricalEvents() { |
| 467 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 468 |
| 469 std::vector<base::string16> all_events; |
| 470 for (const auto& renderer_info_it : renderer_info_) { |
| 471 for (const auto& player_info_it : renderer_info_it.second) { |
| 472 const auto& player_events = player_info_it.second.media_log_event_history; |
| 473 all_events.insert(all_events.end(), player_events.begin(), |
| 474 player_events.end()); |
| 475 } |
| 476 } |
| 477 |
| 478 return all_events; |
453 } | 479 } |
454 | 480 |
455 MediaInternals* MediaInternals::GetInstance() { | 481 MediaInternals* MediaInternals::GetInstance() { |
456 return g_media_internals.Pointer(); | 482 return g_media_internals.Pointer(); |
457 } | 483 } |
458 | 484 |
459 MediaInternals::MediaInternals() | 485 MediaInternals::MediaInternals() |
460 : owner_ids_(), uma_handler_(new MediaInternalsUMAHandler()) { | 486 : owner_ids_(), uma_handler_(new MediaInternalsUMAHandler()) { |
461 } | 487 } |
462 | 488 |
(...skipping 23 matching lines...) Expand all Loading... |
486 status > static_cast<int>(media::PIPELINE_STATUS_MAX)) { | 512 status > static_cast<int>(media::PIPELINE_STATUS_MAX)) { |
487 continue; | 513 continue; |
488 } | 514 } |
489 media::PipelineStatus error = static_cast<media::PipelineStatus>(status); | 515 media::PipelineStatus error = static_cast<media::PipelineStatus>(status); |
490 dict.SetString("params.pipeline_error", | 516 dict.SetString("params.pipeline_error", |
491 media::MediaLog::PipelineStatusToString(error)); | 517 media::MediaLog::PipelineStatusToString(error)); |
492 } else { | 518 } else { |
493 dict.Set("params", event->params.DeepCopy()); | 519 dict.Set("params", event->params.DeepCopy()); |
494 } | 520 } |
495 | 521 |
496 SendUpdate(SerializeUpdate("media.onMediaEvent", &dict)); | 522 const base::string16 update(SerializeUpdate("media.onMediaEvent", &dict)); |
497 uma_handler_->SavePlayerState(*event, render_process_id); | 523 SendUpdate(update); |
| 524 uma_handler_->SavePlayerState(*event, update, render_process_id); |
498 } | 525 } |
499 } | 526 } |
500 | 527 |
501 void MediaInternals::AddUpdateCallback(const UpdateCallback& callback) { | 528 void MediaInternals::AddUpdateCallback(const UpdateCallback& callback) { |
502 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 529 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
503 update_callbacks_.push_back(callback); | 530 update_callbacks_.push_back(callback); |
504 } | 531 } |
505 | 532 |
506 void MediaInternals::RemoveUpdateCallback(const UpdateCallback& callback) { | 533 void MediaInternals::RemoveUpdateCallback(const UpdateCallback& callback) { |
507 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 534 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
508 for (size_t i = 0; i < update_callbacks_.size(); ++i) { | 535 for (size_t i = 0; i < update_callbacks_.size(); ++i) { |
509 if (update_callbacks_[i].Equals(callback)) { | 536 if (update_callbacks_[i].Equals(callback)) { |
510 update_callbacks_.erase(update_callbacks_.begin() + i); | 537 update_callbacks_.erase(update_callbacks_.begin() + i); |
511 return; | 538 return; |
512 } | 539 } |
513 } | 540 } |
514 NOTREACHED(); | 541 NOTREACHED(); |
515 } | 542 } |
516 | 543 |
| 544 void MediaInternals::SendHistoricalMediaEvents() { |
| 545 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 546 for (const auto& event : uma_handler_->GetHistoricalEvents()) |
| 547 SendUpdate(event); |
| 548 } |
| 549 |
517 void MediaInternals::SendAudioStreamData() { | 550 void MediaInternals::SendAudioStreamData() { |
518 base::string16 audio_stream_update; | 551 base::string16 audio_stream_update; |
519 { | 552 { |
520 base::AutoLock auto_lock(lock_); | 553 base::AutoLock auto_lock(lock_); |
521 audio_stream_update = SerializeUpdate( | 554 audio_stream_update = SerializeUpdate( |
522 "media.onReceiveAudioStreamData", &audio_streams_cached_data_); | 555 "media.onReceiveAudioStreamData", &audio_streams_cached_data_); |
523 } | 556 } |
524 SendUpdate(audio_stream_update); | 557 SendUpdate(audio_stream_update); |
525 } | 558 } |
526 | 559 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 CHECK( | 640 CHECK( |
608 audio_streams_cached_data_.GetDictionary(cache_key, &existing_dict)); | 641 audio_streams_cached_data_.GetDictionary(cache_key, &existing_dict)); |
609 existing_dict->MergeDictionary(value); | 642 existing_dict->MergeDictionary(value); |
610 } | 643 } |
611 } | 644 } |
612 | 645 |
613 SendUpdate(SerializeUpdate(function, value)); | 646 SendUpdate(SerializeUpdate(function, value)); |
614 } | 647 } |
615 | 648 |
616 } // namespace content | 649 } // namespace content |
OLD | NEW |