OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/extension_processes_api.h" | 5 #include "chrome/browser/extensions/extension_processes_api.h" |
6 | 6 |
| 7 #include "base/callback.h" |
| 8 #include "base/json/json_writer.h" |
| 9 #include "base/message_loop.h" |
| 10 #include "base/string_number_conversions.h" |
| 11 #include "base/task.h" |
| 12 #include "base/utf_string_conversions.h" |
7 #include "base/values.h" | 13 #include "base/values.h" |
8 | 14 |
| 15 #include "chrome/browser/extensions/extension_event_router.h" |
| 16 #include "chrome/browser/extensions/extension_processes_api_constants.h" |
9 #include "chrome/browser/extensions/extension_tabs_module.h" | 17 #include "chrome/browser/extensions/extension_tabs_module.h" |
10 #include "chrome/browser/extensions/extension_processes_api_constants.h" | 18 #include "chrome/browser/extensions/extension_tabs_module_constants.h" |
| 19 #include "chrome/browser/profile.h" |
11 #include "chrome/browser/renderer_host/render_process_host.h" | 20 #include "chrome/browser/renderer_host/render_process_host.h" |
12 #include "chrome/browser/tab_contents/tab_contents.h" | 21 #include "chrome/browser/tab_contents/tab_contents.h" |
| 22 #include "chrome/browser/task_manager/task_manager.h" |
| 23 #include "chrome/common/extensions/extension_error_utils.h" |
| 24 #include "chrome/common/notification_service.h" |
| 25 #include "chrome/common/notification_type.h" |
13 | 26 |
14 namespace keys = extension_processes_api_constants; | 27 namespace keys = extension_processes_api_constants; |
15 | 28 |
16 DictionaryValue* CreateProcessValue(int process_id) { | 29 DictionaryValue* CreateProcessValue(int process_id, |
| 30 std::string type, |
| 31 double cpu, |
| 32 int64 net, |
| 33 int64 pr_mem, |
| 34 int64 sh_mem) { |
17 DictionaryValue* result = new DictionaryValue(); | 35 DictionaryValue* result = new DictionaryValue(); |
18 result->SetInteger(keys::kIdKey, process_id); | 36 result->SetInteger(keys::kIdKey, process_id); |
19 | 37 result->SetString(keys::kTypeKey, type); |
| 38 result->SetReal(keys::kCpuKey, cpu); |
| 39 result->SetReal(keys::kNetworkKey, static_cast<double>(net)); |
| 40 result->SetReal(keys::kPrivateMemoryKey, static_cast<double>(pr_mem)); |
| 41 result->SetReal(keys::kSharedMemoryKey, static_cast<double>(sh_mem)); |
20 return result; | 42 return result; |
21 } | 43 } |
22 | 44 |
23 bool GetProcessForTabFunction::RunImpl() { | 45 ExtensionProcessesEventRouter* ExtensionProcessesEventRouter::GetInstance() { |
| 46 return Singleton<ExtensionProcessesEventRouter>::get(); |
| 47 } |
| 48 |
| 49 ExtensionProcessesEventRouter::ExtensionProcessesEventRouter() { |
| 50 model_ = TaskManager::GetInstance()->model(); |
| 51 model_->AddObserver(this); |
| 52 } |
| 53 |
| 54 ExtensionProcessesEventRouter::~ExtensionProcessesEventRouter() { |
| 55 model_->RemoveObserver(this); |
| 56 } |
| 57 |
| 58 void ExtensionProcessesEventRouter::ObserveProfile(Profile* profile) { |
| 59 profiles_.insert(profile); |
| 60 } |
| 61 |
| 62 void ExtensionProcessesEventRouter::ListenerAdded() { |
| 63 model_->StartUpdating(); |
| 64 } |
| 65 |
| 66 void ExtensionProcessesEventRouter::ListenerRemoved() { |
| 67 model_->StopUpdating(); |
| 68 } |
| 69 |
| 70 void ExtensionProcessesEventRouter::OnItemsChanged(int start, int length) { |
| 71 if (model_) { |
| 72 ListValue args; |
| 73 DictionaryValue* processes = new DictionaryValue(); |
| 74 for (int i = start; i < start + length; i++) { |
| 75 if (model_->IsResourceFirstInGroup(i)) { |
| 76 int id = model_->GetProcessId(i); |
| 77 |
| 78 // Determine process type |
| 79 std::string type = keys::kProcessTypeOther; |
| 80 TaskManager::Resource::Type resource_type = model_->GetResourceType(i); |
| 81 switch (resource_type) { |
| 82 case TaskManager::Resource::BROWSER: |
| 83 type = keys::kProcessTypeBrowser; |
| 84 break; |
| 85 case TaskManager::Resource::RENDERER: |
| 86 type = keys::kProcessTypeRenderer; |
| 87 break; |
| 88 case TaskManager::Resource::EXTENSION: |
| 89 type = keys::kProcessTypeExtension; |
| 90 break; |
| 91 case TaskManager::Resource::NOTIFICATION: |
| 92 type = keys::kProcessTypeNotification; |
| 93 break; |
| 94 case TaskManager::Resource::PLUGIN: |
| 95 type = keys::kProcessTypePlugin; |
| 96 break; |
| 97 case TaskManager::Resource::WORKER: |
| 98 type = keys::kProcessTypeWorker; |
| 99 break; |
| 100 case TaskManager::Resource::NACL: |
| 101 type = keys::kProcessTypeNacl; |
| 102 break; |
| 103 case TaskManager::Resource::UTILITY: |
| 104 type = keys::kProcessTypeUtility; |
| 105 break; |
| 106 case TaskManager::Resource::GPU: |
| 107 type = keys::kProcessTypeGPU; |
| 108 break; |
| 109 case TaskManager::Resource::PROFILE_IMPORT: |
| 110 case TaskManager::Resource::ZYGOTE: |
| 111 case TaskManager::Resource::SANDBOX_HELPER: |
| 112 case TaskManager::Resource::UNKNOWN: |
| 113 type = keys::kProcessTypeOther; |
| 114 break; |
| 115 default: |
| 116 NOTREACHED() << "Unknown resource type."; |
| 117 } |
| 118 |
| 119 // Get process metrics as numbers |
| 120 double cpu = model_->GetCPUUsage(i); |
| 121 |
| 122 // TODO(creis): Network is actually reported per-resource (tab), |
| 123 // not per-process. We should aggregate it here. |
| 124 int64 net = model_->GetNetworkUsage(i); |
| 125 size_t mem; |
| 126 int64 pr_mem = model_->GetPrivateMemory(i, &mem) ? |
| 127 static_cast<int64>(mem) : -1; |
| 128 int64 sh_mem = model_->GetSharedMemory(i, &mem) ? |
| 129 static_cast<int64>(mem) : -1; |
| 130 |
| 131 // Store each process indexed by the string version of its id |
| 132 processes->Set(base::IntToString(id), |
| 133 CreateProcessValue(id, type, cpu, net, pr_mem, sh_mem)); |
| 134 } |
| 135 } |
| 136 args.Append(processes); |
| 137 |
| 138 std::string json_args; |
| 139 base::JSONWriter::Write(&args, false, &json_args); |
| 140 |
| 141 // Notify each profile that is interested. |
| 142 for (ProfileSet::iterator it = profiles_.begin(); |
| 143 it != profiles_.end(); it++) { |
| 144 Profile* profile = *it; |
| 145 DispatchEvent(profile, keys::kOnUpdated, json_args); |
| 146 } |
| 147 } |
| 148 } |
| 149 |
| 150 void ExtensionProcessesEventRouter::DispatchEvent(Profile* profile, |
| 151 const char* event_name, |
| 152 const std::string& json_args) { |
| 153 if (profile && profile->GetExtensionEventRouter()) { |
| 154 profile->GetExtensionEventRouter()->DispatchEventToRenderers( |
| 155 event_name, json_args, NULL, GURL()); |
| 156 } |
| 157 } |
| 158 |
| 159 bool GetProcessIdForTabFunction::RunImpl() { |
24 int tab_id; | 160 int tab_id; |
25 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &tab_id)); | 161 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &tab_id)); |
26 | 162 |
27 TabContents* contents = NULL; | 163 TabContents* contents = NULL; |
28 int tab_index = -1; | 164 int tab_index = -1; |
29 if (!ExtensionTabUtil::GetTabById(tab_id, profile(), include_incognito(), | 165 if (!ExtensionTabUtil::GetTabById(tab_id, profile(), include_incognito(), |
30 NULL, NULL, &contents, &tab_index)) | 166 NULL, NULL, &contents, &tab_index)) { |
| 167 error_ = ExtensionErrorUtils::FormatErrorMessage( |
| 168 extension_tabs_module_constants::kTabNotFoundError, |
| 169 base::IntToString(tab_id)); |
31 return false; | 170 return false; |
| 171 } |
32 | 172 |
33 int process_id = contents->GetRenderProcessHost()->id(); | 173 // Return the process ID of the tab as an integer. |
34 result_.reset(CreateProcessValue(process_id)); | 174 int id = base::GetProcId(contents->GetRenderProcessHost()->GetHandle()); |
| 175 result_.reset(Value::CreateIntegerValue(id)); |
35 return true; | 176 return true; |
36 } | 177 } |
OLD | NEW |