summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/dom_ui/plugins_ui.cc67
-rw-r--r--chrome/browser/plugin_service.cc7
-rw-r--r--chrome/browser/plugin_updater.cc3
-rw-r--r--chrome/browser/plugin_updater.h4
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);