diff options
-rw-r--r-- | chrome/browser/dom_ui/plugins_ui.cc | 67 | ||||
-rw-r--r-- | chrome/browser/plugin_service.cc | 7 | ||||
-rw-r--r-- | chrome/browser/plugin_updater.cc | 3 | ||||
-rw-r--r-- | chrome/browser/plugin_updater.h | 4 |
4 files changed, 67 insertions, 14 deletions
diff --git a/chrome/browser/dom_ui/plugins_ui.cc b/chrome/browser/dom_ui/plugins_ui.cc index 1d2d347..a427970 100644 --- a/chrome/browser/dom_ui/plugins_ui.cc +++ b/chrome/browser/dom_ui/plugins_ui.cc @@ -155,12 +155,33 @@ class PluginsDOMHandler : public DOMMessageHandler, const NotificationDetails& details); private: + // This extra wrapper is used to ensure we don't leak the ListValue* pointer + // if the PluginsDOMHandler object goes away before the task on the UI thread + // to give it the plugin list runs. + struct ListWrapper { + ListValue* list; + }; + // Loads the plugins on the FILE thread. + static void LoadPluginsOnFileThread(ListWrapper* wrapper, Task* task); + + // Used in conjunction with ListWrapper to avoid any memory leaks. + static void EnsureListDeleted(ListWrapper* wrapper); + + // Call this to start getting the plugins on the UI thread. + void LoadPlugins(); + + // Called on the UI thread when the plugin information is ready. + void PluginsLoaded(ListWrapper* wrapper); + NotificationRegistrar registrar_; + ScopedRunnableMethodFactory<PluginsDOMHandler> get_plugins_factory_; + DISALLOW_COPY_AND_ASSIGN(PluginsDOMHandler); }; -PluginsDOMHandler::PluginsDOMHandler() { +PluginsDOMHandler::PluginsDOMHandler() + : ALLOW_THIS_IN_INITIALIZER_LIST(get_plugins_factory_(this)) { registrar_.Add(this, NotificationType::PLUGIN_ENABLE_STATUS_CHANGED, NotificationService::AllSources()); @@ -176,10 +197,7 @@ void PluginsDOMHandler::RegisterMessages() { } void PluginsDOMHandler::HandleRequestPluginsData(const ListValue* args) { - DictionaryValue results; - results.Set("plugins", - PluginUpdater::GetPluginUpdater()->GetPluginGroupsData()); - dom_ui_->CallJavascriptFunction(L"returnPluginsData", results); + LoadPlugins(); } void PluginsDOMHandler::HandleEnablePluginMessage(const ListValue* args) { @@ -227,9 +245,44 @@ void PluginsDOMHandler::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { DCHECK_EQ(NotificationType::PLUGIN_ENABLE_STATUS_CHANGED, type.value); + LoadPlugins(); +} + +void PluginsDOMHandler::LoadPluginsOnFileThread(ListWrapper* wrapper, + Task* task) { + wrapper->list = PluginUpdater::GetPluginUpdater()->GetPluginGroupsData(); + ChromeThread::PostTask(ChromeThread::UI, FROM_HERE, task); + ChromeThread::PostTask( + ChromeThread::UI, + FROM_HERE, + NewRunnableFunction(&PluginsDOMHandler::EnsureListDeleted, wrapper)); +} + +void PluginsDOMHandler::EnsureListDeleted(ListWrapper* wrapper) { + delete wrapper->list; + delete wrapper; +} + +void PluginsDOMHandler::LoadPlugins() { + if (!get_plugins_factory_.empty()) + return; + + ListWrapper* wrapper = new ListWrapper; + wrapper->list = NULL; + Task* task = get_plugins_factory_.NewRunnableMethod( + &PluginsDOMHandler::PluginsLoaded, wrapper); + + ChromeThread::PostTask( + ChromeThread::FILE, + FROM_HERE, + NewRunnableFunction( + &PluginsDOMHandler::LoadPluginsOnFileThread, wrapper, task)); +} + +void PluginsDOMHandler::PluginsLoaded(ListWrapper* wrapper) { DictionaryValue results; - results.Set("plugins", - PluginUpdater::GetPluginUpdater()->GetPluginGroupsData()); + results.Set("plugins", wrapper->list); + wrapper->list = NULL; // So it doesn't get deleted. dom_ui_->CallJavascriptFunction(L"returnPluginsData", results); } diff --git a/chrome/browser/plugin_service.cc b/chrome/browser/plugin_service.cc index 81aedb61..7736a9f 100644 --- a/chrome/browser/plugin_service.cc +++ b/chrome/browser/plugin_service.cc @@ -57,10 +57,9 @@ static void NotifyPluginsOfActivation() { bool PluginService::enable_chrome_plugins_ = true; void LoadPluginsFromDiskHook() { - // Disable while we investigate why it's firing for interactive_ui_tests - // DCHECK(!ChromeThread::CurrentlyOn(ChromeThread::UI) && - // !ChromeThread::CurrentlyOn(ChromeThread::IO)) << - // "Can't load plugins on the IO/UI threads since it's very slow."; + DCHECK(!ChromeThread::CurrentlyOn(ChromeThread::UI) && + !ChromeThread::CurrentlyOn(ChromeThread::IO)) << + "Can't load plugins on the IO/UI threads since it's very slow."; } // static diff --git a/chrome/browser/plugin_updater.cc b/chrome/browser/plugin_updater.cc index 3a96cee..17ec60a 100644 --- a/chrome/browser/plugin_updater.cc +++ b/chrome/browser/plugin_updater.cc @@ -26,7 +26,7 @@ PluginUpdater::PluginUpdater() : enable_internal_pdf_(true) { } -// Convert to a List of Groups +// static void PluginUpdater::GetPluginGroups(PluginMap* plugin_groups) { DCHECK(plugin_groups); @@ -73,6 +73,7 @@ DictionaryValue* PluginUpdater::CreatePluginFileSummary( return data; } +// static ListValue* PluginUpdater::GetPluginGroupsData() { PluginMap plugin_groups; GetPluginGroups(&plugin_groups); diff --git a/chrome/browser/plugin_updater.h b/chrome/browser/plugin_updater.h index 401ab61..74cc286 100644 --- a/chrome/browser/plugin_updater.h +++ b/chrome/browser/plugin_updater.h @@ -27,11 +27,11 @@ class PluginUpdater : public NotificationObserver { typedef std::map<std::string, linked_ptr<PluginGroup> > PluginMap; // Get a map from identifier to plugin group for all plugin groups. - void GetPluginGroups(PluginMap* plugin_groups); + static void GetPluginGroups(PluginMap* plugin_groups); // Get a list of all the plugin groups. The caller should take ownership // of the returned ListValue. - ListValue* GetPluginGroupsData(); + static ListValue* GetPluginGroupsData(); // Enable or disable a plugin group. void EnablePluginGroup(bool enable, const string16& group_name); |