summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcreis@google.com <creis@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-19 21:47:11 +0000
committercreis@google.com <creis@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-19 21:47:11 +0000
commit8a661f84e6e4ab569de30228b717f0c2b26a1d57 (patch)
tree8e4eed99ddb033b7cdc8489b2264659775f7b0cc
parent293309b27926f9ab2d2567b7e0f2fd04e568a50c (diff)
downloadchromium_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
-rw-r--r--chrome/browser/cocoa/task_manager_mac_unittest.mm1
-rw-r--r--chrome/browser/extensions/extension_event_router.cc12
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc2
-rw-r--r--chrome/browser/extensions/extension_processes_api.cc155
-rw-r--r--chrome/browser/extensions/extension_processes_api.h58
-rw-r--r--chrome/browser/extensions/extension_processes_api_constants.cc19
-rw-r--r--chrome/browser/extensions/extension_processes_api_constants.h21
-rw-r--r--chrome/browser/extensions/extension_processes_apitest.cc36
-rw-r--r--chrome/browser/extensions/extensions_service.cc2
-rw-r--r--chrome/browser/gtk/task_manager_gtk.cc5
-rw-r--r--chrome/browser/task_manager/task_manager.cc74
-rw-r--r--chrome/browser/task_manager/task_manager.h72
-rw-r--r--chrome/browser/task_manager/task_manager_resource_providers.cc30
-rw-r--r--chrome/browser/task_manager/task_manager_resource_providers.h5
-rw-r--r--chrome/browser/task_manager/task_manager_unittest.cc1
-rw-r--r--chrome/common/extensions/api/extension_api.json49
-rw-r--r--chrome/common/extensions/docs/examples/api/processes/process_monitor/icon.pngbin0 -> 2809 bytes
-rw-r--r--chrome/common/extensions/docs/examples/api/processes/process_monitor/manifest.json13
-rw-r--r--chrome/common/extensions/docs/examples/api/processes/process_monitor/popup.html70
-rw-r--r--chrome/common/extensions/docs/examples/api/processes/show_tabs/popup.html14
-rw-r--r--chrome/common/extensions/docs/experimental.processes.html397
-rw-r--r--chrome/common/extensions/docs/samples.html45
-rw-r--r--chrome/common/extensions/docs/samples.json40
-rw-r--r--chrome/test/data/extensions/api_test/permissions/enabled/background.html4
-rw-r--r--chrome/test/data/extensions/api_test/processes/api/a.html (renamed from chrome/test/data/extensions/api_test/processes/a.html)0
-rw-r--r--chrome/test/data/extensions/api_test/processes/api/b.html (renamed from chrome/test/data/extensions/api_test/processes/b.html)0
-rw-r--r--chrome/test/data/extensions/api_test/processes/api/manifest.json (renamed from chrome/test/data/extensions/api_test/processes/manifest.json)0
-rw-r--r--chrome/test/data/extensions/api_test/processes/api/test.html (renamed from chrome/test/data/extensions/api_test/processes/test.html)0
-rw-r--r--chrome/test/data/extensions/api_test/processes/api/test.js155
-rw-r--r--chrome/test/data/extensions/api_test/processes/onupdated/background.html15
-rw-r--r--chrome/test/data/extensions/api_test/processes/onupdated/manifest.json7
-rw-r--r--chrome/test/data/extensions/api_test/processes/test.js91
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
new file mode 100644
index 0000000..9a79a46
--- /dev/null
+++ b/chrome/common/extensions/docs/examples/api/processes/process_monitor/icon.png
Binary files differ
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);
- }));
- }));
- },
-
-]);