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"
8 #include "base/message_loop/message_loop.h"
9 #include "content/browser/media/media_internals_handler.h"
10 #include "content/public/browser/content_browser_client.h"
11 #include "content/public/browser/notification_service.h"
12 #include "content/public/browser/notification_types.h"
13 #include "content/public/browser/render_process_host.h"
14 #include "content/public/browser/web_ui.h"
18 static const int kMediaInternalsProxyEventDelayMilliseconds
= 100;
20 static const net::NetLog::EventType kNetEventTypeFilter
[] = {
21 net::NetLog::TYPE_DISK_CACHE_ENTRY_IMPL
,
22 net::NetLog::TYPE_SPARSE_READ
,
23 net::NetLog::TYPE_SPARSE_WRITE
,
24 net::NetLog::TYPE_URL_REQUEST_START_JOB
,
25 net::NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS
,
28 MediaInternalsProxy::MediaInternalsProxy() {
29 registrar_
.Add(this, NOTIFICATION_RENDERER_PROCESS_TERMINATED
,
30 NotificationService::AllBrowserContextsAndSources());
33 void MediaInternalsProxy::Observe(int type
,
34 const NotificationSource
& source
,
35 const NotificationDetails
& details
) {
36 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
37 DCHECK_EQ(type
, NOTIFICATION_RENDERER_PROCESS_TERMINATED
);
38 RenderProcessHost
* process
= Source
<RenderProcessHost
>(source
).ptr();
39 CallJavaScriptFunctionOnUIThread("media.onRendererTerminated",
40 new base::FundamentalValue(process
->GetID()));
43 void MediaInternalsProxy::Attach(MediaInternalsMessageHandler
* handler
) {
44 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
46 BrowserThread::PostTask(
47 BrowserThread::IO
, FROM_HERE
,
48 base::Bind(&MediaInternalsProxy::ObserveMediaInternalsOnIOThread
, this));
51 void MediaInternalsProxy::Detach() {
52 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
54 BrowserThread::PostTask(
55 BrowserThread::IO
, FROM_HERE
,
57 &MediaInternalsProxy::StopObservingMediaInternalsOnIOThread
, this));
60 void MediaInternalsProxy::GetEverything() {
61 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
63 // Ask MediaInternals for all its data.
64 BrowserThread::PostTask(
65 BrowserThread::IO
, FROM_HERE
,
66 base::Bind(&MediaInternalsProxy::GetEverythingOnIOThread
, this));
68 // Send the page names for constants.
69 CallJavaScriptFunctionOnUIThread("media.onReceiveConstants", GetConstants());
72 void MediaInternalsProxy::OnUpdate(const base::string16
& update
) {
73 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
74 BrowserThread::PostTask(
75 BrowserThread::UI
, FROM_HERE
,
76 base::Bind(&MediaInternalsProxy::UpdateUIOnUIThread
, this, update
));
79 void MediaInternalsProxy::OnAddEntry(const net::NetLog::Entry
& entry
) {
80 bool is_event_interesting
= false;
81 for (size_t i
= 0; i
< arraysize(kNetEventTypeFilter
); i
++) {
82 if (entry
.type() == kNetEventTypeFilter
[i
]) {
83 is_event_interesting
= true;
88 if (!is_event_interesting
)
91 BrowserThread::PostTask(
92 BrowserThread::UI
, FROM_HERE
,
93 base::Bind(&MediaInternalsProxy::AddNetEventOnUIThread
, this,
97 MediaInternalsProxy::~MediaInternalsProxy() {}
99 base::Value
* MediaInternalsProxy::GetConstants() {
100 base::DictionaryValue
* event_phases
= new base::DictionaryValue();
101 event_phases
->SetInteger(
102 net::NetLog::EventPhaseToString(net::NetLog::PHASE_NONE
),
103 net::NetLog::PHASE_NONE
);
104 event_phases
->SetInteger(
105 net::NetLog::EventPhaseToString(net::NetLog::PHASE_BEGIN
),
106 net::NetLog::PHASE_BEGIN
);
107 event_phases
->SetInteger(
108 net::NetLog::EventPhaseToString(net::NetLog::PHASE_END
),
109 net::NetLog::PHASE_END
);
111 base::DictionaryValue
* constants
= new base::DictionaryValue();
112 constants
->Set("eventTypes", net::NetLog::GetEventTypesAsValue());
113 constants
->Set("eventPhases", event_phases
);
118 void MediaInternalsProxy::ObserveMediaInternalsOnIOThread() {
119 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
120 update_callback_
= base::Bind(&MediaInternalsProxy::OnUpdate
,
121 base::Unretained(this));
122 MediaInternals::GetInstance()->AddUpdateCallback(update_callback_
);
123 if (GetContentClient()->browser()->GetNetLog()) {
124 net::NetLog
* net_log
= GetContentClient()->browser()->GetNetLog();
125 net_log
->DeprecatedAddObserver(this, net::NetLog::LOG_ALL_BUT_BYTES
);
129 void MediaInternalsProxy::StopObservingMediaInternalsOnIOThread() {
130 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
131 MediaInternals::GetInstance()->RemoveUpdateCallback(update_callback_
);
132 if (GetContentClient()->browser()->GetNetLog()) {
133 net::NetLog
* net_log
= GetContentClient()->browser()->GetNetLog();
134 net_log
->DeprecatedRemoveObserver(this);
138 void MediaInternalsProxy::GetEverythingOnIOThread() {
139 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
140 MediaInternals::GetInstance()->SendAudioStreamData();
141 MediaInternals::GetInstance()->SendVideoCaptureDeviceCapabilities();
144 void MediaInternalsProxy::UpdateUIOnUIThread(const base::string16
& update
) {
145 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
146 // Don't forward updates to a destructed UI.
148 handler_
->OnUpdate(update
);
151 void MediaInternalsProxy::AddNetEventOnUIThread(base::Value
* entry
) {
152 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
154 // Send the updates to the page in kMediaInternalsProxyEventDelayMilliseconds
155 // if an update is not already pending.
156 if (!pending_net_updates_
) {
157 pending_net_updates_
.reset(new base::ListValue());
158 base::MessageLoop::current()->PostDelayedTask(
160 base::Bind(&MediaInternalsProxy::SendNetEventsOnUIThread
, this),
161 base::TimeDelta::FromMilliseconds(
162 kMediaInternalsProxyEventDelayMilliseconds
));
164 pending_net_updates_
->Append(entry
);
167 void MediaInternalsProxy::SendNetEventsOnUIThread() {
168 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
169 CallJavaScriptFunctionOnUIThread("media.onNetUpdate",
170 pending_net_updates_
.release());
173 void MediaInternalsProxy::CallJavaScriptFunctionOnUIThread(
174 const std::string
& function
, base::Value
* args
) {
175 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
176 scoped_ptr
<base::Value
> args_value(args
);
177 std::vector
<const base::Value
*> args_vector
;
178 args_vector
.push_back(args_value
.get());
179 base::string16 update
= WebUI::GetJavascriptCall(function
, args_vector
);
180 UpdateUIOnUIThread(update
);
183 } // namespace content