summaryrefslogtreecommitdiffstats
path: root/chrome/browser/task_manager
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/task_manager')
-rw-r--r--chrome/browser/task_manager/task_manager.cc54
-rw-r--r--chrome/browser/task_manager/task_manager.h18
-rw-r--r--chrome/browser/task_manager/task_manager_browsertest.cc36
-rw-r--r--chrome/browser/task_manager/task_manager_resource_providers.cc368
-rw-r--r--chrome/browser/task_manager/task_manager_resource_providers.h113
5 files changed, 509 insertions, 80 deletions
diff --git a/chrome/browser/task_manager/task_manager.cc b/chrome/browser/task_manager/task_manager.cc
index 2711925..c6500fa 100644
--- a/chrome/browser/task_manager/task_manager.cc
+++ b/chrome/browser/task_manager/task_manager.cc
@@ -78,6 +78,10 @@ TaskManagerModel::TaskManagerModel(TaskManager* task_manager)
new TaskManagerBrowserProcessResourceProvider(task_manager);
browser_provider->AddRef();
providers_.push_back(browser_provider);
+ TaskManagerBackgroundContentsResourceProvider* bc_provider =
+ new TaskManagerBackgroundContentsResourceProvider(task_manager);
+ bc_provider->AddRef();
+ providers_.push_back(bc_provider);
TaskManagerTabContentsResourceProvider* wc_provider =
new TaskManagerTabContentsResourceProvider(task_manager);
wc_provider->AddRef();
@@ -116,12 +120,12 @@ void TaskManagerModel::RemoveObserver(TaskManagerModelObserver* observer) {
}
string16 TaskManagerModel::GetResourceTitle(int index) const {
- CHECK(index < ResourceCount());
+ CHECK_LT(index, ResourceCount());
return WideToUTF16Hack(resources_[index]->GetTitle());
}
int64 TaskManagerModel::GetNetworkUsage(int index) const {
- CHECK(index < ResourceCount());
+ CHECK_LT(index, ResourceCount());
return GetNetworkUsage(resources_[index]);
}
@@ -138,12 +142,12 @@ string16 TaskManagerModel::GetResourceNetworkUsage(int index) const {
}
double TaskManagerModel::GetCPUUsage(int index) const {
- CHECK(index < ResourceCount());
+ CHECK_LT(index, ResourceCount());
return GetCPUUsage(resources_[index]);
}
string16 TaskManagerModel::GetResourceCPUUsage(int index) const {
- CHECK(index < ResourceCount());
+ CHECK_LT(index, ResourceCount());
return WideToUTF16Hack(StringPrintf(
#if defined(OS_MACOSX)
// Activity Monitor shows %cpu with one decimal digit -- be
@@ -176,7 +180,7 @@ string16 TaskManagerModel::GetResourcePhysicalMemory(int index) const {
}
int TaskManagerModel::GetProcessId(int index) const {
- CHECK(index < ResourceCount());
+ CHECK_LT(index, ResourceCount());
return base::GetProcId(resources_[index]->GetProcess());
}
@@ -185,13 +189,13 @@ string16 TaskManagerModel::GetResourceProcessId(int index) const {
}
string16 TaskManagerModel::GetResourceGoatsTeleported(int index) const {
- CHECK(index < ResourceCount());
+ CHECK_LT(index, ResourceCount());
return base::FormatNumber(GetGoatsTeleported(index));
}
string16 TaskManagerModel::GetResourceWebCoreImageCacheSize(
int index) const {
- CHECK(index < ResourceCount());
+ CHECK_LT(index, ResourceCount());
if (!resources_[index]->ReportsCacheStats())
return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
const WebKit::WebCache::ResourceTypeStats stats(
@@ -201,7 +205,7 @@ string16 TaskManagerModel::GetResourceWebCoreImageCacheSize(
string16 TaskManagerModel::GetResourceWebCoreScriptsCacheSize(
int index) const {
- CHECK(index < ResourceCount());
+ CHECK_LT(index, ResourceCount());
if (!resources_[index]->ReportsCacheStats())
return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
const WebKit::WebCache::ResourceTypeStats stats(
@@ -211,7 +215,7 @@ string16 TaskManagerModel::GetResourceWebCoreScriptsCacheSize(
string16 TaskManagerModel::GetResourceWebCoreCSSCacheSize(
int index) const {
- CHECK(index < ResourceCount());
+ CHECK_LT(index, ResourceCount());
if (!resources_[index]->ReportsCacheStats())
return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
const WebKit::WebCache::ResourceTypeStats stats(
@@ -220,7 +224,7 @@ string16 TaskManagerModel::GetResourceWebCoreCSSCacheSize(
}
string16 TaskManagerModel::GetResourceSqliteMemoryUsed(int index) const {
- CHECK(index < ResourceCount());
+ CHECK_LT(index, ResourceCount());
if (!resources_[index]->ReportsSqliteMemoryUsed())
return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT);
return GetMemCellText(resources_[index]->SqliteMemoryUsedBytes());
@@ -240,7 +244,7 @@ string16 TaskManagerModel::GetResourceV8MemoryAllocatedSize(
}
bool TaskManagerModel::IsResourceFirstInGroup(int index) const {
- CHECK(index < ResourceCount());
+ CHECK_LT(index, ResourceCount());
TaskManager::Resource* resource = resources_[index];
GroupMap::const_iterator iter = group_map_.find(resource->GetProcess());
DCHECK(iter != group_map_.end());
@@ -248,8 +252,13 @@ bool TaskManagerModel::IsResourceFirstInGroup(int index) const {
return ((*group)[0] == resource);
}
+bool TaskManagerModel::IsBackgroundResource(int index) const {
+ CHECK_LT(index, ResourceCount());
+ return resources_[index]->IsBackground();
+}
+
SkBitmap TaskManagerModel::GetResourceIcon(int index) const {
- CHECK(index < ResourceCount());
+ CHECK_LT(index, ResourceCount());
SkBitmap icon = resources_[index]->GetIcon();
if (!icon.isNull())
return icon;
@@ -261,7 +270,7 @@ SkBitmap TaskManagerModel::GetResourceIcon(int index) const {
std::pair<int, int> TaskManagerModel::GetGroupRangeForResource(int index)
const {
- CHECK(index < ResourceCount());
+ CHECK_LT(index, ResourceCount());
TaskManager::Resource* resource = resources_[index];
GroupMap::const_iterator group_iter =
group_map_.find(resource->GetProcess());
@@ -388,22 +397,22 @@ int TaskManagerModel::CompareValues(int row1, int row2, int col_id) const {
base::ProcessHandle TaskManagerModel::GetResourceProcessHandle(int index)
const {
- CHECK(index < ResourceCount());
+ CHECK_LT(index, ResourceCount());
return resources_[index]->GetProcess();
}
TaskManager::Resource::Type TaskManagerModel::GetResourceType(int index) const {
- CHECK(index < ResourceCount());
+ CHECK_LT(index, ResourceCount());
return resources_[index]->GetType();
}
TabContents* TaskManagerModel::GetResourceTabContents(int index) const {
- CHECK(index < ResourceCount());
+ CHECK_LT(index, ResourceCount());
return resources_[index]->GetTabContents();
}
const Extension* TaskManagerModel::GetResourceExtension(int index) const {
- CHECK(index < ResourceCount());
+ CHECK_LT(index, ResourceCount());
return resources_[index]->GetExtension();
}
@@ -607,7 +616,7 @@ void TaskManagerModel::AddResource(TaskManager::Resource* resource) {
resources_.end(),
(*group_entries)[group_entries->size() - 2]);
DCHECK(iter != resources_.end());
- new_entry_index = static_cast<int>(iter - resources_.begin());
+ new_entry_index = static_cast<int>(iter - resources_.begin()) + 1;
resources_.insert(++iter, resource);
}
@@ -711,6 +720,11 @@ void TaskManagerModel::Clear() {
}
}
+void TaskManagerModel::ModelChanged() {
+ // Notify the table that the contents have changed for it to redraw.
+ FOR_EACH_OBSERVER(TaskManagerModelObserver, observer_list_, OnModelChanged());
+}
+
void TaskManagerModel::NotifyResourceTypeStats(
base::ProcessId renderer_id,
const WebKit::WebCache::ResourceTypeStats& stats) {
@@ -962,6 +976,10 @@ void TaskManager::OnWindowClosed() {
model_->StopUpdating();
}
+void TaskManager::ModelChanged() {
+ model_->ModelChanged();
+}
+
// static
TaskManager* TaskManager::GetInstance() {
return Singleton<TaskManager>::get();
diff --git a/chrome/browser/task_manager/task_manager.h b/chrome/browser/task_manager/task_manager.h
index cef241c..9d933e5 100644
--- a/chrome/browser/task_manager/task_manager.h
+++ b/chrome/browser/task_manager/task_manager.h
@@ -102,6 +102,10 @@ class TaskManager {
const WebKit::WebCache::ResourceTypeStats& stats) {}
virtual void NotifyV8HeapStats(size_t v8_memory_allocated,
size_t v8_memory_used) {}
+
+ // Returns true if this resource is not visible to the user because it lives
+ // in the background (e.g. extension background page, background contents).
+ virtual bool IsBackground() const { return false; }
};
// ResourceProviders are responsible for adding/removing resources to the task
@@ -156,6 +160,12 @@ class TaskManager {
void OnWindowClosed();
+ // Invoked when a change to a resource has occurred that should cause any
+ // observers to completely refresh themselves (for example, the creation of
+ // a background resource in a process). Results in all observers receiving
+ // OnModelChanged() events.
+ void ModelChanged();
+
// Returns the singleton instance (and initializes it if necessary).
static TaskManager* GetInstance();
@@ -259,6 +269,10 @@ class TaskManagerModel : public URLRequestJobTracker::JobObserver,
// rendered by the same process are groupped together).
bool IsResourceFirstInGroup(int index) const;
+ // Returns true if the resource runs in the background (not visible to the
+ // user, e.g. extension background pages and BackgroundContents).
+ bool IsBackgroundResource(int index) const;
+
// Returns icon to be used for resource (for example a favicon).
SkBitmap GetResourceIcon(int index) const;
@@ -300,6 +314,10 @@ class TaskManagerModel : public URLRequestJobTracker::JobObserver,
void Clear(); // Removes all items.
+ // Sends OnModelChanged() to all observers to inform them of significant
+ // changes to the model.
+ void ModelChanged();
+
void NotifyResourceTypeStats(
base::ProcessId renderer_id,
const WebKit::WebCache::ResourceTypeStats& stats);
diff --git a/chrome/browser/task_manager/task_manager_browsertest.cc b/chrome/browser/task_manager/task_manager_browsertest.cc
index 9e3c181..91cc23d 100644
--- a/chrome/browser/task_manager/task_manager_browsertest.cc
+++ b/chrome/browser/task_manager/task_manager_browsertest.cc
@@ -7,18 +7,20 @@
#include "app/l10n_util.h"
#include "base/file_path.h"
#include "base/utf_string_conversions.h"
-#include "chrome/browser/browser.h"
-#include "chrome/browser/browser_navigator.h"
+#include "chrome/browser/background_contents_service.h"
#include "chrome/browser/browser_process.h"
-#include "chrome/browser/browser_window.h"
#include "chrome/browser/extensions/crashed_extension_infobar.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/notifications/desktop_notification_service.h"
#include "chrome/browser/notifications/notification_test_util.h"
#include "chrome/browser/notifications/notification_ui_manager.h"
+#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/infobar_delegate.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_navigator.h"
+#include "chrome/browser/ui/browser_window.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/page_transition_types.h"
#include "chrome/test/in_process_browser_test.h"
@@ -118,6 +120,34 @@ IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, NoticeTabContentsChanges) {
WaitForResourceChange(2);
}
+IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, NoticeBGContentsChanges) {
+ EXPECT_EQ(0, model()->ResourceCount());
+
+ // Show the task manager. This populates the model, and helps with debugging
+ // (you see the task manager).
+ browser()->window()->ShowTaskManager();
+
+ // Browser and the New Tab Page.
+ EXPECT_EQ(2, model()->ResourceCount());
+
+ // Open a new background contents and make sure we notice that.
+ GURL url(ui_test_utils::GetTestUrl(FilePath(FilePath::kCurrentDirectory),
+ FilePath(kTitle1File)));
+
+ BackgroundContentsService* service =
+ browser()->profile()->GetBackgroundContentsService();
+ string16 application_id(ASCIIToUTF16("test_app_id"));
+ service->LoadBackgroundContents(browser()->profile(),
+ url,
+ ASCIIToUTF16("background_page"),
+ application_id);
+ WaitForResourceChange(3);
+
+ // Close the background contents and verify that we notice.
+ service->ShutdownAssociatedBackgroundContents(application_id);
+ WaitForResourceChange(2);
+}
+
#if defined(OS_WIN)
// http://crbug.com/31663
#define MAYBE_NoticeExtensionChanges DISABLED_NoticeExtensionChanges
diff --git a/chrome/browser/task_manager/task_manager_resource_providers.cc b/chrome/browser/task_manager/task_manager_resource_providers.cc
index 0c3d5d8..73476c9 100644
--- a/chrome/browser/task_manager/task_manager_resource_providers.cc
+++ b/chrome/browser/task_manager/task_manager_resource_providers.cc
@@ -15,13 +15,16 @@
#include "base/stl_util-inl.h"
#include "base/string_util.h"
#include "base/thread.h"
+#include "base/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/background_contents_service.h"
#include "chrome/browser/browser_child_process_host.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_thread.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_process_manager.h"
+#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/notifications/balloon_collection.h"
#include "chrome/browser/notifications/balloon_host.h"
#include "chrome/browser/notifications/notification_ui_manager.h"
@@ -29,8 +32,9 @@
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/resource_message_filter.h"
-#include "chrome/browser/tab_contents/tab_util.h"
+#include "chrome/browser/tab_contents/background_contents.h"
#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/render_messages.h"
@@ -46,20 +50,20 @@
#include "gfx/icon_util.h"
#endif // defined(OS_WIN)
+
////////////////////////////////////////////////////////////////////////////////
-// TaskManagerTabContentsResource class
+// TaskManagerRendererResource class
////////////////////////////////////////////////////////////////////////////////
-
-TaskManagerTabContentsResource::TaskManagerTabContentsResource(
- TabContents* tab_contents)
- : tab_contents_(tab_contents),
+TaskManagerRendererResource::TaskManagerRendererResource(
+ base::ProcessHandle process, RenderViewHost* render_view_host)
+ : process_(process),
+ render_view_host_(render_view_host),
pending_stats_update_(false),
v8_memory_allocated_(0),
v8_memory_used_(0),
pending_v8_memory_allocated_update_(false) {
- // We cache the process as when the TabContents is closed the process
- // becomes NULL and the TaskManager still needs it.
- process_ = tab_contents_->GetRenderProcessHost()->GetHandle();
+ // We cache the process and pid as when a Tab/BackgroundContents is closed the
+ // process reference becomes NULL and the TaskManager still needs it.
pid_ = base::GetProcId(process_);
stats_.images.size = 0;
stats_.cssStyleSheets.size = 0;
@@ -68,76 +72,92 @@ TaskManagerTabContentsResource::TaskManagerTabContentsResource(
stats_.fonts.size = 0;
}
-TaskManagerTabContentsResource::~TaskManagerTabContentsResource() {
+TaskManagerRendererResource::~TaskManagerRendererResource() {
}
-std::wstring TaskManagerTabContentsResource::GetTitle() const {
- // Fall back on the URL if there's no title.
- std::wstring tab_title(UTF16ToWideHack(tab_contents_->GetTitle()));
- if (tab_title.empty()) {
- tab_title = UTF8ToWide(tab_contents_->GetURL().spec());
- // Force URL to be LTR.
- tab_title = UTF16ToWide(base::i18n::GetDisplayStringInLTRDirectionality(
- WideToUTF16(tab_title)));
- } else {
- // Since the tab_title will be concatenated with
- // IDS_TASK_MANAGER_TAB_PREFIX, we need to explicitly set the tab_title to
- // be LTR format if there is no strong RTL charater in it. Otherwise, if
- // IDS_TASK_MANAGER_TAB_PREFIX is an RTL word, the concatenated result
- // might be wrong. For example, http://mail.yahoo.com, whose title is
- // "Yahoo! Mail: The best web-based Email!", without setting it explicitly
- // as LTR format, the concatenated result will be "!Yahoo! Mail: The best
- // web-based Email :BAT", in which the capital letters "BAT" stands for
- // the Hebrew word for "tab".
- base::i18n::AdjustStringForLocaleDirection(tab_title, &tab_title);
- }
-
- return l10n_util::GetStringF(IDS_TASK_MANAGER_TAB_PREFIX, tab_title);
-}
-
-void TaskManagerTabContentsResource::Refresh() {
+void TaskManagerRendererResource::Refresh() {
if (!pending_stats_update_) {
- tab_contents_->render_view_host()->Send(new ViewMsg_GetCacheResourceStats);
+ render_view_host_->Send(new ViewMsg_GetCacheResourceStats);
pending_stats_update_ = true;
}
if (!pending_v8_memory_allocated_update_) {
- tab_contents_->render_view_host()->Send(new ViewMsg_GetV8HeapStats);
+ render_view_host_->Send(new ViewMsg_GetV8HeapStats);
pending_v8_memory_allocated_update_ = true;
}
}
WebKit::WebCache::ResourceTypeStats
- TaskManagerTabContentsResource::GetWebCoreCacheStats() const {
+TaskManagerRendererResource::GetWebCoreCacheStats() const {
return stats_;
}
-size_t TaskManagerTabContentsResource::GetV8MemoryAllocated() const {
+size_t TaskManagerRendererResource::GetV8MemoryAllocated() const {
return v8_memory_allocated_;
}
-size_t TaskManagerTabContentsResource::GetV8MemoryUsed() const {
+size_t TaskManagerRendererResource::GetV8MemoryUsed() const {
return v8_memory_used_;
}
-void TaskManagerTabContentsResource::NotifyResourceTypeStats(
+void TaskManagerRendererResource::NotifyResourceTypeStats(
const WebKit::WebCache::ResourceTypeStats& stats) {
stats_ = stats;
pending_stats_update_ = false;
}
-void TaskManagerTabContentsResource::NotifyV8HeapStats(
+void TaskManagerRendererResource::NotifyV8HeapStats(
size_t v8_memory_allocated, size_t v8_memory_used) {
v8_memory_allocated_ = v8_memory_allocated;
v8_memory_used_ = v8_memory_used;
pending_v8_memory_allocated_update_ = false;
}
-SkBitmap TaskManagerTabContentsResource::GetIcon() const {
- return tab_contents_->GetFavIcon();
+base::ProcessHandle TaskManagerRendererResource::GetProcess() const {
+ return process_;
}
-base::ProcessHandle TaskManagerTabContentsResource::GetProcess() const {
- return process_;
+////////////////////////////////////////////////////////////////////////////////
+// TaskManagerTabContentsResource class
+////////////////////////////////////////////////////////////////////////////////
+
+TaskManagerTabContentsResource::TaskManagerTabContentsResource(
+ TabContents* tab_contents)
+ : TaskManagerRendererResource(
+ tab_contents->GetRenderProcessHost()->GetHandle(),
+ tab_contents->render_view_host()),
+ tab_contents_(tab_contents) {
+}
+
+TaskManagerTabContentsResource::~TaskManagerTabContentsResource() {
+}
+
+std::wstring TaskManagerTabContentsResource::GetTitle() const {
+ // Fall back on the URL if there's no title.
+ std::wstring tab_title(UTF16ToWideHack(tab_contents_->GetTitle()));
+ if (tab_title.empty()) {
+ tab_title = UTF8ToWide(tab_contents_->GetURL().spec());
+ // Force URL to be LTR.
+ tab_title = UTF16ToWide(base::i18n::GetDisplayStringInLTRDirectionality(
+ WideToUTF16(tab_title)));
+ } else {
+ // Since the tab_title will be concatenated with
+ // IDS_TASK_MANAGER_TAB_PREFIX, we need to explicitly set the tab_title to
+ // be LTR format if there is no strong RTL charater in it. Otherwise, if
+ // IDS_TASK_MANAGER_TAB_PREFIX is an RTL word, the concatenated result
+ // might be wrong. For example, http://mail.yahoo.com, whose title is
+ // "Yahoo! Mail: The best web-based Email!", without setting it explicitly
+ // as LTR format, the concatenated result will be "!Yahoo! Mail: The best
+ // web-based Email :BAT", in which the capital letters "BAT" stands for
+ // the Hebrew word for "tab".
+ base::i18n::AdjustStringForLocaleDirection(tab_title, &tab_title);
+ }
+
+ return l10n_util::GetStringF(IDS_TASK_MANAGER_TAB_PREFIX, tab_title);
+}
+
+
+SkBitmap TaskManagerTabContentsResource::GetIcon() const {
+ return tab_contents_->GetFavIcon();
}
TabContents* TaskManagerTabContentsResource::GetTabContents() const {
@@ -183,11 +203,11 @@ TaskManager::Resource* TaskManagerTabContentsResourceProvider::GetResource(
std::map<TabContents*, TaskManagerTabContentsResource*>::iterator
res_iter = resources_.find(tab_contents);
- if (res_iter == resources_.end())
+ if (res_iter == resources_.end()) {
// Can happen if the tab was closed while a network request was being
// performed.
return NULL;
-
+ }
return res_iter->second;
}
@@ -316,6 +336,253 @@ void TaskManagerTabContentsResourceProvider::Observe(NotificationType type,
}
////////////////////////////////////////////////////////////////////////////////
+// TaskManagerBackgroundContentsResource class
+////////////////////////////////////////////////////////////////////////////////
+
+SkBitmap* TaskManagerBackgroundContentsResource::default_icon_ = NULL;
+
+TaskManagerBackgroundContentsResource::TaskManagerBackgroundContentsResource(
+ BackgroundContents* background_contents,
+ const std::wstring& application_name)
+ : TaskManagerRendererResource(
+ background_contents->render_view_host()->process()->GetHandle(),
+ background_contents->render_view_host()),
+ background_contents_(background_contents),
+ application_name_(application_name) {
+ // Just use the same icon that other extension resources do.
+ // TODO(atwilson): Use the favicon when that's available.
+ if (!default_icon_) {
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ default_icon_ = rb.GetBitmapNamed(IDR_PLUGIN);
+ }
+ // Ensure that the string has the appropriate direction markers (see comment
+ // in TaskManagerTabContentsResource::GetTitle()).
+ base::i18n::AdjustStringForLocaleDirection(application_name_,
+ &application_name_);
+}
+
+TaskManagerBackgroundContentsResource::~TaskManagerBackgroundContentsResource(
+ ) {
+}
+
+std::wstring TaskManagerBackgroundContentsResource::GetTitle() const {
+ std::wstring title = application_name_;
+
+ if (title.empty()) {
+ // No title (can't locate the parent app for some reason) so just display
+ // the URL (properly forced to be LTR).
+ title = UTF16ToWide(base::i18n::GetDisplayStringInLTRDirectionality(
+ UTF8ToUTF16(background_contents_->GetURL().spec())));
+ }
+ return l10n_util::GetStringF(IDS_TASK_MANAGER_BACKGROUND_PREFIX, title);
+}
+
+
+SkBitmap TaskManagerBackgroundContentsResource::GetIcon() const {
+ return *default_icon_;
+}
+
+bool TaskManagerBackgroundContentsResource::IsBackground() const {
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// TaskManagerBackgroundContentsResourceProvider class
+////////////////////////////////////////////////////////////////////////////////
+
+TaskManagerBackgroundContentsResourceProvider::
+ TaskManagerBackgroundContentsResourceProvider(TaskManager* task_manager)
+ : updating_(false),
+ task_manager_(task_manager) {
+}
+
+TaskManagerBackgroundContentsResourceProvider::
+ ~TaskManagerBackgroundContentsResourceProvider() {
+}
+
+TaskManager::Resource*
+TaskManagerBackgroundContentsResourceProvider::GetResource(
+ int origin_pid,
+ int render_process_host_id,
+ int routing_id) {
+
+ BackgroundContents* contents = BackgroundContents::GetBackgroundContentsByID(
+ render_process_host_id, routing_id);
+ if (!contents) // This resource no longer exists.
+ return NULL;
+
+ base::ProcessHandle process_handle =
+ contents->render_view_host()->process()->GetHandle();
+ if (!process_handle) // Process crashed.
+ return NULL;
+
+ int pid = base::GetProcId(process_handle);
+ if (pid != origin_pid)
+ return NULL;
+
+ std::map<BackgroundContents*,
+ TaskManagerBackgroundContentsResource*>::iterator res_iter =
+ resources_.find(contents);
+ if (res_iter == resources_.end())
+ // Can happen if the page went away while a network request was being
+ // performed.
+ return NULL;
+
+ return res_iter->second;
+}
+
+void TaskManagerBackgroundContentsResourceProvider::StartUpdating() {
+ DCHECK(!updating_);
+ updating_ = true;
+
+ // Add all the existing BackgroundContents from every profile.
+ ProfileManager* profile_manager = g_browser_process->profile_manager();
+ for (ProfileManager::const_iterator it = profile_manager->begin();
+ it != profile_manager->end(); ++it) {
+ BackgroundContentsService* background_contents_service =
+ (*it)->GetBackgroundContentsService();
+ ExtensionsService* extensions_service = (*it)->GetExtensionsService();
+ std::vector<BackgroundContents*> contents =
+ background_contents_service->GetBackgroundContents();
+ for (std::vector<BackgroundContents*>::iterator iterator = contents.begin();
+ iterator != contents.end(); ++iterator) {
+ std::wstring application_name;
+ // Lookup the name from the parent extension.
+ if (extensions_service) {
+ const string16& application_id =
+ background_contents_service->GetParentApplicationId(*iterator);
+ const Extension* extension = extensions_service->GetExtensionById(
+ UTF16ToUTF8(application_id), false);
+ if (extension)
+ application_name = UTF8ToWide(extension->name());
+ }
+ Add(*iterator, application_name);
+ }
+ }
+
+ // Then we register for notifications to get new BackgroundContents.
+ registrar_.Add(this, NotificationType::BACKGROUND_CONTENTS_OPENED,
+ NotificationService::AllSources());
+ registrar_.Add(this, NotificationType::BACKGROUND_CONTENTS_NAVIGATED,
+ NotificationService::AllSources());
+ registrar_.Add(this, NotificationType::BACKGROUND_CONTENTS_DELETED,
+ NotificationService::AllSources());
+}
+
+void TaskManagerBackgroundContentsResourceProvider::StopUpdating() {
+ DCHECK(updating_);
+ updating_ = false;
+
+ // Unregister for notifications
+ registrar_.Remove(this, NotificationType::BACKGROUND_CONTENTS_OPENED,
+ NotificationService::AllSources());
+ registrar_.Remove(this, NotificationType::BACKGROUND_CONTENTS_NAVIGATED,
+ NotificationService::AllSources());
+ registrar_.Remove(this, NotificationType::BACKGROUND_CONTENTS_DELETED,
+ NotificationService::AllSources());
+
+ // Delete all the resources.
+ STLDeleteContainerPairSecondPointers(resources_.begin(), resources_.end());
+
+ resources_.clear();
+}
+
+void TaskManagerBackgroundContentsResourceProvider::AddToTaskManager(
+ BackgroundContents* background_contents,
+ const std::wstring& application_name) {
+ TaskManagerBackgroundContentsResource* resource =
+ new TaskManagerBackgroundContentsResource(background_contents,
+ application_name);
+ resources_[background_contents] = resource;
+ task_manager_->AddResource(resource);
+}
+
+void TaskManagerBackgroundContentsResourceProvider::Add(
+ BackgroundContents* contents, const std::wstring& application_name) {
+ if (!updating_)
+ return;
+
+ // Don't add contents whose process is dead.
+ if (!contents->render_view_host()->process()->GetHandle())
+ return;
+
+ // Should never add the same BackgroundContents twice.
+ DCHECK(resources_.find(contents) == resources_.end());
+ AddToTaskManager(contents, application_name);
+}
+
+void TaskManagerBackgroundContentsResourceProvider::Remove(
+ BackgroundContents* contents) {
+ if (!updating_)
+ return;
+ std::map<BackgroundContents*,
+ TaskManagerBackgroundContentsResource*>::iterator iter =
+ resources_.find(contents);
+ DCHECK(iter != resources_.end());
+
+ // Remove the resource from the Task Manager.
+ TaskManagerBackgroundContentsResource* resource = iter->second;
+ task_manager_->RemoveResource(resource);
+ // And from the provider.
+ resources_.erase(iter);
+ // Finally, delete the resource.
+ delete resource;
+}
+
+void TaskManagerBackgroundContentsResourceProvider::Observe(
+ NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ switch (type.value) {
+ case NotificationType::BACKGROUND_CONTENTS_OPENED: {
+ // Get the name from the parent application. If no parent application is
+ // found, just pass an empty string - BackgroundContentsResource::GetTitle
+ // will display the URL instead in this case. This should never happen
+ // except in rare cases when an extension is being unloaded or chrome is
+ // exiting while the task manager is displayed.
+ std::wstring application_name;
+ ExtensionsService* service =
+ Source<Profile>(source)->GetExtensionsService();
+ if (service) {
+ std::string application_id = UTF16ToUTF8(
+ Details<BackgroundContentsOpenedDetails>(details)->application_id);
+ const Extension* extension =
+ service->GetExtensionById(application_id, false);
+ // Extension can be NULL when running unit tests.
+ if (extension)
+ application_name = UTF8ToWide(extension->name());
+ }
+ Add(Details<BackgroundContentsOpenedDetails>(details)->contents,
+ application_name);
+ // Opening a new BackgroundContents needs to force the display to refresh
+ // (applications may now be considered "background" that weren't before).
+ task_manager_->ModelChanged();
+ break;
+ }
+ case NotificationType::BACKGROUND_CONTENTS_NAVIGATED: {
+ BackgroundContents* contents = Details<BackgroundContents>(details).ptr();
+ // Should never get a NAVIGATED before OPENED.
+ DCHECK(resources_.find(contents) != resources_.end());
+ // Preserve the application name.
+ std::wstring application_name(
+ resources_.find(contents)->second->application_name());
+ Remove(contents);
+ Add(contents, application_name);
+ break;
+ }
+ case NotificationType::BACKGROUND_CONTENTS_DELETED:
+ Remove(Details<BackgroundContents>(details).ptr());
+ // Closing a BackgroundContents needs to force the display to refresh
+ // (applications may now be considered "foreground" that weren't before).
+ task_manager_->ModelChanged();
+ break;
+ default:
+ NOTREACHED() << "Unexpected notification.";
+ return;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
// TaskManagerChildProcessResource class
////////////////////////////////////////////////////////////////////////////////
SkBitmap* TaskManagerChildProcessResource::default_icon_ = NULL;
@@ -590,6 +857,11 @@ const Extension* TaskManagerExtensionProcessResource::GetExtension() const {
return extension_host_->extension();
}
+bool TaskManagerExtensionProcessResource::IsBackground() const {
+ return extension_host_->GetRenderViewType() ==
+ ViewType::EXTENSION_BACKGROUND_PAGE;
+}
+
////////////////////////////////////////////////////////////////////////////////
// TaskManagerExtensionProcessResourceProvider class
////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/task_manager/task_manager_resource_providers.h b/chrome/browser/task_manager/task_manager_resource_providers.h
index 5145a7e..9c4e8c4 100644
--- a/chrome/browser/task_manager/task_manager_resource_providers.h
+++ b/chrome/browser/task_manager/task_manager_resource_providers.h
@@ -17,33 +17,33 @@
#include "chrome/common/notification_registrar.h"
#include "third_party/WebKit/WebKit/chromium/public/WebCache.h"
+class BackgroundContents;
class BalloonHost;
class Extension;
class ExtensionHost;
+class RenderViewHost;
class TabContents;
// These file contains the resource providers used in the task manager.
-class TaskManagerTabContentsResource : public TaskManager::Resource {
+// Base class for various types of render process resources that provides common
+// functionality like stats tracking.
+class TaskManagerRendererResource : public TaskManager::Resource {
public:
- explicit TaskManagerTabContentsResource(TabContents* tab_contents);
- ~TaskManagerTabContentsResource();
+ TaskManagerRendererResource(base::ProcessHandle process,
+ RenderViewHost* render_view_host);
+ virtual ~TaskManagerRendererResource();
- // TaskManagerResource methods:
- std::wstring GetTitle() const;
- SkBitmap GetIcon() const;
+ // TaskManager::Resource methods:
base::ProcessHandle GetProcess() const;
Type GetType() const { return RENDERER; }
- TabContents* GetTabContents() const;
-
virtual bool ReportsCacheStats() const { return true; }
virtual WebKit::WebCache::ResourceTypeStats GetWebCoreCacheStats() const;
-
virtual bool ReportsV8MemoryStats() const { return true; }
virtual size_t GetV8MemoryAllocated() const;
virtual size_t GetV8MemoryUsed() const;
- // TabContents always provide the network usage.
+ // RenderResources always provide the network usage.
bool SupportNetworkUsage() const { return true; }
void SetSupportNetworkUsage() { }
@@ -56,9 +56,11 @@ class TaskManagerTabContentsResource : public TaskManager::Resource {
size_t v8_memory_used);
private:
- TabContents* tab_contents_;
base::ProcessHandle process_;
int pid_;
+
+ // RenderViewHost we use to fetch stats.
+ RenderViewHost* render_view_host_;
// The stats_ field holds information about resource usage in the renderer
// process and so it is updated asynchronously by the Refresh() call.
WebKit::WebCache::ResourceTypeStats stats_;
@@ -70,6 +72,22 @@ class TaskManagerTabContentsResource : public TaskManager::Resource {
size_t v8_memory_used_;
bool pending_v8_memory_allocated_update_;
+ DISALLOW_COPY_AND_ASSIGN(TaskManagerRendererResource);
+};
+
+class TaskManagerTabContentsResource : public TaskManagerRendererResource {
+ public:
+ explicit TaskManagerTabContentsResource(TabContents* tab_contents);
+ ~TaskManagerTabContentsResource();
+
+ // TaskManager::Resource methods:
+ virtual std::wstring GetTitle() const;
+ virtual SkBitmap GetIcon() const;
+ virtual TabContents* GetTabContents() const;
+
+ private:
+ TabContents* tab_contents_;
+
DISALLOW_COPY_AND_ASSIGN(TaskManagerTabContentsResource);
};
@@ -114,6 +132,77 @@ class TaskManagerTabContentsResourceProvider
DISALLOW_COPY_AND_ASSIGN(TaskManagerTabContentsResourceProvider);
};
+class TaskManagerBackgroundContentsResource
+ : public TaskManagerRendererResource {
+ public:
+ TaskManagerBackgroundContentsResource(
+ BackgroundContents* background_contents,
+ const std::wstring& application_name);
+ ~TaskManagerBackgroundContentsResource();
+
+ // TaskManager::Resource methods:
+ virtual std::wstring GetTitle() const;
+ virtual SkBitmap GetIcon() const;
+ virtual bool IsBackground() const;
+
+ const std::wstring& application_name() const { return application_name_; }
+ private:
+ BackgroundContents* background_contents_;
+
+ std::wstring application_name_;
+
+ // The icon painted for BackgroundContents.
+ // TODO(atwilson): Use the favicon when there's a way to get the favicon for
+ // BackgroundContents.
+ static SkBitmap* default_icon_;
+
+ DISALLOW_COPY_AND_ASSIGN(TaskManagerBackgroundContentsResource);
+};
+
+class TaskManagerBackgroundContentsResourceProvider
+ : public TaskManager::ResourceProvider,
+ public NotificationObserver {
+ public:
+ explicit TaskManagerBackgroundContentsResourceProvider(
+ TaskManager* task_manager);
+
+ virtual TaskManager::Resource* GetResource(int origin_pid,
+ int render_process_host_id,
+ int routing_id);
+ virtual void StartUpdating();
+ virtual void StopUpdating();
+
+ // NotificationObserver method:
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ private:
+ virtual ~TaskManagerBackgroundContentsResourceProvider();
+
+ void Add(BackgroundContents* background_contents, const std::wstring& title);
+ void Remove(BackgroundContents* background_contents);
+
+ void AddToTaskManager(BackgroundContents* background_contents,
+ const std::wstring& title);
+
+ // Whether we are currently reporting to the task manager. Used to ignore
+ // notifications sent after StopUpdating().
+ bool updating_;
+
+ TaskManager* task_manager_;
+
+ // Maps the actual resources (the BackgroundContents) to the Task Manager
+ // resources.
+ std::map<BackgroundContents*, TaskManagerBackgroundContentsResource*>
+ resources_;
+
+ // A scoped container for notification registries.
+ NotificationRegistrar registrar_;
+
+ DISALLOW_COPY_AND_ASSIGN(TaskManagerBackgroundContentsResourceProvider);
+};
+
class TaskManagerChildProcessResource : public TaskManager::Resource {
public:
explicit TaskManagerChildProcessResource(const ChildProcessInfo& child_proc);
@@ -221,6 +310,8 @@ class TaskManagerExtensionProcessResource : public TaskManager::Resource {
// Returns the pid of the extension process.
int process_id() const { return pid_; }
+ // Returns true if the associated extension has a background page.
+ bool IsBackground() const;
private:
// The icon painted for the extension process.
static SkBitmap* default_icon_;