Chromium Code Reviews| Index: chrome/browser/ui/webui/media_internals_ui.cc |
| diff --git a/chrome/browser/ui/webui/media_internals_ui.cc b/chrome/browser/ui/webui/media_internals_ui.cc |
| index de2f4227113effe68db6fbd58a91fd8c1faac324..21467fece5672c6449f0b8c75551b428200c1ddd 100644 |
| --- a/chrome/browser/ui/webui/media_internals_ui.cc |
| +++ b/chrome/browser/ui/webui/media_internals_ui.cc |
| @@ -6,16 +6,23 @@ |
| #include "base/memory/ref_counted_memory.h" |
| #include "base/values.h" |
| +#include "chrome/browser/browser_process.h" |
| +#include "chrome/browser/io_thread.h" |
| +#include "chrome/browser/media/media_internals.h" |
| +#include "chrome/browser/media/media_internals_observer.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
| #include "chrome/browser/ui/webui/chrome_url_data_manager.h" |
| #include "chrome/common/jstemplate_builder.h" |
| #include "chrome/common/url_constants.h" |
| +#include "content/browser/renderer_host/render_view_host.h" |
| #include "grit/browser_resources.h" |
| #include "ui/base/resource/resource_bundle.h" |
| namespace { |
| +class MediaInternalsProxy; |
| + |
| class MediaInternalsHTMLSource : public ChromeURLDataManager::DataSource { |
| public: |
| MediaInternalsHTMLSource(); |
| @@ -32,6 +39,66 @@ class MediaInternalsHTMLSource : public ChromeURLDataManager::DataSource { |
| DISALLOW_COPY_AND_ASSIGN(MediaInternalsHTMLSource); |
| }; |
| +// This class handles messages to and from MediaInternalsUI. |
| +// It does all its work on the IO thread through the proxy below. |
| +class MediaInternalsMessageHandler : public WebUIMessageHandler { |
|
Evan Stade
2011/06/30 22:24:27
please do break this into a separate file. net_int
Scott Franklin
2011/07/01 01:42:32
Alright, split and filed (directoried?). I'm assum
|
| + public: |
| + MediaInternalsMessageHandler(); |
| + virtual ~MediaInternalsMessageHandler(); |
| + |
| + // WebUIMessageHandler implementation. |
| + virtual WebUIMessageHandler* Attach(WebUI* web_ui); |
| + virtual void RegisterMessages(); |
| + |
| + // Javascript message handlers. |
| + void OnGetEverything(const ListValue* list); |
| + |
| + // MediaInternals message handlers. |
| + void OnUpdate(const string16& update); |
| + |
| + private: |
| + scoped_refptr<MediaInternalsProxy> proxy_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(MediaInternalsMessageHandler); |
| +}; |
| + |
| +// This class is a proxy between MediaInternals (on the IO thread) and |
| +// MediaInternalsMessageHandler (on the UI thread). |
| +// It is ref_counted to ensure that it completes all pending Tasks on both |
| +// threads before destruction. |
| +class MediaInternalsProxy |
| + : public MediaInternalsObserver, |
| + public base::RefCountedThreadSafe<MediaInternalsProxy> { |
| + public: |
| + MediaInternalsProxy(); |
| + |
| + // Register a Handler and start receiving callbacks from MediaInternals. |
| + void Attach(MediaInternalsMessageHandler* handler); |
| + |
| + // Unregister the same and stop receiving callbacks. |
| + void Detach(); |
| + |
| + // Have MediaInternals send all the data it has. |
| + void GetEverything(); |
| + |
| + // MediaInternalsObserver implementation. Called on the IO thread. |
| + virtual void OnUpdate(const string16& update); |
| + |
| + private: |
| + friend class base::RefCountedThreadSafe<MediaInternalsProxy>; |
| + virtual ~MediaInternalsProxy(); |
| + |
| + void ObserveMediaInternalsOnIOThread(); |
| + void StopObservingMediaInternalsOnIOThread(); |
| + void GetEverythingOnIOThread(); |
| + void UpdateUIOnUIThread(const string16& update); |
| + |
| + MediaInternalsMessageHandler* handler_; |
| + IOThread* io_thread_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(MediaInternalsProxy); |
| +}; |
| + |
| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // MediaInternalsHTMLSource |
| @@ -69,8 +136,102 @@ std::string MediaInternalsHTMLSource::GetMimeType( |
| return "text/html"; |
| } |
| -} // namespace |
| +//////////////////////////////////////////////////////////////////////////////// |
| +// |
| +// MediaInternalsMessageHandler |
| +// |
| +//////////////////////////////////////////////////////////////////////////////// |
| + |
| +MediaInternalsMessageHandler::MediaInternalsMessageHandler() |
| + : proxy_(new MediaInternalsProxy()) {} |
| + |
| +MediaInternalsMessageHandler::~MediaInternalsMessageHandler() { |
| + proxy_->Detach(); |
| +} |
| + |
| +WebUIMessageHandler* MediaInternalsMessageHandler::Attach(WebUI* web_ui) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + WebUIMessageHandler* result = WebUIMessageHandler::Attach(web_ui); |
| + proxy_->Attach(this); |
| + return result; |
| +} |
| + |
| +void MediaInternalsMessageHandler::RegisterMessages() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + web_ui_->RegisterMessageCallback( |
| + "getEverything", |
| + NewCallback(this, &MediaInternalsMessageHandler::OnGetEverything)); |
| +} |
| + |
| +void MediaInternalsMessageHandler::OnGetEverything(const ListValue* list) { |
| + proxy_->GetEverything(); |
| +} |
| + |
| +void MediaInternalsMessageHandler::OnUpdate(const string16& update) { |
| + web_ui_->GetRenderViewHost()->ExecuteJavascriptInWebFrame(string16(), update); |
| +} |
| + |
| +//////////////////////////////////////////////////////////////////////////////// |
| +// |
| +// MediaInternalsProxy |
| +// |
| +//////////////////////////////////////////////////////////////////////////////// |
| + |
| +MediaInternalsProxy::MediaInternalsProxy() { |
| + io_thread_ = g_browser_process->io_thread(); |
| +} |
| + |
| +void MediaInternalsProxy::Attach(MediaInternalsMessageHandler* handler) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + handler_ = handler; |
| + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| + NewRunnableMethod(this, |
| + &MediaInternalsProxy::ObserveMediaInternalsOnIOThread)); |
| +} |
| + |
| +void MediaInternalsProxy::Detach() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + handler_ = NULL; |
| + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| + NewRunnableMethod(this, |
| + &MediaInternalsProxy::StopObservingMediaInternalsOnIOThread)); |
| +} |
| + |
| +void MediaInternalsProxy::GetEverything() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| + NewRunnableMethod(this, &MediaInternalsProxy::GetEverythingOnIOThread)); |
| +} |
| + |
| +void MediaInternalsProxy::OnUpdate(const string16& update) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| + NewRunnableMethod(this, |
| + &MediaInternalsProxy::UpdateUIOnUIThread, update)); |
| +} |
| + |
| +MediaInternalsProxy::~MediaInternalsProxy() {} |
| + |
| +void MediaInternalsProxy::ObserveMediaInternalsOnIOThread() { |
| + io_thread_->globals()->media.media_internals->AddUI(this); |
| +} |
| + |
| +void MediaInternalsProxy::StopObservingMediaInternalsOnIOThread() { |
| + io_thread_->globals()->media.media_internals->RemoveUI(this); |
| +} |
| + |
| +void MediaInternalsProxy::GetEverythingOnIOThread() { |
| + io_thread_->globals()->media.media_internals->SendEverything(); |
| +} |
| + |
| +void MediaInternalsProxy::UpdateUIOnUIThread(const string16& update) { |
| + // Don't forward updates to a destructed UI. |
| + if (handler_) |
| + handler_->OnUpdate(update); |
| +} |
| + |
| +} // namespace |
| //////////////////////////////////////////////////////////////////////////////// |
| // |
| @@ -80,7 +241,8 @@ std::string MediaInternalsHTMLSource::GetMimeType( |
| MediaInternalsUI::MediaInternalsUI(TabContents* contents) |
| : ChromeWebUI(contents) { |
| + AddMessageHandler((new MediaInternalsMessageHandler())->Attach(this)); |
| + |
| contents->profile()->GetChromeURLDataManager()->AddDataSource( |
| new MediaInternalsHTMLSource()); |
| } |
| - |