15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/media/media_internals_proxy.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 89ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/media/media_internals_handler.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/content_browser_client.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kMediaInternalsProxyEventDelayMilliseconds = 100; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const net::NetLog::EventType kNetEventTypeFilter[] = { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_DISK_CACHE_ENTRY_IMPL, 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_SPARSE_READ, 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_SPARSE_WRITE, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_URL_REQUEST_START_JOB, 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaInternalsProxy::MediaInternalsProxy() { 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_TERMINATED, 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotificationService::AllBrowserContextsAndSources()); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaInternalsProxy::Observe(int type, 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const NotificationSource& source, 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const NotificationDetails& details) { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(type, NOTIFICATION_RENDERER_PROCESS_TERMINATED); 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RenderProcessHost* process = Source<RenderProcessHost>(source).ptr(); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallJavaScriptFunctionOnUIThread("media.onRendererTerminated", 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new base::FundamentalValue(process->GetID())); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaInternalsProxy::Attach(MediaInternalsMessageHandler* handler) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handler_ = handler; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::IO, FROM_HERE, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&MediaInternalsProxy::ObserveMediaInternalsOnIOThread, this)); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaInternalsProxy::Detach() { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handler_ = NULL; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::IO, FROM_HERE, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind( 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &MediaInternalsProxy::StopObservingMediaInternalsOnIOThread, this)); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaInternalsProxy::GetEverything() { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ask MediaInternals for all its data. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::IO, FROM_HERE, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&MediaInternalsProxy::GetEverythingOnIOThread, this)); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send the page names for constants. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallJavaScriptFunctionOnUIThread("media.onReceiveConstants", GetConstants()); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaInternalsProxy::OnUpdate(const base::string16& update) { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::UI, FROM_HERE, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&MediaInternalsProxy::UpdateUIOnUIThread, this, update)); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaInternalsProxy::OnAddEntry(const net::NetLog::Entry& entry) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_event_interesting = false; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < arraysize(kNetEventTypeFilter); i++) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry.type() == kNetEventTypeFilter[i]) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_event_interesting = true; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_event_interesting) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::UI, FROM_HERE, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&MediaInternalsProxy::AddNetEventOnUIThread, this, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry.ToValue())); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaInternalsProxy::~MediaInternalsProxy() {} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::Value* MediaInternalsProxy::GetConstants() { 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* event_phases = new base::DictionaryValue(); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_phases->SetInteger( 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::EventPhaseToString(net::NetLog::PHASE_NONE), 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::PHASE_NONE); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_phases->SetInteger( 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::EventPhaseToString(net::NetLog::PHASE_BEGIN), 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::PHASE_BEGIN); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_phases->SetInteger( 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::EventPhaseToString(net::NetLog::PHASE_END), 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetLog::PHASE_END); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* constants = new base::DictionaryValue(); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) constants->Set("eventTypes", net::NetLog::GetEventTypesAsValue()); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) constants->Set("eventPhases", event_phases); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return constants; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaInternalsProxy::ObserveMediaInternalsOnIOThread() { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) update_callback_ = base::Bind(&MediaInternalsProxy::OnUpdate, 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this)); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MediaInternals::GetInstance()->AddUpdateCallback(update_callback_); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (GetContentClient()->browser()->GetNetLog()) { 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::NetLog* net_log = GetContentClient()->browser()->GetNetLog(); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net_log->AddThreadSafeObserver(this, net::NetLog::LOG_ALL_BUT_BYTES); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaInternalsProxy::StopObservingMediaInternalsOnIOThread() { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MediaInternals::GetInstance()->RemoveUpdateCallback(update_callback_); 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (GetContentClient()->browser()->GetNetLog()) { 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::NetLog* net_log = GetContentClient()->browser()->GetNetLog(); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net_log->RemoveThreadSafeObserver(this); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaInternalsProxy::GetEverythingOnIOThread() { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MediaInternals::GetInstance()->SendEverything(); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MediaInternalsProxy::UpdateUIOnUIThread(const base::string16& update) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't forward updates to a destructed UI. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (handler_) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handler_->OnUpdate(update); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaInternalsProxy::AddNetEventOnUIThread(base::Value* entry) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send the updates to the page in kMediaInternalsProxyEventDelayMilliseconds 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if an update is not already pending. 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!pending_net_updates_) { 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_net_updates_.reset(new base::ListValue()); 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&MediaInternalsProxy::SendNetEventsOnUIThread, this), 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds( 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kMediaInternalsProxyEventDelayMilliseconds)); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_net_updates_->Append(entry); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaInternalsProxy::SendNetEventsOnUIThread() { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallJavaScriptFunctionOnUIThread("media.onNetUpdate", 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_net_updates_.release()); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaInternalsProxy::CallJavaScriptFunctionOnUIThread( 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& function, base::Value* args) { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> args_value(args); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<const base::Value*> args_vector; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args_vector.push_back(args_value.get()); 178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 update = WebUI::GetJavascriptCall(function, args_vector); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateUIOnUIThread(update); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace content 183