diff options
author | creis@google.com <creis@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-19 21:47:11 +0000 |
---|---|---|
committer | creis@google.com <creis@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-19 21:47:11 +0000 |
commit | 8a661f84e6e4ab569de30228b717f0c2b26a1d57 (patch) | |
tree | 8e4eed99ddb033b7cdc8489b2264659775f7b0cc | |
parent | 293309b27926f9ab2d2567b7e0f2fd04e568a50c (diff) | |
download | chromium_src-8a661f84e6e4ab569de30228b717f0c2b26a1d57.zip chromium_src-8a661f84e6e4ab569de30228b717f0c2b26a1d57.tar.gz chromium_src-8a661f84e6e4ab569de30228b717f0c2b26a1d57.tar.bz2 |
Expands the chrome.experimental.processes extension API.
Adds an onUpdated event that reports process metrics from the TaskManager,
and modifies the TaskManager to support multiple independent observers.
BUG=32302
TEST=ExtensionApiTest.Processes browsertest
TEST=process_monitor sample extension
Review URL: http://codereview.chromium.org/3801008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@63116 0039d316-1c4b-4281-b951-d872f2087c98
32 files changed, 1198 insertions, 195 deletions
diff --git a/chrome/browser/cocoa/task_manager_mac_unittest.mm b/chrome/browser/cocoa/task_manager_mac_unittest.mm index a1e6b29..c82928b 100644 --- a/chrome/browser/cocoa/task_manager_mac_unittest.mm +++ b/chrome/browser/cocoa/task_manager_mac_unittest.mm @@ -22,6 +22,7 @@ class TestResource : public TaskManager::Resource { virtual std::wstring GetTitle() const { return UTF16ToWide(title_); } virtual SkBitmap GetIcon() const { return SkBitmap(); } virtual base::ProcessHandle GetProcess() const { return pid_; } + virtual Type GetType() const { return RENDERER; } virtual bool SupportNetworkUsage() const { return false; } virtual void SetSupportNetworkUsage() { NOTREACHED(); } virtual void Refresh() {} diff --git a/chrome/browser/extensions/extension_event_router.cc b/chrome/browser/extensions/extension_event_router.cc index 830f8ca5..5e2707e 100644 --- a/chrome/browser/extensions/extension_event_router.cc +++ b/chrome/browser/extensions/extension_event_router.cc @@ -7,6 +7,8 @@ #include "base/values.h" #include "chrome/browser/child_process_security_policy.h" #include "chrome/browser/extensions/extension_devtools_manager.h" +#include "chrome/browser/extensions/extension_processes_api.h" +#include "chrome/browser/extensions/extension_processes_api_constants.h" #include "chrome/browser/extensions/extension_tabs_module.h" #include "chrome/browser/profile.h" #include "chrome/browser/renderer_host/render_process_host.h" @@ -62,6 +64,11 @@ void ExtensionEventRouter::AddEventListener( extension_devtools_manager_->AddEventListener(event_name, render_process_id); } + + // We lazily tell the TaskManager to start updating when listeners to the + // processes.onUpdated event arrive. + if (event_name.compare(extension_processes_api_constants::kOnUpdated) == 0) + ExtensionProcessesEventRouter::GetInstance()->ListenerAdded(); } void ExtensionEventRouter::RemoveEventListener( @@ -75,6 +82,11 @@ void ExtensionEventRouter::RemoveEventListener( extension_devtools_manager_->RemoveEventListener(event_name, render_process_id); } + + // If a processes.onUpdated event listener is removed (or a process with one + // exits), then we let the TaskManager know that it has one fewer listener. + if (event_name.compare(extension_processes_api_constants::kOnUpdated) == 0) + ExtensionProcessesEventRouter::GetInstance()->ListenerRemoved(); } bool ExtensionEventRouter::HasEventListener(const std::string& event_name) { diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc index 621b5b4..7a99137 100644 --- a/chrome/browser/extensions/extension_function_dispatcher.cc +++ b/chrome/browser/extensions/extension_function_dispatcher.cc @@ -193,7 +193,7 @@ void FactoryRegistry::ResetFunctions() { RegisterFunction<PopupShowFunction>(); // Processes. - RegisterFunction<GetProcessForTabFunction>(); + RegisterFunction<GetProcessIdForTabFunction>(); // Metrics. RegisterFunction<MetricsRecordUserActionFunction>(); diff --git a/chrome/browser/extensions/extension_processes_api.cc b/chrome/browser/extensions/extension_processes_api.cc index 1c6c8dc..2246965 100644 --- a/chrome/browser/extensions/extension_processes_api.cc +++ b/chrome/browser/extensions/extension_processes_api.cc @@ -4,33 +4,174 @@ #include "chrome/browser/extensions/extension_processes_api.h" +#include "base/callback.h" +#include "base/json/json_writer.h" +#include "base/message_loop.h" +#include "base/string_number_conversions.h" +#include "base/task.h" +#include "base/utf_string_conversions.h" #include "base/values.h" -#include "chrome/browser/extensions/extension_tabs_module.h" +#include "chrome/browser/extensions/extension_event_router.h" #include "chrome/browser/extensions/extension_processes_api_constants.h" +#include "chrome/browser/extensions/extension_tabs_module.h" +#include "chrome/browser/extensions/extension_tabs_module_constants.h" +#include "chrome/browser/profile.h" #include "chrome/browser/renderer_host/render_process_host.h" #include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/task_manager/task_manager.h" +#include "chrome/common/extensions/extension_error_utils.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/notification_type.h" namespace keys = extension_processes_api_constants; -DictionaryValue* CreateProcessValue(int process_id) { +DictionaryValue* CreateProcessValue(int process_id, + std::string type, + double cpu, + int64 net, + int64 pr_mem, + int64 sh_mem) { DictionaryValue* result = new DictionaryValue(); result->SetInteger(keys::kIdKey, process_id); - + result->SetString(keys::kTypeKey, type); + result->SetReal(keys::kCpuKey, cpu); + result->SetReal(keys::kNetworkKey, static_cast<double>(net)); + result->SetReal(keys::kPrivateMemoryKey, static_cast<double>(pr_mem)); + result->SetReal(keys::kSharedMemoryKey, static_cast<double>(sh_mem)); return result; } -bool GetProcessForTabFunction::RunImpl() { +ExtensionProcessesEventRouter* ExtensionProcessesEventRouter::GetInstance() { + return Singleton<ExtensionProcessesEventRouter>::get(); +} + +ExtensionProcessesEventRouter::ExtensionProcessesEventRouter() { + model_ = TaskManager::GetInstance()->model(); + model_->AddObserver(this); +} + +ExtensionProcessesEventRouter::~ExtensionProcessesEventRouter() { + model_->RemoveObserver(this); +} + +void ExtensionProcessesEventRouter::ObserveProfile(Profile* profile) { + profiles_.insert(profile); +} + +void ExtensionProcessesEventRouter::ListenerAdded() { + model_->StartUpdating(); +} + +void ExtensionProcessesEventRouter::ListenerRemoved() { + model_->StopUpdating(); +} + +void ExtensionProcessesEventRouter::OnItemsChanged(int start, int length) { + if (model_) { + ListValue args; + DictionaryValue* processes = new DictionaryValue(); + for (int i = start; i < start + length; i++) { + if (model_->IsResourceFirstInGroup(i)) { + int id = model_->GetProcessId(i); + + // Determine process type + std::string type = keys::kProcessTypeOther; + TaskManager::Resource::Type resource_type = model_->GetResourceType(i); + switch (resource_type) { + case TaskManager::Resource::BROWSER: + type = keys::kProcessTypeBrowser; + break; + case TaskManager::Resource::RENDERER: + type = keys::kProcessTypeRenderer; + break; + case TaskManager::Resource::EXTENSION: + type = keys::kProcessTypeExtension; + break; + case TaskManager::Resource::NOTIFICATION: + type = keys::kProcessTypeNotification; + break; + case TaskManager::Resource::PLUGIN: + type = keys::kProcessTypePlugin; + break; + case TaskManager::Resource::WORKER: + type = keys::kProcessTypeWorker; + break; + case TaskManager::Resource::NACL: + type = keys::kProcessTypeNacl; + break; + case TaskManager::Resource::UTILITY: + type = keys::kProcessTypeUtility; + break; + case TaskManager::Resource::GPU: + type = keys::kProcessTypeGPU; + break; + case TaskManager::Resource::PROFILE_IMPORT: + case TaskManager::Resource::ZYGOTE: + case TaskManager::Resource::SANDBOX_HELPER: + case TaskManager::Resource::UNKNOWN: + type = keys::kProcessTypeOther; + break; + default: + NOTREACHED() << "Unknown resource type."; + } + + // Get process metrics as numbers + double cpu = model_->GetCPUUsage(i); + + // TODO(creis): Network is actually reported per-resource (tab), + // not per-process. We should aggregate it here. + int64 net = model_->GetNetworkUsage(i); + size_t mem; + int64 pr_mem = model_->GetPrivateMemory(i, &mem) ? + static_cast<int64>(mem) : -1; + int64 sh_mem = model_->GetSharedMemory(i, &mem) ? + static_cast<int64>(mem) : -1; + + // Store each process indexed by the string version of its id + processes->Set(base::IntToString(id), + CreateProcessValue(id, type, cpu, net, pr_mem, sh_mem)); + } + } + args.Append(processes); + + std::string json_args; + base::JSONWriter::Write(&args, false, &json_args); + + // Notify each profile that is interested. + for (ProfileSet::iterator it = profiles_.begin(); + it != profiles_.end(); it++) { + Profile* profile = *it; + DispatchEvent(profile, keys::kOnUpdated, json_args); + } + } +} + +void ExtensionProcessesEventRouter::DispatchEvent(Profile* profile, + const char* event_name, + const std::string& json_args) { + if (profile && profile->GetExtensionEventRouter()) { + profile->GetExtensionEventRouter()->DispatchEventToRenderers( + event_name, json_args, NULL, GURL()); + } +} + +bool GetProcessIdForTabFunction::RunImpl() { int tab_id; EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &tab_id)); TabContents* contents = NULL; int tab_index = -1; if (!ExtensionTabUtil::GetTabById(tab_id, profile(), include_incognito(), - NULL, NULL, &contents, &tab_index)) + NULL, NULL, &contents, &tab_index)) { + error_ = ExtensionErrorUtils::FormatErrorMessage( + extension_tabs_module_constants::kTabNotFoundError, + base::IntToString(tab_id)); return false; + } - int process_id = contents->GetRenderProcessHost()->id(); - result_.reset(CreateProcessValue(process_id)); + // Return the process ID of the tab as an integer. + int id = base::GetProcId(contents->GetRenderProcessHost()->GetHandle()); + result_.reset(Value::CreateIntegerValue(id)); return true; } diff --git a/chrome/browser/extensions/extension_processes_api.h b/chrome/browser/extensions/extension_processes_api.h index b58cb56..5eb54a1 100644 --- a/chrome/browser/extensions/extension_processes_api.h +++ b/chrome/browser/extensions/extension_processes_api.h @@ -6,14 +6,66 @@ #define CHROME_BROWSER_EXTENSIONS_EXTENSION_PROCESSES_API_H__ #pragma once +#include <set> +#include <string> + #include "chrome/browser/extensions/extension_function.h" +#include "chrome/browser/task_manager/task_manager.h" +#include "chrome/common/notification_observer.h" +#include "chrome/common/notification_registrar.h" + +// Observes the Task Manager and routes the notifications as events to the +// extension system. +class ExtensionProcessesEventRouter : public TaskManagerModelObserver { + public: + // Single instance of the event router. + static ExtensionProcessesEventRouter* GetInstance(); + + // Safe to call multiple times. + void ObserveProfile(Profile* profile); + + // Called when an extension process wants to listen to process events. + void ListenerAdded(); + + // Called when an extension process with a listener exits or removes it. + void ListenerRemoved(); + + private: + friend struct DefaultSingletonTraits<ExtensionProcessesEventRouter>; + + ExtensionProcessesEventRouter(); + virtual ~ExtensionProcessesEventRouter(); + + // TaskManagerModelObserver methods. + virtual void OnModelChanged() {} + virtual void OnItemsChanged(int start, int length); + virtual void OnItemsAdded(int start, int length) {} + virtual void OnItemsRemoved(int start, int length) {} + + void DispatchEvent(Profile* profile, + const char* event_name, + const std::string& json_args); + + // Used for tracking registrations to process related notifications. + NotificationRegistrar registrar_; + + // Registered profiles. + typedef std::set<Profile*> ProfileSet; + ProfileSet profiles_; + + // TaskManager to observe for updates. + TaskManagerModel* model_; + + DISALLOW_COPY_AND_ASSIGN(ExtensionProcessesEventRouter); +}; + // This extension function returns the Process object for the renderer process // currently in use by the specified Tab. -class GetProcessForTabFunction : public SyncExtensionFunction { - virtual ~GetProcessForTabFunction() {} +class GetProcessIdForTabFunction : public SyncExtensionFunction { + virtual ~GetProcessIdForTabFunction() {} virtual bool RunImpl(); - DECLARE_EXTENSION_FUNCTION_NAME("experimental.processes.getProcessForTab") + DECLARE_EXTENSION_FUNCTION_NAME("experimental.processes.getProcessIdForTab") }; #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_PROCESSES_API_H__ diff --git a/chrome/browser/extensions/extension_processes_api_constants.cc b/chrome/browser/extensions/extension_processes_api_constants.cc index bb0cccb..ecb226f 100644 --- a/chrome/browser/extensions/extension_processes_api_constants.cc +++ b/chrome/browser/extensions/extension_processes_api_constants.cc @@ -6,6 +6,25 @@ namespace extension_processes_api_constants { +const char kCpuKey[] = "cpu"; const char kIdKey[] = "id"; +const char kNetworkKey[] = "network"; +const char kPrivateMemoryKey[] = "privateMemory"; +const char kProcessesKey[] = "processes"; +const char kSharedMemoryKey[] = "sharedMemory"; +const char kTypeKey[] = "type"; + +const char kProcessTypeBrowser[] = "browser"; +const char kProcessTypeExtension[] = "extension"; +const char kProcessTypeGPU[] = "gpu"; +const char kProcessTypeNacl[] = "nacl"; +const char kProcessTypeNotification[] = "notification"; +const char kProcessTypeOther[] = "other"; +const char kProcessTypePlugin[] = "plugin"; +const char kProcessTypeRenderer[] = "renderer"; +const char kProcessTypeUtility[] = "utility"; +const char kProcessTypeWorker[] = "worker"; + +const char kOnUpdated[] = "experimental.processes.onUpdated"; } // namespace extension_processes_api_constants diff --git a/chrome/browser/extensions/extension_processes_api_constants.h b/chrome/browser/extensions/extension_processes_api_constants.h index 7e6c844..6f9bdea 100644 --- a/chrome/browser/extensions/extension_processes_api_constants.h +++ b/chrome/browser/extensions/extension_processes_api_constants.h @@ -10,8 +10,27 @@ namespace extension_processes_api_constants { -// Keys used in serializing tab data & events. +// Keys used in serializing process data & events. +extern const char kCpuKey[]; extern const char kIdKey[]; +extern const char kNetworkKey[]; +extern const char kPrivateMemoryKey[]; +extern const char kProcessesKey[]; +extern const char kSharedMemoryKey[]; +extern const char kTypeKey[]; + +extern const char kProcessTypeBrowser[]; +extern const char kProcessTypeExtension[]; +extern const char kProcessTypeGPU[]; +extern const char kProcessTypeNacl[]; +extern const char kProcessTypeNotification[]; +extern const char kProcessTypeOther[]; +extern const char kProcessTypePlugin[]; +extern const char kProcessTypeRenderer[]; +extern const char kProcessTypeUtility[]; +extern const char kProcessTypeWorker[]; + +extern const char kOnUpdated[]; }; // namespace extension_processes_api_constants diff --git a/chrome/browser/extensions/extension_processes_apitest.cc b/chrome/browser/extensions/extension_processes_apitest.cc index f5531d0..82f3f70 100644 --- a/chrome/browser/extensions/extension_processes_apitest.cc +++ b/chrome/browser/extensions/extension_processes_apitest.cc @@ -3,12 +3,46 @@ // found in the LICENSE file. #include "base/command_line.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/browser_window.h" #include "chrome/browser/extensions/extension_apitest.h" +#include "chrome/browser/extensions/extension_test_message_listener.h" +#include "chrome/browser/task_manager/task_manager.h" #include "chrome/common/chrome_switches.h" IN_PROC_BROWSER_TEST_F(ExtensionApiTest, Processes) { CommandLine::ForCurrentProcess()->AppendSwitch( switches::kEnableExperimentalExtensionApis); - ASSERT_TRUE(RunExtensionTest("processes")) << message_; + ASSERT_TRUE(RunExtensionTest("processes/api")) << message_; } + +IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProcessesVsTaskManager) { + CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kEnableExperimentalExtensionApis); + + // Ensure task manager is not yet updating + TaskManagerModel* model = TaskManager::GetInstance()->model(); + EXPECT_EQ(0, model->update_requests_); + EXPECT_EQ(TaskManagerModel::IDLE, model->update_state_); + + // Load extension that adds listener in background page + ExtensionTestMessageListener listener("ready", false); + ASSERT_TRUE(LoadExtension( + test_data_dir_.AppendASCII("processes").AppendASCII("onupdated"))); + ASSERT_TRUE(listener.WaitUntilSatisfied()); + + // Ensure the task manager has started updating + EXPECT_EQ(1, model->update_requests_); + EXPECT_EQ(TaskManagerModel::TASK_PENDING, model->update_state_); + + // Now show the task manager + browser()->window()->ShowTaskManager(); + EXPECT_EQ(2, model->update_requests_); + EXPECT_EQ(TaskManagerModel::TASK_PENDING, model->update_state_); + + // Unload the extension and check that listener count decreases + UnloadExtension(last_loaded_extension_id_); + EXPECT_EQ(1, model->update_requests_); +} + diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc index af187b15..33fade0 100644 --- a/chrome/browser/extensions/extensions_service.cc +++ b/chrome/browser/extensions/extensions_service.cc @@ -35,6 +35,7 @@ #include "chrome/browser/extensions/extension_host.h" #include "chrome/browser/extensions/extension_management_api.h" #include "chrome/browser/extensions/extension_process_manager.h" +#include "chrome/browser/extensions/extension_processes_api.h" #include "chrome/browser/extensions/extension_updater.h" #include "chrome/browser/extensions/extension_webnavigation_api.h" #include "chrome/browser/extensions/external_extension_provider.h" @@ -622,6 +623,7 @@ void ExtensionsService::InitEventRouters() { profile_->GetBookmarkModel()); ExtensionCookiesEventRouter::GetInstance()->Init(); ExtensionManagementEventRouter::GetInstance()->Init(); + ExtensionProcessesEventRouter::GetInstance()->ObserveProfile(profile_); ExtensionWebNavigationEventRouter::GetInstance()->Init(); event_routers_initialized_ = true; } diff --git a/chrome/browser/gtk/task_manager_gtk.cc b/chrome/browser/gtk/task_manager_gtk.cc index c03db6b8..ad7137d 100644 --- a/chrome/browser/gtk/task_manager_gtk.cc +++ b/chrome/browser/gtk/task_manager_gtk.cc @@ -486,6 +486,11 @@ void TaskManagerGtk::Init() { SetInitialDialogSize(); gtk_util::ShowDialog(dialog_); + // If the model already has resources, we need to add them before we start + // observing events. + if (model_->ResourceCount() > 0) + OnItemsAdded(0, model_->ResourceCount()); + model_->AddObserver(this); } diff --git a/chrome/browser/task_manager/task_manager.cc b/chrome/browser/task_manager/task_manager.cc index 0793a4d..2711925 100644 --- a/chrome/browser/task_manager/task_manager.cc +++ b/chrome/browser/task_manager/task_manager.cc @@ -70,7 +70,8 @@ string16 FormatStatsSize(const WebKit::WebCache::ResourceTypeStat& stat) { //////////////////////////////////////////////////////////////////////////////// TaskManagerModel::TaskManagerModel(TaskManager* task_manager) - : update_state_(IDLE), + : update_requests_(0), + update_state_(IDLE), goat_salt_(rand()) { TaskManagerBrowserProcessResourceProvider* browser_provider = @@ -115,13 +116,17 @@ void TaskManagerModel::RemoveObserver(TaskManagerModelObserver* observer) { } string16 TaskManagerModel::GetResourceTitle(int index) const { - DCHECK(index < ResourceCount()); + CHECK(index < ResourceCount()); return WideToUTF16Hack(resources_[index]->GetTitle()); } +int64 TaskManagerModel::GetNetworkUsage(int index) const { + CHECK(index < ResourceCount()); + return GetNetworkUsage(resources_[index]); +} + string16 TaskManagerModel::GetResourceNetworkUsage(int index) const { - DCHECK(index < ResourceCount()); - int64 net_usage = GetNetworkUsage(resources_[index]); + int64 net_usage = GetNetworkUsage(index); if (net_usage == -1) return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT); if (net_usage == 0) @@ -132,8 +137,13 @@ string16 TaskManagerModel::GetResourceNetworkUsage(int index) const { return base::i18n::GetDisplayStringInLTRDirectionality(net_byte); } +double TaskManagerModel::GetCPUUsage(int index) const { + CHECK(index < ResourceCount()); + return GetCPUUsage(resources_[index]); +} + string16 TaskManagerModel::GetResourceCPUUsage(int index) const { - DCHECK(index < ResourceCount()); + CHECK(index < ResourceCount()); return WideToUTF16Hack(StringPrintf( #if defined(OS_MACOSX) // Activity Monitor shows %cpu with one decimal digit -- be @@ -165,19 +175,23 @@ string16 TaskManagerModel::GetResourcePhysicalMemory(int index) const { return GetMemCellText(phys_mem); } +int TaskManagerModel::GetProcessId(int index) const { + CHECK(index < ResourceCount()); + return base::GetProcId(resources_[index]->GetProcess()); +} + string16 TaskManagerModel::GetResourceProcessId(int index) const { - DCHECK(index < ResourceCount()); - return base::IntToString16(base::GetProcId(resources_[index]->GetProcess())); + return base::IntToString16(GetProcessId(index)); } string16 TaskManagerModel::GetResourceGoatsTeleported(int index) const { - DCHECK(index < ResourceCount()); + CHECK(index < ResourceCount()); return base::FormatNumber(GetGoatsTeleported(index)); } string16 TaskManagerModel::GetResourceWebCoreImageCacheSize( int index) const { - DCHECK(index < ResourceCount()); + CHECK(index < ResourceCount()); if (!resources_[index]->ReportsCacheStats()) return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT); const WebKit::WebCache::ResourceTypeStats stats( @@ -187,7 +201,7 @@ string16 TaskManagerModel::GetResourceWebCoreImageCacheSize( string16 TaskManagerModel::GetResourceWebCoreScriptsCacheSize( int index) const { - DCHECK(index < ResourceCount()); + CHECK(index < ResourceCount()); if (!resources_[index]->ReportsCacheStats()) return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT); const WebKit::WebCache::ResourceTypeStats stats( @@ -197,7 +211,7 @@ string16 TaskManagerModel::GetResourceWebCoreScriptsCacheSize( string16 TaskManagerModel::GetResourceWebCoreCSSCacheSize( int index) const { - DCHECK(index < ResourceCount()); + CHECK(index < ResourceCount()); if (!resources_[index]->ReportsCacheStats()) return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT); const WebKit::WebCache::ResourceTypeStats stats( @@ -206,7 +220,7 @@ string16 TaskManagerModel::GetResourceWebCoreCSSCacheSize( } string16 TaskManagerModel::GetResourceSqliteMemoryUsed(int index) const { - DCHECK(index < ResourceCount()); + CHECK(index < ResourceCount()); if (!resources_[index]->ReportsSqliteMemoryUsed()) return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT); return GetMemCellText(resources_[index]->SqliteMemoryUsedBytes()); @@ -226,7 +240,7 @@ string16 TaskManagerModel::GetResourceV8MemoryAllocatedSize( } bool TaskManagerModel::IsResourceFirstInGroup(int index) const { - DCHECK(index < ResourceCount()); + CHECK(index < ResourceCount()); TaskManager::Resource* resource = resources_[index]; GroupMap::const_iterator iter = group_map_.find(resource->GetProcess()); DCHECK(iter != group_map_.end()); @@ -235,7 +249,7 @@ bool TaskManagerModel::IsResourceFirstInGroup(int index) const { } SkBitmap TaskManagerModel::GetResourceIcon(int index) const { - DCHECK(index < ResourceCount()); + CHECK(index < ResourceCount()); SkBitmap icon = resources_[index]->GetIcon(); if (!icon.isNull()) return icon; @@ -247,7 +261,7 @@ SkBitmap TaskManagerModel::GetResourceIcon(int index) const { std::pair<int, int> TaskManagerModel::GetGroupRangeForResource(int index) const { - DCHECK(index < ResourceCount()); + CHECK(index < ResourceCount()); TaskManager::Resource* resource = resources_[index]; GroupMap::const_iterator group_iter = group_map_.find(resource->GetProcess()); @@ -267,7 +281,7 @@ std::pair<int, int> TaskManagerModel::GetGroupRangeForResource(int index) } int TaskManagerModel::CompareValues(int row1, int row2, int col_id) const { - DCHECK(row1 < ResourceCount() && row2 < ResourceCount()); + CHECK(row1 < ResourceCount() && row2 < ResourceCount()); switch (col_id) { case IDS_TASK_MANAGER_PAGE_COLUMN: { // Let's do the default, string compare on the resource title. @@ -374,17 +388,22 @@ int TaskManagerModel::CompareValues(int row1, int row2, int col_id) const { base::ProcessHandle TaskManagerModel::GetResourceProcessHandle(int index) const { - DCHECK(index < ResourceCount()); + CHECK(index < ResourceCount()); return resources_[index]->GetProcess(); } +TaskManager::Resource::Type TaskManagerModel::GetResourceType(int index) const { + CHECK(index < ResourceCount()); + return resources_[index]->GetType(); +} + TabContents* TaskManagerModel::GetResourceTabContents(int index) const { - DCHECK(index < ResourceCount()); + CHECK(index < ResourceCount()); return resources_[index]->GetTabContents(); } const Extension* TaskManagerModel::GetResourceExtension(int index) const { - DCHECK(index < ResourceCount()); + CHECK(index < ResourceCount()); return resources_[index]->GetExtension(); } @@ -482,6 +501,12 @@ string16 TaskManagerModel::GetMemCellText(int64 number) const { } void TaskManagerModel::StartUpdating() { + // Multiple StartUpdating requests may come in, and we only need to take + // action the first time. + update_requests_++; + if (update_requests_ > 1) + return; + DCHECK_EQ(1, update_requests_); DCHECK_NE(TASK_PENDING, update_state_); // If update_state_ is STOPPING, it means a task is still pending. Setting @@ -508,6 +533,13 @@ void TaskManagerModel::StartUpdating() { } void TaskManagerModel::StopUpdating() { + // Don't actually stop updating until we have heard as many calls as those + // to StartUpdating. + update_requests_--; + if (update_requests_ > 0) + return; + // Make sure that update_requests_ cannot go negative. + CHECK_EQ(0, update_requests_); DCHECK_EQ(TASK_PENDING, update_state_); update_state_ = STOPPING; @@ -522,6 +554,9 @@ void TaskManagerModel::StopUpdating() { BrowserThread::IO, FROM_HERE, NewRunnableMethod( this, &TaskManagerModel::UnregisterForJobDoneNotifications)); + + // Must clear the resources before the next attempt to start updating. + Clear(); } void TaskManagerModel::AddResourceProvider( @@ -925,7 +960,6 @@ void TaskManager::RemoveResource(Resource* resource) { void TaskManager::OnWindowClosed() { model_->StopUpdating(); - model_->Clear(); } // static diff --git a/chrome/browser/task_manager/task_manager.h b/chrome/browser/task_manager/task_manager.h index b7b6890..cef241c 100644 --- a/chrome/browser/task_manager/task_manager.h +++ b/chrome/browser/task_manager/task_manager.h @@ -42,9 +42,26 @@ class TaskManager { public: virtual ~Resource() {} + enum Type { + UNKNOWN = 0, // An unknown process type. + BROWSER, // The main browser process. + RENDERER, // A normal TabContents renderer process. + EXTENSION, // An extension or app process. + NOTIFICATION, // A notification process. + PLUGIN, // A plugin process. + WORKER, // A web worker process. + NACL, // A NativeClient loader or broker process. + UTILITY, // A browser utility process. + PROFILE_IMPORT, // A profile import process. + ZYGOTE, // A Linux zygote process. + SANDBOX_HELPER, // A sandbox helper process. + GPU // A graphics process. + }; + virtual std::wstring GetTitle() const = 0; virtual SkBitmap GetIcon() const = 0; virtual base::ProcessHandle GetProcess() const = 0; + virtual Type GetType() const = 0; virtual bool ReportsCacheStats() const { return false; } virtual WebKit::WebCache::ResourceTypeStats GetWebCoreCacheStats() const { @@ -197,6 +214,11 @@ class TaskManagerModel : public URLRequestJobTracker::JobObserver, // Returns number of registered resources. int ResourceCount() const; + // Methods to return raw resource information. + int64 GetNetworkUsage(int index) const; + double GetCPUUsage(int index) const; + int GetProcessId(int index) const; + // Methods to return formatted resource information. string16 GetResourceTitle(int index) const; string16 GetResourceNetworkUsage(int index) const; @@ -212,6 +234,27 @@ class TaskManagerModel : public URLRequestJobTracker::JobObserver, string16 GetResourceGoatsTeleported(int index) const; string16 GetResourceV8MemoryAllocatedSize(int index) const; + // Gets the private memory (in bytes) that should be displayed for the passed + // resource index. Caches the result since this calculation can take time on + // some platforms. + bool GetPrivateMemory(int index, size_t* result) const; + + // Gets the shared memory (in bytes) that should be displayed for the passed + // resource index. Caches the result since this calculation can take time on + // some platforms. + bool GetSharedMemory(int index, size_t* result) const; + + // Gets the physical memory (in bytes) that should be displayed for the passed + // resource index. + bool GetPhysicalMemory(int index, size_t* result) const; + + // Gets the amount of memory allocated for javascript. Returns false if the + // resource for the given row isn't a renderer. + bool GetV8Memory(int index, size_t* result) const; + + // See design doc at http://go/at-teleporter for more information. + int GetGoatsTeleported(int index) const; + // Returns true if the resource is first in its group (resources // rendered by the same process are groupped together). bool IsResourceFirstInGroup(int index) const; @@ -230,6 +273,9 @@ class TaskManagerModel : public URLRequestJobTracker::JobObserver, // Returns process handle for given resource. base::ProcessHandle GetResourceProcessHandle(int index) const; + // Returns the type of the given resource. + TaskManager::Resource::Type GetResourceType(int index) const; + // Returns TabContents of given resource or NULL if not applicable. TabContents* GetResourceTabContents(int index) const; @@ -265,6 +311,7 @@ class TaskManagerModel : public URLRequestJobTracker::JobObserver, private: friend class base::RefCountedThreadSafe<TaskManagerModel>; FRIEND_TEST_ALL_PREFIXES(TaskManagerTest, RefreshCalled); + FRIEND_TEST_ALL_PREFIXES(ExtensionApiTest, ProcessesVsTaskManager); ~TaskManagerModel(); @@ -332,27 +379,6 @@ class TaskManagerModel : public URLRequestJobTracker::JobObserver, // |resource|. double GetCPUUsage(TaskManager::Resource* resource) const; - // Gets the private memory (in bytes) that should be displayed for the passed - // resource index. Caches the result since this calculation can take time on - // some platforms. - bool GetPrivateMemory(int index, size_t* result) const; - - // Gets the shared memory (in bytes) that should be displayed for the passed - // resource index. Caches the result since this calculation can take time on - // some platforms. - bool GetSharedMemory(int index, size_t* result) const; - - // Gets the physical memory (in bytes) that should be displayed for the passed - // resource index. - bool GetPhysicalMemory(int index, size_t* result) const; - - // Gets the amount of memory allocated for javascript. Returns false if the - // resource for the given row isn't a renderer. - bool GetV8Memory(int index, size_t* result) const; - - // See design doc at http://go/at-teleporter for more information. - int GetGoatsTeleported(int index) const; - // Retrieves the ProcessMetrics for the resources at the specified row. // Returns true if there was a ProcessMetrics available. bool GetProcessMetricsForRow(int row, @@ -403,6 +429,10 @@ class TaskManagerModel : public URLRequestJobTracker::JobObserver, ObserverList<TaskManagerModelObserver> observer_list_; + // How many calls to StartUpdating have been made without matching calls to + // StopUpdating. + int update_requests_; + // Whether we are currently in the process of updating. UpdateState update_state_; diff --git a/chrome/browser/task_manager/task_manager_resource_providers.cc b/chrome/browser/task_manager/task_manager_resource_providers.cc index 127be81..d1b6b7f 100644 --- a/chrome/browser/task_manager/task_manager_resource_providers.cc +++ b/chrome/browser/task_manager/task_manager_resource_providers.cc @@ -354,6 +354,36 @@ base::ProcessHandle TaskManagerChildProcessResource::GetProcess() const { return child_process_.handle(); } +TaskManager::Resource::Type TaskManagerChildProcessResource::GetType() const { + // Translate types to TaskManager::ResourceType, since ChildProcessInfo's type + // is not available for all TaskManager resources. + switch (child_process_.type()) { + case ChildProcessInfo::BROWSER_PROCESS: + return TaskManager::Resource::BROWSER; + case ChildProcessInfo::RENDER_PROCESS: + return TaskManager::Resource::RENDERER; + case ChildProcessInfo::PLUGIN_PROCESS: + return TaskManager::Resource::PLUGIN; + case ChildProcessInfo::WORKER_PROCESS: + return TaskManager::Resource::WORKER; + case ChildProcessInfo::NACL_LOADER_PROCESS: + case ChildProcessInfo::NACL_BROKER_PROCESS: + return TaskManager::Resource::NACL; + case ChildProcessInfo::UTILITY_PROCESS: + return TaskManager::Resource::UTILITY; + case ChildProcessInfo::PROFILE_IMPORT_PROCESS: + return TaskManager::Resource::PROFILE_IMPORT; + case ChildProcessInfo::ZYGOTE_PROCESS: + return TaskManager::Resource::ZYGOTE; + case ChildProcessInfo::SANDBOX_HELPER_PROCESS: + return TaskManager::Resource::SANDBOX_HELPER; + case ChildProcessInfo::GPU_PROCESS: + return TaskManager::Resource::GPU; + default: + return TaskManager::Resource::UNKNOWN; + } +} + //////////////////////////////////////////////////////////////////////////////// // TaskManagerChildProcessResourceProvider class //////////////////////////////////////////////////////////////////////////////// diff --git a/chrome/browser/task_manager/task_manager_resource_providers.h b/chrome/browser/task_manager/task_manager_resource_providers.h index d794111..44e24b6 100644 --- a/chrome/browser/task_manager/task_manager_resource_providers.h +++ b/chrome/browser/task_manager/task_manager_resource_providers.h @@ -33,6 +33,7 @@ class TaskManagerTabContentsResource : public TaskManager::Resource { std::wstring GetTitle() const; SkBitmap GetIcon() const; base::ProcessHandle GetProcess() const; + Type GetType() const { return RENDERER; } TabContents* GetTabContents() const; virtual bool ReportsCacheStats() const { return true; } @@ -122,6 +123,7 @@ class TaskManagerChildProcessResource : public TaskManager::Resource { std::wstring GetTitle() const; SkBitmap GetIcon() const; base::ProcessHandle GetProcess() const; + Type GetType() const; bool SupportNetworkUsage() const { return network_usage_support_; @@ -211,6 +213,7 @@ class TaskManagerExtensionProcessResource : public TaskManager::Resource { std::wstring GetTitle() const; SkBitmap GetIcon() const; base::ProcessHandle GetProcess() const; + Type GetType() const { return EXTENSION; } bool SupportNetworkUsage() const { return true; } void SetSupportNetworkUsage() { NOTREACHED(); } const Extension* GetExtension() const; @@ -282,6 +285,7 @@ class TaskManagerNotificationResource : public TaskManager::Resource { std::wstring GetTitle() const { return title_; } SkBitmap GetIcon() const; base::ProcessHandle GetProcess() const; + Type GetType() const { return NOTIFICATION; } virtual bool SupportNetworkUsage() const { return false; } virtual void SetSupportNetworkUsage() { } @@ -346,6 +350,7 @@ class TaskManagerBrowserProcessResource : public TaskManager::Resource { std::wstring GetTitle() const; SkBitmap GetIcon() const; base::ProcessHandle GetProcess() const; + Type GetType() const { return BROWSER; } bool SupportNetworkUsage() const { return true; } void SetSupportNetworkUsage() { NOTREACHED(); } diff --git a/chrome/browser/task_manager/task_manager_unittest.cc b/chrome/browser/task_manager/task_manager_unittest.cc index 44d0e31..03b5705 100644 --- a/chrome/browser/task_manager/task_manager_unittest.cc +++ b/chrome/browser/task_manager/task_manager_unittest.cc @@ -35,6 +35,7 @@ class TestResource : public TaskManager::Resource { virtual base::ProcessHandle GetProcess() const { return base::GetCurrentProcessHandle(); } + virtual Type GetType() const { return RENDERER; } virtual bool SupportNetworkUsage() const { return false; } virtual void SetSupportNetworkUsage() { NOTREACHED(); } virtual void Refresh() { refresh_called_ = true; } diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json index dcd73f0..af52b4f 100644 --- a/chrome/common/extensions/api/extension_api.json +++ b/chrome/common/extensions/api/extension_api.json @@ -2590,16 +2590,37 @@ "properties": { "id": { "type": "integer", - "description": "The internal ID of the process." + "description": "The ID of the process, as provided by the OS." + }, + "type": { + "type": "string", + "enum": ["browser", "renderer", "extension", "notification", "plugin", "worker", "nacl", "utility", "gpu", "other"], + "description": "The type of process." + }, + "cpu": { + "type": "number", + "description": "The most recent measurement of the process's CPU usage, between 0 and 100%." + }, + "network": { + "type": "number", + "description": "The most recent measurement of the process's network usage, in bytes per second." + }, + "privateMemory": { + "type": "number", + "description": "The most recent measurement of the process's private memory usage, in bytes." + }, + "sharedMemory": { + "type": "number", + "description": "The most recent measurement of the process's shared memory usage, in bytes." } } } ], "functions": [ { - "name": "getProcessForTab", + "name": "getProcessIdForTab", "type": "function", - "description": "Returns details about the current renderer process of the specified tab.", + "description": "Returns the ID of the renderer process for the specified tab.", "parameters": [ { "name": "tabId", @@ -2611,16 +2632,30 @@ "name": "callback", "parameters": [ { - "name": "process", - "$ref": "Process", - "description": "Details about the tab's process." + "name": "processId", + "type": "integer", + "description": "Process ID of the tab's renderer process." } ] } ] } ], - "events": [] + "events": [ + { + "name": "onUpdated", + "type": "function", + "description": "Fires each time the Task Manager updates its process statistics, providing the dictionary of updated Process objects, indexed by process ID.", + "parameters": [ + { + "name": "processes", + "type": "object", + "properties": {}, + "additionalProperties": { "$ref": "Process" } + } + ] + } + ] }, { "namespace": "contextMenus", diff --git a/chrome/common/extensions/docs/examples/api/processes/process_monitor/icon.png b/chrome/common/extensions/docs/examples/api/processes/process_monitor/icon.png Binary files differnew file mode 100644 index 0000000..9a79a46 --- /dev/null +++ b/chrome/common/extensions/docs/examples/api/processes/process_monitor/icon.png diff --git a/chrome/common/extensions/docs/examples/api/processes/process_monitor/manifest.json b/chrome/common/extensions/docs/examples/api/processes/process_monitor/manifest.json new file mode 100644 index 0000000..ae633d3 --- /dev/null +++ b/chrome/common/extensions/docs/examples/api/processes/process_monitor/manifest.json @@ -0,0 +1,13 @@ +{ + "name": "Process Monitor", + "version": "1.0", + "description": "Adds a browser action that monitors resource usage of all browser processes.", + "permissions": [ + "experimental", "tabs" + ], + "browser_action": { + "default_title": "Process Monitor", + "default_icon": "icon.png", + "popup": "popup.html" + } +} diff --git a/chrome/common/extensions/docs/examples/api/processes/process_monitor/popup.html b/chrome/common/extensions/docs/examples/api/processes/process_monitor/popup.html new file mode 100644 index 0000000..61e736b --- /dev/null +++ b/chrome/common/extensions/docs/examples/api/processes/process_monitor/popup.html @@ -0,0 +1,70 @@ +<html> +<head> +<script> + // Shows an updating list of process statistics. + function init() { + chrome.experimental.processes.onUpdated.addListener(function(processes) { + var table = "<table>\n" + + "<tr><td><b>Process</b></td>" + + "<td>Type</td>" + + "<td>CPU</td>" + + "<td>Network</td>" + + "<td>Shared Memory</td>" + + "<td>Private Memory</td>" + + "</tr>\n"; + for (pid in processes) { + table = displayProcessInfo(processes[pid], table); + } + table += "</table>\n"; + var div = document.getElementById("process-list"); + div.innerHTML = table; + }); + } + + function displayProcessInfo(process, table) { + // Format network string like task manager + var network = process.network; + if (network > 1024) { + network = (network / 1024).toFixed(1) + " kB/s"; + } else if (network > 0) { + network += " B/s"; + } else if (network == -1) { + network = "N/A"; + } + + table += + "<tr><td>" + process.id + "</td>" + + "<td>" + process.type + "</td>" + + "<td>" + process.cpu + "</td>" + + "<td>" + network + "</td>" + + "<td>" + (process.sharedMemory / 1024) + "K</td>" + + "<td>" + (process.privateMemory / 1024) + "K</td>" + + "</tr>\n"; + return table; + } +</script> +<style> +body { + overflow: hidden; + margin: 0px; + padding: 0px; + background: white; +} + +div:first-child { + margin-top: 0px; +} + +div, td { + padding: 1px 3px; + font-family: sans-serif; + font-size: 10pt; + margin-top: 1px; +} +</style> +</head> +<body onload="init()"> +<div id="title"><b>Process Monitor</b></div> +<div id="process-list"><i>Loading...</i></div> +</body> +</html> diff --git a/chrome/common/extensions/docs/examples/api/processes/show_tabs/popup.html b/chrome/common/extensions/docs/examples/api/processes/show_tabs/popup.html index 8f69fc0..5978bfd 100644 --- a/chrome/common/extensions/docs/examples/api/processes/show_tabs/popup.html +++ b/chrome/common/extensions/docs/examples/api/processes/show_tabs/popup.html @@ -5,13 +5,13 @@ function init() { chrome.windows.getCurrent(function(currentWindow) { chrome.tabs.getSelected(currentWindow.id, function(selectedTab) { - chrome.experimental.processes.getProcessForTab(selectedTab.id, - function(process) { + chrome.experimental.processes.getProcessIdForTab(selectedTab.id, + function(pid) { var outputDiv = document.getElementById("tab-list"); var titleDiv = document.getElementById("title"); - titleDiv.innerHTML = "<b>Tabs in Process " + process.id + ":</b>"; + titleDiv.innerHTML = "<b>Tabs in Process " + pid + ":</b>"; displayTabInfo(currentWindow.id, selectedTab, outputDiv); - displaySameProcessTabs(selectedTab, process.id, outputDiv); + displaySameProcessTabs(selectedTab, pid, outputDiv); } ); @@ -34,9 +34,9 @@ // Display tab in list if it is in the same process tabs.forEach(function(tab) { - chrome.experimental.processes.getProcessForTab(tab.id, - function(process) { - if (process.id == processId) { + chrome.experimental.processes.getProcessIdForTab(tab.id, + function(pid) { + if (pid == processId) { displayTabInfo(tab.windowId, tab, outputDiv); } } diff --git a/chrome/common/extensions/docs/experimental.processes.html b/chrome/common/extensions/docs/experimental.processes.html index 5e0fbc9..801ff1e 100644 --- a/chrome/common/extensions/docs/experimental.processes.html +++ b/chrome/common/extensions/docs/experimental.processes.html @@ -257,15 +257,15 @@ <a href="#methods">Methods</a> <ol> <li> - <a href="#method-getProcessForTab">getProcessForTab</a> + <a href="#method-getProcessIdForTab">getProcessIdForTab</a> </li> </ol> </li> - <li style="display: none; "> + <li> <a href="#events">Events</a> <ol> <li> - <a href="#event-anchor">eventName</a> + <a href="#event-onUpdated">onUpdated</a> </li> </ol> </li> @@ -333,18 +333,18 @@ http://src.chromium.org/viewvc/chrome/trunk/src/chrome/test/data/extensions/api_ <!-- iterates over all functions --> <div class="apiItem"> - <a name="method-getProcessForTab"></a> <!-- method-anchor --> - <h4>getProcessForTab</h4> + <a name="method-getProcessIdForTab"></a> <!-- method-anchor --> + <h4>getProcessIdForTab</h4> <div class="summary"><span style="display: none; ">void</span> <!-- Note: intentionally longer 80 columns --> - <span>chrome.experimental.processes.getProcessForTab</span>(<span class="null"><span style="display: none; ">, </span><span>integer</span> + <span>chrome.experimental.processes.getProcessIdForTab</span>(<span class="null"><span style="display: none; ">, </span><span>integer</span> <var><span>tabId</span></var></span><span class="null"><span>, </span><span>function</span> <var><span>callback</span></var></span>)</div> <div class="description"> <p class="todo" style="display: none; ">Undocumented.</p> - <p>Returns details about the current renderer process of the specified tab.</p> + <p>Returns the ID of the renderer process for the specified tab.</p> <!-- PARAMETERS --> <h4>Parameters</h4> @@ -495,12 +495,12 @@ http://src.chromium.org/viewvc/chrome/trunk/src/chrome/test/data/extensions/api_ </p> <!-- Note: intentionally longer 80 columns --> - <pre>function(<span>Process process</span>) <span class="subdued">{...}</span>;</pre> + <pre>function(<span>integer processId</span>) <span class="subdued">{...}</span>;</pre> <dl> <div> <div> <dt> - <var>process</var> + <var>processId</var> <em> <!-- TYPE --> @@ -509,15 +509,15 @@ http://src.chromium.org/viewvc/chrome/trunk/src/chrome/test/data/extensions/api_ <span class="optional" style="display: none; ">optional</span> <span class="enum" style="display: none; ">enumerated</span> <span id="typeTemplate"> - <span> - <a href="experimental.processes.html#type-Process">Process</a> - </span> <span style="display: none; "> - <span> + <a> Type</a> + </span> + <span> + <span style="display: none; "> array of <span><span></span></span> </span> - <span>paramType</span> - <span></span> + <span>integer</span> + <span style="display: none; "></span> </span> </span> ) @@ -528,7 +528,7 @@ http://src.chromium.org/viewvc/chrome/trunk/src/chrome/test/data/extensions/api_ <dd class="todo" style="display: none; "> Undocumented. </dd> - <dd>Details about the tab's process.</dd> + <dd>Process ID of the tab's renderer process.</dd> <dd style="display: none; "> This parameter was added in version <b><span></span></b>. @@ -574,32 +574,87 @@ http://src.chromium.org/viewvc/chrome/trunk/src/chrome/test/data/extensions/api_ </div> <!-- /apiGroup --> <!-- EVENTS --> - <div class="apiGroup" style="display: none; "> + <div class="apiGroup"> <a name="events"></a> <h3 id="events">Events</h3> <!-- iterates over all events --> <div class="apiItem"> - <a></a> - <h4>event name</h4> + <a name="event-onUpdated"></a> + <h4>onUpdated</h4> <div class="summary"> <!-- Note: intentionally longer 80 columns --> - <span class="subdued">chrome.bookmarks</span><span>onEvent</span><span class="subdued">.addListener</span>(function(<span>Type param1, Type param2</span>) <span class="subdued">{...}</span>); + <span class="subdued">chrome.experimental.processes.</span><span>onUpdated</span><span class="subdued">.addListener</span>(function(<span>object processes</span>) <span class="subdued">{...}</span>); </div> <div class="description"> - <p class="todo">Undocumented.</p> - <p> - A description from the json schema def of the event goes here. - </p> + <p class="todo" style="display: none; ">Undocumented.</p> + <p>Fires each time the Task Manager updates its process statistics, providing the dictionary of updated Process objects, indexed by process ID.</p> <!-- PARAMETERS --> <h4>Parameters</h4> <dl> <div> <div> - </div> + <dt> + <var>processes</var> + <em> + + <!-- TYPE --> + <div style="display:inline"> + ( + <span class="optional" style="display: none; ">optional</span> + <span class="enum" style="display: none; ">enumerated</span> + <span id="typeTemplate"> + <span style="display: none; "> + <a> Type</a> + </span> + <span> + <span style="display: none; "> + array of <span><span></span></span> + </span> + <span>object</span> + <span style="display: none; "></span> + </span> + </span> + ) + </div> + + </em> + </dt> + <dd class="todo"> + Undocumented. + </dd> + <dd style="display: none; "> + Description of this parameter from the json schema. + </dd> + <dd style="display: none; "> + This parameter was added in version + <b><span></span></b>. + You must omit this parameter in earlier versions, + and you may omit it in any version. If you require this + parameter, the manifest key + <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a> + can ensure that your extension won't be run in an earlier browser version. + </dd> + + <!-- OBJECT PROPERTIES --> + <dd> + <dl> + <div style="display: none; "> + <div> + </div> + </div> + </dl> + </dd> + + <!-- FUNCTION PARAMETERS --> + <dd style="display: none; "> + <div></div> + </dd> + + </div> </div> </dl> @@ -694,7 +749,297 @@ http://src.chromium.org/viewvc/chrome/trunk/src/chrome/test/data/extensions/api_ <dd class="todo" style="display: none; "> Undocumented. </dd> - <dd>The internal ID of the process.</dd> + <dd>The ID of the process, as provided by the OS.</dd> + <dd style="display: none; "> + This parameter was added in version + <b><span></span></b>. + You must omit this parameter in earlier versions, + and you may omit it in any version. If you require this + parameter, the manifest key + <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a> + can ensure that your extension won't be run in an earlier browser version. + </dd> + + <!-- OBJECT PROPERTIES --> + <dd style="display: none; "> + <dl> + <div> + <div> + </div> + </div> + </dl> + </dd> + + <!-- FUNCTION PARAMETERS --> + <dd style="display: none; "> + <div></div> + </dd> + + </div> + </div><div> + <div> + <dt> + <var>type</var> + <em> + + <!-- TYPE --> + <div style="display:inline"> + ( + <span class="optional" style="display: none; ">optional</span> + <span class="enum">enumerated</span> + <span id="typeTemplate"> + <span style="display: none; "> + <a> Type</a> + </span> + <span> + <span style="display: none; "> + array of <span><span></span></span> + </span> + <span>string</span> + <span>["browser", "renderer", "extension", "notification", "plugin", "worker", "nacl", "utility", "gpu", "other"]</span> + </span> + </span> + ) + </div> + + </em> + </dt> + <dd class="todo" style="display: none; "> + Undocumented. + </dd> + <dd>The type of process.</dd> + <dd style="display: none; "> + This parameter was added in version + <b><span></span></b>. + You must omit this parameter in earlier versions, + and you may omit it in any version. If you require this + parameter, the manifest key + <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a> + can ensure that your extension won't be run in an earlier browser version. + </dd> + + <!-- OBJECT PROPERTIES --> + <dd style="display: none; "> + <dl> + <div> + <div> + </div> + </div> + </dl> + </dd> + + <!-- FUNCTION PARAMETERS --> + <dd style="display: none; "> + <div></div> + </dd> + + </div> + </div><div> + <div> + <dt> + <var>cpu</var> + <em> + + <!-- TYPE --> + <div style="display:inline"> + ( + <span class="optional" style="display: none; ">optional</span> + <span class="enum" style="display: none; ">enumerated</span> + <span id="typeTemplate"> + <span style="display: none; "> + <a> Type</a> + </span> + <span> + <span style="display: none; "> + array of <span><span></span></span> + </span> + <span>number</span> + <span style="display: none; "></span> + </span> + </span> + ) + </div> + + </em> + </dt> + <dd class="todo" style="display: none; "> + Undocumented. + </dd> + <dd>The most recent measurement of the process's CPU usage, between 0 and 100%.</dd> + <dd style="display: none; "> + This parameter was added in version + <b><span></span></b>. + You must omit this parameter in earlier versions, + and you may omit it in any version. If you require this + parameter, the manifest key + <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a> + can ensure that your extension won't be run in an earlier browser version. + </dd> + + <!-- OBJECT PROPERTIES --> + <dd style="display: none; "> + <dl> + <div> + <div> + </div> + </div> + </dl> + </dd> + + <!-- FUNCTION PARAMETERS --> + <dd style="display: none; "> + <div></div> + </dd> + + </div> + </div><div> + <div> + <dt> + <var>network</var> + <em> + + <!-- TYPE --> + <div style="display:inline"> + ( + <span class="optional" style="display: none; ">optional</span> + <span class="enum" style="display: none; ">enumerated</span> + <span id="typeTemplate"> + <span style="display: none; "> + <a> Type</a> + </span> + <span> + <span style="display: none; "> + array of <span><span></span></span> + </span> + <span>number</span> + <span style="display: none; "></span> + </span> + </span> + ) + </div> + + </em> + </dt> + <dd class="todo" style="display: none; "> + Undocumented. + </dd> + <dd>The most recent measurement of the process's network usage, in bytes per second.</dd> + <dd style="display: none; "> + This parameter was added in version + <b><span></span></b>. + You must omit this parameter in earlier versions, + and you may omit it in any version. If you require this + parameter, the manifest key + <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a> + can ensure that your extension won't be run in an earlier browser version. + </dd> + + <!-- OBJECT PROPERTIES --> + <dd style="display: none; "> + <dl> + <div> + <div> + </div> + </div> + </dl> + </dd> + + <!-- FUNCTION PARAMETERS --> + <dd style="display: none; "> + <div></div> + </dd> + + </div> + </div><div> + <div> + <dt> + <var>privateMemory</var> + <em> + + <!-- TYPE --> + <div style="display:inline"> + ( + <span class="optional" style="display: none; ">optional</span> + <span class="enum" style="display: none; ">enumerated</span> + <span id="typeTemplate"> + <span style="display: none; "> + <a> Type</a> + </span> + <span> + <span style="display: none; "> + array of <span><span></span></span> + </span> + <span>number</span> + <span style="display: none; "></span> + </span> + </span> + ) + </div> + + </em> + </dt> + <dd class="todo" style="display: none; "> + Undocumented. + </dd> + <dd>The most recent measurement of the process's private memory usage, in bytes.</dd> + <dd style="display: none; "> + This parameter was added in version + <b><span></span></b>. + You must omit this parameter in earlier versions, + and you may omit it in any version. If you require this + parameter, the manifest key + <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a> + can ensure that your extension won't be run in an earlier browser version. + </dd> + + <!-- OBJECT PROPERTIES --> + <dd style="display: none; "> + <dl> + <div> + <div> + </div> + </div> + </dl> + </dd> + + <!-- FUNCTION PARAMETERS --> + <dd style="display: none; "> + <div></div> + </dd> + + </div> + </div><div> + <div> + <dt> + <var>sharedMemory</var> + <em> + + <!-- TYPE --> + <div style="display:inline"> + ( + <span class="optional" style="display: none; ">optional</span> + <span class="enum" style="display: none; ">enumerated</span> + <span id="typeTemplate"> + <span style="display: none; "> + <a> Type</a> + </span> + <span> + <span style="display: none; "> + array of <span><span></span></span> + </span> + <span>number</span> + <span style="display: none; "></span> + </span> + </span> + ) + </div> + + </em> + </dt> + <dd class="todo" style="display: none; "> + Undocumented. + </dd> + <dd>The most recent measurement of the process's shared memory usage, in bytes.</dd> <dd style="display: none; "> This parameter was added in version <b><span></span></b>. diff --git a/chrome/common/extensions/docs/samples.html b/chrome/common/extensions/docs/samples.html index 385b931..1593349 100644 --- a/chrome/common/extensions/docs/samples.html +++ b/chrome/common/extensions/docs/samples.html @@ -290,7 +290,7 @@ <!-- STATIC CONTENT PLACEHOLDER --> <div id="static"><link rel="stylesheet" href="css/samples.css"> -<script>var search_data = {"0262260daf0c8f7b28feff2ef23b05e7abf9d1e0":"A BROWSER ACTION WHICH CHANGES ITS ICON WHEN CLICKED. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETICON","ea2894c41cb8e80a4433a3e6c5772dadce9be90d":"A BROWSER ACTION WITH A POPUP THAT CHANGES THE PAGE COLOR. BROWSER_ACTION POPUP TABS CHROME.TABS.EXECUTESCRIPT","ede3c47b7757245be42ec33fd5ca63df4b490066":"A BROWSER ACTION WITH NO ICON THAT MAKES THE PAGE RED BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.TABS.EXECUTESCRIPT","fbf0aa1a09a15ff8cc4fc7de4fd176d6c663d07a":"ACCEPTLANGUAGE RETURNS ACCEPT LANGUAGES OF THE BROWSER BROWSER_ACTION POPUP CHROME.I18N.GETACCEPTLANGUAGES CHROME.I18N.GETMESSAGE","9a6e4ec46997fb92b324974afa08a3d007e2537f":"ANIMATED PAGE ACTION THIS EXTENSION ADDS AN ANIMATED BROWSER ACTION TO THE TOOLBAR. BACKGROUND_PAGE PAGE_ACTION TABS CHROME.PAGEACTION.HIDE CHROME.PAGEACTION.ONCLICKED CHROME.PAGEACTION.SETICON CHROME.PAGEACTION.SETTITLE CHROME.PAGEACTION.SHOW CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONSELECTIONCHANGED","9747e3d6a3eab39bc7c17f11a80573c62d44c7e5":"BLANK NEW TAB PAGE CHROME_URL_OVERRIDES","903e7277139e1e6caec123d3319cab295d8d1b3a":"CHROME SOUNDS ENJOY A MORE MAGICAL AND IMMERSIVE EXPERIENCE WHEN BROWSING THE WEB USING THE POWER OF SOUND. BACKGROUND_PAGE BOOKMARKS OPTIONS_PAGE TABS CHROME.BOOKMARKS.ONCREATED CHROME.BOOKMARKS.ONMOVED CHROME.BOOKMARKS.ONREMOVED CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST CHROME.TABS.GET CHROME.TABS.ONATTACHED CHROME.TABS.ONCREATED CHROME.TABS.ONDETACHED CHROME.TABS.ONMOVED CHROME.TABS.ONREMOVED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED CHROME.WINDOWS.ONCREATED CHROME.WINDOWS.ONFOCUSCHANGED CHROME.WINDOWS.ONREMOVED","0e790e035a4a00b6f1def5ef9a7d7be1bce95ab5":"CHROMIUM BUILDBOT MONITOR DISPLAYS THE STATUS OF THE CHROMIUM BUILDBOT IN THE TOOLBAR. CLICK TO SEE MORE DETAILED STATUS IN A POPUP. BACKGROUND_PAGE BROWSER_ACTION NOTIFICATIONS OPTIONS_PAGE POPUP CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.BROWSERACTION.SETTITLE CHROME.EXTENSION.GETURL","ac31228200b41a87982e386cc90d3a6eee4ad885":"CHROMIUM SEARCH ADD SUPPORT TO THE OMNIBOX TO SEARCH THE CHROMIUM SOURCE CODE. BACKGROUND_PAGE EXPERIMENTAL TABS CHROME.EXPERIMENTAL.OMNIBOX.ONINPUTCHANGED CHROME.EXPERIMENTAL.OMNIBOX.ONINPUTENTERED CHROME.EXPERIMENTAL.OMNIBOX.STYLEMATCH CHROME.EXPERIMENTAL.OMNIBOX.STYLENONE CHROME.EXPERIMENTAL.OMNIBOX.STYLEURL CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.UPDATE","7d5d6cf195bc25480256618e360aa38c6e6fba82":"CLD DISPLAYS THE LANGUAGE OF A TAB BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.SETBADGETEXT CHROME.TABS.DETECTLANGUAGE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED","5d81304a17cf7ac2887484f730fbd2b01e51e166":"CONTEXT MENUS SAMPLE SHOWS SOME OF THE FEATURES OF THE CONTEXT MENUS API BACKGROUND_PAGE CONTEXTMENUS CHROME.CONTEXTMENUS.CREATE","4daa6becd0899a54776d9cf7f09613ed1a9f4d77":"COOKIE API TEST EXTENSION TESTING COOKIE API BACKGROUND_PAGE BROWSER_ACTION COOKIES TABS CHROME.BROWSERACTION.ONCLICKED CHROME.COOKIES.GET CHROME.COOKIES.GETALL CHROME.COOKIES.ONCHANGED CHROME.COOKIES.REMOVE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL","6871d09f4a96bf9d4b6cc724d00e909cee0f3902":"CROSS-DOMAIN XMLHTTPREQUEST FROM A CONTENT SCRIPT DEMONSTRATES A METHOD TO MAKE A CROSS-DOMAIN XMLHTTPREQUEST FETCH FROM A CONTENT SCRIPT. THIS EXTENSION FETCHES THE CURRENT TRENDING TOPICS FROM TWITTER AND INSERTS THEM IN AN OVERLAY AT THE TOP OF GOOGLE NEWS. VISIT HTTP://NEWS.GOOGLE.COM TO TEST THIS EXTENSION. BACKGROUND_PAGE CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST","028eb5364924344029bcbe1d527f132fc72b34e5":"EMAIL THIS PAGE (BY GOOGLE) THIS EXTENSION ADDS AN EMAIL BUTTON TO THE TOOLBAR WHICH ALLOWS YOU TO EMAIL THE PAGE LINK USING YOUR DEFAULT MAIL CLIENT OR GMAIL. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.CONNECT CHROME.EXTENSION.ONCONNECT CHROME.TABS.CREATE CHROME.TABS.EXECUTESCRIPT CHROME.TABS.UPDATE","763a08e9b06595d785568a8d392b95a2f3700258":"EVENT TRACKING WITH GOOGLE ANALYTICS A SAMPLE EXTENSION WHICH USES GOOGLE ANALYTICS TO TRACK USAGE. BACKGROUND_PAGE BROWSER_ACTION POPUP","4e35caa9742fb82dbd628892d23a781614f6eff6":"GOOGLE DOCUMENT LIST VIEWER DEMONSTRATES HOW TO USE OAUTH TO CONNECT THE GOOGLE DOCUMENTS LIST DATA API. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE POPUP TABS CHROME.BROWSERACTION.SETBADGETEXT CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE","bb57f7a0132cbeb36ad7e7bb0ab75c21704234ca":"GOOGLE MAIL CHECKER DISPLAYS THE NUMBER OF UNREAD MESSAGES IN YOUR GOOGLE MAIL INBOX. YOU CAN ALSO CLICK THE BUTTON TO OPEN YOUR INBOX. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.BROWSERACTION.SETICON CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.I18N.GETMESSAGE CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.ONUPDATED CHROME.TABS.UPDATE","1682e05ea9a1bde985123b04f6f8ac50a8a64033":"GOOGLE WAVE NOTIFIER FIND OUT WHEN YOU HAVE NEW WAVES AND PREVIEW THEM FAST. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE POPUP TABS CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE","14b9651fda4e57b2a5914ba73a779812201b750a":"HELLO WORLD THE FIRST EXTENSION THAT I MADE. BROWSER_ACTION POPUP","2020d72f2577f53caf8e94e3dbac0fb849ceaa4d":"IDLE - SIMPLE EXAMPLE DEMONSTRATES THE IDLE API BACKGROUND_PAGE BROWSER_ACTION IDLE CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.IDLE.ONSTATECHANGED CHROME.IDLE.QUERYSTATE","0ea1588bd07b20338fc21f725de1542a5fdf9726":"IGOOGLE NEW TAB PAGE CHROME_URL_OVERRIDES","646325c25f572a1d15edc73d057f821d847a4fbe":"IMAGEINFO GET IMAGE INFO FOR IMAGES, INCLUDING EXIF DATA BACKGROUND_PAGE CONTEXTMENUS TABS CHROME.CONTEXTMENUS.CREATE CHROME.TABS.GET CHROME.TABS.GETCURRENT CHROME.WINDOWS.CREATE CHROME.WINDOWS.UPDATE","ec97ec20ca2f095d081e39f1565fc12af09ef067":"MAPPY FINDS ADDRESSES IN THE WEB PAGE YOURE ON AND POPS UP A MAP WINDOW. BACKGROUND_PAGE PAGE_ACTION POPUP TABS CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.ONREQUEST CHROME.PAGEACTION.HIDE CHROME.PAGEACTION.SETTITLE CHROME.PAGEACTION.SHOW CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED CHROME.TABS.SENDREQUEST","b2f5f8a790e16f091a7e4e0a39b2d0a6d32e3a6d":"MERGE WINDOWS MERGES ALL OF THE BROWSERS WINDOWS INTO THE CURRENT WINDOW BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.MOVE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL CHROME.WINDOWS.GETCURRENT","51a83d2ba3a32e3ff1bdb624d4e18ccec4c4038e":"MESSAGE TIMER TIMES HOW LONG IT TAKES TO SEND A MESSAGE TO A CONTENT SCRIPT AND BACK. BROWSER_ACTION POPUP TABS CHROME.EXTENSION.ONCONNECT CHROME.EXTENSION.ONREQUEST CHROME.TABS.CONNECT CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.SENDREQUEST","4f6785ec4f937add6728615682dd37c9a42d9548":"MY BOOKMARKS A BROWSER ACTION WITH A POPUP DUMP OF ALL BOOKMARKS, INCLUDING SEARCH, ADD, EDIT AND DELETE. BOOKMARKS BROWSER_ACTION POPUP TABS CHROME.BOOKMARKS.CREATE CHROME.BOOKMARKS.GET CHROME.BOOKMARKS.GETTREE CHROME.BOOKMARKS.REMOVE CHROME.BOOKMARKS.UPDATE CHROME.TABS.CREATE","3aea027164cb9b732ba4a8c51cb93708891726ef":"NEWS READER DISPLAYS THE FIRST 5 ITEMS FROM THE GOOGLE NEWS - TOP NEWS RSS FEED IN A POPUP. BROWSER_ACTION POPUP TABS CHROME.TABS.CREATE","597015d3bcce3da693b02314afd607bec4f55291":"NEWS READER DISPLAYS THE FIRST 5 ITEMS FROM THE GOOGLE NEWS - TOP NEWS RSS FEED IN A POPUP. BROWSER_ACTION POPUP TABS CHROME.TABS.CREATE","6444e5c8ae112a6a433909c5e770669cd16e2e5f":"NEWS READER DISPLAYS THE FIRST 5 ITEMS FROM THE GOOGLE NEWS - TOP NEWS RSS FEED IN A POPUP. BROWSER_ACTION POPUP TABS CHROME.I18N.GETMESSAGE CHROME.TABS.CREATE","f799e26ceef2367cf836f24bcb47df4398b0df58":"NOTIFICATION DEMO SHOWS OFF DESKTOP NOTIFICATIONS, WHICH ARE TOAST WINDOWS THAT POP UP ON THE DESKTOP. BACKGROUND_PAGE NOTIFICATIONS OPTIONS_PAGE TABS CHROME.TABS.CREATE","a88ab12b0241ee3dac6e74bb04da7964fab0f57d":"OMNIBOX EXAMPLE BACKGROUND_PAGE EXPERIMENTAL CHROME.EXPERIMENTAL.OMNIBOX.ONINPUTCHANGED CHROME.EXPERIMENTAL.OMNIBOX.ONINPUTENTERED","8d0a50b57c26bb498be592e871001ffed91541b4":"PAGE ACTION BY CONTENT SHOWS A PAGE ACTION FOR HTML PAGES CONTAINING THE WORD SANDWICH BACKGROUND_PAGE PAGE_ACTION CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST CHROME.PAGEACTION.SHOW","80b86ccc6e8520660fa591caa565826f0ed1b12c":"PAGE ACTION BY URL SHOWS A PAGE ACTION FOR URLS WHICH HAVE THE LETTER G IN THEM. BACKGROUND_PAGE PAGE_ACTION TABS CHROME.PAGEACTION.SHOW CHROME.TABS.ONUPDATED","d74c3c18a1c1dd18b035149105a306f837c8823e":"PAGE BENCHMARKER CHROMIUM PAGE BENCHMARKER. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.BROWSERACTION.SETTITLE CHROME.EXTENSION.CONNECT CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETEXTENSIONTABS CHROME.EXTENSION.GETURL CHROME.EXTENSION.ONCONNECT CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.GETSELECTED CHROME.TABS.REMOVE CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETCURRENT","e6ae17ab4ccfd7e059c8c01f25760ca5d894c7fd":"PRINT THIS PAGE ADDS A PRINT BUTTON TO THE BROWSER. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.TABS.UPDATE","56a8d2ac24ca7bba78fd88ad57f43fc13c784497":"SAMPLE - OAUTH CONTACTS USES OAUTH TO CONNECT TO GOOGLES CONTACTS SERVICE AND DISPLAY A LIST OF YOUR CONTACTS. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETICON CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE","38f6e1e17756ede38b1364c7114a738ca717dcbb":"SANDWICHBAR SHOWS AN INFOBAR ON PAGES WHICH CONTAIN THE WORD SANDWICH BACKGROUND_PAGE EXPERIMENTAL CHROME.EXPERIMENTAL.INFOBARS.SHOW CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST","fc89b35755483af30b66cd72cefa34a43a3e8312":"SHOW TABS IN PROCESS ADDS A BROWSER ACTION SHOWING WHICH TABS SHARE THE CURRENT TABS PROCESS. BROWSER_ACTION EXPERIMENTAL POPUP TABS CHROME.EXPERIMENTAL.PROCESSES.GETPROCESSFORTAB CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL CHROME.WINDOWS.GETCURRENT CHROME.WINDOWS.UPDATE","230463f2d5c3d4d0ca13c230e1f00f2aae0a8a64":"TAB INSPECTOR UTILITY FOR WORKING WITH THE EXTENSION TABS API BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.GETSELECTED CHROME.TABS.MOVE CHROME.TABS.ONATTACHED CHROME.TABS.ONCREATED CHROME.TABS.ONDETACHED CHROME.TABS.ONMOVED CHROME.TABS.ONREMOVED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE CHROME.TABS.UPDATE CHROME.WINDOWS.CREATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL CHROME.WINDOWS.GETCURRENT CHROME.WINDOWS.GETLASTFOCUSED CHROME.WINDOWS.ONCREATED CHROME.WINDOWS.ONFOCUSCHANGED CHROME.WINDOWS.ONREMOVED CHROME.WINDOWS.REMOVE CHROME.WINDOWS.UPDATE","e1697cacebad05218798bf3e8a0f724517f0e8c3":"TEST SCREENSHOT EXTENSION DEMONSTRATE SCREENSHOT FUNCTIONALITY IN THE CHROME.TABS API. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.GETURL CHROME.EXTENSION.GETVIEWS CHROME.TABS.CAPTUREVISIBLETAB CHROME.TABS.CREATE CHROME.TABS.ONUPDATED","b3de91ab04b7d7a2670ca7ee9d740eb42cead0b6":"TYPED URL HISTORY READS YOUR HISTORY, AND SHOWS THE TOP TEN PAGES YOU GO TO BY TYPING THE URL. BROWSER_ACTION HISTORY TABS CHROME.HISTORY.GETVISITS CHROME.HISTORY.SEARCH CHROME.TABS.CREATE"}</script> +<script>var search_data = {"0262260daf0c8f7b28feff2ef23b05e7abf9d1e0":"A BROWSER ACTION WHICH CHANGES ITS ICON WHEN CLICKED. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETICON","ea2894c41cb8e80a4433a3e6c5772dadce9be90d":"A BROWSER ACTION WITH A POPUP THAT CHANGES THE PAGE COLOR. BROWSER_ACTION POPUP TABS CHROME.TABS.EXECUTESCRIPT","ede3c47b7757245be42ec33fd5ca63df4b490066":"A BROWSER ACTION WITH NO ICON THAT MAKES THE PAGE RED BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.TABS.EXECUTESCRIPT","fbf0aa1a09a15ff8cc4fc7de4fd176d6c663d07a":"ACCEPTLANGUAGE RETURNS ACCEPT LANGUAGES OF THE BROWSER BROWSER_ACTION POPUP CHROME.I18N.GETACCEPTLANGUAGES CHROME.I18N.GETMESSAGE","9a6e4ec46997fb92b324974afa08a3d007e2537f":"ANIMATED PAGE ACTION THIS EXTENSION ADDS AN ANIMATED BROWSER ACTION TO THE TOOLBAR. BACKGROUND_PAGE PAGE_ACTION TABS CHROME.PAGEACTION.HIDE CHROME.PAGEACTION.ONCLICKED CHROME.PAGEACTION.SETICON CHROME.PAGEACTION.SETTITLE CHROME.PAGEACTION.SHOW CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONSELECTIONCHANGED","9747e3d6a3eab39bc7c17f11a80573c62d44c7e5":"BLANK NEW TAB PAGE CHROME_URL_OVERRIDES","903e7277139e1e6caec123d3319cab295d8d1b3a":"CHROME SOUNDS ENJOY A MORE MAGICAL AND IMMERSIVE EXPERIENCE WHEN BROWSING THE WEB USING THE POWER OF SOUND. BACKGROUND_PAGE BOOKMARKS OPTIONS_PAGE TABS CHROME.BOOKMARKS.ONCREATED CHROME.BOOKMARKS.ONMOVED CHROME.BOOKMARKS.ONREMOVED CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST CHROME.TABS.GET CHROME.TABS.ONATTACHED CHROME.TABS.ONCREATED CHROME.TABS.ONDETACHED CHROME.TABS.ONMOVED CHROME.TABS.ONREMOVED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED CHROME.WINDOWS.ONCREATED CHROME.WINDOWS.ONFOCUSCHANGED CHROME.WINDOWS.ONREMOVED","0e790e035a4a00b6f1def5ef9a7d7be1bce95ab5":"CHROMIUM BUILDBOT MONITOR DISPLAYS THE STATUS OF THE CHROMIUM BUILDBOT IN THE TOOLBAR. CLICK TO SEE MORE DETAILED STATUS IN A POPUP. BACKGROUND_PAGE BROWSER_ACTION NOTIFICATIONS OPTIONS_PAGE POPUP CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.BROWSERACTION.SETTITLE CHROME.EXTENSION.GETURL","ac31228200b41a87982e386cc90d3a6eee4ad885":"CHROMIUM SEARCH ADD SUPPORT TO THE OMNIBOX TO SEARCH THE CHROMIUM SOURCE CODE. BACKGROUND_PAGE EXPERIMENTAL TABS CHROME.EXPERIMENTAL.OMNIBOX.ONINPUTCHANGED CHROME.EXPERIMENTAL.OMNIBOX.ONINPUTENTERED CHROME.EXPERIMENTAL.OMNIBOX.STYLEMATCH CHROME.EXPERIMENTAL.OMNIBOX.STYLENONE CHROME.EXPERIMENTAL.OMNIBOX.STYLEURL CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.UPDATE","7d5d6cf195bc25480256618e360aa38c6e6fba82":"CLD DISPLAYS THE LANGUAGE OF A TAB BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.SETBADGETEXT CHROME.TABS.DETECTLANGUAGE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED","5d81304a17cf7ac2887484f730fbd2b01e51e166":"CONTEXT MENUS SAMPLE SHOWS SOME OF THE FEATURES OF THE CONTEXT MENUS API BACKGROUND_PAGE CONTEXTMENUS CHROME.CONTEXTMENUS.CREATE","4daa6becd0899a54776d9cf7f09613ed1a9f4d77":"COOKIE API TEST EXTENSION TESTING COOKIE API BACKGROUND_PAGE BROWSER_ACTION COOKIES TABS CHROME.BROWSERACTION.ONCLICKED CHROME.COOKIES.GET CHROME.COOKIES.GETALL CHROME.COOKIES.ONCHANGED CHROME.COOKIES.REMOVE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL","6871d09f4a96bf9d4b6cc724d00e909cee0f3902":"CROSS-DOMAIN XMLHTTPREQUEST FROM A CONTENT SCRIPT DEMONSTRATES A METHOD TO MAKE A CROSS-DOMAIN XMLHTTPREQUEST FETCH FROM A CONTENT SCRIPT. THIS EXTENSION FETCHES THE CURRENT TRENDING TOPICS FROM TWITTER AND INSERTS THEM IN AN OVERLAY AT THE TOP OF GOOGLE NEWS. VISIT HTTP://NEWS.GOOGLE.COM TO TEST THIS EXTENSION. BACKGROUND_PAGE CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST","028eb5364924344029bcbe1d527f132fc72b34e5":"EMAIL THIS PAGE (BY GOOGLE) THIS EXTENSION ADDS AN EMAIL BUTTON TO THE TOOLBAR WHICH ALLOWS YOU TO EMAIL THE PAGE LINK USING YOUR DEFAULT MAIL CLIENT OR GMAIL. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.CONNECT CHROME.EXTENSION.ONCONNECT CHROME.TABS.CREATE CHROME.TABS.EXECUTESCRIPT CHROME.TABS.UPDATE","763a08e9b06595d785568a8d392b95a2f3700258":"EVENT TRACKING WITH GOOGLE ANALYTICS A SAMPLE EXTENSION WHICH USES GOOGLE ANALYTICS TO TRACK USAGE. BACKGROUND_PAGE BROWSER_ACTION POPUP","4e35caa9742fb82dbd628892d23a781614f6eff6":"GOOGLE DOCUMENT LIST VIEWER DEMONSTRATES HOW TO USE OAUTH TO CONNECT THE GOOGLE DOCUMENTS LIST DATA API. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE POPUP TABS CHROME.BROWSERACTION.SETBADGETEXT CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE","bb57f7a0132cbeb36ad7e7bb0ab75c21704234ca":"GOOGLE MAIL CHECKER DISPLAYS THE NUMBER OF UNREAD MESSAGES IN YOUR GOOGLE MAIL INBOX. YOU CAN ALSO CLICK THE BUTTON TO OPEN YOUR INBOX. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.BROWSERACTION.SETICON CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.I18N.GETMESSAGE CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.ONUPDATED CHROME.TABS.UPDATE","1682e05ea9a1bde985123b04f6f8ac50a8a64033":"GOOGLE WAVE NOTIFIER FIND OUT WHEN YOU HAVE NEW WAVES AND PREVIEW THEM FAST. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE POPUP TABS CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE","14b9651fda4e57b2a5914ba73a779812201b750a":"HELLO WORLD THE FIRST EXTENSION THAT I MADE. BROWSER_ACTION POPUP","2020d72f2577f53caf8e94e3dbac0fb849ceaa4d":"IDLE - SIMPLE EXAMPLE DEMONSTRATES THE IDLE API BACKGROUND_PAGE BROWSER_ACTION IDLE CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.IDLE.ONSTATECHANGED CHROME.IDLE.QUERYSTATE","0ea1588bd07b20338fc21f725de1542a5fdf9726":"IGOOGLE NEW TAB PAGE CHROME_URL_OVERRIDES","646325c25f572a1d15edc73d057f821d847a4fbe":"IMAGEINFO GET IMAGE INFO FOR IMAGES, INCLUDING EXIF DATA BACKGROUND_PAGE CONTEXTMENUS TABS CHROME.CONTEXTMENUS.CREATE CHROME.TABS.GET CHROME.TABS.GETCURRENT CHROME.WINDOWS.CREATE CHROME.WINDOWS.UPDATE","ec97ec20ca2f095d081e39f1565fc12af09ef067":"MAPPY FINDS ADDRESSES IN THE WEB PAGE YOURE ON AND POPS UP A MAP WINDOW. BACKGROUND_PAGE PAGE_ACTION POPUP TABS CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.ONREQUEST CHROME.PAGEACTION.HIDE CHROME.PAGEACTION.SETTITLE CHROME.PAGEACTION.SHOW CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED CHROME.TABS.SENDREQUEST","b2f5f8a790e16f091a7e4e0a39b2d0a6d32e3a6d":"MERGE WINDOWS MERGES ALL OF THE BROWSERS WINDOWS INTO THE CURRENT WINDOW BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.MOVE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL CHROME.WINDOWS.GETCURRENT","51a83d2ba3a32e3ff1bdb624d4e18ccec4c4038e":"MESSAGE TIMER TIMES HOW LONG IT TAKES TO SEND A MESSAGE TO A CONTENT SCRIPT AND BACK. BROWSER_ACTION POPUP TABS CHROME.EXTENSION.ONCONNECT CHROME.EXTENSION.ONREQUEST CHROME.TABS.CONNECT CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.SENDREQUEST","4f6785ec4f937add6728615682dd37c9a42d9548":"MY BOOKMARKS A BROWSER ACTION WITH A POPUP DUMP OF ALL BOOKMARKS, INCLUDING SEARCH, ADD, EDIT AND DELETE. BOOKMARKS BROWSER_ACTION POPUP TABS CHROME.BOOKMARKS.CREATE CHROME.BOOKMARKS.GET CHROME.BOOKMARKS.GETTREE CHROME.BOOKMARKS.REMOVE CHROME.BOOKMARKS.UPDATE CHROME.TABS.CREATE","3aea027164cb9b732ba4a8c51cb93708891726ef":"NEWS READER DISPLAYS THE FIRST 5 ITEMS FROM THE GOOGLE NEWS - TOP NEWS RSS FEED IN A POPUP. BROWSER_ACTION POPUP TABS CHROME.TABS.CREATE","597015d3bcce3da693b02314afd607bec4f55291":"NEWS READER DISPLAYS THE FIRST 5 ITEMS FROM THE GOOGLE NEWS - TOP NEWS RSS FEED IN A POPUP. BROWSER_ACTION POPUP TABS CHROME.TABS.CREATE","6444e5c8ae112a6a433909c5e770669cd16e2e5f":"NEWS READER DISPLAYS THE FIRST 5 ITEMS FROM THE GOOGLE NEWS - TOP NEWS RSS FEED IN A POPUP. BROWSER_ACTION POPUP TABS CHROME.I18N.GETMESSAGE CHROME.TABS.CREATE","f799e26ceef2367cf836f24bcb47df4398b0df58":"NOTIFICATION DEMO SHOWS OFF DESKTOP NOTIFICATIONS, WHICH ARE TOAST WINDOWS THAT POP UP ON THE DESKTOP. BACKGROUND_PAGE NOTIFICATIONS OPTIONS_PAGE TABS CHROME.TABS.CREATE","a88ab12b0241ee3dac6e74bb04da7964fab0f57d":"OMNIBOX EXAMPLE BACKGROUND_PAGE EXPERIMENTAL CHROME.EXPERIMENTAL.OMNIBOX.ONINPUTCHANGED CHROME.EXPERIMENTAL.OMNIBOX.ONINPUTENTERED","8d0a50b57c26bb498be592e871001ffed91541b4":"PAGE ACTION BY CONTENT SHOWS A PAGE ACTION FOR HTML PAGES CONTAINING THE WORD SANDWICH BACKGROUND_PAGE PAGE_ACTION CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST CHROME.PAGEACTION.SHOW","80b86ccc6e8520660fa591caa565826f0ed1b12c":"PAGE ACTION BY URL SHOWS A PAGE ACTION FOR URLS WHICH HAVE THE LETTER G IN THEM. BACKGROUND_PAGE PAGE_ACTION TABS CHROME.PAGEACTION.SHOW CHROME.TABS.ONUPDATED","d74c3c18a1c1dd18b035149105a306f837c8823e":"PAGE BENCHMARKER CHROMIUM PAGE BENCHMARKER. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.BROWSERACTION.SETTITLE CHROME.EXTENSION.CONNECT CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETEXTENSIONTABS CHROME.EXTENSION.GETURL CHROME.EXTENSION.ONCONNECT CHROME.TABS.CREATE CHROME.TABS.EXECUTESCRIPT CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.GETSELECTED CHROME.TABS.REMOVE CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETCURRENT","e6ae17ab4ccfd7e059c8c01f25760ca5d894c7fd":"PRINT THIS PAGE ADDS A PRINT BUTTON TO THE BROWSER. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.TABS.UPDATE","beff6ecd9677dea0a7c648c5042165b48bb66f09":"PROCESS MONITOR ADDS A BROWSER ACTION THAT MONITORS RESOURCE USAGE OF ALL BROWSER PROCESSES. BROWSER_ACTION EXPERIMENTAL POPUP TABS CHROME.EXPERIMENTAL.PROCESSES.ONUPDATED","56a8d2ac24ca7bba78fd88ad57f43fc13c784497":"SAMPLE - OAUTH CONTACTS USES OAUTH TO CONNECT TO GOOGLES CONTACTS SERVICE AND DISPLAY A LIST OF YOUR CONTACTS. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETICON CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE","38f6e1e17756ede38b1364c7114a738ca717dcbb":"SANDWICHBAR SHOWS AN INFOBAR ON PAGES WHICH CONTAIN THE WORD SANDWICH BACKGROUND_PAGE EXPERIMENTAL CHROME.EXPERIMENTAL.INFOBARS.SHOW CHROME.EXTENSION.ONREQUEST CHROME.EXTENSION.SENDREQUEST","fc89b35755483af30b66cd72cefa34a43a3e8312":"SHOW TABS IN PROCESS ADDS A BROWSER ACTION SHOWING WHICH TABS SHARE THE CURRENT TABS PROCESS. BROWSER_ACTION EXPERIMENTAL POPUP TABS CHROME.EXPERIMENTAL.PROCESSES.GETPROCESSIDFORTAB CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL CHROME.WINDOWS.GETCURRENT CHROME.WINDOWS.UPDATE","230463f2d5c3d4d0ca13c230e1f00f2aae0a8a64":"TAB INSPECTOR UTILITY FOR WORKING WITH THE EXTENSION TABS API BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.GETURL CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.GETSELECTED CHROME.TABS.MOVE CHROME.TABS.ONATTACHED CHROME.TABS.ONCREATED CHROME.TABS.ONDETACHED CHROME.TABS.ONMOVED CHROME.TABS.ONREMOVED CHROME.TABS.ONSELECTIONCHANGED CHROME.TABS.ONUPDATED CHROME.TABS.REMOVE CHROME.TABS.UPDATE CHROME.WINDOWS.CREATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL CHROME.WINDOWS.GETCURRENT CHROME.WINDOWS.GETLASTFOCUSED CHROME.WINDOWS.ONCREATED CHROME.WINDOWS.ONFOCUSCHANGED CHROME.WINDOWS.ONREMOVED CHROME.WINDOWS.REMOVE CHROME.WINDOWS.UPDATE","e1697cacebad05218798bf3e8a0f724517f0e8c3":"TEST SCREENSHOT EXTENSION DEMONSTRATE SCREENSHOT FUNCTIONALITY IN THE CHROME.TABS API. BACKGROUND_PAGE BROWSER_ACTION TABS CHROME.BROWSERACTION.ONCLICKED CHROME.EXTENSION.GETURL CHROME.EXTENSION.GETVIEWS CHROME.TABS.CAPTUREVISIBLETAB CHROME.TABS.CREATE CHROME.TABS.ONUPDATED","b3de91ab04b7d7a2670ca7ee9d740eb42cead0b6":"TYPED URL HISTORY READS YOUR HISTORY, AND SHOWS THE TOP TEN PAGES YOU GO TO BY TYPING THE URL. BROWSER_ACTION HISTORY TABS CHROME.HISTORY.GETVISITS CHROME.HISTORY.SEARCH CHROME.TABS.CREATE"}</script> <script src="js/sample_search.js"></script> @@ -1979,6 +1979,8 @@ </li><li> <code><a href="tabs.html#method-create">chrome.tabs.create</a></code> </li><li> + <code><a href="tabs.html#method-executeScript">chrome.tabs.executeScript</a></code> + </li><li> <code><a href="tabs.html#method-get">chrome.tabs.get</a></code> </li><li> <code><a href="tabs.html#method-getAllInWindow">chrome.tabs.getAllInWindow</a></code> @@ -2055,6 +2057,45 @@ </ul> </div> <div><a href="examples/api/browserAction/print.zip">Download .zip</a></div> +</div><div class="sample" id="beff6ecd9677dea0a7c648c5042165b48bb66f09"> + <img class="icon" style="display: none; "> + <img class="icon" src="images/sample-default-icon.png"> + <h2 class="name"> + <a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/api/processes/process_monitor/">Process Monitor</a> + </h2> + <p class="metadata features">Uses + <span> + <strong>browser_action</strong><span>, </span> + <span style="display: none; "> and</span> + </span><span> + <strong>experimental</strong><span>, </span> + <span style="display: none; "> and</span> + </span><span> + <strong>popup</strong><span style="display: none; ">, </span> + <span> and</span> + </span><span> + <strong>tabs</strong><span style="display: none; ">, </span> + <span style="display: none; "> and</span> + </span> + </p> + <p>Adds a browser action that monitors resource usage of all browser processes.</p> + <div class="apicalls"><strong>Calls:</strong> + <ul> + <li> + <code><a href="experimental.processes.html#event-onUpdated">chrome.experimental.processes.onUpdated</a></code> + </li> + </ul> + </div> + <div class="sourcefiles"><strong>Source files:</strong> + <ul> + <li> + <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/api/processes/process_monitor/manifest.json?content-type=text/plain">manifest.json</a></code> + </li><li> + <code><a target="_blank" href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/api/processes/process_monitor/popup.html?content-type=text/plain">popup.html</a></code> + </li> + </ul> + </div> + <div><a href="examples/api/processes/process_monitor.zip">Download .zip</a></div> </div><div class="sample" id="56a8d2ac24ca7bba78fd88ad57f43fc13c784497"> <img class="icon" src="examples/extensions/oauth_contacts/img/icon-128.png"> <img class="icon" src="images/sample-default-icon.png" style="display: none; "> @@ -2181,7 +2222,7 @@ <div class="apicalls"><strong>Calls:</strong> <ul> <li> - <code><a href="experimental.processes.html#method-getProcessForTab">chrome.experimental.processes.getProcessForTab</a></code> + <code><a href="experimental.processes.html#method-getProcessIdForTab">chrome.experimental.processes.getProcessIdForTab</a></code> </li><li> <code><a href="tabs.html#method-get">chrome.tabs.get</a></code> </li><li> diff --git a/chrome/common/extensions/docs/samples.json b/chrome/common/extensions/docs/samples.json index 9dd8085..30a3b02 100644 --- a/chrome/common/extensions/docs/samples.json +++ b/chrome/common/extensions/docs/samples.json @@ -15,7 +15,6 @@ "chrome.pageAction.setTitle": "pageAction.html#method-setTitle", "chrome.bookmarks.onImportBegan": "bookmarks.html#event-onImportBegan", "chrome.experimental.omnibox.styleDim": "experimental.omnibox.html#method-styleDim", - "chrome.experimental.processes.getProcessForTab": "experimental.processes.html#method-getProcessForTab", "chrome.bookmarks.getTree": "bookmarks.html#method-getTree", "chrome.experimental.infobars.show": "experimental.infobars.html#method-show", "chrome.windows.get": "windows.html#method-get", @@ -28,7 +27,7 @@ "chrome.extension.onConnect": "extension.html#event-onConnect", "chrome.bookmarks.removeTree": "bookmarks.html#method-removeTree", "chrome.bookmarks.get": "bookmarks.html#method-get", - "chrome.experimental.sidebar.hide": "experimental.sidebar.html#method-hide", + "chrome.experimental.processes.onUpdated": "experimental.processes.html#event-onUpdated", "chrome.bookmarks.getRecent": "bookmarks.html#method-getRecent", "chrome.history.onVisitRemoved": "history.html#event-onVisitRemoved", "chrome.experimental.sidebar.navigate": "experimental.sidebar.html#method-navigate", @@ -36,6 +35,7 @@ "chrome.bookmarks.onChanged": "bookmarks.html#event-onChanged", "chrome.tabs.detectLanguage": "tabs.html#method-detectLanguage", "chrome.windows.onRemoved": "windows.html#event-onRemoved", + "chrome.experimental.sidebar.hide": "experimental.sidebar.html#method-hide", "chrome.management.uninstall": "management.html#method-uninstall", "chrome.experimental.clipboard.executePaste": "experimental.clipboard.html#method-executePaste", "chrome.experimental.webNavigation.onCompleted": "experimental.webNavigation.html#event-onCompleted", @@ -139,6 +139,7 @@ "chrome.tabs.move": "tabs.html#method-move", "chrome.windows.onFocusChanged": "windows.html#event-onFocusChanged", "chrome.pageAction.setPopup": "pageAction.html#method-setPopup", + "chrome.experimental.processes.getProcessIdForTab": "experimental.processes.html#method-getProcessIdForTab", "chrome.history.addUrl": "history.html#method-addUrl" }, "samples": [ @@ -1121,7 +1122,7 @@ ], "icon": null, "description": "Chromium Page Benchmarker.", - "search_string": "PAGE BENCHMARKER CHROMIUM PAGE BENCHMARKER. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.BROWSERACTION.SETTITLE CHROME.EXTENSION.CONNECT CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETEXTENSIONTABS CHROME.EXTENSION.GETURL CHROME.EXTENSION.ONCONNECT CHROME.TABS.CREATE CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.GETSELECTED CHROME.TABS.REMOVE CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETCURRENT", + "search_string": "PAGE BENCHMARKER CHROMIUM PAGE BENCHMARKER. BACKGROUND_PAGE BROWSER_ACTION OPTIONS_PAGE TABS CHROME.BROWSERACTION.ONCLICKED CHROME.BROWSERACTION.SETBADGEBACKGROUNDCOLOR CHROME.BROWSERACTION.SETBADGETEXT CHROME.BROWSERACTION.SETTITLE CHROME.EXTENSION.CONNECT CHROME.EXTENSION.GETBACKGROUNDPAGE CHROME.EXTENSION.GETEXTENSIONTABS CHROME.EXTENSION.GETURL CHROME.EXTENSION.ONCONNECT CHROME.TABS.CREATE CHROME.TABS.EXECUTESCRIPT CHROME.TABS.GET CHROME.TABS.GETALLINWINDOW CHROME.TABS.GETSELECTED CHROME.TABS.REMOVE CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETCURRENT", "source_files": [ "background.html", "jst/jsevalcontext.js", @@ -1145,6 +1146,7 @@ "chrome.extension.getURL", "chrome.extension.onConnect", "chrome.tabs.create", + "chrome.tabs.executeScript", "chrome.tabs.get", "chrome.tabs.getAllInWindow", "chrome.tabs.getSelected", @@ -1154,7 +1156,10 @@ "chrome.windows.getCurrent" ], "id": "d74c3c18a1c1dd18b035149105a306f837c8823e", - "protocols": [], + "protocols": [ + "https://", + "http://" + ], "name": "Page Benchmarker" }, { @@ -1185,6 +1190,29 @@ }, { "features": [ + "browser_action", + "experimental", + "popup", + "tabs" + ], + "icon": null, + "description": "Adds a browser action that monitors resource usage of all browser processes.", + "search_string": "PROCESS MONITOR ADDS A BROWSER ACTION THAT MONITORS RESOURCE USAGE OF ALL BROWSER PROCESSES. BROWSER_ACTION EXPERIMENTAL POPUP TABS CHROME.EXPERIMENTAL.PROCESSES.ONUPDATED", + "source_files": [ + "manifest.json", + "popup.html" + ], + "zip_path": "examples/api/processes/process_monitor.zip", + "path": "examples/api/processes/process_monitor/", + "api_calls": [ + "chrome.experimental.processes.onUpdated" + ], + "id": "beff6ecd9677dea0a7c648c5042165b48bb66f09", + "protocols": [], + "name": "Process Monitor" + }, + { + "features": [ "background_page", "browser_action", "tabs" @@ -1256,7 +1284,7 @@ ], "icon": null, "description": "Adds a browser action showing which tabs share the current tab's process.", - "search_string": "SHOW TABS IN PROCESS ADDS A BROWSER ACTION SHOWING WHICH TABS SHARE THE CURRENT TABS PROCESS. BROWSER_ACTION EXPERIMENTAL POPUP TABS CHROME.EXPERIMENTAL.PROCESSES.GETPROCESSFORTAB CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL CHROME.WINDOWS.GETCURRENT CHROME.WINDOWS.UPDATE", + "search_string": "SHOW TABS IN PROCESS ADDS A BROWSER ACTION SHOWING WHICH TABS SHARE THE CURRENT TABS PROCESS. BROWSER_ACTION EXPERIMENTAL POPUP TABS CHROME.EXPERIMENTAL.PROCESSES.GETPROCESSIDFORTAB CHROME.TABS.GET CHROME.TABS.GETSELECTED CHROME.TABS.UPDATE CHROME.WINDOWS.GET CHROME.WINDOWS.GETALL CHROME.WINDOWS.GETCURRENT CHROME.WINDOWS.UPDATE", "source_files": [ "manifest.json", "popup.html" @@ -1264,7 +1292,7 @@ "zip_path": "examples/api/processes/show_tabs.zip", "path": "examples/api/processes/show_tabs/", "api_calls": [ - "chrome.experimental.processes.getProcessForTab", + "chrome.experimental.processes.getProcessIdForTab", "chrome.tabs.get", "chrome.tabs.getSelected", "chrome.tabs.update", diff --git a/chrome/test/data/extensions/api_test/permissions/enabled/background.html b/chrome/test/data/extensions/api_test/permissions/enabled/background.html index eb186e3..633600d 100644 --- a/chrome/test/data/extensions/api_test/permissions/enabled/background.html +++ b/chrome/test/data/extensions/api_test/permissions/enabled/background.html @@ -11,8 +11,8 @@ chrome.test.runTests([ // experimental, this test needs to be updated.
chrome.tabs.getSelected(null, function(tab) {
try {
- chrome.experimental.processes.getProcessForTab(
- tab.id, pass(function(process) {}));
+ chrome.experimental.processes.getProcessIdForTab(
+ tab.id, pass(function(pid) {}));
} catch (e) {
chrome.test.fail();
}
diff --git a/chrome/test/data/extensions/api_test/processes/a.html b/chrome/test/data/extensions/api_test/processes/api/a.html index dcd442e..dcd442e 100644 --- a/chrome/test/data/extensions/api_test/processes/a.html +++ b/chrome/test/data/extensions/api_test/processes/api/a.html diff --git a/chrome/test/data/extensions/api_test/processes/b.html b/chrome/test/data/extensions/api_test/processes/api/b.html index 7bff50a..7bff50a 100644 --- a/chrome/test/data/extensions/api_test/processes/b.html +++ b/chrome/test/data/extensions/api_test/processes/api/b.html diff --git a/chrome/test/data/extensions/api_test/processes/manifest.json b/chrome/test/data/extensions/api_test/processes/api/manifest.json index 44fcdfb..44fcdfb 100644 --- a/chrome/test/data/extensions/api_test/processes/manifest.json +++ b/chrome/test/data/extensions/api_test/processes/api/manifest.json diff --git a/chrome/test/data/extensions/api_test/processes/test.html b/chrome/test/data/extensions/api_test/processes/api/test.html index 46f4d74..46f4d74 100644 --- a/chrome/test/data/extensions/api_test/processes/test.html +++ b/chrome/test/data/extensions/api_test/processes/api/test.html diff --git a/chrome/test/data/extensions/api_test/processes/api/test.js b/chrome/test/data/extensions/api_test/processes/api/test.js new file mode 100644 index 0000000..be15c8f --- /dev/null +++ b/chrome/test/data/extensions/api_test/processes/api/test.js @@ -0,0 +1,155 @@ +// Processes API test for Chrome. +// browser_tests.exe --gtest_filter=ExtensionApiTest.Processes + +var pass = chrome.test.callbackPass; +var fail = chrome.test.callbackFail; +var assertEq = chrome.test.assertEq; +var assertTrue = chrome.test.assertTrue; +var listenOnce = chrome.test.listenOnce; + +var tabs = []; + +function createTab(index, url) { + chrome.tabs.create({"url": url}, pass(function(tab) { + tabs[index] = tab; + })); +} + +var getProcessId = chrome.experimental.processes.getProcessIdForTab; + +function pageUrl(letter) { + return chrome.extension.getURL(letter + ".html"); +} + +chrome.test.runTests([ + function setupProcessTests() { + // Open 4 tabs for test, then wait and create a 5th + createTab(0, "about:blank"); + createTab(1, pageUrl("a")); + createTab(2, pageUrl("b")); + createTab(3, "chrome://newtab/"); + + // Wait for all loads to complete. + var completedCount = 0; + var onUpdatedCompleted = chrome.test.listenForever( + chrome.tabs.onUpdated, + function(changedTabId, changeInfo, changedTab) { + if (changedTab.status == "complete") { + completedCount++; + + // Once the NTP finishes loading, create another one. This ensures + // both NTPs end up in the same process. + if (changedTabId == tabs[3].id) { + createTab(4, "chrome://newtab/"); + } + } + + // Once all tabs are done loading, continue with the next test. + if (completedCount == 4) { + onUpdatedCompleted(); + } + } + ); + + }, + + function extensionPageInOwnProcess() { + getProcessId(tabs[0].id, pass(function(pid0) { + getProcessId(tabs[1].id, pass(function(pid1) { + // about:blank and extension page should not share a process + assertTrue(pid0 != pid1); + })); + })); + }, + + function extensionPagesShareProcess() { + getProcessId(tabs[1].id, pass(function(pid1) { + getProcessId(tabs[2].id, pass(function(pid2) { + // Pages from same extension should share a process + assertEq(pid1, pid2); + })); + })); + }, + + function newTabPageInOwnProcess() { + getProcessId(tabs[0].id, pass(function(pid0) { + getProcessId(tabs[3].id, pass(function(pid3) { + // NTP should not share a process with current tabs + assertTrue(pid0 != pid3); + })); + })); + }, + + function newTabPagesShareProcess() { + getProcessId(tabs[3].id, pass(function(pid3) { + getProcessId(tabs[4].id, pass(function(pid4) { + // Multiple NTPs should share a process + assertEq(pid3, pid4); + })); + })); + }, + + function idsInUpdateEvent() { + listenOnce(chrome.experimental.processes.onUpdated, function(processes) { + // onUpdated should return a valid dictionary of processes, + // indexed by process ID. + var pids = Object.keys(processes); + // There should be at least 5 processes: 1 browser, 1 extension, and 3 + // renderers (for the 5 tabs). + assertTrue(pids.length >= 5); + + // Should be able to look up process object by ID. + assertTrue(processes[pids[0]].id == pids[0]); + assertTrue(processes[pids[0]].id != processes[pids[1]].id); + + getProcessId(tabs[0].id, pass(function(pidTab0) { + // Process ID for tab 0 should be listed in pids. + assertTrue(processes[pidTab0] != undefined); + assertEq("renderer", processes[pidTab0].type); + })); + }); + }, + + function typesInUpdateEvent() { + listenOnce(chrome.experimental.processes.onUpdated, function(processes) { + // Check types: 1 browser, 3 renderers, and 1 extension + var browserCount = 0; + var rendererCount = 0; + var extensionCount = 0; + var otherCount = 0; + for (pid in processes) { + switch (processes[pid].type) { + case "browser": + browserCount++; + break; + case "renderer": + rendererCount++; + break; + case "extension": + extensionCount++; + break; + default: + otherCount++; + } + } + assertEq(1, browserCount); + assertTrue(rendererCount >= 3); + assertTrue(extensionCount >= 1); + }); + }, + + function propertiesOfProcesses() { + listenOnce(chrome.experimental.processes.onUpdated, function(processes) { + for (pid in processes) { + var process = processes[pid]; + assertTrue("id" in process); + assertTrue("type" in process); + assertTrue("cpu" in process); + assertTrue("network" in process); + assertTrue("sharedMemory" in process); + assertTrue("privateMemory" in process); + } + }); + }, + +]); diff --git a/chrome/test/data/extensions/api_test/processes/onupdated/background.html b/chrome/test/data/extensions/api_test/processes/onupdated/background.html new file mode 100644 index 0000000..6dd1fd2 --- /dev/null +++ b/chrome/test/data/extensions/api_test/processes/onupdated/background.html @@ -0,0 +1,15 @@ +<script> +// Add a simple listener to onUpdated to ensure it does not conflict with the +// task manager. +chrome.experimental.processes.onUpdated.addListener(function(processes) { + console.log("Received update."); +}); + +// Add a second listener to onUpdated to ensure the task manager only hears +// about one extension listener per process. +chrome.experimental.processes.onUpdated.addListener(function(processes) { + console.log("Second listener received update."); +}); + +chrome.test.sendMessage("ready"); +</script> diff --git a/chrome/test/data/extensions/api_test/processes/onupdated/manifest.json b/chrome/test/data/extensions/api_test/processes/onupdated/manifest.json new file mode 100644 index 0000000..9810b2a --- /dev/null +++ b/chrome/test/data/extensions/api_test/processes/onupdated/manifest.json @@ -0,0 +1,7 @@ +{ + "name": "processes onupdated test", + "description": "extension that listens to processes.onUpdated", + "version": "0.1", + "background_page": "background.html", + "permissions": [ "tabs", "experimental" ] +} diff --git a/chrome/test/data/extensions/api_test/processes/test.js b/chrome/test/data/extensions/api_test/processes/test.js deleted file mode 100644 index ecdcaf8..0000000 --- a/chrome/test/data/extensions/api_test/processes/test.js +++ /dev/null @@ -1,91 +0,0 @@ -// Processes API test for Chrome. -// browser_tests.exe --gtest_filter=ExtensionApiTest.Processes - -var pass = chrome.test.callbackPass; -var fail = chrome.test.callbackFail; -var assertEq = chrome.test.assertEq; -var assertTrue = chrome.test.assertTrue; - -var tabs = []; - -function createTab(index, url) { - chrome.tabs.create({"url": url}, pass(function(tab) { - tabs[index] = tab; - })); -} - -var getProcess = chrome.experimental.processes.getProcessForTab; - -function pageUrl(letter) { - return chrome.extension.getURL(letter + ".html"); -} - -chrome.test.runTests([ - function setupProcessTests() { - // Open 4 tabs for test, then wait and create a 5th - createTab(0, "about:blank"); - createTab(1, pageUrl("a")); - createTab(2, pageUrl("b")); - createTab(3, "chrome://newtab/"); - - // Wait for all loads to complete. - var completedCount = 0; - var onUpdatedCompleted = chrome.test.listenForever( - chrome.tabs.onUpdated, - function(changedTabId, changeInfo, changedTab) { - if (changedTab.status == "complete") { - completedCount++; - - // Once the NTP finishes loading, create another one. This ensures - // both NTPs end up in the same process. - if (changedTabId == tabs[3].id) { - createTab(4, "chrome://newtab/"); - } - } - - // Once all tabs are done loading, continue with the next test. - if (completedCount == 4) { - onUpdatedCompleted(); - } - } - ); - - }, - - function extensionPageInOwnProcess() { - getProcess(tabs[0].id, pass(function(process0) { - getProcess(tabs[1].id, pass(function(process1) { - // about:blank and extension page should not share a process - assertTrue(process0.id != process1.id); - })); - })); - }, - - function extensionPagesShareProcess() { - getProcess(tabs[1].id, pass(function(process1) { - getProcess(tabs[2].id, pass(function(process2) { - // Pages from same extension should share a process - assertEq(process1.id, process2.id); - })); - })); - }, - - function newTabPageInOwnProcess() { - getProcess(tabs[0].id, pass(function(process0) { - getProcess(tabs[3].id, pass(function(process3) { - // NTP should not share a process with current tabs - assertTrue(process0.id != process3.id); - })); - })); - }, - - function newTabPagesShareProcess() { - getProcess(tabs[3].id, pass(function(process3) { - getProcess(tabs[4].id, pass(function(process4) { - // Multiple NTPs should share a process - assertEq(process3.id, process4.id); - })); - })); - }, - -]); |