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()); |
} |
- |