Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #ifndef CHROME_BROWSER_EXTENSIONS_API_PROCESSES_PROCESSES_API_H__ | 5 #ifndef CHROME_BROWSER_EXTENSIONS_API_PROCESSES_PROCESSES_API_H__ |
| 6 #define CHROME_BROWSER_EXTENSIONS_API_PROCESSES_PROCESSES_API_H__ | 6 #define CHROME_BROWSER_EXTENSIONS_API_PROCESSES_PROCESSES_API_H__ |
| 7 | 7 |
| 8 #include <set> | 8 #include <vector> |
| 9 #include <string> | |
| 10 | 9 |
| 11 #include "base/macros.h" | 10 #include "base/macros.h" |
| 12 #include "base/memory/scoped_ptr.h" | 11 #include "chrome/browser/task_management/task_manager_observer.h" |
| 13 #include "chrome/browser/extensions/chrome_extension_function.h" | |
| 14 #include "chrome/browser/task_manager/task_manager.h" | |
| 15 #include "components/keyed_service/core/keyed_service.h" | |
| 16 #include "content/public/browser/notification_registrar.h" | |
| 17 #include "content/public/browser/render_process_host.h" | |
| 18 #include "content/public/browser/render_widget_host.h" | |
| 19 #include "extensions/browser/browser_context_keyed_api_factory.h" | 12 #include "extensions/browser/browser_context_keyed_api_factory.h" |
| 20 #include "extensions/browser/event_router.h" | 13 #include "extensions/browser/event_router.h" |
| 21 #include "extensions/browser/extension_event_histogram_value.h" | 14 #include "extensions/browser/extension_event_histogram_value.h" |
| 15 #include "extensions/browser/extension_function.h" | |
| 22 | 16 |
| 23 namespace base { | 17 class ProcessesApiTest; |
| 24 class ListValue; | |
| 25 } | |
| 26 | |
| 27 namespace content { | |
| 28 class BrowserContext; | |
| 29 } | |
| 30 | 18 |
| 31 namespace extensions { | 19 namespace extensions { |
| 32 | 20 |
| 33 // Observes the Task Manager and routes the notifications as events to the | 21 // Observes the Task Manager and routes the notifications as events to the |
| 34 // extension system. | 22 // extension system. |
| 35 class ProcessesEventRouter : public TaskManagerModelObserver, | 23 class ProcessesEventRouter : public task_management::TaskManagerObserver { |
| 36 public content::NotificationObserver { | |
| 37 public: | 24 public: |
| 38 explicit ProcessesEventRouter(content::BrowserContext* context); | 25 explicit ProcessesEventRouter(content::BrowserContext* context); |
| 39 ~ProcessesEventRouter() override; | 26 ~ProcessesEventRouter() override; |
| 40 | 27 |
| 41 // Called when an extension process wants to listen to process events. | 28 // Called when an extension process wants to listen to process events. |
| 42 void ListenerAdded(); | 29 void ListenerAdded(); |
| 43 | 30 |
| 44 // Called when an extension process with a listener exits or removes it. | 31 // Called when an extension process with a listener exits or removes it. |
| 45 void ListenerRemoved(); | 32 void ListenerRemoved(); |
| 46 | 33 |
| 47 // Called on the first invocation of extension API function. This will call | 34 // task_management::TaskManagerObserver: |
| 48 // out to the Task Manager to start listening for notifications. Returns | 35 void OnTaskAdded(task_management::TaskId id) override; |
| 49 // true if this was the first call and false if this has already been called. | 36 void OnTaskToBeRemoved(task_management::TaskId id) override; |
| 50 void StartTaskManagerListening(); | 37 void OnTasksRefreshed(const task_management::TaskIdList& task_ids) override {} |
| 51 | 38 void OnTasksRefreshedWithBackgroundCalculations( |
| 52 bool is_task_manager_listening() { return task_manager_listening_; } | 39 const task_management::TaskIdList& task_ids) override; |
| 40 void OnTaskUnresponsive(task_management::TaskId id) override; | |
| 53 | 41 |
| 54 private: | 42 private: |
| 55 // content::NotificationObserver implementation. | 43 friend class ::ProcessesApiTest; |
| 56 void Observe(int type, | |
| 57 const content::NotificationSource& source, | |
| 58 const content::NotificationDetails& details) override; | |
| 59 | |
| 60 // TaskManagerModelObserver methods. | |
| 61 void OnItemsAdded(int start, int length) override; | |
| 62 void OnModelChanged() override {} | |
| 63 void OnItemsChanged(int start, int length) override; | |
| 64 void OnItemsRemoved(int start, int length) override {} | |
| 65 void OnItemsToBeRemoved(int start, int length) override; | |
| 66 | |
| 67 // Internal helpers for processing notifications. | |
| 68 void ProcessHangEvent(content::RenderWidgetHost* widget); | |
| 69 void ProcessClosedEvent( | |
| 70 content::RenderProcessHost* rph, | |
| 71 content::RenderProcessHost::RendererClosedDetails* details); | |
| 72 | 44 |
| 73 void DispatchEvent(events::HistogramValue histogram_value, | 45 void DispatchEvent(events::HistogramValue histogram_value, |
| 74 const std::string& event_name, | 46 const std::string& event_name, |
| 75 scoped_ptr<base::ListValue> event_args); | 47 scoped_ptr<base::ListValue> event_args) const; |
| 76 | 48 |
| 77 // Determines whether there is a registered listener for the specified event. | 49 // Determines whether there is a registered listener for the specified event. |
| 78 // It helps to avoid collecing data if no one is interested in it. | 50 // It helps to avoid collecting data if no one is interested in it. |
| 79 bool HasEventListeners(const std::string& event_name); | 51 bool HasEventListeners(const std::string& event_name) const; |
| 80 | 52 |
| 81 // Used for tracking registrations to process related notifications. | 53 // If a task with task |id| was just added or about to be removed, should we |
|
Devlin
2016/03/08 21:27:22
nit: this comment is too implementation-specific,
afakhry
2016/03/09 02:10:13
Agree. Makes sense. Done.
| |
| 82 content::NotificationRegistrar registrar_; | 54 // report this event by OnCreated or OnExited respectively? |
| 55 // It has to be the first task to be created on the process, or the last task | |
| 56 // to be removed from the process. It can't be the browser process, nor | |
| 57 // processes with invalid child process host IDs like ARC processes. | |
| 58 // |out_child_process_host_id| will be filled with the valid ID of the process | |
| 59 // to report in the event. | |
| 60 bool ShouldReportOnCreatedOrOnExited(task_management::TaskId id, | |
| 61 int* out_child_process_host_id) const; | |
| 83 | 62 |
| 84 content::BrowserContext* browser_context_; | 63 content::BrowserContext* browser_context_; |
| 85 | 64 |
| 86 // TaskManager to observe for updates. | |
| 87 TaskManagerModel* model_; | |
| 88 | |
| 89 // Count of listeners, so we avoid sending updates if no one is interested. | 65 // Count of listeners, so we avoid sending updates if no one is interested. |
| 90 int listeners_; | 66 int listeners_; |
| 91 | 67 |
| 92 // Indicator whether we've initialized the Task Manager listeners. This is | |
| 93 // done once for the lifetime of this object. | |
| 94 bool task_manager_listening_; | |
| 95 | |
| 96 DISALLOW_COPY_AND_ASSIGN(ProcessesEventRouter); | 68 DISALLOW_COPY_AND_ASSIGN(ProcessesEventRouter); |
| 97 }; | 69 }; |
| 98 | 70 |
| 71 //////////////////////////////////////////////////////////////////////////////// | |
| 99 // The profile-keyed service that manages the processes extension API. | 72 // The profile-keyed service that manages the processes extension API. |
| 100 class ProcessesAPI : public BrowserContextKeyedAPI, | 73 class ProcessesAPI : public BrowserContextKeyedAPI, |
| 101 public EventRouter::Observer { | 74 public EventRouter::Observer { |
| 102 public: | 75 public: |
| 103 explicit ProcessesAPI(content::BrowserContext* context); | 76 explicit ProcessesAPI(content::BrowserContext* context); |
| 104 ~ProcessesAPI() override; | 77 ~ProcessesAPI() override; |
| 105 | 78 |
| 106 // KeyedService implementation. | 79 // BrowserContextKeyedAPI: |
| 107 void Shutdown() override; | |
| 108 | |
| 109 // BrowserContextKeyedAPI implementation. | |
| 110 static BrowserContextKeyedAPIFactory<ProcessesAPI>* GetFactoryInstance(); | 80 static BrowserContextKeyedAPIFactory<ProcessesAPI>* GetFactoryInstance(); |
| 111 | 81 |
| 112 // Convenience method to get the ProcessesAPI for a profile. | 82 // Convenience method to get the ProcessesAPI for a profile. |
| 113 static ProcessesAPI* Get(content::BrowserContext* context); | 83 static ProcessesAPI* Get(content::BrowserContext* context); |
| 114 | 84 |
| 115 ProcessesEventRouter* processes_event_router(); | 85 // KeyedService: |
| 86 void Shutdown() override; | |
| 116 | 87 |
| 117 // EventRouter::Observer implementation. | 88 // EventRouter::Observer: |
| 118 void OnListenerAdded(const EventListenerInfo& details) override; | 89 void OnListenerAdded(const EventListenerInfo& details) override; |
| 119 void OnListenerRemoved(const EventListenerInfo& details) override; | 90 void OnListenerRemoved(const EventListenerInfo& details) override; |
| 120 | 91 |
| 92 ProcessesEventRouter* processes_event_router(); | |
| 93 | |
| 121 private: | 94 private: |
| 122 friend class BrowserContextKeyedAPIFactory<ProcessesAPI>; | 95 friend class BrowserContextKeyedAPIFactory<ProcessesAPI>; |
| 123 | 96 |
| 124 content::BrowserContext* browser_context_; | 97 // BrowserContextKeyedAPI: |
| 125 | 98 static const char* service_name() { return "ProcessesAPI"; } |
| 126 // BrowserContextKeyedAPI implementation. | |
| 127 static const char* service_name() { | |
| 128 return "ProcessesAPI"; | |
| 129 } | |
| 130 static const bool kServiceRedirectedInIncognito = true; | 99 static const bool kServiceRedirectedInIncognito = true; |
| 131 static const bool kServiceIsNULLWhileTesting = true; | 100 static const bool kServiceIsNULLWhileTesting = true; |
| 132 | 101 |
| 102 content::BrowserContext* browser_context_; | |
| 103 | |
| 133 // Created lazily on first access. | 104 // Created lazily on first access. |
| 134 scoped_ptr<ProcessesEventRouter> processes_event_router_; | 105 scoped_ptr<ProcessesEventRouter> processes_event_router_; |
|
Devlin
2016/03/08 21:27:22
DISALLOW_COPY_AND_ASSIGN
afakhry
2016/03/09 02:10:14
Done.
| |
| 135 }; | 106 }; |
| 136 | 107 |
| 137 //////////////////////////////////////////////////////////////////////////////// | 108 //////////////////////////////////////////////////////////////////////////////// |
| 138 // This extension function returns the Process object for the renderer process | 109 // This extension function returns the Process object for the renderer process |
| 139 // currently in use by the specified Tab. | 110 // currently in use by the specified Tab. |
| 140 class ProcessesGetProcessIdForTabFunction : public UIThreadExtensionFunction { | 111 class ProcessesGetProcessIdForTabFunction : public UIThreadExtensionFunction { |
| 141 public: | 112 public: |
| 142 ProcessesGetProcessIdForTabFunction(); | |
| 143 | |
| 144 // UIThreadExtensionFunction: | 113 // UIThreadExtensionFunction: |
| 145 ExtensionFunction::ResponseAction Run() override; | 114 ExtensionFunction::ResponseAction Run() override; |
| 146 | 115 |
| 116 DECLARE_EXTENSION_FUNCTION("processes.getProcessIdForTab", | |
| 117 PROCESSES_GETPROCESSIDFORTAB); | |
| 118 | |
| 147 private: | 119 private: |
| 148 ~ProcessesGetProcessIdForTabFunction() override {} | 120 ~ProcessesGetProcessIdForTabFunction() override {} |
| 149 | |
| 150 void GetProcessIdForTab(); | |
| 151 | |
| 152 // Storage for the tab ID parameter. | |
| 153 int tab_id_; | |
| 154 | |
| 155 DECLARE_EXTENSION_FUNCTION("processes.getProcessIdForTab", | |
| 156 PROCESSES_GETPROCESSIDFORTAB) | |
| 157 }; | 121 }; |
| 158 | 122 |
| 159 //////////////////////////////////////////////////////////////////////////////// | 123 //////////////////////////////////////////////////////////////////////////////// |
| 160 // Extension function that allows terminating Chrome subprocesses, by supplying | 124 // Extension function that allows terminating Chrome subprocesses, by supplying |
| 161 // the unique ID for the process coming from the ChildProcess ID pool. | 125 // the unique ID for the process coming from the ChildProcess ID pool. |
| 162 // Using unique IDs instead of OS process IDs allows two advantages: | 126 // Using unique IDs instead of OS process IDs allows two advantages: |
| 163 // * guaranteed uniqueness, since OS process IDs can be reused. | 127 // * guaranteed uniqueness, since OS process IDs can be reused. |
| 164 // * guards against killing non-Chrome processes. | 128 // * guards against killing non-Chrome processes. |
| 165 class ProcessesTerminateFunction : public UIThreadExtensionFunction { | 129 class ProcessesTerminateFunction : public UIThreadExtensionFunction { |
| 166 public: | 130 public: |
| 167 ProcessesTerminateFunction(); | |
| 168 | |
| 169 // UIThreadExtensionFunction: | 131 // UIThreadExtensionFunction: |
| 170 ExtensionFunction::ResponseAction Run() override; | 132 ExtensionFunction::ResponseAction Run() override; |
| 171 | 133 |
| 134 DECLARE_EXTENSION_FUNCTION("processes.terminate", PROCESSES_TERMINATE); | |
| 135 | |
| 172 private: | 136 private: |
| 173 ~ProcessesTerminateFunction() override {} | 137 ~ProcessesTerminateFunction() override {} |
| 174 | 138 |
| 175 void TerminateProcess(); | 139 // Functions to get the process handle on the IO thread and post it back to |
| 140 // the UI thread from processing. | |
| 141 base::ProcessHandle GetProcessHandleOnIO(int child_process_host_id) const; | |
| 142 void OnProcessHandleOnUI(base::ProcessHandle handle); | |
| 176 | 143 |
| 177 // Storage for the process ID parameter. | 144 // Checks if |handle| is valid and we can terminate the process. |
| 178 int process_id_; | 145 // |out_error_message| will be filled if we can't terminate the processes. |
| 146 bool CanTerminate(base::ProcessHandle handle, | |
| 147 const char** out_error_message) const; | |
| 179 | 148 |
| 180 DECLARE_EXTENSION_FUNCTION("processes.terminate", | 149 // Terminates the process with |handle| and returns true if it did terminate. |
| 181 PROCESSES_TERMINATE) | 150 bool Terminate(base::ProcessHandle handle) const; |
| 151 | |
| 152 // Caches the parameter of this function. To be accessed only on the UI | |
| 153 // thread. | |
| 154 int child_process_host_id_ = 0; | |
| 182 }; | 155 }; |
| 183 | 156 |
| 184 //////////////////////////////////////////////////////////////////////////////// | 157 //////////////////////////////////////////////////////////////////////////////// |
| 185 // Extension function which returns a set of Process objects, containing the | 158 // Extension function which returns a set of Process objects, containing the |
| 186 // details corresponding to the process IDs supplied as input. | 159 // details corresponding to the process IDs supplied as input. |
| 187 class ProcessesGetProcessInfoFunction : public UIThreadExtensionFunction { | 160 class ProcessesGetProcessInfoFunction : |
| 161 public UIThreadExtensionFunction, | |
| 162 public task_management::TaskManagerObserver { | |
| 188 public: | 163 public: |
| 189 ProcessesGetProcessInfoFunction(); | 164 ProcessesGetProcessInfoFunction(); |
| 190 | 165 |
| 191 // UIThreadExtensionFunction: | 166 // UIThreadExtensionFunction: |
| 192 ExtensionFunction::ResponseAction Run() override; | 167 ExtensionFunction::ResponseAction Run() override; |
| 193 | 168 |
| 169 // task_management::TaskManagerObserver: | |
| 170 void OnTaskAdded(task_management::TaskId id) override {} | |
| 171 void OnTaskToBeRemoved(task_management::TaskId id) override {} | |
| 172 void OnTasksRefreshed(const task_management::TaskIdList& task_ids) override; | |
| 173 void OnTasksRefreshedWithBackgroundCalculations( | |
| 174 const task_management::TaskIdList& task_ids) override; | |
| 175 | |
| 176 DECLARE_EXTENSION_FUNCTION("processes.getProcessInfo", | |
| 177 PROCESSES_GETPROCESSINFO); | |
| 178 | |
| 194 private: | 179 private: |
| 195 ~ProcessesGetProcessInfoFunction() override; | 180 ~ProcessesGetProcessInfoFunction() override; |
| 196 | 181 |
| 197 void GatherProcessInfo(); | 182 // Since we don't report optional process data like CPU usage in the results |
| 183 // of this function, the only background calculations we want to watch is | |
| 184 // memory usage (which will be requested only when |include_memory_| is true). | |
| 185 // This function will be called by either OnTasksRefreshed() or | |
| 186 // OnTasksRefreshedWithBackgroundCalculations() depending on whether memory is | |
| 187 // requested. | |
| 188 void GatherDataAndRespond(const task_management::TaskIdList& task_ids); | |
| 198 | 189 |
| 199 // Member variables to store the function parameters | 190 std::vector<int> process_host_ids_; |
| 200 std::vector<int> process_ids_; | 191 bool include_memory_ = false; |
| 201 #if defined(ENABLE_TASK_MANAGER) | |
| 202 bool memory_; | |
| 203 #endif | |
| 204 | |
| 205 DECLARE_EXTENSION_FUNCTION("processes.getProcessInfo", | |
| 206 PROCESSES_GETPROCESSINFO) | |
| 207 }; | 192 }; |
| 208 | 193 |
| 209 } // namespace extensions | 194 } // namespace extensions |
| 210 | 195 |
| 211 #endif // CHROME_BROWSER_EXTENSIONS_API_PROCESSES_PROCESSES_API_H__ | 196 #endif // CHROME_BROWSER_EXTENSIONS_API_PROCESSES_PROCESSES_API_H__ |
| OLD | NEW |