Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / content / browser / media / media_internals_proxy.cc
blob6e338ed5da83e9cc7c3a659c46779a79a4e25008
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
3 // found in the LICENSE file.
5 #include "content/browser/media/media_internals_proxy.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "content/browser/media/media_internals_handler.h"
12 #include "content/public/browser/content_browser_client.h"
13 #include "content/public/browser/notification_service.h"
14 #include "content/public/browser/notification_types.h"
15 #include "content/public/browser/render_process_host.h"
16 #include "content/public/browser/web_ui.h"
18 namespace content {
20 static const int kMediaInternalsProxyEventDelayMilliseconds = 100;
22 static const net::NetLog::EventType kNetEventTypeFilter[] = {
23 net::NetLog::TYPE_DISK_CACHE_ENTRY_IMPL,
24 net::NetLog::TYPE_SPARSE_READ,
25 net::NetLog::TYPE_SPARSE_WRITE,
26 net::NetLog::TYPE_URL_REQUEST_START_JOB,
27 net::NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
30 MediaInternalsProxy::MediaInternalsProxy() {
31 registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_TERMINATED,
32 NotificationService::AllBrowserContextsAndSources());
35 void MediaInternalsProxy::Observe(int type,
36 const NotificationSource& source,
37 const NotificationDetails& details) {
38 DCHECK_CURRENTLY_ON(BrowserThread::UI);
39 DCHECK_EQ(type, NOTIFICATION_RENDERER_PROCESS_TERMINATED);
40 RenderProcessHost* process = Source<RenderProcessHost>(source).ptr();
41 CallJavaScriptFunctionOnUIThread("media.onRendererTerminated",
42 new base::FundamentalValue(process->GetID()));
45 void MediaInternalsProxy::Attach(MediaInternalsMessageHandler* handler) {
46 DCHECK_CURRENTLY_ON(BrowserThread::UI);
48 handler_ = handler;
49 update_callback_ = base::Bind(&MediaInternalsProxy::UpdateUIOnUIThread, this);
50 MediaInternals::GetInstance()->AddUpdateCallback(update_callback_);
52 BrowserThread::PostTask(
53 BrowserThread::IO, FROM_HERE,
54 base::Bind(&MediaInternalsProxy::ObserveMediaInternalsOnIOThread, this));
57 void MediaInternalsProxy::Detach() {
58 DCHECK_CURRENTLY_ON(BrowserThread::UI);
60 handler_ = NULL;
61 MediaInternals::GetInstance()->RemoveUpdateCallback(update_callback_);
63 BrowserThread::PostTask(
64 BrowserThread::IO, FROM_HERE,
65 base::Bind(
66 &MediaInternalsProxy::StopObservingMediaInternalsOnIOThread, this));
69 void MediaInternalsProxy::GetEverything() {
70 DCHECK_CURRENTLY_ON(BrowserThread::UI);
72 MediaInternals::GetInstance()->SendHistoricalMediaEvents();
74 // Ask MediaInternals for its data on IO thread.
75 BrowserThread::PostTask(
76 BrowserThread::IO, FROM_HERE,
77 base::Bind(&MediaInternalsProxy::GetEverythingOnIOThread, this));
79 // Send the page names for constants.
80 CallJavaScriptFunctionOnUIThread("media.onReceiveConstants", GetConstants());
83 void MediaInternalsProxy::OnAddEntry(const net::NetLog::Entry& entry) {
84 bool is_event_interesting = false;
85 for (size_t i = 0; i < arraysize(kNetEventTypeFilter); i++) {
86 if (entry.type() == kNetEventTypeFilter[i]) {
87 is_event_interesting = true;
88 break;
92 if (!is_event_interesting)
93 return;
95 BrowserThread::PostTask(
96 BrowserThread::UI, FROM_HERE,
97 base::Bind(&MediaInternalsProxy::AddNetEventOnUIThread, this,
98 entry.ToValue()));
101 MediaInternalsProxy::~MediaInternalsProxy() {}
103 base::Value* MediaInternalsProxy::GetConstants() {
104 base::DictionaryValue* event_phases = new base::DictionaryValue();
105 event_phases->SetInteger(
106 net::NetLog::EventPhaseToString(net::NetLog::PHASE_NONE),
107 net::NetLog::PHASE_NONE);
108 event_phases->SetInteger(
109 net::NetLog::EventPhaseToString(net::NetLog::PHASE_BEGIN),
110 net::NetLog::PHASE_BEGIN);
111 event_phases->SetInteger(
112 net::NetLog::EventPhaseToString(net::NetLog::PHASE_END),
113 net::NetLog::PHASE_END);
115 base::DictionaryValue* constants = new base::DictionaryValue();
116 constants->Set("eventTypes", net::NetLog::GetEventTypesAsValue());
117 constants->Set("eventPhases", event_phases);
119 return constants;
122 void MediaInternalsProxy::ObserveMediaInternalsOnIOThread() {
123 DCHECK_CURRENTLY_ON(BrowserThread::IO);
124 if (GetContentClient()->browser()->GetNetLog()) {
125 net::NetLog* net_log = GetContentClient()->browser()->GetNetLog();
126 net_log->DeprecatedAddObserver(
127 this, net::NetLogCaptureMode::IncludeCookiesAndCredentials());
131 void MediaInternalsProxy::StopObservingMediaInternalsOnIOThread() {
132 DCHECK_CURRENTLY_ON(BrowserThread::IO);
133 if (GetContentClient()->browser()->GetNetLog()) {
134 net::NetLog* net_log = GetContentClient()->browser()->GetNetLog();
135 net_log->DeprecatedRemoveObserver(this);
139 void MediaInternalsProxy::GetEverythingOnIOThread() {
140 DCHECK_CURRENTLY_ON(BrowserThread::IO);
141 // TODO(xhwang): Investigate whether we can update on UI thread directly.
142 MediaInternals::GetInstance()->SendAudioStreamData();
143 MediaInternals::GetInstance()->SendVideoCaptureDeviceCapabilities();
146 void MediaInternalsProxy::UpdateUIOnUIThread(const base::string16& update) {
147 DCHECK_CURRENTLY_ON(BrowserThread::UI);
148 // Don't forward updates to a destructed UI.
149 if (handler_)
150 handler_->OnUpdate(update);
153 void MediaInternalsProxy::AddNetEventOnUIThread(base::Value* entry) {
154 DCHECK_CURRENTLY_ON(BrowserThread::UI);
156 // Send the updates to the page in kMediaInternalsProxyEventDelayMilliseconds
157 // if an update is not already pending.
158 if (!pending_net_updates_) {
159 pending_net_updates_.reset(new base::ListValue());
160 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
161 FROM_HERE,
162 base::Bind(&MediaInternalsProxy::SendNetEventsOnUIThread, this),
163 base::TimeDelta::FromMilliseconds(
164 kMediaInternalsProxyEventDelayMilliseconds));
166 pending_net_updates_->Append(entry);
169 void MediaInternalsProxy::SendNetEventsOnUIThread() {
170 DCHECK_CURRENTLY_ON(BrowserThread::UI);
171 CallJavaScriptFunctionOnUIThread("media.onNetUpdate",
172 pending_net_updates_.release());
175 void MediaInternalsProxy::CallJavaScriptFunctionOnUIThread(
176 const std::string& function, base::Value* args) {
177 DCHECK_CURRENTLY_ON(BrowserThread::UI);
178 scoped_ptr<base::Value> args_value(args);
179 std::vector<const base::Value*> args_vector;
180 args_vector.push_back(args_value.get());
181 base::string16 update = WebUI::GetJavascriptCall(function, args_vector);
182 UpdateUIOnUIThread(update);
185 } // namespace content